Skip to content

fuzzQuery table function enters infinite loop when max_query_length > 500 #104973

@clickgapai

Description

@clickgapai

Found via ClickGap automated review. Please close or comment if this is incorrect or needs adjustment.

Retrospective finding from a historical scan of PR #67655 (merged 2024-08-09). Confirmed on current codebase — close with a note if already fixed.

Describe what's wrong

Calling fuzzQuery('SELECT 1', 501, seed) or any max_query_length > 500 hangs indefinitely — the query never completes

Root cause: StorageFuzzQuery.cpp:48: if (config.max_query_length > 500) — this compares the wrong variable. The comment says 'AST is too long, will start from the original query' but the code checks if the configured max exceeds 500, not if the actual fuzzed text exceeds the configured max. When max_query_length > 500, this condition is ALWAYS true, causing the loop to reset fuzz_base and continue on every iteration without incrementing row_num, resulting in an infinite loop.

Why we believe this is a bug: StorageFuzzQuery.cpp:48 → FuzzQuerySource::createColumn — the condition config.max_query_length > 500 compares the configuration parameter against 500 instead of comparing fuzzed_text.size() against config.max_query_length

Affected locations:

  • src/Storages/StorageFuzzQuery.cpp:48 — Length check in createColumn loop

Impact: Users setting max_query_length > 500 (to allow longer fuzzed queries) will experience hung queries that never return, requiring manual cancellation. Default value of 500 works correctly only by coincidence (500 > 500 is false).

Does it reproduce on most recent release?

Yes — confirmed on current master (commit b6844b26db6).

How to reproduce

-- Test shows infinite loop when max_query_length > 500
-- Run with timeout to demonstrate:
-- timeout 5 clickhouse-client -q "SELECT * FROM fuzzQuery('SELECT 1', 501, 8956) LIMIT 1" # HANGS
-- timeout 5 clickhouse-client -q "SELECT * FROM fuzzQuery('SELECT 1', 500, 8956) LIMIT 1" # WORKS

-- Working case (max_query_length <= 500):
SELECT length(query) > 0 FROM fuzzQuery('SELECT 1', 500, 8956) LIMIT 1;
-- Returns: 1 (success)

-- Bug case (max_query_length > 500):
-- SELECT * FROM fuzzQuery('SELECT 1', 501, 8956) LIMIT 1;
-- This query hangs indefinitely due to the bug

Try it on ClickHouse Fiddle

Expected behavior

Both queries should complete successfully, with max_query_length controlling the maximum length of generated fuzzed queries

Error message and/or stacktrace

Query with max_query_length=500 returns: 'SELECT 1 PREWHERE NULL'
Query with max_query_length=501 times out after 5 seconds (infinite loop)

Additional context

Suggested fix: Change if (config.max_query_length > 500) to if (fuzzed_text.size() > config.max_query_length) — compare the actual length of the fuzzed text against the configured maximum

Analysis details: Confidence HIGH | Severity P1 | Testability: STATELESS_SQL

Found during automated review of PR #67655.


ClickGapAI · Confidence: HIGH · Severity: P1 · Finding: h_pr67655_001

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions