diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlConformance.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlConformance.java index 821d87d5b29cb..e775724be1815 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlConformance.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlConformance.java @@ -50,4 +50,9 @@ public class IgniteSqlConformance extends SqlAbstractConformance { @Override public boolean allowNiladicParentheses() { return true; } + + /** {@inheritDoc} */ + @Override public boolean isApplyAllowed() { + return true; + } } diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java index 569420c7401b5..320a69c2b744b 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java @@ -162,6 +162,24 @@ public void testSystemFunctionOverriding() throws Exception { assertEquals(1, dfltSchema.getFunctions("PLUS").size()); } + /** */ + @Test + public void testApplyTableFunction() { + assertQuery("SELECT v.a, r.x FROM (VALUES (1), (2)) v(a) " + + "CROSS APPLY TABLE(system_range(1, v.a)) r ORDER BY v.a, r.x") + .returns(1, 1L) + .returns(2, 1L) + .returns(2, 2L) + .check(); + + assertQuery("SELECT v.a, r.x FROM (VALUES (0), (2)) v(a) " + + "OUTER APPLY TABLE(system_range(1, v.a)) r ORDER BY v.a, r.x") + .returns(0, null) + .returns(2, 1L) + .returns(2, 2L) + .check(); + } + /** */ @Test public void testFunctions() throws Exception { diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TableFunctionPlannerTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TableFunctionPlannerTest.java index 227a95b5a2c67..67da18efd6a9a 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TableFunctionPlannerTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TableFunctionPlannerTest.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.query.calcite.planner; import org.apache.calcite.rel.core.Join; +import org.apache.calcite.rel.core.JoinRelType; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin; @@ -107,4 +108,34 @@ public void testCorrelatedTableFunctionJoin() throws Exception { .and(input(1, nodeOrAnyChild(isInstanceOf(IgniteTableFunctionScan.class)))) )); } + + /** + * @throws Exception If failed. + */ + @Test + public void testCrossApply() throws Exception { + String sql = "SELECT t.id, r.x FROM random_tbl t " + + "CROSS APPLY TABLE(system_range(t.id, t.id)) r"; + + assertPlan(sql, publicSchema, nodeOrAnyChild(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class) + .and(join -> join.getJoinType() == JoinRelType.INNER) + .and(input(0, nodeOrAnyChild(isTableScan("random_tbl")))) + .and(input(1, nodeOrAnyChild(isInstanceOf(IgniteTableFunctionScan.class)))) + )); + } + + /** + * @throws Exception If failed. + */ + @Test + public void testOuterApply() throws Exception { + String sql = "SELECT t.id, r.x FROM random_tbl t " + + "OUTER APPLY TABLE(system_range(t.id, t.id)) r"; + + assertPlan(sql, publicSchema, nodeOrAnyChild(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class) + .and(join -> join.getJoinType() == JoinRelType.LEFT) + .and(input(0, nodeOrAnyChild(isTableScan("random_tbl")))) + .and(input(1, nodeOrAnyChild(isInstanceOf(IgniteTableFunctionScan.class)))) + )); + } }