This is an automated email from the ASF dual-hosted git repository.

strongduanmu 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 81994d66d72 Fix Oracle DML scalar subqueries and system datetime 
functions (#39710)
81994d66d72 is described below

commit 81994d66d7258ed533667e1c20c27ae4a512e989
Author: ZhangCheng <[email protected]>
AuthorDate: Thu Sep 3 19:15:58 2026 +0800

    Fix Oracle DML scalar subqueries and system datetime functions (#39710)
    
    * Fix Oracle DML parser
    
    * Preserve bare function syntax in SQL node converter
    
    * Limit bare function conversion to Oracle system functions
---
 .../segment/expression/impl/FunctionConverter.java |   9 ++
 .../expression/impl/FunctionConverterTest.java     |  24 +++++
 .../src/main/antlr4/imports/oracle/DMLStatement.g4 |   4 +-
 .../visitor/statement/OracleStatementVisitor.java  |  10 ++
 .../statement/type/OracleDMLStatementVisitor.java  |  25 +++--
 .../type/OracleDMLStatementVisitorTest.java        | 103 +++++++++++++++++++++
 .../parser/src/main/resources/case/dml/delete.xml  |   2 +-
 .../parser/src/main/resources/case/dml/insert.xml  |   4 +-
 .../parser/src/main/resources/case/dml/select.xml  |  46 +++++++--
 .../main/resources/sql/supported/dml/select.xml    |   3 +-
 10 files changed, 201 insertions(+), 29 deletions(-)

diff --git 
a/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/FunctionConverter.java
 
b/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/FunctionConverter.java
index 1a69b1faad1..72c75de1df4 100644
--- 
a/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/FunctionConverter.java
+++ 
b/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/FunctionConverter.java
@@ -66,6 +66,9 @@ public final class FunctionConverter {
         if ("OVER".equalsIgnoreCase(functionName.getSimple())) {
             return WindowFunctionConverter.convert(segment);
         }
+        if (isSystemDateTimeFunctionWithoutParentheses(segment)) {
+            return functionName;
+        }
         List<SqlOperator> functions = new LinkedList<>();
         SqlStdOperatorTable.instance().lookupOperatorOverloads(functionName, 
null, SqlSyntax.FUNCTION, functions, SqlNameMatchers.withCaseSensitive(false));
         if (!functions.isEmpty() && segment.getWindow().isPresent()) {
@@ -79,6 +82,12 @@ public final class FunctionConverter {
         return new SqlBasicCall(operator, 
getFunctionParameters(segment.getParameters()), SqlParserPos.ZERO);
     }
     
+    private static boolean isSystemDateTimeFunctionWithoutParentheses(final 
FunctionSegment segment) {
+        String functionName = segment.getFunctionName();
+        return null == segment.getOwner() && segment.getParameters().isEmpty() 
&& segment.getText().equalsIgnoreCase(functionName)
+                && ("SYSDATE".equalsIgnoreCase(functionName) || 
"SYSTIMESTAMP".equalsIgnoreCase(functionName));
+    }
+    
     private static List<String> getQualifiedFunctionNames(final 
FunctionSegment segment) {
         List<String> result = null == segment.getOwner() ? new LinkedList<>() 
: OwnerConverter.convert(segment.getOwner());
         result.add(segment.getFunctionName());
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/FunctionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/FunctionConverterTest.java
index f15dfdb8ec6..56d6232957c 100644
--- 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/FunctionConverterTest.java
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/FunctionConverterTest.java
@@ -61,6 +61,30 @@ class FunctionConverterTest {
         assertThat(actual.getSimple(), is("CURRENT_USER"));
     }
     
+    @Test
+    void assertConvertSysdateWithoutParentheses() {
+        FunctionSegment segment = new FunctionSegment(0, 0, "SYSDATE", 
"SYSDATE");
+        assertThat(FunctionConverter.convert(segment), 
isA(SqlIdentifier.class));
+    }
+    
+    @Test
+    void assertConvertSystimestampWithoutParentheses() {
+        FunctionSegment segment = new FunctionSegment(0, 0, "SYSTIMESTAMP", 
"SYSTIMESTAMP");
+        assertThat(FunctionConverter.convert(segment), 
isA(SqlIdentifier.class));
+    }
+    
+    @Test
+    void assertConvertFunctionWithParentheses() {
+        FunctionSegment segment = new FunctionSegment(0, 0, "SYSDATE", 
"SYSDATE()");
+        assertThat(FunctionConverter.convert(segment), 
isA(SqlBasicCall.class));
+    }
+    
+    @Test
+    void assertConvertOtherFunctionWithoutParentheses() {
+        FunctionSegment segment = new FunctionSegment(0, 0, "CUSTOM_FUNC", 
"CUSTOM_FUNC");
+        assertThat(FunctionConverter.convert(segment), 
isA(SqlBasicCall.class));
+    }
+    
     @Test
     void assertConvertDelegatesToTrimFunctionConverter() {
         FunctionSegment segment = new FunctionSegment(0, 0, "TRIM", "TRIM");
diff --git 
a/parser/sql/engine/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
 
b/parser/sql/engine/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
index 745c3392bcb..054e3e5cdd3 100644
--- 
a/parser/sql/engine/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
+++ 
b/parser/sql/engine/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
@@ -816,7 +816,7 @@ mergeAssignment
     ;
 
 mergeAssignmentValue
-    : expr | DEFAULT
+    : expr | LP_ selectSubquery RP_ | DEFAULT
     ;
 
 deleteWhereClause
@@ -832,7 +832,7 @@ mergeInsertColumn
     ;
 
 mergeColumnValue
-    : VALUES LP_ (expr | DEFAULT) (COMMA_ (expr | DEFAULT))* RP_
+    : VALUES LP_ mergeAssignmentValue (COMMA_ mergeAssignmentValue)* RP_
     ;
 
 errorLoggingClause
diff --git 
a/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/OracleStatementVisitor.java
 
b/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/OracleStatementVisitor.java
index 31688e4c7bf..44de9435938 100644
--- 
a/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/OracleStatementVisitor.java
+++ 
b/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/OracleStatementVisitor.java
@@ -504,6 +504,9 @@ public abstract class OracleStatementVisitor extends 
OracleStatementBaseVisitor<
     
     @Override
     public final ASTNode visitColumnName(final ColumnNameContext ctx) {
+        if (isSystemDateTimeFunction(ctx)) {
+            return new FunctionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), ctx.name().getText(), getOriginalText(ctx));
+        }
         if (SequenceFunction.valueFrom(ctx.name().getText()).isPresent()) {
             return createSequenceFunction(ctx);
         }
@@ -523,6 +526,13 @@ public abstract class OracleStatementVisitor extends 
OracleStatementBaseVisitor<
         return result;
     }
     
+    private boolean isSystemDateTimeFunction(final ColumnNameContext ctx) {
+        if (null != ctx.owner() || null != ctx.nestedItem() && 
!ctx.nestedItem().isEmpty()) {
+            return false;
+        }
+        return "SYSDATE".equalsIgnoreCase(ctx.name().getText()) || 
"SYSTIMESTAMP".equalsIgnoreCase(ctx.name().getText());
+    }
+    
     private FunctionSegment createSequenceFunction(final ColumnNameContext 
ctx) {
         FunctionSegment result = new 
FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), 
ctx.name().getText(), getOriginalText(ctx));
         OwnerContext owner = ctx.owner();
diff --git 
a/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
 
b/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
index 15c1df850fa..5859d542aa9 100644
--- 
a/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
+++ 
b/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
@@ -330,14 +330,10 @@ public final class OracleDMLStatementVisitor extends 
OracleStatementVisitor impl
             SubquerySegment subquerySegment = new 
SubquerySegment(ctx.selectSubquery().start.getStartIndex(), 
ctx.selectSubquery().stop.getStopIndex(),
                     (SelectStatement) visit(ctx.selectSubquery()), 
getOriginalText(ctx.selectSubquery()));
             SubqueryExpressionSegment value = new 
SubqueryExpressionSegment(subquerySegment);
-            ColumnAssignmentSegment result = new 
ColumnAssignmentSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), columnSegments, value);
-            result.getColumns().add(column);
-            return result;
+            return new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), columnSegments, value);
         }
         CommonExpressionSegment value = new 
CommonExpressionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), ctx.DEFAULT().getText());
-        ColumnAssignmentSegment result = new 
ColumnAssignmentSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), columnSegments, value);
-        result.getColumns().add(column);
-        return result;
+        return new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), columnSegments, value);
     }
     
     private ColumnAssignmentSegment 
createAssignmentSegmentFromMultiColumnAssignment(final 
UpdateSetColumnClauseContext ctx) {
@@ -358,16 +354,12 @@ public final class OracleDMLStatementVisitor extends 
OracleStatementVisitor impl
         columnSegments.add(column);
         if (null != ctx.expr()) {
             ExpressionSegment value = (ExpressionSegment) visit(ctx.expr());
-            ColumnAssignmentSegment result = new 
ColumnAssignmentSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), columnSegments, value);
-            result.getColumns().add(column);
-            return result;
+            return new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), columnSegments, value);
         } else {
             SubquerySegment subquerySegment = new 
SubquerySegment(ctx.selectSubquery().start.getStartIndex(), 
ctx.selectSubquery().stop.getStopIndex(),
                     (SelectStatement) visit(ctx.selectSubquery()), 
getOriginalText(ctx.selectSubquery()));
             SubqueryExpressionSegment value = new 
SubqueryExpressionSegment(subquerySegment);
-            ColumnAssignmentSegment result = new 
ColumnAssignmentSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), columnSegments, value);
-            result.getColumns().add(column);
-            return result;
+            return new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), columnSegments, value);
         }
     }
     
