This is an automated email from the ASF dual-hosted git repository.
alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 091b0580101 IGNITE-27940 SQL Calcite: Refactor
IgniteSqlCallRewriteTable usage - Fixes #12785.
091b0580101 is described below
commit 091b05801013e49bbf79bbffd100d02cdc3ac1bb
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Fri Mar 27 10:36:57 2026 +0300
IGNITE-27940 SQL Calcite: Refactor IgniteSqlCallRewriteTable usage - Fixes
#12785.
Signed-off-by: Aleksey Plekhanov <[email protected]>
---
.../query/calcite/CalciteQueryProcessor.java | 6 ++--
.../calcite/prepare/IgniteSqlCallRewriteTable.java | 34 ++++++++--------------
.../calcite/prepare/IgniteSqlNodeRewriter.java | 29 ++++++++++++++++++
.../query/calcite/prepare/IgniteSqlValidator.java | 31 ++++++++++++++++++--
.../OperatorsExtensionIntegrationTest.java | 22 ++++++++++----
5 files changed, 91 insertions(+), 31 deletions(-)
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
index 5f5adbfdb03..015ae25b6b9 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
@@ -47,7 +47,6 @@ import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.util.SqlOperatorTables;
import org.apache.calcite.sql.util.SqlShuttle;
-import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql2rel.SqlToRelConverter;
import org.apache.calcite.tools.FrameworkConfig;
import org.apache.calcite.tools.Frameworks;
@@ -98,6 +97,8 @@ import
org.apache.ignite.internal.processors.query.calcite.prepare.CacheKey;
import org.apache.ignite.internal.processors.query.calcite.prepare.ExplainPlan;
import
org.apache.ignite.internal.processors.query.calcite.prepare.FieldsMetadata;
import
org.apache.ignite.internal.processors.query.calcite.prepare.IgniteConvertletTable;
+import
org.apache.ignite.internal.processors.query.calcite.prepare.IgniteSqlCallRewriteTable;
+import
org.apache.ignite.internal.processors.query.calcite.prepare.IgniteSqlValidator;
import
org.apache.ignite.internal.processors.query.calcite.prepare.IgniteTypeCoercion;
import
org.apache.ignite.internal.processors.query.calcite.prepare.MultiStepPlan;
import
org.apache.ignite.internal.processors.query.calcite.prepare.PrepareServiceImpl;
@@ -190,7 +191,8 @@ public class CalciteQueryProcessor extends
GridProcessorAdapter implements Query
.withParserFactory(IgniteSqlParserImpl.FACTORY)
.withLex(Lex.ORACLE)
.withConformance(IgniteSqlConformance.INSTANCE))
- .sqlValidatorConfig(SqlValidator.Config.DEFAULT
+ .sqlValidatorConfig(IgniteSqlValidator.Config.DFLT
+ .withSqlNodeRewriter(IgniteSqlCallRewriteTable.INSTANCE)
// TODO Workaround for
https://issues.apache.org/jira/browse/CALCITE-6978
.withCallRewrite(false)
.withIdentifierExpansion(true)
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlCallRewriteTable.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlCallRewriteTable.java
index 526c66e674c..163b01996bd 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlCallRewriteTable.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlCallRewriteTable.java
@@ -26,14 +26,12 @@ import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlUtil;
import org.apache.calcite.sql.fun.SqlCase;
import org.apache.calcite.sql.fun.SqlLibraryOperators;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParserPos;
-import org.apache.calcite.sql.util.SqlBasicVisitor;
-import org.apache.calcite.sql.util.SqlVisitor;
import org.apache.calcite.sql.validate.SqlValidator;
-import org.apache.calcite.util.Util;
import static org.apache.calcite.util.Static.RESOURCE;
@@ -41,7 +39,7 @@ import static org.apache.calcite.util.Static.RESOURCE;
* Ignite SQL call rewrite table. Performs unconditional rewrites for some
predefined Calcite SQL operators,
* which can't be extended other ways by Ignite.
*/
-public class IgniteSqlCallRewriteTable {
+public class IgniteSqlCallRewriteTable implements IgniteSqlNodeRewriter {
/** Instance. */
public static final IgniteSqlCallRewriteTable INSTANCE = new
IgniteSqlCallRewriteTable();
@@ -68,6 +66,14 @@ public class IgniteSqlCallRewriteTable {
map.put(operatorName, rewriter);
}
+ /** {@inheritDoc} */
+ @Override public SqlNode rewrite(SqlValidator validator, SqlNode node) {
+ if (node instanceof SqlCall)
+ return rewrite(validator, (SqlCall)node);
+ else
+ return node;
+ }
+
/** Rewrites SQL call. */
SqlNode rewrite(SqlValidator validator, SqlCall call) {
BiFunction<SqlValidator, SqlCall, SqlCall> rewriter =
map.get(call.getOperator().getName());
@@ -107,24 +113,8 @@ public class IgniteSqlCallRewriteTable {
}
/** */
- public static boolean containsSubquery(SqlNode call) {
- try {
- SqlVisitor<Void> visitor = new SqlBasicVisitor<>() {
- @Override public Void visit(SqlCall call) {
- if (call.getKind() == SqlKind.SELECT)
- throw new Util.FoundOne(call);
-
- return super.visit(call);
- }
- };
-
- call.accept(visitor);
-
- return false;
- }
- catch (Util.FoundOne e) {
- return true;
- }
+ public static boolean containsSubquery(SqlNode node) {
+ return SqlUtil.containsCall(node, call -> call.getKind() ==
SqlKind.SELECT);
}
/** Rewrites DECODE call to CASE WHEN call. */
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlNodeRewriter.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlNodeRewriter.java
new file mode 100644
index 00000000000..732d6cae1c8
--- /dev/null
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlNodeRewriter.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.prepare;
+
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.validate.SqlValidator;
+
+/**
+ * SQL node rewriter interface.
+ */
+public interface IgniteSqlNodeRewriter {
+ /** Rewrites SQL node. */
+ public SqlNode rewrite(SqlValidator validator, SqlNode node);
+}
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
index c7101b05db6..92308f805a4 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
@@ -53,6 +53,7 @@ import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.FamilyOperandTypeChecker;
import org.apache.calcite.sql.type.SqlOperandTypeChecker;
import org.apache.calcite.sql.type.SqlOperandTypeInference;
+import org.apache.calcite.sql.type.SqlTypeCoercionRule;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.validate.SelectScope;
@@ -73,11 +74,13 @@ import
org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactor
import org.apache.ignite.internal.processors.query.calcite.type.OtherType;
import org.apache.ignite.internal.processors.query.calcite.util.IgniteResource;
import org.apache.ignite.internal.util.typedef.F;
+import org.immutables.value.Value;
import org.jetbrains.annotations.Nullable;
import static org.apache.calcite.util.Static.RESOURCE;
/** Validator. */
[email protected]
public class IgniteSqlValidator extends SqlValidatorImpl {
/** Decimal of Integer.MAX_VALUE for fetch/offset bounding. */
private static final BigDecimal DEC_INT_MAX =
BigDecimal.valueOf(Integer.MAX_VALUE);
@@ -345,8 +348,8 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
node = super.performUnconditionalRewrites(node, underFrom);
- if (node instanceof SqlCall)
- node = IgniteSqlCallRewriteTable.INSTANCE.rewrite(this,
(SqlCall)node);
+ if (config() instanceof Config && ((Config)config()).sqlNodeRewriter()
!= null)
+ node = ((Config)config()).sqlNodeRewriter().rewrite(this, node);
return node;
}
@@ -657,4 +660,28 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
super.validateUnnest(call, scope, targetRowType);
}
+
+ /**
+ * Interface to define extension to the configuration for a
IgniteSqlValidator.
+ */
+ @Value.Immutable(singleton = false)
+ public interface Config extends SqlValidator.Config {
+ /** Default configuration. */
+ Config DFLT =
ImmutableIgniteSqlValidator.Config.builder().from(DEFAULT).build();
+
+ /** Gets custom call rewriter. */
+ @Value.Default
+ @Nullable default IgniteSqlNodeRewriter sqlNodeRewriter() {
+ return null;
+ }
+
+ /** Sets custom call rewriter. */
+ Config withSqlNodeRewriter(@Nullable IgniteSqlNodeRewriter rewriter);
+
+ /** Ovverride due to lost @Nullable annotation from the super-class by
immutables generator. */
+ @Override @Nullable SqlTypeCoercionRule typeCoercionRules();
+
+ /** Ovverride due to lost @Nullable annotation from the super-class by
immutables generator. */
+ @Override Config withTypeCoercionRules(@Nullable SqlTypeCoercionRule
rules);
+ }
}
diff --git
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/OperatorsExtensionIntegrationTest.java
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/OperatorsExtensionIntegrationTest.java
index d21fc66e0dc..53b6d23bcf1 100644
---
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/OperatorsExtensionIntegrationTest.java
+++
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/OperatorsExtensionIntegrationTest.java
@@ -28,6 +28,7 @@ import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.fun.SqlTrimFunction;
import org.apache.calcite.sql.parser.SqlParserPos;
@@ -46,7 +47,8 @@ import org.apache.ignite.configuration.IgniteConfiguration;
import
org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessor;
import
org.apache.ignite.internal.processors.query.calcite.exec.exp.RexImpTable;
import
org.apache.ignite.internal.processors.query.calcite.prepare.IgniteConvertletTable;
-import
org.apache.ignite.internal.processors.query.calcite.prepare.IgniteSqlCallRewriteTable;
+import
org.apache.ignite.internal.processors.query.calcite.prepare.IgniteSqlNodeRewriter;
+import
org.apache.ignite.internal.processors.query.calcite.prepare.IgniteSqlValidator;
import org.apache.ignite.plugin.AbstractTestPluginProvider;
import org.apache.ignite.plugin.PluginContext;
import org.jetbrains.annotations.Nullable;
@@ -70,6 +72,9 @@ public class OperatorsExtensionIntegrationTest extends
AbstractBasicIntegrationT
.convertletTable(new ConvertletTable())
.operatorTable(SqlOperatorTables.chain(
new OperatorTable().init(),
CalciteQueryProcessor.FRAMEWORK_CONFIG.getOperatorTable()))
+ .sqlValidatorConfig(
+
((IgniteSqlValidator.Config)CalciteQueryProcessor.FRAMEWORK_CONFIG.getSqlValidatorConfig())
+ .withSqlNodeRewriter(new SqlRewriter()))
.build();
return (T)cfg;
@@ -102,10 +107,6 @@ public class OperatorsExtensionIntegrationTest extends
AbstractBasicIntegrationT
RexImpTable.FALSE_EXPR
), NullPolicy.ARG0, false
));
-
- // Tests operator extension via SQL rewrite.
- IgniteSqlCallRewriteTable.INSTANCE.register("LTRIM",
- OperatorsExtensionIntegrationTest::rewriteLtrim);
}
});
}
@@ -217,4 +218,15 @@ public class OperatorsExtensionIntegrationTest extends
AbstractBasicIntegrationT
}
}
}
+
+ /** Extended SQL rewriter. */
+ private static class SqlRewriter implements IgniteSqlNodeRewriter {
+ /** {@inheritDoc} */
+ @Override public SqlNode rewrite(SqlValidator validator, SqlNode node)
{
+ if (node instanceof SqlCall &&
"LTRIM".equals(((SqlCall)node).getOperator().getName()))
+ node = rewriteLtrim(validator, (SqlCall)node);
+
+ return node;
+ }
+ }
}