Skip to content

Commit f0645b1

Browse files
committed
added basic dynamic support for rowbinary reader
1 parent 6788dbc commit f0645b1

File tree

4 files changed

+253
-74
lines changed

4 files changed

+253
-74
lines changed

clickhouse-data/src/main/java/com/clickhouse/data/ClickHouseDataType.java

Lines changed: 158 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -36,72 +36,126 @@
3636
*/
3737
@SuppressWarnings("squid:S115")
3838
public enum ClickHouseDataType {
39-
Bool(Boolean.class, false, false, true, 1, 1, 0, 0, 0, false, "BOOLEAN"),
40-
Date(LocalDate.class, false, false, false, 2, 10, 0, 0, 0, false),
41-
Date32(LocalDate.class, false, false, false, 4, 10, 0, 0, 0, false),
42-
DateTime(LocalDateTime.class, true, false, false, 0, 29, 0, 0, 9, false, "TIMESTAMP"),
43-
DateTime32(LocalDateTime.class, true, false, false, 4, 19, 0, 0, 0, false),
44-
DateTime64(LocalDateTime.class, true, false, false, 8, 29, 3, 0, 9, false),
45-
Enum8(String.class, true, true, false, 1, 0, 0, 0, 0, false, "ENUM"),
46-
Enum16(String.class, true, true, false, 2, 0, 0, 0, 0, false),
47-
FixedString(String.class, true, true, false, 0, 0, 0, 0, 0, false, "BINARY"),
48-
Int8(Byte.class, false, true, true, 1, 3, 0, 0, 0, false, "BYTE", "INT1", "INT1 SIGNED", "TINYINT",
39+
Bool(Boolean.class, false, false, true, 1, 1, 0, 0, 0, false,0x2D, "BOOLEAN"),
40+
Date(LocalDate.class, false, false, false, 2, 10, 0, 0, 0, false, 0x0F),
41+
Date32(LocalDate.class, false, false, false, 4, 10, 0, 0, 0, false, 0x10),
42+
DateTime(LocalDateTime.class, true, false, false, 0, 29, 0, 0, 9, false, 0x11, "TIMESTAMP"),
43+
DateTime32(LocalDateTime.class, true, false, false, 4, 19, 0, 0, 0, false, 0x12),
44+
DateTime64(LocalDateTime.class, true, false, false, 8, 29, 3, 0, 9, false, 0x13),
45+
Enum8(String.class, true, true, false, 1, 0, 0, 0, 0, false, 0x17, "ENUM"),
46+
Enum16(String.class, true, true, false, 2, 0, 0, 0, 0, false, 0x18),
47+
FixedString(String.class, true, true, false, 0, 0, 0, 0, 0, false, 0x16, "BINARY"),
48+
Int8(Byte.class, false, true, true, 1, 3, 0, 0, 0, false, 0x07,"BYTE", "INT1", "INT1 SIGNED", "TINYINT",
4949
"TINYINT SIGNED"),
50-
UInt8(UnsignedByte.class, false, true, false, 1, 3, 0, 0, 0, false, "INT1 UNSIGNED", "TINYINT UNSIGNED"),
51-
Int16(Short.class, false, true, true, 2, 5, 0, 0, 0, false, "SMALLINT", "SMALLINT SIGNED"),
52-
UInt16(UnsignedShort.class, false, true, false, 2, 5, 0, 0, 0, false, "SMALLINT UNSIGNED", "YEAR"),
53-
Int32(Integer.class, false, true, true, 4, 10, 0, 0, 0, false, "INT", "INT SIGNED", "INTEGER", "INTEGER SIGNED",
50+
UInt8(UnsignedByte.class, false, true, false, 1, 3, 0, 0, 0, false,0x01, "INT1 UNSIGNED", "TINYINT UNSIGNED"),
51+
Int16(Short.class, false, true, true, 2, 5, 0, 0, 0, false, 0x08,"SMALLINT", "SMALLINT SIGNED"),
52+
UInt16(UnsignedShort.class, false, true, false, 2, 5, 0, 0, 0, false, 0x02,"SMALLINT UNSIGNED", "YEAR"),
53+
Int32(Integer.class, false, true, true, 4, 10, 0, 0, 0, false, 0x09, "INT", "INT SIGNED", "INTEGER", "INTEGER SIGNED",
5454
"MEDIUMINT", "MEDIUMINT SIGNED"),
5555
// https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html#PageTitle
56-
UInt32(UnsignedInteger.class, false, true, false, 4, 10, 0, 0, 0, false, "INT UNSIGNED", "INTEGER UNSIGNED",
56+
UInt32(UnsignedInteger.class, false, true, false, 4, 10, 0, 0, 0, false, 0x03, "INT UNSIGNED", "INTEGER UNSIGNED",
5757
"MEDIUMINT UNSIGNED"),
58-
Int64(Long.class, false, true, true, 8, 19, 0, 0, 0, false, "BIGINT", "BIGINT SIGNED", "TIME"),
59-
IntervalYear(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
60-
IntervalQuarter(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
61-
IntervalMonth(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
62-
IntervalWeek(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
63-
IntervalDay(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
64-
IntervalHour(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
65-
IntervalMinute(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
66-
IntervalSecond(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
67-
IntervalMicrosecond(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
68-
IntervalMillisecond(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
69-
IntervalNanosecond(Long.class, false, true, true, 8, 19, 0, 0, 0, false),
70-
UInt64(UnsignedLong.class, false, true, false, 8, 20, 0, 0, 0, false, "BIGINT UNSIGNED", "BIT", "SET"),
71-
Int128(BigInteger.class, false, true, true, 16, 39, 0, 0, 0, false),
72-
UInt128(BigInteger.class, false, true, false, 16, 39, 0, 0, 0, false),
73-
Int256(BigInteger.class, false, true, true, 32, 77, 0, 0, 0, false),
74-
UInt256(BigInteger.class, false, true, false, 32, 78, 0, 0, 0, false),
58+
Int64(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x0A,"BIGINT", "BIGINT SIGNED", "TIME"),
59+
IntervalYear(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
60+
IntervalQuarter(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
61+
IntervalMonth(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
62+
IntervalWeek(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
63+
IntervalDay(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
64+
IntervalHour(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
65+
IntervalMinute(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
66+
IntervalSecond(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
67+
IntervalMicrosecond(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
68+
IntervalMillisecond(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
69+
IntervalNanosecond(Long.class, false, true, true, 8, 19, 0, 0, 0, false, 0x22),
70+
UInt64(UnsignedLong.class, false, true, false, 8, 20, 0, 0, 0, false, 0x04, "BIGINT UNSIGNED", "BIT", "SET"),
71+
Int128(BigInteger.class, false, true, true, 16, 39, 0, 0, 0, false, 0x0B),
72+
UInt128(BigInteger.class, false, true, false, 16, 39, 0, 0, 0, false, 0x05),
73+
Int256(BigInteger.class, false, true, true, 32, 77, 0, 0, 0, false, 0x0C),
74+
UInt256(BigInteger.class, false, true, false, 32, 78, 0, 0, 0, false, 0x06),
7575
Decimal(BigDecimal.class, true, false, true, 0, 76, 0, 0, 76, false, "DEC", "FIXED", "NUMERIC"),
76-
Decimal32(BigDecimal.class, true, false, true, 4, 9, 9, 0, 9, false),
77-
Decimal64(BigDecimal.class, true, false, true, 8, 18, 18, 0, 18, false),
78-
Decimal128(BigDecimal.class, true, false, true, 16, 38, 38, 0, 38, false),
79-
Decimal256(BigDecimal.class, true, false, true, 32, 76, 20, 0, 76, false),
80-
Float32(Float.class, false, true, true, 4, 12, 0, 0, 38, false, "FLOAT", "REAL", "SINGLE"),
81-
Float64(Double.class, false, true, true, 8, 22, 0, 0, 308, false, "DOUBLE", "DOUBLE PRECISION"),
82-
IPv4(Inet4Address.class, false, true, false, 4, 10, 0, 0, 0, false, "INET4"),
83-
IPv6(Inet6Address.class, false, true, false, 16, 39, 0, 0, 0, false, "INET6"),
84-
UUID(UUID.class, false, true, false, 16, 69, 0, 0, 0, false),
85-
Point(Object.class, false, true, true, 33, 0, 0, 0, 0, true), // same as Tuple(Float64, Float64)
86-
Polygon(Object.class, false, true, true, 0, 0, 0, 0, 0, true), // same as Array(Ring)
87-
MultiPolygon(Object.class, false, true, true, 0, 0, 0, 0, 0, true), // same as Array(Polygon)
88-
Ring(Object.class, false, true, true, 0, 0, 0, 0, 0, true), // same as Array(Point)
89-
JSON(Object.class, false, false, false, 0, 0, 0, 0, 0, true), // same as Object('JSON')
76+
Decimal32(BigDecimal.class, true, false, true, 4, 9, 9, 0, 9, false, 0x19),
77+
Decimal64(BigDecimal.class, true, false, true, 8, 18, 18, 0, 18, false, 0x1A),
78+
Decimal128(BigDecimal.class, true, false, true, 16, 38, 38, 0, 38, false, 0x1B),
79+
Decimal256(BigDecimal.class, true, false, true, 32, 76, 20, 0, 76, false, 0x1C),
80+
Float32(Float.class, false, true, true, 4, 12, 0, 0, 38, false, 0x0D, "FLOAT", "REAL", "SINGLE"),
81+
Float64(Double.class, false, true, true, 8, 22, 0, 0, 308, false, 0x0E, "DOUBLE", "DOUBLE PRECISION"),
82+
IPv4(Inet4Address.class, false, true, false, 4, 10, 0, 0, 0, false, 0x28, "INET4"),
83+
IPv6(Inet6Address.class, false, true, false, 16, 39, 0, 0, 0, false, 0x29, "INET6"),
84+
UUID(UUID.class, false, true, false, 16, 69, 0, 0, 0, false, 0x1D),
85+
Point(Object.class, false, true, true, 33, 0, 0, 0, 0, true, 0x2C), // same as Tuple(Float64, Float64)
86+
Polygon(Object.class, false, true, true, 0, 0, 0, 0, 0, true, 0x2C), // same as Array(Ring)
87+
MultiPolygon(Object.class, false, true, true, 0, 0, 0, 0, 0, true, 0x2C), // same as Array(Polygon)
88+
Ring(Object.class, false, true, true, 0, 0, 0, 0, 0, true, 0x2C), // same as Array(Point)
89+
JSON(Object.class, false, false, false, 0, 0, 0, 0, 0, true, 0x30),
90+
@Deprecated
9091
Object(Object.class, true, true, false, 0, 0, 0, 0, 0, true),
91-
String(String.class, false, false, false, 0, 0, 0, 0, 0, false, "BINARY LARGE OBJECT", "BINARY VARYING", "BLOB",
92+
String(String.class, false, false, false, 0, 0, 0, 0, 0, false, 0x15, "BINARY LARGE OBJECT", "BINARY VARYING", "BLOB",
9293
"BYTEA", "CHAR", "CHAR LARGE OBJECT", "CHAR VARYING", "CHARACTER", "CHARACTER LARGE OBJECT",
9394
"CHARACTER VARYING", "CLOB", "GEOMETRY", "LONGBLOB", "LONGTEXT", "MEDIUMBLOB", "MEDIUMTEXT",
9495
"NATIONAL CHAR", "NATIONAL CHAR VARYING", "NATIONAL CHARACTER", "NATIONAL CHARACTER LARGE OBJECT",
9596
"NATIONAL CHARACTER VARYING", "NCHAR", "NCHAR LARGE OBJECT", "NCHAR VARYING", "NVARCHAR", "TEXT",
9697
"TINYBLOB", "TINYTEXT", "VARBINARY", "VARCHAR", "VARCHAR2"),
97-
Array(Object.class, true, true, false, 0, 0, 0, 0, 0, true),
98-
Map(Map.class, true, true, false, 0, 0, 0, 0, 0, true),
99-
Nested(Object.class, true, true, false, 0, 0, 0, 0, 0, true),
100-
Tuple(List.class, true, true, false, 0, 0, 0, 0, 0, true),
101-
Nothing(Object.class, false, true, false, 0, 0, 0, 0, 0, true),
102-
SimpleAggregateFunction(String.class, true, true, false, 0, 0, 0, 0, 0, false),
98+
Array(Object.class, true, true, false, 0, 0, 0, 0, 0, true, 0x1E),
99+
Map(Map.class, true, true, false, 0, 0, 0, 0, 0, true, 0x27),
100+
Nested(Object.class, true, true, false, 0, 0, 0, 0, 0, true, 0x2F),
101+
Tuple(List.class, true, true, false, 0, 0, 0, 0, 0, true, 0x1F),
102+
Nothing(Object.class, false, true, false, 0, 0, 0, 0, 0, true, 0x00),
103+
SimpleAggregateFunction(String.class, true, true, false, 0, 0, 0, 0, 0, false, 0x2E),
103104
// implementation-defined intermediate state
104-
AggregateFunction(String.class, true, true, false, 0, 0, 0, 0, 0, true);
105+
AggregateFunction(String.class, true, true, false, 0, 0, 0, 0, 0, true, 0x25),
106+
Dynamic(Object.class, true, true, false, 0, 0, 0, 0, 0, true, 0x2B),
107+
;
108+
109+
110+
public static final byte INTERVAL_BIN_TAG = 0x22;
111+
112+
public static final byte NULLABLE_BIN_TAG = 0x23;
113+
114+
public static final byte LOW_CARDINALITY_BIN_TAG = 0x26;
115+
116+
public static final byte SET_BIN_TAG = 0x21;
117+
118+
public enum IntervalKindBinTag {
119+
Nanosecond(IntervalNanosecond, 0x00),
120+
Microsecond(IntervalMicrosecond, 0x01),
121+
122+
Millisecond(IntervalMillisecond, 0x02),
123+
124+
Second(IntervalSecond, 0x03),
125+
126+
Minute(IntervalMinute, 0x04),
127+
128+
Hour(IntervalHour, 0x05),
129+
130+
Day(IntervalDay, 0x06),
131+
132+
Week(IntervalWeek, 0x07),
133+
134+
Month(IntervalMonth, 0x08),
135+
136+
Quarter(IntervalQuarter, 0x09),
137+
138+
Year(IntervalYear, 0x1A) // why 1A ?
139+
140+
;
141+
142+
private ClickHouseDataType intervalType;
143+
144+
byte tag;
145+
IntervalKindBinTag(ClickHouseDataType clickHouseDataType, int tag) {
146+
this.intervalType = clickHouseDataType;
147+
this.tag = (byte) tag;
148+
}
149+
150+
public ClickHouseDataType getIntervalType() {
151+
return intervalType;
152+
}
153+
154+
public byte getTag() {
155+
return tag;
156+
}
157+
}
158+
105159

106160
/**
107161
* Immutable set(sorted) for all aliases.
@@ -113,6 +167,10 @@ public enum ClickHouseDataType {
113167
*/
114168
public static final Map<String, ClickHouseDataType> name2type;
115169

170+
public static final Map<Byte, ClickHouseDataType> binTag2Type;
171+
172+
public static final Map<Byte, ClickHouseDataType> intervalKind2Type;
173+
116174
static {
117175
Set<String> set = new TreeSet<>();
118176
Map<String, ClickHouseDataType> map = new HashMap<>();
@@ -141,6 +199,18 @@ public enum ClickHouseDataType {
141199

142200
allAliases = Collections.unmodifiableSet(set);
143201
name2type = Collections.unmodifiableMap(map);
202+
203+
Map<Byte, ClickHouseDataType> tmpbinTag2Type = new HashMap<>();
204+
for (ClickHouseDataType type : ClickHouseDataType.values()) {
205+
tmpbinTag2Type.put((byte) type.getBinTag(), type);
206+
}
207+
binTag2Type = Collections.unmodifiableMap(tmpbinTag2Type);
208+
209+
Map<Byte, ClickHouseDataType> tmpIntervalKind2Type = new HashMap<>();
210+
for (IntervalKindBinTag kind : IntervalKindBinTag.values()) {
211+
tmpIntervalKind2Type.put(kind.getTag(), kind.getIntervalType());
212+
}
213+
intervalKind2Type = Collections.unmodifiableMap(tmpIntervalKind2Type);
144214
}
145215

146216
/**
@@ -373,6 +443,8 @@ public static Class<?> toWiderPrimitiveType(Class<?> javaClass) {
373443
private final int maxScale;
374444
private final boolean nestedType;
375445

446+
private final byte binTag;
447+
376448
/**
377449
* Default constructor.
378450
*
@@ -404,6 +476,30 @@ public static Class<?> toWiderPrimitiveType(Class<?> javaClass) {
404476
this.minScale = minScale;
405477
this.maxScale = maxScale;
406478
this.nestedType = nestedType;
479+
this.binTag = -1;
480+
if (aliases == null || aliases.length == 0) {
481+
this.aliases = Collections.emptyList();
482+
} else {
483+
this.aliases = Collections.unmodifiableList(Arrays.asList(aliases));
484+
}
485+
}
486+
487+
ClickHouseDataType(Class<?> javaClass, boolean parameter, boolean caseSensitive, boolean signed, int byteLength,
488+
int maxPrecision, int defaultScale, int minScale, int maxScale, boolean nestedType, int binTag, String... aliases) {
489+
this.objectType = toObjectType(javaClass);
490+
this.widerObjectType = !signed ? toWiderObjectType(javaClass) : this.objectType;
491+
this.primitiveType = toPrimitiveType(javaClass);
492+
this.widerPrimitiveType = !signed ? toWiderPrimitiveType(javaClass) : this.primitiveType;
493+
this.parameter = parameter;
494+
this.caseSensitive = caseSensitive;
495+
this.signed = signed;
496+
this.byteLength = byteLength;
497+
this.maxPrecision = maxPrecision;
498+
this.defaultScale = defaultScale;
499+
this.minScale = minScale;
500+
this.maxScale = maxScale;
501+
this.nestedType = nestedType;
502+
this.binTag = (byte) binTag;
407503
if (aliases == null || aliases.length == 0) {
408504
this.aliases = Collections.emptyList();
409505
} else {
@@ -541,4 +637,12 @@ public int getMinScale() {
541637
public int getMaxScale() {
542638
return maxScale;
543639
}
640+
641+
/**
642+
* Returns a binary tag for the type
643+
* @return tag value
644+
*/
645+
public byte getBinTag() {
646+
return binTag;
647+
}
544648
}

0 commit comments

Comments
 (0)