diff --git a/e2e_test/batch/join/issue_7115.slt.part b/e2e_test/batch/join/issue_7115.slt.part index 85ce1682d7589..1d18c0b24a2a6 100644 --- a/e2e_test/batch/join/issue_7115.slt.part +++ b/e2e_test/batch/join/issue_7115.slt.part @@ -12,7 +12,7 @@ statement ok INSERT INTO t VALUES(1), (4), (6), (0), (5); query II -SELECT * FROM v JOIN (SELECT COUNT(*) FROM t) T; +SELECT * FROM v CROSS JOIN (SELECT COUNT(*) FROM t) T; ---- 5 5 diff --git a/e2e_test/streaming/join.slt b/e2e_test/streaming/join.slt index 8f50fac0eb729..b01d385dd52d9 100644 --- a/e2e_test/streaming/join.slt +++ b/e2e_test/streaming/join.slt @@ -179,7 +179,7 @@ statement ok create table t2 (uid int, name string); statement ok -create materialized view v as SELECT event, t1.name FROM t1 INNER JOIN t2 WHERE t1.name=t2.name AND t1.event=concat('event_', array_join(array[t2.uid, t1.item_id], '_')); +create materialized view v as SELECT event, t1.name FROM t1 INNER JOIN t2 ON t1.name=t2.name AND t1.event=concat('event_', array_join(array[t2.uid, t1.item_id], '_')); statement ok insert into t1 values (0, 0, 'event_0_0', 'a'), (1, NULL, 'event_1', 'b'), (2, 3, 'event_2_1', 'c'); diff --git a/src/frontend/planner_test/tests/testdata/batch_seq_scan.yaml b/src/frontend/planner_test/tests/testdata/batch_seq_scan.yaml index 7dd4c445a10ab..eff50c7152c86 100644 --- a/src/frontend/planner_test/tests/testdata/batch_seq_scan.yaml +++ b/src/frontend/planner_test/tests/testdata/batch_seq_scan.yaml @@ -5,7 +5,7 @@ create table t (id int); create materialized view v as select count(*) cnt from t; SET QUERY_MODE TO distributed; - select * from v join (select count(*) from t) T; + select * from v cross join (select count(*) from t) T; batch_plan: | BatchExchange { order: [], dist: Single } └─BatchNestedLoopJoin { type: Inner, predicate: true, output: all } diff --git a/src/frontend/planner_test/tests/testdata/join.yaml b/src/frontend/planner_test/tests/testdata/join.yaml index 318b7e28d4ced..bee2b0fbdde0a 100644 --- a/src/frontend/planner_test/tests/testdata/join.yaml +++ b/src/frontend/planner_test/tests/testdata/join.yaml @@ -218,7 +218,7 @@ create table t1 (v1 int, v2 int); create table t2 (v1 int, v2 int); create materialized view t3 as select v1, count(v2) as v2 from t2 group by v1; - select * from t1 join t3 where t1.v2 = t3.v1; + select * from t1 cross join t3 where t1.v2 = t3.v1; batch_local_plan: | BatchLookupJoin { type: Inner, predicate: t1.v2 = t3.v1, output: all } └─BatchExchange { order: [], dist: Single } @@ -288,7 +288,7 @@ - sql: | create table a(a1 int); create table b(b1 int); - select * from a join lateral (select * from b where a1 = b1); + select * from a cross join lateral (select * from b where a1 = b1); binder_error: |- Feature is not yet implemented: lateral subqueries are not yet supported Tracking issue: https://github.com/risingwavelabs/risingwave/issues/3815 @@ -541,7 +541,7 @@ create table t1 (v1 int, v2 int); create table t2 (v1 int, v2 int); create materialized view t3 as select v1, count(v2) as v2 from t2 group by v1; - select * from t1 join t3 where t1.v2 = t3.v1 and t3.v1 > 1; + select * from t1 cross join t3 where t1.v2 = t3.v1 and t3.v1 > 1; optimized_logical_plan: | LogicalJoin { type: Inner, on: (t1.v2 = t3.v1), output: all } ├─LogicalScan { table: t1, columns: [t1.v1, t1.v2], predicate: (t1.v2 > 1:Int32) } diff --git a/src/frontend/planner_test/tests/testdata/predicate_pushdown.yaml b/src/frontend/planner_test/tests/testdata/predicate_pushdown.yaml index 5431a9a1f8760..ff75c47bca61f 100644 --- a/src/frontend/planner_test/tests/testdata/predicate_pushdown.yaml +++ b/src/frontend/planner_test/tests/testdata/predicate_pushdown.yaml @@ -149,7 +149,7 @@ sql: | create table t1(v1 int, v2 int); create table t2(v3 int, v4 int); - with cte as (select * from t1 join t2) select * from cte where v1 is null AND v2 is null AND v3 is null AND v4 is null; + with cte as (select * from t1 cross join t2) select * from cte where v1 is null AND v2 is null AND v3 is null AND v4 is null; logical_plan: | LogicalProject { exprs: [t1.v1, t1.v2, t2.v3, t2.v4] } └─LogicalFilter { predicate: IsNull(t1.v1) AND IsNull(t1.v2) AND IsNull(t2.v3) AND IsNull(t2.v4) } @@ -256,7 +256,7 @@ sql: | create table t1(v1 timestamp with time zone); create table t2(v2 timestamp with time zone); - select * from t1 join t2 where v1 = v2 and v1 > now() + '1 hr'; + select * from t1 cross join t2 where v1 = v2 and v1 > now() + '1 hr'; optimized_logical_plan: | LogicalJoin { type: Inner, on: (t1.v1 = t2.v2), output: all } ├─LogicalFilter { predicate: (t1.v1 > (Now + '01:00:00':Interval)) } @@ -288,7 +288,7 @@ sql: | create table t1(v1 timestamp with time zone); create table t2(v2 timestamp with time zone, v3 interval); - select * from t1 join t2 where v1 = v2 and v1 > now() + v3; + select * from t1 cross join t2 where v1 = v2 and v1 > now() + v3; optimized_logical_plan: | LogicalFilter { predicate: (t1.v1 > (Now + t2.v3)) } └─LogicalJoin { type: Inner, on: (t1.v1 = t2.v2), output: all } @@ -314,7 +314,7 @@ sql: | create table t1(v1 int, v2 int); create table t2(v1 int, v2 int); - select * from t1 join t2 where t1.v1 = t2.v1 and t1.v1 > 1000; + select * from t1 cross join t2 where t1.v1 = t2.v1 and t1.v1 > 1000; optimized_logical_plan: | LogicalJoin { type: Inner, on: (t1.v1 = t2.v1), output: all } ├─LogicalScan { table: t1, columns: [t1.v1, t1.v2], predicate: (t1.v1 > 1000:Int32) } @@ -342,7 +342,7 @@ sql: | create table t1(v1 timestamp with time zone); create table t2(v2 timestamp with time zone); - select * from t1 join t2 where v1 = v2 and v1 > now(); + select * from t1 cross join t2 where v1 = v2 and v1 > now(); optimized_logical_plan: | LogicalJoin { type: Inner, on: (t1.v1 = t2.v2), output: all } ├─LogicalFilter { predicate: (t1.v1 > Now) } diff --git a/src/frontend/planner_test/tests/testdata/struct_field_access.yaml b/src/frontend/planner_test/tests/testdata/struct_field_access.yaml index da1fe76a6af81..f7e5e040a15ad 100644 --- a/src/frontend/planner_test/tests/testdata/struct_field_access.yaml +++ b/src/frontend/planner_test/tests/testdata/struct_field_access.yaml @@ -44,7 +44,7 @@ - sql: | create table t1(c STRUCT); create table t2(c STRUCT); - select (c).x from t1 join t2; + select (c).x from t1 cross join t2; binder_error: 'internal error: Ambiguous column name: c' - sql: | create table t1(c STRUCT); diff --git a/src/frontend/planner_test/tests/testdata/subquery.yaml b/src/frontend/planner_test/tests/testdata/subquery.yaml index 9ef343d766105..a5409528c62a2 100644 --- a/src/frontend/planner_test/tests/testdata/subquery.yaml +++ b/src/frontend/planner_test/tests/testdata/subquery.yaml @@ -94,7 +94,7 @@ binder_error: 'Item not found: Invalid column: x' - sql: | create table t(x int); - select * from t JOIN (select t.x) as t1; + select * from t CROSS JOIN (select t.x) as t1; binder_error: 'Item not found: Invalid column: x' - sql: | create table ab (a int, b int); diff --git a/src/sqlparser/src/parser.rs b/src/sqlparser/src/parser.rs index 19e22a9ad55f1..bca6c826a0cf7 100644 --- a/src/sqlparser/src/parser.rs +++ b/src/sqlparser/src/parser.rs @@ -3412,9 +3412,13 @@ impl Parser { }; let relation = self.parse_table_factor()?; let join_constraint = self.parse_join_constraint(natural)?; + let join_operator = join_operator_type(join_constraint); + if let JoinOperator::Inner(JoinConstraint::None) = join_operator { + return self.expected("join constraint after INNER JOIN", self.peek_token()); + } Join { relation, - join_operator: join_operator_type(join_constraint), + join_operator, } }; joins.push(join);