Goal
Implement the setup Dashboard role on top of the role-aware result selector and Dashboard role partition introduced by #160 .
A favorited Setup query runs hidden preparation statements before Filter queries and displayed Panels.
Persisted Spec:
{
"favorite" : true ,
"dashboard" : {
"role" : " setup"
}
}
A Setup query:
creates no Dashboard tile;
runs before Filter queries and Panels;
may create temporary tables and set session settings;
shares one ClickHouse HTTP session with all later queries in the same Dashboard wave;
executes sequentially because ClickHouse permits only one active query per session;
exposes status and errors without pretending to be a Panel;
preserves dormant Panel configuration.
This issue adds Setup to the selector foundation shipped by #160 .
Dependencies
Required:
Dashboard: multi-filter option bundles, shared preview, and role-aware result selector #160 — role-aware result selector, role partition, Filter execution, and Dashboard wave foundation;
Optional SQL blocks /*[ … ]*/ + explicit filter activation — an empty parameter cannot omit surrounding SQL #165 — optional SQL blocks and explicit activation;
Phase 7.0 — shared parameter pipeline: analyze()/prepare() two-phase multi-source API, type conflicts, typed serializer (arrays, big ints), field states #173 — shared parameter analysis/preparation with bindPolicy: "all";
Panels: visualization registry + Panel drawer tab + Library panel field #166 — Panel registry and workbench/Dashboard shared renderers;
Saved-query format v2: separate SQL from an extensible Spec document #211 — saved-query v2 model;
Workbench: add separate SQL and Spec JSON editor modes #212 — SQL and Spec editors with atomic Save;
Spec: canonical JSON Schema service for validation and shared tooling #220 / PR feat: add canonical Spec schema service #222 — canonical Presentation Spec schema and validation service;
Spec editor: schema-driven autocomplete with SQL-editor-consistent popup UX #221 — schema-driven Spec completion.
Persisted model
Setup is a Dashboard execution role:
query . spec . dashboard . role === "setup"
It is not a Panel type.
Do not add setup to:
panel.cfg.type
PANEL_TYPE_IDS
PANEL_PICKER_OPTIONS
PANEL_TYPES
autoPanel()
resolvePanel()
isQuerylessPanel()
A Setup query may retain a complete dormant spec.panel object.
Switching to Setup changes only spec.dashboard.role.
Switching from Setup to a Panel choice changes the effective role to Panel and restores or updates the preserved Panel configuration through the existing switchPanelType() behavior.
No specVersion change is required.
Unknown dashboard fields remain preserved.
Canonical schema
The canonical dashboard.role enum already includes:
[" panel" , " filter" , " setup" ]
Update the setup completion information to document:
automatic Dashboard execution occurs before Filter and Panel queries;
the query creates no tile;
statements run sequentially in a shared session;
only the supported safe statement classes are accepted automatically;
parameters use the shared Dashboard filter state.
Do not add a Setup branch to panelCfg.
Drawer selector
Extend the role-choice list created by #160 :
Panel
KPI
Column
Horizontal bar
Line
Area
Pie
Logs
Text
Dashboard role
Filter
Setup
Normal Setup query header:
[ Table ] [ JSON ] [ Setup ▾ ]
The closed control uses:
Do not display Setup source in the drawer header.
Selecting Setup
Selecting Setup:
patches only spec.dashboard.role = "setup";
preserves all unknown dashboard siblings;
preserves the complete spec.panel object;
activates the transient setup drawer view;
marks the Spec draft dirty;
runs normal validation;
does not execute SQL;
does not modify spec.view.
Selecting a Panel choice from Setup
Selecting any Panel choice:
patches the effective role to panel;
preserves unknown dashboard siblings;
uses switchPanelType() for the selected visualization;
activates the panel drawer view;
preserves existing Panel continuity and chart-role stash behavior.
Table and JSON
Table and JSON:
inspect the last explicit workbench result;
do not change the Setup role;
do not execute SQL.
Transient view
Extend result-view state with:
setup is not persisted into spec.view.
Retain it across explicit reruns during the current tab lifetime. Restore the normal persisted view when the tab is recreated.
Workbench Setup view
The Setup view is an authoring and last-run status surface. It never runs the Dashboard setup wave.
Static execution plan
Before any Run, show the parsed Setup plan:
Setup
1 SET max_threads = 4
Allowed · session setting
2 CREATE TEMPORARY TABLE daily AS SELECT …
Allowed · temporary table
3 SELECT count() FROM daily
Allowed · output discarded on Dashboard
For each statement show:
statement number;
compact SQL preview;
classified kind;
allowed or blocked state;
declared parameters;
optional parameters;
blocking diagnostic.
The plan is produced by the same pure classifier used by Dashboard automatic execution.
No explicit Run result
Show:
Run the query to test this script in the workbench.
Dashboard execution uses a fresh serialized session.
Running
Show current explicit workbench status without simulating Dashboard execution.
Completed explicit Run
Reuse the workbench’s existing per-statement result/status data.
Show:
statement status;
elapsed time;
error;
first-row preview or result link where the existing script result provides it.
The ordinary workbench Run path remains unchanged:
it is an explicit development/debug action;
it is not forced through Dashboard readonly=2;
it does not create or replace the Dashboard session;
it does not trigger Filter queries or Panels.
Single row-returning statement
Table and JSON remain available for the explicit result.
Setup view shows its classified Dashboard behavior and last-run status.
Multi-statement script
The Setup view becomes the primary role-specific representation. Reuse the existing script-grid data rather than creating a second result model.
The drawer toolbar may show:
[ Setup ▾ ] Script · 3 statements
when Table/JSON are not meaningful for the script result.
The role selector remains available even in the script-result toolbar.
Library and workbench labels
Use compact UI labels:
Library row:
★ Build daily temporary data [Setup]
Workbench title badge:
Clicking either badge:
activates the query tab;
switches to Spec mode;
navigates to dashboard.role.
Do not display Setup source in the drawer header.
Dashboard partition
Partition the favorited Library snapshot before execution:
effective role setup → Setup scheduler, no grid slot;
effective role filter → Filter scheduler from Dashboard: multi-filter option bundles, shared preview, and role-aware result selector #160 , no grid slot;
effective role panel → displayed Panel;
unknown role → excluded with a diagnostic.
Setup and Filter queries:
create no grid slots;
are excluded from “N not shown” counts;
remain absent when not favorited.
Shared-session rule
When at least one favorited Setup query exists, the complete Dashboard wave uses one fresh named HTTP session.
Wave order:
Setup queries in Library order
→ Filter queries in Library order
→ Filter reconciliation
→ Panel queries in Library order
Only one request may be active in the session at a time.
Do not run Filter queries or Panels concurrently in Setup mode.
When no Setup query exists, retain #160 ’s normal behavior:
Filter queries may use the bounded concurrency limiter;
Panels may use the bounded concurrency limiter;
no named session is required.
This conditional preserves performance for normal dashboards.
Session identity and lifetime
Generate a cryptographically random session ID for each fresh setup wave.
Suggested shape:
asb-dashboard-<random UUID>
Send on every request in the wave:
session_id
session_timeout
Suggested timeout:
DASHBOARD_SESSION_TIMEOUT_SECONDS = 600
The timeout must respect the server’s configured maximum. A server rejection is surfaced as a setup/session error.
Maintain Dashboard session state:
{
id ,
generation ,
createdAt ,
status ,
setupFingerprint ,
abortController
}
The session is abandoned by forgetting its ID. No explicit DROP cleanup is required.
A new fresh session is required for:
Dashboard open;
Dashboard Refresh;
any committed parameter change affecting a Setup query;
one recovery attempt after a session-expiry or missing-temporary-table failure.
Setup SQL contract
A Setup saved query may contain one or more SQL statements.
Split with the canonical statement splitter.
Execute statements sequentially.
Use the parameter pipeline with:
Use one prepared batch and one wallNowMs for the complete fresh wave.
Allowed automatic statements
V1 accepts only:
SET
Requirements:
one normal SET statement;
no attempt to change readonly;
server setting constraints remain authoritative.
CREATE TEMPORARY TABLE AS SELECT
CREATE TEMPORARY TABLE daily AS
SELECT ...
Accepted syntax includes an optional:
The statement must:
explicitly contain TEMPORARY;
create an unqualified temporary table name;
contain an AS SELECT row-returning source;
not use ON CLUSTER;
not use a permanent database-qualified target;
not include an authored top-level output FORMAT.
CREATE OR REPLACE is not supported in v1. Every recomputation uses a fresh session, so replacement is unnecessary.
Row-returning read statement
Examples:
SELECT ...
SHOW ...
DESCRIBE ...
EXPLAIN ...
The result is discarded during automatic Dashboard execution.
Use this for cache warming, validation reads, or session-local checks.
Rejected statements
Reject client-side before any setup request:
permanent CREATE
CREATE TABLE without TEMPORARY
CREATE OR REPLACE
DROP
ALTER
RENAME
ATTACH
DETACH
TRUNCATE
INSERT
OPTIMIZE
SYSTEM
KILL
GRANT
REVOKE
CREATE USER/ROLE/ROW POLICY/SETTINGS PROFILE/QUOTA
mutations
USE
Reject any unclassified statement.
A blocked statement invalidates the complete Setup query.
Do not weaken the allowlist based on server permissions.
Pure Setup classifier
Add:
Suggested API:
analyzeSetupSql ( {
sql,
parameterAnalysis
} ) - > {
statements : [
{
index,
sql,
kind : "set" | "create-temporary-as-select" | "read" ,
allowed,
params,
optionalParams,
diagnostics
}
] ,
diagnostics,
valid
}
The classifier must use lexical/statement utilities rather than broad regular expressions over raw SQL.
It must correctly ignore keywords inside:
strings;
quoted identifiers;
comments;
nested SELECT expressions.
It must be:
pure;
DOM-free;
network-free;
non-mutating;
covered at 100% per-file.
Parameters
Setup SQL participates in shared Dashboard parameter analysis.
Supported:
required parameters;
optional-block parameters;
typed validation;
relative-time values;
activation state;
persisted values;
typed serialization;
exact large integers and arrays supported by the pipeline.
Preparation uses:
This is required because Setup includes non-row-returning statements.
A missing, invalid, or serialization-failed parameter blocks the fresh wave before the first network request.
Filter dependency prohibition
A Setup query may not declare a parameter that is curated by a Filter helper from #160 .
Reason:
Setup must run before Filter queries;
Filter reconciliation has not yet validated the selected value;
Setup cannot safely consume an option-backed value before its provider runs.
Detect this after Filter helper names are known from the last successful configuration snapshot or after static/provider planning where available.
For a fresh Dashboard open with no provider result yet:
use the configured Filter query’s last known helper metadata when available;
otherwise run Filter queries only after Setup as required and treat an overlapping target discovered afterward as a configuration error;
abort before Panels;
surface the cycle;
require the author to remove the dependency.
Persist a lightweight derived helper-name cache only if #160 already provides one for diagnostics. Do not persist option values or option lists.
Diagnostic:
The message names:
Setup query;
Filter query;
parameter.
Automatic statement execution
Add:
src/core/setup-execution.js
Suggested API:
setupStatementExecution ( statement , defaults = { } ) - > {
owned,
command,
format?,
params,
error
}
SET and CREATE TEMPORARY
Use a command request path:
readonly = 2;
same session_id;
same session_timeout;
no result-row parser;
structured HTTP error handling;
cancellation;
timing.
Do not append FORMAT Null to command statements.
Read statements
Use a null-output request:
readonly = 2;
same session;
no client row accumulation;
server-side FORMAT Null or equivalent owned format;
reject authored top-level FORMAT rather than rewriting it;
retain progress and error handling;
cancellation.
Safety settings
Every automatic Setup request includes:
Do not send allow_ddl = 1 as a query override.
The connected ClickHouse user and server constraints remain authoritative.
Network session seam
Extend the shared HTTP request options:
{
sessionId ,
sessionTimeout ,
signal
}
chUrl() maps these to:
session_id
session_timeout
Add a command execution seam that:
uses POST;
supports typed param_<name> values;
returns elapsed/progress/error metadata;
does not buffer result rows;
supports abort;
uses the same authentication and token-refresh behavior as normal reads.
Filter and Panel execution functions accept optional session fields and pass them unchanged.
No request may omit the active session ID during a Setup wave.
Dashboard wave planner
Add pure planning in:
src/core/dashboard-wave.js
Suggested result:
planDashboardWave ( {
queries,
parameterAnalysis,
filterProviders,
hasSetup,
changedParameter?
} ) - > {
mode : "parallel" | "session" ,
setupSources,
filterSources,
panelSources,
fullRerun,
diagnostics
}
Rules:
No Setup
Use existing #160 parallel behavior.
Fresh Setup wave
Run:
all Setup statements in source/statement order;
all Filter queries in source order;
merge and reconcile Filter helpers;
all Panels in source order.
Stop at the first Setup failure.
A Filter failure uses ordinary fallback controls and does not block Panels.
Parameter change affecting Setup
Start a fresh session and rerun the complete wave.
Conservative v1 rule:
all Setup queries rerun;
all Filter queries rerun;
all Panels rerun.
Parameter change not affecting Setup
Reuse the current session.
Run only affected Panels, sequentially in the session.
Do not rerun Setup or Filter queries.
Dashboard Refresh
Start a fresh session and rerun the complete wave.
Setup fingerprint
Compute a pure fingerprint from:
ordered Setup query IDs;
Setup SQL text;
Setup Spec role-relevant data;
bound parameter snapshots for parameters used by Setup;
optional-block activation state;
server/connection identity where already available.
Use the fingerprint to determine whether current session setup state matches the requested wave.
Do not include unrelated Panel-only filter values.
Do not use the fingerprint as a security boundary.
Request scheduling and cancellation
Setup mode uses one serialized request queue.
State:
waveGeneration
current AbortController
session ID
phase
source index
statement index
Rules:
a new full wave reserves a generation immediately;
abort the current request;
queued old work checks generation before issuing;
stale responses never update UI;
Dashboard close aborts the current request and discards the session;
a non-Setup affected rerun is queued after the current session request;
never allow two in-flight requests with the same session ID.
Error behavior
Setup validation failure
Before network:
show Setup configuration error;
do not run any Setup, Filter, or Panel request;
render Panel slots as blocked.
Setup execution failure
On first failure:
stop the current statement;
skip remaining Setup statements and queries;
do not run Filter queries;
do not run Panels;
preserve the failed statement and ClickHouse message;
keep the session abandoned.
Dashboard UI
Header indicator:
States:
Setup · running
Setup · ready
Setup · failed
Expanding shows:
Setup query name;
statement number;
kind;
status;
elapsed time;
error.
Failure banner:
Setup failed
Build daily temporary data · statement 2
<ClickHouse error>
Every blocked Panel slot shows:
Filter controls remain visible but do not trigger Panel execution until a successful fresh wave.
Session recovery
Recognize only narrow session-state failures:
session expired or not found;
unknown temporary table referenced by a Filter or Panel query while Setup mode is active.
On the first recognized failure in a wave:
abandon the current session;
create a fresh session;
rerun the complete Setup → Filter → Panel wave once.
On a second failure:
stop;
surface the original phase/source error;
do not retry again.
Do not retry:
syntax errors;
permission errors;
parameter errors;
arbitrary unknown-table errors when the table is not known to be created by a Setup statement;
aborted requests.
Track temporary table names produced by the Setup plan so recovery classification is precise.
Workbench and Dashboard separation
Workbench explicit Run and Dashboard automatic Setup execution are independent.
Workbench:
develops and debugs the SQL;
keeps existing multi-statement results;
may use existing workbench session behavior;
does not modify Dashboard session state.
Dashboard:
uses the strict allowlist;
uses readonly=2;
creates a fresh named session when required;
discards automatic read output;
serializes the complete wave.
Selecting Setup in the drawer changes Spec only.
Diagnostics
Stable codes:
setup-sql-empty
setup-statement-unsupported
setup-create-not-temporary
setup-create-not-as-select
setup-create-qualified-target
setup-create-on-cluster
setup-create-or-replace
setup-owned-format
setup-readonly-change
setup-parameter-missing
setup-parameter-invalid
setup-parameter-serialization
setup-filter-dependency
setup-session-create
setup-session-timeout
setup-query-failed
setup-session-expired
setup-temporary-table-missing
setup-recovery-failed
Diagnostic shape:
{
severity ,
code ,
message ,
sourceId ?,
statementIndex ?,
parameterName ?,
path ?
}
Static Setup plan errors may block Save.
Runtime and cross-Dashboard errors appear in Setup view and Dashboard status.
Only real errors appear in the bottom error area.
Files
Add:
src/core/setup-plan.js
src/core/setup-execution.js
src/core/dashboard-wave.js
src/core/dashboard-session.js
src/ui/setup-view.js
src/ui/setup-status.js
Modify:
schemas/query-spec-v1.schema.json
src/generated/json-schemas.js
src/generated/json-schema-validators.js
src/core/result-choice.js
src/core/saved-query.js
src/core/dashboard.js
src/core/param-pipeline.js
src/ui/panels.js
src/ui/results.js
src/ui/dashboard.js
src/ui/saved-history.js
src/ui/app.js
src/net/ch-client.js
src/state.js
src/styles.css
README.md
CHANGELOG.md
docs/saved-query-spec-json-schema.md
docs/visualization-spec-authoring-guide.md
Add corresponding unit, integration, live compatibility, and E2E tests.
No new runtime dependency.
Implementation order
1. Selector and labels
append Setup role choice;
add transient Setup view;
retain selector in script-result toolbar;
add compact badges;
preserve Panel config through role changes.
2. Setup plan and validation
implement pure statement classifier;
implement allowlist;
integrate bindPolicy: "all";
add static diagnostics;
render workbench Setup plan.
3. Session-aware network seam
add session URL options;
add command/null-output execution;
thread session through Filter and Panel paths;
add cancellation and metadata.
4. Dashboard wave
add session-mode planner;
serialize Setup, Filter, reconciliation, and Panels;
retain parallel mode without Setup;
implement fresh-session triggers and fingerprints.
5. Status and errors
add header status;
add expanded details;
add banner and blocked slots;
implement one recovery attempt.
6. Documentation and compatibility
document safe SQL subset;
document serialized performance behavior;
run supported-server compatibility tests;
update README and changelog.
Tests
Selector
Classifier
SET allowed;
SET readonly rejected;
CREATE TEMPORARY TABLE AS SELECT allowed;
IF NOT EXISTS allowed;
CREATE OR REPLACE rejected;
permanent/qualified CREATE rejected;
ON CLUSTER rejected;
read statements allowed;
writes and administrative statements rejected;
keywords in strings/comments ignored;
multi-statement order;
authored FORMAT rejection;
100% per-file coverage.
Parameters
bindPolicy: "all" binds SET/CREATE/read statements;
required and optional parameters;
missing/invalid/serialization blockers;
one wall clock per wave;
Filter-provider dependency rejection.
Workbench Setup view
static plan before Run;
blocked statement display;
no Dashboard execution from view;
existing explicit script result reused;
single-result Table/JSON inspection;
no role selection network call.
Session seam
session ID and timeout on every wave request;
no session fields outside Setup mode;
command path buffers no rows;
read path uses Null output;
readonly=2 always present;
abort works;
auth refresh retains session fields.
Wave planning
no Setup keeps parallel mode;
Setup creates serialized mode;
source/statement Library order;
Setup → Filter → reconcile → Panel order;
first Setup error stops wave;
Filter failure falls back and Panels continue;
Setup-affecting parameter starts fresh full wave;
unrelated parameter reuses session and runs affected Panels only;
Refresh starts fresh full wave;
no concurrent request uses one session.
Status and recovery
running/ready/failed header;
expanded statement detail;
failure banner;
blocked Panel state;
session-expiry recovery once;
known temporary-table missing recovery once;
unrelated unknown table does not trigger recovery;
second failure stops.
Compatibility
On every supported ClickHouse version:
readonly=2 accepts SET;
readonly=2 accepts CREATE TEMPORARY TABLE AS SELECT;
HTTP parameters bind in allowed statements;
named session preserves temporary table visibility;
concurrent same-session request is never issued;
session timeout behavior is handled.
Regression
Acceptance criteria
Goal
Implement the
setupDashboard role on top of the role-aware result selector and Dashboard role partition introduced by #160.A favorited Setup query runs hidden preparation statements before Filter queries and displayed Panels.
Persisted Spec:
{ "favorite": true, "dashboard": { "role": "setup" } }A Setup query:
This issue adds
Setupto the selector foundation shipped by #160.Dependencies
Required:
/*[ … ]*/+ explicit filter activation — an empty parameter cannot omit surrounding SQL #165 — optional SQL blocks and explicit activation;bindPolicy: "all";Persisted model
Setup is a Dashboard execution role:
It is not a Panel type.
Do not add
setupto:A Setup query may retain a complete dormant
spec.panelobject.Switching to Setup changes only
spec.dashboard.role.Switching from Setup to a Panel choice changes the effective role to Panel and restores or updates the preserved Panel configuration through the existing
switchPanelType()behavior.No
specVersionchange is required.Unknown
dashboardfields remain preserved.Canonical schema
The canonical
dashboard.roleenum already includes:Update the
setupcompletion information to document:Do not add a Setup branch to
panelCfg.Drawer selector
Extend the role-choice list created by #160:
Normal Setup query header:
The closed control uses:
Do not display
Setup sourcein the drawer header.Selecting Setup
Selecting
Setup:spec.dashboard.role = "setup";dashboardsiblings;spec.panelobject;setupdrawer view;spec.view.Selecting a Panel choice from Setup
Selecting any Panel choice:
panel;dashboardsiblings;switchPanelType()for the selected visualization;paneldrawer view;Table and JSON
Table and JSON:
Transient view
Extend result-view state with:
setupis not persisted intospec.view.Retain it across explicit reruns during the current tab lifetime. Restore the normal persisted view when the tab is recreated.
Workbench Setup view
The Setup view is an authoring and last-run status surface. It never runs the Dashboard setup wave.
Static execution plan
Before any Run, show the parsed Setup plan:
For each statement show:
The plan is produced by the same pure classifier used by Dashboard automatic execution.
No explicit Run result
Show:
Running
Show current explicit workbench status without simulating Dashboard execution.
Completed explicit Run
Reuse the workbench’s existing per-statement result/status data.
Show:
The ordinary workbench Run path remains unchanged:
readonly=2;Single row-returning statement
Table and JSON remain available for the explicit result.
Setup view shows its classified Dashboard behavior and last-run status.
Multi-statement script
The Setup view becomes the primary role-specific representation. Reuse the existing script-grid data rather than creating a second result model.
The drawer toolbar may show:
when Table/JSON are not meaningful for the script result.
The role selector remains available even in the script-result toolbar.
Library and workbench labels
Use compact UI labels:
Library row:
Workbench title badge:
Clicking either badge:
dashboard.role.Do not display
Setup sourcein the drawer header.Dashboard partition
Partition the favorited Library snapshot before execution:
setup→ Setup scheduler, no grid slot;filter→ Filter scheduler from Dashboard: multi-filter option bundles, shared preview, and role-aware result selector #160, no grid slot;panel→ displayed Panel;Setup and Filter queries:
Shared-session rule
When at least one favorited Setup query exists, the complete Dashboard wave uses one fresh named HTTP session.
Wave order:
Only one request may be active in the session at a time.
Do not run Filter queries or Panels concurrently in Setup mode.
When no Setup query exists, retain #160’s normal behavior:
This conditional preserves performance for normal dashboards.
Session identity and lifetime
Generate a cryptographically random session ID for each fresh setup wave.
Suggested shape:
Send on every request in the wave:
Suggested timeout:
The timeout must respect the server’s configured maximum. A server rejection is surfaced as a setup/session error.
Maintain Dashboard session state:
The session is abandoned by forgetting its ID. No explicit DROP cleanup is required.
A new fresh session is required for:
Setup SQL contract
A Setup saved query may contain one or more SQL statements.
Split with the canonical statement splitter.
Execute statements sequentially.
Use the parameter pipeline with:
bindPolicy: "all"Use one prepared batch and one
wallNowMsfor the complete fresh wave.Allowed automatic statements
V1 accepts only:
SET
Requirements:
readonly;CREATE TEMPORARY TABLE AS SELECT
Accepted syntax includes an optional:
The statement must:
TEMPORARY;AS SELECTrow-returning source;ON CLUSTER;CREATE OR REPLACEis not supported in v1. Every recomputation uses a fresh session, so replacement is unnecessary.Row-returning read statement
Examples:
SELECT ... SHOW ... DESCRIBE ... EXPLAIN ...The result is discarded during automatic Dashboard execution.
Use this for cache warming, validation reads, or session-local checks.
Rejected statements
Reject client-side before any setup request:
Reject any unclassified statement.
A blocked statement invalidates the complete Setup query.
Do not weaken the allowlist based on server permissions.
Pure Setup classifier
Add:
Suggested API:
The classifier must use lexical/statement utilities rather than broad regular expressions over raw SQL.
It must correctly ignore keywords inside:
It must be:
Parameters
Setup SQL participates in shared Dashboard parameter analysis.
Supported:
Preparation uses:
bindPolicy: "all"This is required because Setup includes non-row-returning statements.
A missing, invalid, or serialization-failed parameter blocks the fresh wave before the first network request.
Filter dependency prohibition
A Setup query may not declare a parameter that is curated by a Filter helper from #160.
Reason:
Detect this after Filter helper names are known from the last successful configuration snapshot or after static/provider planning where available.
For a fresh Dashboard open with no provider result yet:
Persist a lightweight derived helper-name cache only if #160 already provides one for diagnostics. Do not persist option values or option lists.
Diagnostic:
The message names:
Automatic statement execution
Add:
Suggested API:
SET and CREATE TEMPORARY
Use a command request path:
readonly = 2;session_id;session_timeout;Do not append
FORMAT Nullto command statements.Read statements
Use a null-output request:
readonly = 2;FORMAT Nullor equivalent owned format;Safety settings
Every automatic Setup request includes:
Do not send
allow_ddl = 1as a query override.The connected ClickHouse user and server constraints remain authoritative.
Network session seam
Extend the shared HTTP request options:
chUrl()maps these to:Add a command execution seam that:
param_<name>values;Filter and Panel execution functions accept optional session fields and pass them unchanged.
No request may omit the active session ID during a Setup wave.
Dashboard wave planner
Add pure planning in:
Suggested result:
Rules:
No Setup
Use existing #160 parallel behavior.
Fresh Setup wave
Run:
Stop at the first Setup failure.
A Filter failure uses ordinary fallback controls and does not block Panels.
Parameter change affecting Setup
Start a fresh session and rerun the complete wave.
Conservative v1 rule:
Parameter change not affecting Setup
Reuse the current session.
Run only affected Panels, sequentially in the session.
Do not rerun Setup or Filter queries.
Dashboard Refresh
Start a fresh session and rerun the complete wave.
Setup fingerprint
Compute a pure fingerprint from:
Use the fingerprint to determine whether current session setup state matches the requested wave.
Do not include unrelated Panel-only filter values.
Do not use the fingerprint as a security boundary.
Request scheduling and cancellation
Setup mode uses one serialized request queue.
State:
Rules:
Error behavior
Setup validation failure
Before network:
Setup execution failure
On first failure:
Dashboard UI
Header indicator:
States:
Expanding shows:
Failure banner:
Every blocked Panel slot shows:
Filter controls remain visible but do not trigger Panel execution until a successful fresh wave.
Session recovery
Recognize only narrow session-state failures:
On the first recognized failure in a wave:
On a second failure:
Do not retry:
Track temporary table names produced by the Setup plan so recovery classification is precise.
Workbench and Dashboard separation
Workbench explicit Run and Dashboard automatic Setup execution are independent.
Workbench:
Dashboard:
readonly=2;Selecting Setup in the drawer changes Spec only.
Diagnostics
Stable codes:
Diagnostic shape:
Static Setup plan errors may block Save.
Runtime and cross-Dashboard errors appear in Setup view and Dashboard status.
Only real errors appear in the bottom error area.
Files
Add:
Modify:
Add corresponding unit, integration, live compatibility, and E2E tests.
No new runtime dependency.
Implementation order
1. Selector and labels
2. Setup plan and validation
bindPolicy: "all";3. Session-aware network seam
4. Dashboard wave
5. Status and errors
6. Documentation and compatibility
Tests
Selector
Setup;spec.view;Classifier
Parameters
bindPolicy: "all"binds SET/CREATE/read statements;Workbench Setup view
Session seam
readonly=2always present;Wave planning
Status and recovery
Compatibility
On every supported ClickHouse version:
readonly=2accepts SET;readonly=2accepts CREATE TEMPORARY TABLE AS SELECT;Regression
Acceptance criteria
spec.dashboard.role = "setup".Setup, notSetup source.readonly=2.bindPolicy: "all".npm testpasses.npm run buildsucceeds.