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.segment.expression;
19  
20  import lombok.AccessLevel;
21  import lombok.NoArgsConstructor;
22  import org.apache.shardingsphere.sql.parser.sql.common.segment.dal.VariableSegment;
23  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
24  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression;
25  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
26  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.CaseWhenExpression;
27  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.CollateExpression;
28  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExistsSubqueryExpression;
29  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
30  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExtractArgExpression;
31  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
32  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
33  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.KeyValueSegment;
34  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ListExpression;
35  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.NotExpression;
36  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.RowExpression;
37  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.TypeCastExpression;
38  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.UnaryOperationExpression;
39  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ValuesExpression;
40  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
41  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.ComplexExpressionSegment;
42  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
43  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
44  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment;
45  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
46  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
47  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
48  import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.IntervalExpressionProjection;
49  import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeSegment;
50  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.mysql.match.MatchAgainstExpression;
51  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.interval.IntervalDayToSecondExpression;
52  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.interval.IntervalYearToMonthExpression;
53  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.join.OuterJoinExpression;
54  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.multiset.MultisetExpression;
55  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlQueryAndExistsFunctionSegment;
56  import org.apache.shardingsphere.sql.parser.sql.dialect.segment.sqlserver.json.JsonNullClauseSegment;
57  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
58  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.SQLSegmentAssert;
59  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.column.ColumnAssert;
60  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.column.OuterJoinExpressionAssert;
61  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.generic.DataTypeAssert;
62  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.insert.InsertValuesClauseAssert;
63  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.owner.OwnerAssert;
64  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.projection.ProjectionAssert;
65  import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.dml.impl.SelectStatementAssert;
66  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedBetweenExpression;
67  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedBinaryOperationExpression;
68  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedCaseWhenExpression;
69  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedCollateExpression;
70  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedExistsSubquery;
71  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedExpression;
72  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedExtractArgExpression;
73  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedInExpression;
74  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedIntervalDayToSecondExpression;
75  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedIntervalExpression;
76  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedIntervalYearToMonthExpression;
77  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedKeyValueSegment;
78  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedListExpression;
79  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedMatchExpression;
80  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedMultisetExpression;
81  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedNotExpression;
82  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedRowExpression;
83  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedTypeCastExpression;
84  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedUnaryOperationExpression;
85  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedValuesExpression;
86  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedVariableSegment;
87  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.complex.ExpectedCommonExpression;
88  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.simple.ExpectedLiteralExpression;
89  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.simple.ExpectedParameterMarkerExpression;
90  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.simple.ExpectedSubquery;
91  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.function.ExpectedFunction;
92  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.json.ExpectedJsonNullClauseSegment;
93  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.xmlquery.ExpectedXmlQueryAndExistsFunctionSegment;
94  import org.apache.shardingsphere.test.it.sql.parser.internal.cases.sql.type.SQLCaseType;
95  
96  import java.util.Iterator;
97  
98  import static org.hamcrest.CoreMatchers.is;
99  import static org.hamcrest.MatcherAssert.assertThat;
100 import static org.junit.jupiter.api.Assertions.assertFalse;
101 import static org.junit.jupiter.api.Assertions.assertNotNull;
102 import static org.junit.jupiter.api.Assertions.assertNull;
103 import static org.junit.jupiter.api.Assertions.assertTrue;
104 
105 /**
106  * Expression assert.
107  */
108 @NoArgsConstructor(access = AccessLevel.PRIVATE)
109 public final class ExpressionAssert {
110     
111     /**
112      * Assert parameter marker expression.
113      *
114      * @param assertContext assert context
115      * @param actual actual parameter marker expression segment
116      * @param expected expected parameter marker expression
117      */
118     public static void assertParameterMarkerExpression(final SQLCaseAssertContext assertContext,
119                                                        final ParameterMarkerExpressionSegment actual, final ExpectedParameterMarkerExpression expected) {
120         if (null == expected) {
121             assertNull(actual, assertContext.getText("Actual parameter marker expression should not exist."));
122         } else {
123             assertNotNull(actual, assertContext.getText("Actual parameter marker expression should exist."));
124             assertThat(assertContext.getText("Parameter marker index assertion error: "), actual.getParameterMarkerIndex(), is(expected.getParameterIndex()));
125             SQLSegmentAssert.assertIs(assertContext, actual, expected);
126         }
127     }
128     
129     /**
130      * Assert literal expression.
131      *
132      * @param assertContext assert context
133      * @param actual actual literal expression segment
134      * @param expected expected literal expression
135      */
136     public static void assertLiteralExpression(final SQLCaseAssertContext assertContext,
137                                                final LiteralExpressionSegment actual, final ExpectedLiteralExpression expected) {
138         if (null == expected) {
139             assertNull(actual, assertContext.getText("Actual literal expression should not exist."));
140         } else {
141             assertNotNull(actual, assertContext.getText("Actual literal expression should exist."));
142             assertThat(assertContext.getText("Literal assertion error: "), String.valueOf(actual.getLiterals()), is(expected.getValue()));
143             SQLSegmentAssert.assertIs(assertContext, actual, expected);
144         }
145     }
146     
147     /**
148      * Assert common expression.
149      *
150      * @param assertContext assert context
151      * @param actual actual common expression segment
152      * @param expected expected common expression
153      */
154     public static void assertCommonExpression(final SQLCaseAssertContext assertContext,
155                                               final ComplexExpressionSegment actual, final ExpectedCommonExpression expected) {
156         if (null == expected) {
157             assertNull(actual, assertContext.getText("Actual common expression should not exist."));
158         } else {
159             assertNotNull(actual, assertContext.getText("Actual common expression should exist."));
160             String expectedText = SQLCaseType.LITERAL == assertContext.getCaseType() && null != expected.getLiteralText() ? expected.getLiteralText() : expected.getText();
161             assertThat(assertContext.getText("Common expression text assertion error: "), actual.getText(), is(expectedText));
162             SQLSegmentAssert.assertIs(assertContext, actual, expected);
163         }
164     }
165     
166     /**
167      * Assert subquery expression.
168      *
169      * @param assertContext assert context
170      * @param actual actual subquery expression segment
171      * @param expected expected subquery expression
172      */
173     public static void assertSubqueryExpression(final SQLCaseAssertContext assertContext,
174                                                 final SubqueryExpressionSegment actual, final ExpectedSubquery expected) {
175         if (null == expected) {
176             assertNull(actual, assertContext.getText("Actual subquery expression should not exist."));
177         } else {
178             assertNotNull(actual, assertContext.getText("Actual subquery expression should exist."));
179             assertSubquery(assertContext, actual.getSubquery(), expected);
180         }
181     }
182     
183     /**
184      * Assert subquery.
185      *
186      * @param assertContext assert context
187      * @param actual actual subquery segment
188      * @param expected expected subquery expression
189      */
190     public static void assertSubquery(final SQLCaseAssertContext assertContext,
191                                       final SubquerySegment actual, final ExpectedSubquery expected) {
192         if (null == expected) {
193             assertNull(actual, assertContext.getText("Actual subquery should not exist."));
194         } else {
195             assertNotNull(actual, assertContext.getText("Actual subquery should exist."));
196             SelectStatementAssert.assertIs(assertContext, actual.getSelect(), expected.getSelectTestCases());
197             SQLSegmentAssert.assertIs(assertContext, actual, expected);
198         }
199     }
200     
201     /**
202      * Assert exists subquery expression.
203      *
204      * @param assertContext assert context
205      * @param actual actual exists subquery expression
206      * @param expected expected exists subquery expression
207      */
208     public static void assertExistsSubqueryExpression(final SQLCaseAssertContext assertContext,
209                                                       final ExistsSubqueryExpression actual, final ExpectedExistsSubquery expected) {
210         if (null == expected) {
211             assertNull(actual, assertContext.getText("Actual exists subquery should not exist."));
212         } else {
213             assertNotNull(actual, assertContext.getText("Actual exists subquery should exist."));
214             assertSubquery(assertContext, actual.getSubquery(), expected.getSubquery());
215             assertThat(assertContext.getText("Exists subquery expression not value assert error."),
216                     actual.isNot(), is(expected.isNot()));
217             SQLSegmentAssert.assertIs(assertContext, actual, expected);
218         }
219     }
220     
221     /**
222      * Assert binary operation expression.
223      *
224      * @param assertContext assert context
225      * @param actual actual binary operation expression
226      * @param expected expected binary operation expression
227      */
228     public static void assertBinaryOperationExpression(final SQLCaseAssertContext assertContext,
229                                                        final BinaryOperationExpression actual, final ExpectedBinaryOperationExpression expected) {
230         if (null == expected) {
231             assertNull(actual, assertContext.getText("Actual binary operation expression should not exist."));
232         } else {
233             assertNotNull(actual, assertContext.getText("Actual binary operation expression should exist."));
234             assertExpression(assertContext, actual.getLeft(), expected.getLeft());
235             assertThat(assertContext.getText("Binary operation expression operator assert error."),
236                     actual.getOperator(), is(expected.getOperator()));
237             assertExpression(assertContext, actual.getRight(), expected.getRight());
238             SQLSegmentAssert.assertIs(assertContext, actual, expected);
239         }
240     }
241     
242     /**
243      * Assert in operation expression.
244      *
245      * @param assertContext assert context
246      * @param actual actual in operation expression
247      * @param expected expected in operation expression
248      */
249     public static void assertInExpression(final SQLCaseAssertContext assertContext,
250                                           final InExpression actual, final ExpectedInExpression expected) {
251         if (null == expected) {
252             assertNull(actual, assertContext.getText("Actual in expression should not exist."));
253         } else {
254             assertNotNull(actual, assertContext.getText("Actual in expression should exist."));
255             assertExpression(assertContext, actual.getLeft(), expected.getLeft());
256             assertThat(assertContext.getText("In expression not value assert error."),
257                     actual.isNot(), is(expected.isNot()));
258             assertExpression(assertContext, actual.getRight(), expected.getRight());
259             SQLSegmentAssert.assertIs(assertContext, actual, expected);
260         }
261     }
262     
263     /**
264      * Assert not operation expression.
265      *
266      * @param assertContext assert context
267      * @param actual actual not operation expression
268      * @param expected expected not operation expression
269      */
270     public static void assertNotExpression(final SQLCaseAssertContext assertContext,
271                                            final NotExpression actual, final ExpectedNotExpression expected) {
272         if (null == expected) {
273             assertNull(actual, assertContext.getText("Actual not expression should not exist."));
274         } else {
275             assertNotNull(actual, assertContext.getText("Actual not expression should exist."));
276             assertExpression(assertContext, actual.getExpression(), expected.getExpr());
277             SQLSegmentAssert.assertIs(assertContext, actual, expected);
278         }
279     }
280     
281     /**
282      * Assert list operation expression.
283      *
284      * @param assertContext assert context
285      * @param actual actual list operation expression
286      * @param expected expected list operation expression
287      */
288     public static void assertListExpression(final SQLCaseAssertContext assertContext,
289                                             final ListExpression actual, final ExpectedListExpression expected) {
290         if (null == expected) {
291             assertNull(actual, assertContext.getText("Actual list expression should not exist."));
292         } else {
293             assertNotNull(actual, assertContext.getText("Actual list expression should exist."));
294             assertThat(assertContext.getText("List expression item size assert error."),
295                     actual.getItems().size(), is(expected.getItems().size()));
296             Iterator<ExpressionSegment> actualItems = actual.getItems().iterator();
297             Iterator<ExpectedExpression> expectedItems = expected.getItems().iterator();
298             while (actualItems.hasNext()) {
299                 assertExpression(assertContext, actualItems.next(), expectedItems.next());
300             }
301             SQLSegmentAssert.assertIs(assertContext, actual, expected);
302         }
303     }
304     
305     /**
306      * Assert between operation expression.
307      *
308      * @param assertContext assert context
309      * @param actual actual between operation expression
310      * @param expected expected between operation expression
311      */
312     public static void assertBetweenExpression(final SQLCaseAssertContext assertContext,
313                                                final BetweenExpression actual, final ExpectedBetweenExpression expected) {
314         if (null == expected) {
315             assertNull(actual, assertContext.getText("Actual between expression should not exist."));
316         } else {
317             assertNotNull(actual, assertContext.getText("Actual between expression should exist."));
318             assertExpression(assertContext, actual.getLeft(), expected.getLeft());
319             assertExpression(assertContext, actual.getBetweenExpr(), expected.getBetweenExpr());
320             assertExpression(assertContext, actual.getAndExpr(), expected.getAndExpr());
321             assertThat(assertContext.getText("Between expression not value assert error."),
322                     actual.isNot(), is(expected.isNot()));
323             SQLSegmentAssert.assertIs(assertContext, actual, expected);
324         }
325     }
326     
327     /**
328      * Assert function.
329      *
330      * @param assertContext assert context
331      * @param actual actual function segment
332      * @param expected expected function segment
333      */
334     public static void assertFunction(final SQLCaseAssertContext assertContext, final FunctionSegment actual, final ExpectedFunction expected) {
335         SQLSegmentAssert.assertIs(assertContext, actual, expected);
336         assertThat(assertContext.getText("Function method name assertion error: "), actual.getFunctionName(), is(expected.getFunctionName()));
337         String expectedText = SQLCaseType.LITERAL == assertContext.getCaseType() && null != expected.getLiteralText()
338                 ? expected.getLiteralText()
339                 : expected.getText();
340         assertThat(assertContext.getText("Function text name assertion error: "), actual.getText(), is(expectedText));
341         assertThat(assertContext.getText("Function parameter size assertion error: "), actual.getParameters().size(), is(expected.getParameters().size()));
342         Iterator<ExpectedExpression> expectedIterator = expected.getParameters().iterator();
343         Iterator<ExpressionSegment> actualIterator = actual.getParameters().iterator();
344         while (expectedIterator.hasNext()) {
345             ExpressionAssert.assertExpression(assertContext, actualIterator.next(), expectedIterator.next());
346         }
347         if (null != expected.getOwner()) {
348             OwnerAssert.assertIs(assertContext, actual.getOwner(), expected.getOwner());
349         }
350     }
351     
352     /**
353      * Assert collate.
354      *
355      * @param assertContext assert context
356      * @param actual actual collate expression
357      * @param expected expected collate expression
358      */
359     public static void assertCollateExpression(final SQLCaseAssertContext assertContext, final CollateExpression actual, final ExpectedCollateExpression expected) {
360         if (null == expected) {
361             assertNull(actual, assertContext.getText("Actual collate expression should not exist."));
362         } else {
363             assertExpression(assertContext, actual.getCollateName(), expected.getCollateName());
364             SQLSegmentAssert.assertIs(assertContext, actual, expected);
365         }
366     }
367     
368     /**
369      * Assert case when expression.
370      *
371      * @param assertContext assert context
372      * @param actual actual case when expression
373      * @param expected expected case when expression
374      */
375     public static void assertCaseWhenExpression(final SQLCaseAssertContext assertContext, final CaseWhenExpression actual, final ExpectedCaseWhenExpression expected) {
376         assertThat(assertContext.getText("When exprs size is not same!"), actual.getWhenExprs().size(), is(expected.getWhenExprs().size()));
377         assertThat(assertContext.getText("Then exprs size is not same!"), actual.getThenExprs().size(), is(expected.getThenExprs().size()));
378         Iterator<ExpectedExpression> whenExprsIterator = expected.getWhenExprs().iterator();
379         for (ExpressionSegment each : actual.getWhenExprs()) {
380             assertExpression(assertContext, each, whenExprsIterator.next());
381         }
382         Iterator<ExpectedExpression> thenExprsIterator = expected.getThenExprs().iterator();
383         for (ExpressionSegment each : actual.getThenExprs()) {
384             assertExpression(assertContext, each, thenExprsIterator.next());
385         }
386         assertExpression(assertContext, actual.getCaseExpr(), expected.getCaseExpr());
387         assertExpression(assertContext, actual.getElseExpr(), expected.getElseExpr());
388     }
389     
390     private static void assertTypeCastExpression(final SQLCaseAssertContext assertContext, final TypeCastExpression actual, final ExpectedTypeCastExpression expected) {
391         if (null == expected) {
392             assertNull(actual, assertContext.getText("Type cast expression should not exist."));
393             return;
394         }
395         assertNotNull(actual, assertContext.getText("Type cast expression is expected."));
396         assertThat(assertContext.getText("Actual data type is different with expected in type case expression."), actual.getDataType(), is(expected.getDataType()));
397         assertExpression(assertContext, actual.getExpression(), expected.getExpression());
398     }
399     
400     private static void assertVariableSegment(final SQLCaseAssertContext assertContext, final VariableSegment actual, final ExpectedVariableSegment expected) {
401         if (null == expected) {
402             assertNull(actual, assertContext.getText("Variable segment should not exist."));
403             return;
404         }
405         assertThat(assertContext.getText("Actual scope is different with expected scope."), actual.getScope().orElse(null), is(expected.getScope()));
406         assertThat(assertContext.getText("Actual variable is different with expected variable."), actual.getVariable(), is(expected.getVariable()));
407     }
408     
409     private static void assertValuesExpression(final SQLCaseAssertContext assertContext, final ValuesExpression actual, final ExpectedValuesExpression expected) {
410         if (null == expected) {
411             assertNull(actual, assertContext.getText("Values segment should not exist."));
412             return;
413         }
414         assertNotNull(actual, assertContext.getText("Values segment should exist."));
415         if (null == expected.getInsertValuesClause()) {
416             assertTrue(actual.getRowConstructorList().isEmpty(), "Values expression should not exist.");
417         } else {
418             assertFalse(actual.getRowConstructorList().isEmpty(), assertContext.getText("Values expression should exist."));
419             InsertValuesClauseAssert.assertIs(assertContext, actual.getRowConstructorList(), expected.getInsertValuesClause());
420         }
421     }
422     
423     /**
424      * Assert extract arg expression.
425      *
426      * @param assertContext assert context
427      * @param actual actual extract arg expression
428      * @param expected expected extract arg expression
429      */
430     private static void assertExtractArgExpression(final SQLCaseAssertContext assertContext, final ExtractArgExpression actual, final ExpectedExtractArgExpression expected) {
431         if (null == expected) {
432             assertNull(actual, assertContext.getText("Extract arg expression should not exist."));
433             return;
434         }
435         assertThat(assertContext.getText("Extract arg expression assertion error: "), actual.getText(), is(expected.getText()));
436     }
437     
438     private static void assertMatchSegment(final SQLCaseAssertContext assertContext, final MatchAgainstExpression actual, final ExpectedMatchExpression expected) {
439         if (null == expected) {
440             assertNull(actual, assertContext.getText("Actual match expression should not exist."));
441         } else {
442             assertNotNull(actual, assertContext.getText("Actual match expression should exist"));
443             assertExpression(assertContext, actual.getExpr(), expected.getExpr());
444         }
445     }
446     
447     /**
448      * Assert expression by actual expression segment class type.
449      *
450      * @param assertContext assert context
451      * @param actual actual interval expression
452      * @param expected expected interval expression
453      */
454     private static void assertIntervalExpression(final SQLCaseAssertContext assertContext, final IntervalExpressionProjection actual, final ExpectedIntervalExpression expected) {
455         if (null == expected) {
456             assertNull(actual, assertContext.getText("Actual interval expression should not exist."));
457         } else {
458             assertNotNull(actual, assertContext.getText("Actual interval expression should exist"));
459             assertExpression(assertContext, actual.getLeft(), expected.getLeft());
460             assertExpression(assertContext, actual.getRight(), expected.getRight());
461             assertExpression(assertContext, actual.getMinus(), expected.getOperator());
462             if (null != actual.getDayToSecondExpression()) {
463                 assertIntervalDayToSecondExpression(assertContext, actual.getDayToSecondExpression(), expected.getDayToSecondExpression());
464             } else {
465                 assertIntervalYearToMonthExpression(assertContext, actual.getYearToMonthExpression(), expected.getYearToMonthExpression());
466             }
467         }
468     }
469     
470     /**
471      * Assert expression by actual expression segment class type.
472      *
473      * @param assertContext assert context
474      * @param actual actual interval day to second expression
475      * @param expected expected interval day to second expression
476      */
477     private static void assertIntervalDayToSecondExpression(final SQLCaseAssertContext assertContext,
478                                                             final IntervalDayToSecondExpression actual, final ExpectedIntervalDayToSecondExpression expected) {
479         if (null == expected) {
480             assertNull(actual, assertContext.getText("Actual interval expression should not exist."));
481         } else {
482             assertNotNull(actual, assertContext.getText("Actual interval expression should exist"));
483             if (null != actual.getLeadingFieldPrecision()) {
484                 assertThat(actual.getLeadingFieldPrecision(), is(expected.getLeadingFieldPrecision()));
485             } else {
486                 assertNull(expected.getLeadingFieldPrecision(), assertContext.getText("Actual leading field precision should not exist."));
487             }
488             if (null != actual.getFractionalSecondPrecision()) {
489                 assertThat(actual.getFractionalSecondPrecision(), is(expected.getFractionalSecondPrecision()));
490             } else {
491                 assertThat(expected.getFractionalSecondPrecision(), is(assertContext.getText("Actual fractional second precision should not exist.")));
492             }
493         }
494     }
495     
496     /**
497      * Assert expression by actual expression segment class type.
498      *
499      * @param assertContext assert context
500      * @param actual actual interval year to month expression
501      * @param expected expected interval year to month expression
502      */
503     private static void assertIntervalYearToMonthExpression(final SQLCaseAssertContext assertContext,
504                                                             final IntervalYearToMonthExpression actual, final ExpectedIntervalYearToMonthExpression expected) {
505         if (null == expected) {
506             assertNull(actual, assertContext.getText("Actual interval expression should not exist."));
507         } else {
508             assertNotNull(actual, assertContext.getText("Actual interval expression should exist"));
509             if (null != actual.getLeadingFieldPrecision()) {
510                 assertThat(actual.getLeadingFieldPrecision(), is(expected.getLeadingFieldPrecision()));
511             } else {
512                 assertNull(expected.getLeadingFieldPrecision(), assertContext.getText("Actual leading field precision should not exist."));
513             }
514         }
515     }
516     
517     private static void assertMultisetExpression(final SQLCaseAssertContext assertContext, final MultisetExpression actual, final ExpectedMultisetExpression expected) {
518         if (null == expected) {
519             assertNull(actual, assertContext.getText("Multiset expression should not exist."));
520             return;
521         }
522         assertNotNull(actual, assertContext.getText("Multiset expression should exist."));
523         assertExpression(assertContext, actual.getLeft(), expected.getLeft());
524         assertExpression(assertContext, actual.getRight(), expected.getRight());
525         assertThat(assertContext.getText("Multiset operator assertion error: "), actual.getOperator(), is(expected.getOperator()));
526         assertThat(assertContext.getText("Multiset keyword assertion error: "), actual.getKeyWord(), is(expected.getKeyWord()));
527     }
528     
529     /**
530      * Assert row expression.
531      *
532      * @param assertContext assert context
533      * @param actual actual row expression
534      * @param expected expected row expression
535      */
536     private static void assertRowExpression(final SQLCaseAssertContext assertContext, final RowExpression actual, final ExpectedRowExpression expected) {
537         if (null == expected) {
538             assertNull(actual, assertContext.getText("Row expression should not exist."));
539         } else {
540             assertNotNull(actual, assertContext.getText("Actual list expression should not exist."));
541             assertThat(assertContext.getText("Row expression item size assert error."),
542                     actual.getItems().size(), is(expected.getItems().size()));
543             Iterator<ExpressionSegment> actualItems = actual.getItems().iterator();
544             Iterator<ExpectedExpression> expectedItems = expected.getItems().iterator();
545             while (actualItems.hasNext()) {
546                 assertExpression(assertContext, actualItems.next(), expectedItems.next());
547             }
548             SQLSegmentAssert.assertIs(assertContext, actual, expected);
549         }
550     }
551     
552     /**
553      * Assert unary operation expression.
554      *
555      * @param assertContext assert context
556      * @param actual actual unary operation expression
557      * @param expected expected unary operation expression
558      */
559     private static void assertUnaryOperationExpression(final SQLCaseAssertContext assertContext, final UnaryOperationExpression actual, final ExpectedUnaryOperationExpression expected) {
560         if (null == expected) {
561             assertNull(actual, assertContext.getText("Actual unary operation expression should not exist."));
562         } else {
563             assertNotNull(actual, assertContext.getText("Actual unary operation expression should exist."));
564             assertExpression(assertContext, actual.getExpression(), expected.getExpr());
565             assertThat(assertContext.getText("Unary operation expression operator assert error."),
566                     actual.getOperator(), is(expected.getOperator()));
567             SQLSegmentAssert.assertIs(assertContext, actual, expected);
568         }
569     }
570     
571     /**
572      * Assert xml query and exists function segment.
573      *
574      * @param assertContext assert context
575      * @param actual actual xml query and exists function segment
576      * @param expected expected xml query and exists function segment
577      */
578     private static void assertXmlQueryAndExistsFunctionSegment(final SQLCaseAssertContext assertContext, final XmlQueryAndExistsFunctionSegment actual,
579                                                                final ExpectedXmlQueryAndExistsFunctionSegment expected) {
580         assertThat(assertContext.getText("function name assertion error"), actual.getFunctionName(), is(expected.getFunctionName()));
581         assertThat(assertContext.getText("xquery string assertion error"), actual.getXQueryString(), is(expected.getXQueryString()));
582         assertThat(assertContext.getText("parameter size assertion error: "), actual.getParameters().size(), is(expected.getParameters().size()));
583         Iterator<ExpectedExpression> expectedIterator = expected.getParameters().iterator();
584         Iterator<ExpressionSegment> actualIterator = actual.getParameters().iterator();
585         while (expectedIterator.hasNext()) {
586             ExpressionAssert.assertExpression(assertContext, actualIterator.next(), expectedIterator.next());
587         }
588     }
589     
590     /**
591      * Assert key value segment.
592      *
593      * @param assertContext assert context
594      * @param actual actual key value segment
595      * @param expected expected key value segment
596      */
597     private static void assertKeyValueSegment(final SQLCaseAssertContext assertContext, final KeyValueSegment actual, final ExpectedKeyValueSegment expected) {
598         if (null == expected) {
599             assertNull(actual, assertContext.getText("Actual key value should not exist."));
600         } else {
601             assertNotNull(actual, assertContext.getText("Actual key value should exist."));
602             assertExpression(assertContext, actual.getKey(), expected.getKey());
603             assertExpression(assertContext, actual.getValue(), expected.getValue());
604         }
605     }
606     
607     /**
608      * Assert json null clause segment.
609      *
610      * @param assertContext assert context
611      * @param actual actual json null clause segment
612      * @param expected expected json null clause segment
613      */
614     private static void assertJsonNullClauseSegment(final SQLCaseAssertContext assertContext, final JsonNullClauseSegment actual, final ExpectedJsonNullClauseSegment expected) {
615         if (null == expected) {
616             assertNull(actual, assertContext.getText("Actual json null clause should not exist."));
617         } else {
618             assertNotNull(actual, assertContext.getText("Actual json null clause should exist."));
619             assertThat(assertContext.getText("Json null clause assertion error."), actual.getText(), is(expected.getText()));
620         }
621     }
622     
623     /**
624      * Assert expression by actual expression segment class type.
625      *
626      * @param assertContext assert context
627      * @param actual actual expression segment
628      * @param expected expected expression
629      * @throws UnsupportedOperationException When expression segment class type is not supported.
630      */
631     public static void assertExpression(final SQLCaseAssertContext assertContext,
632                                         final ExpressionSegment actual, final ExpectedExpression expected) {
633         if (null == expected) {
634             assertNull(actual, assertContext.getText("Actual expression should not exist."));
635             return;
636         }
637         assertNotNull(actual, assertContext.getText("Actual expression should exist."));
638         if (actual instanceof BinaryOperationExpression) {
639             assertBinaryOperationExpression(assertContext, (BinaryOperationExpression) actual, expected.getBinaryOperationExpression());
640         } else if (actual instanceof SubqueryExpressionSegment) {
641             assertSubqueryExpression(assertContext, (SubqueryExpressionSegment) actual, expected.getSubquery());
642         } else if (actual instanceof ColumnSegment) {
643             ColumnAssert.assertIs(assertContext, (ColumnSegment) actual, expected.getColumn());
644         } else if (actual instanceof DataTypeSegment) {
645             DataTypeAssert.assertIs(assertContext, (DataTypeSegment) actual, expected.getDataType());
646         } else if (actual instanceof LiteralExpressionSegment) {
647             assertLiteralExpression(assertContext, (LiteralExpressionSegment) actual, expected.getLiteralExpression());
648         } else if (actual instanceof ParameterMarkerExpressionSegment) {
649             assertParameterMarkerExpression(assertContext, (ParameterMarkerExpressionSegment) actual, expected.getParameterMarkerExpression());
650         } else if (actual instanceof ExistsSubqueryExpression) {
651             assertExistsSubqueryExpression(assertContext, (ExistsSubqueryExpression) actual, expected.getExistsSubquery());
652         } else if (actual instanceof CommonExpressionSegment) {
653             assertCommonExpression(assertContext, (ComplexExpressionSegment) actual, expected.getCommonExpression());
654         } else if (actual instanceof InExpression) {
655             assertInExpression(assertContext, (InExpression) actual, expected.getInExpression());
656         } else if (actual instanceof NotExpression) {
657             assertNotExpression(assertContext, (NotExpression) actual, expected.getNotExpression());
658         } else if (actual instanceof ListExpression) {
659             assertListExpression(assertContext, (ListExpression) actual, expected.getListExpression());
660         } else if (actual instanceof BetweenExpression) {
661             assertBetweenExpression(assertContext, (BetweenExpression) actual, expected.getBetweenExpression());
662         } else if (actual instanceof ExpressionProjectionSegment) {
663             ProjectionAssert.assertProjection(assertContext, (ExpressionProjectionSegment) actual, expected.getExpressionProjection());
664         } else if (actual instanceof AggregationProjectionSegment) {
665             ProjectionAssert.assertProjection(assertContext, (AggregationProjectionSegment) actual, expected.getAggregationProjection());
666         } else if (actual instanceof FunctionSegment) {
667             assertFunction(assertContext, (FunctionSegment) actual, expected.getFunction());
668         } else if (actual instanceof CollateExpression) {
669             assertCollateExpression(assertContext, (CollateExpression) actual, expected.getCollateExpression());
670         } else if (actual instanceof CaseWhenExpression) {
671             assertCaseWhenExpression(assertContext, (CaseWhenExpression) actual, expected.getCaseWhenExpression());
672         } else if (actual instanceof TypeCastExpression) {
673             assertTypeCastExpression(assertContext, (TypeCastExpression) actual, expected.getTypeCastExpression());
674         } else if (actual instanceof VariableSegment) {
675             assertVariableSegment(assertContext, (VariableSegment) actual, expected.getVariableSegment());
676         } else if (actual instanceof ValuesExpression) {
677             assertValuesExpression(assertContext, (ValuesExpression) actual, expected.getValuesExpression());
678         } else if (actual instanceof ExtractArgExpression) {
679             assertExtractArgExpression(assertContext, (ExtractArgExpression) actual, expected.getExtractArgExpression());
680         } else if (actual instanceof MatchAgainstExpression) {
681             assertMatchSegment(assertContext, (MatchAgainstExpression) actual, expected.getMatchExpression());
682         } else if (actual instanceof OuterJoinExpression) {
683             OuterJoinExpressionAssert.assertIs(assertContext, (OuterJoinExpression) actual, expected.getOuterJoinExpression());
684         } else if (actual instanceof IntervalExpressionProjection) {
685             assertIntervalExpression(assertContext, (IntervalExpressionProjection) actual, expected.getIntervalExpression());
686         } else if (actual instanceof MultisetExpression) {
687             assertMultisetExpression(assertContext, (MultisetExpression) actual, expected.getMultisetExpression());
688         } else if (actual instanceof RowExpression) {
689             assertRowExpression(assertContext, (RowExpression) actual, expected.getRowExpression());
690         } else if (actual instanceof UnaryOperationExpression) {
691             assertUnaryOperationExpression(assertContext, (UnaryOperationExpression) actual, expected.getUnaryOperationExpression());
692         } else if (actual instanceof XmlQueryAndExistsFunctionSegment) {
693             assertXmlQueryAndExistsFunctionSegment(assertContext, (XmlQueryAndExistsFunctionSegment) actual, expected.getExpectedXmlQueryAndExistsFunctionSegment());
694         } else if (actual instanceof KeyValueSegment) {
695             assertKeyValueSegment(assertContext, (KeyValueSegment) actual, expected.getKeyValueSegment());
696         } else if (actual instanceof JsonNullClauseSegment) {
697             assertJsonNullClauseSegment(assertContext, (JsonNullClauseSegment) actual, expected.getJsonNullClauseSegment());
698         } else {
699             throw new UnsupportedOperationException(String.format("Unsupported expression: %s", actual.getClass().getName()));
700         }
701     }
702 }