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

duanzhengqiang 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 2c3eb0ca0b7 Support parsing SQL Server SELECT TRIM (#30249)
2c3eb0ca0b7 is described below

commit 2c3eb0ca0b7741875b87cae6ede325fcfd515b5b
Author: zhengke zhou <[email protected]>
AuthorDate: Sat Feb 24 15:09:29 2024 +0800

    Support parsing SQL Server SELECT TRIM (#30249)
    
    * Support parsing SQL Server SELECT TRIM
    
    * fix up
    
    * fix code format
---
 .../src/main/antlr4/imports/sqlserver/BaseRule.g4  | 11 ++-
 .../src/main/antlr4/imports/sqlserver/Keyword.g4   | 12 ++++
 .../statement/SQLServerStatementVisitor.java       | 25 +++++++
 .../parser/src/main/resources/case/dml/select.xml  | 79 +++++++++++++++++++++-
 .../main/resources/sql/supported/dml/select.xml    |  6 +-
 5 files changed, 128 insertions(+), 5 deletions(-)

diff --git 
a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/BaseRule.g4 
b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/BaseRule.g4
index 4ec987a43ea..380e20c58aa 100644
--- a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/BaseRule.g4
+++ b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/BaseRule.g4
@@ -54,7 +54,7 @@ hexadecimalLiterals
 bitValueLiterals
     : BIT_NUM_
     ;
-    
+
 booleanLiterals
     : TRUE | FALSE
     ;
@@ -315,9 +315,14 @@ distinct
     ;
 
 specialFunction
-    : conversionFunction | charFunction | openJsonFunction | jsonFunction | 
openRowSetFunction | windowFunction | approxFunction | openDatasourceFunction | 
rowNumberFunction | graphFunction
+    : conversionFunction | charFunction | openJsonFunction | jsonFunction | 
openRowSetFunction | windowFunction | approxFunction | openDatasourceFunction | 
rowNumberFunction | graphFunction | trimFunction
     ;
 
+    trimFunction
+        : TRIM LP_ ((LEADING | BOTH | TRAILING) expr? FROM)? expr RP_
+        | TRIM LP_ (expr FROM)? expr RP_
+        ;
+
 graphFunction
     : graphAggFunction
     ;
@@ -478,7 +483,7 @@ partitionByClause
     : PARTITION BY expr (COMMA_ expr)*
     ;
 
-rowRangeClause 
+rowRangeClause
     : (ROWS | RANGE) windowFrameExtent
     ;
 
diff --git 
a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/Keyword.g4 
b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/Keyword.g4
index 1bbf16738a6..90b39ae64e3 100644
--- a/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/Keyword.g4
+++ b/parser/sql/dialect/sqlserver/src/main/antlr4/imports/sqlserver/Keyword.g4
@@ -811,3 +811,15 @@ MATCHED
 TARGET
     : T A R G E T
     ;
+
+LEADING
+    : L E A D I N G
+    ;
+
+BOTH
+    : B O T H
+    ;
+
+TRAILING
+    : T R A I L I N G
+    ;
diff --git 
a/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/SQLServerStatementVisitor.java
 
b/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/SQLServerStatementVisitor.java
index 600709517d1..7ac2fd263e9 100644
--- 
a/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/SQLServerStatementVisitor.java
+++ 
b/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/SQLServerStatementVisitor.java
@@ -128,6 +128,7 @@ import 
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.Tab
 import 
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TableReferenceContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TableReferencesContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TopContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TrimFunctionContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.UnreservedWordContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.UpdateContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.UpdateStatisticsContext;
@@ -705,9 +706,33 @@ public abstract class SQLServerStatementVisitor extends 
SQLServerStatementBaseVi
         if (null != ctx.graphFunction()) {
             return visit(ctx.graphFunction());
         }
+        if (null != ctx.trimFunction()) {
+            return visit(ctx.trimFunction());
+        }
         return new FunctionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), ctx.getChild(0).getChild(0).getText(), 
getOriginalText(ctx));
     }
     
+    @Override
+    public ASTNode visitTrimFunction(final TrimFunctionContext ctx) {
+        FunctionSegment result = new 
FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), 
ctx.TRIM().getText(), getOriginalText(ctx));
+        if (null != ctx.BOTH()) {
+            result.getParameters().add(new 
LiteralExpressionSegment(ctx.BOTH().getSymbol().getStartIndex(), 
ctx.BOTH().getSymbol().getStopIndex(),
+                    new 
OtherLiteralValue(ctx.BOTH().getSymbol().getText()).getValue()));
+        }
+        if (null != ctx.TRAILING()) {
+            result.getParameters().add(new 
LiteralExpressionSegment(ctx.TRAILING().getSymbol().getStartIndex(), 
ctx.TRAILING().getSymbol().getStopIndex(),
+                    new 
OtherLiteralValue(ctx.TRAILING().getSymbol().getText()).getValue()));
+        }
+        if (null != ctx.LEADING()) {
+            result.getParameters().add(new 
LiteralExpressionSegment(ctx.LEADING().getSymbol().getStartIndex(), 
ctx.LEADING().getSymbol().getStopIndex(),
+                    new 
OtherLiteralValue(ctx.LEADING().getSymbol().getText()).getValue()));
+        }
+        for (ExprContext each : ctx.expr()) {
+            result.getParameters().add((ExpressionSegment) visit(each));
+        }
+        return result;
+    }
+    
     @Override
     public ASTNode visitGraphFunction(final GraphFunctionContext ctx) {
         if (null != ctx.graphAggFunction()) {
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 2ad4839e311..4998f34fe5c 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -6436,7 +6436,7 @@
         </order-by>
     </select>
 
-    <select sql-case-id="select_with_trim_function">
+    <select sql-case-id="select_with_trim_function_multi">
         <projections start-index="7" stop-index="203" literal-start-index="7" 
literal-stop-index="203">
             <expression-projection text="TRIM('  derby ')" start-index="7" 
stop-index="22" literal-start-index="7" literal-stop-index="22">
                 <literalText>TRIM(' derby ')</literalText>
@@ -6517,6 +6517,83 @@
             <simple-table name="employees" start-index="210" stop-index="218" 
literal-start-index="210" literal-stop-index="218" />
         </from>
     </select>
+    
+    <select sql-case-id="select_with_trim_function_simple">
+        <projections start-index="7" stop-index="57">
+            <expression-projection text="TRIM( '.,! ' FROM '     #     test    
.')" start-index="7" stop-index="57" alias="Result">
+                <expr>
+                    <function function-name="TRIM" start-index="7" 
stop-index="47" text="TRIM( '.,! ' FROM '     #     test    .')">
+                        <parameter>
+                            <literal-expression value=".,! " start-index="13" 
stop-index="18" />
+                        </parameter>
+                        <parameter>
+                            <literal-expression value="     #     test    ." 
start-index="25" stop-index="46" />
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+    </select>
+    
+    <select sql-case-id="select_with_trim_function_leading">
+        <projections start-index="7" stop-index="66">
+            <expression-projection text="TRIM(LEADING '.,! ' FROM  '     .#    
 test    .')" start-index="7" stop-index="66" alias="Result">
+                <expr>
+                    <function function-name="TRIM" start-index="7" 
stop-index="56" text="TRIM(LEADING '.,! ' FROM  '     .#     test    .')">
+                        <parameter>
+                            <literal-expression value="LEADING" 
start-index="12" stop-index="18" />
+                        </parameter>
+                        <parameter>
+                            <literal-expression value=".,! " start-index="20" 
stop-index="25" />
+                        </parameter>
+                        <parameter>
+                            <literal-expression value="     .#     test    ." 
start-index="33" stop-index="55" />
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+    </select>
+    
+    <select sql-case-id="select_with_trim_function_trailing">
+        <projections start-index="7" stop-index="66">
+            <expression-projection text="TRIM(TRAILING '.,! ' FROM '     .#    
 test    .')" start-index="7" stop-index="66" alias="Result">
+                <expr>
+                    <function function-name="TRIM" start-index="7" 
stop-index="56" text="TRIM(TRAILING '.,! ' FROM '     .#     test    .')">
+                        <parameter>
+                            <literal-expression value="TRAILING" 
start-index="12" stop-index="19" />
+                        </parameter>
+                        <parameter>
+                            <literal-expression value=".,! " start-index="21" 
stop-index="26" />
+                        </parameter>
+                        <parameter>
+                            <literal-expression value="     .#     test    ." 
start-index="33" stop-index="55" />
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+    </select>
+    
+    <select sql-case-id="select_with_trim_function_both">
+        <projections start-index="7" stop-index="49">
+            <expression-projection text="TRIM(BOTH '123' FROM '123abc123')" 
start-index="7" stop-index="49" alias="Result">
+                <expr>
+                    <function function-name="TRIM" start-index="7" 
stop-index="39" text="TRIM(BOTH '123' FROM '123abc123')">
+                        <parameter>
+                            <literal-expression value="BOTH" start-index="12" 
stop-index="15" />
+                        </parameter>
+                        <parameter>
+                            <literal-expression value="123" start-index="17" 
stop-index="21" />
+                        </parameter>
+                        <parameter>
+                            <literal-expression value="123abc123" 
start-index="28" stop-index="38" />
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+    </select>
 
     <select sql-case-id="select_with_ratio_to_report_function">
         <projections start-index="7" stop-index="79" literal-start-index="7" 
literal-stop-index="79">
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 6147314ac3f..add821df9fd 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
@@ -208,7 +208,11 @@
     <sql-case id="select_with_percentile_functions" value="SELECT 
department_id, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary DESC) 'Median 
cont', PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY salary DESC) 'Median disc' 
FROM employees GROUP BY department_id" db-types="Oracle" />
     <sql-case id="select_with_keep_clause" value="SELECT salary,MIN(salary) 
KEEP (DENSE_RANK FIRST ORDER BY commission_pct) OVER (PARTITION BY 
department_id) 'Worst', MAX(salary) KEEP (DENSE_RANK LAST ORDER BY 
commission_pct) OVER (PARTITION BY department_id) 'Best' FROM employees ORDER 
BY department_id" db-types="Oracle" />
     <sql-case id="select_with_corr_function" value="SELECT employee_id, 
CORR(SYSDATE - hire_date, salary) FROM employees WHERE department_id in (50, 
80) ORDER BY employee_id" db-types="Oracle" />
-    <sql-case id="select_with_trim_function" value="select TRIM('  derby '), 
TRIM(BOTH ' ' FROM '  derby '), TRIM(TRAILING ' ' FROM '  derby '), TRIM(cast 
(null as char(1)) FROM '  derby '), TRIM(' ' FROM cast(null as varchar(30))), 
TRIM('y' FROM ' derby') FROM employees" db-types="Oracle" />
+    <sql-case id="select_with_trim_function_multi" value="select TRIM('  derby 
'), TRIM(BOTH ' ' FROM '  derby '), TRIM(TRAILING ' ' FROM '  derby '), 
TRIM(cast (null as char(1)) FROM '  derby '), TRIM(' ' FROM cast(null as 
varchar(30))), TRIM('y' FROM ' derby') FROM employees" db-types="Oracle" />
+    <sql-case id="select_with_trim_function_simple" value="SELECT TRIM( '.,! ' 
FROM '     #     test    .') AS Result" db-types="SQLServer" />
+    <sql-case id="select_with_trim_function_leading" value="SELECT 
TRIM(LEADING '.,! ' FROM  '     .#     test    .') AS Result" 
db-types="SQLServer" />
+    <sql-case id="select_with_trim_function_trailing" value="SELECT 
TRIM(TRAILING '.,! ' FROM '     .#     test    .') AS Result" 
db-types="SQLServer" />
+    <sql-case id="select_with_trim_function_both" value="SELECT TRIM(BOTH 
'123' FROM '123abc123') AS Result" db-types="SQLServer" />
     <sql-case id="select_with_ratio_to_report_function" value="SELECT 
TO_CHAR(RATIO_TO_REPORT(amount_sold) OVER (), '9.999') AS RATIO_TO_REPORT FROM 
sales s GROUP BY s.channel_desc" db-types="Oracle" />
     <sql-case id="select_with_sys_xmlagg_and_xmlgen" value="SELECT 
SYS_XMLAGG(last_name) a, SYS_XMLGEN(last_name) b FROM employees WHERE last_name 
LIKE 'R%' ORDER BY xmlagg;" db-types="Oracle" />
     <sql-case id="select_with_cover_pop_and_covar_samp" value="SELECT 
product_id, supplier_id, COVAR_POP(list_price, min_price)  OVER (ORDER BY 
product_id, supplier_id) AS CUM_COVP, COVAR_SAMP(list_price, min_price) OVER 
(ORDER BY product_id, supplier_id) AS CUM_COVS  FROM product_information p 
WHERE category_id = 29 ORDER BY product_id, supplier_id" db-types="Oracle" />

Reply via email to