cockroachdb / cockroachdb/cockroach
plpgsql: implement ASSERT statement
- Dominant language
- Go
- Stars
- 32.5k
- Forks
- 4.1k
- PR merge metrics
- PR metrics pending
Description
**Is your feature request related to a problem? Please describe.**
PostgreSQL's PL/pgSQL supports an `ASSERT` statement that evaluates
a boolean condition and, when false, raises an `assert_failure`
exception (SQLSTATE `P0004`). It is intended for sanity-checking
invariants in routine bodies; assertions can be enabled or disabled
globally via the `plpgsql.check_asserts` GUC.
```sql
ASSERT count(*) > 0 FROM pending_jobs, 'no pending jobs at startup';
```
The PL/pgSQL parser successfully constructs an `*ast.Assert` node
([`pkg/sql/plpgsql/parser/plpgsql.y:1343-1346`](https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/plpgsql/parser/plpgsql.y#L1343-L1346)),
but the optbuilder has no `case *ast.Assert` arm
([`pkg/sql/opt/optbuilder/plpgsql.go:478-1314`](https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/opt/optbuilder/plpgsql.go#L478-L1314)),
so it falls into the `default:` arm and panics
`unsupportedPLStmtErr`. Today this surfaces under the catch-all
telemetry bucket `unimplemented.unimplemented PL/pgSQL statement`
(see #169557).
Note that the parser currently only stores the keyword form and
discards the condition expression and optional message string
(`$$.val = &plpgsqltree.Assert{}`); implementing the statement will
also require teaching the parser to capture those.
**Describe the solution you'd like**
1. Extend `*ast.Assert` (in
[`pkg/sql/sem/plpgsqltree/statements.go`](https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/sem/plpgsqltree/statements.go))
and the parser at
[`plpgsql.y:1343`](https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/plpgsql/parser/plpgsql.y#L1343)
to capture the boolean condition and the optional message
expression.
2. Add a `case *ast.Assert` arm to `buildPLpgSQLStatements` that, at
runtime: evaluates the condition; if false, raises an
`assert_failure` exception (SQLSTATE `P0004`) with the message
string (or PostgreSQL's default message if none was supplied).
3. Honor a session/cluster setting equivalent to PG's
`plpgsql.check_asserts`. When asserts are disabled the condition
should be skipped entirely (PG short-circuits without evaluating
it).
Epic CRDB-49018
Jira issue: CRDB-63544
Contributor guide
Assessment
This issue has not been assessed yet.