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