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

terrymanu 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 f73b57cae98 Fix derived table alias columns for PostgreSQL values 
subquery (#38989)
f73b57cae98 is described below

commit f73b57cae98c8c9d3aa80b70149a87c6c6caaa58
Author: Zhengcy05 <[email protected]>
AuthorDate: Sun Jul 5 05:15:26 2026 +0800

    Fix derived table alias columns for PostgreSQL values subquery (#38989)
    
    * fix: support derived table alias columns for PostgreSQL values subquery
    
    * fix: checkstyle and CI
    
    * fix: modify CI xml
---
 .../dml/from/type/SubqueryTableSegmentBinder.java  |  17 ++-
 .../from/type/SubqueryTableSegmentBinderTest.java  | 126 ++++++++++++++-------
 .../statement/PostgreSQLStatementVisitor.java      |  39 +++++--
 .../statement/PostgreSQLStatementVisitorTest.java  |  35 ++++++
 .../core/segment/generic/AliasSegment.java         |   5 +
 .../src/main/resources/case/ddl/create-view.xml    |  40 ++++++-
 .../resources/sql/supported/ddl/create-view.xml    |   3 +-
 7 files changed, 211 insertions(+), 54 deletions(-)

diff --git 
a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinder.java
 
b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinder.java
index 12feba37d8d..592345efbeb 100644
--- 
a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinder.java
+++ 
b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinder.java
@@ -84,7 +84,7 @@ public final class SubqueryTableSegmentBinder {
         segment.getAliasSegment().ifPresent(result::setAlias);
         Collection<ProjectionSegment> subqueryProjections = 
SubqueryTableBindUtils.createSubqueryProjections(
                 boundSubSelect.getProjections().getProjections(), 
subqueryTableName, binderContext.getSqlStatement().getDatabaseType(), 
TableSourceType.TEMPORARY_TABLE);
-        Collection<ColumnSegment> boundSubqueryColumns = 
bindSubqueryColumns(segment.getColumns(), new ArrayList<>(subqueryProjections));
+        Collection<ColumnSegment> boundSubqueryColumns = 
bindSubqueryColumns(getSubqueryColumns(segment), new 
ArrayList<>(subqueryProjections));
         result.getColumns().addAll(boundSubqueryColumns);
         if (!boundSubqueryColumns.isEmpty()) {
             subqueryProjections = 
createBoundSubqueryColumnProjections(boundSubqueryColumns, subqueryTableName);
@@ -97,6 +97,21 @@ public final class SubqueryTableSegmentBinder {
         return result;
     }
     
+    private static Collection<ColumnSegment> getSubqueryColumns(final 
SubqueryTableSegment segment) {
+        if (!segment.getColumns().isEmpty()) {
+            return segment.getColumns();
+        }
+        if (!segment.getAliasSegment().isPresent() || 
segment.getAliasSegment().get().getColumnAliases().isEmpty()) {
+            return Collections.emptyList();
+        }
+        Collection<ColumnSegment> result = new LinkedList<>();
+        AliasSegment aliasSegment = segment.getAliasSegment().get();
+        for (IdentifierValue each : aliasSegment.getColumnAliases()) {
+            result.add(new ColumnSegment(aliasSegment.getStartIndex(), 
aliasSegment.getStopIndex(), each));
+        }
+        return result;
+    }
+    
     private static Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
createTableBinderContexts(final IdentifierValue subqueryTableName,
                                                                                
                         final TableSegmentBinderContext tableBinderContext) {
         Multimap<CaseInsensitiveString, TableSegmentBinderContext> result = 
LinkedHashMultimap.create();
diff --git 
a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinderTest.java
 
b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinderTest.java
index 6928f681ffd..3cf1b58b27d 100644
--- 
a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinderTest.java
+++ 
b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinderTest.java
@@ -23,10 +23,16 @@ import com.google.common.collect.Multimap;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.dml.from.context.TableSegmentBinderContext;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
+import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
+import 
org.apache.shardingsphere.infra.exception.kernel.syntax.DifferenceInColumnCountOfSelectListAndColumnNameListException;
 import org.apache.shardingsphere.infra.hint.HintValueContext;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import 
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
+import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import 
org.apache.shardingsphere.sql.parser.statement.core.enums.TableSourceType;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
@@ -46,17 +52,18 @@ import org.junit.jupiter.api.Test;
 import java.sql.Types;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
+import java.util.Properties;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.isA;
 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.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
 class SubqueryTableSegmentBinderTest {
     
@@ -64,12 +71,7 @@ class SubqueryTableSegmentBinderTest {
     
     @Test
     void assertBindWithSubqueryTableAlias() {
-        SelectStatement selectStatement = mock(SelectStatement.class);
-        when(selectStatement.getDatabaseType()).thenReturn(databaseType);
-        when(selectStatement.getFrom()).thenReturn(Optional.of(new 
SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("t_order")))));
-        ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0);
-        projectionsSegment.getProjections().add(new 
ShorthandProjectionSegment(0, 0));
-        when(selectStatement.getProjections()).thenReturn(projectionsSegment);
+        SelectStatement selectStatement = createSelectStatement(new 
ShorthandProjectionSegment(0, 0));
         SubqueryTableSegment subqueryTableSegment = new 
SubqueryTableSegment(0, 0, new SubquerySegment(0, 0, selectStatement, ""));
         subqueryTableSegment.setAlias(new AliasSegment(0, 0, new 
IdentifierValue("temp")));
         ShardingSphereMetaData metaData = createMetaData();
@@ -96,14 +98,9 @@ class SubqueryTableSegmentBinderTest {
     
     @Test
     void assertBindWithSubqueryProjectionAlias() {
-        SelectStatement selectStatement = mock(SelectStatement.class);
-        when(selectStatement.getDatabaseType()).thenReturn(databaseType);
-        when(selectStatement.getFrom()).thenReturn(Optional.of(new 
SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("t_order")))));
-        ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0);
         ColumnProjectionSegment columnProjectionSegment = new 
ColumnProjectionSegment(new ColumnSegment(0, 0, new 
IdentifierValue("order_id")));
         columnProjectionSegment.setAlias(new AliasSegment(0, 0, new 
IdentifierValue("order_id_alias")));
-        projectionsSegment.getProjections().add(columnProjectionSegment);
-        when(selectStatement.getProjections()).thenReturn(projectionsSegment);
+        SelectStatement selectStatement = 
createSelectStatement(columnProjectionSegment);
         SubqueryTableSegment subqueryTableSegment = new 
SubqueryTableSegment(0, 0, new SubquerySegment(0, 0, selectStatement, ""));
         subqueryTableSegment.setAlias(new AliasSegment(0, 0, new 
IdentifierValue("temp")));
         ShardingSphereMetaData metaData = createMetaData();
@@ -122,12 +119,7 @@ class SubqueryTableSegmentBinderTest {
     
     @Test
     void assertBindWithoutSubqueryTableAlias() {
-        SelectStatement selectStatement = mock(SelectStatement.class);
-        when(selectStatement.getDatabaseType()).thenReturn(databaseType);
-        when(selectStatement.getFrom()).thenReturn(Optional.of(new 
SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("t_order")))));
-        ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0);
-        projectionsSegment.getProjections().add(new 
ShorthandProjectionSegment(0, 0));
-        when(selectStatement.getProjections()).thenReturn(projectionsSegment);
+        SelectStatement selectStatement = createSelectStatement(new 
ShorthandProjectionSegment(0, 0));
         SubqueryTableSegment subqueryTableSegment = new 
SubqueryTableSegment(0, 0, new SubquerySegment(0, 0, selectStatement, ""));
         ShardingSphereMetaData metaData = createMetaData();
         Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
tableBinderContexts = LinkedHashMultimap.create();
@@ -139,13 +131,9 @@ class SubqueryTableSegmentBinderTest {
     
     @Test
     void assertBindWithSubqueryTableColumns() {
-        SelectStatement selectStatement = mock(SelectStatement.class);
-        when(selectStatement.getDatabaseType()).thenReturn(databaseType);
-        when(selectStatement.getFrom()).thenReturn(Optional.of(new 
SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("t_order")))));
-        ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0);
-        projectionsSegment.getProjections().add(new 
ColumnProjectionSegment(new ColumnSegment(0, 0, new 
IdentifierValue("user_id"))));
-        projectionsSegment.getProjections().add(new 
ColumnProjectionSegment(new ColumnSegment(0, 0, new 
IdentifierValue("status"))));
-        when(selectStatement.getProjections()).thenReturn(projectionsSegment);
+        SelectStatement selectStatement = createSelectStatement(
+                new ColumnProjectionSegment(new ColumnSegment(0, 0, new 
IdentifierValue("user_id"))),
+                new ColumnProjectionSegment(new ColumnSegment(0, 0, new 
IdentifierValue("status"))));
         SubqueryTableSegment subqueryTableSegment = new 
SubqueryTableSegment(0, 0, new SubquerySegment(0, 0, selectStatement, ""));
         subqueryTableSegment.setAlias(new AliasSegment(0, 0, new 
IdentifierValue("combined")));
         subqueryTableSegment.getColumns().add(new ColumnSegment(0, 0, new 
IdentifierValue("id")));
@@ -187,23 +175,75 @@ class SubqueryTableSegmentBinderTest {
         
assertThat(actualNameProjection.getColumn().getColumnBoundInfo().getTableSourceType(),
 is(TableSourceType.TEMPORARY_TABLE));
     }
     
+    @Test
+    void assertBindWithSubqueryAliasColumns() {
+        SelectStatement selectStatement = createSelectStatement(
+                new ColumnProjectionSegment(new ColumnSegment(0, 0, new 
IdentifierValue("user_id"))),
+                new ColumnProjectionSegment(new ColumnSegment(0, 0, new 
IdentifierValue("status"))));
+        SubqueryTableSegment subqueryTableSegment = new 
SubqueryTableSegment(0, 0, new SubquerySegment(0, 0, selectStatement, ""));
+        AliasSegment aliasSegment = new AliasSegment(0, 0, new 
IdentifierValue("combined"));
+        aliasSegment.getColumnAliases().add(new IdentifierValue("id"));
+        aliasSegment.getColumnAliases().add(new IdentifierValue("name"));
+        subqueryTableSegment.setAlias(aliasSegment);
+        ShardingSphereMetaData metaData = createMetaData();
+        Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
tableBinderContexts = LinkedHashMultimap.create();
+        SubqueryTableSegment actual = 
SubqueryTableSegmentBinder.bind(subqueryTableSegment,
+                new SQLStatementBinderContext(metaData, "foo_db", new 
HintValueContext(), selectStatement),
+                tableBinderContexts, LinkedHashMultimap.create(), false);
+        assertThat(actual.getColumns().size(), is(2));
+        List<ColumnSegment> actualColumns = new 
ArrayList<>(actual.getColumns());
+        assertFalse(actualColumns.get(0).getOwner().isPresent());
+        assertThat(actualColumns.get(0).getIdentifier().getValue(), is("id"));
+        
assertThat(actualColumns.get(0).getColumnBoundInfo().getOriginalTable().getValue(),
 is("t_order"));
+        
assertThat(actualColumns.get(0).getColumnBoundInfo().getOriginalColumn().getValue(),
 is("user_id"));
+        assertFalse(actualColumns.get(1).getOwner().isPresent());
+        assertThat(actualColumns.get(1).getIdentifier().getValue(), 
is("name"));
+        
assertThat(actualColumns.get(1).getColumnBoundInfo().getOriginalTable().getValue(),
 is("t_order"));
+        
assertThat(actualColumns.get(1).getColumnBoundInfo().getOriginalColumn().getValue(),
 is("status"));
+        
assertTrue(tableBinderContexts.containsKey(CaseInsensitiveString.of("combined")));
+        TableSegmentBinderContext tableSegmentBinderContext = 
tableBinderContexts.get(CaseInsensitiveString.of("combined")).iterator().next();
+        Optional<ProjectionSegment> idProjection = 
tableSegmentBinderContext.findProjectionSegmentByColumnLabel("id");
+        assertTrue(idProjection.isPresent());
+        assertThat(idProjection.get(), isA(ColumnProjectionSegment.class));
+        Optional<ProjectionSegment> nameProjection = 
tableSegmentBinderContext.findProjectionSegmentByColumnLabel("name");
+        assertTrue(nameProjection.isPresent());
+        assertThat(nameProjection.get(), isA(ColumnProjectionSegment.class));
+    }
+    
+    @Test
+    void assertBindWithSubqueryAliasColumnsAndDifferentColumnCount() {
+        SelectStatement selectStatement = createSelectStatement(new 
ColumnProjectionSegment(new ColumnSegment(0, 0, new 
IdentifierValue("user_id"))));
+        SubqueryTableSegment subqueryTableSegment = new 
SubqueryTableSegment(0, 0, new SubquerySegment(0, 0, selectStatement, ""));
+        AliasSegment aliasSegment = new AliasSegment(0, 0, new 
IdentifierValue("combined"));
+        aliasSegment.getColumnAliases().add(new IdentifierValue("id"));
+        aliasSegment.getColumnAliases().add(new IdentifierValue("name"));
+        subqueryTableSegment.setAlias(aliasSegment);
+        ShardingSphereMetaData metaData = createMetaData();
+        
assertThrows(DifferenceInColumnCountOfSelectListAndColumnNameListException.class,
+                () -> SubqueryTableSegmentBinder.bind(subqueryTableSegment,
+                        new SQLStatementBinderContext(metaData, "foo_db", new 
HintValueContext(), selectStatement),
+                        LinkedHashMultimap.create(), 
LinkedHashMultimap.create(), false));
+    }
+    
+    private SelectStatement createSelectStatement(final ProjectionSegment... 
projections) {
+        ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0);
+        projectionsSegment.getProjections().addAll(Arrays.asList(projections));
+        return 
SelectStatement.builder().databaseType(databaseType).projections(projectionsSegment)
+                .from(new SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("t_order")))).build();
+    }
+    
     private ShardingSphereMetaData createMetaData() {
-        ShardingSphereSchema schema = mock(ShardingSphereSchema.class, 
RETURNS_DEEP_STUBS);
-        IdentifierValue fooDatabase = new IdentifierValue("foo_db");
-        IdentifierValue tOrder = new IdentifierValue("t_order");
-        when(schema.getTable(tOrder).getAllColumns()).thenReturn(Arrays.asList(
+        Collection<ShardingSphereColumn> columns = Arrays.asList(
                 new ShardingSphereColumn("order_id", Types.INTEGER, true, 
false, false, true, false, false),
                 new ShardingSphereColumn("user_id", Types.INTEGER, false, 
false, false, true, false, false),
-                new ShardingSphereColumn("status", Types.INTEGER, false, 
false, false, true, false, false)));
-        ShardingSphereMetaData result = mock(ShardingSphereMetaData.class, 
RETURNS_DEEP_STUBS);
-        
when(result.getDatabase("foo_db").getSchema("foo_db")).thenReturn(schema);
-        
when(result.getDatabase(fooDatabase).getSchema(fooDatabase)).thenReturn(schema);
-        when(result.containsDatabase(fooDatabase)).thenReturn(true);
-        
when(result.getDatabase("foo_db").getDefaultSchemaName()).thenReturn("foo_db");
-        
when(result.getDatabase(fooDatabase).getDefaultSchemaName()).thenReturn("foo_db");
-        
when(result.getDatabase("foo_db").containsSchema("foo_db")).thenReturn(true);
-        
when(result.getDatabase(fooDatabase).containsSchema(fooDatabase)).thenReturn(true);
-        
when(result.getDatabase(fooDatabase).getSchema(fooDatabase).containsTable(tOrder)).thenReturn(true);
-        return result;
+                new ShardingSphereColumn("status", Types.INTEGER, false, 
false, false, true, false, false));
+        ShardingSphereTable table = new ShardingSphereTable("t_order", 
columns, Collections.emptyList(), Collections.emptyList());
+        ShardingSphereSchema schema = new ShardingSphereSchema("foo_db", 
databaseType, Collections.singletonList(table), Collections.emptyList());
+        ConfigurationProperties props = new ConfigurationProperties(new 
Properties());
+        ResourceMetaData globalResourceMetaData = new 
ResourceMetaData(Collections.emptyMap(), Collections.emptyMap());
+        RuleMetaData globalRuleMetaData = new 
RuleMetaData(Collections.emptyList());
+        ShardingSphereDatabase database = new ShardingSphereDatabase("foo_db", 
databaseType,
+                new ResourceMetaData(Collections.emptyMap(), 
Collections.emptyMap()), new RuleMetaData(Collections.emptyList()), 
Collections.singletonList(schema), props);
+        return new ShardingSphereMetaData(Collections.singletonList(database), 
globalResourceMetaData, globalRuleMetaData, props);
     }
 }
