-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add xmltype in postgres #1112
Open
mauravan
wants to merge
4
commits into
eclipse-vertx:master
Choose a base branch
from
mauravan:datatype-xml-pg
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+149
−4
Open
add xmltype in postgres #1112
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,16 +20,16 @@ | |
import io.netty.buffer.ByteBuf; | ||
import io.netty.buffer.Unpooled; | ||
import io.netty.handler.codec.DecoderException; | ||
import io.vertx.core.buffer.Buffer; | ||
import io.vertx.core.impl.logging.Logger; | ||
import io.vertx.core.impl.logging.LoggerFactory; | ||
import io.vertx.core.json.Json; | ||
import io.vertx.sqlclient.Tuple; | ||
import io.vertx.sqlclient.data.Numeric; | ||
import io.vertx.pgclient.data.*; | ||
import io.vertx.pgclient.impl.util.UTF8StringEndDetector; | ||
import io.vertx.core.buffer.Buffer; | ||
import io.vertx.core.json.JsonArray; | ||
import io.vertx.core.json.JsonObject; | ||
import io.vertx.pgclient.data.*; | ||
import io.vertx.pgclient.impl.util.UTF8StringEndDetector; | ||
import io.vertx.sqlclient.Tuple; | ||
import io.vertx.sqlclient.data.Numeric; | ||
import io.vertx.sqlclient.impl.codec.CommonCodec; | ||
|
||
import java.net.Inet4Address; | ||
|
@@ -50,18 +50,22 @@ | |
|
||
import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE; | ||
import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME; | ||
import static java.util.concurrent.TimeUnit.*; | ||
import static java.util.concurrent.TimeUnit.NANOSECONDS; | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Julien Viet</a> | ||
* @author <a href="mailto:[email protected]">Emad Alblueshi</a> | ||
* | ||
* <p> | ||
* See also https://www.npgsql.org/doc/dev/type-representations.html | ||
*/ | ||
public class DataTypeCodec { | ||
|
||
// Sentinel used when an object is refused by the data type | ||
public static final Object REFUSED_SENTINEL = new Object(); | ||
// 4714-11-24 00:00:00 BC | ||
public static final LocalDateTime LDT_MINUS_INFINITY = LocalDateTime.parse("4714-11-24 00:00:00 BC", | ||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss G", Locale.ROOT)); | ||
private static final Logger logger = LoggerFactory.getLogger(DataTypeCodec.class); | ||
|
||
private static final String[] empty_string_array = new String[0]; | ||
private static final LocalDate[] empty_local_date_array = new LocalDate[0]; | ||
private static final LocalTime[] empty_local_time_array = new LocalTime[0]; | ||
|
@@ -88,13 +92,11 @@ public class DataTypeCodec { | |
private static final Double[] empty_double_array = new Double[0]; | ||
private static final LocalDate LOCAL_DATE_EPOCH = LocalDate.of(2000, 1, 1); | ||
private static final LocalDateTime LOCAL_DATE_TIME_EPOCH = LocalDateTime.of(2000, 1, 1, 0, 0, 0); | ||
// 294277-01-09 04:00:54.775807 | ||
public static final LocalDateTime LDT_PLUS_INFINITY = LOCAL_DATE_TIME_EPOCH.plus(Long.MAX_VALUE, ChronoUnit.MICROS); | ||
private static final OffsetDateTime OFFSET_DATE_TIME_EPOCH = LocalDateTime.of(2000, 1, 1, 0, 0, 0).atOffset(ZoneOffset.UTC); | ||
private static final Inet[] empty_inet_array = new Inet[0]; | ||
private static final Money[] empty_money_array = new Money[0]; | ||
|
||
// Sentinel used when an object is refused by the data type | ||
public static final Object REFUSED_SENTINEL = new Object(); | ||
|
||
private static final IntFunction<Boolean[]> BOOLEAN_ARRAY_FACTORY = size -> size == 0 ? empty_boolean_array : new Boolean[size]; | ||
private static final IntFunction<Short[]> SHORT_ARRAY_FACTORY = size -> size == 0 ? empty_short_array : new Short[size]; | ||
private static final IntFunction<Integer[]> INTEGER_ARRAY_FACTORY = size -> size == 0 ? empty_integer_array : new Integer[size]; | ||
|
@@ -107,7 +109,7 @@ public class DataTypeCodec { | |
private static final IntFunction<OffsetTime[]> OFFSETTIME_ARRAY_FACTORY = size -> size == 0 ? empty_offset_time_array : new OffsetTime[size]; | ||
private static final IntFunction<LocalDateTime[]> LOCALDATETIME_ARRAY_FACTORY = size -> size == 0 ? empty_local_date_time_array : new LocalDateTime[size]; | ||
private static final IntFunction<OffsetDateTime[]> OFFSETDATETIME_ARRAY_FACTORY = size -> size == 0 ? empty_offset_date_time_array : new OffsetDateTime[size]; | ||
private static final IntFunction<Buffer[]> BUFFER_ARRAY_FACTORY =size -> size == 0 ? empty_buffer_array : new Buffer[size]; | ||
private static final IntFunction<Buffer[]> BUFFER_ARRAY_FACTORY = size -> size == 0 ? empty_buffer_array : new Buffer[size]; | ||
private static final IntFunction<UUID[]> UUID_ARRAY_FACTORY = size -> size == 0 ? empty_uuid_array : new UUID[size]; | ||
private static final IntFunction<Object[]> JSON_ARRAY_FACTORY = size -> size == 0 ? empty_json_array : new Object[size]; | ||
private static final IntFunction<Numeric[]> NUMERIC_ARRAY_FACTORY = size -> size == 0 ? empty_numeric_array : new Numeric[size]; | ||
|
@@ -121,20 +123,17 @@ public class DataTypeCodec { | |
private static final IntFunction<Interval[]> INTERVAL_ARRAY_FACTORY = size -> size == 0 ? empty_interval_array : new Interval[size]; | ||
private static final IntFunction<Inet[]> INET_ARRAY_FACTORY = size -> size == 0 ? empty_inet_array : new Inet[size]; | ||
private static final IntFunction<Money[]> MONEY_ARRAY_FACTORY = size -> size == 0 ? empty_money_array : new Money[size]; | ||
|
||
private static final java.time.format.DateTimeFormatter TIMETZ_FORMAT = new DateTimeFormatterBuilder() | ||
.parseCaseInsensitive() | ||
.append(ISO_LOCAL_TIME) | ||
.appendOffset("+HH:mm", "00:00") | ||
.toFormatter(); | ||
|
||
private static final java.time.format.DateTimeFormatter TIMESTAMP_FORMAT = new DateTimeFormatterBuilder() | ||
.parseCaseInsensitive() | ||
.append(ISO_LOCAL_DATE) | ||
.appendLiteral(' ') | ||
.append(ISO_LOCAL_TIME) | ||
.toFormatter(); | ||
|
||
private static final java.time.format.DateTimeFormatter TIMESTAMPTZ_FORMAT = new DateTimeFormatterBuilder() | ||
.append(TIMESTAMP_FORMAT) | ||
.appendOffset("+HH:mm", "00:00") | ||
|
@@ -277,13 +276,13 @@ public static void encodeBinary(DataType id, Object value, ByteBuf buff) { | |
binaryEncodeArray((UUID[]) value, DataType.UUID, buff); | ||
break; | ||
case JSON: | ||
binaryEncodeJSON((Object) value, buff); | ||
binaryEncodeJSON(value, buff); | ||
break; | ||
case JSON_ARRAY: | ||
binaryEncodeArray((Object[]) value, DataType.JSON, buff); | ||
break; | ||
case JSONB: | ||
binaryEncodeJSONB((Object) value, buff); | ||
binaryEncodeJSONB(value, buff); | ||
break; | ||
case JSONB_ARRAY: | ||
binaryEncodeArray((Object[]) value, DataType.JSONB, buff); | ||
|
@@ -360,6 +359,12 @@ public static void encodeBinary(DataType id, Object value, ByteBuf buff) { | |
case MONEY_ARRAY: | ||
binaryEncodeArray((Money[]) value, DataType.MONEY, buff); | ||
break; | ||
case XML: | ||
binaryEncodeXML((String) value, buff); | ||
break; | ||
case XML_ARRAY: | ||
binaryEncodeArray((String[]) value, DataType.XML, buff); | ||
break; | ||
default: | ||
logger.debug("Data type " + id + " does not support binary encoding"); | ||
defaultEncodeBinary(value, buff); | ||
|
@@ -497,6 +502,10 @@ public static Object decodeBinary(DataType id, int index, int len, ByteBuf buff) | |
return binaryDecodeMoney(index, len, buff); | ||
case MONEY_ARRAY: | ||
return binaryDecodeArray(MONEY_ARRAY_FACTORY, DataType.MONEY, index, len, buff); | ||
case XML: | ||
return binaryDecodeXML(index, len, buff); | ||
case XML_ARRAY: | ||
return binaryDecodeArray(STRING_ARRAY_FACTORY, DataType.XML, index, len, buff); | ||
default: | ||
logger.debug("Data type " + id + " does not support binary decoding"); | ||
return defaultDecodeBinary(index, len, buff); | ||
|
@@ -637,6 +646,10 @@ public static Object decodeText(DataType id, int index, int len, ByteBuf buff) { | |
return textDecodeMoney(index, len, buff); | ||
case MONEY_ARRAY: | ||
return textDecodeArray(MONEY_ARRAY_FACTORY, DataType.MONEY, index, len, buff); | ||
case XML: | ||
return textDecodeXML(index, len, buff); | ||
case XML_ARRAY: | ||
return textDecodeArray(STRING_ARRAY_FACTORY, DataType.XML, index, len, buff); | ||
default: | ||
return defaultDecodeText(index, len, buff); | ||
} | ||
|
@@ -669,7 +682,7 @@ private static Boolean binaryDecodeBOOL(int index, int len, ByteBuf buff) { | |
} | ||
|
||
private static Boolean textDecodeBOOL(int index, int len, ByteBuf buff) { | ||
if(buff.getByte(index) == 't') { | ||
if (buff.getByte(index) == 't') { | ||
return Boolean.TRUE; | ||
} else { | ||
return Boolean.FALSE; | ||
|
@@ -770,7 +783,7 @@ private static Line textDecodeLine(int index, int len, ByteBuf buff) { | |
|
||
private static LineSegment textDecodeLseg(int index, int len, ByteBuf buff) { | ||
// Lseg representation: [p1,p2] | ||
int idxOfPointsSeparator = buff.indexOf(index, index+len, (byte) ')') + 1; | ||
int idxOfPointsSeparator = buff.indexOf(index, index + len, (byte) ')') + 1; | ||
int lenOfP1 = idxOfPointsSeparator - index - 1; | ||
Point p1 = textDecodePOINT(index + 1, lenOfP1, buff); | ||
Point p2 = textDecodePOINT(idxOfPointsSeparator + 1, len - lenOfP1 - 3, buff); | ||
|
@@ -779,7 +792,7 @@ private static LineSegment textDecodeLseg(int index, int len, ByteBuf buff) { | |
|
||
private static Box textDecodeBox(int index, int len, ByteBuf buff) { | ||
// Box representation: p1,p2 | ||
int idxOfPointsSeparator = buff.indexOf(index, index+len, (byte) ')') + 1; | ||
int idxOfPointsSeparator = buff.indexOf(index, index + len, (byte) ')') + 1; | ||
int lenOfUpperRightCornerPoint = idxOfPointsSeparator - index; | ||
Point upperRightCorner = textDecodePOINT(index, lenOfUpperRightCornerPoint, buff); | ||
Point lowerLeftCorner = textDecodePOINT(idxOfPointsSeparator + 1, len - lenOfUpperRightCornerPoint - 1, buff); | ||
|
@@ -862,7 +875,7 @@ private static Interval textDecodeINTERVAL(int index, int len, ByteBuf buff) { | |
int years = 0, months = 0, days = 0, hours = 0, minutes = 0, seconds = 0, microseconds = 0; | ||
final List<String> chunks = new ArrayList<>(7); | ||
int idx = 0; | ||
for (;;) { | ||
for (; ; ) { | ||
int newIdx = value.indexOf(' ', idx); | ||
if (newIdx == -1) { | ||
chunks.add(value.substring(idx)); | ||
|
@@ -895,25 +908,25 @@ private static Interval textDecodeINTERVAL(int index, int len, ByteBuf buff) { | |
boolean isNeg = timeChunk.charAt(0) == '-'; | ||
if (isNeg) timeChunk = timeChunk.substring(1); | ||
int sidx = 0; | ||
for (;;) { | ||
for (; ; ) { | ||
int newIdx = timeChunk.indexOf(':', sidx); | ||
if (newIdx == -1) { | ||
int m = timeChunk.substring(sidx).indexOf('.'); | ||
if(m == -1) { | ||
if (m == -1) { | ||
// seconds without microseconds | ||
seconds = isNeg ? -Integer.parseInt(timeChunk.substring(sidx)) | ||
: Integer.parseInt(timeChunk.substring(sidx)); | ||
} else { | ||
// seconds with microseconds | ||
seconds = isNeg ? -Integer.parseInt(timeChunk.substring(sidx).substring(0, m)) | ||
seconds = isNeg ? -Integer.parseInt(timeChunk.substring(sidx).substring(0, m)) | ||
: Integer.parseInt(timeChunk.substring(sidx).substring(0, m)); | ||
microseconds = isNeg ? -Integer.parseInt(timeChunk.substring(sidx).substring(m + 1)) | ||
: Integer.parseInt(timeChunk.substring(sidx).substring(m + 1)); | ||
} | ||
break; | ||
} | ||
// hours | ||
if(sidx == 0) { | ||
if (sidx == 0) { | ||
hours = isNeg ? -Integer.parseInt(timeChunk.substring(sidx, newIdx)) | ||
: Integer.parseInt(timeChunk.substring(sidx, newIdx)); | ||
} else { | ||
|
@@ -990,7 +1003,6 @@ private static String textDecodeNAME(int index, int len, ByteBuf buff) { | |
return buff.getCharSequence(index, len, StandardCharsets.UTF_8).toString(); | ||
} | ||
|
||
|
||
private static void binaryEncodeNAME(String value, ByteBuf buff) { | ||
String s = String.valueOf(value); | ||
buff.writeCharSequence(s, StandardCharsets.UTF_8); | ||
|
@@ -1069,12 +1081,6 @@ private static OffsetTime textDecodeTIMETZ(int index, int len, ByteBuf buff) { | |
return OffsetTime.parse(cs, TIMETZ_FORMAT); | ||
} | ||
|
||
// 294277-01-09 04:00:54.775807 | ||
public static final LocalDateTime LDT_PLUS_INFINITY = LOCAL_DATE_TIME_EPOCH.plus(Long.MAX_VALUE, ChronoUnit.MICROS); | ||
// 4714-11-24 00:00:00 BC | ||
public static final LocalDateTime LDT_MINUS_INFINITY = LocalDateTime.parse("4714-11-24 00:00:00 BC", | ||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss G", Locale.ROOT)); | ||
|
||
private static void binaryEncodeTIMESTAMP(LocalDateTime value, ByteBuf buff) { | ||
if (value.compareTo(LDT_PLUS_INFINITY) >= 0) { | ||
value = LDT_PLUS_INFINITY; | ||
|
@@ -1466,7 +1472,7 @@ private static void binaryEncodeMoney(Money money, ByteBuf buff) { | |
|
||
private static Money binaryDecodeMoney(int index, int len, ByteBuf buff) { | ||
long value = binaryDecodeINT8(index, len, buff); | ||
return new Money(value / 100, Math.abs(((int)value % 100))); | ||
return new Money(value / 100, Math.abs(((int) value % 100))); | ||
} | ||
|
||
private static String binaryDecodeTsQuery(int index, int len, ByteBuf buff) { | ||
|
@@ -1477,6 +1483,18 @@ private static void binaryEncodeTsQuery(String value, ByteBuf buff) { | |
buff.writeCharSequence(String.valueOf(value), StandardCharsets.UTF_8); | ||
} | ||
|
||
private static String binaryDecodeXML(int index, int len, ByteBuf buff) { | ||
return buff.getCharSequence(index, len, StandardCharsets.UTF_8).toString(); | ||
} | ||
|
||
private static void binaryEncodeXML(String value, ByteBuf buff) { | ||
buff.writeCharSequence(value, StandardCharsets.UTF_8); | ||
} | ||
|
||
private static String textDecodeXML(int index, int len, ByteBuf buff) { | ||
return buff.getCharSequence(index, len, StandardCharsets.UTF_8).toString(); | ||
} | ||
|
||
private static String textDecodeTsVector(int index, int len, ByteBuf buff) { | ||
return buff.getCharSequence(index, len, StandardCharsets.UTF_8).toString(); | ||
} | ||
|
@@ -1535,7 +1553,7 @@ private static Money textDecodeMoney(int index, int len, ByteBuf buff) { | |
* Decode the specified {@code buff} formatted as an hex string starting at the buffer readable index | ||
* with the specified {@code length} to a {@link Buffer}. | ||
* | ||
* @param len the hex string length | ||
* @param len the hex string length | ||
* @param buff the byte buff to read from | ||
* @return the decoded value as a Buffer | ||
*/ | ||
|
@@ -1551,7 +1569,7 @@ private static Buffer decodeHexStringToBytes(int index, int len, ByteBuf buff) { | |
} | ||
|
||
private static byte decodeHexChar(byte ch) { | ||
return (byte)(((ch & 0x1F) + ((ch >> 6) * 0x19) - 0x10) & 0x0F); | ||
return (byte) (((ch & 0x1F) + ((ch >> 6) * 0x19) - 0x10) & 0x0F); | ||
} | ||
|
||
private static boolean isHexFormat(int index, int len, ByteBuf buff) { | ||
|
@@ -1619,7 +1637,7 @@ private static <T> T[] binaryDecodeArray(IntFunction<T[]> supplier, DataType typ | |
return array; | ||
} | ||
|
||
private static <T> void binaryEncodeArray(T[] values, DataType type, ByteBuf buff){ | ||
private static <T> void binaryEncodeArray(T[] values, DataType type, ByteBuf buff) { | ||
int startIndex = buff.writerIndex(); | ||
buff.writeInt(1); // ndim | ||
buff.writeInt(0); // dataoffset | ||
|
@@ -1681,7 +1699,7 @@ private static <T> T textDecodeArrayElement(DataType type, int index, int len, B | |
// Some escaping - improve that later... | ||
String s = buff.toString(index + 1, len - 2, StandardCharsets.UTF_8); | ||
StringBuilder sb = new StringBuilder(); | ||
for (int i = 0;i < s.length();i++) { | ||
for (int i = 0; i < s.length(); i++) { | ||
char c = s.charAt(i); | ||
if (c == '\\') { | ||
c = s.charAt(++i); | ||
|
@@ -1696,7 +1714,7 @@ private static <T> T textDecodeArrayElement(DataType type, int index, int len, B | |
} | ||
} | ||
|
||
private static <T> void textEncodeArray(T[] values, DataType type, ByteBuf buff){ | ||
private static <T> void textEncodeArray(T[] values, DataType type, ByteBuf buff) { | ||
buff.writeByte('{'); | ||
int len = values.length; | ||
for (int i = 0; i < len; i++) { | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this commented ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the Comment from the 22. of Dec: