cockroachdb / cockroachdb/cockroach

plpgsql: implement ASSERT statement

Open
#169,580 0 comments 0 reactions 0 assignees View on GitHub
A-sql-plpgsql C-enhancement O-agent T-sql-foundations
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.