Dangerous-SQL detection

Before executing SQL, the CLI performs a keyword-based scan (uppercased, whitespace-split) to detect destructive operations. A match prompts for `yes` confirmation; the `--force` / `-y` flag bypasses confirmation for automation. Gated statements: DROP TABLE, DROP SCHEMA, DROP ZONE, TRUNCATE, and DELETE / UPDATE without a WHERE clause.

Category: safety

Description

## Overview The CLI performs a client-side keyword scan on every SQL statement before sending it to the compute node. When the scan matches a destructive pattern, the user must type `yes` to confirm; any other answer aborts. The check is intentionally simple (a safety net, not a parser) and can be bypassed with `--force` / `-y` for automation. The scan runs in all modes that submit SQL: the interactive REPL (`query` typed into the shell), the `query` subcommand, the `run` subcommand, and piped stdin. For `run`, each statement in the script is scanned individually after statement splitting. ## Detection rules The scanner uppercases the statement and splits on whitespace, then matches these patterns in order: | Pattern | Prompt | | --- | --- | | `DROP TABLE ...` | `This will permanently drop a table.` | | `DROP SCHEMA ...` | `This will permanently drop a schema and all its tables.` | | `DROP ZONE ...` | `This will permanently drop a zone and all its contents.` | | `DELETE FROM ...` with no `WHERE` keyword anywhere in the statement | `DELETE without WHERE clause will remove ALL rows.` | | `UPDATE ...` with no `WHERE` keyword anywhere in the statement | `UPDATE without WHERE clause will modify ALL rows.` | | statement whose first word is `TRUNCATE` | `TRUNCATE will remove all data from the table.` | The source is [delta-forge-cli/src/safety.rs](delta-forge-cli/src/safety.rs). ## Behavior - The check is purely lexical and case-insensitive. A statement is dangerous if its keyword pattern matches, not if its runtime effect is destructive. - `DELETE` and `UPDATE` are safe when `WHERE` appears anywhere in the uppercased statement. The scanner does not verify that the WHERE clause is actually bound to the target table; `UPDATE t SET x = (SELECT y FROM s WHERE ...)` counts as safe. - `DROP VIEW`, `DROP INDEX`, `DROP PIPELINE`, and other DROP variants are not gated. Only TABLE, SCHEMA, and ZONE trigger prompts. - The confirmation requires typing exactly `yes`. Any other input (including `y` or `YES`) aborts the statement. - In script mode (`run`), a rejected confirmation halts execution. Remaining statements are not attempted. - `--force` / `-y` applies to the entire invocation and bypasses every dangerous-SQL prompt for that process. ## Compatibility - The scanner operates on the raw SQL text as supplied to the CLI, before any server-side parsing. A statement the server rejects as invalid may still have tripped the scanner on the client. - When SQL is generated by upstream tools and piped in, the scanner still runs. Use `--force` for trusted pipelines.

Examples

# Interactive: prompts 'This will permanently drop a table. Type yes to confirm:'
delta-forge-cli query "DROP TABLE staging.events"
# Automation: bypass confirmation with --force
delta-forge-cli --force query "DROP TABLE staging.events"
# DROP SCHEMA / DROP ZONE also prompt
delta-forge-cli query "DROP SCHEMA staging"
delta-forge-cli query "DROP ZONE landing"
# Safe (WHERE present, no prompt)
delta-forge-cli query "DELETE FROM sales.orders WHERE created_at < '2026-01-01'"
# Dangerous (no WHERE, prompts)
delta-forge-cli query "UPDATE sales.orders SET status = 'void'"
# TRUNCATE is always gated regardless of clause order
delta-forge-cli query "TRUNCATE TABLE staging.events"

Pitfalls

See Also

Open in interactive docs →   DeltaForge home →