Commit 1e885341 authored by terrymanu's avatar terrymanu
Browse files

for #2084, add LiteralExpressionExtractor

parent 89a6b180
Loading
Loading
Loading
Loading
+6 −16
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.CommonExp
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.LiteralExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.core.util.NumberUtil;

import java.util.Map;

@@ -40,6 +39,8 @@ public final class ExpressionExtractor implements OptionalSQLSegmentExtractor {
    
    private final ParameterMarkerExpressionExtractor parameterMarkerExpressionExtractor = new ParameterMarkerExpressionExtractor();
    
    private final LiteralExpressionExtractor literalExpressionExtractor = new LiteralExpressionExtractor();
    
    @Override
    public Optional<? extends ExpressionSegment> extract(final ParserRuleContext expressionNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
        Optional<ParserRuleContext> subqueryNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.SUBQUERY);
@@ -51,22 +52,11 @@ public final class ExpressionExtractor implements OptionalSQLSegmentExtractor {
        if (parameterMarkerExpressionSegment.isPresent()) {
            return parameterMarkerExpressionSegment.get();
        }
        Optional<ParserRuleContext> literalsNode = ExtractorUtils.findSingleNodeFromFirstDescendant(expressionNode, RuleName.LITERALS);
        return literalsNode.isPresent() ? extractLiteralExpressionSegment(literalsNode.get()) : extractCommonExpressionSegment(expressionNode);
    }
    
    private LiteralExpressionSegment extractLiteralExpressionSegment(final ParserRuleContext expressionNode) {
        Optional<ParserRuleContext> numberLiteralsNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.NUMBER_LITERALS);
        Object literals = null;
        if (numberLiteralsNode.isPresent()) {
            literals = NumberUtil.getExactlyNumber(numberLiteralsNode.get().getText(), 10);
        }
        Optional<ParserRuleContext> stringLiteralsNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.STRING_LITERALS);
        if (stringLiteralsNode.isPresent()) {
            String text = stringLiteralsNode.get().getText();
            literals = text.substring(1, text.length() - 1);
        Optional<LiteralExpressionSegment> literalExpressionSegment = literalExpressionExtractor.extract(expressionNode, parameterMarkerIndexes);
        if (literalExpressionSegment.isPresent()) {
            return literalExpressionSegment.get();
        }
        return new LiteralExpressionSegment(expressionNode.getStart().getStartIndex(), expressionNode.getStop().getStopIndex(), literals);
        return extractCommonExpressionSegment(expressionNode);
    }
    
    // TODO extract column name and value from expression
+66 −0
Original line number Diff line number Diff line
/*
 * 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.core.parse.antlr.extractor.impl.common.expression;

import com.google.common.base.Optional;
import org.antlr.v4.runtime.ParserRuleContext;
import org.apache.shardingsphere.core.parse.antlr.extractor.api.OptionalSQLSegmentExtractor;
import org.apache.shardingsphere.core.parse.antlr.extractor.util.ExtractorUtils;
import org.apache.shardingsphere.core.parse.antlr.extractor.util.RuleName;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.LiteralExpressionSegment;
import org.apache.shardingsphere.core.util.NumberUtil;

import java.util.Map;

/**
 * Literal expression extractor.
 *
 * @author zhangliang
 */
public final class LiteralExpressionExtractor implements OptionalSQLSegmentExtractor {
    
    @Override
    public Optional<LiteralExpressionSegment> extract(final ParserRuleContext expressionNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
        Optional<ParserRuleContext> literalsNode = ExtractorUtils.findSingleNodeFromFirstDescendant(expressionNode, RuleName.LITERALS);
        return literalsNode.isPresent() 
                ? Optional.of(new LiteralExpressionSegment(literalsNode.get().getStart().getStartIndex(), literalsNode.get().getStop().getStopIndex(), getLiterals(literalsNode.get())))
                : Optional.<LiteralExpressionSegment>absent();
    }
    
    private Object getLiterals(final ParserRuleContext literalsNode) {
        Optional<Number> numberLiterals = getNumberLiterals(literalsNode);
        if (numberLiterals.isPresent()) {
            return numberLiterals.get();
        }
        return getStringLiterals(literalsNode).orNull();
    }
    
    private Optional<Number> getNumberLiterals(final ParserRuleContext literalsNode) {
        Optional<ParserRuleContext> numberLiteralsNode = ExtractorUtils.findFirstChildNode(literalsNode, RuleName.NUMBER_LITERALS);
        return numberLiteralsNode.isPresent() ? Optional.of(NumberUtil.getExactlyNumber(numberLiteralsNode.get().getText(), 10)) : Optional.<Number>absent();
    }
    
    private Optional<String> getStringLiterals(final ParserRuleContext literalsNode) {
        Optional<ParserRuleContext> stringLiteralsNode = ExtractorUtils.findFirstChildNode(literalsNode, RuleName.STRING_LITERALS);
        if (stringLiteralsNode.isPresent()) {
            String text = stringLiteralsNode.get().getText();
            return Optional.of(text.substring(1, text.length() - 1));
        }
        return Optional.absent();
    }
}