tristaZero commented on a change in pull request #7353:
URL: https://github.com/apache/shardingsphere/pull/7353#discussion_r486936546
##########
File path:
shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-rewrite/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
##########
@@ -81,50 +88,65 @@
private Collection<EncryptCondition> createEncryptConditions(final
SQLStatementContext sqlStatementContext, final AndPredicate andPredicate) {
Collection<EncryptCondition> result = new LinkedList<>();
Collection<Integer> stopIndexes = new HashSet<>();
- for (PredicateSegment predicate : andPredicate.getPredicates()) {
+ for (ExpressionSegment predicate : andPredicate.getPredicates()) {
if (stopIndexes.add(predicate.getStopIndex())) {
createEncryptCondition(sqlStatementContext,
predicate).ifPresent(result::add);
}
}
return result;
}
- private Optional<EncryptCondition> createEncryptCondition(final
SQLStatementContext sqlStatementContext, final PredicateSegment
predicateSegment) {
- Optional<String> tableName =
sqlStatementContext.getTablesContext().findTableName(predicateSegment.getColumn(),
schemaMetaData);
- return tableName.isPresent() &&
encryptRule.findEncryptor(tableName.get(),
predicateSegment.getColumn().getIdentifier().getValue()).isPresent()
- ? createEncryptCondition(predicateSegment, tableName.get()) :
Optional.empty();
+ private Optional<EncryptCondition> createEncryptCondition(final
SQLStatementContext sqlStatementContext, final ExpressionSegment expression) {
+ ColumnSegment column =
ExpressionUtil.getColumnFromExpression(expression);
Review comment:
return Optional<ColumnSegment>
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/MySQLVisitor.java
##########
@@ -255,123 +254,173 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
+ if (null != ctx.XOR()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator("XOR");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.logicalOperator()) {
- return new PredicateBuildUtils(visit(ctx.expr(0)),
visit(ctx.expr(1)), ctx.logicalOperator().getText()).mergePredicate();
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator(ctx.logicalOperator().getText());
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- // TODO deal with XOR
- return visit(ctx.expr().get(0));
+ NotExpression result = new NotExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setExpression((ExpressionSegment) visit(ctx.expr(0)));
+ return result;
}
@Override
public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
+ if (null != ctx.IS()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ result.setRight(new
LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 1,
ctx.stop.getStopIndex(), new Interval(ctx.IS().getSymbol().getStopIndex() + 1,
+ ctx.stop.getStopIndex())));
+ result.setOperator("IS");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) {
return createCompareSegment(ctx);
}
- if (null != ctx.predicate()) {
- return visit(ctx.predicate());
- }
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- //TODO deal with IS NOT? (TRUE | FALSE | UNKNOWN | NULL)
- String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
- return new CommonExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), text);
+ return visit(ctx.predicate());
}
private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) {
- ASTNode leftValue = visit(ctx.booleanPrimary());
- if (!(leftValue instanceof ColumnSegment)) {
- return leftValue;
- }
- PredicateRightValue rightValue = (PredicateRightValue)
createPredicateRightValue(ctx);
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (ColumnSegment) leftValue, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx)
{
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- ASTNode rightValue = visit(ctx.predicate());
- return createPredicateRightValue(ctx, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx,
final ASTNode rightValue) {
- if (rightValue instanceof ColumnSegment) {
- return rightValue;
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ if (null != ctx.predicate()) {
+ result.setRight((ExpressionSegment) visit(ctx.predicate()));
+ } else {
+ result.setRight((ExpressionSegment) visit(ctx.subquery()));
}
- return rightValue instanceof SubquerySegment ? new
PredicateCompareRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- ctx.comparisonOperator().getText(), new
SubqueryExpressionSegment((SubquerySegment) rightValue))
- : new
PredicateCompareRightValue(ctx.predicate().start.getStartIndex(),
ctx.predicate().stop.getStopIndex(), ctx.comparisonOperator().getText(),
- (ExpressionSegment) rightValue);
+ String operator = null != ctx.SAFE_EQ_() ? ctx.SAFE_EQ_().getText() :
ctx.comparisonOperator().getText();
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
@Override
public final ASTNode visitPredicate(final PredicateContext ctx) {
- if (null != ctx.IN() && null == ctx.NOT()) {
+ if (null != ctx.IN()) {
return createInSegment(ctx);
}
- if (null != ctx.BETWEEN() && null == ctx.NOT()) {
+ if (null != ctx.BETWEEN()) {
return createBetweenSegment(ctx);
}
- if (1 == ctx.children.size()) {
- return visit(ctx.bitExpr(0));
+ if (null != ctx.LIKE()) {
+ return createBinaryOperationExpressionFromLike(ctx);
}
- return visitRemainPredicate(ctx);
- }
-
- private PredicateSegment createInSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- PredicateInRightValue predicateInRightValue = null != ctx.subquery() ?
new PredicateInRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- getExpressionSegments(ctx))
- : new
PredicateInRightValue(ctx.LP_().getSymbol().getStartIndex(),
ctx.RP_().getSymbol().getStopIndex(), getExpressionSegments(ctx));
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, predicateInRightValue);
+ if (null != ctx.REGEXP()) {
+ return createBinaryOperationExpressionFromRegexp(ctx);
+ }
+ return visit(ctx.bitExpr(0));
}
- private Collection<ExpressionSegment> getExpressionSegments(final
PredicateContext ctx) {
- Collection<ExpressionSegment> result = new LinkedList<>();
+ private InExpression createInSegment(final PredicateContext ctx) {
+ InExpression result = new InExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
if (null != ctx.subquery()) {
- SubqueryContext subquery = ctx.subquery();
- result.add(new SubqueryExpressionSegment(new
SubquerySegment(subquery.getStart().getStartIndex(),
subquery.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
- return result;
- }
- for (ExprContext each : ctx.expr()) {
- result.add((ExpressionSegment) visit(each));
- }
+ result.setRight(new SubqueryExpressionSegment(new
SubquerySegment(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
+ } else {
+ ListExpression listExpression = new ListExpression();
+
listExpression.setStartIndex(ctx.LP_().getSymbol().getStartIndex());
+ listExpression.setStopIndex(ctx.RP_().getSymbol().getStopIndex());
+ for (ExprContext each : ctx.expr()) {
+ listExpression.getItems().add((ExpressionSegment) visit(each));
+ }
+ result.setRight(listExpression);
+ }
+ Boolean operator = null != ctx.NOT() ? true : false;
+ result.setNot(operator);
return result;
}
- private PredicateSegment createBetweenSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- ExpressionSegment between = (ExpressionSegment) visit(ctx.bitExpr(1));
- ExpressionSegment and = (ExpressionSegment) visit(ctx.predicate());
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, new
PredicateBetweenRightValue(between.getStartIndex(), and.getStopIndex(),
between, and));
+ private BinaryOperationExpression
createBinaryOperationExpressionFromLike(final PredicateContext ctx) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ String operator;
+ if (null != ctx.SOUNDS()) {
+ result.setRight((ExpressionSegment) visit(ctx.bitExpr(1)));
+ operator = "SOUNDS LIKE";
+ } else {
+ ListExpression listExpression = new ListExpression();
+ for (SimpleExprContext each : ctx.simpleExpr()) {
+ listExpression.getItems().add((ExpressionSegment) visit(each));
+ }
+ result.setRight(listExpression);
+ operator = null != ctx.NOT() ? "NOT LIKE" : "LIKE";
+ }
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- private ASTNode visitRemainPredicate(final PredicateContext ctx) {
- for (BitExprContext each : ctx.bitExpr()) {
- visit(each);
- }
- for (ExprContext each : ctx.expr()) {
- visit(each);
- }
- for (SimpleExprContext each : ctx.simpleExpr()) {
- visit(each);
- }
- if (null != ctx.predicate()) {
- visit(ctx.predicate());
- }
+ private BinaryOperationExpression
createBinaryOperationExpressionFromRegexp(final PredicateContext ctx) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.bitExpr(1)));
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/MySQLVisitor.java
##########
@@ -255,123 +254,173 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
+ if (null != ctx.XOR()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator("XOR");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.logicalOperator()) {
- return new PredicateBuildUtils(visit(ctx.expr(0)),
visit(ctx.expr(1)), ctx.logicalOperator().getText()).mergePredicate();
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator(ctx.logicalOperator().getText());
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- // TODO deal with XOR
- return visit(ctx.expr().get(0));
+ NotExpression result = new NotExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setExpression((ExpressionSegment) visit(ctx.expr(0)));
+ return result;
}
@Override
public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
+ if (null != ctx.IS()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ result.setRight(new
LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 1,
ctx.stop.getStopIndex(), new Interval(ctx.IS().getSymbol().getStopIndex() + 1,
+ ctx.stop.getStopIndex())));
+ result.setOperator("IS");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) {
return createCompareSegment(ctx);
}
- if (null != ctx.predicate()) {
- return visit(ctx.predicate());
- }
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- //TODO deal with IS NOT? (TRUE | FALSE | UNKNOWN | NULL)
- String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
- return new CommonExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), text);
+ return visit(ctx.predicate());
}
private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) {
- ASTNode leftValue = visit(ctx.booleanPrimary());
- if (!(leftValue instanceof ColumnSegment)) {
- return leftValue;
- }
- PredicateRightValue rightValue = (PredicateRightValue)
createPredicateRightValue(ctx);
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (ColumnSegment) leftValue, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx)
{
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- ASTNode rightValue = visit(ctx.predicate());
- return createPredicateRightValue(ctx, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx,
final ASTNode rightValue) {
- if (rightValue instanceof ColumnSegment) {
- return rightValue;
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ if (null != ctx.predicate()) {
+ result.setRight((ExpressionSegment) visit(ctx.predicate()));
+ } else {
+ result.setRight((ExpressionSegment) visit(ctx.subquery()));
}
- return rightValue instanceof SubquerySegment ? new
PredicateCompareRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- ctx.comparisonOperator().getText(), new
SubqueryExpressionSegment((SubquerySegment) rightValue))
- : new
PredicateCompareRightValue(ctx.predicate().start.getStartIndex(),
ctx.predicate().stop.getStopIndex(), ctx.comparisonOperator().getText(),
- (ExpressionSegment) rightValue);
+ String operator = null != ctx.SAFE_EQ_() ? ctx.SAFE_EQ_().getText() :
ctx.comparisonOperator().getText();
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
@Override
public final ASTNode visitPredicate(final PredicateContext ctx) {
- if (null != ctx.IN() && null == ctx.NOT()) {
+ if (null != ctx.IN()) {
return createInSegment(ctx);
}
- if (null != ctx.BETWEEN() && null == ctx.NOT()) {
+ if (null != ctx.BETWEEN()) {
return createBetweenSegment(ctx);
}
- if (1 == ctx.children.size()) {
- return visit(ctx.bitExpr(0));
+ if (null != ctx.LIKE()) {
+ return createBinaryOperationExpressionFromLike(ctx);
}
- return visitRemainPredicate(ctx);
- }
-
- private PredicateSegment createInSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- PredicateInRightValue predicateInRightValue = null != ctx.subquery() ?
new PredicateInRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- getExpressionSegments(ctx))
- : new
PredicateInRightValue(ctx.LP_().getSymbol().getStartIndex(),
ctx.RP_().getSymbol().getStopIndex(), getExpressionSegments(ctx));
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, predicateInRightValue);
+ if (null != ctx.REGEXP()) {
+ return createBinaryOperationExpressionFromRegexp(ctx);
+ }
+ return visit(ctx.bitExpr(0));
}
- private Collection<ExpressionSegment> getExpressionSegments(final
PredicateContext ctx) {
- Collection<ExpressionSegment> result = new LinkedList<>();
+ private InExpression createInSegment(final PredicateContext ctx) {
+ InExpression result = new InExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
if (null != ctx.subquery()) {
- SubqueryContext subquery = ctx.subquery();
- result.add(new SubqueryExpressionSegment(new
SubquerySegment(subquery.getStart().getStartIndex(),
subquery.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
- return result;
- }
- for (ExprContext each : ctx.expr()) {
- result.add((ExpressionSegment) visit(each));
- }
+ result.setRight(new SubqueryExpressionSegment(new
SubquerySegment(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
+ } else {
+ ListExpression listExpression = new ListExpression();
+
listExpression.setStartIndex(ctx.LP_().getSymbol().getStartIndex());
+ listExpression.setStopIndex(ctx.RP_().getSymbol().getStopIndex());
+ for (ExprContext each : ctx.expr()) {
+ listExpression.getItems().add((ExpressionSegment) visit(each));
+ }
+ result.setRight(listExpression);
+ }
+ Boolean operator = null != ctx.NOT() ? true : false;
+ result.setNot(operator);
return result;
}
- private PredicateSegment createBetweenSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- ExpressionSegment between = (ExpressionSegment) visit(ctx.bitExpr(1));
- ExpressionSegment and = (ExpressionSegment) visit(ctx.predicate());
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, new
PredicateBetweenRightValue(between.getStartIndex(), and.getStopIndex(),
between, and));
+ private BinaryOperationExpression
createBinaryOperationExpressionFromLike(final PredicateContext ctx) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ String operator;
+ if (null != ctx.SOUNDS()) {
+ result.setRight((ExpressionSegment) visit(ctx.bitExpr(1)));
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/OracleVisitor.java
##########
@@ -236,120 +234,141 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
if (null != ctx.logicalOperator()) {
- return new PredicateBuildUtils(visit(ctx.expr(0)),
visit(ctx.expr(1)), ctx.logicalOperator().getText()).mergePredicate();
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator(ctx.logicalOperator().getText());
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- // TODO deal with XOR
- return visit(ctx.expr().get(0));
+ NotExpression result = new NotExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setExpression((ExpressionSegment) visit(ctx.expr(0)));
+ return result;
}
@Override
public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
+ if (null != ctx.IS()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ result.setRight(new
LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 1,
ctx.stop.getStopIndex(), new Interval(ctx.IS().getSymbol().getStopIndex() + 1,
+ ctx.stop.getStopIndex())));
+ result.setOperator("IS");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) {
return createCompareSegment(ctx);
}
- if (null != ctx.predicate()) {
- return visit(ctx.predicate());
- }
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- //TODO deal with IS NOT? (TRUE | FALSE | UNKNOWN | NULL)
- return new CommonExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ctx.getText());
+ return visit(ctx.predicate());
}
private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) {
- ASTNode leftValue = visit(ctx.booleanPrimary());
- if (!(leftValue instanceof ColumnSegment)) {
- return leftValue;
- }
- PredicateRightValue rightValue = (PredicateRightValue)
createPredicateRightValue(ctx);
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (ColumnSegment) leftValue, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx)
{
- if (null != ctx.subquery()) {
- new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- ASTNode rightValue = visit(ctx.predicate());
- return createPredicateRightValue(ctx, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx,
final ASTNode rightValue) {
- if (rightValue instanceof ColumnSegment) {
- return rightValue;
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ if (null != ctx.predicate()) {
+ result.setRight((ExpressionSegment) visit(ctx.predicate()));
+ } else {
+ result.setRight((ExpressionSegment) visit(ctx.subquery()));
}
- return rightValue instanceof SubquerySegment ? new
PredicateCompareRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(), ctx.comparisonOperator().getText(),
- new SubqueryExpressionSegment((SubquerySegment) rightValue))
- : new
PredicateCompareRightValue(ctx.predicate().start.getStartIndex(),
ctx.predicate().stop.getStopIndex(), ctx.comparisonOperator().getText(),
(ExpressionSegment) rightValue);
+ String operator = null != ctx.SAFE_EQ_() ? ctx.SAFE_EQ_().getText() :
ctx.comparisonOperator().getText();
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
@Override
public final ASTNode visitPredicate(final PredicateContext ctx) {
- if (null != ctx.IN() && null == ctx.NOT()) {
+ if (null != ctx.IN()) {
return createInSegment(ctx);
}
- if (null != ctx.BETWEEN() && null == ctx.NOT()) {
+ if (null != ctx.BETWEEN()) {
return createBetweenSegment(ctx);
}
- if (1 == ctx.children.size()) {
- return visit(ctx.bitExpr(0));
+ if (null != ctx.LIKE()) {
+ return createBinaryOperationExpressionFromLike(ctx);
}
- return visitRemainPredicate(ctx);
+ return visit(ctx.bitExpr(0));
}
- private PredicateSegment createInSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- PredicateInRightValue predicateInRightValue = null != ctx.subquery() ?
new PredicateInRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- getExpressionSegments(ctx))
- : new
PredicateInRightValue(ctx.LP_().getSymbol().getStartIndex(),
ctx.RP_().getSymbol().getStopIndex(), getExpressionSegments(ctx));
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, predicateInRightValue);
- }
-
- private Collection<ExpressionSegment> getExpressionSegments(final
PredicateContext ctx) {
- Collection<ExpressionSegment> result = new LinkedList<>();
+ private InExpression createInSegment(final PredicateContext ctx) {
+ InExpression result = new InExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
if (null != ctx.subquery()) {
- SubqueryContext subquery = ctx.subquery();
- result.add(new SubqueryExpressionSegment(new
SubquerySegment(subquery.getStart().getStartIndex(),
subquery.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
- return result;
- }
- for (ExprContext each : ctx.expr()) {
- result.add((ExpressionSegment) visit(each));
- }
+ result.setRight(new SubqueryExpressionSegment(new
SubquerySegment(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
+ } else {
+ ListExpression listExpression = new ListExpression();
+
listExpression.setStartIndex(ctx.LP_().getSymbol().getStartIndex());
+ listExpression.setStopIndex(ctx.RP_().getSymbol().getStopIndex());
+ for (ExprContext each : ctx.expr()) {
+ listExpression.getItems().add((ExpressionSegment) visit(each));
+ }
+ result.setRight(listExpression);
+ }
+ Boolean operator = null != ctx.NOT() ? true : false;
+ result.setNot(operator);
return result;
}
- private PredicateSegment createBetweenSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- ExpressionSegment between = (ExpressionSegment) visit(ctx.bitExpr(1));
- ExpressionSegment and = (ExpressionSegment) visit(ctx.predicate());
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, new
PredicateBetweenRightValue(between.getStartIndex(), and.getStopIndex(),
between, and));
- }
-
- private ASTNode visitRemainPredicate(final PredicateContext ctx) {
- for (BitExprContext each : ctx.bitExpr()) {
- visit(each);
- }
- for (ExprContext each : ctx.expr()) {
- visit(each);
- }
+ private BinaryOperationExpression
createBinaryOperationExpressionFromLike(final PredicateContext ctx) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ ListExpression listExpression = new ListExpression();
for (SimpleExprContext each : ctx.simpleExpr()) {
- visit(each);
- }
- if (null != ctx.predicate()) {
- visit(ctx.predicate());
+ listExpression.getItems().add((ExpressionSegment) visit(each));
}
- return new CommonExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ctx.getText());
+ result.setRight(listExpression);
+ String operator;
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/PostgreSQLVisitor.java
##########
@@ -173,26 +176,33 @@ public ASTNode visitAExpr(final AExprContext ctx) {
if (null != ctx.cExpr()) {
return visit(ctx.cExpr());
}
- if (null != ctx.BETWEEN() && null == ctx.NOT()) {
+ if (null != ctx.BETWEEN()) {
return createBetweenSegment(ctx);
}
- if (null != ctx.IN() && null == ctx.NOT()) {
+ if (null != ctx.IN()) {
return createInSegment(ctx);
}
if (null != ctx.comparisonOperator()) {
- ASTNode left = visit(ctx.aExpr(0));
- if (left instanceof ColumnSegment) {
- ColumnSegment columnSegment = (ColumnSegment) left;
- SQLSegment right = (SQLSegment) visit(ctx.aExpr(1));
- PredicateRightValue value = right instanceof ColumnSegment
- ? (PredicateRightValue) right : new
PredicateCompareRightValue(right.getStartIndex(), right.getStopIndex(),
ctx.comparisonOperator().getText(), (ExpressionSegment) right);
- return new PredicateSegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), columnSegment, value);
- }
- visit(ctx.aExpr(1));
- return new
LiteralExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ctx.getText());
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.aExpr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.aExpr(1)));
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/PostgreSQLVisitor.java
##########
@@ -250,24 +260,76 @@ public ASTNode visitColumnref(final ColumnrefContext ctx)
{
return new ColumnSegment(ctx.colId().start.getStartIndex(),
ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText()));
}
- private PredicateSegment createInSegment(final AExprContext ctx) {
- ColumnSegment column = (ColumnSegment)
visit(ctx.aExpr(0).cExpr().columnref());
- ASTNode predicateInRightValue = visit(ctx.inExpr());
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, (PredicateRightValue)
predicateInRightValue);
+ private InExpression createInSegment(final AExprContext ctx) {
+ InExpression result = new InExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.aExpr(0)));
+ result.setRight(visitInExpression(ctx.inExpr()));
+ if (null != ctx.NOT()) {
+ result.setNot(true);
+ } else {
+ result.setNot(false);
+ }
+ return result;
}
- private PredicateSegment createBetweenSegment(final AExprContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.aExpr().get(0));
- SQLSegment value = (SQLSegment) visit(ctx.bExpr());
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, new
PredicateBetweenRightValue(value.getStartIndex(), value.getStopIndex(),
- (ExpressionSegment) value, (ExpressionSegment)
visit(ctx.aExpr(1))));
+ private ExpressionSegment visitInExpression(final InExprContext ctx) {
+ if (null != ctx.selectWithParens()) {
+ SelectStatement select = (SelectStatement)
visit(ctx.selectWithParens());
+ SubquerySegment subquerySegment = new
SubquerySegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), select);
+ SubqueryExpressionSegment result = new
SubqueryExpressionSegment(subquerySegment);
+ return result;
+ }
+ return (ExpressionSegment) visit(ctx.exprList());
+ }
+
+ @Override
+ public ASTNode visitExprList(final ExprListContext ctx) {
+ ListExpression result = new ListExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ if (null != ctx.exprList()) {
+ result.getItems().addAll(((ListExpression)
visitExprList(ctx.exprList())).getItems());
+ }
+ result.getItems().add((ExpressionSegment) visit(ctx.aExpr()));
+ return result;
+ }
+
+ private BetweenExpression createBetweenSegment(final AExprContext ctx) {
+ BetweenExpression result = new BetweenExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.aExpr(0)));
+ result.setBetweenExpr((ExpressionSegment) visit(ctx.bExpr()));
+ result.setAndExpr((ExpressionSegment) visit(ctx.aExpr(1)));
+ if (null != ctx.NOT()) {
+ result.setNot(true);
+ }
+ return result;
}
@Override
public ASTNode visitBExpr(final BExprContext ctx) {
if (null != ctx.cExpr()) {
return visit(ctx.cExpr());
}
+ if (null != ctx.TYPE_CAST_() || null != ctx.qualOp()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bExpr(0)));
+ if (null != ctx.TYPE_CAST_()) {
+ result.setOperator(ctx.TYPE_CAST_().getText());
+ result.setRight(new
CommonExpressionSegment(ctx.typeName().start.getStartIndex(),
ctx.typeName().stop.getStopIndex(), ctx.typeName().getText()));
+ } else {
Review comment:
A function is needed here.
##########
File path:
shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-route/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngine.java
##########
@@ -98,22 +107,45 @@
return result;
}
- private Map<Column, Collection<RouteValue>> createRouteValueMap(final
SQLStatementContext sqlStatementContext, final AndPredicate andPredicate, final
List<Object> parameters) {
+ private Map<Column, Collection<RouteValue>> createRouteValueMap(final
SQLStatementContext sqlStatementContext, final AndPredicate expressions, final
List<Object> parameters) {
Map<Column, Collection<RouteValue>> result = new HashMap<>();
- for (PredicateSegment each : andPredicate.getPredicates()) {
- Optional<String> tableName =
sqlStatementContext.getTablesContext().findTableName(each.getColumn(),
schemaMetaData);
- if (!tableName.isPresent() ||
!shardingRule.isShardingColumn(each.getColumn().getIdentifier().getValue(),
tableName.get())) {
- continue;
+
+ for (ExpressionSegment each : expressions.getPredicates()) {
+ Optional<RouteValue> routeValue = Optional.empty();
+ Column column = null;
+ if (each instanceof BinaryOperationExpression &&
((BinaryOperationExpression) each).getLeft() instanceof ColumnSegment) {
+ ColumnSegment columnSegment = (ColumnSegment)
((BinaryOperationExpression) each).getLeft();
+ Optional<String> tableName =
sqlStatementContext.getTablesContext().findTableName(columnSegment,
schemaMetaData);
+ if (tableName.isPresent() &&
shardingRule.isShardingColumn(columnSegment.getIdentifier().getValue(),
tableName.get())) {
+ column = new
Column(columnSegment.getIdentifier().getValue(), tableName.get());
+ routeValue = ConditionValueGeneratorFactory.generate(each,
column, parameters);
+ }
}
- Column column = new
Column(each.getColumn().getIdentifier().getValue(), tableName.get());
- Optional<RouteValue> routeValue =
ConditionValueGeneratorFactory.generate(each.getRightValue(), column,
parameters);
- if (!routeValue.isPresent()) {
- continue;
+ if (each instanceof InExpression && ((InExpression)
each).getLeft() instanceof ColumnSegment) {
+ ColumnSegment columnSegment = (ColumnSegment) ((InExpression)
each).getLeft();
+ Optional<String> tableName =
sqlStatementContext.getTablesContext().findTableName(columnSegment,
schemaMetaData);
+ if (tableName.isPresent() &&
shardingRule.isShardingColumn(columnSegment.getIdentifier().getValue(),
tableName.get())) {
+ column = new
Column(columnSegment.getIdentifier().getValue(), tableName.get());
+ routeValue = ConditionValueGeneratorFactory.generate(each,
column, parameters);
+ }
}
- if (!result.containsKey(column)) {
- result.put(column, new LinkedList<>());
+ if (each instanceof BetweenExpression && ((BetweenExpression)
each).getLeft() instanceof ColumnSegment) {
+ ColumnSegment columnSegment = (ColumnSegment)
((BetweenExpression) each).getLeft();
Review comment:
Functions are needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/MySQLVisitor.java
##########
@@ -255,123 +254,173 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
+ if (null != ctx.XOR()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/impl/MySQLDMLVisitor.java
##########
@@ -516,6 +506,13 @@ private ASTNode createProjection(final ProjectionContext
ctx, final AliasSegment
result.setAlias(alias);
return result;
}
+ if (projection instanceof BinaryOperationExpression) {
+ int startIndex = ((BinaryOperationExpression)
projection).getStartIndex();
+ int stopIndex = null != alias ? alias.getStopIndex() :
((BinaryOperationExpression) projection).getStopIndex();
+ ExpressionProjectionSegment result = new
ExpressionProjectionSegment(startIndex, stopIndex, ((BinaryOperationExpression)
projection).getText());
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/SQLServerVisitor.java
##########
@@ -244,121 +241,141 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
if (null != ctx.logicalOperator()) {
- return new PredicateBuildUtils(visit(ctx.expr(0)),
visit(ctx.expr(1)), ctx.logicalOperator().getText()).mergePredicate();
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator(ctx.logicalOperator().getText());
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- // TODO deal with XOR
- return visit(ctx.expr().get(0));
+ NotExpression result = new NotExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setExpression((ExpressionSegment) visit(ctx.expr(0)));
+ return result;
}
@Override
public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
+ if (null != ctx.IS()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ result.setRight(new
LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 1,
ctx.stop.getStopIndex(), new Interval(ctx.IS().getSymbol().getStopIndex() + 1,
+ ctx.stop.getStopIndex())));
+ result.setOperator("IS");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) {
return createCompareSegment(ctx);
}
- if (null != ctx.predicate()) {
- return visit(ctx.predicate());
- }
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- //TODO deal with IS NOT? (TRUE | FALSE | UNKNOWN | NULL)
- return new CommonExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ctx.getText());
+ return visit(ctx.predicate());
}
private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) {
- ASTNode leftValue = visit(ctx.booleanPrimary());
- if (!(leftValue instanceof ColumnSegment)) {
- return leftValue;
- }
- PredicateRightValue rightValue = (PredicateRightValue)
createPredicateRightValue(ctx);
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (ColumnSegment) leftValue, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx)
{
- if (null != ctx.subquery()) {
- new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- ASTNode rightValue = visit(ctx.predicate());
- return createPredicateRightValue(ctx, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx,
final ASTNode rightValue) {
- if (rightValue instanceof ColumnSegment) {
- return rightValue;
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ if (null != ctx.predicate()) {
+ result.setRight((ExpressionSegment) visit(ctx.predicate()));
+ } else {
+ result.setRight((ExpressionSegment) visit(ctx.subquery()));
}
- return rightValue instanceof SubquerySegment ? new
PredicateCompareRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(), ctx.comparisonOperator().getText(),
- new SubqueryExpressionSegment((SubquerySegment) rightValue))
- : new
PredicateCompareRightValue(ctx.predicate().start.getStartIndex(),
ctx.predicate().stop.getStopIndex(), ctx.comparisonOperator().getText(),
(ExpressionSegment) rightValue);
+ String operator = null != ctx.SAFE_EQ_() ? ctx.SAFE_EQ_().getText() :
ctx.comparisonOperator().getText();
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
@Override
public final ASTNode visitPredicate(final PredicateContext ctx) {
- if (null != ctx.IN() && null == ctx.NOT()) {
+ if (null != ctx.IN()) {
return createInSegment(ctx);
}
- if (null != ctx.BETWEEN() && null == ctx.NOT()) {
+ if (null != ctx.BETWEEN()) {
return createBetweenSegment(ctx);
}
- if (1 == ctx.children.size()) {
- return visit(ctx.bitExpr(0));
+ if (null != ctx.LIKE()) {
+ return createBinaryOperationExpressionFromLike(ctx);
}
- return visitRemainPredicate(ctx);
- }
-
- private PredicateSegment createInSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- PredicateInRightValue predicateInRightValue = null != ctx.subquery() ?
new PredicateInRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- getExpressionSegments(ctx))
- : new
PredicateInRightValue(ctx.LP_().getSymbol().getStartIndex(),
ctx.RP_().getSymbol().getStopIndex(), getExpressionSegments(ctx));
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, predicateInRightValue);
+ return visit(ctx.bitExpr(0));
}
- private Collection<ExpressionSegment> getExpressionSegments(final
PredicateContext ctx) {
- Collection<ExpressionSegment> result = new LinkedList<>();
- if (null != ctx.subquery()) {
- SubqueryContext subquery = ctx.subquery();
- result.add(new SubqueryExpressionSegment(new
SubquerySegment(subquery.getStart().getStartIndex(),
subquery.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
- return result;
- }
- for (ExprContext each : ctx.expr()) {
- result.add((ExpressionSegment) visit(each));
+ private BinaryOperationExpression
createBinaryOperationExpressionFromLike(final PredicateContext ctx) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ ListExpression listExpression = new ListExpression();
+ for (SimpleExprContext each : ctx.simpleExpr()) {
+ listExpression.getItems().add((ExpressionSegment) visit(each));
}
+ result.setRight(listExpression);
+ String operator;
+ operator = null != ctx.NOT() ? "NOT LIKE" : "LIKE";
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
return result;
}
- private PredicateSegment createBetweenSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- ExpressionSegment between = (ExpressionSegment) visit(ctx.bitExpr(1));
- ExpressionSegment and = (ExpressionSegment) visit(ctx.predicate());
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, new
PredicateBetweenRightValue(between.getStartIndex(), and.getStopIndex(),
between, and));
+ private InExpression createInSegment(final PredicateContext ctx) {
+ InExpression result = new InExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ if (null != ctx.subquery()) {
+ result.setRight(new SubqueryExpressionSegment(new
SubquerySegment(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
+ } else {
+ ListExpression listExpression = new ListExpression();
+
listExpression.setStartIndex(ctx.LP_().getSymbol().getStartIndex());
+ listExpression.setStopIndex(ctx.RP_().getSymbol().getStopIndex());
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/MySQLVisitor.java
##########
@@ -255,123 +254,173 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
+ if (null != ctx.XOR()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator("XOR");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.logicalOperator()) {
- return new PredicateBuildUtils(visit(ctx.expr(0)),
visit(ctx.expr(1)), ctx.logicalOperator().getText()).mergePredicate();
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator(ctx.logicalOperator().getText());
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- // TODO deal with XOR
- return visit(ctx.expr().get(0));
+ NotExpression result = new NotExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setExpression((ExpressionSegment) visit(ctx.expr(0)));
+ return result;
}
@Override
public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
+ if (null != ctx.IS()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ result.setRight(new
LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 1,
ctx.stop.getStopIndex(), new Interval(ctx.IS().getSymbol().getStopIndex() + 1,
+ ctx.stop.getStopIndex())));
+ result.setOperator("IS");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) {
return createCompareSegment(ctx);
}
- if (null != ctx.predicate()) {
- return visit(ctx.predicate());
- }
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- //TODO deal with IS NOT? (TRUE | FALSE | UNKNOWN | NULL)
- String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
- return new CommonExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), text);
+ return visit(ctx.predicate());
}
private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) {
- ASTNode leftValue = visit(ctx.booleanPrimary());
- if (!(leftValue instanceof ColumnSegment)) {
- return leftValue;
- }
- PredicateRightValue rightValue = (PredicateRightValue)
createPredicateRightValue(ctx);
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (ColumnSegment) leftValue, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx)
{
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- ASTNode rightValue = visit(ctx.predicate());
- return createPredicateRightValue(ctx, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx,
final ASTNode rightValue) {
- if (rightValue instanceof ColumnSegment) {
- return rightValue;
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ if (null != ctx.predicate()) {
+ result.setRight((ExpressionSegment) visit(ctx.predicate()));
+ } else {
+ result.setRight((ExpressionSegment) visit(ctx.subquery()));
}
- return rightValue instanceof SubquerySegment ? new
PredicateCompareRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- ctx.comparisonOperator().getText(), new
SubqueryExpressionSegment((SubquerySegment) rightValue))
- : new
PredicateCompareRightValue(ctx.predicate().start.getStartIndex(),
ctx.predicate().stop.getStopIndex(), ctx.comparisonOperator().getText(),
- (ExpressionSegment) rightValue);
+ String operator = null != ctx.SAFE_EQ_() ? ctx.SAFE_EQ_().getText() :
ctx.comparisonOperator().getText();
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
@Override
public final ASTNode visitPredicate(final PredicateContext ctx) {
- if (null != ctx.IN() && null == ctx.NOT()) {
+ if (null != ctx.IN()) {
return createInSegment(ctx);
}
- if (null != ctx.BETWEEN() && null == ctx.NOT()) {
+ if (null != ctx.BETWEEN()) {
return createBetweenSegment(ctx);
}
- if (1 == ctx.children.size()) {
- return visit(ctx.bitExpr(0));
+ if (null != ctx.LIKE()) {
+ return createBinaryOperationExpressionFromLike(ctx);
}
- return visitRemainPredicate(ctx);
- }
-
- private PredicateSegment createInSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- PredicateInRightValue predicateInRightValue = null != ctx.subquery() ?
new PredicateInRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- getExpressionSegments(ctx))
- : new
PredicateInRightValue(ctx.LP_().getSymbol().getStartIndex(),
ctx.RP_().getSymbol().getStopIndex(), getExpressionSegments(ctx));
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, predicateInRightValue);
+ if (null != ctx.REGEXP()) {
+ return createBinaryOperationExpressionFromRegexp(ctx);
+ }
+ return visit(ctx.bitExpr(0));
}
- private Collection<ExpressionSegment> getExpressionSegments(final
PredicateContext ctx) {
- Collection<ExpressionSegment> result = new LinkedList<>();
+ private InExpression createInSegment(final PredicateContext ctx) {
+ InExpression result = new InExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
if (null != ctx.subquery()) {
- SubqueryContext subquery = ctx.subquery();
- result.add(new SubqueryExpressionSegment(new
SubquerySegment(subquery.getStart().getStartIndex(),
subquery.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
- return result;
- }
- for (ExprContext each : ctx.expr()) {
- result.add((ExpressionSegment) visit(each));
- }
+ result.setRight(new SubqueryExpressionSegment(new
SubquerySegment(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
+ } else {
+ ListExpression listExpression = new ListExpression();
+
listExpression.setStartIndex(ctx.LP_().getSymbol().getStartIndex());
+ listExpression.setStopIndex(ctx.RP_().getSymbol().getStopIndex());
+ for (ExprContext each : ctx.expr()) {
+ listExpression.getItems().add((ExpressionSegment) visit(each));
+ }
+ result.setRight(listExpression);
+ }
+ Boolean operator = null != ctx.NOT() ? true : false;
+ result.setNot(operator);
return result;
}
- private PredicateSegment createBetweenSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- ExpressionSegment between = (ExpressionSegment) visit(ctx.bitExpr(1));
- ExpressionSegment and = (ExpressionSegment) visit(ctx.predicate());
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, new
PredicateBetweenRightValue(between.getStartIndex(), and.getStopIndex(),
between, and));
+ private BinaryOperationExpression
createBinaryOperationExpressionFromLike(final PredicateContext ctx) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ String operator;
+ if (null != ctx.SOUNDS()) {
+ result.setRight((ExpressionSegment) visit(ctx.bitExpr(1)));
+ operator = "SOUNDS LIKE";
+ } else {
+ ListExpression listExpression = new ListExpression();
+ for (SimpleExprContext each : ctx.simpleExpr()) {
+ listExpression.getItems().add((ExpressionSegment) visit(each));
+ }
+ result.setRight(listExpression);
+ operator = null != ctx.NOT() ? "NOT LIKE" : "LIKE";
+ }
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- private ASTNode visitRemainPredicate(final PredicateContext ctx) {
- for (BitExprContext each : ctx.bitExpr()) {
- visit(each);
- }
- for (ExprContext each : ctx.expr()) {
- visit(each);
- }
- for (SimpleExprContext each : ctx.simpleExpr()) {
- visit(each);
- }
- if (null != ctx.predicate()) {
- visit(ctx.predicate());
- }
+ private BinaryOperationExpression
createBinaryOperationExpressionFromRegexp(final PredicateContext ctx) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.bitExpr(1)));
+ String operator = null != ctx.NOT() ? "NOT REGEXP" : "REGEXP";
+ result.setOperator(operator);
String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
- return new CommonExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), text);
+ result.setText(text);
+ return result;
+ }
+
+ private BetweenExpression createBetweenSegment(final PredicateContext ctx)
{
+ BetweenExpression result = new BetweenExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/OracleVisitor.java
##########
@@ -236,120 +234,141 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
if (null != ctx.logicalOperator()) {
- return new PredicateBuildUtils(visit(ctx.expr(0)),
visit(ctx.expr(1)), ctx.logicalOperator().getText()).mergePredicate();
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator(ctx.logicalOperator().getText());
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- // TODO deal with XOR
- return visit(ctx.expr().get(0));
+ NotExpression result = new NotExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setExpression((ExpressionSegment) visit(ctx.expr(0)));
+ return result;
}
@Override
public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
+ if (null != ctx.IS()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ result.setRight(new
LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 1,
ctx.stop.getStopIndex(), new Interval(ctx.IS().getSymbol().getStopIndex() + 1,
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sql92/src/main/java/org/apache/shardingsphere/sql/parser/sql92/visitor/SQL92Visitor.java
##########
@@ -229,123 +227,141 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
if (null != ctx.logicalOperator()) {
- return new PredicateBuildUtils(visit(ctx.expr(0)),
visit(ctx.expr(1)), ctx.logicalOperator().getText()).mergePredicate();
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator(ctx.logicalOperator().getText());
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- // TODO deal with XOR
- return visit(ctx.expr().get(0));
+ NotExpression result = new NotExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setExpression((ExpressionSegment) visit(ctx.expr(0)));
+ return result;
}
@Override
public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
+ if (null != ctx.IS()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ result.setRight(new
LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 1,
ctx.stop.getStopIndex(), new Interval(ctx.IS().getSymbol().getStopIndex() + 1,
+ ctx.stop.getStopIndex())));
+ result.setOperator("IS");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) {
return createCompareSegment(ctx);
}
- if (null != ctx.predicate()) {
- return visit(ctx.predicate());
- }
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- //TODO deal with IS NOT? (TRUE | FALSE | UNKNOWN | NULL)
- String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
- return new CommonExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), text);
+ return visit(ctx.predicate());
}
private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) {
- ASTNode leftValue = visit(ctx.booleanPrimary());
- if (!(leftValue instanceof ColumnSegment)) {
- return leftValue;
- }
- PredicateRightValue rightValue = (PredicateRightValue)
createPredicateRightValue(ctx);
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (ColumnSegment) leftValue, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx)
{
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- ASTNode rightValue = visit(ctx.predicate());
- return createPredicateRightValue(ctx, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx,
final ASTNode rightValue) {
- if (rightValue instanceof ColumnSegment) {
- return rightValue;
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ if (null != ctx.predicate()) {
+ result.setRight((ExpressionSegment) visit(ctx.predicate()));
+ } else {
+ result.setRight((ExpressionSegment) visit(ctx.subquery()));
}
- return rightValue instanceof SubquerySegment ? new
PredicateCompareRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- ctx.comparisonOperator().getText(), new
SubqueryExpressionSegment((SubquerySegment) rightValue))
- : new
PredicateCompareRightValue(ctx.predicate().start.getStartIndex(),
ctx.predicate().stop.getStopIndex(), ctx.comparisonOperator().getText(),
- (ExpressionSegment) rightValue);
+ String operator = null != ctx.SAFE_EQ_() ? ctx.SAFE_EQ_().getText() :
ctx.comparisonOperator().getText();
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
@Override
public final ASTNode visitPredicate(final PredicateContext ctx) {
- if (null != ctx.IN() && null == ctx.NOT()) {
+ if (null != ctx.IN()) {
return createInSegment(ctx);
}
- if (null != ctx.BETWEEN() && null == ctx.NOT()) {
+ if (null != ctx.BETWEEN()) {
return createBetweenSegment(ctx);
}
- if (1 == ctx.children.size()) {
- return visit(ctx.bitExpr(0));
+ if (null != ctx.LIKE()) {
+ return createBinaryOperationExpressionFromLike(ctx);
}
- return visitRemainPredicate(ctx);
- }
-
- private PredicateSegment createInSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- PredicateInRightValue predicateInRightValue = null != ctx.subquery() ?
new PredicateInRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- getExpressionSegments(ctx))
- : new
PredicateInRightValue(ctx.LP_().getSymbol().getStartIndex(),
ctx.RP_().getSymbol().getStopIndex(), getExpressionSegments(ctx));
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, predicateInRightValue);
+ return visit(ctx.bitExpr(0));
}
- private Collection<ExpressionSegment> getExpressionSegments(final
PredicateContext ctx) {
- Collection<ExpressionSegment> result = new LinkedList<>();
- if (null != ctx.subquery()) {
- SubqueryContext subquery = ctx.subquery();
- result.add(new SubqueryExpressionSegment(new
SubquerySegment(subquery.getStart().getStartIndex(),
subquery.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
- return result;
- }
- for (ExprContext each : ctx.expr()) {
- result.add((ExpressionSegment) visit(each));
+ private BinaryOperationExpression
createBinaryOperationExpressionFromLike(final PredicateContext ctx) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ ListExpression listExpression = new ListExpression();
+ for (SimpleExprContext each : ctx.simpleExpr()) {
+ listExpression.getItems().add((ExpressionSegment) visit(each));
}
+ result.setRight(listExpression);
+ String operator;
+ operator = null != ctx.NOT() ? "NOT LIKE" : "LIKE";
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
return result;
}
- private PredicateSegment createBetweenSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- ExpressionSegment between = (ExpressionSegment) visit(ctx.bitExpr(1));
- ExpressionSegment and = (ExpressionSegment) visit(ctx.predicate());
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, new
PredicateBetweenRightValue(between.getStartIndex(), and.getStopIndex(),
between, and));
+ private InExpression createInSegment(final PredicateContext ctx) {
+ InExpression result = new InExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ if (null != ctx.subquery()) {
+ result.setRight(new SubqueryExpressionSegment(new
SubquerySegment(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
+ } else {
+ ListExpression listExpression = new ListExpression();
+
listExpression.setStartIndex(ctx.LP_().getSymbol().getStartIndex());
+ listExpression.setStopIndex(ctx.RP_().getSymbol().getStopIndex());
+ for (ExprContext each : ctx.expr()) {
Review comment:
A function is needed here.
##########
File path:
shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-route/src/main/java/org/apache/shardingsphere/shadow/route/engine/judge/impl/PreparedShadowDataSourceJudgeEngine.java
##########
@@ -61,27 +63,46 @@ public boolean isShadow() {
}
return false;
}
- if (sqlStatementContext instanceof WhereAvailable) {
- Optional<WhereSegment> whereSegment = ((WhereAvailable)
sqlStatementContext).getWhere();
- if (!whereSegment.isPresent()) {
- return false;
- }
- Collection<AndPredicate> andPredicates =
whereSegment.get().getAndPredicates();
- for (AndPredicate andPredicate : andPredicates) {
- if (judgePredicateSegments(andPredicate.getPredicates())) {
- return true;
- }
+ if (!(sqlStatementContext instanceof WhereAvailable)) {
+ return false;
+ }
+ Optional<WhereSegment> whereSegment = ((WhereAvailable)
sqlStatementContext).getWhere();
+ if (!whereSegment.isPresent()) {
+ return false;
+ }
+ Collection<AndPredicate> andPredicates = new LinkedList<>();
+ ExpressionSegment expression = whereSegment.get().getExpr();
+ ExpressionBuildUtil util = new ExpressionBuildUtil(expression);
+ andPredicates.addAll(util.extractAndPredicates().getAndPredicates());
+ for (AndPredicate andPredicate : andPredicates) {
+ if (judgePredicateSegments(andPredicate.getPredicates())) {
+ return true;
}
}
return false;
}
- private boolean judgePredicateSegments(final Collection<PredicateSegment>
predicates) {
- for (PredicateSegment each : predicates) {
- if
(each.getColumn().getIdentifier().getValue().equals(shadowRule.getColumn())) {
- Preconditions.checkArgument(each.getRightValue() instanceof
PredicateCompareRightValue, "must be PredicateCompareRightValue");
- PredicateCompareRightValue rightValue =
(PredicateCompareRightValue) each.getRightValue();
- int parameterMarkerIndex = ((ParameterMarkerExpressionSegment)
rightValue.getExpression()).getParameterMarkerIndex();
+ private boolean judgePredicateSegments(final Collection<ExpressionSegment>
predicates) {
+ for (ExpressionSegment each : predicates) {
+ if (!(each instanceof BinaryOperationExpression)) {
+ continue;
+ }
+ BinaryOperationExpression expression = (BinaryOperationExpression)
each;
+ ColumnSegment column = null;
+ ExpressionSegment right = null;
+ if (expression.getLeft() instanceof ColumnSegment) {
+ column = (ColumnSegment) ((BinaryOperationExpression)
each).getLeft();
+ right = ((BinaryOperationExpression) each).getRight();
+ }
+ if (null == column) {
+ continue;
+ }
Review comment:
Refactoring
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/impl/PostgreSQLDMLVisitor.java
##########
@@ -459,101 +451,87 @@ public ASTNode visitTargetEl(final TargetElContext ctx) {
return result;
}
- private ColumnProjectionSegment generateColumnProjection(final
ColumnrefContext ctx) {
- if (null != ctx.indirection()) {
- PostgreSQLStatementParser.AttrNameContext attrName =
ctx.indirection().indirectionEl().attrName();
- ColumnSegment columnSegment = new
ColumnSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), new
IdentifierValue(attrName.getText()));
- OwnerSegment owner = new
OwnerSegment(ctx.colId().start.getStartIndex(),
ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText()));
- columnSegment.setOwner(owner);
- return new ColumnProjectionSegment(columnSegment);
- }
- ColumnSegment columnSegment = new
ColumnSegment(ctx.colId().start.getStartIndex(),
ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText()));
- return new ColumnProjectionSegment(columnSegment);
- }
-
@Override
public ASTNode visitFromClause(final FromClauseContext ctx) {
return visit(ctx.fromList());
}
@Override
- public ASTNode visitFromList(final
PostgreSQLStatementParser.FromListContext ctx) {
- CollectionValue<TableReferenceSegment> result = new
CollectionValue<>();
+ public ASTNode visitFromList(final FromListContext ctx) {
if (null != ctx.fromList()) {
- result.getValue().addAll(((CollectionValue<TableReferenceSegment>)
visit(ctx.fromList())).getValue());
+ JoinTableSegment result = new JoinTableSegment();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((TableSegment) visit(ctx.fromList()));
+ result.setRight((TableSegment) visit(ctx.tableReference()));
+ return result;
}
- result.getValue().add((TableReferenceSegment)
visit(ctx.tableReference()));
+ TableSegment result = (TableSegment) visit(ctx.tableReference());
return result;
}
@Override
public ASTNode visitTableReference(final TableReferenceContext ctx) {
- if (null != ctx.tableReference()) {
- TableReferenceSegment result = (TableReferenceSegment)
visit(ctx.tableReference());
- if (null != ctx.joinedTable()) {
- result.getJoinedTables().add((JoinedTableSegment)
visit(ctx.joinedTable()));
- }
- return result;
- }
if (null != ctx.relationExpr()) {
- TableReferenceSegment result = new TableReferenceSegment();
- SimpleTableSegment table =
generateTableFromRelationExpr(ctx.relationExpr());
+ SimpleTableSegment result =
generateTableFromRelationExpr(ctx.relationExpr());
if (null != ctx.aliasClause()) {
- table.setAlias((AliasSegment) visit(ctx.aliasClause()));
+ result.setAlias((AliasSegment) visit(ctx.aliasClause()));
}
- TableFactorSegment tableFactorSegment = new TableFactorSegment();
- tableFactorSegment.setTable(table);
- result.setTableFactor(tableFactorSegment);
return result;
}
if (null != ctx.selectWithParens()) {
- TableReferenceSegment result = new TableReferenceSegment();
SelectStatement select = (SelectStatement)
visit(ctx.selectWithParens());
SubquerySegment subquery = new
SubquerySegment(ctx.selectWithParens().start.getStartIndex(),
ctx.selectWithParens().stop.getStopIndex(), select);
AliasSegment alias = null != ctx.aliasClause() ? (AliasSegment)
visit(ctx.aliasClause()) : null;
- SubqueryTableSegment subqueryTable = new
SubqueryTableSegment(subquery);
- subqueryTable.setAlias(alias);
- TableFactorSegment tableFactor = new TableFactorSegment();
- tableFactor.setTable(subqueryTable);
- result.setTableFactor(tableFactor);
+ SubqueryTableSegment result = new SubqueryTableSegment(subquery);
+ result.setAlias(alias);
+ return result;
+ }
+ if (null != ctx.tableReference()) {
+ JoinTableSegment result = new JoinTableSegment();
+ int startIndex = null != ctx.LP_() ?
ctx.LP_().getSymbol().getStartIndex() :
ctx.tableReference().start.getStartIndex();
+ int stopIndex = 0;
+ AliasSegment alias = null;
+ if (null != ctx.aliasClause()) {
+ alias = (AliasSegment) visit(ctx.aliasClause());
+ startIndex = null != ctx.RP_() ?
ctx.RP_().getSymbol().getStopIndex() : ctx.joinedTable().stop.getStopIndex();
+ } else {
Review comment:
A function is needed here.
##########
File path:
shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-rewrite/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
##########
@@ -65,8 +67,13 @@
if (!whereSegment.isPresent()) {
return Collections.emptyList();
}
+
Review comment:
Remove
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/main/java/org/apache/shardingsphere/sql/parser/binder/segment/select/pagination/engine/RowNumberPaginationContextEngine.java
##########
@@ -51,27 +50,39 @@
/**
* Create pagination context.
*
- * @param andPredicates and predicates
+ * @param where where condition
* @param projectionsContext projections context
* @param parameters SQL parameters
* @return pagination context
*/
- public PaginationContext createPaginationContext(final
Collection<AndPredicate> andPredicates, final ProjectionsContext
projectionsContext, final List<Object> parameters) {
+ public PaginationContext createPaginationContext(final ExpressionSegment
where, final ProjectionsContext projectionsContext, final List<Object>
parameters) {
Optional<String> rowNumberAlias = isRowNumberAlias(projectionsContext);
if (!rowNumberAlias.isPresent()) {
return new PaginationContext(null, null, parameters);
}
- Collection<PredicateSegment> rowNumberPredicates =
getRowNumberPredicates(andPredicates, rowNumberAlias.get());
+ Collection<BinaryOperationExpression> rowNumberPredicates =
getRowNumberPredicates(where, rowNumberAlias.get());
return rowNumberPredicates.isEmpty() ? new PaginationContext(null,
null, parameters) : createPaginationWithRowNumber(rowNumberPredicates,
parameters);
}
- private Collection<PredicateSegment> getRowNumberPredicates(final
Collection<AndPredicate> andPredicates, final String rowNumberAlias) {
- Collection<PredicateSegment> result = new LinkedList<>();
- for (AndPredicate each : andPredicates) {
- for (PredicateSegment predicate : each.getPredicates()) {
- if (isRowNumberColumn(predicate, rowNumberAlias) &&
isCompareCondition(predicate)) {
- result.add(predicate);
- }
+ private Collection<BinaryOperationExpression> getRowNumberPredicates(final
ExpressionSegment where, final String rowNumberAlias) {
+ List<BinaryOperationExpression> result = new LinkedList<>();
+ if (!(where instanceof BinaryOperationExpression)) {
+ return result;
+ }
+ String operator = ((BinaryOperationExpression) where).getOperator();
+ if (((BinaryOperationExpression) where).getLeft() instanceof
ColumnSegment && isRowNumberColumn((ColumnSegment) ((BinaryOperationExpression)
where).getLeft(), rowNumberAlias)
+ && isCompareCondition(operator)) {
+ result.add((BinaryOperationExpression) where);
+ return result;
+ }
+ if ("and".equalsIgnoreCase(operator) ||
"&&".equalsIgnoreCase(operator) || "||".equalsIgnoreCase(operator) ||
"or".equalsIgnoreCase(operator)) {
+ Collection<BinaryOperationExpression> left =
getRowNumberPredicates(((BinaryOperationExpression) where).getLeft(),
rowNumberAlias);
Review comment:
Refactoring
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionUtil.java
##########
@@ -0,0 +1,45 @@
+/*
+ * 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.sql.common.util;
+
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
+
+public final class ExpressionUtil {
+
+ /**
+ * Get left value if left value of expression is ColumnSegment.
Review comment:
Consider merging this one with `ExpressionBuildUtil.java`
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/segment/select/pagination/engine/TopPaginationContextEngineTest.java
##########
@@ -76,25 +76,23 @@ public void
assertCreatePaginationContextWhenRowNumberPredicatePresentAndOperato
public void assertCreatePaginationContextWhenPredicateInRightValue() {
String name = "rowNumberAlias";
ColumnSegment columnSegment = new ColumnSegment(0, 10, new
IdentifierValue(name));
- PredicateSegment predicateSegment = new PredicateSegment(0, 10,
columnSegment, new PredicateInRightValue(0, 10, Collections.emptyList()));
- AndPredicate andPredicate = new AndPredicate();
- andPredicate.getPredicates().add(predicateSegment);
- Collection<AndPredicate> andPredicates =
Collections.singleton(andPredicate);
- PaginationContext paginationContext =
topPaginationContextEngine.createPaginationContext(new TopProjectionSegment(0,
10, null, name), andPredicates, Collections.emptyList());
+ InExpression inExpression = new InExpression();
+ inExpression.setLeft(new ColumnSegment(0, 10, new
IdentifierValue(name)));
+ inExpression.setRight(new ListExpression());
+ PaginationContext paginationContext =
topPaginationContextEngine.createPaginationContext(new TopProjectionSegment(0,
10, null, name), inExpression, Collections.emptyList());
assertFalse(paginationContext.getOffsetSegment().isPresent());
assertFalse(paginationContext.getRowCountSegment().isPresent());
}
@Test
public void
assertCreatePaginationContextWhenParameterMarkerRowNumberValueSegment() {
String name = "rowNumberAlias";
- ColumnSegment columnSegment = new ColumnSegment(0, 10, new
IdentifierValue(name));
- PredicateCompareRightValue predicateCompareRightValue = new
PredicateCompareRightValue(0, 10, ">", new ParameterMarkerExpressionSegment(0,
10, 0));
- PredicateSegment predicateSegment = new PredicateSegment(0, 10,
columnSegment, predicateCompareRightValue);
- AndPredicate andPredicate = new AndPredicate();
- andPredicate.getPredicates().add(predicateSegment);
- Collection<AndPredicate> andPredicates =
Collections.singleton(andPredicate);
- PaginationContext paginationContext =
topPaginationContextEngine.createPaginationContext(new TopProjectionSegment(0,
10, null, name), andPredicates, Collections.singletonList(1));
+ BinaryOperationExpression expression = new BinaryOperationExpression();
+ expression.setOperator(">");
+ expression.setRight(new ParameterMarkerExpressionSegment(0, 10, 0));
+ expression.setLeft(new ColumnSegment(0, 10, new
IdentifierValue(name)));
+
Review comment:
Remove.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionBuildUtil.java
##########
@@ -0,0 +1,76 @@
+/*
+ * 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.sql.common.util;
+
+import lombok.RequiredArgsConstructor;
+import
org.apache.shardingsphere.sql.parser.sql.common.constant.LogicalOperator;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.AndPredicate;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.OrPredicateSegment;
+
+import java.util.Optional;
+
+@RequiredArgsConstructor
+public final class ExpressionBuildUtil {
+
+ private final ExpressionSegment expression;
+
+ /**
+ * Extract andPredicates.
+ *
+ * @return OrPredicateSegment.
+ */
+ public OrPredicateSegment extractAndPredicates() {
+ OrPredicateSegment orPredicate = new OrPredicateSegment();
+ if (expression instanceof BinaryOperationExpression) {
+ String operator = ((BinaryOperationExpression)
expression).getOperator();
+ Optional<LogicalOperator> logicalOperator =
LogicalOperator.valueFrom(operator);
+ if (logicalOperator.isPresent() && LogicalOperator.OR ==
logicalOperator.get()) {
+ ExpressionBuildUtil leftUtil = new
ExpressionBuildUtil(((BinaryOperationExpression) expression).getLeft());
+ ExpressionBuildUtil rightUtil = new
ExpressionBuildUtil(((BinaryOperationExpression) expression).getRight());
+
orPredicate.getAndPredicates().addAll(leftUtil.extractAndPredicates().getAndPredicates());
+
orPredicate.getAndPredicates().addAll(rightUtil.extractAndPredicates().getAndPredicates());
+ } else if (logicalOperator.isPresent() && LogicalOperator.AND ==
logicalOperator.get()) {
+ ExpressionBuildUtil leftUtil = new
ExpressionBuildUtil(((BinaryOperationExpression) expression).getLeft());
+ ExpressionBuildUtil rightUtil = new
ExpressionBuildUtil(((BinaryOperationExpression) expression).getRight());
+ for (AndPredicate eachLeft :
leftUtil.extractAndPredicates().getAndPredicates()) {
Review comment:
A function is needed here.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/OracleVisitor.java
##########
@@ -236,120 +234,141 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
if (null != ctx.logicalOperator()) {
- return new PredicateBuildUtils(visit(ctx.expr(0)),
visit(ctx.expr(1)), ctx.logicalOperator().getText()).mergePredicate();
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
Review comment:
A function is needed here.
##########
File path:
shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-route/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/impl/ShardingUpdateStatementValidator.java
##########
@@ -95,27 +93,35 @@ public void postValidate(final SQLStatement sqlStatement,
final RouteResult rout
}
private Optional<Object> getShardingValue(final WhereSegment whereSegment,
final List<Object> parameters, final String shardingColumn) {
- for (AndPredicate each : whereSegment.getAndPredicates()) {
- return getShardingValue(each, parameters, shardingColumn);
+ if (null != whereSegment) {
+ return getShardingValue(whereSegment.getExpr(), parameters,
shardingColumn);
}
return Optional.empty();
}
- private Optional<Object> getShardingValue(final AndPredicate andPredicate,
final List<Object> parameters, final String shardingColumn) {
- for (PredicateSegment each : andPredicate.getPredicates()) {
- if
(!shardingColumn.equalsIgnoreCase(each.getColumn().getIdentifier().getValue()))
{
- continue;
+ private Optional<Object> getShardingValue(final ExpressionSegment
expression, final List<Object> parameters, final String shardingColumn) {
+ if (expression instanceof InExpression && ((InExpression)
expression).getLeft() instanceof ColumnSegment) {
+ ColumnSegment column = (ColumnSegment) ((InExpression)
expression).getLeft();
+ if
(!shardingColumn.equalsIgnoreCase(column.getIdentifier().getValue())) {
+ return getPredicateInShardingValue(((InExpression)
expression).getRight(), parameters);
}
- PredicateRightValue rightValue = each.getRightValue();
- if (rightValue instanceof PredicateCompareRightValue) {
- ExpressionSegment segment = ((PredicateCompareRightValue)
rightValue).getExpression();
- return getPredicateCompareShardingValue(segment, parameters);
- }
- if (rightValue instanceof PredicateInRightValue) {
- Collection<ExpressionSegment> segments =
((PredicateInRightValue) rightValue).getSqlExpressions();
- return getPredicateInShardingValue(segments, parameters);
+ }
+ if (!(expression instanceof BinaryOperationExpression)) {
+ return Optional.empty();
+ }
+ String operator = ((BinaryOperationExpression)
expression).getOperator();
+ boolean compare = ">".equalsIgnoreCase(operator) ||
">=".equalsIgnoreCase(operator) || "=".equalsIgnoreCase(operator) ||
"<".equalsIgnoreCase(operator) || "<=".equalsIgnoreCase(operator);
+ if (compare && ((BinaryOperationExpression) expression).getLeft()
instanceof ColumnSegment) {
+ ColumnSegment column = (ColumnSegment)
((BinaryOperationExpression) expression).getLeft();
+ if
(shardingColumn.equalsIgnoreCase(column.getIdentifier().getValue())) {
Review comment:
Refactoring
##########
File path:
shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-route/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngine.java
##########
@@ -98,22 +107,45 @@
return result;
}
- private Map<Column, Collection<RouteValue>> createRouteValueMap(final
SQLStatementContext sqlStatementContext, final AndPredicate andPredicate, final
List<Object> parameters) {
+ private Map<Column, Collection<RouteValue>> createRouteValueMap(final
SQLStatementContext sqlStatementContext, final AndPredicate expressions, final
List<Object> parameters) {
Map<Column, Collection<RouteValue>> result = new HashMap<>();
- for (PredicateSegment each : andPredicate.getPredicates()) {
- Optional<String> tableName =
sqlStatementContext.getTablesContext().findTableName(each.getColumn(),
schemaMetaData);
- if (!tableName.isPresent() ||
!shardingRule.isShardingColumn(each.getColumn().getIdentifier().getValue(),
tableName.get())) {
- continue;
+
+ for (ExpressionSegment each : expressions.getPredicates()) {
+ Optional<RouteValue> routeValue = Optional.empty();
+ Column column = null;
+ if (each instanceof BinaryOperationExpression &&
((BinaryOperationExpression) each).getLeft() instanceof ColumnSegment) {
+ ColumnSegment columnSegment = (ColumnSegment)
((BinaryOperationExpression) each).getLeft();
+ Optional<String> tableName =
sqlStatementContext.getTablesContext().findTableName(columnSegment,
schemaMetaData);
+ if (tableName.isPresent() &&
shardingRule.isShardingColumn(columnSegment.getIdentifier().getValue(),
tableName.get())) {
Review comment:
Refactoring
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/main/java/org/apache/shardingsphere/sql/parser/binder/segment/select/pagination/engine/TopPaginationContextEngine.java
##########
@@ -43,47 +41,57 @@
* Create pagination context.
*
* @param topProjectionSegment top projection segment
- * @param andPredicates and predicates
+ * @param where where condition
* @param parameters SQL parameters
* @return pagination context
*/
- public PaginationContext createPaginationContext(final
TopProjectionSegment topProjectionSegment, final Collection<AndPredicate>
andPredicates, final List<Object> parameters) {
- Optional<PredicateSegment> rowNumberPredicate =
getRowNumberPredicate(andPredicates, topProjectionSegment.getAlias());
+ public PaginationContext createPaginationContext(final
TopProjectionSegment topProjectionSegment, final ExpressionSegment where, final
List<Object> parameters) {
+ Optional<ExpressionSegment> rowNumberPredicate = null != where ?
getRowNumberPredicate(where, topProjectionSegment.getAlias()) :
Optional.empty();
Optional<PaginationValueSegment> offset =
rowNumberPredicate.isPresent() ?
createOffsetWithRowNumber(rowNumberPredicate.get()) : Optional.empty();
PaginationValueSegment rowCount = topProjectionSegment.getTop();
return new PaginationContext(offset.orElse(null), rowCount,
parameters);
}
- private Optional<PredicateSegment> getRowNumberPredicate(final
Collection<AndPredicate> andPredicates, final String rowNumberAlias) {
- for (AndPredicate each : andPredicates) {
- for (PredicateSegment predicate : each.getPredicates()) {
- if (isRowNumberColumn(predicate, rowNumberAlias) &&
isCompareCondition(predicate)) {
- return Optional.of(predicate);
- }
+ private Optional<ExpressionSegment> getRowNumberPredicate(final
ExpressionSegment where, final String rowNumberAlias) {
+ if (!(where instanceof BinaryOperationExpression)) {
+ return Optional.empty();
+ }
+ String operator = ((BinaryOperationExpression) where).getOperator();
+ if (((BinaryOperationExpression) where).getLeft() instanceof
ColumnSegment && isRowNumberColumn((ColumnSegment) ((BinaryOperationExpression)
where).getLeft(), rowNumberAlias)
Review comment:
The function is needed.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/segment/select/pagination/engine/TopPaginationContextEngineTest.java
##########
@@ -107,13 +105,12 @@ public void
assertCreatePaginationContextWhenParameterMarkerRowNumberValueSegmen
private void
assertCreatePaginationContextWhenRowNumberPredicatePresentAndWithGivenOperator(final
String operator) {
String name = "rowNumberAlias";
- ColumnSegment columnSegment = new ColumnSegment(0, 10, new
IdentifierValue(name));
- PredicateCompareRightValue predicateCompareRightValue = new
PredicateCompareRightValue(0, 10, operator, new LiteralExpressionSegment(0, 10,
100));
- PredicateSegment predicateSegment = new PredicateSegment(0, 10,
columnSegment, predicateCompareRightValue);
- AndPredicate andPredicate = new AndPredicate();
- andPredicate.getPredicates().add(predicateSegment);
- Collection<AndPredicate> andPredicates =
Collections.singleton(andPredicate);
- PaginationContext paginationContext =
topPaginationContextEngine.createPaginationContext(new TopProjectionSegment(0,
10, null, name), andPredicates, Collections.emptyList());
+ BinaryOperationExpression expression = new BinaryOperationExpression();
+ expression.setOperator(operator);
+ expression.setRight(new LiteralExpressionSegment(0, 10, 100));
+ expression.setLeft(new ColumnSegment(0, 10, new
IdentifierValue(name)));
+
Review comment:
Remove.
##########
File path:
shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/SQLServerVisitor.java
##########
@@ -244,121 +241,141 @@ public final ASTNode visitExpr(final ExprContext ctx) {
if (null != ctx.booleanPrimary()) {
return visit(ctx.booleanPrimary());
}
+ if (null != ctx.LP_()) {
+ return visit(ctx.expr(0));
+ }
if (null != ctx.logicalOperator()) {
- return new PredicateBuildUtils(visit(ctx.expr(0)),
visit(ctx.expr(1)), ctx.logicalOperator().getText()).mergePredicate();
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.expr(0)));
+ result.setRight((ExpressionSegment) visit(ctx.expr(1)));
+ result.setOperator(ctx.logicalOperator().getText());
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
- // TODO deal with XOR
- return visit(ctx.expr().get(0));
+ NotExpression result = new NotExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setExpression((ExpressionSegment) visit(ctx.expr(0)));
+ return result;
}
@Override
public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
+ if (null != ctx.IS()) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ result.setRight(new
LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 1,
ctx.stop.getStopIndex(), new Interval(ctx.IS().getSymbol().getStopIndex() + 1,
+ ctx.stop.getStopIndex())));
+ result.setOperator("IS");
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
+ }
if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) {
return createCompareSegment(ctx);
}
- if (null != ctx.predicate()) {
- return visit(ctx.predicate());
- }
- if (null != ctx.subquery()) {
- return new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- //TODO deal with IS NOT? (TRUE | FALSE | UNKNOWN | NULL)
- return new CommonExpressionSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), ctx.getText());
+ return visit(ctx.predicate());
}
private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) {
- ASTNode leftValue = visit(ctx.booleanPrimary());
- if (!(leftValue instanceof ColumnSegment)) {
- return leftValue;
- }
- PredicateRightValue rightValue = (PredicateRightValue)
createPredicateRightValue(ctx);
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (ColumnSegment) leftValue, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx)
{
- if (null != ctx.subquery()) {
- new SubquerySegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()));
- }
- ASTNode rightValue = visit(ctx.predicate());
- return createPredicateRightValue(ctx, rightValue);
- }
-
- private ASTNode createPredicateRightValue(final BooleanPrimaryContext ctx,
final ASTNode rightValue) {
- if (rightValue instanceof ColumnSegment) {
- return rightValue;
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.booleanPrimary()));
+ if (null != ctx.predicate()) {
+ result.setRight((ExpressionSegment) visit(ctx.predicate()));
+ } else {
+ result.setRight((ExpressionSegment) visit(ctx.subquery()));
}
- return rightValue instanceof SubquerySegment ? new
PredicateCompareRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(), ctx.comparisonOperator().getText(),
- new SubqueryExpressionSegment((SubquerySegment) rightValue))
- : new
PredicateCompareRightValue(ctx.predicate().start.getStartIndex(),
ctx.predicate().stop.getStopIndex(), ctx.comparisonOperator().getText(),
(ExpressionSegment) rightValue);
+ String operator = null != ctx.SAFE_EQ_() ? ctx.SAFE_EQ_().getText() :
ctx.comparisonOperator().getText();
+ result.setOperator(operator);
+ String text = ctx.start.getInputStream().getText(new
Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
+ result.setText(text);
+ return result;
}
@Override
public final ASTNode visitPredicate(final PredicateContext ctx) {
- if (null != ctx.IN() && null == ctx.NOT()) {
+ if (null != ctx.IN()) {
return createInSegment(ctx);
}
- if (null != ctx.BETWEEN() && null == ctx.NOT()) {
+ if (null != ctx.BETWEEN()) {
return createBetweenSegment(ctx);
}
- if (1 == ctx.children.size()) {
- return visit(ctx.bitExpr(0));
+ if (null != ctx.LIKE()) {
+ return createBinaryOperationExpressionFromLike(ctx);
}
- return visitRemainPredicate(ctx);
- }
-
- private PredicateSegment createInSegment(final PredicateContext ctx) {
- ColumnSegment column = (ColumnSegment) visit(ctx.bitExpr(0));
- PredicateInRightValue predicateInRightValue = null != ctx.subquery() ?
new PredicateInRightValue(ctx.subquery().start.getStartIndex(),
ctx.subquery().stop.getStopIndex(),
- getExpressionSegments(ctx))
- : new
PredicateInRightValue(ctx.LP_().getSymbol().getStartIndex(),
ctx.RP_().getSymbol().getStopIndex(), getExpressionSegments(ctx));
- return new PredicateSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), column, predicateInRightValue);
+ return visit(ctx.bitExpr(0));
}
- private Collection<ExpressionSegment> getExpressionSegments(final
PredicateContext ctx) {
- Collection<ExpressionSegment> result = new LinkedList<>();
- if (null != ctx.subquery()) {
- SubqueryContext subquery = ctx.subquery();
- result.add(new SubqueryExpressionSegment(new
SubquerySegment(subquery.getStart().getStartIndex(),
subquery.getStop().getStopIndex(), (SelectStatement) visit(ctx.subquery()))));
- return result;
- }
- for (ExprContext each : ctx.expr()) {
- result.add((ExpressionSegment) visit(each));
+ private BinaryOperationExpression
createBinaryOperationExpressionFromLike(final PredicateContext ctx) {
+ BinaryOperationExpression result = new BinaryOperationExpression();
+ result.setStartIndex(ctx.start.getStartIndex());
+ result.setStopIndex(ctx.stop.getStopIndex());
+ result.setLeft((ExpressionSegment) visit(ctx.bitExpr(0)));
+ ListExpression listExpression = new ListExpression();
+ for (SimpleExprContext each : ctx.simpleExpr()) {
+ listExpression.getItems().add((ExpressionSegment) visit(each));
}
+ result.setRight(listExpression);
Review comment:
A function is needed here.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]