From 2c3eb0ca0b7741875b87cae6ede325fcfd515b5b Mon Sep 17 00:00:00 2001 From: zhengke zhou <36791902+zzzk1@users.noreply.github.com> Date: Sat, 24 Feb 2024 15:09:29 +0800 Subject: [PATCH] Support parsing SQL Server SELECT TRIM (#30249) * Support parsing SQL Server SELECT TRIM * fix up * fix code format --- .../main/antlr4/imports/sqlserver/BaseRule.g4 | 11 ++- .../main/antlr4/imports/sqlserver/Keyword.g4 | 12 +++ .../statement/SQLServerStatementVisitor.java | 25 ++++++ .../src/main/resources/case/dml/select.xml | 79 ++++++++++++++++++- .../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 4ec987a43ea77..380e20c58aaa7 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 1bbf16738a687..90b39ae64e391 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 600709517d1d6..7ac2fd263e9ed 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.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 final ASTNode visitSpecialFunction(final SpecialFunctionContext ctx) { 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 2ad4839e31138..4998f34fe5cff 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 @@ - TRIM(' derby ') @@ -6517,6 +6517,83 @@ + + + + + + + +