Skip to content

Commit d1e527e

Browse files
committed
plpgsql: handle NULL values correctly for RAISE statements
This patch fixes two behaviors related to RAISE statements handling NULL values: 1. When a NULL value is passed as a formatting argument, it is printed as `<NULL>` in the result string. 2. When a NULL value is passed as a RAISE option (message, detail, etc.) a runtime `RAISE statement option cannot be null` error results. Informs cockroachdb#105254 Release note: None
1 parent 7a597b6 commit d1e527e

File tree

4 files changed

+113
-32
lines changed

4 files changed

+113
-32
lines changed

pkg/sql/logictest/testdata/logic_test/udf_plpgsql

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,42 @@ CREATE OR REPLACE FUNCTION f() RETURNS INT AS $$
685685
END
686686
$$ LANGUAGE PLpgSQL;
687687

688+
# NULL formatting arguments are printed as "<NULL>".
689+
statement ok
690+
CREATE OR REPLACE FUNCTION f() RETURNS INT AS $$
691+
BEGIN
692+
RAISE 'foo % bar %', NULL::TEXT, NULL::INT;
693+
return 0;
694+
END
695+
$$ LANGUAGE PLpgSQL;
696+
697+
statement error pgcode P0001 pq: foo <NULL> bar <NULL>
698+
SELECT f();
699+
700+
# NULL values cannot be supplied as RAISE options.
701+
statement ok
702+
CREATE OR REPLACE FUNCTION f(n INT) RETURNS INT AS $$
703+
BEGIN
704+
IF n = 0 THEN
705+
RAISE division_by_zero USING message = NULL::TEXT;
706+
END IF;
707+
IF n = 1 THEN
708+
RAISE division_by_zero USING detail = NULL::TEXT;
709+
END IF;
710+
RAISE division_by_zero USING hint = (SELECT 'foo' FROM xy WHERE False);
711+
return 0;
712+
END
713+
$$ LANGUAGE PLpgSQL;
714+
715+
statement error pgcode 22004 pq: RAISE statement option cannot be null
716+
SELECT f(0);
717+
718+
statement error pgcode 22004 pq: RAISE statement option cannot be null
719+
SELECT f(1);
720+
721+
statement error pgcode 22004 pq: RAISE statement option cannot be null
722+
SELECT f(2);
723+
688724
statement error pgcode 42601 pq: \"i\" is not a known variable
689725
CREATE OR REPLACE FUNCTION f() RETURNS INT AS $$
690726
BEGIN

pkg/sql/opt/optbuilder/plpgsql.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,10 @@ func (b *plpgsqlBuilder) makeRaiseFormatMessage(
545545
if argIdx >= len(args) {
546546
panic(pgerror.Newf(pgcode.Syntax, "too few parameters specified for RAISE"))
547547
}
548-
addToResult(b.buildPLpgSQLExpr(args[argIdx], types.String, s))
548+
// If the argument is NULL, postgres prints "<NULL>".
549+
arg := b.buildPLpgSQLExpr(args[argIdx], types.String, s)
550+
arg = b.ob.factory.ConstructCoalesce(memo.ScalarListExpr{arg, makeConstStr("<NULL>")})
551+
addToResult(arg)
549552
argIdx++
550553
}
551554
addToResult(makeConstStr(paramSubstr))

0 commit comments

Comments
 (0)