View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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.expr.ExpressionSegment;
24  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
25  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
26  import org.apache.shardingsphere.sql.parser.sql.common.util.ExpressionExtractUtils;
27  
28  import java.util.ArrayList;
29  import java.util.Collection;
30  import java.util.Collections;
31  import java.util.List;
32  import java.util.Optional;
33  
34  /**
35   * Insert value context.
36   */
37  @Getter
38  @ToString
39  public final class InsertValueContext {
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      public InsertValueContext(final Collection<ExpressionSegment> assignments, final List<Object> params, final int parametersOffset) {
50          valueExpressions = getValueExpressions(assignments);
51          parameterMarkerExpressions = ExpressionExtractUtils.getParameterMarkerExpressions(assignments);
52          parameterCount = parameterMarkerExpressions.size();
53          parameters = getParameters(params, parametersOffset);
54      }
55      
56      private List<ExpressionSegment> getValueExpressions(final Collection<ExpressionSegment> assignments) {
57          List<ExpressionSegment> result = new ArrayList<>(assignments.size());
58          result.addAll(assignments);
59          return result;
60      }
61      
62      private List<Object> getParameters(final List<Object> params, final int paramsOffset) {
63          if (params.isEmpty() || 0 == parameterCount) {
64              return Collections.emptyList();
65          }
66          List<Object> result = new ArrayList<>(parameterCount);
67          result.addAll(params.subList(paramsOffset, paramsOffset + parameterCount));
68          return result;
69      }
70      
71      /**
72       * Get literal value.
73       *
74       * @param index index
75       * @return literal value
76       */
77      public Optional<Object> getLiteralValue(final int index) {
78          ExpressionSegment valueExpression = valueExpressions.get(index);
79          if (valueExpression instanceof ParameterMarkerExpressionSegment) {
80              return Optional.ofNullable(parameters.get(getParameterIndex((ParameterMarkerExpressionSegment) valueExpression)));
81          }
82          if (valueExpression instanceof LiteralExpressionSegment) {
83              return Optional.ofNullable(((LiteralExpressionSegment) valueExpression).getLiterals());
84          }
85          return Optional.empty();
86      }
87      
88      private int getParameterIndex(final ParameterMarkerExpressionSegment paramMarkerExpression) {
89          int result = parameterMarkerExpressions.indexOf(paramMarkerExpression);
90          Preconditions.checkArgument(result >= 0, "Can not get parameter index.");
91          return result;
92      }
93      
94      /**
95       * Get parameter index via column index.
96       *
97       * @param index column index
98       * @return parameter index
99       */
100     public int getParameterIndex(final int index) {
101         ExpressionSegment valueExpression = valueExpressions.get(index);
102         return valueExpression instanceof ParameterMarkerExpressionSegment ? getParameterIndex((ParameterMarkerExpressionSegment) valueExpression) : -1;
103     }
104 }