This is an automated email from the ASF dual-hosted git repository.

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new a6fb834d653 Add more converter test cases (#37354)
a6fb834d653 is described below

commit a6fb834d653ee5968d04809ab929700e8007b011
Author: Liang Zhang <[email protected]>
AuthorDate: Fri Dec 12 00:26:18 2025 +0800

    Add more converter test cases (#37354)
    
    * Add more converter test cases
    
    * Add more converter test cases
---
 .../expression/impl/InExpressionConverterTest.java |  85 +++++++++
 .../impl/IntervalExpressionConverterTest.java      |  86 +++++++++
 .../impl/ListExpressionConverterTest.java          |  64 +++++++
 .../impl/LiteralExpressionConverterTest.java       | 204 +++++++++++++++++++++
 .../impl/MatchExpressionConverterTest.java         |  86 +++++++++
 .../impl/NotExpressionConverterTest.java           |  63 +++++++
 .../ParameterMarkerExpressionConverterTest.java    |  38 ++++
 .../QuantifySubqueryExpressionConverterTest.java   |  53 ++++++
 .../impl/RowExpressionConverterTest.java           |  61 ++++++
 .../impl/SubqueryExpressionConverterTest.java      |  52 ++++++
 .../expression/impl/TrimFunctionConverterTest.java |  78 ++++++++
 .../impl/TypeCastExpressionConverterTest.java      |  64 +++++++
 .../UnaryOperationExpressionConverterTest.java     |  54 ++++++
 .../impl/VariableSegmentConverterTest.java         |  39 ++++
 .../impl/WindowFunctionConverterTest.java          |  70 +++++++
 15 files changed, 1097 insertions(+)

diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/InExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/InExpressionConverterTest.java
new file mode 100644
index 00000000000..ed0bd303754
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/InExpressionConverterTest.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class InExpressionConverterTest {
+    
+    @Test
+    void assertConvertReturnsEmptyWhenExpressionIsNull() {
+        assertFalse(InExpressionConverter.convert(null).isPresent());
+    }
+    
+    @Test
+    void assertConvertWrapsSqlBasicCallRightAsListForNotIn() {
+        LiteralExpressionSegment left = new LiteralExpressionSegment(0, 0, 1);
+        LiteralExpressionSegment right = new LiteralExpressionSegment(0, 0, 2);
+        SqlNode leftNode = mock(SqlNode.class);
+        SqlNode rightOperand = mock(SqlNode.class);
+        SqlBasicCall rightBasicCall = new 
SqlBasicCall(SqlStdOperatorTable.PLUS, Collections.singletonList(rightOperand), 
SqlParserPos.ZERO);
+        
when(ExpressionConverter.convert(left)).thenReturn(Optional.of(leftNode));
+        
when(ExpressionConverter.convert(right)).thenReturn(Optional.of(rightBasicCall));
+        SqlBasicCall actual = (SqlBasicCall) InExpressionConverter.convert(new 
InExpression(0, 0, left, right, true)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperator(), is(SqlStdOperatorTable.NOT_IN));
+        SqlNode secondOperand = actual.getOperandList().get(1);
+        assertThat(secondOperand, instanceOf(SqlNodeList.class));
+        assertThat(((SqlNodeList) secondOperand).size(), is(1));
+        assertThat(((SqlNodeList) secondOperand).get(0), is(rightOperand));
+    }
+    
+    @Test
+    void assertConvertAddsNonBasicCallRightForIn() {
+        LiteralExpressionSegment left = new LiteralExpressionSegment(0, 0, 1);
+        LiteralExpressionSegment right = new LiteralExpressionSegment(0, 0, 2);
+        SqlNode leftNode = mock(SqlNode.class);
+        SqlNode rightNode = mock(SqlNode.class);
+        
when(ExpressionConverter.convert(left)).thenReturn(Optional.of(leftNode));
+        
when(ExpressionConverter.convert(right)).thenReturn(Optional.of(rightNode));
+        SqlBasicCall actual = (SqlBasicCall) InExpressionConverter.convert(new 
InExpression(0, 0, left, right, false)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperator(), is(SqlStdOperatorTable.IN));
+        assertThat(actual.getOperandList(), is(Arrays.asList(leftNode, 
rightNode)));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/IntervalExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/IntervalExpressionConverterTest.java
new file mode 100644
index 00000000000..ea958f4caad
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/IntervalExpressionConverterTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.avatica.util.TimeUnit;
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlIntervalQualifier;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.IntervalExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.IntervalUnit;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.operator.common.SQLExtensionOperatorTable;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class IntervalExpressionConverterTest {
+    
+    @Test
+    void assertConvertThrowsForUnsupportedIntervalUnit() {
+        LiteralExpressionSegment value = new LiteralExpressionSegment(0, 0, 1);
+        IntervalExpression intervalExpression = new IntervalExpression(0, 0, 
value, IntervalUnit.YEAR_MONTH, "INTERVAL 1");
+        assertThrows(UnsupportedOperationException.class, () -> 
IntervalExpressionConverter.convert(intervalExpression));
+    }
+    
+    @ParameterizedTest(name = "convert interval unit {0}")
+    @MethodSource("provideIntervalUnits")
+    void assertConvertIntervalUnits(final IntervalUnit intervalUnit, final 
TimeUnit expectedTimeUnit) {
+        LiteralExpressionSegment value = new LiteralExpressionSegment(0, 0, 1);
+        SqlNode literalNode = SqlLiteral.createExactNumeric("1", 
SqlParserPos.ZERO);
+        
when(ExpressionConverter.convert(value)).thenReturn(Optional.of(literalNode));
+        IntervalExpression intervalExpression = new IntervalExpression(0, 0, 
value, intervalUnit, "INTERVAL 1");
+        SqlBasicCall actual = (SqlBasicCall) 
IntervalExpressionConverter.convert(intervalExpression).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperator(), 
is(SQLExtensionOperatorTable.INTERVAL_OPERATOR));
+        assertThat(actual.getOperandList().get(0), is(literalNode));
+        SqlIntervalQualifier qualifier = (SqlIntervalQualifier) 
actual.getOperandList().get(1);
+        assertThat(qualifier.getStartUnit(), is(expectedTimeUnit));
+    }
+    
+    private static Stream<Arguments> provideIntervalUnits() {
+        return Stream.of(
+                Arguments.of(IntervalUnit.MICROSECOND, TimeUnit.MICROSECOND),
+                Arguments.of(IntervalUnit.SECOND, TimeUnit.SECOND),
+                Arguments.of(IntervalUnit.MINUTE, TimeUnit.MINUTE),
+                Arguments.of(IntervalUnit.HOUR, TimeUnit.HOUR),
+                Arguments.of(IntervalUnit.DAY, TimeUnit.DAY),
+                Arguments.of(IntervalUnit.WEEK, TimeUnit.WEEK),
+                Arguments.of(IntervalUnit.MONTH, TimeUnit.MONTH),
+                Arguments.of(IntervalUnit.QUARTER, TimeUnit.QUARTER),
+                Arguments.of(IntervalUnit.YEAR, TimeUnit.YEAR));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/ListExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/ListExpressionConverterTest.java
new file mode 100644
index 00000000000..4cd99505654
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/ListExpressionConverterTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ListExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class ListExpressionConverterTest {
+    
+    @Test
+    void assertConvertReturnsEmptyWhenNoItems() {
+        assertFalse(ListExpressionConverter.convert(new ListExpression(0, 
0)).isPresent());
+    }
+    
+    @Test
+    void assertConvertSkipsEmptyConvertedItems() {
+        ListExpression expression = new ListExpression(0, 0);
+        LiteralExpressionSegment first = new LiteralExpressionSegment(0, 0, 1);
+        LiteralExpressionSegment second = new LiteralExpressionSegment(0, 0, 
2);
+        expression.getItems().add(first);
+        expression.getItems().add(second);
+        SqlNode secondNode = SqlLiteral.createExactNumeric("2", 
SqlParserPos.ZERO);
+        when(ExpressionConverter.convert(first)).thenReturn(Optional.empty());
+        
when(ExpressionConverter.convert(second)).thenReturn(Optional.of(secondNode));
+        SqlNodeList actual = (SqlNodeList) 
ListExpressionConverter.convert(expression).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.size(), is(1));
+        assertThat(actual.get(0), is(secondNode));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverterTest.java
new file mode 100644
index 00000000000..2020e454556
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverterTest.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlIntervalQualifier;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNumericLiteral;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.util.TimeString;
+import org.apache.calcite.runtime.CalciteException;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Calendar;
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class LiteralExpressionConverterTest {
+    
+    private enum SampleEnum {
+        VALUE
+    }
+    
+    @Test
+    void assertConvertNullLiteral() {
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
null)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getTypeName(), is(SqlTypeName.NULL));
+    }
+    
+    @Test
+    void assertConvertTrimFlags() {
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
"both")).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getValueAs(Enum.class).toString(), is("BOTH"));
+        SqlLiteral leading = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
"LEADING")).orElse(null);
+        assertNotNull(leading);
+        assertThat(leading.getValueAs(Enum.class).toString(), is("LEADING"));
+        SqlLiteral trailing = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
"trailing")).orElse(null);
+        assertNotNull(trailing);
+        assertThat(trailing.getValueAs(Enum.class).toString(), is("TRAILING"));
+    }
+    
+    @Test
+    void assertConvertTimeUnitName() {
+        SqlIntervalQualifier actual = (SqlIntervalQualifier) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
"year")).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getStartUnit().name(), is("YEAR"));
+    }
+    
+    @Test
+    void assertConvertApproximateNumber() {
+        SqlNumericLiteral actual = (SqlNumericLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, new 
BigDecimal("1.5"))).orElse(null);
+        assertNotNull(actual);
+        assertFalse(actual.isExact());
+    }
+    
+    @Test
+    void assertConvertExactNumber() {
+        SqlNumericLiteral actual = (SqlNumericLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
10)).orElse(null);
+        assertNotNull(actual);
+        assertTrue(actual.isExact());
+    }
+    
+    @Test
+    void assertConvertStringLiteral() {
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
"text")).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getValueAs(String.class), is("text"));
+    }
+    
+    @Test
+    void assertConvertBooleanLiteral() {
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
true)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getValueAs(Boolean.class), is(true));
+    }
+    
+    @Test
+    void assertConvertCalendarWithoutTimePart() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(2020, Calendar.JANUARY, 1, 0, 0, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
calendar)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getTypeName(), is(SqlTypeName.DATE));
+    }
+    
+    @Test
+    void assertConvertCalendarWithTimePart() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(2020, Calendar.JANUARY, 1, 1, 1, 1);
+        calendar.set(Calendar.MILLISECOND, 1);
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
calendar)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getTypeName(), is(SqlTypeName.TIMESTAMP));
+    }
+    
+    @Test
+    void assertConvertTimestampDate() {
+        Timestamp timestamp = Timestamp.valueOf("2023-01-02 03:04:05");
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
timestamp)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getTypeName(), is(SqlTypeName.TIMESTAMP));
+    }
+    
+    @Test
+    void assertConvertTimeDate() {
+        Time time = new Time(new TimeString("01:02:03").getMillisOfDay());
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
time)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getTypeName(), is(SqlTypeName.TIME));
+    }
+    
+    @Test
+    void assertConvertUtilDate() {
+        java.sql.Date date = java.sql.Date.valueOf("2020-01-01");
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
date)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getTypeName(), is(SqlTypeName.DATE));
+    }
+    
+    @Test
+    void assertConvertLocalDate() {
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
LocalDate.of(2020, 1, 1))).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getTypeName(), is(SqlTypeName.DATE));
+    }
+    
+    @Test
+    void assertConvertLocalTime() {
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
LocalTime.of(1, 2, 3))).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getTypeName(), is(SqlTypeName.TIME));
+    }
+    
+    @Test
+    void assertConvertLocalDateTime() {
+        assertThrows(IllegalArgumentException.class, () -> 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
LocalDateTime.of(2020, 1, 1, 1, 1, 1))));
+    }
+    
+    @Test
+    void assertConvertZonedDateTime() {
+        ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.of(2020, 
1, 1, 1, 1, 1), ZoneId.of("UTC"));
+        assertThrows(CalciteException.class, () -> 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
zonedDateTime)));
+    }
+    
+    @Test
+    void assertConvertBinary() {
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, new 
byte[]{1, 2})).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getTypeName(), is(SqlTypeName.BINARY));
+    }
+    
+    @Test
+    void assertConvertEnumLiteral() {
+        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
SampleEnum.VALUE)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getValueAs(String.class), is("VALUE"));
+    }
+    
+    @Test
+    void assertConvertReturnsEmptyForUnsupportedType() {
+        Optional<?> actual = LiteralExpressionConverter.convert(new 
LiteralExpressionSegment(0, 0, new Object()));
+        assertFalse(actual.isPresent());
+    }
+    
+    @Test
+    void assertConvertBigIntegerUsesApproximateNumeric() {
+        SqlNumericLiteral actual = (SqlNumericLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, new 
BigInteger("12345678901234567890"))).orElse(null);
+        assertNotNull(actual);
+        assertFalse(actual.isExact());
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/MatchExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/MatchExpressionConverterTest.java
new file mode 100644
index 00000000000..0a7bad46420
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/MatchExpressionConverterTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNode;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.operator.common.SQLExtensionOperatorTable;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.match.MatchAgainstExpression;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class MatchExpressionConverterTest {
+    
+    @Test
+    void assertConvertWithOwnerHierarchyAndExpression() {
+        ColumnSegment columnSegment = new ColumnSegment(0, 0, new 
IdentifierValue("column"));
+        OwnerSegment tableOwner = new OwnerSegment(0, 0, new 
IdentifierValue("table"));
+        OwnerSegment schemaOwner = new OwnerSegment(0, 0, new 
IdentifierValue("schema"));
+        tableOwner.setOwner(schemaOwner);
+        columnSegment.setOwner(tableOwner);
+        LiteralExpressionSegment expr = new LiteralExpressionSegment(0, 0, 
"expr");
+        SqlNode exprNode = mock(SqlNode.class);
+        
when(ExpressionConverter.convert(expr)).thenReturn(Optional.of(exprNode));
+        MatchAgainstExpression segment = new MatchAgainstExpression(0, 0, 
expr, "modifier", "");
+        segment.getColumns().add(columnSegment);
+        SqlBasicCall actual = (SqlBasicCall) 
MatchExpressionConverter.convert(segment).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperator(), 
is(SQLExtensionOperatorTable.MATCH_AGAINST));
+        SqlIdentifier identifier = (SqlIdentifier) 
actual.getOperandList().get(0);
+        assertThat(identifier.names, is(Arrays.asList("schema", "table", 
"column")));
+        assertThat(actual.getOperandList().get(1), is(exprNode));
+        SqlLiteral modifier = (SqlLiteral) actual.getOperandList().get(2);
+        assertThat(modifier.getValueAs(String.class), is("modifier"));
+    }
+    
+    @Test
+    void assertConvertWithoutExpressionLeavesSearchModifierOnly() {
+        ColumnSegment columnSegment = new ColumnSegment(0, 0, new 
IdentifierValue("column"));
+        LiteralExpressionSegment expr = new LiteralExpressionSegment(0, 0, 
"expr");
+        when(ExpressionConverter.convert(expr)).thenReturn(Optional.empty());
+        MatchAgainstExpression segment = new MatchAgainstExpression(0, 0, 
expr, "modifier", "");
+        segment.getColumns().add(columnSegment);
+        SqlBasicCall actual = (SqlBasicCall) 
MatchExpressionConverter.convert(segment).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperandList().size(), is(2));
+        assertThat(actual.getOperandList().get(0), 
instanceOf(SqlIdentifier.class));
+        SqlLiteral modifier = (SqlLiteral) actual.getOperandList().get(1);
+        assertThat(modifier.getValueAs(String.class), is("modifier"));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/NotExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/NotExpressionConverterTest.java
new file mode 100644
index 00000000000..4053a4ee14a
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/NotExpressionConverterTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlNode;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.NotExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.operator.common.SQLExtensionOperatorTable;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class NotExpressionConverterTest {
+    
+    @Test
+    void assertConvertNotSignTrue() {
+        LiteralExpressionSegment expression = new LiteralExpressionSegment(0, 
0, 1);
+        SqlNode expressionNode = mock(SqlNode.class);
+        
when(ExpressionConverter.convert(expression)).thenReturn(Optional.of(expressionNode));
+        SqlBasicCall actual = (SqlBasicCall) 
NotExpressionConverter.convert(new NotExpression(0, 0, expression, 
true)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperator(), 
is(SQLExtensionOperatorTable.NOT_SIGN));
+        assertThat(actual.getOperandList().get(0), is(expressionNode));
+    }
+    
+    @Test
+    void assertConvertNotSignFalse() {
+        LiteralExpressionSegment expression = new LiteralExpressionSegment(0, 
0, 1);
+        SqlNode expressionNode = mock(SqlNode.class);
+        
when(ExpressionConverter.convert(expression)).thenReturn(Optional.of(expressionNode));
+        SqlBasicCall actual = (SqlBasicCall) 
NotExpressionConverter.convert(new NotExpression(0, 0, expression, 
false)).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperator(), is(SQLExtensionOperatorTable.NOT));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/ParameterMarkerExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/ParameterMarkerExpressionConverterTest.java
new file mode 100644
index 00000000000..28932e7aa29
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/ParameterMarkerExpressionConverterTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlDynamicParam;
+import org.apache.calcite.sql.SqlNode;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class ParameterMarkerExpressionConverterTest {
+    
+    @Test
+    void assertConvertParameterMarker() {
+        SqlNode actual = ParameterMarkerExpressionConverter.convert(new 
ParameterMarkerExpressionSegment(0, 0, 5)).orElse(null);
+        assertNotNull(actual);
+        SqlDynamicParam param = (SqlDynamicParam) actual;
+        assertThat(param.getIndex(), is(5));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/QuantifySubqueryExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/QuantifySubqueryExpressionConverterTest.java
new file mode 100644
index 00000000000..1c1adbfdce2
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/QuantifySubqueryExpressionConverterTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlNode;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.QuantifySubqueryExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class QuantifySubqueryExpressionConverterTest {
+    
+    private final DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    
+    @Test
+    void assertConvertReturnsEmptyWhenExpressionIsNull() {
+        
assertFalse(QuantifySubqueryExpressionConverter.convert(null).isPresent());
+    }
+    
+    @Test
+    void assertConvertQuantifySubqueryExpression() {
+        SelectStatement selectStatement = new SelectStatement(databaseType);
+        ProjectionsSegment projections = new ProjectionsSegment(0, 0);
+        projections.getProjections().add(new 
ParameterMarkerExpressionSegment(0, 0, 0));
+        selectStatement.setProjections(projections);
+        SubquerySegment subquerySegment = new SubquerySegment(0, 0, 
selectStatement, "sub");
+        QuantifySubqueryExpression expression = new 
QuantifySubqueryExpression(0, 0, subquerySegment, "ALL");
+        SqlNode actual = 
QuantifySubqueryExpressionConverter.convert(expression).orElse(null);
+        assertNotNull(actual);
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/RowExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/RowExpressionConverterTest.java
new file mode 100644
index 00000000000..42bdb33ec65
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/RowExpressionConverterTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.RowExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class RowExpressionConverterTest {
+    
+    @Test
+    void assertConvertRowExpression() {
+        RowExpression expression = new RowExpression(0, 0, "row");
+        LiteralExpressionSegment first = new LiteralExpressionSegment(0, 0, 1);
+        LiteralExpressionSegment second = new LiteralExpressionSegment(0, 0, 
2);
+        expression.getItems().add(first);
+        expression.getItems().add(second);
+        SqlNode firstNode = SqlLiteral.createExactNumeric("1", 
SqlParserPos.ZERO);
+        SqlNode secondNode = SqlLiteral.createExactNumeric("2", 
SqlParserPos.ZERO);
+        
when(ExpressionConverter.convert(first)).thenReturn(Optional.of(firstNode));
+        
when(ExpressionConverter.convert(second)).thenReturn(Optional.of(secondNode));
+        SqlBasicCall actual = (SqlBasicCall) 
RowExpressionConverter.convert(expression).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperator(), is(SqlStdOperatorTable.ROW));
+        assertThat(actual.getOperandList(), is(Arrays.asList(firstNode, 
secondNode)));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/SubqueryExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/SubqueryExpressionConverterTest.java
new file mode 100644
index 00000000000..5199874a879
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/SubqueryExpressionConverterTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlNode;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class SubqueryExpressionConverterTest {
+    
+    private final DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    
+    @Test
+    void assertConvertReturnsEmptyWhenExpressionIsNull() {
+        assertFalse(SubqueryExpressionConverter.convert(null).isPresent());
+    }
+    
+    @Test
+    void assertConvertSubqueryExpression() {
+        SelectStatement selectStatement = new SelectStatement(databaseType);
+        ProjectionsSegment projections = new ProjectionsSegment(0, 0);
+        projections.getProjections().add(new 
ParameterMarkerExpressionSegment(0, 0, 0));
+        selectStatement.setProjections(projections);
+        SubquerySegment subquerySegment = new SubquerySegment(0, 0, 
selectStatement, "sub");
+        SqlNode actual = SubqueryExpressionConverter.convert(new 
SubqueryExpressionSegment(subquerySegment)).orElse(null);
+        assertNotNull(actual);
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/TrimFunctionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/TrimFunctionConverterTest.java
new file mode 100644
index 00000000000..d39890de717
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/TrimFunctionConverterTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.fun.SqlTrimFunction.Flag;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class TrimFunctionConverterTest {
+    
+    @Test
+    void assertConvertSingleParameterAddsDefaultTrimOptions() {
+        FunctionSegment segment = new FunctionSegment(0, 0, "TRIM", "TRIM");
+        LiteralExpressionSegment parameter = new LiteralExpressionSegment(0, 
0, "param");
+        segment.getParameters().add(parameter);
+        SqlNode paramNode = mock(SqlNode.class);
+        
when(ExpressionConverter.convert(parameter)).thenReturn(Optional.of(paramNode));
+        SqlBasicCall actual = (SqlBasicCall) 
TrimFunctionConverter.convert(segment).orElse(null);
+        assertNotNull(actual);
+        SqlLiteral trimFlag = (SqlLiteral) actual.getOperandList().get(0);
+        assertThat(trimFlag.getValueAs(Flag.class), is(Flag.BOTH));
+        SqlLiteral padding = (SqlLiteral) actual.getOperandList().get(1);
+        assertThat(padding.getValueAs(String.class), is(" "));
+        assertThat(actual.getOperandList().get(2), is(paramNode));
+    }
+    
+    @Test
+    void assertConvertTwoParametersAddsDefaultFlag() {
+        FunctionSegment segment = new FunctionSegment(0, 0, "TRIM", "TRIM");
+        LiteralExpressionSegment first = new LiteralExpressionSegment(0, 0, 
"first");
+        LiteralExpressionSegment second = new LiteralExpressionSegment(0, 0, 
"second");
+        segment.getParameters().add(first);
+        segment.getParameters().add(second);
+        SqlNode firstNode = mock(SqlNode.class);
+        SqlNode secondNode = mock(SqlNode.class);
+        
when(ExpressionConverter.convert(first)).thenReturn(Optional.of(firstNode));
+        
when(ExpressionConverter.convert(second)).thenReturn(Optional.of(secondNode));
+        SqlBasicCall actual = (SqlBasicCall) 
TrimFunctionConverter.convert(segment).orElse(null);
+        assertNotNull(actual);
+        SqlLiteral trimFlag = (SqlLiteral) actual.getOperandList().get(0);
+        assertThat(trimFlag.getValueAs(Flag.class), is(Flag.BOTH));
+        assertThat(actual.getOperandList().get(1), is(firstNode));
+        assertThat(actual.getOperandList().get(2), is(secondNode));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/TypeCastExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/TypeCastExpressionConverterTest.java
new file mode 100644
index 00000000000..56c132db8fb
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/TypeCastExpressionConverterTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlDataTypeSpec;
+import org.apache.calcite.sql.SqlNode;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.TypeCastExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class TypeCastExpressionConverterTest {
+    
+    @Test
+    void assertConvertReturnsEmptyWhenExpressionMissing() {
+        LiteralExpressionSegment expression = new LiteralExpressionSegment(0, 
0, 1);
+        TypeCastExpression typeCastExpression = new TypeCastExpression(0, 0, 
"", expression, "char");
+        
when(ExpressionConverter.convert(expression)).thenReturn(Optional.empty());
+        
assertFalse(TypeCastExpressionConverter.convert(typeCastExpression).isPresent());
+    }
+    
+    @Test
+    void assertConvertTypeCastExpression() {
+        LiteralExpressionSegment expression = new LiteralExpressionSegment(0, 
0, 1);
+        SqlNode expressionNode = mock(SqlNode.class);
+        
when(ExpressionConverter.convert(expression)).thenReturn(Optional.of(expressionNode));
+        TypeCastExpression typeCastExpression = new TypeCastExpression(0, 0, 
"", expression, "char");
+        SqlBasicCall actual = (SqlBasicCall) 
TypeCastExpressionConverter.convert(typeCastExpression).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperandList().get(0), is(expressionNode));
+        assertThat(actual.getOperandList().get(1), 
instanceOf(SqlDataTypeSpec.class));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/UnaryOperationExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/UnaryOperationExpressionConverterTest.java
new file mode 100644
index 00000000000..b957ba7f986
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/UnaryOperationExpressionConverterTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlNode;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.UnaryOperationExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.operator.common.SQLExtensionOperatorTable;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class UnaryOperationExpressionConverterTest {
+    
+    @Test
+    void assertConvertSupportedOperator() {
+        LiteralExpressionSegment expression = new LiteralExpressionSegment(0, 
0, 1);
+        SqlNode expressionNode = mock(SqlNode.class);
+        
when(ExpressionConverter.convert(expression)).thenReturn(Optional.of(expressionNode));
+        UnaryOperationExpression unaryOperationExpression = new 
UnaryOperationExpression(0, 0, expression, "~", "~1");
+        SqlBasicCall actual = (SqlBasicCall) 
UnaryOperationExpressionConverter.convert(unaryOperationExpression).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperator(), is(SQLExtensionOperatorTable.TILDE));
+        assertThat(actual.getOperandList().get(0), is(expressionNode));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/VariableSegmentConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/VariableSegmentConverterTest.java
new file mode 100644
index 00000000000..3effa280804
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/VariableSegmentConverterTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlNode;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dal.VariableSegment;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class VariableSegmentConverterTest {
+    
+    @Test
+    void assertConvertVariableSegment() {
+        VariableSegment variableSegment = new VariableSegment(0, 0, 
"@@session.tx");
+        SqlNode actual = 
VariableSegmentConverter.convert(variableSegment).orElse(null);
+        assertNotNull(actual);
+        SqlIdentifier identifier = (SqlIdentifier) actual;
+        assertThat(identifier.getSimple(), is("@@session.tx"));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/WindowFunctionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/WindowFunctionConverterTest.java
new file mode 100644
index 00000000000..3b77aa6d921
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/WindowFunctionConverterTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
+
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlWindow;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.ExpressionConverter;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ExpressionConverter.class)
+class WindowFunctionConverterTest {
+    
+    @Test
+    void assertConvertAddsDefaultWindowWhenSingleParameter() {
+        FunctionSegment segment = new FunctionSegment(0, 0, "OVER", "OVER");
+        LiteralExpressionSegment parameter = new LiteralExpressionSegment(0, 
0, "value");
+        segment.getParameters().add(parameter);
+        SqlNode paramNode = mock(SqlNode.class);
+        
when(ExpressionConverter.convert(parameter)).thenReturn(Optional.of(paramNode));
+        SqlBasicCall actual = (SqlBasicCall) 
WindowFunctionConverter.convert(segment).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.getOperator(), is(SqlStdOperatorTable.OVER));
+        assertThat(actual.getOperandList().get(0), is(paramNode));
+        assertThat(actual.getOperandList().get(1), 
instanceOf(SqlWindow.class));
+    }
+    
+    @Test
+    void assertConvertWithoutParametersSkipsWindowAddition() {
+        FunctionSegment segment = new FunctionSegment(0, 0, "OVER", "OVER");
+        LiteralExpressionSegment parameter = new LiteralExpressionSegment(0, 
0, "value");
+        segment.getParameters().add(parameter);
+        
when(ExpressionConverter.convert(parameter)).thenReturn(Optional.empty());
+        SqlBasicCall actual = (SqlBasicCall) 
WindowFunctionConverter.convert(segment).orElse(null);
+        assertNotNull(actual);
+        assertTrue(actual.getOperandList().isEmpty());
+    }
+}

Reply via email to