This is an automated email from the ASF dual-hosted git repository.
zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new dad1b290908 [Parser][PostgreSQL] Preserve unary NOT as NotExpression
for scalar-subquery table extraction (#38187)
dad1b290908 is described below
commit dad1b290908e75f0777df73e1c067f8bab9f98ab
Author: ym0506 <[email protected]>
AuthorDate: Thu Feb 26 00:13:45 2026 +0900
[Parser][PostgreSQL] Preserve unary NOT as NotExpression for
scalar-subquery table extraction (#38187)
* [Parser][PostgreSQL] Handle unary NOT as NotExpression in AExpr
Fixes #37770.
PostgreSQL visitor could parse unary NOT expression in scalar-subquery form
as CommonExpressionSegment, which prevents recursive table extraction for inner
subquery tables.
This can skip sharding table rewrite and send logical names (for example
t23/t22) to backend.
Add explicit unary NOT handling in visitAExpr and a regression test for the
reported SQL shape.
* [Parser][PostgreSQL] Avoid static Matcher import in visitor test
* [Parser][PostgreSQL] Limit unary NOT handling to NOT aExpr
---
.../statement/PostgreSQLStatementVisitor.java | 4 ++
.../statement/PostgreSQLStatementVisitorTest.java | 52 ++++++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git
a/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
b/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
index 76014f3b6b2..c4cb6799556 100644
---
a/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
+++
b/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
@@ -145,6 +145,7 @@ import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.Extr
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ListExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.NotExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.TypeCastExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonExpressionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonTableExpressionSegment;
@@ -325,6 +326,9 @@ public abstract class PostgreSQLStatementVisitor extends
PostgreSQLStatementPars
if (null != ctx.patternMatchingOperator()) {
return createPatternMatchingOperationSegment(ctx);
}
+ if (null != ctx.NOT() && null == ctx.IS() && 1 == ctx.aExpr().size()) {
+ return new NotExpression(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), (ExpressionSegment) visit(ctx.aExpr(0)), false);
+ }
Optional<String> binaryOperator = findBinaryOperator(ctx);
if (binaryOperator.isPresent()) {
return createBinaryOperationSegment(ctx, binaryOperator.get());
diff --git
a/parser/sql/engine/dialect/postgresql/src/test/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitorTest.java
b/parser/sql/engine/dialect/postgresql/src/test/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitorTest.java
new file mode 100644
index 00000000000..98de69063d0
--- /dev/null
+++
b/parser/sql/engine/dialect/postgresql/src/test/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitorTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.shardingsphere.sql.parser.engine.postgresql.visitor.statement;
+
+import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
+import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
+import
org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
+import org.apache.shardingsphere.sql.parser.engine.core.ParseASTNode;
+import
org.apache.shardingsphere.sql.parser.statement.core.extractor.TableExtractor;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.NotExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class PostgreSQLStatementVisitorTest {
+
+ @Test
+ void assertVisitUnaryNotWithScalarSubquery() {
+ String sql = "select 1 from t17 as ref_0 where not ((ref_0.c59) <
(select ref_1.c36 as c_0 from t23 as ref_1 join t22 as ref_2 "
+ + "on(ref_1.colocated_key = ref_2.colocated_key)))";
+ ParseASTNode parseASTNode = new SQLParserEngine("PostgreSQL", new
CacheOption(128, 1024L)).parse(sql, false);
+ SelectStatement statement = (SelectStatement) new
SQLStatementVisitorEngine("PostgreSQL").visit(parseASTNode);
+ assertTrue(statement.getWhere().isPresent());
+ assertThat(statement.getWhere().get().getExpr(),
Matchers.instanceOf(NotExpression.class));
+ TableExtractor tableExtractor = new TableExtractor();
+ tableExtractor.extractTablesFromSelect(statement);
+ Collection<String> rewriteTableNames =
tableExtractor.getRewriteTables().stream()
+ .map(each ->
each.getTableName().getIdentifier().getValue()).collect(Collectors.toList());
+ assertThat(rewriteTableNames, Matchers.hasItems("t17", "t23", "t22"));
+ }
+}