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.test.it.sql.parser.internal.asserts.statement.dml.impl;
19  
20  import lombok.AccessLevel;
21  import lombok.NoArgsConstructor;
22  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.ReturningSegment;
23  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
24  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.OnDuplicateKeyColumnsSegment;
25  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
26  import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OutputSegment;
27  import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WithSegment;
28  import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement;
29  import org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.InsertStatementHandler;
30  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.table.MultiTableConditionalIntoSegment;
31  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.table.MultiTableInsertIntoSegment;
32  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.table.MultiTableInsertType;
33  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.exec.ExecSegment;
34  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.hint.WithTableHintSegment;
35  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
36  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.expression.ExpressionAssert;
37  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.hint.WithTableHintClauseAssert;
38  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.InsertExecClauseAssert;
39  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.InsertColumnsClauseAssert;
40  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.InsertValuesClauseAssert;
41  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.MultiTableConditionalIntoClauseAssert;
42  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.MultiTableInsertIntoClauseAssert;
43  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.OnDuplicateKeyColumnsAssert;
44  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.output.OutputClauseAssert;
45  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.parameter.ParameterMarkerAssert;
46  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.returning.ReturningClauseAssert;
47  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.set.SetClauseAssert;
48  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.table.TableAssert;
49  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.with.WithClauseAssert;
50  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.dml.InsertStatementTestCase;
51  
52  import java.util.Optional;
53  
54  import static org.hamcrest.CoreMatchers.is;
55  import static org.hamcrest.MatcherAssert.assertThat;
56  import static org.junit.jupiter.api.Assertions.assertFalse;
57  import static org.junit.jupiter.api.Assertions.assertNull;
58  import static org.junit.jupiter.api.Assertions.assertTrue;
59  
60  /**
61   * Insert statement assert.
62   */
63  @NoArgsConstructor(access = AccessLevel.PRIVATE)
64  public final class InsertStatementAssert {
65      
66      /**
67       * Assert insert statement is correct with expected parser result.
68       *
69       * @param assertContext assert context
70       * @param actual actual insert statement
71       * @param expected expected insert statement test case
72       */
73      public static void assertIs(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
74          assertTable(assertContext, actual, expected);
75          assertInsertColumnsClause(assertContext, actual, expected);
76          assertInsertValuesClause(assertContext, actual, expected);
77          assertSetClause(assertContext, actual, expected);
78          assertInsertSelectClause(assertContext, actual, expected);
79          assertOnDuplicateKeyColumns(assertContext, actual, expected);
80          assertWithClause(assertContext, actual, expected);
81          assertOutputClause(assertContext, actual, expected);
82          assertMultiTableInsertType(assertContext, actual, expected);
83          assertMultiTableInsertIntoClause(assertContext, actual, expected);
84          assertMultiTableConditionalIntoClause(assertContext, actual, expected);
85          assertReturningClause(assertContext, actual, expected);
86          assertInsertExecClause(assertContext, actual, expected);
87          assertWithTableHintClause(assertContext, actual, expected);
88          assertRowSetFunctionClause(assertContext, actual, expected);
89      }
90      
91      private static void assertTable(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
92          if (null == expected.getTable()) {
93              assertNull(actual.getTable(), assertContext.getText("Actual table should not exist."));
94          } else {
95              TableAssert.assertIs(assertContext, actual.getTable(), expected.getTable());
96          }
97      }
98      
99      private static void assertInsertColumnsClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
100         if (null == expected.getInsertColumnsClause()) {
101             assertFalse(actual.getInsertColumns().isPresent(), assertContext.getText("Actual insert columns segment should not exist."));
102         } else {
103             assertTrue(actual.getInsertColumns().isPresent(), assertContext.getText("Actual insert columns segment should exist."));
104             InsertColumnsClauseAssert.assertIs(assertContext, actual.getInsertColumns().get(), expected.getInsertColumnsClause());
105         }
106     }
107     
108     private static void assertInsertValuesClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
109         if (null == expected.getInsertValuesClause()) {
110             assertTrue(actual.getValues().isEmpty(), assertContext.getText("Actual insert values segment should not exist."));
111         } else {
112             assertFalse(actual.getValues().isEmpty(), assertContext.getText("Actual insert values segment should exist."));
113             InsertValuesClauseAssert.assertIs(assertContext, actual.getValues(), expected.getInsertValuesClause());
114         }
115     }
116     
117     private static void assertSetClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
118         Optional<SetAssignmentSegment> setAssignmentSegment = InsertStatementHandler.getSetAssignmentSegment(actual);
119         if (null == expected.getSetClause()) {
120             assertFalse(setAssignmentSegment.isPresent(), assertContext.getText("Actual set assignment segment should not exist."));
121         } else {
122             assertTrue(setAssignmentSegment.isPresent(), assertContext.getText("Actual set assignment segment should exist."));
123             SetClauseAssert.assertIs(assertContext, setAssignmentSegment.get(), expected.getSetClause());
124         }
125     }
126     
127     private static void assertInsertSelectClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
128         if (null == expected.getSelectTestCase()) {
129             assertFalse(actual.getInsertSelect().isPresent(), assertContext.getText("Actual insert select segment should not exist."));
130         } else {
131             assertTrue(actual.getInsertSelect().isPresent(), assertContext.getText("Actual insert select segment should exist."));
132             ParameterMarkerAssert.assertCount(assertContext, actual.getInsertSelect().get().getSelect().getParameterCount(), expected.getSelectTestCase().getParameters().size());
133             SelectStatementAssert.assertIs(assertContext, actual.getInsertSelect().get().getSelect(), expected.getSelectTestCase());
134         }
135     }
136     
137     private static void assertOnDuplicateKeyColumns(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
138         Optional<OnDuplicateKeyColumnsSegment> onDuplicateKeyColumnsSegment = InsertStatementHandler.getOnDuplicateKeyColumnsSegment(actual);
139         if (null == expected.getOnDuplicateKeyColumns()) {
140             assertFalse(onDuplicateKeyColumnsSegment.isPresent(), assertContext.getText("Actual on duplicate key columns segment should not exist."));
141         } else {
142             assertTrue(onDuplicateKeyColumnsSegment.isPresent(), assertContext.getText("Actual on duplicate key columns segment should exist."));
143             OnDuplicateKeyColumnsAssert.assertIs(assertContext, onDuplicateKeyColumnsSegment.get(), expected.getOnDuplicateKeyColumns());
144         }
145     }
146     
147     private static void assertWithClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
148         Optional<WithSegment> withSegment = InsertStatementHandler.getWithSegment(actual);
149         if (null == expected.getWithClause()) {
150             assertFalse(withSegment.isPresent(), assertContext.getText("Actual with segment should not exist."));
151         } else {
152             assertTrue(withSegment.isPresent(), assertContext.getText("Actual with segment should exist."));
153             WithClauseAssert.assertIs(assertContext, withSegment.get(), expected.getWithClause());
154         }
155     }
156     
157     private static void assertOutputClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
158         Optional<OutputSegment> outputSegment = InsertStatementHandler.getOutputSegment(actual);
159         if (null == expected.getOutputClause()) {
160             assertFalse(outputSegment.isPresent(), assertContext.getText("Actual output segment should not exist."));
161         } else {
162             assertTrue(outputSegment.isPresent(), assertContext.getText("Actual output segment should exist."));
163             OutputClauseAssert.assertIs(assertContext, outputSegment.get(), expected.getOutputClause());
164         }
165     }
166     
167     private static void assertMultiTableInsertType(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
168         Optional<MultiTableInsertType> multiTableInsertType = InsertStatementHandler.getMultiTableInsertType(actual);
169         if (null == expected.getMultiTableInsertType()) {
170             assertFalse(multiTableInsertType.isPresent(), assertContext.getText("Actual multi table insert type should not exist."));
171         } else {
172             assertTrue(multiTableInsertType.isPresent(), assertContext.getText("Actual multi table insert type should exist."));
173             assertThat(assertContext.getText(String.format("`%s`'s multiTableInsertType assertion error: ", actual.getClass().getSimpleName())), multiTableInsertType.get().name(),
174                     is(expected.getMultiTableInsertType().getMultiTableInsertType()));
175         }
176     }
177     
178     private static void assertMultiTableInsertIntoClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
179         Optional<MultiTableInsertIntoSegment> multiTableInsertIntoSegment = InsertStatementHandler.getMultiTableInsertIntoSegment(actual);
180         if (null == expected.getMultiTableInsertInto()) {
181             assertFalse(multiTableInsertIntoSegment.isPresent(), assertContext.getText("Actual multi table insert into segment should not exist."));
182         } else {
183             assertTrue(multiTableInsertIntoSegment.isPresent(), assertContext.getText("Actual multi table insert into segment should exist."));
184             MultiTableInsertIntoClauseAssert.assertIs(assertContext, multiTableInsertIntoSegment.get(), expected.getMultiTableInsertInto());
185         }
186     }
187     
188     private static void assertMultiTableConditionalIntoClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
189         Optional<MultiTableConditionalIntoSegment> multiTableConditionalIntoSegment = InsertStatementHandler.getMultiTableConditionalIntoSegment(actual);
190         if (null == expected.getMultiTableConditionalInto()) {
191             assertFalse(multiTableConditionalIntoSegment.isPresent(), assertContext.getText("Actual multi table conditional into segment should not exist."));
192         } else {
193             assertTrue(multiTableConditionalIntoSegment.isPresent(), assertContext.getText("Actual multi table conditional into segment should exist."));
194             MultiTableConditionalIntoClauseAssert.assertIs(assertContext, multiTableConditionalIntoSegment.get(), expected.getMultiTableConditionalInto());
195         }
196     }
197     
198     private static void assertReturningClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
199         Optional<ReturningSegment> returningSegment = InsertStatementHandler.getReturningSegment(actual);
200         if (null == expected.getReturningClause()) {
201             assertFalse(returningSegment.isPresent(), assertContext.getText("Actual returning segment should not exist."));
202         } else {
203             assertTrue(returningSegment.isPresent(), assertContext.getText("Actual returning segment should exist."));
204             ReturningClauseAssert.assertIs(assertContext, returningSegment.get(), expected.getReturningClause());
205         }
206     }
207     
208     private static void assertInsertExecClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
209         Optional<ExecSegment> execSegment = InsertStatementHandler.getExecSegment(actual);
210         if (null == expected.getExecClause()) {
211             assertFalse(execSegment.isPresent(), assertContext.getText("Actual exec segment should not exist."));
212         } else {
213             assertTrue(execSegment.isPresent(), assertContext.getText("Actual exec segment should exist."));
214             InsertExecClauseAssert.assertIs(assertContext, execSegment.get(), expected.getExecClause());
215         }
216     }
217     
218     private static void assertWithTableHintClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
219         Optional<WithTableHintSegment> withTableHintSegment = InsertStatementHandler.getWithTableHintSegment(actual);
220         if (null == expected.getExpectedWithTableHintClause()) {
221             assertFalse(withTableHintSegment.isPresent(), assertContext.getText("Actual with table hint should not exist."));
222         } else {
223             assertTrue(withTableHintSegment.isPresent(), assertContext.getText("Actual with table hint segment should exist."));
224             WithTableHintClauseAssert.assertIs(assertContext, withTableHintSegment.get(), expected.getExpectedWithTableHintClause());
225         }
226     }
227     
228     private static void assertRowSetFunctionClause(final SQLCaseAssertContext assertContext, final InsertStatement actual, final InsertStatementTestCase expected) {
229         Optional<FunctionSegment> rowSetFunctionSegment = InsertStatementHandler.getRowSetFunctionSegment(actual);
230         if (null == expected.getExpectedRowSetFunctionClause()) {
231             assertFalse(rowSetFunctionSegment.isPresent(), assertContext.getText("Actual row set function should not exist."));
232         } else {
233             assertTrue(rowSetFunctionSegment.isPresent(), assertContext.getText("Actual row set function should exist."));
234             ExpressionAssert.assertFunction(assertContext, rowSetFunctionSegment.get(), expected.getExpectedRowSetFunctionClause());
235         }
236     }
237 }