Skip to content

Commit 7e3c046

Browse files
authored
[feature][dinky-metadata-paimon]support query statement for paimon (#4355)
1 parent e85f163 commit 7e3c046

11 files changed

Lines changed: 1333 additions & 6 deletions

File tree

dinky-admin/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@
279279
<dependency>
280280
<groupId>com.github.jsqlparser</groupId>
281281
<artifactId>jsqlparser</artifactId>
282-
<version>4.9</version>
282+
<version>${jsqlparser.version}</version>
283283
</dependency>
284284
<!-- for cache-->
285285
<dependency>

dinky-common/src/main/java/org/dinky/data/model/QueryData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public class QueryData {
6060

6161
@Data
6262
@ApiModel(value = "Option", description = "Options for customizing a SQL query")
63-
public class Option {
63+
public static class Option {
6464

6565
@ApiModelProperty(
6666
value = "WHERE clause for the query",

dinky-metadata/dinky-metadata-base/src/main/java/org/dinky/metadata/utils/DateTimeUtils.java

Lines changed: 339 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/*
2+
*
3+
* Licensed to the Apache Software Foundation (ASF) under one or more
4+
* contributor license agreements. See the NOTICE file distributed with
5+
* this work for additional information regarding copyright ownership.
6+
* The ASF licenses this file to You under the Apache License, Version 2.0
7+
* (the "License"); you may not use this file except in compliance with
8+
* the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
*/
19+
20+
package org.dinky.metadata.utils;
21+
22+
import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE;
23+
import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME;
24+
import static java.time.format.DateTimeFormatter.ISO_OFFSET_TIME;
25+
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
26+
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
27+
import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
28+
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
29+
import static java.time.temporal.ChronoField.NANO_OF_SECOND;
30+
import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
31+
import static java.time.temporal.ChronoField.YEAR;
32+
33+
import java.time.LocalDate;
34+
import java.time.format.DateTimeFormatter;
35+
import java.time.format.DateTimeFormatterBuilder;
36+
import java.time.format.SignStyle;
37+
import java.util.HashMap;
38+
import java.util.Map;
39+
import java.util.regex.Pattern;
40+
41+
public class DateUtils {
42+
private static final Map<Formatter, DateTimeFormatter> FORMATTER_MAP = new HashMap<>();
43+
44+
static {
45+
FORMATTER_MAP.put(Formatter.YYYY_MM_DD, DateTimeFormatter.ofPattern(Formatter.YYYY_MM_DD.value));
46+
FORMATTER_MAP.put(Formatter.YYYY_MM_DD_SPOT, DateTimeFormatter.ofPattern(Formatter.YYYY_MM_DD_SPOT.value));
47+
FORMATTER_MAP.put(Formatter.YYYY_MM_DD_SLASH, DateTimeFormatter.ofPattern(Formatter.YYYY_MM_DD_SLASH.value));
48+
}
49+
50+
public static final Pattern[] PATTERN_ARRAY = new Pattern[] {
51+
Pattern.compile("\\d{4}-\\d{2}-\\d{2}"),
52+
Pattern.compile("\\d{4}年\\d{2}月\\d{2}日"),
53+
Pattern.compile("\\d{4}/\\d{2}/\\d{2}"),
54+
Pattern.compile("\\d{4}\\.\\d{2}\\.\\d{2}"),
55+
Pattern.compile("\\d{8}"),
56+
Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?Z"),
57+
Pattern.compile("\\d{2}:\\d{2}:\\d{2}\\+\\d{2}:\\d{2}"),
58+
Pattern.compile("\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?"),
59+
Pattern.compile("\\d{4}/\\d{1,2}/\\d{1,2}")
60+
};
61+
62+
public static final Map<Pattern, DateTimeFormatter> DATE_FORMATTER_MAP = new HashMap();
63+
64+
static {
65+
DATE_FORMATTER_MAP.put(
66+
PATTERN_ARRAY[0],
67+
new DateTimeFormatterBuilder()
68+
.parseCaseInsensitive()
69+
.append(DateTimeFormatter.ISO_LOCAL_DATE)
70+
.toFormatter());
71+
72+
DATE_FORMATTER_MAP.put(
73+
PATTERN_ARRAY[1],
74+
new DateTimeFormatterBuilder()
75+
.parseCaseInsensitive()
76+
.append(new DateTimeFormatterBuilder()
77+
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
78+
.appendLiteral("年")
79+
.appendValue(MONTH_OF_YEAR, 2)
80+
.appendLiteral("月")
81+
.appendValue(DAY_OF_MONTH, 2)
82+
.appendLiteral("日")
83+
.toFormatter())
84+
.toFormatter());
85+
86+
DATE_FORMATTER_MAP.put(
87+
PATTERN_ARRAY[2],
88+
new DateTimeFormatterBuilder()
89+
.parseCaseInsensitive()
90+
.append(new DateTimeFormatterBuilder()
91+
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
92+
.appendLiteral('/')
93+
.appendValue(MONTH_OF_YEAR, 2)
94+
.appendLiteral('/')
95+
.appendValue(DAY_OF_MONTH, 2)
96+
.toFormatter())
97+
.toFormatter());
98+
99+
DATE_FORMATTER_MAP.put(
100+
PATTERN_ARRAY[3],
101+
new DateTimeFormatterBuilder()
102+
.parseCaseInsensitive()
103+
.append(new DateTimeFormatterBuilder()
104+
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
105+
.appendLiteral('.')
106+
.appendValue(MONTH_OF_YEAR, 2)
107+
.appendLiteral('.')
108+
.appendValue(DAY_OF_MONTH, 2)
109+
.toFormatter())
110+
.toFormatter());
111+
112+
DATE_FORMATTER_MAP.put(
113+
PATTERN_ARRAY[4],
114+
new DateTimeFormatterBuilder()
115+
.parseCaseInsensitive()
116+
.append(new DateTimeFormatterBuilder()
117+
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
118+
.appendValue(MONTH_OF_YEAR, 2)
119+
.appendValue(DAY_OF_MONTH, 2)
120+
.toFormatter())
121+
.toFormatter());
122+
DATE_FORMATTER_MAP.put(
123+
PATTERN_ARRAY[5],
124+
new DateTimeFormatterBuilder()
125+
.parseCaseInsensitive()
126+
.append(ISO_LOCAL_DATE)
127+
.appendLiteral('T')
128+
.append(new DateTimeFormatterBuilder()
129+
.appendValue(HOUR_OF_DAY, 2)
130+
.appendLiteral(':')
131+
.appendValue(MINUTE_OF_HOUR, 2)
132+
.optionalStart()
133+
.appendLiteral(':')
134+
.appendValue(SECOND_OF_MINUTE, 2)
135+
.optionalStart()
136+
.appendFraction(NANO_OF_SECOND, 0, 9, true)
137+
.appendLiteral('Z')
138+
.toFormatter())
139+
.toFormatter());
140+
DATE_FORMATTER_MAP.put(PATTERN_ARRAY[6], ISO_OFFSET_TIME);
141+
DATE_FORMATTER_MAP.put(PATTERN_ARRAY[7], ISO_LOCAL_TIME);
142+
DATE_FORMATTER_MAP.put(
143+
PATTERN_ARRAY[8],
144+
new DateTimeFormatterBuilder()
145+
.parseCaseInsensitive()
146+
.append(DateTimeFormatter.ofPattern("yyyy/M/d"))
147+
.toFormatter());
148+
}
149+
150+
/**
151+
* gave a date string and return the {@link DateTimeFormatter} which can be used to parse it.
152+
*
153+
* @param dateTime eg: 2020-02-03
154+
* @return the DateTimeFormatter matched, will return null when not matched any pattern in
155+
* {@link #PATTERN_ARRAY}
156+
*/
157+
public static DateTimeFormatter matchDateFormatter(String dateTime) {
158+
for (int j = 0; j < PATTERN_ARRAY.length; j++) {
159+
if (PATTERN_ARRAY[j].matcher(dateTime).matches()) {
160+
return DATE_FORMATTER_MAP.get(PATTERN_ARRAY[j]);
161+
}
162+
}
163+
return null;
164+
}
165+
166+
public static LocalDate parse(String date) {
167+
DateTimeFormatter dateTimeFormatter = matchDateFormatter(date);
168+
return parse(date, dateTimeFormatter);
169+
}
170+
171+
public static LocalDate parse(String date, DateTimeFormatter dateTimeFormatter) {
172+
return LocalDate.parse(date, dateTimeFormatter);
173+
}
174+
175+
public static LocalDate parse(String date, Formatter formatter) {
176+
return LocalDate.parse(date, FORMATTER_MAP.get(formatter));
177+
}
178+
179+
public static String toString(LocalDate date, Formatter formatter) {
180+
return date.format(FORMATTER_MAP.get(formatter));
181+
}
182+
183+
public enum Formatter {
184+
YYYY_MM_DD("yyyy-MM-dd"),
185+
YYYY_M_D("yyyy/M/d"),
186+
YYYY_MM_DD_SPOT("yyyy.MM.dd"),
187+
YYYY_MM_DD_SLASH("yyyy/MM/dd");
188+
private final String value;
189+
190+
Formatter(String value) {
191+
this.value = value;
192+
}
193+
194+
public String getValue() {
195+
return value;
196+
}
197+
198+
public static Formatter parse(String format) {
199+
Formatter[] formatters = Formatter.values();
200+
for (Formatter formatter : formatters) {
201+
if (formatter.getValue().equals(format)) {
202+
return formatter;
203+
}
204+
}
205+
String errorMsg = String.format("Illegal format [%s]", format);
206+
throw new IllegalArgumentException(errorMsg);
207+
}
208+
}
209+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
*
3+
* Licensed to the Apache Software Foundation (ASF) under one or more
4+
* contributor license agreements. See the NOTICE file distributed with
5+
* this work for additional information regarding copyright ownership.
6+
* The ASF licenses this file to You under the Apache License, Version 2.0
7+
* (the "License"); you may not use this file except in compliance with
8+
* the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
*/
19+
20+
package org.dinky.metadata.utils;
21+
22+
import java.time.LocalTime;
23+
import java.time.format.DateTimeFormatter;
24+
import java.util.HashMap;
25+
import java.util.Map;
26+
import java.util.regex.Pattern;
27+
28+
public class TimeUtils {
29+
private static final Map<Formatter, DateTimeFormatter> FORMATTER_MAP = new HashMap<Formatter, DateTimeFormatter>();
30+
31+
static {
32+
FORMATTER_MAP.put(Formatter.HH_MM_SS, DateTimeFormatter.ofPattern(Formatter.HH_MM_SS.value));
33+
FORMATTER_MAP.put(Formatter.HH_MM_SS_SSS, DateTimeFormatter.ofPattern(Formatter.HH_MM_SS_SSS.value));
34+
}
35+
36+
public static LocalTime parse(String time, Formatter formatter) {
37+
return LocalTime.parse(time, FORMATTER_MAP.get(formatter));
38+
}
39+
40+
public static LocalTime parse(String dateTime) {
41+
return LocalTime.parse(dateTime, FORMATTER_MAP.get(matchTimeFormatter(dateTime)));
42+
}
43+
44+
public static final Pattern[] PATTERN_ARRAY = new Pattern[] {
45+
Pattern.compile("\\d{2}:\\d{2}:\\d{2}"), Pattern.compile("\\d{2}:\\d{2}:\\d{2}.\\d{3}"),
46+
};
47+
48+
public static Formatter matchTimeFormatter(String dateTime) {
49+
for (int j = 0; j < PATTERN_ARRAY.length; j++) {
50+
if (PATTERN_ARRAY[j].matcher(dateTime).matches()) {
51+
Formatter dateTimeFormatter = Time_FORMATTER_MAP.get(PATTERN_ARRAY[j]);
52+
return dateTimeFormatter;
53+
}
54+
}
55+
return null;
56+
}
57+
58+
public static final Map<Pattern, Formatter> Time_FORMATTER_MAP = new HashMap();
59+
60+
static {
61+
Time_FORMATTER_MAP.put(PATTERN_ARRAY[0], Formatter.parse(Formatter.HH_MM_SS.value));
62+
Time_FORMATTER_MAP.put(PATTERN_ARRAY[1], Formatter.parse(Formatter.HH_MM_SS_SSS.value));
63+
}
64+
65+
public static String toString(LocalTime time, Formatter formatter) {
66+
return time.format(FORMATTER_MAP.get(formatter));
67+
}
68+
69+
public enum Formatter {
70+
HH_MM_SS("HH:mm:ss"),
71+
HH_MM_SS_SSS("HH:mm:ss.SSS");
72+
private final String value;
73+
74+
Formatter(String value) {
75+
this.value = value;
76+
}
77+
78+
public String getValue() {
79+
return value;
80+
}
81+
82+
public static Formatter parse(String format) {
83+
Formatter[] formatters = Formatter.values();
84+
for (Formatter formatter : formatters) {
85+
if (formatter.getValue().equals(format)) {
86+
return formatter;
87+
}
88+
}
89+
String errorMsg = String.format("Illegal format [%s]", format);
90+
throw new IllegalArgumentException(errorMsg);
91+
}
92+
}
93+
}

dinky-metadata/dinky-metadata-paimon/pom.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<groupId>org.dinky</groupId>
3636
<artifactId>dinky-metadata-base</artifactId>
3737
</dependency>
38+
3839
<!-- https://mvnrepository.com/artifact/org.apache.paimon/paimon-bundle -->
3940
<dependency>
4041
<groupId>org.apache.paimon</groupId>
@@ -50,6 +51,18 @@
5051
<scope>${scope.runtime}</scope>
5152
</dependency>
5253

54+
<dependency>
55+
<groupId>org.dinky</groupId>
56+
<artifactId>dinky-client-hadoop</artifactId>
57+
<scope>${scope.runtime}</scope>
58+
</dependency>
59+
60+
<dependency>
61+
<groupId>com.github.jsqlparser</groupId>
62+
<artifactId>jsqlparser</artifactId>
63+
<version>${jsqlparser.version}</version>
64+
</dependency>
65+
5366
<!-- test dependencies -->
5467
<dependency>
5568
<groupId>org.junit.jupiter</groupId>

0 commit comments

Comments
 (0)