Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -19,9 +19,15 @@

import lombok.Getter;
import org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CaseWhenExpression;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.NumberLiteralPaginationValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.PaginationValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ParameterMarkerPaginationValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ExpressionPaginationValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.ExpressionRowNumberValueSegment;

Expand Down Expand Up @@ -63,9 +69,74 @@ private Long getValue(final PaginationValueSegment paginationValueSegment, final
if (paginationValueSegment instanceof ExpressionRowNumberValueSegment) {
return ((ExpressionRowNumberValueSegment) paginationValueSegment).getValue(params);
}
if (paginationValueSegment instanceof ExpressionPaginationValueSegment) {
Long result = getValueFromExpression(((ExpressionPaginationValueSegment) paginationValueSegment).getExpression(), params);
return result;
}
return ((NumberLiteralPaginationValueSegment) paginationValueSegment).getValue();
}

private Long getValueFromExpression(final ExpressionSegment expressionSegment, final List<Object> params) {
if (expressionSegment instanceof BinaryOperationExpression) {
return getValueFromBinaryOperationExpression((BinaryOperationExpression) expressionSegment, params);
}
if (expressionSegment instanceof CaseWhenExpression) {
return getValueFromCaseWhenExpression((CaseWhenExpression) expressionSegment, params);
}
return null;
}

private Long getValueFromBinaryOperationExpression(final BinaryOperationExpression binaryOperationExpression, final List<Object> params) {
Long left = getValueFromExpression(binaryOperationExpression.getLeft(), params);
Long right = getValueFromExpression(binaryOperationExpression.getRight(), params);
if (null == left || null == right) {
return null;
}
switch (binaryOperationExpression.getOperator()) {
case "+":
return left + right;
case "-":
return left - right;
case "*":
return left * right;
case "/":
return 0L == right ? null : left / right;
default:
return null;
}
}

private Long getValueFromCaseWhenExpression(final CaseWhenExpression caseWhenExpression, final List<Object> params) {
if (null != caseWhenExpression.getCaseExpr()) {
return null;
}
java.util.Iterator<ExpressionSegment> whenIterator = caseWhenExpression.getWhenExprs().iterator();
java.util.Iterator<ExpressionSegment> thenIterator = caseWhenExpression.getThenExprs().iterator();
while (whenIterator.hasNext() && thenIterator.hasNext()) {
Boolean whenValue = getBooleanValueFromExpression(whenIterator.next(), params);
if (Boolean.TRUE.equals(whenValue)) {
return getValueFromExpression(thenIterator.next(), params);
}
thenIterator.next();
}
return null == caseWhenExpression.getElseExpr() ? null : getValueFromExpression(caseWhenExpression.getElseExpr(), params);
}

private Boolean getBooleanValueFromExpression(final ExpressionSegment expressionSegment, final List<Object> params) {
if (expressionSegment instanceof LiteralExpressionSegment) {
Object literals = ((LiteralExpressionSegment) expressionSegment).getLiterals();
if (literals instanceof Boolean) {
return (Boolean) literals;
}
return null == literals ? null : Boolean.parseBoolean(literals.toString());
}
if (expressionSegment instanceof ParameterMarkerExpressionSegment) {
Object obj = null == params || params.isEmpty() ? null : params.get(((ParameterMarkerExpressionSegment) expressionSegment).getParameterMarkerIndex());
return null == obj ? null : Boolean.parseBoolean(obj.toString());
}
return null;
}

/**
* Get offset segment.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ExpressionPaginationValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.NumberLiteralPaginationValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.PaginationValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ParameterMarkerLimitValueSegment;
import org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;

import java.util.Optional;

Expand All @@ -42,9 +44,13 @@ public final class PaginationValueSQLConverter {
* @return SQL node
*/
public static Optional<SqlNode> convert(final PaginationValueSegment segment) {
return Optional.of(segment instanceof NumberLiteralPaginationValueSegment
? getLiteralSQLNode((NumberLiteralPaginationValueSegment) segment)
: getParameterMarkerSQLNode((ParameterMarkerLimitValueSegment) segment));
if (segment instanceof NumberLiteralPaginationValueSegment) {
return Optional.of(getLiteralSQLNode((NumberLiteralPaginationValueSegment) segment));
}
if (segment instanceof ExpressionPaginationValueSegment) {
return ExpressionConverter.convert(((ExpressionPaginationValueSegment) segment).getExpression());
}
return Optional.of(getParameterMarkerSQLNode((ParameterMarkerLimitValueSegment) segment));
}

private static SqlNode getLiteralSQLNode(final NumberLiteralPaginationValueSegment segment) {
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 @@ -167,6 +167,7 @@
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ExpressionLimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.NumberLiteralLimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ParameterMarkerLimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.HavingSegment;
Expand Down Expand Up @@ -444,7 +445,7 @@ public ASTNode visitCaseExpr(final CaseExprContext ctx) {
}
ExpressionSegment caseExpr = null == ctx.caseArg() ? null : (ExpressionSegment) visit(ctx.caseArg().aExpr());
ExpressionSegment elseExpr = null == ctx.caseDefault() ? null : (ExpressionSegment) visit(ctx.caseDefault().aExpr());
return new CaseWhenExpression(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr);
return new CaseWhenExpression(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr, getOriginalText(ctx));
}

@Override
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 createLimitValueSegment(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(), Long.parseLong(((ExpressionSegment) astNode).getText()));
return createLimitValueSegment(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 createLimitValueSegment(ctx, (ExpressionSegment) visit(ctx.aExpr()));
}

private LimitValueSegment createLimitValueSegment(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 createLimitValueSegment(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()));
return new ExpressionLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), 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 @@ -168,6 +168,7 @@
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ExpressionLimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.NumberLiteralLimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ParameterMarkerLimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.HavingSegment;
Expand Down Expand Up @@ -445,7 +446,7 @@ public ASTNode visitCaseExpr(final CaseExprContext ctx) {
}
ExpressionSegment caseExpr = null == ctx.caseArg() ? null : (ExpressionSegment) visit(ctx.caseArg().aExpr());
ExpressionSegment elseExpr = null == ctx.caseDefault() ? null : (ExpressionSegment) visit(ctx.caseDefault().aExpr());
return new CaseWhenExpression(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr);
return new CaseWhenExpression(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr, getOriginalText(ctx));
}

@Override
Expand Down Expand Up @@ -1361,32 +1362,34 @@ 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 createLimitValueSegment(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 createLimitValueSegment(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 createLimitValueSegment(ctx, (ExpressionSegment) visit(ctx.aExpr()));
}

private LimitValueSegment createLimitValueSegment(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 createLimitValueSegment(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()));
return new ExpressionLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), segment);
}

private LimitSegment createLimitSegmentWhenLimitAndOffset(final SelectLimitContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.statement.core.segment.dml.pagination;

import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;

/**
* Pagination value segment for expression.
*/
public interface ExpressionPaginationValueSegment extends PaginationValueSegment {

/**
* Get expression segment.
*
* @return expression segment
*/
ExpressionSegment getExpression();
}
Loading