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;
+        }
+    }
 }

Reply via email to