cockroachdb / cockroachdb/cockroach
plpgsql: internal error when using SELECT INTO with TG_* variables in trigger functions
- Dominant language
- Go
- Stars
- 32.5k
- Forks
- 4.1k
- PR merge metrics
- PR metrics pending
Description
**Describe the problem**
Using `SELECT INTO ` inside a PL/pgSQL trigger function causes an internal error:
```
internal error: top-level relational expression cannot have outer columns: (38)
```
This affects all trigger-specific variables (`TG_NAME`, `TG_OP`, `TG_WHEN`, `TG_TABLE_NAME`, `TG_TABLE_SCHEMA`, `TG_NARGS`, `TG_RELID`).
**Workaround:** Direct assignment works correctly (`v := TG_NAME`).
**To Reproduce**
```sql
CREATE TABLE xy (x INT, y INT);
CREATE FUNCTION test_select_into() RETURNS TRIGGER LANGUAGE PLpgSQL AS $$
DECLARE
v TEXT;
BEGIN
SELECT TG_NAME INTO v; -- This fails
RAISE NOTICE 'TG_NAME: %', v;
RETURN NEW;
END
$$;
CREATE TRIGGER tr_test BEFORE INSERT ON xy FOR EACH ROW EXECUTE FUNCTION test_select_into();
INSERT INTO xy VALUES (1, 1); -- Internal error
```
**Expected behavior**
The `SELECT INTO` statement should work the same as PostgreSQL, which correctly assigns the trigger variable value to the local variable.
**Working workaround**
Direct assignment works correctly:
```sql
CREATE FUNCTION test_direct_assign() RETURNS TRIGGER LANGUAGE PLpgSQL AS $$
DECLARE
v TEXT;
BEGIN
v := TG_NAME; -- This works
RAISE NOTICE 'TG_NAME: %', v;
RETURN NEW;
END
$$;
```
**PostgreSQL behavior**
PostgreSQL 16 handles `SELECT TG_NAME INTO v` correctly:
```
NOTICE: TG_NAME: tr_test, TG_OP: INSERT, TG_WHEN: BEFORE, ...
```
**Environment:**
- CockroachDB version: master (commit ~0fbbeaf8982)
- Server OS: macOS (darwin_arm64)
**Stack trace**
```
ERROR: internal error: top-level relational expression cannot have outer columns: (38)
SQLSTATE: XX000
DETAIL: stack trace:
pkg/sql/opt/xform/optimizer.go:277: Optimize()
pkg/sql/opt/exec/execbuilder/scalar.go:1288: func2()
pkg/sql/routine.go:329: startInternal()
pkg/sql/routine.go:279: Start()
pkg/sql/routine.go:179: EvalRoutineExpr()
pkg/sql/sem/eval/expr.go:648: EvalRoutineExpr()
bazel-out/darwin_arm64-fastbuild/bin/pkg/sql/sem/tree/eval_expr_generated.go:361: Eval()
pkg/sql/sem/eval/expr.go:22: Expr()
pkg/sql/execinfra/execexpr/expr.go:310: eval()
pkg/sql/execinfra/execexpr/expr.go:163: EvalExpr()
pkg/sql/execinfra/processorsbase.go:294: ProcessRow()
pkg/sql/execinfra/processorsbase.go:744: ProcessRowHelper()
pkg/sql/rowexec/noop.go:96: Next()
pkg/sql/colexec/columnarizer.go:244: Next()
pkg/sql/colflow/stats.go:122: next()
pkg/sql/colexecerror/error.go:162: CatchVectorizedRuntimeError()
pkg/sql/colflow/stats.go:130: Next()
bazel-out/darwin_arm64-fastbuild/bin/pkg/sql/colexec/is_null_ops.eg.go:220: Next()
pkg/sql/colflow/stats.go:122: next()
pkg/sql/colexecerror/error.go:162: CatchVectorizedRuntimeError()
pkg/sql/colflow/stats.go:130: Next()
pkg/sql/colexecop/operator.go:472: Next()
pkg/sql/colexec/materializer.go:248: next()
pkg/sql/colexec/materializer.go:276: nextAdapter()
pkg/sql/colexecerror/error.go:162: CatchVectorizedRuntimeError()
pkg/sql/colexec/materializer.go:282: Next()
pkg/sql/rowexec/stats.go:64: Next()
pkg/sql/rowexec/noop.go:83: Next()
pkg/sql/colexec/columnarizer.go:244: Next()
pkg/sql/colflow/stats.go:122: next()
pkg/sql/colexecerror/error.go:162: CatchVectorizedRuntimeError()
pkg/sql/colflow/stats.go:130: Next()
```
Jira issue: CRDB-59360
Contributor guide
Assessment
This issue has not been assessed yet.