Skip to content

Commit 1f3484c

Browse files
committed
Remove redundent brackets for the join syntax (#649)
* remove redundant brackets * add relationship test for clickhouse * enable dynamic-query by default * fix checkstyle * fix dry plan test * remove redundant limit
1 parent 2f01c85 commit 1f3484c

File tree

7 files changed

+183
-20
lines changed

7 files changed

+183
-20
lines changed

ibis-server/tests/routers/ibis/test_clickhouse.py

+122-4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ def clickhouse(request) -> ClickHouseContainer:
4343
os.path.dirname(__file__), "../../resource/tpch/data/orders.parquet"
4444
)
4545
client.insert_df("orders", pd.read_parquet(data_path))
46+
client.command("""
47+
CREATE TABLE customer (
48+
c_custkey Int32,
49+
c_name String,
50+
c_address String,
51+
c_nationkey Int32,
52+
c_phone String,
53+
c_acctbal Decimal(15,2),
54+
c_mktsegment String,
55+
c_comment String
56+
)
57+
ENGINE = MergeTree
58+
ORDER BY (c_custkey)
59+
""")
60+
data_path = os.path.join(
61+
os.path.dirname(__file__), "../../resource/tpch/data/customer.parquet"
62+
)
63+
client.insert_df("customer", pd.read_parquet(data_path))
4664
request.addfinalizer(ch.stop)
4765
return ch
4866

@@ -87,9 +105,48 @@ class TestClickHouse:
87105
"expression": "toDateTime64('2024-01-01T23:59:59', 9, 'UTC')",
88106
"type": "timestamp",
89107
},
108+
{
109+
"name": "customer",
110+
"type": "Customer",
111+
"relationship": "OrdersCustomer",
112+
},
113+
{
114+
"name": "customer_name",
115+
"type": "varchar",
116+
"isCalculated": True,
117+
"expression": "customer.name",
118+
},
90119
],
91120
"primaryKey": "orderkey",
92-
}
121+
},
122+
{
123+
"name": "Customer",
124+
"refSql": "select * from test.customer",
125+
"columns": [
126+
{"name": "custkey", "expression": "c_custkey", "type": "integer"},
127+
{"name": "name", "expression": "c_name", "type": "varchar"},
128+
{
129+
"name": "orders",
130+
"type": "Orders",
131+
"relationship": "OrdersCustomer",
132+
},
133+
{
134+
"name": "totalprice",
135+
"type": "float",
136+
"isCalculated": True,
137+
"expression": "sum(orders.totalprice)",
138+
},
139+
],
140+
"primaryKey": "custkey",
141+
},
142+
],
143+
"relationships": [
144+
{
145+
"name": "OrdersCustomer",
146+
"models": ["Orders", "Customer"],
147+
"joinType": "MANY_TO_ONE",
148+
"condition": "Orders.custkey = Customer.custkey",
149+
},
93150
],
94151
}
95152

@@ -122,7 +179,7 @@ def test_query(self, clickhouse: ClickHouseContainer):
122179
)
123180
assert response.status_code == 200
124181
result = response.json()
125-
assert len(result["columns"]) == len(self.manifest["models"][0]["columns"])
182+
assert len(result["columns"]) == 9
126183
assert len(result["data"]) == 1
127184
assert result["data"][0] == [
128185
1,
@@ -133,6 +190,7 @@ def test_query(self, clickhouse: ClickHouseContainer):
133190
"1_370",
134191
1704153599000,
135192
1704153599000,
193+
"Customer#000000370",
136194
]
137195
assert result["dtypes"] == {
138196
"orderkey": "int32",
@@ -143,6 +201,7 @@ def test_query(self, clickhouse: ClickHouseContainer):
143201
"order_cust_key": "object",
144202
"timestamp": "datetime64[ns]",
145203
"timestamptz": "datetime64[ns, UTC]",
204+
"customer_name": "object",
146205
}
147206

148207
def test_query_with_connection_url(self, clickhouse: ClickHouseContainer):
@@ -157,7 +216,7 @@ def test_query_with_connection_url(self, clickhouse: ClickHouseContainer):
157216
)
158217
assert response.status_code == 200
159218
result = response.json()
160-
assert len(result["columns"]) == len(self.manifest["models"][0]["columns"])
219+
assert len(result["columns"]) == 9
161220
assert len(result["data"]) == 1
162221
assert result["data"][0][0] == 1
163222
assert result["dtypes"] is not None
@@ -180,7 +239,7 @@ def test_query_with_column_dtypes(self, clickhouse: ClickHouseContainer):
180239
)
181240
assert response.status_code == 200
182241
result = response.json()
183-
assert len(result["columns"]) == len(self.manifest["models"][0]["columns"])
242+
assert len(result["columns"]) == 9
184243
assert len(result["data"]) == 1
185244
assert result["data"][0] == [
186245
1,
@@ -191,6 +250,7 @@ def test_query_with_column_dtypes(self, clickhouse: ClickHouseContainer):
191250
"1_370",
192251
"2024-01-01 23:59:59.000000",
193252
"2024-01-01 23:59:59.000000 UTC",
253+
"Customer#000000370",
194254
]
195255
assert result["dtypes"] == {
196256
"orderkey": "int32",
@@ -201,6 +261,7 @@ def test_query_with_column_dtypes(self, clickhouse: ClickHouseContainer):
201261
"order_cust_key": "object",
202262
"timestamp": "object",
203263
"timestamptz": "object",
264+
"customer_name": "object",
204265
}
205266

