Skip to content

Commit 2c7bf77

Browse files
committed
Fix issue when parsing multi-word data type
1 parent 753e67f commit 2c7bf77

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseColumn.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -321,16 +321,18 @@ protected static int readColumn(String args, int startIndex, int len, String nam
321321
StringBuilder sb = new StringBuilder();
322322
i = ClickHouseUtils.readNameOrQuotedString(args, i, len, sb);
323323
String modifier = sb.toString();
324+
String normalizedModifier = modifier.toUpperCase();
324325
sb.setLength(0);
325326
boolean startsWithNot = false;
326-
if ("not".equalsIgnoreCase(modifier)) {
327+
if ("NOT".equals(normalizedModifier)) {
327328
startsWithNot = true;
328329
i = ClickHouseUtils.readNameOrQuotedString(args, i, len, sb);
329330
modifier = sb.toString();
331+
normalizedModifier = modifier.toUpperCase();
330332
sb.setLength(0);
331333
}
332334

333-
if ("null".equalsIgnoreCase(modifier)) {
335+
if ("NULL".equals(normalizedModifier)) {
334336
if (nullable) {
335337
throw new IllegalArgumentException("Nullable and NULL cannot be used together");
336338
}
@@ -339,14 +341,14 @@ protected static int readColumn(String args, int startIndex, int len, String nam
339341
break;
340342
} else if (startsWithNot) {
341343
throw new IllegalArgumentException("Expect keyword NULL after NOT");
342-
} else if ("alias".equalsIgnoreCase(modifier) || "codec".equalsIgnoreCase(modifier)
343-
|| "default".equalsIgnoreCase(modifier) || "materialized".equalsIgnoreCase(modifier)
344-
|| "ttl".equalsIgnoreCase(modifier)) { // stop words
344+
} else if ("ALIAS".equals(normalizedModifier) || "CODEC".equals(normalizedModifier)
345+
|| "DEFAULT".equals(normalizedModifier) || "MATERIALIZED".equals(normalizedModifier)
346+
|| "TTL".equals(normalizedModifier)) { // stop words
345347
i = ClickHouseUtils.skipContentsUntil(args, i, len, ',') - 1;
346348
break;
347349
} else {
348350
if ((name == null || name.isEmpty())
349-
&& !ClickHouseDataType.mayStartWith(builder.toString())) {
351+
&& !ClickHouseDataType.mayStartWith(builder.toString(), normalizedModifier)) {
350352
return readColumn(args, i - modifier.length(), len, builder.toString(), list);
351353
} else {
352354
builder.append(' ');

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

+13-7
Original file line numberDiff line numberDiff line change
@@ -181,19 +181,25 @@ public static List<String> match(String part) {
181181
}
182182

183183
/**
184-
* Checks if any alias uses the given prefix.
184+
* Checks if any alias uses the given prefixes.
185185
*
186-
* @param prefix prefix to check
187-
* @return true if any alias using the given prefix; false otherwise
186+
* @param prefixes prefixes to check
187+
* @return true if any alias using the given prefixes; false otherwise
188188
*/
189-
public static boolean mayStartWith(String prefix) {
190-
if (prefix == null || prefix.isEmpty()) {
189+
public static boolean mayStartWith(String... prefixes) {
190+
if (prefixes == null || prefixes.length == 0) {
191191
return false;
192192
}
193193

194-
prefix = prefix.toUpperCase();
194+
StringBuilder builder = new StringBuilder();
195+
for (int i = 0, len = prefixes.length; i < len; i++) {
196+
builder.append(prefixes[i].toUpperCase()).append(' ');
197+
}
198+
String prefix = builder.toString();
199+
builder.setLength(builder.length() - 1);
200+
String typeName = builder.toString();
195201
for (String alias : allAliases) {
196-
if (alias.startsWith(prefix)) {
202+
if (alias.startsWith(prefix) || alias.equals(typeName)) {
197203
return true;
198204
}
199205
}

clickhouse-client/src/test/java/com/clickhouse/client/ClickHouseColumnTest.java

+8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ private Object[][] getEnumTypes() {
1717
@DataProvider(name = "objectTypesProvider")
1818
private Object[][] getObjectTypes() {
1919
return new Object[][] {
20+
{ "Tuple(not NChar Large Object)" },
21+
{ "nchar Large Object" },
22+
{ "Tuple(int Int32)" },
23+
{ "a Tuple(i Int32)" },
24+
{ "b Tuple(i1 Int32)" },
25+
{ "Tuple(i Int32)" },
26+
{ "Tuple(i1 Int32)" },
27+
{ "Tuple(i Int32, a Array(Int32), m Map(LowCardinality(String), Int32))" },
2028
{ "Int8" }, { "TINYINT SIGNED" },
2129
{ "k1 Int8" }, { "k1 TINYINT SIGNED" },
2230
{ "k1 Nullable(Int8)" }, { "k1 Nullable( Int8 )" }, { "k1 TINYINT SIGNED null" },

0 commit comments

Comments
 (0)