@@ -1679,8 +1671,8 @@ public final class OracleDMLStatementVisitor extends 
OracleStatementVisitor impl
     public ASTNode visitMergeColumnValue(final MergeColumnValueContext ctx) {
         CollectionValue<InsertValuesSegment> result = new CollectionValue<>();
         List<ExpressionSegment> segments = new LinkedList<>();
-        for (ExprContext each : ctx.expr()) {
-            segments.add(null == each ? new 
CommonExpressionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), ctx.getText()) : (ExpressionSegment) visit(each));
+        for (MergeAssignmentValueContext each : ctx.mergeAssignmentValue()) {
+            segments.add((ExpressionSegment) visit(each));
         }
         result.getValue().add(new 
InsertValuesSegment(ctx.LP_().getSymbol().getStartIndex(), 
ctx.RP_().getSymbol().getStopIndex(), segments));
         return result;
@@ -1773,6 +1765,11 @@ public final class OracleDMLStatementVisitor extends 
OracleStatementVisitor impl
     
     @Override
     public ASTNode visitMergeAssignmentValue(final MergeAssignmentValueContext 
ctx) {
+        if (null != ctx.selectSubquery()) {
+            SelectStatement selectStatement = (SelectStatement) 
visit(ctx.selectSubquery());
+            SubquerySegment subquerySegment = new 
SubquerySegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), 
selectStatement, getOriginalText(ctx));
+            return new SubqueryExpressionSegment(subquerySegment);
+        }
         ExprContext expr = ctx.expr();
         return null == expr ? new 
CommonExpressionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), ctx.getText()) : visit(expr);
     }
diff --git 
a/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitorTest.java
 