diff --git 
a/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
 
b/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
index 8ec7348f9e1..9eb2f88e9d8 100644
--- 
a/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
+++ 
b/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
@@ -1075,14 +1075,16 @@ public abstract class PostgreSQLStatementVisitor 
extends PostgreSQLStatementPars
     @Override
     public ASTNode visitSimpleSelect(final SimpleSelectContext ctx) {
         SelectStatement.SelectStatementBuilder selectStatementBuilder = 
SelectStatement.builder().databaseType(databaseType);
-        if (null == ctx.targetList()) {
-            selectStatementBuilder.projections(new ProjectionsSegment(-1, -1));
-        } else {
+        if (null != ctx.targetList()) {
             ProjectionsSegment projects = (ProjectionsSegment) 
visit(ctx.targetList());
             if (null != ctx.distinctClause()) {
                 projects.setDistinctRow(true);
             }
             selectStatementBuilder.projections(projects);
+        } else if (null != ctx.valuesClause()) {
+            
selectStatementBuilder.projections(createValuesProjections(ctx.valuesClause()));
+        } else {
+            selectStatementBuilder.projections(new ProjectionsSegment(-1, -1));
         }
         if (null != ctx.intoClause()) {
             selectStatementBuilder.into((TableSegment) 
visit(ctx.intoClause()));
@@ -1105,6 +1107,18 @@ public abstract class PostgreSQLStatementVisitor extends 
PostgreSQLStatementPars
         return selectStatementBuilder.build();
     }
     
+    private ProjectionsSegment createValuesProjections(final 
ValuesClauseContext ctx) {
+        ProjectionsSegment result = new 
ProjectionsSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
+        Collection<InsertValuesSegment> values = 
createInsertValuesSegments(ctx);
+        if (values.isEmpty()) {
+            return result;
+        }
+        for (ExpressionSegment each : values.iterator().next().getValues()) {
+            result.getProjections().add(new 
ExpressionProjectionSegment(each.getStartIndex(), each.getStopIndex(), 
each.getText(), each));
+        }
+        return result;
+    }
+    
     @Override
     public ASTNode visitIntoClause(final IntoClauseContext ctx) {
         return visit(ctx.optTempTableName().qualifiedName());
@@ -1422,13 +1436,22 @@ public abstract class PostgreSQLStatementVisitor 
extends PostgreSQLStatementPars
     
     @Override
     public ASTNode visitAliasClause(final AliasClauseContext ctx) {
-        StringBuilder aliasName = new StringBuilder(ctx.colId().getText());
+        AliasSegment result = new 
AliasSegment(ctx.colId().start.getStartIndex(), ctx.stop.getStopIndex(), new 
IdentifierValue(ctx.colId().getText()));
+        if (null != ctx.nameList()) {
+            
result.getColumnAliases().addAll(generateAliasColumns(ctx.nameList()));
+        }
+        return result;
+    }
+    
+    private Collection<IdentifierValue> generateAliasColumns(final 
NameListContext ctx) {
+        Collection<IdentifierValue> result = new LinkedList<>();
         if (null != ctx.nameList()) {
-            aliasName.append(ctx.LP_().getText());
-            aliasName.append(ctx.nameList().getText());
-            aliasName.append(ctx.RP_().getText());
+            result.addAll(generateAliasColumns(ctx.nameList()));
         }
-        return new AliasSegment(ctx.colId().start.getStartIndex(), 
ctx.stop.getStopIndex(), new IdentifierValue(aliasName.toString()));
+        if (null != ctx.name()) {
+            result.add(new IdentifierValue(ctx.name().getText()));
+        }
+        return result;
     }
     
     private OwnerSegment createTableOwner(final IndirectionContext ctx) {
diff --git 
a/parser/sql/engine/dialect/postgresql/src/test/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitorTest.java
 
b/parser/sql/engine/dialect/postgresql/src/test/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitorTest.java
index 2a42131aba9..681d4528a57 100644
--- 
a/parser/sql/engine/dialect/postgresql/src/test/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitorTest.java
+++ 
b/parser/sql/engine/dialect/postgresql/src/test/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitorTest.java
@@ -24,15 +24,20 @@ import 
org.apache.shardingsphere.sql.parser.engine.core.ParseASTNode;
 import 
org.apache.shardingsphere.sql.parser.statement.core.extractor.TableExtractor;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.NotExpression;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationProjectionSegment;
+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.generic.WindowItemSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.UpdateStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 import org.junit.jupiter.api.Test;
 
 import java.util.Collection;
 import java.util.stream.Collectors;
 
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
 import static org.hamcrest.Matchers.hasItems;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.isA;
@@ -55,6 +60,36 @@ class PostgreSQLStatementVisitorTest {
         assertThat(rewriteTableNames, hasItems("t17", "t23", "t22"));
     }
     
+    @Test
+    void assertVisitSelectWithValuesDerivedTableColumnAliases() {
+        SelectStatement statement = (SelectStatement) new 
SQLStatementVisitorEngine("PostgreSQL").visit(
+                new SQLParserEngine("PostgreSQL", new CacheOption(128, 
1024L)).parse("SELECT * FROM (VALUES ('k1', 'v1', 1)) AS t(pk, col_a, 
col_a_type)", false));
+        assertTrue(statement.getFrom().isPresent());
+        assertThat(statement.getFrom().get(), isA(SubqueryTableSegment.class));
+        SubqueryTableSegment subqueryTableSegment = (SubqueryTableSegment) 
statement.getFrom().get();
+        assertTrue(subqueryTableSegment.getAliasSegment().isPresent());
+        
assertThat(subqueryTableSegment.getAliasSegment().get().getIdentifier().getValue(),
 is("t"));
+        Collection<String> actualColumnAliases = 
subqueryTableSegment.getAliasSegment().get().getColumnAliases().stream().map(IdentifierValue::getValue).collect(Collectors.toList());
+        assertThat(actualColumnAliases, contains("pk", "col_a", "col_a_type"));
+        Collection<ProjectionSegment> actualProjections = 
subqueryTableSegment.getSubquery().getSelect().getProjections().getProjections();
+        assertThat(actualProjections.size(), is(3));
+        actualProjections.forEach(each -> assertThat(each, 
isA(ExpressionProjectionSegment.class)));
+    }
+    
+    @Test
+    void assertVisitUpdateWithValuesDerivedTableColumnAliases() {
+        UpdateStatement statement = (UpdateStatement) new 
SQLStatementVisitorEngine("PostgreSQL").visit(new SQLParserEngine("PostgreSQL", 
new CacheOption(128, 1024L))
+                .parse("UPDATE t_order SET status = t.status FROM (VALUES (1, 
'PAID')) AS t(order_id, status) WHERE t_order.order_id = t.order_id", false));
+        assertTrue(statement.getFrom().isPresent());
+        assertThat(statement.getFrom().get(), isA(SubqueryTableSegment.class));
+        SubqueryTableSegment subqueryTableSegment = (SubqueryTableSegment) 
statement.getFrom().get();
+        assertTrue(subqueryTableSegment.getAliasSegment().isPresent());
+        
assertThat(subqueryTableSegment.getAliasSegment().get().getIdentifier().getValue(),
 is("t"));
+        Collection<String> actualColumnAliases = 
subqueryTableSegment.getAliasSegment().get().getColumnAliases().stream().map(IdentifierValue::getValue).collect(Collectors.toList());
+        assertThat(actualColumnAliases, contains("order_id", "status"));
+        
assertThat(subqueryTableSegment.getSubquery().getSelect().getProjections().getProjections().size(),
 is(2));
+    }
+    
     @Test
     void assertVisitWindowAggregationProjection() {
         String sql = "select pg_catalog.max(ref_0.c36) over (partition by 
ref_0.c39 order by ref_0.vkey desc) as c_5 from t24 as ref_0";
diff --git 
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/generic/AliasSegment.java
 
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/generic/AliasSegment.java
index ed6db791145..7605fca53da 100644
--- 
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/generic/AliasSegment.java
+++ 
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/generic/AliasSegment.java
@@ -22,6 +22,9 @@ import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.SQLSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 
+import java.util.Collection;
+import java.util.LinkedList;
+
 /**
  * Alias segment.
  */
@@ -34,4 +37,6 @@ public final class AliasSegment implements SQLSegment {
     private final int stopIndex;
     
     private final IdentifierValue identifier;
+    
+    private final Collection<IdentifierValue> columnAliases = new 
LinkedList<>();
 }
diff --git a/test/it/parser/src/main/resources/case/ddl/create-view.xml 
b/test/it/parser/src/main/resources/case/ddl/create-view.xml
index ab2cb958bd3..9a9409d1492 100644
--- a/test/it/parser/src/main/resources/case/ddl/create-view.xml
+++ b/test/it/parser/src/main/resources/case/ddl/create-view.xml
@@ -156,7 +156,45 @@
             <owner name="public" start-index="22" stop-index="27" />
         </view>
         <select>
-            <!-- FIXME support VALUES (1) projection parse -->
+            <projections start-index="47" stop-index="56">
+                <expression-projection text="1" start-index="55" 
stop-index="55" />
+            </projections>
+            <combine combine-type="UNION_ALL" start-index="47" 
stop-index="107">
+                <left>
+                    <projections start-index="47" stop-index="56">
+                        <expression-projection text="1" start-index="55" 
stop-index="55" />
+                    </projections>
+                </left>
+                <right>
+                    <projections start-index="75" stop-index="77">
+                        <expression-projection text="n+1" start-index="75" 
stop-index="77" />
+                    </projections>
+                    <from>
+                        <simple-table name="nums_1_100" start-index="84" 
stop-index="93" />
+                    </from>
+                    <where start-index="95" stop-index="107">
+                        <expr>
+                            <binary-operation-expression start-index="101" 
stop-index="107">
+                                <left>
+                                    <column name="n" start-index="101" 
stop-index="101" />
+                                </left>
+                                <right>
+                                    <literal-expression value="100" 
start-index="105" stop-index="107" />
+                                </right>
+                                <operator>=</operator>
+                            </binary-operation-expression>
+                        </expr>
+                    </where>
+                </right>
+            </combine>
+        </select>
+    </create-view>
+
+    <create-view sql-case-id="create_view_with_recursive_opengauss" 
view-definition="VALUES (1) UNION ALL SELECT n+1 FROM nums_1_100 WHERE n = 100">
+        <view name="nums_1_100" start-index="22" stop-index="38">
+            <owner name="public" start-index="22" stop-index="27" />
+        </view>
+        <select>
             <projections start-index="-1" stop-index="-1" />
             <combine combine-type="UNION_ALL" start-index="47" 
stop-index="107">
                 <left>
diff --git 
a/test/it/parser/src/main/resources/sql/supported/ddl/create-view.xml 
b/test/it/parser/src/main/resources/sql/supported/ddl/create-view.xml
index bd54900366e..5d741687521 100644
--- a/test/it/parser/src/main/resources/sql/supported/ddl/create-view.xml
+++ b/test/it/parser/src/main/resources/sql/supported/ddl/create-view.xml
@@ -24,7 +24,8 @@
     <sql-case id="create_view_with_owner_doris" value="CREATE VIEW 
report.v_sales AS SELECT order_id, user_id FROM t_order" db-types="Doris" />
     <sql-case id="create_view_with_columns_doris" value="CREATE VIEW 
example_view (c1, c2) AS SELECT k1, k2 FROM example_table" db-types="Doris" />
     <sql-case id="create_view_with_check_option" value="CREATE VIEW 
universal_comedies AS SELECT * FROM comedies WHERE classification = 'U' WITH 
LOCAL CHECK OPTION" db-types="PostgreSQL,openGauss" />
-    <sql-case id="create_view_with_recursive" value="CREATE RECURSIVE VIEW 
public.nums_1_100 (n) AS VALUES (1) UNION ALL SELECT n+1 FROM nums_1_100 WHERE 
n = 100" db-types="PostgreSQL,openGauss" />
+    <sql-case id="create_view_with_recursive" value="CREATE RECURSIVE VIEW 
public.nums_1_100 (n) AS VALUES (1) UNION ALL SELECT n+1 FROM nums_1_100 WHERE 
n = 100" db-types="PostgreSQL" />
+    <sql-case id="create_view_with_recursive_opengauss" value="CREATE 
RECURSIVE VIEW public.nums_1_100 (n) AS VALUES (1) UNION ALL SELECT n+1 FROM 
nums_1_100 WHERE n = 100" db-types="openGauss" />
     <sql-case id="create_view_with_option" value="CREATE OR REPLACE TEMP view 
order_view (order_id,user_id) WITH (security_barrier=TRUE) AS SELECT * FROM 
t_order" db-types="PostgreSQL,openGauss" />
     <sql-case id="create_or_replace_view_with_select" value="create or replace 
view named_moons as select p.name planet, p.class, m.name moon, m.radius from 
planets p, moons m where p.name = m.planet_name(+) and m.name(+) not like 
'S/%'" db-types="Oracle" />
     <sql-case id="create_view_as_simple_select1" value="CREATE VIEW 
laurel.employee AS SELECT * FROM laurel.emp" db-types="Oracle" />

Reply via email to