github-actions[bot] commented on code in PR #66329:
URL: https://github.com/apache/doris/pull/66329#discussion_r3703719367


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowColumnsCommand.java:
##########
@@ -138,9 +140,25 @@ public Expression visitUnboundSlot(UnboundSlot slot, Void 
context) {
     @Override
     public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) 
throws Exception {
         validate(ctx);
+        String ctl = tableNameInfo.getCtl();
+        DatabaseIf db = 
Env.getCurrentEnv().getCatalogMgr().getCatalogOrAnalysisException(ctl)
+                .getDbOrAnalysisException(tableNameInfo.getDb());
+        TableIf table = db.getTableOrAnalysisException(tableNameInfo.getTbl());
         if (whereClause != null) {
+            Map<String, String> visibleColumnTypes = new HashMap<>();
+            table.readLock();
+            try {
+                for (Column column : table.getBaseSchema()) {
+                    visibleColumnTypes.put(column.getName(),
+                            
column.getOriginType().hideVersionForVersionColumn(false));
+                }
+            } finally {
+                table.readUnlock();
+            }
+

Review Comment:
   [P1] Match the external catalog's published schema name
   
   `TABLE_SCHEMA` is produced from the resolved external database, but this 
predicate uses the caller spelling. With 
`show_full_db_name_in_info_schema_db=true`, the scanner publishes `catalog.db` 
while this compares plain `db`; with `lower_case_database_names=2`, lookup can 
resolve `sales` to canonical `Sales` while the predicate still compares 
`sales`. The pushed database pattern can eliminate the database before rows are 
produced, and the residual equality fails too. Please filter on a 
presentation-independent database identity (or exactly the published name) and 
test both external-catalog settings.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowColumnsCommand.java:
##########
@@ -47,16 +47,18 @@
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 
 /**
  * Represents the SHOW COLUMNS command.
  */
 public class ShowColumnsCommand extends ShowCommand {
     private static final ShowResultSetMetaData META_DATA = 
ShowResultSetMetaData.builder()
             .addColumn(new Column("Field", ScalarType.createVarchar(20)))
-            .addColumn(new Column("Type", ScalarType.createVarchar(20)))

Review Comment:
   [P1] Keep the SHOW type column character-typed
   
   `ScalarType.createStringType()` is not just an unbounded VARCHAR in the 
MySQL protocol: `PrimitiveType.STRING.toMysqlType()` advertises the BLOB-family 
field code 252, while the previous VARCHAR advertises code 254 (`STRING`). This 
changes the observable result-set metadata even though the row text is 
unchanged. Row serialization is already length-encoded, so please widen this 
with a character type such as `createVarchar(MAX_VARCHAR_LENGTH)` (and do the 
same in the verbose metadata) instead of changing the wire type.



##########
regression-test/suites/datatype_p0/scalar_types/test_information_types.groovy:
##########
@@ -20,10 +20,10 @@ suite("test_information_types") {
     def tb_name = "test_information_schema_types"
 
     def datatype_arr = ["boolean", "tinyint(4)", "smallint(6)", "int(11)", 
"bigint(20)", "largeint(40)", "float",
-                       "double", "decimal(20, 3)", "decimalv3(20, 3)", "date", 
"datetime", "datev2", "datetimev2(0)",
+                       "double", "decimalv3(20, 3)", "date", "datetime", 
"datev2", "datetimev2(3)",

Review Comment:
   [P2] Recreate the table before checking the new scale
   
   This suite uses `CREATE TABLE IF NOT EXISTS` and leaves the table behind, 
but this patch changes `c_datetimev2` from scale 0 to 3 and now expects 
`datetime(3)`. Re-running against a table created by the previous suite version 
skips the DDL and still returns scale 0, so the new oracle is not repeatable. 
Please `DROP TABLE IF EXISTS test_information_schema_types` before setup, as 
required by the regression-test guidelines.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowColumnsCommand.java:
##########
@@ -166,17 +184,12 @@ public ShowResultSet doRun(ConnectContext ctx, 
StmtExecutor executor) throws Exc
             LogicalPlan plan = Utils.buildLogicalPlan(selectList, info, 
whereCondition);
             List<List<String>> rows = Utils.executePlan(ctx, executor, plan);

Review Comment:
   [P1] Filter on the same Type value that is returned
   
   The `WHERE Type` predicate is evaluated against BE `COLUMN_TYPE` before this 
replacement. For a STRING column the scanner supplies `string` while this map 
now supplies `text`: `WHERE Type = 'text'` returns no row, whereas `WHERE Type 
= 'string'` returns a row displayed as `text`, which does not satisfy its 
predicate. Named STRUCTs have the same newly introduced mismatch because the 
scanner omits field names while the replacement preserves them. Please evaluate 
the predicate and construct the result from one canonical type representation, 
and cover non-Decimal cases.



##########
be/src/information_schema/schema_columns_scanner.cpp:
##########
@@ -210,20 +210,18 @@ std::string 
SchemaColumnsScanner::_type_to_string(TColumnDesc& desc) {
         return "datetime";
     case TPrimitiveType::DECIMALV2: {
         return fmt::format(
-                "decimal({}, {})",
+                "decimal({},{})",
                 desc.__isset.columnPrecision ? 
std::to_string(desc.columnPrecision) : "27",
                 desc.__isset.columnScale ? std::to_string(desc.columnScale) : 
"9");
     }
     case TPrimitiveType::DECIMAL32:
     case TPrimitiveType::DECIMAL64:
     case TPrimitiveType::DECIMAL128I:
     case TPrimitiveType::DECIMAL256: {
-        fmt::memory_buffer debug_string_buffer;
-        fmt::format_to(
-                debug_string_buffer, "decimalv3({}, {})",
+        return fmt::format(

Review Comment:
   [P1] Preserve Decimal metadata across mixed BE versions
   
   Schema scans run on one eligible backend, but `TColumnDesc` has no 
formatter-version fence: an old BE emits `decimalv3(p, s)` and this BE emits 
`decimal(p,s)`. During a BE rolling upgrade, direct 
`information_schema.columns` results and predicates therefore depend on which 
BE executes the scan; if a new FE is active before every BE is upgraded, the 
added `SHOW ... WHERE Type = 'decimal(10,2)'` path inherits the same split. 
Please add a mixed-version compatibility strategy so metadata text is not 
selected by the executing BE binary.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowColumnsCommand.java:
##########
@@ -138,9 +140,25 @@ public Expression visitUnboundSlot(UnboundSlot slot, Void 
context) {
     @Override
     public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) 
throws Exception {
         validate(ctx);
+        String ctl = tableNameInfo.getCtl();
+        DatabaseIf db = 
Env.getCurrentEnv().getCatalogMgr().getCatalogOrAnalysisException(ctl)
+                .getDbOrAnalysisException(tableNameInfo.getDb());
+        TableIf table = db.getTableOrAnalysisException(tableNameInfo.getTbl());
         if (whereClause != null) {
+            Map<String, String> visibleColumnTypes = new HashMap<>();
+            table.readLock();
+            try {
+                for (Column column : table.getBaseSchema()) {
+                    visibleColumnTypes.put(column.getName(),
+                            
column.getOriginType().hideVersionForVersionColumn(false));
+                }
+            } finally {
+                table.readUnlock();
+            }
+
             Expression rewritten = whereClause.accept(new 
ReplaceColumnNameVisitor(), null);

Review Comment:
   [P1] Encode the database as a SQL literal
   
   External catalog database names are not constrained by internal `CREATE 
DATABASE` validation; JDBC imports `TABLE_SCHEM` verbatim. A valid 
backtick-addressed external schema such as `sales'2026` makes this generated 
text `TABLE_SCHEMA = 'sales'2026'`, so `buildLogicalPlan()` reparses a broken 
or structurally changed predicate. Please build this condition structurally or 
apply the repository's SQL string-literal escaping instead of concatenating the 
analyzed name.



##########
regression-test/suites/query_p0/show/test_show_columns_command.groovy:
##########
@@ -50,10 +53,31 @@ suite("test_show_columns_command", "query_p0") {
         checkNereidsExecute("""SHOW COLUMNS FROM ${dbName}.${tableName} WHERE 
Field = 'id'""")
         qt_cmd("""SHOW COLUMNS FROM ${dbName}.${tableName} WHERE Field = 
'id'""")
 
+        // WHERE must preserve the user-visible type, including DecimalV3 and 
DATETIMEV2 precision.
+        checkNereidsExecute("""SHOW COLUMNS FROM ${dbName}.${tableName} WHERE 
Field LIKE 'decimal%'""")
+        qt_cmd("""SHOW COLUMNS FROM ${dbName}.${tableName} WHERE Field LIKE 
'decimal%'""")
+        checkNereidsExecute("""SHOW COLUMNS FROM ${dbName}.${tableName} WHERE 
Field = 'event_time_v2'""")
+        qt_cmd("""SHOW COLUMNS FROM ${dbName}.${tableName} WHERE Field = 
'event_time_v2'""")
+        checkNereidsExecute("""SHOW COLUMNS FROM ${dbName}.${tableName} WHERE 
Type = 'decimal(10,2)'""")
+        qt_cmd("""SHOW COLUMNS FROM ${dbName}.${tableName} WHERE Type = 
'decimal(10,2)'""")
+
         // Test SHOW FULL COLUMNS with WHERE clause
         checkNereidsExecute("""SHOW FULL COLUMNS FROM ${dbName}.${tableName} 
WHERE Field LIKE '%name%'""")
 
+        // A same-name table in another database must not affect the WHERE 
path.
+        sql """CREATE DATABASE IF NOT EXISTS ${otherDbName}"""
+        sql """
+            CREATE TABLE IF NOT EXISTS ${otherDbName}.${tableName} (
+                other_db_only INT
+            )
+            DISTRIBUTED BY HASH(other_db_only) BUCKETS 1
+            PROPERTIES ("replication_num" = "1");
+        """
+        qt_cmd("""SHOW COLUMNS FROM ${dbName}.${tableName} WHERE Field LIKE 
'%'""")
+

Review Comment:
   [P2] Do not let cleanup replace the test failure
   
   If any SHOW check above fails before `otherDbName` is created, this first 
`finally` statement throws too: `DROP TABLE IF EXISTS db.table` resolves the 
database before applying the table-level `IF EXISTS`, so a missing database is 
still an error. That cleanup error obscures the original failure and prevents 
the remaining main-table cleanup from running. Please create/reset the second 
database before entering the failure-prone block or otherwise make cleanup 
preserve the original exception.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowColumnsCommand.java:
##########
@@ -138,9 +140,25 @@ public Expression visitUnboundSlot(UnboundSlot slot, Void 
context) {
     @Override
     public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) 
throws Exception {
         validate(ctx);
+        String ctl = tableNameInfo.getCtl();
+        DatabaseIf db = 
Env.getCurrentEnv().getCatalogMgr().getCatalogOrAnalysisException(ctl)
+                .getDbOrAnalysisException(tableNameInfo.getDb());

Review Comment:
   [P1] Keep the displayed type in the scan's schema snapshot
   
   This map is captured under the target table's read lock, but the lock is 
released before `executePlan()` starts a separate information-schema scan and 
takes a later schema snapshot. A concurrent ALTER (or drop/recreate with the 
same name) can therefore return later `Null`/key/default fields while the 
post-processing step substitutes the earlier type; an added or renamed column 
produces a null lookup. Please produce the predicate fields and displayed type 
from one version-fenced metadata source rather than joining snapshots by column 
name.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to