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

duanzhengqiang 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 2dbd51d799d Fix error parsing \l command SQL statement when front-end 
protocol is og (#37953)
2dbd51d799d is described below

commit 2dbd51d799d616bbd4ac9dc83509769446b83c3e
Author: Claire <[email protected]>
AuthorDate: Wed Feb 4 15:04:30 2026 +0800

    Fix error parsing \l command SQL statement when front-end protocol is og 
(#37953)
    
    * support og
    
    * update
    
    * update
    
    * release-notes
---
 RELEASE-NOTES.md                                   |  1 +
 .../OpenGaussSystemTableQueryExecutorFactory.java  |  7 ++-
 ...enGaussSystemTableQueryExecutorFactoryTest.java | 30 +++++++++++
 .../parser/src/main/resources/case/dml/select.xml  | 63 ++++++++++++++++++++++
 .../main/resources/sql/supported/dml/select.xml    |  1 +
 5 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 8d7ee36daef..aea2c709e27 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -8,6 +8,7 @@
 
 1. SQL Parser: Support Oracle SQL parser correctly extract REGEXP_SUBSTR 
parameters - [#37924](https://github.com/apache/shardingsphere/pull/37924)
 2. SQL Parser: Fix escape '\' in SQL causing DialectSQLParsingException - 
[#37943](https://github.com/apache/shardingsphere/pull/37943)
+3. SQL Parser: Fix error parsing \l command SQL statement when front-end 
protocol is og - [#37953](https://github.com/apache/shardingsphere/pull/37953)
 
 ## Release 5.5.3
 
diff --git 
a/proxy/backend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/factory/OpenGaussSystemTableQueryExecutorFactory.java
 
b/proxy/backend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/factory/OpenGaussSystemTableQueryExecutorFactory.java
index 248e3c78f39..e4bdf9ff0fc 100644
--- 
a/proxy/backend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/factory/OpenGaussSystemTableQueryExecutorFactory.java
+++ 
b/proxy/backend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/factory/OpenGaussSystemTableQueryExecutorFactory.java
@@ -33,6 +33,7 @@ import 
org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminExecutor;
 import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseMetaDataExecutor;
 import 
org.apache.shardingsphere.proxy.backend.opengauss.handler.admin.executor.OpenGaussSelectDatCompatibilityExecutor;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
@@ -87,12 +88,16 @@ public final class OpenGaussSystemTableQueryExecutorFactory 
{
         for (SimpleTableSegment each : 
selectStatementContext.getTablesContext().getSimpleTables()) {
             TableNameSegment tableNameSegment = each.getTableName();
             String tableName = tableNameSegment.getIdentifier().getValue();
-            String schemaName = 
tableNameSegment.getTableBoundInfo().map(TableSegmentBoundInfo::getOriginalSchema).map(IdentifierValue::getValue).orElse(null);
+            String schemaName = 
tableNameSegment.getTableBoundInfo().map(TableSegmentBoundInfo::getOriginalSchema).map(IdentifierValue::getValue).orElseGet(()
 -> getOwnerSchemaName(each));
             Optional.ofNullable(schemaName).ifPresent(optional -> 
result.computeIfAbsent(optional, key -> new 
CaseInsensitiveSet<>()).add(tableName));
         }
         return result;
     }
     
+    private static String getOwnerSchemaName(final SimpleTableSegment 
tableSegment) {
+        return 
tableSegment.getOwner().map(OwnerSegment::getIdentifier).map(IdentifierValue::getValue).orElse(null);
+    }
+    
     private static boolean isSelectSystemTable(final Map<String, 
Collection<String>> selectedSchemaTables) {
         if (selectedSchemaTables.isEmpty()) {
             return false;
diff --git 
a/proxy/backend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/factory/OpenGaussSystemTableQueryExecutorFactoryTest.java
 
b/proxy/backend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/factory/OpenGaussSystemTableQueryExecutorFactoryTest.java
index c0e4dd0959e..ca4db6e1026 100644
--- 
a/proxy/backend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/factory/OpenGaussSystemTableQueryExecutorFactoryTest.java
+++ 
b/proxy/backend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/handler/admin/factory/OpenGaussSystemTableQueryExecutorFactoryTest.java
@@ -17,16 +17,23 @@
 
 package 
org.apache.shardingsphere.proxy.backend.opengauss.handler.admin.factory;
 
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ColumnProjection;
 import 
org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.parser.ShardingSphereSQLParserEngine;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminExecutor;
 import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseMetaDataExecutor;
 import 
org.apache.shardingsphere.proxy.backend.opengauss.handler.admin.executor.OpenGaussSelectDatCompatibilityExecutor;
+import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
+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.junit.jupiter.api.Test;
 
@@ -60,6 +67,29 @@ class OpenGaussSystemTableQueryExecutorFactoryTest {
         assertThat(actual.get(), isA(DatabaseMetaDataExecutor.class));
     }
     
+    @Test
+    void 
assertSelectFromPgCatalogPgDatabaseViaParserShouldBeRecognizedAsSystemTable() {
+        String sql = "SELECT d.datname AS \"Name\",\n"
+                + "       pg_catalog.pg_get_userbyid(d.datdba) AS \"Owner\",\n"
+                + "       pg_catalog.pg_encoding_to_char(d.encoding) AS 
\"Encoding\",\n"
+                + "       d.datcollate AS \"Collate\",\n"
+                + "       d.datctype AS \"Ctype\",\n"
+                + "       pg_catalog.array_to_string(d.datacl, E'\\\\n') AS 
\"Access privileges\"\n"
+                + "FROM pg_catalog.pg_database d\n"
+                + "ORDER BY 1;";
+        SelectStatementContext sqlStatementContext = 
createSelectStatementContext(sql);
+        Optional<DatabaseAdminExecutor> actual = 
OpenGaussSystemTableQueryExecutorFactory.newInstance(sqlStatementContext, sql, 
Collections.emptyList());
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), isA(DatabaseMetaDataExecutor.class));
+    }
+    
+    private SelectStatementContext createSelectStatementContext(final String 
sql) {
+        DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "openGauss");
+        ShardingSphereSQLParserEngine parserEngine = new 
ShardingSphereSQLParserEngine(databaseType, new CacheOption(128, 64), new 
CacheOption(128, 64));
+        SQLStatement sqlStatement = parserEngine.parse(sql, false);
+        return new SelectStatementContext((SelectStatement) sqlStatement, 
mock(ShardingSphereMetaData.class), null, Collections.emptyList());
+    }
+    
     private SelectStatementContext mockSelectStatementContext(final String 
schemaName, final String tableName, final String columnName) {
         TableSegmentBoundInfo tableSegmentBoundInfo = 
mock(TableSegmentBoundInfo.class, RETURNS_DEEP_STUBS);
         
when(tableSegmentBoundInfo.getOriginalSchema().getValue()).thenReturn(schemaName);
diff --git a/test/it/parser/src/main/resources/case/dml/select.xml 
b/test/it/parser/src/main/resources/case/dml/select.xml
index c785980d3a7..2aaf5fc7ff1 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -13713,4 +13713,67 @@
             </expr>
         </where>
     </select>
+
+    <select sql-case-id="select_pg_database_info">
+        <projections start-index="7" stop-index="250">
+            <column-projection name="datname" alias="Name" start-index="7" 
stop-index="25">
+                <owner name="d" start-index="7" stop-index="7"/>
+            </column-projection>
+            <expression-projection alias="Owner" 
text="pg_catalog.pg_get_userbyid(d.datdba)" start-index="28" stop-index="74">
+                <expr>
+                    <function function-name="pg_get_userbyid" 
text="pg_catalog.pg_get_userbyid(d.datdba)" start-index="28" stop-index="63">
+                        <parameter>
+                            <column name="datdba" start-index="55" 
stop-index="62">
+                                <owner name="d" start-index="55" 
stop-index="55"/>
+                            </column>
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+            <expression-projection alias="Encoding" 
text="pg_catalog.pg_encoding_to_char(d.encoding)" start-index="77" 
stop-index="132">
+                <expr>
+                    <function function-name="pg_encoding_to_char" 
text="pg_catalog.pg_encoding_to_char(d.encoding)" start-index="77" 
stop-index="118">
+                        <parameter>
+                            <column name="encoding" start-index="108" 
stop-index="117">
+                                <owner name="d" start-index="108" 
stop-index="108"/>
+                            </column>
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+            <column-projection name="datcollate" alias="Collate" 
start-index="135" stop-index="159">
+                <owner name="d" start-index="135" stop-index="135"/>
+            </column-projection>
+            <column-projection name="datctype" alias="Ctype" start-index="162" 
stop-index="182">
+                <owner name="d" start-index="162" stop-index="162"/>
+            </column-projection>
+            <expression-projection alias="Access privileges" 
text="pg_catalog.array_to_string(d.datacl, E'\n')" start-index="185" 
stop-index="250">
+                <expr>
+                    <function function-name="array_to_string" 
text="pg_catalog.array_to_string(d.datacl, E'\n')" start-index="185" 
stop-index="227">
+                        <parameter>
+                            <column name="datacl" start-index="212" 
stop-index="219">
+                                <owner name="d" start-index="212" 
stop-index="212"/>
+                            </column>
+                        </parameter>
+                        <parameter>
+                            <type-cast-expression>
+                                <expression>
+                                    <literal-expression value="\n" 
start-index="223" stop-index="226"/>
+                                </expression>
+                                <data-type>E</data-type>
+                            </type-cast-expression>
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+        <from start-index="252" stop-index="280">
+            <simple-table name="pg_database" alias="d" start-index="257" 
stop-index="280">
+                <owner name="pg_catalog" start-index="257" stop-index="266"/>
+            </simple-table>
+        </from>
+        <order-by>
+            <index-item index="1" start-index="291" stop-index="291"/>
+        </order-by>
+    </select>
 </sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/select.xml 
b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
index 5fb3196d5b5..7279a7c32b6 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
@@ -495,4 +495,5 @@
     <sql-case id="select_format_function_oracle" value="SELECT FORMAT('abc', 
'999') FROM dual" db-types="Oracle" />
     <sql-case id="select_first_value_oracle" value="SELECT FIRST_VALUE(salary) 
OVER (ORDER BY salary) FROM employees" db-types="Oracle" />
     <sql-case id="select_datetime_lbe_literal_oracle" value="SELECT {ts 
'2020-02-02 10:00:00'} FROM dual" db-types="Oracle" />
+    <sql-case id="select_pg_database_info" value="SELECT d.datname as 
&quot;Name&quot;, pg_catalog.pg_get_userbyid(d.datdba) as &quot;Owner&quot;, 
pg_catalog.pg_encoding_to_char(d.encoding) as &quot;Encoding&quot;, 
d.datcollate as &quot;Collate&quot;, d.datctype as &quot;Ctype&quot;, 
pg_catalog.array_to_string(d.datacl, E'\n') AS &quot;Access privileges&quot; 
FROM pg_catalog.pg_database d ORDER BY 1;" db-types="openGauss" />
 </sql-cases>

Reply via email to