Commit 344b10ef authored by tristaZero's avatar tristaZero
Browse files

Merge branch 'dev' of ssh://github.com/shardingjdbc/sharding-jdbc into dev

parents 9e067570 4f790238
Loading
Loading
Loading
Loading
+21 −24
Original line number Diff line number Diff line
@@ -17,43 +17,40 @@

package org.apache.shardingsphere.core.parse.antlr.constant;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.shardingsphere.core.parse.old.lexer.token.Symbol;
import com.google.common.base.Optional;

import java.util.Arrays;
import java.util.Collection;
import java.util.TreeSet;

/**
 * Logical operator.
 *
 * @author zhangliang
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class LogicalOperator {
    
    private static final String AND = "AND";
public enum LogicalOperator {
    
    private static final String OR = "OR";
    AND("AND", "&&"), 
    OR("OR", "||");
    
    /**
     * Judge is logical operator or not.
     *
     * @param token token
     * @return is logical operator or not
     */
    public static boolean isLogicalOperator(final String token) {
        return isAndOperator(token) || isOrOperator(token);
    }
    private final Collection<String> texts = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
    
    private static boolean isAndOperator(final String token) {
        return AND.equalsIgnoreCase(token) || Symbol.DOUBLE_AMP.getLiterals().equalsIgnoreCase(token);
    LogicalOperator(final String... texts) {
        this.texts.addAll(Arrays.asList(texts));
    }
    
    /**
     * Judge is or operator or not.
     * Get logical operator value from text.
     *
     * @param token token
     * @return OR operator or not
     * @param text text
     * @return logical operator value
     */
    public static boolean isOrOperator(final String token) {
        return OR.equalsIgnoreCase(token) || Symbol.DOUBLE_BAR.getLiterals().equalsIgnoreCase(token);
    public static Optional<LogicalOperator> valueFrom(final String text) {
        for (LogicalOperator each : LogicalOperator.values()) {
            if (each.texts.contains(text)) {
                return Optional.of(each);
            }
        }
        return Optional.absent();
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ package org.apache.shardingsphere.core.parse.antlr.extractor.impl.dml;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.apache.shardingsphere.core.parse.antlr.extractor.api.OptionalSQLSegmentExtractor;
import org.apache.shardingsphere.core.parse.antlr.extractor.impl.common.column.ColumnExtractor;
import org.apache.shardingsphere.core.parse.antlr.extractor.impl.dml.select.SubqueryExtractor;
@@ -42,6 +41,8 @@ import java.util.Map;
 */
public final class ExpressionExtractor implements OptionalSQLSegmentExtractor {
    
    private final ColumnExtractor columnExtractor = new ColumnExtractor();
    
    @Override
    public Optional<? extends ExpressionSegment> extract(final ParserRuleContext expressionNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
        Optional<ParserRuleContext> subqueryNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.SUBQUERY);
@@ -61,13 +62,12 @@ public final class ExpressionExtractor implements OptionalSQLSegmentExtractor {
    
    // TODO extract column name and value from function
    private ExpressionSegment extractFunctionExpressionSegment(final ParserRuleContext functionNode) {
        return new FunctionExpressionSegment(functionNode.getStart().getStartIndex(), functionNode.getStop().getStopIndex(), functionNode.getChild(0).getText(), 
                ((TerminalNode) functionNode.getChild(1)).getSymbol().getStartIndex(), functionNode.getStop().getStopIndex(), -1);
        return new FunctionExpressionSegment(functionNode.getStart().getStartIndex(), functionNode.getStop().getStopIndex());
    }
    
    private ExpressionSegment extractPropertyExpressionSegment(final ParserRuleContext expressionNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
        ParserRuleContext columnNode = (ParserRuleContext) expressionNode.getChild(0);
        Optional<ColumnSegment> columnSegment = new ColumnExtractor().extract(columnNode, parameterMarkerIndexes);
        Optional<ColumnSegment> columnSegment = columnExtractor.extract(columnNode, parameterMarkerIndexes);
        Preconditions.checkState(columnSegment.isPresent());
        return new PropertyExpressionSegment(columnNode.getStart().getStartIndex(), columnNode.getStop().getStopIndex(), columnSegment.get().getName(), columnSegment.get().getOwner().orNull());
    }
+34 −49
Original line number Diff line number Diff line
@@ -55,57 +55,28 @@ public final class PredicateExtractor implements OptionalSQLSegmentExtractor {
    
    @Override
    public Optional<OrPredicateSegment> extract(final ParserRuleContext exprNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
        return extractRecursive(exprNode, parameterMarkerIndexes);
        return extractRecursiveWithLogicalOperation(exprNode, parameterMarkerIndexes);
    }
    
    private Optional<OrPredicateSegment> extractRecursive(final ParserRuleContext exprNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
        Optional<Integer> index = getLogicalOperatorIndex(exprNode);
        if (!index.isPresent()) {
            return extractPredicateForParen(exprNode, parameterMarkerIndexes);
    private Optional<OrPredicateSegment> extractRecursiveWithLogicalOperation(final ParserRuleContext exprNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
        Optional<ParserRuleContext> logicalOperatorNode = ExtractorUtils.findFirstChildNodeNoneRecursive(exprNode, RuleName.LOGICAL_OPERATOR);
        if (!logicalOperatorNode.isPresent()) {
            return extractRecursiveWithParen(exprNode, parameterMarkerIndexes);
        }
        Optional<OrPredicateSegment> leftPredicate = extractRecursive((ParserRuleContext) exprNode.getChild(index.get() - 1), parameterMarkerIndexes);
        Optional<OrPredicateSegment> rightPredicate = extractRecursive((ParserRuleContext) exprNode.getChild(index.get() + 1), parameterMarkerIndexes);
        Optional<OrPredicateSegment> leftPredicate = extractRecursiveWithLogicalOperation((ParserRuleContext) exprNode.getChild(0), parameterMarkerIndexes);
        Optional<OrPredicateSegment> rightPredicate = extractRecursiveWithLogicalOperation((ParserRuleContext) exprNode.getChild(2), parameterMarkerIndexes);
        if (leftPredicate.isPresent() && rightPredicate.isPresent()) {
            return Optional.of(mergePredicate(leftPredicate.get(), rightPredicate.get(), exprNode.getChild(index.get()).getText()));
            return Optional.of(mergePredicate(leftPredicate.get(), rightPredicate.get(), logicalOperatorNode.get().getText()));
        }
        return leftPredicate.isPresent() ? leftPredicate : rightPredicate;
    }
    
    private Optional<Integer> getLogicalOperatorIndex(final ParserRuleContext exprNode) {
        for (int i = 0; i < exprNode.getChildCount(); i++) {
            if (LogicalOperator.isLogicalOperator(exprNode.getChild(i).getText())) {
                return Optional.of(i);
            }
        }
        return Optional.absent();
    }
    
    private Optional<OrPredicateSegment> extractPredicateForParen(final ParserRuleContext exprNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
        Optional<Integer> index = getLeftParenIndex(exprNode);
        if (index.isPresent()) {
            if (RuleName.EXPR.getName().equals(exprNode.getChild(index.get() + 1).getClass().getSimpleName())) {
                return extractRecursive((ParserRuleContext) exprNode.getChild(index.get() + 1), parameterMarkerIndexes);
            }
            return Optional.absent();
    private Optional<OrPredicateSegment> extractRecursiveWithParen(final ParserRuleContext exprNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
        if (Paren.isLeftParen(exprNode.getChild(0).getText())) {
            return extractRecursiveWithLogicalOperation((ParserRuleContext) exprNode.getChild(1), parameterMarkerIndexes);
        }
        Optional<PredicateSegment> predicate = extractPredicate(exprNode, parameterMarkerIndexes);
        if (!predicate.isPresent()) {
            return Optional.absent();
        }
        OrPredicateSegment result = new OrPredicateSegment();
        AndPredicateSegment newAndPredicate = new AndPredicateSegment();
        newAndPredicate.getPredicates().add(predicate.get());
        result.getAndPredicates().add(newAndPredicate);
        return Optional.of(result);
    }
    
    private Optional<Integer> getLeftParenIndex(final ParserRuleContext exprNode) {
        for (int i = 0; i < exprNode.getChildCount(); i++) {
            if (Paren.isLeftParen(exprNode.getChild(i).getText())) {
                return Optional.of(i);
            }
        }
        return Optional.absent();
        return predicate.isPresent() ? Optional.of(getOrPredicateSegment(predicate.get())) : Optional.<OrPredicateSegment>absent();
    }
    
    private Optional<PredicateSegment> extractPredicate(final ParserRuleContext exprNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
@@ -156,7 +127,7 @@ public final class PredicateExtractor implements OptionalSQLSegmentExtractor {
        Optional<ColumnSegment> column = columnExtractor.extract(exprNode, parameterMarkerIndexes);
        Preconditions.checkState(column.isPresent());
        ParserRuleContext valueNode = leftColumnNode.isPresent()
                ? (ParserRuleContext) comparisonOperatorNode.get().parent.getChild(2) : (ParserRuleContext) comparisonOperatorNode.get().parent.getChild(0);
                ? (ParserRuleContext) comparisonOperatorNode.get().getParent().getChild(2) : (ParserRuleContext) comparisonOperatorNode.get().getParent().getChild(0);
        Optional<? extends ExpressionSegment> sqlExpression = expressionExtractor.extract(valueNode, parameterMarkerIndexes);
        String compareOperator = comparisonOperatorNode.get().getText();
        return sqlExpression.isPresent() ? Optional.of(new PredicateSegment(column.get(), compareOperator, 
@@ -193,20 +164,34 @@ public final class PredicateExtractor implements OptionalSQLSegmentExtractor {
        return result;
    }
    
    private OrPredicateSegment getOrPredicateSegment(final PredicateSegment predicate) {
        OrPredicateSegment result = new OrPredicateSegment();
        AndPredicateSegment andPredicate = new AndPredicateSegment();
        andPredicate.getPredicates().add(predicate);
        result.getAndPredicates().add(andPredicate);
        return result;
    }
    
    private OrPredicateSegment mergePredicate(final OrPredicateSegment leftPredicate, final OrPredicateSegment rightPredicate, final String operator) {
        if (LogicalOperator.isOrOperator(operator)) {
        Optional<LogicalOperator> logicalOperator = LogicalOperator.valueFrom(operator);
        Preconditions.checkState(logicalOperator.isPresent());
        if (LogicalOperator.OR == logicalOperator.get()) {
            leftPredicate.getAndPredicates().addAll(rightPredicate.getAndPredicates());
            return leftPredicate;
        }
        OrPredicateSegment result = new OrPredicateSegment();
        for (AndPredicateSegment each : leftPredicate.getAndPredicates()) {
            for (AndPredicateSegment eachRightOr : rightPredicate.getAndPredicates()) {
                AndPredicateSegment tempList = new AndPredicateSegment();
                tempList.getPredicates().addAll(each.getPredicates());
                tempList.getPredicates().addAll(eachRightOr.getPredicates());
                result.getAndPredicates().add(tempList);
        for (AndPredicateSegment eachLeftPredicate : leftPredicate.getAndPredicates()) {
            for (AndPredicateSegment eachRightPredicate : rightPredicate.getAndPredicates()) {
                result.getAndPredicates().add(getAndPredicateSegment(eachLeftPredicate, eachRightPredicate));
            }
        }
        return result;
    }
    
    private AndPredicateSegment getAndPredicateSegment(final AndPredicateSegment leftPredicate, final AndPredicateSegment rightPredicate) {
        AndPredicateSegment result = new AndPredicateSegment();
        result.getPredicates().addAll(leftPredicate.getPredicates());
        result.getPredicates().addAll(rightPredicate.getPredicates());
        return result;
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -119,6 +119,8 @@ public enum RuleName {
    
    BIT_EXPR("BitExpr"),
    
    LOGICAL_OPERATOR("LogicalOperator"),
    
    FROM_CLAUSE("FromClause"),
    
    WHERE_CLAUSE("WhereClause"),
+3 −3
Original line number Diff line number Diff line
@@ -31,12 +31,12 @@ import org.apache.shardingsphere.core.parse.old.parser.context.condition.Conditi
@Getter
public final class BetweenValueExpressionSegment implements SQLRightValueExpressionSegment {
    
    private final ExpressionSegment beginExpress;
    private final ExpressionSegment betweenExpression;
    
    private final ExpressionSegment endExpress;
    private final ExpressionSegment andExpression;
    
    @Override
    public Condition buildCondition(final Column column, final String sql) {
        return new Condition(column, beginExpress.getSQLExpression(sql), endExpress.getSQLExpression(sql));
        return new Condition(column, betweenExpression.getSQLExpression(sql), andExpression.getSQLExpression(sql));
    }
}
Loading