Skip to content

Commit

Permalink
for apache#2084, add ParameterMarkerExpressionSegment
Browse files Browse the repository at this point in the history
  • Loading branch information
terrymanu committed Apr 24, 2019
1 parent 89b30f4 commit ac44049
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
import org.apache.shardingsphere.core.parse.antlr.extractor.util.RuleName;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.assignment.AssignmentSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.LiteralExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ParameterMarkerExpressionSegment;

import java.util.Map;

Expand All @@ -51,7 +52,10 @@ public Optional<AssignmentSegment> extract(final ParserRuleContext ancestorNode,
}
Optional<ColumnSegment> columnSegment = columnExtractor.extract((ParserRuleContext) assignmentNode.get().getChild(0), parameterMarkerIndexes);
Preconditions.checkState(columnSegment.isPresent());
LiteralExpressionSegment expressionSegment = expressionExtractor.extractLiteralExpressionSegment((ParserRuleContext) assignmentNode.get().getChild(2), parameterMarkerIndexes);
Optional<ParameterMarkerExpressionSegment> parameterMarkerExpressionSegment = expressionExtractor.extractParameterMarkerExpressionSegment(
(ParserRuleContext) assignmentNode.get().getChild(2), parameterMarkerIndexes);
ExpressionSegment expressionSegment = parameterMarkerExpressionSegment.isPresent()
? parameterMarkerExpressionSegment.get() : expressionExtractor.extractLiteralExpressionSegment((ParserRuleContext) assignmentNode.get().getChild(2));
return Optional.of(new AssignmentSegment(columnSegment.get(), expressionSegment));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
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.apache.shardingsphere.core.parse.antlr.extractor.api.OptionalSQLSegmentExtractor;
import org.apache.shardingsphere.core.parse.antlr.extractor.impl.dml.select.SubqueryExtractor;
Expand All @@ -26,6 +27,7 @@
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.CommonExpressionSegment;
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;
Expand All @@ -46,26 +48,36 @@ public Optional<? extends ExpressionSegment> extract(final ParserRuleContext exp
private ExpressionSegment extractExpression(final ParserRuleContext expressionNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
Optional<ParserRuleContext> parameterMarkerNode = ExtractorUtils.findSingleNodeFromFirstDescendant(expressionNode, RuleName.PARAMETER_MARKER);
if (parameterMarkerNode.isPresent()) {
return extractLiteralExpressionSegment(parameterMarkerNode.get(), parameterMarkerIndexes);
Optional<ParameterMarkerExpressionSegment> result = extractParameterMarkerExpressionSegment(parameterMarkerNode.get(), parameterMarkerIndexes);
Preconditions.checkState(result.isPresent());
return result.get();
}
Optional<ParserRuleContext> literalsNode = ExtractorUtils.findSingleNodeFromFirstDescendant(expressionNode, RuleName.LITERALS);
return literalsNode.isPresent() ? extractLiteralExpressionSegment(literalsNode.get(), parameterMarkerIndexes) : extractCommonExpressionSegment(expressionNode);
return literalsNode.isPresent() ? extractLiteralExpressionSegment(literalsNode.get()) : extractCommonExpressionSegment(expressionNode);
}

/**
* Extract literal expression segment.
* Extract parameter marker expression segment.
*
* @param parameterMarkerIndexes parameter marker indexes
* @param expressionNode expression node
* @return common expression segment
* @return parameter marker expression segment
*/
public LiteralExpressionSegment extractLiteralExpressionSegment(final ParserRuleContext expressionNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
LiteralExpressionSegment result = new LiteralExpressionSegment(expressionNode.getStart().getStartIndex(), expressionNode.getStop().getStopIndex());
public Optional<ParameterMarkerExpressionSegment> extractParameterMarkerExpressionSegment(final ParserRuleContext expressionNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
Optional<ParserRuleContext> parameterMarkerNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.PARAMETER_MARKER);
if (parameterMarkerNode.isPresent()) {
result.setParameterMarkerIndex(parameterMarkerIndexes.get(parameterMarkerNode.get()));
return result;
}
return parameterMarkerNode.isPresent()
? Optional.of(new ParameterMarkerExpressionSegment(expressionNode.getStart().getStartIndex(), expressionNode.getStop().getStopIndex(),
parameterMarkerIndexes.get(parameterMarkerNode.get()))) : Optional.<ParameterMarkerExpressionSegment>absent();
}

/**
* Extract literal expression segment.
*
* @param expressionNode expression node
* @return literal expression segment
*/
public LiteralExpressionSegment extractLiteralExpressionSegment(final ParserRuleContext expressionNode) {
LiteralExpressionSegment result = new LiteralExpressionSegment(expressionNode.getStart().getStartIndex(), expressionNode.getStop().getStopIndex());
Optional<ParserRuleContext> numberLiteralsNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.NUMBER_LITERALS);
if (numberLiteralsNode.isPresent()) {
result.setLiterals(NumberUtil.getExactlyNumber(numberLiteralsNode.get().getText(), 10));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
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.InsertValuesSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.LiteralExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ParameterMarkerExpressionSegment;

import java.util.Collection;
import java.util.Collections;
Expand All @@ -48,15 +49,20 @@ public Collection<InsertValuesSegment> extract(final ParserRuleContext ancestorN
}
Collection<InsertValuesSegment> result = new LinkedList<>();
for (ParserRuleContext each : ExtractorUtils.getAllDescendantNodes(insertValuesClauseNode.get(), RuleName.ASSIGNMENT_VALUES)) {
result.add(new InsertValuesSegment(extractCommonExpressionSegments(each, parameterMarkerIndexes)));
result.add(new InsertValuesSegment(extractExpressionSegments(each, parameterMarkerIndexes)));
}
return result;
}

private Collection<LiteralExpressionSegment> extractCommonExpressionSegments(final ParserRuleContext assignmentValuesNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
Collection<LiteralExpressionSegment> result = new LinkedList<>();
private Collection<ExpressionSegment> extractExpressionSegments(final ParserRuleContext assignmentValuesNode, final Map<ParserRuleContext, Integer> parameterMarkerIndexes) {
Collection<ExpressionSegment> result = new LinkedList<>();
for (ParserRuleContext each : ExtractorUtils.getAllDescendantNodes(assignmentValuesNode, RuleName.ASSIGNMENT_VALUE)) {
result.add(expressionExtractor.extractLiteralExpressionSegment(each, parameterMarkerIndexes));
Optional<ParameterMarkerExpressionSegment> parameterMarkerExpressionSegment = expressionExtractor.extractParameterMarkerExpressionSegment(each, parameterMarkerIndexes);
if (parameterMarkerExpressionSegment.isPresent()) {
result.add(parameterMarkerExpressionSegment.get());
} else {
result.add(expressionExtractor.extractLiteralExpressionSegment(each));
}
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import org.apache.shardingsphere.core.parse.antlr.filler.api.SQLSegmentFiller;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.InsertValuesSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.LiteralExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.statement.SQLStatement;
import org.apache.shardingsphere.core.parse.antlr.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.core.parse.old.parser.context.insertvalue.InsertValue;
Expand All @@ -45,7 +45,7 @@ public void fill(final InsertValuesSegment sqlSegment, final SQLStatement sqlSta

private InsertValue getInsertValue(final InsertValuesSegment sqlSegment, final String sql) {
List<SQLExpression> columnValues = new LinkedList<>();
for (LiteralExpressionSegment each : sqlSegment.getValues()) {
for (ExpressionSegment each : sqlSegment.getValues()) {
SQLExpression sqlExpression = each.getSQLExpression(sql);
columnValues.add(sqlExpression);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.assignment.AssignmentSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.assignment.SetAssignmentsSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.LiteralExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.statement.SQLStatement;
import org.apache.shardingsphere.core.parse.antlr.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.core.parse.antlr.sql.statement.dml.UpdateStatement;
Expand Down Expand Up @@ -107,7 +107,7 @@ private int getColumnCountExcludeAssistedQueryColumns(final InsertStatement inse
return insertStatement.getColumnNames().size() - assistedQueryColumnCount;
}

private SQLExpression getColumnValue(final InsertStatement insertStatement, final AndCondition andCondition, final String columnName, final LiteralExpressionSegment expressionSegment) {
private SQLExpression getColumnValue(final InsertStatement insertStatement, final AndCondition andCondition, final String columnName, final ExpressionSegment expressionSegment) {
SQLExpression result = expressionSegment.getSQLExpression(insertStatement.getLogicSQL());
String tableName = insertStatement.getTables().getSingleTableName();
fillShardingCondition(andCondition, columnName, tableName, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import org.apache.shardingsphere.core.parse.antlr.filler.api.SQLSegmentFiller;
import org.apache.shardingsphere.core.parse.antlr.filler.api.ShardingRuleAwareFiller;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.InsertValuesSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.LiteralExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.statement.SQLStatement;
import org.apache.shardingsphere.core.parse.antlr.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.core.parse.old.parser.context.condition.AndCondition;
Expand Down Expand Up @@ -58,7 +58,7 @@ public void fill(final InsertValuesSegment sqlSegment, final SQLStatement sqlSta
AndCondition andCondition = new AndCondition();
Iterator<String> columnNames = getColumnNames(sqlSegment, insertStatement);
List<SQLExpression> columnValues = new LinkedList<>();
for (LiteralExpressionSegment each : sqlSegment.getValues()) {
for (ExpressionSegment each : sqlSegment.getValues()) {
String columnName = columnNames.next();
SQLExpression columnValue = getColumnValue(insertStatement, andCondition, columnName, each);
columnValues.add(columnValue);
Expand All @@ -78,7 +78,7 @@ private Iterator<String> getColumnNames(final InsertValuesSegment sqlSegment, fi
return result.iterator();
}

private SQLExpression getColumnValue(final InsertStatement insertStatement, final AndCondition andCondition, final String columnName, final LiteralExpressionSegment expressionSegment) {
private SQLExpression getColumnValue(final InsertStatement insertStatement, final AndCondition andCondition, final String columnName, final ExpressionSegment expressionSegment) {
SQLExpression result = expressionSegment.getSQLExpression(insertStatement.getLogicSQL());
String tableName = insertStatement.getTables().getSingleTableName();
fillShardingCondition(andCondition, tableName, columnName, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.SQLSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.LiteralExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ExpressionSegment;

import java.util.Collection;

Expand All @@ -34,5 +34,5 @@
@Getter
public final class InsertValuesSegment implements SQLSegment {

private final Collection<LiteralExpressionSegment> values;
private final Collection<ExpressionSegment> values;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.SQLSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.LiteralExpressionSegment;
import org.apache.shardingsphere.core.parse.antlr.sql.segment.dml.expr.ExpressionSegment;

/**
* Assignment segment.
Expand All @@ -34,5 +34,5 @@ public final class AssignmentSegment implements SQLSegment {

private final ColumnSegment column;

private final LiteralExpressionSegment value;
private final ExpressionSegment value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.apache.shardingsphere.core.parse.old.lexer.token.DefaultKeyword;
import org.apache.shardingsphere.core.parse.old.parser.expression.SQLExpression;
import org.apache.shardingsphere.core.parse.old.parser.expression.SQLNumberExpression;
import org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression;
import org.apache.shardingsphere.core.parse.old.parser.expression.SQLTextExpression;

/**
Expand All @@ -42,15 +41,10 @@ public final class LiteralExpressionSegment implements ExpressionSegment {

private final int stopIndex;

private int parameterMarkerIndex = -1;

private Object literals;

@Override
public SQLExpression getSQLExpression(final String sql) {
if (-1 != parameterMarkerIndex) {
return new SQLPlaceholderExpression(parameterMarkerIndex);
}
if (literals instanceof Number) {
return new SQLNumberExpression((Number) literals);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.sql.segment.dml.expr;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.parse.old.parser.expression.SQLExpression;
import org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression;

/**
* Parameter marker expression segment.
*
* @author zhangliang
*/
@RequiredArgsConstructor
@Getter
public final class ParameterMarkerExpressionSegment implements ExpressionSegment {

private final int startIndex;

private final int stopIndex;

private final int parameterMarkerIndex;

@Override
public SQLExpression getSQLExpression(final String sql) {
return new SQLPlaceholderExpression(parameterMarkerIndex);
}
}

0 comments on commit ac44049

Please sign in to comment.