|
37 | 37 |
|
38 | 38 | import java.io.Serializable; |
39 | 39 | import java.lang.reflect.Array; |
40 | | -import java.math.BigInteger; |
41 | 40 | import java.time.OffsetDateTime; |
42 | 41 | import java.util.ArrayList; |
43 | 42 | import java.util.Arrays; |
44 | | -import java.util.Collection; |
45 | 43 | import java.util.Collections; |
46 | 44 | import java.util.Comparator; |
47 | 45 | import java.util.HashMap; |
@@ -507,19 +505,19 @@ protected static int readColumn(String args, int startIndex, int len, String nam |
507 | 505 | } |
508 | 506 | } else if (args.startsWith(KEYWORD_JSON, i)) { |
509 | 507 | int index = args.indexOf('(', i + KEYWORD_JSON.length()); |
510 | | - if (index < i) { |
511 | | - throw new IllegalArgumentException(ERROR_MISSING_NESTED_TYPE); |
512 | | - } |
513 | | - i = ClickHouseUtils.skipBrackets(args, index, len, '('); |
514 | | - String originalTypeName = args.substring(startIndex, i); |
515 | | - List<ClickHouseColumn> nestedColumns = parse(args.substring(index + 1, i - 1)); |
516 | | - if (nestedColumns.isEmpty()) { |
517 | | - throw new IllegalArgumentException("Nested should have at least one nested column"); |
| 508 | + if (index > i) { |
| 509 | + i = ClickHouseUtils.skipBrackets(args, index, len, '('); |
| 510 | + String originalTypeName = args.substring(startIndex, i); |
| 511 | + List<String> params = new ArrayList<>(); |
| 512 | + List<ClickHouseColumn> nestedColumns = new ArrayList<>(); |
| 513 | + List<String> parameters = new ArrayList<>(); |
| 514 | + parseJSONColumn(args.substring(index + 1, i - 1), nestedColumns, parameters); |
| 515 | + nestedColumns.sort(Comparator.comparing(o -> o.getDataType().name())); |
| 516 | + column = new ClickHouseColumn(ClickHouseDataType.JSON, name, originalTypeName, nullable, lowCardinality, |
| 517 | + parameters, nestedColumns); |
| 518 | + fixedLength = false; |
| 519 | + estimatedLength++; |
518 | 520 | } |
519 | | - column = new ClickHouseColumn(ClickHouseDataType.JSON, name, originalTypeName, nullable, lowCardinality, |
520 | | - null, nestedColumns); |
521 | | - fixedLength = false; |
522 | | - estimatedLength++; |
523 | 521 | } |
524 | 522 |
|
525 | 523 | if (column == null) { |
@@ -674,6 +672,48 @@ public static List<ClickHouseColumn> parse(String args) { |
674 | 672 | return Collections.unmodifiableList(c); |
675 | 673 | } |
676 | 674 |
|
| 675 | + public static final String JSON_MAX_PATHS_PARAM = "max_dynamic_paths"; |
| 676 | + public static final String JSON_MAX_DYN_TYPES_PARAM = "max_dynamic_types"; |
| 677 | + public static final String JSON_SKIP_MARKER = "SKIP"; |
| 678 | + |
| 679 | + public static void parseJSONColumn(String args, List<ClickHouseColumn> nestedColumns, List<String> parameters) { |
| 680 | + if (args == null || args.isEmpty()) { |
| 681 | + return; |
| 682 | + } |
| 683 | + |
| 684 | + String name = null; |
| 685 | + ClickHouseColumn column = null; |
| 686 | + StringBuilder builder = new StringBuilder(); |
| 687 | + for (int i = 0, len = args.length(); i < len; i++) { |
| 688 | + char ch = args.charAt(i); |
| 689 | + if (Character.isWhitespace(ch)) { |
| 690 | + continue; |
| 691 | + } |
| 692 | + |
| 693 | + if (name == null) { // column name |
| 694 | + i = ClickHouseUtils.readNameOrQuotedString(args, i, len, builder) - 1; |
| 695 | + name = builder.toString(); |
| 696 | + if (name.startsWith(JSON_SKIP_MARKER)) { |
| 697 | + name = null; // skip parameters |
| 698 | + i = ClickHouseUtils.skipContentsUntil(args, i, len, ',') - 1; |
| 699 | + } else if ( name.startsWith(JSON_MAX_PATHS_PARAM) || name.startsWith(JSON_MAX_DYN_TYPES_PARAM)) { |
| 700 | + parameters.add(name); |
| 701 | + name = null; |
| 702 | + i = ClickHouseUtils.skipContentsUntil(args, i, len, ',') - 1; |
| 703 | + } |
| 704 | + builder.setLength(0); |
| 705 | + } else if (column == null) { // now type |
| 706 | + LinkedList<ClickHouseColumn> colList = new LinkedList<>(); |
| 707 | + i = readColumn(args, i, len, name, colList) - 1; |
| 708 | + nestedColumns.add(column = colList.getFirst()); |
| 709 | + } else { // prepare for next column |
| 710 | + i = ClickHouseUtils.skipContentsUntil(args, i, len, ',') - 1; |
| 711 | + name = null; |
| 712 | + column = null; |
| 713 | + } |
| 714 | + } |
| 715 | + } |
| 716 | + |
677 | 717 | public ClickHouseColumn(ClickHouseDataType dataType, String columnName, String originalTypeName, boolean nullable, |
678 | 718 | boolean lowCardinality, List<String> parameters, List<ClickHouseColumn> nestedColumns) { |
679 | 719 | this(dataType, columnName, originalTypeName, nullable, lowCardinality, parameters, nestedColumns, ClickHouseEnum.EMPTY); |
|
0 commit comments