206267
def test_query_with_limit(self, clickhouse: ClickHouseContainer):
@@ -231,6 +292,63 @@ def test_query_with_limit(self, clickhouse: ClickHouseContainer):
231292
result = response.json()
232293
assert len(result["data"]) == 1
233294

295+
def test_query_join(self, clickhouse: ClickHouseContainer):
296+
connection_info = self.to_connection_info(clickhouse)
297+
response = client.post(
298+
url=f"{self.base_url}/query",
299+
json={
300+
"connectionInfo": connection_info,
301+
"manifestStr": self.manifest_str,
302+
"sql": 'SELECT name as customer_name FROM "Orders" join "Customer" on "Orders".custkey = "Customer".custkey WHERE custkey = 370 LIMIT 1',
303+
},
304+
)
305+
assert response.status_code == 200
306+
result = response.json()
307+
assert len(result["columns"]) == 1
308+
assert len(result["data"]) == 1
309+
assert result["data"][0] == ["Customer#000000370"]
310+
assert result["dtypes"] == {
311+
"customer_name": "object",
312+
}
313+
314+
def test_query_to_one_relationship(self, clickhouse: ClickHouseContainer):
315+
connection_info = self.to_connection_info(clickhouse)
316+
response = client.post(
317+
url=f"{self.base_url}/query",
318+
json={
319+
"connectionInfo": connection_info,
320+
"manifestStr": self.manifest_str,
321+
"sql": 'SELECT customer_name FROM "Orders" where custkey = 370 LIMIT 1',
322+
},
323+
)
324+
assert response.status_code == 200
325+
result = response.json()
326+
assert len(result["columns"]) == 1
327+
assert len(result["data"]) == 1
328+
assert result["data"][0] == ["Customer#000000370"]
329+
assert result["dtypes"] == {
330+
"customer_name": "object",
331+
}
332+
333+
def test_query_to_many_relationship(self, clickhouse: ClickHouseContainer):
334+
connection_info = self.to_connection_info(clickhouse)
335+
response = client.post(
336+
url=f"{self.base_url}/query",
337+
json={
338+
"connectionInfo": connection_info,
339+
"manifestStr": self.manifest_str,
340+
"sql": 'SELECT totalprice FROM "Customer" where custkey = 370 LIMIT 1',
341+
},
342+
)
343+
assert response.status_code == 200
344+
result = response.json()
345+
assert len(result["columns"]) == 1
346+
assert len(result["data"]) == 1
347+
assert result["data"][0] == [2860895.79]
348+
assert result["dtypes"] == {
349+
"totalprice": "object",
350+
}
351+
234352
def test_query_without_manifest(self, clickhouse: ClickHouseContainer):
235353
connection_info = self.to_connection_info(clickhouse)
236354
response = client.post(

trino-parser/src/main/java/io/trino/sql/SqlFormatter.java

-7
Original file line numberDiff line numberDiff line change
@@ -562,9 +562,6 @@ protected Void visitJoin(Join node, Integer indent)
562562
type = "NATURAL " + type;
563563
}
564564

565-
if (node.getType() != Join.Type.IMPLICIT) {
566-
builder.append('(');
567-
}
568565
process(node.getLeft(), indent);
569566

570567
builder.append('\n');
@@ -594,10 +591,6 @@ else if (!(criteria instanceof NaturalJoin)) {
594591
}
595592
}
596593

597-
if (node.getType() != Join.Type.IMPLICIT) {
598-
builder.append(")");
599-
}
600-
601594
return null;
602595
}
603596

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
15+
package io.trino.sql;
16+
17+
import io.trino.sql.parser.ParsingOptions;
18+
import io.trino.sql.parser.SqlParser;
19+
import org.junit.jupiter.api.Test;
20+
21+
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
23+
public class TestSqlFormatter
24+
{
25+
private static final SqlParser SQL_PARSER = new SqlParser();
26+
27+
@Test
28+
public void testFormatJoin()
29+
{
30+
String sql = "SELECT * FROM a JOIN b ON a.x = b.y";
31+
String formattedSql = SqlFormatter.formatSql(SQL_PARSER.createStatement(sql, new ParsingOptions()));
32+
assertEquals("""
33+
SELECT *
34+
FROM
35+
a
36+
INNER JOIN b ON (a.x = b.y)
37+
""", formattedSql);
38+
39+
sql = "SELECT * FROM a JOIN b ON a.x = b.y JOIN c ON a.x = c.z";
40+
formattedSql = SqlFormatter.formatSql(SQL_PARSER.createStatement(sql, new ParsingOptions()));
41+
assertEquals("""
42+
SELECT *
43+
FROM
44+
a
45+
INNER JOIN b ON (a.x = b.y)
46+
INNER JOIN c ON (a.x = c.z)
47+
""", formattedSql);
48+
}
49+
}

