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