Skip to content

[Bug] stmt_type is recorded as SELECT for SHOW FULL TABLES ... WHERE #69893

Open

Description

@RoanHeNaN

Search before asking

  • I had searched in the issues and found no similar issues.

Version

4.x

What's Wrong?

Problem

The audit log records stmt_type as SELECT after executing SHOW FULL TABLES with a WHERE clause. The logged statement type should match the SQL statement issued by the user: SHOW.

What You Expected?

Corrent stmt_type.

How to Reproduce?

Steps to reproduce

In a Doris environment with audit logging enabled, run:

CREATE DATABASE IF NOT EXISTS show_tables_issue;
USE show_tables_issue;
CREATE TABLE IF NOT EXISTS t1 (id INT) DISTRIBUTED BY HASH(id) BUCKETS 1;

SHOW FULL TABLES WHERE Table_type = 'BASE TABLE';

Check the audit log entry for the SHOW FULL TABLES statement. The actual stmt_type is SELECT; the expected value is SHOW.

Anything Else?

No response

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Activity

  1. Doris-Breakwater commented on Oct 30, 2026

    @Doris-Breakwater
    Collaborator

    The report is strongly supported by the FE code as an audit statement-classification defect: executing the WHERE form replaces the executor's original SHOW statement with an internal SELECT plan, and audit classification subsequently reads that replacement. The internal query itself is an intentional implementation of filtering; the problem is losing the original statement identity for auditing.

    Verified source evidence

    I traced the public 4.0.8 tag (commit bc8ea1bac6d62d92cdebd2e3ac33cc668961ec36). This is a reference version, not an assumption about the reporter's installed build.

    1. LogicalPlanBuilder.visitShowTables() initially constructs a ShowTableCommand for both filtered and unfiltered forms. Its base class, ShowCommand.stmtType(), returns SHOW.
    2. With a WHERE clause, ShowTableCommand.executeWhere() builds a query against information_schema.tables, including the table-type alias and database filter. Plain SHOW FULL TABLES and the LIKE form take a different path.
    3. Utils.buildLogicalPlan() / executePlan() generate a SELECT, wrap its plan in a LogicalPlanAdapter, and call executor.setParsedStmt(adapter) on the same executor. They do not restore the original statement afterward. The SELECT result sink reports StmtType.SELECT.
    4. After execution, ConnectProcessor passes executor.getParsedStmt() to auditing. AuditLogHelper.getStmtType() uses the adapter's logical-plan type, explaining SELECT even when the logged SQL text is the original SHOW.

    The same command/helper/classifier pattern is also present in the inspected 4.1.4 source (ad35a140c7fd0b842f18c23300bac581f7d04326). This is source inspection, not a live reproduction or confirmation that every 4.x build is affected.

    Information still needed

    • Exact FE version and build commit, preferably the version/build information from the FE startup log; “4.x” is too broad for selecting a fix or backport.
    • Redacted raw audit records for the supplied statement, plus SHOW FULL TABLES, SHOW FULL TABLES LIKE 't%', and an ordinary SELECT 1 from the same session. Include SQL text, statement type, query ID, timestamp, status, and internal-query flag if available. Specify whether these are from fe.audit.log, the audit table, or another audit consumer, and whether multiple records appear for one execution.
    • Whether the statement succeeds and returns the expected tables. No profile is needed for this classification issue; FE error logs are useful if execution also fails.

    Recommended next steps for maintainers

    • Reproduce on the exact build and add coverage that asserts the final audit event, not just the parser's initial statement type. Cover filtered/unfiltered/LIKE SHOW, ordinary SELECT, and failure paths.
    • Preserve the original user statement's classification across internal execution. Review both the executor and statement-context mutation when choosing between scoped restoration and separately retained audit metadata.
    • Account for executeInternalQuery(): it also changes query state and emits an audit event in finally. Restoring parsedStmt only after it returns does not address that earlier event. Verify event count, statement identity, and internal-query attribution together.
    • Review the other Utils.executePlan() callers (ShowColumnsCommand, ShowDatabasesCommand, and ShowTableStatusCommand) for the same pattern; their affected runtime scope remains to be tested.

    No Doris code was modified, and no runtime test was executed during this investigation.

    Breakwater-GitHub-Analysis-Slot: slot_455fc757a09f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions