Context
No competitor (sqlite-utils, textql, dsq, sq, duckdb, trdsql, sqly) offers a SQL-powered boolean assertion mode. In CI pipelines, the common pattern is:
sql-pipe data.csv "SELECT COUNT(*) FROM data WHERE status = 'error'" | awk '{exit $1==0?1:0}'
--assert eliminates the awk wrapper and integrates naturally with shell exit-code semantics.
Proposed flag
--assert "<SQL predicate>" Run query, exit 0 if true, 1 if false
UX examples
# Fail CI if any rows have error status
sql-pipe --validate data.csv && sql-pipe data.csv --assert "SELECT COUNT(*) = 0 FROM data WHERE status = 'error'"
# Ensure at least 100 rows exist
sql-pipe data.csv --assert "SELECT COUNT(*) >= 100 FROM data"
# Guard against empty input
sql-pipe data.csv --assert "SELECT COUNT(*) > 0 FROM data"
Scope (v1)
- New mode in
src/modes/ (like --validate, --columns, etc.) or handled in src/main.zig
- Runs the SQL query, reads the first column of the first row
- Truthiness: nonzero integer = true, 0 = false, NULL = false, anything else = error ("assert requires scalar integer")
- Exit code 0 on true, 1 on false
- Compatible with all input formats, type inference,
--no-type-inference
- Mutually exclusive with
--output, --explain, --schema, and query arguments (except the SQL itself)
Excluded (YAGNI)
- Multi-row/multi-column assertions (use SQL to reduce)
- Custom output on assertion failure (exit code is enough for CI)
- Non-integer truth values (strings as true — use SQL CAST)
- Soft assertion (warn but exit 0)
Files affected
src/args.zig — parse --assert <sql> flag, store in ParsedArgs
src/main.zig — new dispatch branch: load input, run assertion query, read result, exit with appropriate code
- New
src/modes/assert.zig — assertion logic (or inline in main if small enough)
Acceptance criteria
Context
No competitor (sqlite-utils, textql, dsq, sq, duckdb, trdsql, sqly) offers a SQL-powered boolean assertion mode. In CI pipelines, the common pattern is:
--asserteliminates theawkwrapper and integrates naturally with shell exit-code semantics.Proposed flag
UX examples
Scope (v1)
src/modes/(like--validate,--columns, etc.) or handled insrc/main.zig--no-type-inference--output,--explain,--schema, and query arguments (except the SQL itself)Excluded (YAGNI)
Files affected
src/args.zig— parse--assert <sql>flag, store inParsedArgssrc/main.zig— new dispatch branch: load input, run assertion query, read result, exit with appropriate codesrc/modes/assert.zig— assertion logic (or inline in main if small enough)Acceptance criteria
sql-pipe data.csv --assert "SELECT 1"exits 0sql-pipe data.csv --assert "SELECT 0"exits 1sql-pipe data.csv --assert "SELECT NULL"exits 1sql-pipe data.csv --assert "SELECT COUNT(*) > 0 FROM data"exits 0 on non-empty inputsql-pipe data.csv --assert "SELECT COUNT(*) > 0 FROM data"exits 1 on empty inputsql-pipe data.csv --assert "SELECT 'hello'"exits with error (non-integer)build.zig