Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
2. SQL Parser: Fix escape '\' in SQL causing DialectSQLParsingException - [#37943](https://github.com/apache/shardingsphere/pull/37943)
3. SQL Parser: Fix error parsing \l command SQL statement when front-end protocol is og - [#37953](https://github.com/apache/shardingsphere/pull/37953)
4. SQL Parser:Fix SQLParsingException when using reserved word `order` in ORDER BY clause - [#37958](https://github.com/apache/shardingsphere/pull/37958)
5. SQL Parser:Support '2'::int statement in PostgreSQL and openGauss - [#37962](https://github.com/apache/shardingsphere/pull/37962)

## Release 5.5.3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,15 @@ offsetClause

selectLimitValue
: ALL
| cExpr
| aExpr
;

selectOffsetValue
: cExpr
: aExpr
;

selectFetchValue
: cExpr
: aExpr
;

rowOrRows
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
import org.apache.shardingsphere.sql.parser.autogen.OpenGaussStatementParser.WindowDefinitionListContext;
import org.apache.shardingsphere.sql.parser.autogen.OpenGaussStatementParser.WithClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.OpenGaussStatementParserBaseVisitor;
import org.apache.shardingsphere.sql.parser.engine.exception.SQLParsingException;
import org.apache.shardingsphere.sql.parser.statement.core.enums.AggregationType;
import org.apache.shardingsphere.sql.parser.statement.core.enums.CombineType;
import org.apache.shardingsphere.sql.parser.statement.core.enums.JoinType;
Expand Down Expand Up @@ -1393,29 +1394,37 @@ public ASTNode visitSelectLimitValue(final SelectLimitValueContext ctx) {
if (null != ctx.ALL()) {
return null;
}
ASTNode astNode = visit(ctx.cExpr());
if (astNode instanceof ParameterMarkerExpressionSegment) {
return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment) astNode).getParameterMarkerIndex());
}
return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), Long.parseLong(((ExpressionSegment) astNode).getText()));
return toLimitValueSegment(ctx, (ExpressionSegment) visit(ctx.aExpr()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think createLimitValueSegment is better?

}

@Override
public ASTNode visitSelectOffsetValue(final SelectOffsetValueContext ctx) {
ASTNode astNode = visit(ctx.cExpr());
if (astNode instanceof ParameterMarkerExpressionSegment) {
return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment) astNode).getParameterMarkerIndex());
}
return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), Long.parseLong(((ExpressionSegment) astNode).getText()));
return toLimitValueSegment(ctx, (ExpressionSegment) visit(ctx.aExpr()));
}

@Override
public ASTNode visitSelectFetchValue(final SelectFetchValueContext ctx) {
ASTNode astNode = visit(ctx.cExpr());
if (astNode instanceof ParameterMarkerExpressionSegment) {
return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment) astNode).getParameterMarkerIndex());
return toLimitValueSegment(ctx, (ExpressionSegment) visit(ctx.aExpr()));
}

private LimitValueSegment toLimitValueSegment(final ParserRuleContext ctx, final ExpressionSegment segment) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think createLimitValueSegment is better?

if (segment instanceof ParameterMarkerExpressionSegment) {
return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
((ParameterMarkerExpressionSegment) segment).getParameterMarkerIndex());
}
if (segment instanceof TypeCastExpression) {
return toLimitValueSegment(ctx, ((TypeCastExpression) segment).getExpression());
}
if (segment instanceof LiteralExpressionSegment) {
Object literals = ((LiteralExpressionSegment) segment).getLiterals();
if (null == literals) {
return ctx instanceof SelectOffsetValueContext
? new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), 0L)
: null;
}
return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), Long.parseLong(literals.toString()));
}
return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), Long.parseLong(((ExpressionSegment) astNode).getText()));
throw new SQLParsingException("Unsupported LIMIT expression: " + segment.getText());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add this check? openGauss does not support limit segment?

}

private LimitSegment createLimitSegmentWhenLimitAndOffset(final SelectLimitContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,16 +233,16 @@ offsetClause
;

selectLimitValue
: cExpr
: aExpr
| ALL
;

selectOffsetValue
: cExpr
: aExpr
;

selectFetchValue
: cExpr
: aExpr
;

rowOrRows
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WindowDefinitionListContext;
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WithClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParserBaseVisitor;
import org.apache.shardingsphere.sql.parser.engine.exception.SQLParsingException;
import org.apache.shardingsphere.sql.parser.statement.core.enums.AggregationType;
import org.apache.shardingsphere.sql.parser.statement.core.enums.CombineType;
import org.apache.shardingsphere.sql.parser.statement.core.enums.JoinType;
Expand Down Expand Up @@ -1361,32 +1362,37 @@ public ASTNode visitSelectLimitValue(final SelectLimitValueContext ctx) {
if (null != ctx.ALL()) {
return null;
}
ASTNode astNode = visit(ctx.cExpr());
if (astNode instanceof ParameterMarkerExpressionSegment) {
return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment) astNode).getParameterMarkerIndex());
}
return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(),
(null == ((ExpressionSegment) astNode).getText()) ? null : Long.parseLong(((ExpressionSegment) astNode).getText()));
return toLimitValueSegment(ctx, (ExpressionSegment) visit(ctx.aExpr()));
}

