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());
+ }
+}