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 2ff04be6e8b Add TableConverterTest and ProjectionsConverterTest 
(#37344)
2ff04be6e8b is described below

commit 2ff04be6e8b861cb22e6f5b265192b1d863c3896
Author: Liang Zhang <[email protected]>
AuthorDate: Thu Dec 11 16:34:44 2025 +0800

    Add TableConverterTest and ProjectionsConverterTest (#37344)
    
    * Add ExpressionConverterTest
    
    * Add TableConverterTest and ProjectionsConverterTest
    
    * Add TableConverterTest and ProjectionsConverterTest
---
 .../expression/ExpressionConverterTest.java        | 233 +++++++++++++++++++++
 .../converter/segment/from/TableConverterTest.java |  92 ++++++++
 .../projection/ProjectionsConverterTest.java       | 104 +++++++++
 3 files changed, 429 insertions(+)

diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/ExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/ExpressionConverterTest.java
new file mode 100644
index 00000000000..1c2cc027552
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/ExpressionConverterTest.java
@@ -0,0 +1,233 @@
+/*
+ * 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;
+
+import org.apache.calcite.sql.SqlNode;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import 
org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import 
org.apache.shardingsphere.sql.parser.statement.core.enums.AggregationType;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dal.VariableSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BetweenExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CaseWhenExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CollateExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExistsSubqueryExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExtractArgExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
+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.ListExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.NotExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.QuantifySubqueryExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.RowExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.TypeCastExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.UnaryOperationExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+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.AggregationProjectionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.DataTypeSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.match.MatchAgainstExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.BetweenExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.BinaryOperationExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.CaseWhenExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.CollateExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.ColumnConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.DataTypeExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.ExistsSubqueryExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.ExtractArgExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.FunctionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.InExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.IntervalExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.ListExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.LiteralExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.MatchExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.NotExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.ParameterMarkerExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.QuantifySubqueryExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.RowExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.SubqueryExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.TypeCastExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.UnaryOperationExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.VariableSegmentConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.projection.impl.AggregationProjectionConverter;
+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.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+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.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings({
+        LiteralExpressionConverter.class, ListExpressionConverter.class, 
BinaryOperationExpressionConverter.class,
+        ColumnConverter.class, ExistsSubqueryExpressionConverter.class, 
SubqueryExpressionConverter.class, InExpressionConverter.class,
+        BetweenExpressionConverter.class, 
ParameterMarkerExpressionConverter.class, FunctionConverter.class, 
AggregationProjectionConverter.class,
+        DataTypeExpressionConverter.class, CaseWhenExpressionConverter.class, 
NotExpressionConverter.class, TypeCastExpressionConverter.class,
+        ExtractArgExpressionConverter.class, MatchExpressionConverter.class, 
CollateExpressionConverter.class, RowExpressionConverter.class,
+        VariableSegmentConverter.class, 
UnaryOperationExpressionConverter.class, IntervalExpressionConverter.class, 
QuantifySubqueryExpressionConverter.class
+})
+class ExpressionConverterTest {
+    
+    private final DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    
+    @Test
+    void assertConvertDelegatesToAllSupportedConverters() {
+        SqlNode expectedLiteralNode = mock(SqlNode.class);
+        LiteralExpressionSegment literalSegment = new 
LiteralExpressionSegment(0, 0, "literal");
+        
when(LiteralExpressionConverter.convert(literalSegment)).thenReturn(Optional.of(expectedLiteralNode));
+        SqlNode expectedListNode = mock(SqlNode.class);
+        ListExpression listSegment = new ListExpression(0, 0);
+        
when(ListExpressionConverter.convert(listSegment)).thenReturn(Optional.of(expectedListNode));
+        SqlNode expectedBinaryNode = mock(SqlNode.class);
+        BinaryOperationExpression binarySegment = new 
BinaryOperationExpression(0, 0, literalSegment, literalSegment, "+", "text");
+        
when(BinaryOperationExpressionConverter.convert(binarySegment)).thenReturn(Optional.of(expectedBinaryNode));
+        SqlNode expectedColumnNode = mock(SqlNode.class);
+        ColumnSegment columnSegment = new ColumnSegment(0, 0, new 
IdentifierValue("col"));
+        
when(ColumnConverter.convert(columnSegment)).thenReturn(Optional.of(expectedColumnNode));
+        SqlNode expectedExistsSubqueryNode = mock(SqlNode.class);
+        SubquerySegment subquerySegment = new SubquerySegment(0, 0, new 
SelectStatement(databaseType), "sub");
+        ExistsSubqueryExpression existsSubqueryExpression = new 
ExistsSubqueryExpression(0, 0, subquerySegment);
+        
when(ExistsSubqueryExpressionConverter.convert(existsSubqueryExpression)).thenReturn(Optional.of(expectedExistsSubqueryNode));
+        SqlNode expectedSubqueryNode = mock(SqlNode.class);
+        SubqueryExpressionSegment subqueryExpressionSegment = new 
SubqueryExpressionSegment(subquerySegment);
+        
when(SubqueryExpressionConverter.convert(subqueryExpressionSegment)).thenReturn(Optional.of(expectedSubqueryNode));
+        SqlNode expectedInNode = mock(SqlNode.class);
+        InExpression inExpression = new InExpression(0, 0, literalSegment, 
literalSegment, false);
+        
when(InExpressionConverter.convert(inExpression)).thenReturn(Optional.of(expectedInNode));
+        SqlNode expectedBetweenNode = mock(SqlNode.class);
+        BetweenExpression betweenExpression = new BetweenExpression(0, 0, 
literalSegment, literalSegment, literalSegment, false);
+        
when(BetweenExpressionConverter.convert(betweenExpression)).thenReturn(Optional.of(expectedBetweenNode));
+        SqlNode expectedParameterNode = mock(SqlNode.class);
+        ParameterMarkerExpressionSegment parameterSegment = new 
ParameterMarkerExpressionSegment(0, 0, 0);
+        
when(ParameterMarkerExpressionConverter.convert(parameterSegment)).thenReturn(Optional.of(expectedParameterNode));
+        SqlNode expectedFunctionNode = mock(SqlNode.class);
+        FunctionSegment functionSegment = new FunctionSegment(0, 0, "func", 
"func_text");
+        
when(FunctionConverter.convert(functionSegment)).thenReturn(Optional.of(expectedFunctionNode));
+        SqlNode expectedAggregationNode = mock(SqlNode.class);
+        AggregationProjectionSegment aggregationSegment = new 
AggregationProjectionSegment(0, 0, AggregationType.COUNT, "count(expr)");
+        
when(AggregationProjectionConverter.convert(aggregationSegment)).thenReturn(Optional.of(expectedAggregationNode));
+        DataTypeSegment dataTypeSegment = new DataTypeSegment();
+        dataTypeSegment.setStartIndex(0);
+        dataTypeSegment.setStopIndex(0);
+        dataTypeSegment.setDataTypeName("int");
+        SqlNode expectedDataTypeNode = mock(SqlNode.class);
+        
when(DataTypeExpressionConverter.convert(dataTypeSegment)).thenReturn(Optional.of(expectedDataTypeNode));
+        SqlNode expectedCaseWhenNode = mock(SqlNode.class);
+        CaseWhenExpression caseWhenExpression = new CaseWhenExpression(0, 0, 
literalSegment, Collections.singleton(literalSegment), 
Collections.singleton(literalSegment), literalSegment);
+        
when(CaseWhenExpressionConverter.convert(caseWhenExpression)).thenReturn(Optional.of(expectedCaseWhenNode));
+        SqlNode expectedNotNode = mock(SqlNode.class);
+        NotExpression notExpression = new NotExpression(0, 0, literalSegment, 
true);
+        
when(NotExpressionConverter.convert(notExpression)).thenReturn(Optional.of(expectedNotNode));
+        SqlNode expectedTypeCastNode = mock(SqlNode.class);
+        TypeCastExpression typeCastExpression = new TypeCastExpression(0, 0, 
"text", literalSegment, "int");
+        
when(TypeCastExpressionConverter.convert(typeCastExpression)).thenReturn(Optional.of(expectedTypeCastNode));
+        SqlNode expectedExtractNode = mock(SqlNode.class);
+        ExtractArgExpression extractArgExpression = new 
ExtractArgExpression(0, 0, "extract");
+        
when(ExtractArgExpressionConverter.convert(extractArgExpression)).thenReturn(Optional.of(expectedExtractNode));
+        SqlNode expectedMatchNode = mock(SqlNode.class);
+        MatchAgainstExpression matchAgainstExpression = new 
MatchAgainstExpression(0, 0, literalSegment, "search", "text");
+        
when(MatchExpressionConverter.convert(matchAgainstExpression)).thenReturn(Optional.of(expectedMatchNode));
+        SqlNode expectedCollateNode = mock(SqlNode.class);
+        CollateExpression collateExpression = new CollateExpression(0, 0, 
literalSegment, literalSegment);
+        
when(CollateExpressionConverter.convert(collateExpression)).thenReturn(Optional.of(expectedCollateNode));
+        SqlNode expectedRowNode = mock(SqlNode.class);
+        RowExpression rowExpression = new RowExpression(0, 0, "row");
+        
when(RowExpressionConverter.convert(rowExpression)).thenReturn(Optional.of(expectedRowNode));
+        SqlNode expectedVariableNode = mock(SqlNode.class);
+        VariableSegment variableSegment = new VariableSegment(0, 0, 
"@@session");
+        
when(VariableSegmentConverter.convert(variableSegment)).thenReturn(Optional.of(expectedVariableNode));
+        SqlNode expectedUnaryNode = mock(SqlNode.class);
+        UnaryOperationExpression unaryOperationExpression = new 
UnaryOperationExpression(0, 0, literalSegment, "+", "text");
+        
when(UnaryOperationExpressionConverter.convert(unaryOperationExpression)).thenReturn(Optional.of(expectedUnaryNode));
+        SqlNode expectedIntervalNode = mock(SqlNode.class);
+        IntervalExpression intervalExpression = new IntervalExpression(0, 0, 
literalSegment, IntervalUnit.DAY, "interval");
+        
when(IntervalExpressionConverter.convert(intervalExpression)).thenReturn(Optional.of(expectedIntervalNode));
+        SqlNode expectedQuantifyNode = mock(SqlNode.class);
+        QuantifySubqueryExpression quantifySubqueryExpression = new 
QuantifySubqueryExpression(0, 0, new SubquerySegment(0, 0, new 
SelectStatement(databaseType), "sub"), "ALL");
+        
when(QuantifySubqueryExpressionConverter.convert(quantifySubqueryExpression)).thenReturn(Optional.of(expectedQuantifyNode));
+        Map<ExpressionSegment, SqlNode> expectations = new LinkedHashMap<>(23, 
1F);
+        expectations.put(literalSegment, expectedLiteralNode);
+        expectations.put(listSegment, expectedListNode);
+        expectations.put(binarySegment, expectedBinaryNode);
+        expectations.put(columnSegment, expectedColumnNode);
+        expectations.put(existsSubqueryExpression, expectedExistsSubqueryNode);
+        expectations.put(subqueryExpressionSegment, expectedSubqueryNode);
+        expectations.put(inExpression, expectedInNode);
+        expectations.put(betweenExpression, expectedBetweenNode);
+        expectations.put(parameterSegment, expectedParameterNode);
+        expectations.put(functionSegment, expectedFunctionNode);
+        expectations.put(aggregationSegment, expectedAggregationNode);
+        expectations.put(dataTypeSegment, expectedDataTypeNode);
+        expectations.put(caseWhenExpression, expectedCaseWhenNode);
+        expectations.put(notExpression, expectedNotNode);
+        expectations.put(typeCastExpression, expectedTypeCastNode);
+        expectations.put(extractArgExpression, expectedExtractNode);
+        expectations.put(matchAgainstExpression, expectedMatchNode);
+        expectations.put(collateExpression, expectedCollateNode);
+        expectations.put(rowExpression, expectedRowNode);
+        expectations.put(variableSegment, expectedVariableNode);
+        expectations.put(unaryOperationExpression, expectedUnaryNode);
+        expectations.put(intervalExpression, expectedIntervalNode);
+        expectations.put(quantifySubqueryExpression, expectedQuantifyNode);
+        for (Entry<ExpressionSegment, SqlNode> entry : 
expectations.entrySet()) {
+            Optional<SqlNode> actualOptional = 
ExpressionConverter.convert(entry.getKey());
+            assertTrue(actualOptional.isPresent());
+            assertThat(actualOptional.orElse(null), is(entry.getValue()));
+        }
+    }
+    
+    @Test
+    void assertConvertThrowsUnsupportedForCommonExpression() {
+        CommonExpressionSegment expressionSegment = new 
CommonExpressionSegment(0, 0, "text");
+        UnsupportedSQLOperationException actualException = 
assertThrows(UnsupportedSQLOperationException.class, () -> 
ExpressionConverter.convert(expressionSegment));
+        assertThat(actualException.getMessage(), is("Unsupported SQL 
operation: unsupported CommonExpressionSegment."));
+    }
+    
+    @Test
+    void assertConvertReturnsEmptyForNullSegment() {
+        assertFalse(ExpressionConverter.convert(null).isPresent());
+    }
+    
+    @Test
+    void assertConvertThrowsUnsupportedForUnknownExpression() {
+        ExpressionSegment expressionSegment = mock(ExpressionSegment.class);
+        UnsupportedSQLOperationException actualException = 
assertThrows(UnsupportedSQLOperationException.class, () -> 
ExpressionConverter.convert(expressionSegment));
+        assertThat(actualException.getMessage(), is("Unsupported SQL 
operation: unsupported TableSegment type: " + expressionSegment.getClass() + 
"."));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/from/TableConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/from/TableConverterTest.java
new file mode 100644
index 00000000000..b6e0181fbb4
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/from/TableConverterTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.from;
+
+import org.apache.calcite.sql.SqlNode;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import 
org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.DeleteMultiTableSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.JoinTableSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.from.impl.DeleteMultiTableConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.from.impl.JoinTableConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.from.impl.SimpleTableConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.from.impl.SubqueryTableConverter;
+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.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings({SimpleTableConverter.class, JoinTableConverter.class, 
SubqueryTableConverter.class, DeleteMultiTableConverter.class})
+class TableConverterTest {
+    
+    private final DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    
+    @Test
+    void assertConvertDelegatesAllSupportedSegments() {
+        SqlNode expectedSimpleNode = mock(SqlNode.class);
+        SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_simple")));
+        
when(SimpleTableConverter.convert(simpleTableSegment)).thenReturn(Optional.of(expectedSimpleNode));
+        SqlNode expectedJoinNode = mock(SqlNode.class);
+        JoinTableSegment joinTableSegment = new JoinTableSegment();
+        joinTableSegment.setLeft(simpleTableSegment);
+        joinTableSegment.setRight(simpleTableSegment);
+        
when(JoinTableConverter.convert(joinTableSegment)).thenReturn(Optional.of(expectedJoinNode));
+        SqlNode expectedSubqueryNode = mock(SqlNode.class);
+        SubquerySegment subquerySegment = new SubquerySegment(0, 0, new 
SelectStatement(databaseType), "sub");
+        SubqueryTableSegment subqueryTableSegment = new 
SubqueryTableSegment(0, 0, subquerySegment);
+        
when(SubqueryTableConverter.convert(subqueryTableSegment)).thenReturn(Optional.of(expectedSubqueryNode));
+        SqlNode expectedDeleteNode = mock(SqlNode.class);
+        DeleteMultiTableSegment deleteMultiTableSegment = new 
DeleteMultiTableSegment();
+        deleteMultiTableSegment.setRelationTable(simpleTableSegment);
+        
when(DeleteMultiTableConverter.convert(deleteMultiTableSegment)).thenReturn(Optional.of(expectedDeleteNode));
+        assertThat(TableConverter.convert(simpleTableSegment).orElse(null), 
is(expectedSimpleNode));
+        assertThat(TableConverter.convert(joinTableSegment).orElse(null), 
is(expectedJoinNode));
+        assertThat(TableConverter.convert(subqueryTableSegment).orElse(null), 
is(expectedSubqueryNode));
+        
assertThat(TableConverter.convert(deleteMultiTableSegment).orElse(null), 
is(expectedDeleteNode));
+    }
+    
+    @Test
+    void assertConvertReturnsEmptyForNullSegment() {
+        assertFalse(TableConverter.convert(null).isPresent());
+    }
+    
+    @Test
+    void assertConvertThrowsUnsupportedForUnknownSegment() {
+        TableSegment unknownSegment = mock(TableSegment.class);
+        UnsupportedSQLOperationException actualException = 
assertThrows(UnsupportedSQLOperationException.class, () -> 
TableConverter.convert(unknownSegment));
+        assertThat(actualException.getMessage(), is("Unsupported SQL 
operation: Unsupported segment type: " + unknownSegment.getClass() + "."));
+    }
+}
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/projection/ProjectionsConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/projection/ProjectionsConverterTest.java
new file mode 100644
index 00000000000..a119ee2efb6
--- /dev/null
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/projection/ProjectionsConverterTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.projection;
+
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationProjectionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ShorthandProjectionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl.ParameterMarkerExpressionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.projection.impl.AggregationProjectionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.projection.impl.ColumnProjectionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.projection.impl.ExpressionProjectionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.projection.impl.ShorthandProjectionConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.projection.impl.SubqueryProjectionConverter;
+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.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings({
+        ColumnProjectionConverter.class, ExpressionProjectionConverter.class, 
ShorthandProjectionConverter.class,
+        SubqueryProjectionConverter.class, 
AggregationProjectionConverter.class, ParameterMarkerExpressionConverter.class
+})
+class ProjectionsConverterTest {
+    
+    @Test
+    void assertConvertCollectsAllSupportedProjections() {
+        ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0);
+        SqlNode expectedColumnNode = mock(SqlNode.class);
+        ColumnProjectionSegment columnProjectionSegment = 
mock(ColumnProjectionSegment.class);
+        
when(ColumnProjectionConverter.convert(columnProjectionSegment)).thenReturn(Optional.of(expectedColumnNode));
+        projectionsSegment.getProjections().add(columnProjectionSegment);
+        SqlNode expectedExpressionNode = mock(SqlNode.class);
+        ExpressionProjectionSegment expressionProjectionSegment = 
mock(ExpressionProjectionSegment.class);
+        
when(ExpressionProjectionConverter.convert(expressionProjectionSegment)).thenReturn(Optional.of(expectedExpressionNode));
+        projectionsSegment.getProjections().add(expressionProjectionSegment);
+        SqlNode expectedShorthandNode = mock(SqlNode.class);
+        ShorthandProjectionSegment shorthandProjectionSegment = 
mock(ShorthandProjectionSegment.class);
+        
when(ShorthandProjectionConverter.convert(shorthandProjectionSegment)).thenReturn(Optional.of(expectedShorthandNode));
+        projectionsSegment.getProjections().add(shorthandProjectionSegment);
+        SqlNode expectedSubqueryNode = mock(SqlNode.class);
+        SubqueryProjectionSegment subqueryProjectionSegment = 
mock(SubqueryProjectionSegment.class);
+        
when(SubqueryProjectionConverter.convert(subqueryProjectionSegment)).thenReturn(Optional.of(expectedSubqueryNode));
+        projectionsSegment.getProjections().add(subqueryProjectionSegment);
+        SqlNode expectedAggregationNode = mock(SqlNode.class);
+        AggregationProjectionSegment aggregationProjectionSegment = 
mock(AggregationProjectionSegment.class);
+        
when(AggregationProjectionConverter.convert(aggregationProjectionSegment)).thenReturn(Optional.of(expectedAggregationNode));
+        projectionsSegment.getProjections().add(aggregationProjectionSegment);
+        SqlNode expectedParameterNode = mock(SqlNode.class);
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment = 
new ParameterMarkerExpressionSegment(0, 0, 0);
+        
when(ParameterMarkerExpressionConverter.convert(parameterMarkerExpressionSegment)).thenReturn(Optional.of(expectedParameterNode));
+        
projectionsSegment.getProjections().add(parameterMarkerExpressionSegment);
+        SqlNodeList actual = 
ProjectionsConverter.convert(projectionsSegment).orElse(null);
+        assertNotNull(actual);
+        assertThat(actual.size(), is(6));
+        assertThat(actual.get(0), is(expectedColumnNode));
+        assertThat(actual.get(1), is(expectedExpressionNode));
+        assertThat(actual.get(2), is(expectedShorthandNode));
+        assertThat(actual.get(3), is(expectedSubqueryNode));
+        assertThat(actual.get(4), is(expectedAggregationNode));
+        assertThat(actual.get(5), is(expectedParameterNode));
+    }
+    
+    @Test
+    void assertConvertSkipsUnsupportedProjection() {
+        ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0);
+        ProjectionSegment unsupportedProjection = 
mock(ProjectionSegment.class);
+        projectionsSegment.getProjections().add(unsupportedProjection);
+        SqlNodeList actual = 
ProjectionsConverter.convert(projectionsSegment).orElse(null);
+        assertNotNull(actual);
+        assertFalse(actual.iterator().hasNext());
+    }
+}

Reply via email to