Skip to content

fix: support column list before ENGINE in CREATE MATERIALIZED VIEW#1

Closed
sharadgaur wants to merge 1 commit into
masterfrom
sharad/fix-rmv-column-list-engine
Closed

fix: support column list before ENGINE in CREATE MATERIALIZED VIEW#1
sharadgaur wants to merge 1 commit into
masterfrom
sharad/fix-rmv-column-list-engine

Conversation

@sharadgaur

Copy link
Copy Markdown
Owner

Problem

The parser fails on CREATE MATERIALIZED VIEW statements where a column list appears between the REFRESH clause and ENGINE. This is valid ClickHouse syntax produced by SHOW CREATE TABLE for refreshable materialized views (RMVs) that use an engine like Memory instead of a TO destination table.

Before (fails)

CREATE MATERIALIZED VIEW db1.config_cache_v0
REFRESH EVERY 1 SECOND
(
    `id` String,
    `name` String,
    `value` Float64
)
ENGINE = Memory
SETTINGS min_rows_to_keep = 250000, max_rows_to_keep = 500000
AS SELECT id, name, value FROM db1.config_v0

Error:

line 2:0 unexpected token: "(", expected TO or ENGINE

The parser expected either TO <table> or ENGINE = <engine> immediately after the REFRESH/SETTINGS/APPEND clauses, but ClickHouse places the column list (...) before ENGINE in its SHOW CREATE TABLE output.

After (works)

The same SQL parses correctly. The column list is stored in the new TableSchema field on CreateMaterializedView and preserved through format roundtrips.

ClickHouse syntax reference

From the ClickHouse docs:

CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]name
  [REFRESH ...] [APPEND]
  [TO [db.]name] [(columns)] [ENGINE = engine]
  [AS SELECT ...]

When no TO clause is used (ENGINE-based MVs), ClickHouse's SHOW CREATE TABLE outputs the column definitions between REFRESH and ENGINE.

Changes

  • parser/parser_view.go — Added a case p.matchTokenKind(TokenKindLParen) branch in the TO/ENGINE switch to parse the column list, then expect ENGINE after it
  • parser/ast.go — Added TableSchema *TableSchemaClause field to CreateMaterializedView for column lists on ENGINE-based MVs (distinct from Destination.TableSchema which is for TO-based MVs)
  • parser/format.go — Emit TableSchema before ENGINE in FormatSQL

Test

Added create_materialized_view_rmv_engine_with_columns.sql covering the full syntax: REFRESH + column list + ENGINE + SETTINGS + DEFINER + COMMENT + subquery with window function. All existing tests pass.

ClickHouse SHOW CREATE TABLE for refreshable materialized views with
ENGINE (e.g. Memory) outputs the column list between REFRESH and ENGINE:

  CREATE MATERIALIZED VIEW db1.mv_name
  REFRESH EVERY 1 SECOND
  (
      col1 String,
      col2 Int8
  )
  ENGINE = Memory
  AS SELECT ...

The parser previously expected TO or ENGINE immediately after REFRESH
clauses. This adds support for the (columns) before ENGINE pattern by
parsing a TableSchemaClause when a left paren is encountered.

Added TableSchema field to CreateMaterializedView AST node and updated
FormatSQL to emit it before ENGINE.
@sharadgaur sharadgaur closed this May 14, 2026
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.

1 participant