apache/seatunnel · error · ClickhouseConnectorException

QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE

QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE

Error message

Query table mode not support non-MergeTree local table. Please specify sql parameter in configuration

What it means

In query-table mode with no explicit sql, ClickhouseSourceSplitEnumerator.getClusterShardList() requires the local (non-distributed) table engine to be a MergeTree family engine so it can derive shard/parallel read ranges. Non-MergeTree local tables (e.g. Log, Memory, external engines) cannot be split this way, so the connector throws QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE.

Solutions

  1. Set the `sql` option in the ClickHouse source config to supply your own query, bypassing MergeTree-based split enumeration.
  2. Use a MergeTree-family local table (or change the underlying table engine) if table-mode reading is required.
  3. Verify the table/database names resolve to the intended MergeTree table.
  4. If the table is Distributed, confirm its local table (system.tables.engine for the inner table) is MergeTree family.

Example fix

// before: config without sql
source {
  Clickhouse {
    url = "jdbc:clickhouse://localhost:8123"
    database = "default"
    table = "my_log_table"
  }
}
// after: provide sql explicitly
source {
  Clickhouse {
    url = "jdbc:clickhouse://localhost:8123"
    sql = "SELECT * FROM default.my_log_table"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Before submitting, check local table engine
SELECT engine FROM system.tables
WHERE database = 'default' AND name = 'my_table';
// must contain 'MergeTree' or config must define `sql`

Try / catch

try {
  runJob(config);
} catch (ClickhouseConnectorException e) {
  if (e.getSeaTunnelErrorCode() == ClickhouseConnectorErrorCode.QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE) {
    // resubmit with `sql` option set
  } else throw e;
}

Prevention

When it happens

Trigger: clickhouse source config has no `sql` option, table not distributed (or distributed whose local table engine string doesn't contain "MergeTree"), and localTableEngine.contains("MergeTree") is false at ClickhouseSourceSplitEnumerator.java:261.

Common situations: Pointing the connector at a Log/Memory/Kafka-engine table; Distributed table whose local table is non-MergeTree; typo'd table name resolving to an unexpected table; older ClickHouse engine naming (e.g. 'ReplicatedMergeTree' works, but 'StripeLog' doesn't).

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/e79c8e4e745736fe. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-clickhouse/src/main/java/org/apache/seatunnel/connectors/seatunnel/clickhouse/source/split/ClickhouseSourceSplitEnumerator.java:261

                clusterShardList =
                        proxy.getClusterShardList(
                                proxy.getClickhouseConnection(),
                                distributedEngine.getClusterName(),
                                distributedEngine.getDatabase(),
                                nodes.get(0).getPort(),
                                clickhouseSourceConfig.getUsername(),
                                clickhouseSourceConfig.getPassword(),
                                nodes.get(0).getOptions());
            } else {
                // if input is local table, generate shard list based on the input nodes
                clusterShardList = buildClusterShardFromNodes(nodes);
                localTableEngine = clickhouseTable.getEngine();
            }

            if (StringUtils.isEmpty(clickhouseSourceTable.getOriginQuery())
                    && !localTableEngine.contains("MergeTree")) {
                throw new ClickhouseConnectorException(
                        ClickhouseConnectorErrorCode.QUERY_TABLE_NOT_SUPPORT_NON_MERGE_TREE_TABLE,
                        "Query table mode not support non-MergeTree local table. Please specify sql parameter in configuration");
            }

            return clusterShardList;
        }
    }

    private List<Shard> buildClusterShardFromNodes(List<ClickHouseNode> nodes) {
        List<Shard> shards = new ArrayList<>();
        IntStream.range(0, nodes.size())
                .forEach(
                        i -> {
                            ClickHouseNode node = nodes.get(i);
                            Shard shard = new Shard(i, 1, node);
                            shards.add(shard);
                        });

View on GitHub (pinned to cf67b549a7)