@Override
public ASTNode visitSelectOffsetValue(final SelectOffsetValueContext ctx) {
ASTNode astNode = visit(ctx.cExpr());
if (astNode instanceof ParameterMarkerExpressionSegment) {
return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment) astNode).getParameterMarkerIndex());
}
return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(),
(null == ((ExpressionSegment) astNode).getText()) ? null : Long.parseLong(((ExpressionSegment) astNode).getText()));
return toLimitValueSegment(ctx, (ExpressionSegment) visit(ctx.aExpr()));
}

@Override
public ASTNode visitSelectFetchValue(final SelectFetchValueContext ctx) {
ASTNode astNode = visit(ctx.cExpr());
if (astNode instanceof ParameterMarkerExpressionSegment) {
return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment) astNode).getParameterMarkerIndex());
return toLimitValueSegment(ctx, (ExpressionSegment) visit(ctx.aExpr()));
}

private LimitValueSegment toLimitValueSegment(final ParserRuleContext ctx, final ExpressionSegment segment) {
if (segment instanceof ParameterMarkerExpressionSegment) {
return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
((ParameterMarkerExpressionSegment) segment).getParameterMarkerIndex());
}
if (segment instanceof TypeCastExpression) {
return toLimitValueSegment(ctx, ((TypeCastExpression) segment).getExpression());
}
if (segment instanceof LiteralExpressionSegment) {
Object literals = ((LiteralExpressionSegment) segment).getLiterals();
if (null == literals) {
return ctx instanceof SelectOffsetValueContext
? new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), 0L)
: null;
}
return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), Long.parseLong(literals.toString()));
}
return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(),
(null == ((ExpressionSegment) astNode).getText()) ? null : Long.parseLong(((ExpressionSegment) astNode).getText()));
throw new SQLParsingException("Unsupported LIMIT expression: " + segment.getText());
}

private LimitSegment createLimitSegmentWhenLimitAndOffset(final SelectLimitContext ctx) {
Expand Down
60 changes: 60 additions & 0 deletions test/it/parser/src/main/resources/case/dml/select.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13802,4 +13802,64 @@
<index-item index="1" start-index="291" stop-index="291"/>
</order-by>
</select>

<select sql-case-id="select_pg_int">
<from>
<simple-table name="t4" start-index="14" stop-index="15" />
</from>
<projections start-index="7" stop-index="7">
<shorthand-projection start-index="7" stop-index="7" />
</projections>
<limit start-index="17" stop-index="30">
<row-count value="2" start-index="23" stop-index="30">
<type-cast-expression>
<expression>
<literal-expression value="2" start-index="23" stop-index="25" />
</expression>
<data-type>int</data-type>
</type-cast-expression>
</row-count>
</limit>
</select>

<select sql-case-id="select_pg_offset_int">
<from>
<simple-table name="t4" start-index="14" stop-index="15" />
</from>
<projections start-index="7" stop-index="7">
<shorthand-projection start-index="7" stop-index="7" />
</projections>
<limit start-index="17" stop-index="32">
<offset value="10" start-index="24" stop-index="32">
<type-cast-expression>
<expression>
<literal-expression value="10" start-index="25" stop-index="27" />
</expression>
<data-type>int</data-type>
</type-cast-expression>
</offset>
</limit>
</select>

<select sql-case-id="select_pg_fetch_next_int">
<from>
<simple-table name="t4" start-index="14" stop-index="15" />
</from>
<projections start-index="7" stop-index="7">
<shorthand-projection start-index="7" stop-index="7" />
</projections>
<order-by start-index="17" stop-index="27">
<column-item name="id" order-direction="ASC" start-index="26" stop-index="27" />
</order-by>
<limit start-index="29" stop-index="58">
<row-count value="10" start-index="40" stop-index="48">
<type-cast-expression>
<expression>
<literal-expression value="10" start-index="41" stop-index="43" />
</expression>
<data-type>int</data-type>
</type-cast-expression>
</row-count>
</limit>
</select>
</sql-parser-test-cases>
Original file line number Diff line number Diff line change
Expand Up @@ -498,4 +498,7 @@
<sql-case id="select_order_by_order" value="SELECT id FROM test ORDER BY `order` " db-types="MySQL,Hive,Doris,Presto" />
<sql-case id="select_order_by_order_two" value="SELECT id FROM t_test ORDER BY t_test.order" db-types="MySQL,Hive,Doris,SQLServer,Firebird,SQL92,Presto" />
<sql-case id="select_pg_database_info" value="SELECT d.datname as &quot;Name&quot;, pg_catalog.pg_get_userbyid(d.datdba) as &quot;Owner&quot;, pg_catalog.pg_encoding_to_char(d.encoding) as &quot;Encoding&quot;, d.datcollate as &quot;Collate&quot;, d.datctype as &quot;Ctype&quot;, pg_catalog.array_to_string(d.datacl, E'\n') AS &quot;Access privileges&quot; FROM pg_catalog.pg_database d ORDER BY 1;" db-types="openGauss" />
<sql-case id="select_pg_int" value="SELECT * FROM t4 LIMIT '2'::int;" db-types="PostgreSQL,openGauss" />
<sql-case id="select_pg_offset_int" value="SELECT * FROM t4 OFFSET '10'::int;" db-types="PostgreSQL,openGauss" />
<sql-case id="select_pg_fetch_next_int" value="SELECT * FROM t4 ORDER BY id FETCH NEXT '10'::int ROWS ONLY;" db-types="PostgreSQL,openGauss" />
</sql-cases>