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
"Name", pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
d.datcollate as "Collate", d.datctype as "Ctype",
pg_catalog.array_to_string(d.datacl, E'\n') AS "Access privileges"
FROM pg_catalog.pg_database d ORDER BY 1;" db-types="openGauss" />
</sql-cases>