v35-0001-only-allow-Const-node-or-scalar-returning-fun.no-cfbot

application/octet-stream

Filename: v35-0001-only-allow-Const-node-or-scalar-returning-fun.no-cfbot
Type: application/octet-stream
Part: 0
Message: Re: remaining sql/json patches
From 10d7b04281bdb78216f4b80b5b4f2ef0fc77a094 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Sun, 21 Jan 2024 22:18:18 +0800
Subject: [PATCH v35 1/1] only allow Const node or scalar-returning function in
 DEFAULT expression  DEFAULT expression can be formed in many Node type, eg
 ColumnRef.  to make SQL/JSON functions: JSON_EXISTS(), JSON_QUERY(),
 JSON_VALUE()  can be used in index, it's necessary to restrict the ON ERROR,
 ON EMPTY DEFAULT expression  node.

---
 src/backend/parser/parse_expr.c             | 20 ++++++++++++++++++++
 src/test/regress/expected/jsonb_sqljson.out | 16 ++++++----------
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 5493b05a..9b43b9e4 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -4699,6 +4699,26 @@ transformJsonBehavior(ParseState *pstate, JsonBehavior *behavior,
 		location = behavior->location;
 		if (behavior_type == JSON_BEHAVIOR_DEFAULT)
 			expr = transformExprRecurse(pstate, behavior->expr);
+		if (expr != NULL)
+		{
+			if (contain_mutable_functions((Node *) expr))
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+						 errmsg("DEFAULT expression is not immutable"),
+						 parser_errposition(pstate, location)));
+
+			if (IsA(expr, FuncExpr) && ((FuncExpr *) expr)->funcretset)
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("set-returning functions are not allowed in DEFAULT expression"),
+						 parser_errposition(pstate, location)));
+
+			if (!(IsA(expr, Const) || IsA(expr, FuncExpr)))
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("only allow constant value expression or scalar-returning function in DEFAULT expression"),
+						 parser_errposition(pstate, location)));
+		}
 	}
 
 	if (expr == NULL && behavior_type != JSON_BEHAVIOR_ERROR)
diff --git a/src/test/regress/expected/jsonb_sqljson.out b/src/test/regress/expected/jsonb_sqljson.out
index 94c1b430..a73105a4 100644
--- a/src/test/regress/expected/jsonb_sqljson.out
+++ b/src/test/regress/expected/jsonb_sqljson.out
@@ -401,17 +401,13 @@ SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' DEFAULT '0' ON ERROR);
 SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int ERROR ON ERROR);
 ERROR:  invalid input syntax for type integer: " "
 SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR);
- json_value 
-------------
-          5
-(1 row)
-
+ERROR:  only allow constant value expression or scalar-returning function in DEFAULT expression
+LINE 1: ...CT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int DEFAULT 2 ...
+                                                             ^
 SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR);
- json_value 
-------------
-          1
-(1 row)
-
+ERROR:  only allow constant value expression or scalar-returning function in DEFAULT expression
+LINE 1: ...CT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int DEFAULT 2 ...
+                                                             ^
 SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int FORMAT JSON); -- RETURNING FORMAT not allowed
 ERROR:  cannot specify FORMAT in RETURNING clause of JSON_VALUE()
 LINE 1: ...CT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int FORMAT JSO...
-- 
2.34.1