b/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitorTest.java
new file mode 100644
index 00000000000..7f83dbd5825
--- /dev/null
+++ 
b/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitorTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.oracle.visitor.statement.type;
+
+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.statement.core.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.MergeStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.UpdateStatement;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isA;
+
+class OracleDMLStatementVisitorTest {
+    
+    private static final CacheOption CACHE_OPTION = new CacheOption(128, 
1024L);
+    
+    @Test
+    void assertVisitMergeUpdateWithScalarSubquery() {
+        MergeStatement actual = parseMerge("MERGE INTO t_user target USING 
(SELECT ? user_id FROM DUAL) source ON (target.user_id = source.user_id) "
+                + "WHEN MATCHED THEN UPDATE SET target.email = (SELECT 
MAX(u.email) FROM t_user u WHERE u.user_id < ?)");
+        ExpressionSegment actualValue = 
actual.getUpdate().get().getAssignment().get().getAssignments().iterator().next().getValue();
+        assertThat(actualValue, isA(SubqueryExpressionSegment.class));
+        assertThat(actualValue.getText(), is("(SELECT MAX(u.email) FROM t_user 
u WHERE u.user_id < ?)"));
+        assertThat(actual.getParameterCount(), is(2));
+    }
+    
+    @Test
+    void assertVisitMergeInsertWithScalarSubquery() {
+        MergeStatement actual = parseMerge("MERGE INTO t_user target USING 
(SELECT ? user_id FROM DUAL) source ON (target.user_id = source.user_id) "
+                + "WHEN NOT MATCHED THEN INSERT (user_id, email) VALUES 
(source.user_id, (SELECT MAX(u.email) FROM t_user u WHERE u.user_id < ?))");
+        ExpressionSegment actualValue = 
actual.getInsert().get().getValues().iterator().next().getValues().get(1);
+        assertThat(actualValue, isA(SubqueryExpressionSegment.class));
+        assertThat(actualValue.getText(), is("(SELECT MAX(u.email) FROM t_user 
u WHERE u.user_id < ?)"));
+        assertThat(actual.getParameterCount(), is(2));
+    }
+    
+    @Test
+    void assertVisitSystemDateTimeFunctions() {
+        MergeStatement actual = parseMerge("MERGE INTO t_user target USING 
(SELECT ? user_id FROM DUAL) source ON (target.user_id = source.user_id) "
+                + "WHEN MATCHED THEN UPDATE SET target.creation_date = SYSDATE 
"
+                + "WHEN NOT MATCHED THEN INSERT (user_id, creation_date) 
VALUES (source.user_id, CAST(SYSTIMESTAMP AS TIMESTAMP))");
+        ExpressionSegment actualSysdate = 
actual.getUpdate().get().getAssignment().get().getAssignments().iterator().next().getValue();
+        FunctionSegment actualCast = (FunctionSegment) 
actual.getInsert().get().getValues().iterator().next().getValues().get(1);
+        assertThat(actualSysdate, isA(FunctionSegment.class));
+        assertThat(((FunctionSegment) actualSysdate).getFunctionName(), 
is("SYSDATE"));
+        assertThat(actualCast.getParameters().iterator().next(), 
isA(FunctionSegment.class));
+        assertThat(((FunctionSegment) 
actualCast.getParameters().iterator().next()).getFunctionName(), 
is("SYSTIMESTAMP"));
+    }
+    
+    @Test
+    void assertVisitQuotedSystemDateTimeColumn() {
+        MergeStatement actual = parseMerge("MERGE INTO t_user target USING 
(SELECT ? user_id FROM DUAL) source ON (target.user_id = source.user_id) "
+                + "WHEN MATCHED THEN UPDATE SET target.creation_date = 
\"SYSDATE\"");
+        
assertThat(actual.getUpdate().get().getAssignment().get().getAssignments().iterator().next().getValue(),
 isA(ColumnSegment.class));
+    }
+    
+    @Test
+    void assertVisitUpdateAssignmentWithScalarSubquery() {
+        UpdateStatement actual = parseUpdate("UPDATE t_order SET status = 
(SELECT ? FROM DUAL) WHERE order_id = ?");
+        
assertThat(actual.getAssignment().get().getAssignments().iterator().next().getColumns().size(),
 is(1));
+        
assertThat(actual.getAssignment().get().getAssignments().iterator().next().getValue(),
 isA(SubqueryExpressionSegment.class));
+    }
+    
+    @Test
+    void assertVisitUpdateValueAssignment() {
+        UpdateStatement actual = parseUpdate("UPDATE ot1 SET VALUE(ot1.x) = 
t1(20) WHERE VALUE(ot1.x) = t1(10)");
+        
assertThat(actual.getAssignment().get().getAssignments().iterator().next().getColumns().size(),
 is(1));
+    }
+    
+    private MergeStatement parseMerge(final String sql) {
+        return (MergeStatement) parse(sql);
+    }
+    
+    private UpdateStatement parseUpdate(final String sql) {
+        return (UpdateStatement) parse(sql);
+    }
+    
+    private Object parse(final String sql) {
+        return new SQLStatementVisitorEngine("Oracle").visit(new 
SQLParserEngine("Oracle", CACHE_OPTION).parse(sql, false));
+    }
+}
diff --git a/test/it/parser/src/main/resources/case/dml/delete.xml 
b/test/it/parser/src/main/resources/case/dml/delete.xml
index 16d8d19e03e..2065465739c 100644
--- a/test/it/parser/src/main/resources/case/dml/delete.xml
+++ b/test/it/parser/src/main/resources/case/dml/delete.xml
@@ -762,7 +762,7 @@
                             </left>
                             <operator>&lt;</operator>
                             <right>
-                                <column name="SYSDATE" start-index="87" 
stop-index="93" />
+                                <function function-name="SYSDATE" 
text="SYSDATE" start-index="87" stop-index="93" />
                             </right>
                         </binary-operation-expression>
                     </right>
diff --git a/test/it/parser/src/main/resources/case/dml/insert.xml 
b/test/it/parser/src/main/resources/case/dml/insert.xml
index 2605405fcb9..8f4bd5d3263 100644
--- a/test/it/parser/src/main/resources/case/dml/insert.xml
+++ b/test/it/parser/src/main/resources/case/dml/insert.xml
@@ -2232,7 +2232,7 @@
                     <literal-expression value="[email protected]" 
start-index="133" stop-index="154" />
                 </assignment-value>
                 <assignment-value>
-                    <column name="sysdate" start-index="157" stop-index="163" 
/>
+                    <function function-name="sysdate" text="sysdate" 
start-index="157" stop-index="163" />
                 </assignment-value>
                 <assignment-value>
                     <literal-expression value="PU_CLERK" start-index="166" 
stop-index="175" />
@@ -2915,7 +2915,7 @@
                     <literal-expression value="500 Oracle Parkway" 
start-index="60" stop-index="79" literal-start-index="59" 
literal-stop-index="79" />
                 </assignment-value>
                 <assignment-value>
-                    <column name="sysdate" start-index="81" stop-index="87" 
literal-start-index="81" literal-stop-index="87" />
+                    <function function-name="sysdate" text="sysdate" 
start-index="81" stop-index="87" literal-start-index="81" 
literal-stop-index="87" />
                 </assignment-value>
             </value>
         </values>
diff --git a/test/it/parser/src/main/resources/case/dml/select.xml 
b/test/it/parser/src/main/resources/case/dml/select.xml
index 5b9b8b9fbb5..de2fdafbdc3 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -6174,7 +6174,7 @@
                         <parameter>
                             <binary-operation-expression start-index="50" 
stop-index="66" literal-start-index="50" literal-stop-index="66">
                                 <left>
-                                    <column name="SYSDATE" start-index="50" 
stop-index="56" literal-start-index="50" literal-stop-index="56" />
+                                    <function function-name="SYSDATE" 
text="SYSDATE" start-index="50" stop-index="56" literal-start-index="50" 
literal-stop-index="56" />
                                 </left>
                                 <operator>-</operator>
                                 <right>
@@ -6196,7 +6196,7 @@
                         <parameter>
                             <binary-operation-expression start-index="126" 
stop-index="142" literal-start-index="126" literal-stop-index="142">
                                 <left>
-                                    <column name="SYSDATE" start-index="126" 
stop-index="132" literal-start-index="126" literal-stop-index="132" />
+                                    <function function-name="SYSDATE" 
text="SYSDATE" start-index="126" stop-index="132" literal-start-index="126" 
literal-stop-index="132" />
                                 </left>
                                 <operator>-</operator>
                                 <right>
@@ -6218,7 +6218,7 @@
                         <parameter>
                             <binary-operation-expression start-index="196" 
stop-index="212" literal-start-index="196" literal-stop-index="212">
                                 <left>
-                                    <column name="SYSDATE" start-index="196" 
stop-index="202" literal-start-index="196" literal-stop-index="202" />
+                                    <function function-name="SYSDATE" 
text="SYSDATE" start-index="196" stop-index="202" literal-start-index="196" 
literal-stop-index="202" />
                                 </left>
                                 <operator>-</operator>
                                 <right>
@@ -6240,7 +6240,7 @@
                         <parameter>
                             <binary-operation-expression start-index="267" 
stop-index="283" literal-start-index="267" literal-stop-index="283">
                                 <left>
-                                    <column name="SYSDATE" start-index="267" 
stop-index="273" literal-start-index="267" literal-stop-index="273" />
+                                    <function function-name="SYSDATE" 
text="SYSDATE" start-index="267" stop-index="273" literal-start-index="267" 
literal-stop-index="273" />
                                 </left>
                                 <operator>-</operator>
                                 <right>
@@ -6262,7 +6262,7 @@
                         <parameter>
                             <binary-operation-expression start-index="338" 
stop-index="354" literal-start-index="338" literal-stop-index="354">
                                 <left>
-                                    <column name="SYSDATE" start-index="338" 
stop-index="344" literal-start-index="338" literal-stop-index="344" />
+                                    <function function-name="SYSDATE" 
text="SYSDATE" start-index="338" stop-index="344" literal-start-index="338" 
literal-stop-index="344" />
                                 </left>
                                 <operator>-</operator>
                                 <right>
@@ -6284,7 +6284,7 @@
                         <parameter>
                             <binary-operation-expression start-index="408" 
stop-index="424" literal-start-index="408" literal-stop-index="424">
                                 <left>
-                                    <column name="SYSDATE" start-index="408" 
stop-index="414" literal-start-index="408" literal-stop-index="414" />
+                                    <function function-name="SYSDATE" 
text="SYSDATE" start-index="408" stop-index="414" literal-start-index="408" 
literal-stop-index="414" />
                                 </left>
                                 <operator>-</operator>
                                 <right>
@@ -6780,7 +6780,35 @@
         </projections>
     </select>
 
-    <select sql-case-id="select_projection_with_parameter" parameters="'OK'">
+    <select sql-case-id="select_projection_with_parameter_oracle" 
parameters="'OK'">
+        <projections start-index="7" stop-index="81" literal-stop-index="84">
+            <expression-projection text="1" start-index="7" stop-index="13" 
alias="id">
+                <expr>
+                    <literal-expression value="1" start-index="7" 
stop-index="7" />
+                </expr>
+            </expression-projection>
+            <parameter-marker-expression parameter-index="0" start-index="16" 
stop-index="26" literal-stop-index="29" />
+            <expression-projection text="SYSDATE" start-index="29" 
stop-index="50" literal-start-index="32" literal-stop-index="53" 
alias="create_time">
+                <expr>
+                    <function function-name="SYSDATE" text="SYSDATE" 
start-index="29" stop-index="35" literal-start-index="32" 
literal-stop-index="38" />
+                </expr>
+            </expression-projection>
+            <expression-projection text="TRUNC(SYSDATE)" start-index="53" 
stop-index="81" literal-start-index="56" literal-stop-index="84" 
alias="create_date">
+                <expr>
+                    <function function-name="TRUNC" start-index="53" 
stop-index="66" literal-start-index="56" literal-stop-index="69" 
text="TRUNC(SYSDATE)">
+                        <parameter>
+                            <function function-name="SYSDATE" text="SYSDATE" 
start-index="59" stop-index="65" literal-start-index="62" 
literal-stop-index="68" />
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+        <from>
+            <simple-table name="DUAL" start-index="88" stop-index="91" 
literal-start-index="91" literal-stop-index="94" />
+        </from>
+    </select>
+
+    <select sql-case-id="select_projection_with_parameter_firebird" 
parameters="'OK'">
         <projections start-index="7" stop-index="81" literal-stop-index="84">
             <expression-projection text="1" start-index="7" stop-index="13" 
alias="id">
                 <expr>
@@ -7423,7 +7451,7 @@
                         <parameter>
                             <binary-operation-expression start-index="25" 
stop-index="43" literal-start-index="25" literal-stop-index="43">
                                 <left>
-                                    <column name="SYSDATE" start-index="25" 
stop-index="31" literal-start-index="25" literal-stop-index="31" />
+                                    <function function-name="SYSDATE" 
text="SYSDATE" start-index="25" stop-index="31" literal-start-index="25" 
literal-stop-index="31" />
                                 </left>
                                 <operator>-</operator>
                                 <right>
@@ -11065,7 +11093,7 @@
                                                 <column name="END_TIME" 
start-index="51" stop-index="58" />
                                             </parameter>
                                             <parameter>
-                                                <column name="sysdate" 
start-index="61" stop-index="67" />
+                                                <function 
function-name="sysdate" text="sysdate" start-index="61" stop-index="67" />
                                             </parameter>
                                         </function>
                                     </left>
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/select.xml 
b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
index b996e738a5a..3c7107c13f2 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
@@ -223,7 +223,8 @@
     <sql-case id="select_positional_parameter_type_cast_money" value="SELECT 
$1::money" db-types="PostgreSQL,openGauss" case-types="Placeholder" />
     <sql-case id="select_string_constant_type_cast" value="SELECT int4 '1', 
money '2'" db-types="PostgreSQL,openGauss" />
     <sql-case id="select_constant_with_nested_type_cast" value="SELECT 
CAST(MONEY '1' AS VARCHAR)::CHAR(10)::VARCHAR::CHAR(4)" 
db-types="PostgreSQL,openGauss"  />
-    <sql-case id="select_projection_with_parameter" value="SELECT 1 AS id, ? 
AS status, SYSDATE AS create_time, TRUNC(SYSDATE) AS create_date FROM DUAL" 
db-types="Oracle,Firebird" case-types="PLACEHOLDER" />
+    <sql-case id="select_projection_with_parameter_oracle" value="SELECT 1 AS 
id, ? AS status, SYSDATE AS create_time, TRUNC(SYSDATE) AS create_date FROM 
DUAL" db-types="Oracle" case-types="PLACEHOLDER" />
+    <sql-case id="select_projection_with_parameter_firebird" value="SELECT 1 
AS id, ? AS status, SYSDATE AS create_time, TRUNC(SYSDATE) AS create_date FROM 
DUAL" db-types="Firebird" case-types="PLACEHOLDER" />
     <sql-case id="select_with_chinese_comma" value="SELECT 1, 2,3 FROM DUAL" 
db-types="Oracle"  />
     <sql-case id="select_with_chinese_whitespace" value="SELECT 1, 2,3 FROM 
DUAL" db-types="Oracle"  />
     <sql-case id="select_with_auto_keyword" value="SELECT * FROM t_auto WHERE 
auto = ?" db-types="MySQL"/>

Reply via email to