1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.infra.binder.context.segment.insert.values;
19
20 import com.google.common.base.Preconditions;
21 import lombok.Getter;
22 import lombok.ToString;
23 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
24 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
25 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
26 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
27 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
28 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
29 import org.apache.shardingsphere.sql.parser.sql.common.util.ExpressionExtractUtils;
30
31 import java.util.ArrayList;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.List;
35 import java.util.stream.Collectors;
36
37 @Getter
38 @ToString
39 public final class OnDuplicateUpdateContext {
40
41 private final int parameterCount;
42
43 private final List<ExpressionSegment> valueExpressions;
44
45 private final List<ParameterMarkerExpressionSegment> parameterMarkerExpressions;
46
47 private final List<Object> parameters;
48
49 private final List<ColumnSegment> columns;
50
51 public OnDuplicateUpdateContext(final Collection<ColumnAssignmentSegment> assignments, final List<Object> params, final int parametersOffset) {
52 List<ExpressionSegment> expressionSegments = assignments.stream().map(ColumnAssignmentSegment::getValue).collect(Collectors.toList());
53 valueExpressions = getValueExpressions(expressionSegments);
54 parameterMarkerExpressions = ExpressionExtractUtils.getParameterMarkerExpressions(expressionSegments);
55 parameterCount = parameterMarkerExpressions.size();
56 parameters = getParameters(params, parametersOffset);
57 columns = assignments.stream().map(each -> each.getColumns().get(0)).collect(Collectors.toList());
58 }
59
60 private List<ExpressionSegment> getValueExpressions(final Collection<ExpressionSegment> assignments) {
61 List<ExpressionSegment> result = new ArrayList<>(assignments.size());
62 result.addAll(assignments);
63 return result;
64 }
65
66 private List<Object> getParameters(final List<Object> params, final int paramsOffset) {
67 if (params.isEmpty() || 0 == parameterCount) {
68 return Collections.emptyList();
69 }
70 List<Object> result = new ArrayList<>(parameterCount);
71 result.addAll(params.subList(paramsOffset, paramsOffset + parameterCount));
72 return result;
73 }
74
75
76
77
78
79
80
81 public Object getValue(final int index) {
82 ExpressionSegment valueExpression = valueExpressions.get(index);
83 if (valueExpression instanceof ParameterMarkerExpressionSegment) {
84 return parameters.get(getParameterIndex((ParameterMarkerExpressionSegment) valueExpression));
85 }
86 if (valueExpression instanceof FunctionSegment) {
87 return valueExpression;
88 }
89 return ((LiteralExpressionSegment) valueExpression).getLiterals();
90 }
91
92 private int getParameterIndex(final ParameterMarkerExpressionSegment paramMarkerExpression) {
93 int result = parameterMarkerExpressions.indexOf(paramMarkerExpression);
94 Preconditions.checkArgument(result >= 0, "Can not get parameter index.");
95 return result;
96 }
97
98
99
100
101
102
103
104 public ColumnSegment getColumn(final int index) {
105 return columns.get(index);
106 }
107 }