wren-base/src/main/java/io/wren/base/config/WrenConfig.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public enum DataSourceType
3737

3838
private File wrenMDLDirectory = new File("etc/mdl");
3939
private DataSourceType dataSourceType = DataSourceType.DUCKDB_BACKEND;
40-
private boolean enableDynamicFields;
40+
private boolean enableDynamicFields = true;
4141
private String wrenWebUrl = "http://localhost:3000";
4242

4343
@NotNull

wren-main/src/main/java/io/wren/main/PreviewService.java

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import com.google.common.collect.Streams;
3232
import com.google.inject.Inject;
33+
import io.airlift.log.Logger;
3334
import io.wren.base.AnalyzedMDL;
3435
import io.wren.base.Column;
3536
import io.wren.base.ConnectorRecordIterator;
@@ -50,6 +51,7 @@
5051

5152
public class PreviewService
5253
{
54+
private static final Logger LOG = Logger.get(PreviewService.class);
5355
private final Metadata metadata;
5456

5557
private final SqlConverter sqlConverter;
@@ -101,6 +103,7 @@ public CompletableFuture<String> dryPlan(WrenMDL mdl, String sql, boolean isMode
101103

102104
String planned = WrenPlanner.rewrite(sql, sessionContext, new AnalyzedMDL(mdl, null));
103105
if (isModelingOnly) {
106+
LOG.info("Planned SQL: %s", planned);
104107
return planned;
105108
}
106109
return sqlConverter.convert(planned, sessionContext);

wren-tests/src/test/java/io/wren/testing/TestMDLResource.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ public void testDryRunAndDryPlan()
223223
, "Orders"."custkey" "custkey"
224224
, "Orders_relationsub"."customer_name" "customer_name"
225225
FROM
226-
((
226+
(
227227
SELECT
228228
"Orders"."orderkey" "orderkey"
229229
, "Orders"."custkey" "custkey"
@@ -245,7 +245,7 @@ LEFT JOIN (
245245
"Orders"."orderkey"
246246
, "Customer"."name" "customer_name"
247247
FROM
248-
((
248+
(
249249
SELECT
250250
o_orderkey "orderkey"
251251
, o_custkey "custkey"
@@ -256,8 +256,8 @@ LEFT JOIN (
256256
tpch.orders
257257
) "Orders"
258258
) "Orders"
259-
LEFT JOIN "Customer" ON ("Customer"."custkey" = "Orders"."custkey"))
260-
) "Orders_relationsub" ON ("Orders"."orderkey" = "Orders_relationsub"."orderkey"))
259+
LEFT JOIN "Customer" ON ("Customer"."custkey" = "Orders"."custkey")
260+
) "Orders_relationsub" ON ("Orders"."orderkey" = "Orders_relationsub"."orderkey")
261261
)\s
262262
SELECT customer_name
263263
FROM

wren-tests/src/test/java/io/wren/testing/TestMDLResourceV2.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ public void testDryPlan()
229229
, "Orders"."custkey" "custkey"
230230
, "Orders_relationsub"."customer_name" "customer_name"
231231
FROM
232-
((
232+
(
233233
SELECT
234234
"Orders"."orderkey" "orderkey"
235235
, "Orders"."custkey" "custkey"
@@ -251,7 +251,7 @@ LEFT JOIN (
251251
"Orders"."orderkey"
252252
, "Customer"."name" "customer_name"
253253
FROM
254-
((
254+
(
255255
SELECT
256256
o_orderkey "orderkey"
257257
, o_custkey "custkey"
@@ -262,8 +262,8 @@ LEFT JOIN (
262262
tpch.orders
263263
) "Orders"
264264
) "Orders"
265-
LEFT JOIN "Customer" ON ("Customer"."custkey" = "Orders"."custkey"))
266-
) "Orders_relationsub" ON ("Orders"."orderkey" = "Orders_relationsub"."orderkey"))
265+
LEFT JOIN "Customer" ON ("Customer"."custkey" = "Orders"."custkey")
266+
) "Orders_relationsub" ON ("Orders"."orderkey" = "Orders_relationsub"."orderkey")
267267
)\s
268268
SELECT customer_name
269269
FROM

0 commit comments

Comments
 (0)