Skip to content

[Feat] Add table less query for table model#17437

Open
FearfulTomcat27 wants to merge 2 commits intoapache:masterfrom
FearfulTomcat27:feat/table-less-query
Open

[Feat] Add table less query for table model#17437
FearfulTomcat27 wants to merge 2 commits intoapache:masterfrom
FearfulTomcat27:feat/table-less-query

Conversation

@FearfulTomcat27
Copy link
Copy Markdown
Contributor

This pull request adds support for SQL queries without a FROM clause (table-less queries) in the IoTDB query engine, along with corresponding tests and necessary planning and execution logic updates. The changes ensure that expressions such as SELECT 1+1, SELECT sin(1), or SELECT COUNT(*) can be parsed, planned, and executed correctly, producing the expected single-row results even when no table is specified.

Key changes include:

Support for Table-less (No-FROM) Queries:

  • Updated the query planner (QueryPlanner.java) to generate a ValuesNode with a single row when a SELECT statement does not have a FROM clause, enabling implicit single-row semantics for such queries.
  • Modified the execution plan generator (TableOperatorGenerator.java) to correctly produce a ValuesOperator with the appropriate number of rows and columns for no-FROM queries, using a RunLengthEncodedColumn to simulate the required rows.

Testing:

  • Added a new test case (testTableLessQuery) in IoTDBComplexQueryIT.java to verify correct behavior for queries without a FROM clause, including arithmetic, function, formatting, and aggregation expressions.

Planner and Optimizer Enhancements:

  • Implemented getOutputSymbols in ValuesNode to support symbol mapping and output column handling in the planner.
  • Updated the unaliasing optimizer (UnaliasSymbolReferences.java) to handle ValuesNode, ensuring correct symbol mapping and row transformation in the optimization pipeline.

Dependency and Import Updates:

  • Added necessary imports for new classes and types used in the planner and operator generator, such as ValuesNode, InternalTypeManager, and RunLengthEncodedColumn. [1] [2] [3] [4]

- Handle cases without a FROM clause in QueryPlanner, returning a plan that includes ValuesNodes
- TableOperatorGenerator supports null values and queries without a FROM clause, generating the corresponding ValuesOperator
- Added support for accessing and overriding ValuesNode in UnaliasSymbolReferences
- Added a new getOutputSymbols method to the ValuesNode class to expose the list of output symbols
- Added relevant package imports to support the new types and node processing logic
Copilot AI review requested due to automatic review settings April 7, 2026 12:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for table-model SQL queries without a FROM clause by introducing an implicit single-row source in the relational planner and enabling execution/optimization to handle it, plus an integration test.

Changes:

  • Update relational planning to produce a ValuesNode (1 row) when FROM is absent.
  • Extend optimizer (UnaliasSymbolReferences) and plan node (ValuesNode) to expose/migrate output symbols for ValuesNode.
  • Update table execution planning to generate a ValuesOperator that can emit the implicit single row for no-FROM queries; add IT coverage.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/QueryPlanner.java Plans no-FROM queries as a single-row ValuesNode source.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/UnaliasSymbolReferences.java Adds unalias rewriting support for ValuesNode.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/ValuesNode.java Implements getOutputSymbols() so planner/optimizers can treat ValuesNode consistently.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java Generates a non-empty ValuesOperator for the implicit single-row source case.
integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBComplexQueryIT.java Adds an integration test for table-less queries.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +95 to +98
retArray =
new String[] {Math.sin(1) + "," + Math.cos(1) + "," + Math.tan(1) + ","};
tableResultSetEqualTest(
"SELECT sin(1), cos(1), tan(1)", expectedHeader, retArray, DATABASE_NAME);
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assertion is likely flaky because it compares ResultSet.getString() output against Double.toString(Math.sin(1))/cos/tan. JDBC/IoTDB formatting (precision, trailing zeros, scientific notation, locale) can differ from Java's Double.toString, causing intermittent failures. Consider using tableResultSetEqualByDataTypeTest (double comparison with delta) or explicitly formatting/rounding in SQL (e.g., ROUND(sin(1), n)) so the returned strings are deterministic.

Suggested change
retArray =
new String[] {Math.sin(1) + "," + Math.cos(1) + "," + Math.tan(1) + ","};
tableResultSetEqualTest(
"SELECT sin(1), cos(1), tan(1)", expectedHeader, retArray, DATABASE_NAME);
retArray = new String[] {"0.841471,0.540302,1.557408,"};
tableResultSetEqualTest(
"SELECT round(sin(1), 6), round(cos(1), 6), round(tan(1), 6)",
expectedHeader,
retArray,
DATABASE_NAME);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants