Skip to content

Feature: --assert mode — run SQL predicate, exit 0 if true, 1 if false #202

Description

@vmvarela

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

  • sql-pipe data.csv --assert "SELECT 1" exits 0
  • sql-pipe data.csv --assert "SELECT 0" exits 1
  • sql-pipe data.csv --assert "SELECT NULL" exits 1
  • sql-pipe data.csv --assert "SELECT COUNT(*) > 0 FROM data" exits 0 on non-empty input
  • sql-pipe data.csv --assert "SELECT COUNT(*) > 0 FROM data" exits 1 on empty input
  • sql-pipe data.csv --assert "SELECT 'hello'" exits with error (non-integer)
  • Integration test in build.zig

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:highMust be in the next sprintsize:sSmall — 1 to 4 hoursstatus:readyRefined and ready for sprint selectiontype:featureNew functionality

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions