Repository navigation
fix(asap-tools): give sketchdb its own SQL in ClickHouse runs - #899
milindsrivastava1997 merged 2 commits into
Conversation
milindsrivastava1997
left a comment
There was a problem hiding this comment.
Code review findings (Claude Code).
| raise ValueError( | ||
| f"Query group {idx} ({name!r}) has a sql_file for mode " | ||
| f"{mode!r} after a group without one; a mode may skip " | ||
| "only trailing groups, so its query indices match baseline's" |
There was a problem hiding this comment.
_mode_sql_files checks that sketchdb's groups are a prefix of baseline's, but not that each sketchdb sql_file has as many statements as baseline's file for the same group. Results are paired by global query index, so a count mismatch shifts every later index.
Example: group 0 has baseline {q0,q1,q2} and sketchdb {q0,q2}, and group 1 is the same for both. Sketchdb's query 1 is then scored against baseline's q1, and all of its group-1 queries against the wrong baseline queries. calculate_fidelity truncates to len(estimate_results) and prints scores with no error. Suggest checking the statement counts per group here.
There was a problem hiding this comment.
Fixed in bbcdac9: _mode_sql_files now fails when a mode's SQL file holds a different number of statements than baseline's for the same group (test: test_statement_count_mismatch_is_refused).
| f"Scoring the first {len(estimate_results)} of {len(queries)} " | ||
| "queries: the estimate mode ran no others" | ||
| ) | ||
| queries = queries[: len(estimate_results)] |
There was a problem hiding this comment.
This truncation assumes the estimate mode ran a prefix of baseline's queries, but nothing ties the scored queries to the groups the mode actually ran; pairing goes only by count. A misconfigured sql_file or a statement-count mismatch is scored against the first N baseline labels, and the only sign is the 'Scoring the first N of M' message.
Both client configs keep 'id': idx, so pairing by group id plus per-group query index would remove the need for both the prefix-only rule and this truncation.
There was a problem hiding this comment.
Declined for now. With the prefix rule and the per-group statement-count check (bbcdac9), the estimate's queries are exactly baseline's first N, so truncating is safe. A gap among them still fails on the lookup. Pairing by (group id, index) would change the client output and every analysis script that indexes by position.
| _SQL_TEMPLATED_TIME_LITERAL = re.compile(r"'\{\{[^']*\}\}[^']*'") | ||
|
|
||
|
|
||
| def _comparable_sql(sql): |
There was a problem hiding this comment.
_comparable_sql rewrites every quoted templated literal to NOW(), so queries that differ only in their time literals compare equal. Examples: SQL floored to different intervals ('{{ end_datetime[:17] }}...' vs '{{ end_datetime[:14] }}...:00'), or BETWEEN '{{start}}' AND '{{end}}' against a plan that uses NOW() for both bounds.
copy_prebuilt_controller_output can then accept a saved plan for different windows, and the mismatch shows up only at query time.
There was a problem hiding this comment.
Known limitation, kept as is. The saved plan holds NOW(), so the flooring interval can't be recovered from its text. The ponytail: comment on _comparable_sql notes this. The check catches a wrong plan; the engine matches queries to the plan structurally at query time.
| # experiment_params.dataset.name=clickbench \ | ||
| # experiment_params.dataset.local_data_file=/path/to/hits.json \ | ||
| # 'experiment_params.query_groups[0].sql_file=/path/to/queries.sql' | ||
| # 'experiment_params.query_groups[0].sql_file={baseline:/path/to/queries.sql}' |
There was a problem hiding this comment.
The template body below (~line 177) still shows sql_file: ??? # path to SQL file as a plain string. _mode_sql_files calls sql_file.get(mode) on it and fails with AttributeError: 'str' object has no attribute 'get' instead of a clear error. The checked-in clickhouse.yaml and quantile_demo.yaml also use a string sql_file. Suggest updating the template to the dict form, and either rejecting a string with a clear message or accepting it as {baseline: path}.
There was a problem hiding this comment.
Fixed in bbcdac9: a plain-string sql_file now fails with a clear error (test: test_plain_string_sql_file_is_refused_clearly), and the docs template uses the dict form. No checked-in YAML sets sql_file, and there is no clickhouse.yaml or quantile_demo.yaml in the repo.
| experiment_params.dataset.name=clickbench \ | ||
| experiment_params.dataset.local_data_file=/path/to/hits.json \ | ||
| 'experiment_params.query_groups[0].sql_file=/path/to/queries.sql' | ||
| 'experiment_params.query_groups[0].sql_file={baseline:/path/to/queries.sql}' |
There was a problem hiding this comment.
This passes only {baseline:...}. Under the new rule, any sketchdb mode in experiment_params.experiment (as in the repo's clickhouse.yaml) needs its own entry, so this command now fails with 'No query group has a sql_file entry for mode sketchdb'. Before, sketchdb fell back to baseline's SQL.
There was a problem hiding this comment.
That example runs baseline only, so it still works. bbcdac9 adds a note below it: with a sketchdb mode, give sketchdb its own entry, e.g. sql_file={baseline:...,sketchdb:...}.
sketchdb ran baseline's sql_file, so ASAPQuery got ClickHouse-only SQL on sketch-bench tables. It now runs its own sql_file entry and skips trailing groups without one, keeping its query indices a prefix of baseline's. The SQL prebuilt-plan check compares queries without comment lines and with templated time literals as NOW(), so a saved plan matches the client's queries, and calculate_fidelity scores only the queries the estimate mode ran. Co-Authored-By: Claude Opus 5.5 <[email protected]>
A mode whose SQL file holds a different number of statements than baseline's for the same group would pair later queries with the wrong baseline queries; a plain-string sql_file failed with an AttributeError. Both now fail with a clear error, and the docs' template uses the dict form. Co-Authored-By: Claude Opus 5.5 <[email protected]>
bbcdac9 to
09375f7
Compare
Part of #874 (1 of 3; #900 and #901 stack on this).
Problem: in a ClickHouse run, sketchdb always ran baseline's
sql_file. For sketch-bench tables that is ClickHouse-only SQL (quantileExactInclusive,uniqExact, ...), while ASAPQuery needs the table's own SQL (asapquery.sql), which exists only for structured entries. Three things block giving sketchdb its own SQL:asap-planner --planner saved) stores each query onNOW(), while the client config holds a templated time literal and a-- descriptionline, socopy_prebuilt_controller_output's text check rejects it;calculate_fidelityindexes the estimate's results for every baseline query.Fix:
_mode_sql_filesreplaces_resolve_sql_file. sketchdb runs its ownsql_fileentry and skips groups without one, but only trailing groups (otherwise it raises), so its query indices are a prefix of baseline's. Every other mode still needs an entry in every group.sql_filefails with a clear error instead of anAttributeError.;, with quoted templated time literals read asNOW().calculate_fidelityscores only the queries the estimate mode ran; a gap among them still fails.Behaviour change: a hand-written baseline + sketchdb run must list
sketchdb:insql_file(e.g. the same file as baseline for ClickBench). No checked-in config usessql_file; the docs' examples are updated (they still showed the old plain-string form).Tests: new
tests/test_clickhouse_client_configs.py; additions totest_prebuilt_controller_output.py,test_sql_planner_input.py,test_calculate_fidelity.py,test_experiment_run_clickhouse.py.🤖 Generated with Claude Code