diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index b1c29e0..9e8b726 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -376,6 +376,8 @@ contain_invalid_rfcolumn(Oid pubid, Relation relation, List *ancestors, /* * Is this a simple Node permitted within a row filter expression? + * + * We can allow other node types after more analysis and testing. */ static bool IsRowFilterSimpleExpr(Node *node) @@ -395,6 +397,7 @@ IsRowFilterSimpleExpr(Node *node) case T_NullTest: case T_RelabelType: case T_XmlExpr: + case T_List: return true; default: return false; @@ -410,6 +413,37 @@ contain_mutable_or_ud_functions_checker(Oid func_id, void *context) } /* + * Check, if the node contains any unallowed object in node. See + * check_simple_rowfilter_expr_walker. + * + * Returns the error detail meesage in errdetail_msg for unallowed expressions. + */ +static bool +expr_allowed_in_node(Node *node, ParseState *pstate, char **errdetail_msg) +{ + if (IsA(node, List)) + { + /* + * OK, we don't need to perform other expr checks for list because those are + * undefined for list. + */ + return true; + } + + if (exprType(node) >= FirstNormalObjectId) + *errdetail_msg = _("User-defined types are not allowed."); + if (check_functions_in_node(node, contain_mutable_or_ud_functions_checker, + (void*) pstate)) + *errdetail_msg = _("User-defined or built-in mutable functions are not allowed."); + else if (exprCollation(node) >= FirstNormalObjectId) + *errdetail_msg = _("User-defined collations are not allowed."); + else if (exprInputCollation(node) >= FirstNormalObjectId) + *errdetail_msg = _("User-defined collations are not allowed."); + + return true; +} + +/* * The row filter walker checks if the row filter expression is a "simple * expression". * @@ -452,21 +486,6 @@ check_simple_rowfilter_expr_walker(Node *node, ParseState *pstate) if (node == NULL) return false; - - /* Check for mutable or user defined functions in node itself */ - if (check_functions_in_node(node, contain_mutable_or_ud_functions_checker, - (void *) pstate)) - errdetail_msg = _("User-defined or mutable functions are not allowed"); - else if (IsA(node, List)) - { - /* OK, node is part of simple expressions */ - } - else if (exprCollation(node) >= FirstNormalObjectId) - errdetail_msg = _("User-defined collations are not allowed."); - else if (exprInputCollation(node) >= FirstNormalObjectId) - errdetail_msg = _("User-defined collations are not allowed."); - else if (exprType(node) >= FirstNormalObjectId) - errdetail_msg = _("User-defined types are not allowed."); else if (IsA(node, Var)) { /* System columns are not allowed. */ @@ -500,12 +519,18 @@ check_simple_rowfilter_expr_walker(Node *node, ParseState *pstate) } } } - else if (!IsRowFilterSimpleExpr(node)) + else if (IsRowFilterSimpleExpr(node)) + { + } + else { elog(DEBUG3, "row filter contains an unexpected expression component: %s", nodeToString(node)); errdetail_msg = _("Expressions only allow columns, constants, built-in operators, built-in data types, built-in collations and immutable built-in functions."); } + if (!errdetail_msg) + expr_allowed_in_node(node, pstate, &errdetail_msg); + if (errdetail_msg) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out index f785efe..c1f70b7 100644 --- a/src/test/regress/expected/publication.out +++ b/src/test/regress/expected/publication.out @@ -371,20 +371,20 @@ CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl3 WHERE (e =#> 27); ERROR: invalid publication WHERE expression LINE 1: ...ICATION testpub6 FOR TABLE testpub_rf_tbl3 WHERE (e =#> 27); ^ -DETAIL: User-defined or mutable functions are not allowed +DETAIL: User-defined operators are not allowed. -- fail - user-defined functions are not allowed CREATE FUNCTION testpub_rf_func2() RETURNS integer AS $$ BEGIN RETURN 123; END; $$ LANGUAGE plpgsql; ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a >= testpub_rf_func2()); ERROR: invalid publication WHERE expression LINE 1: ...ON testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a >= testpub_rf... ^ -DETAIL: User-defined or mutable functions are not allowed +DETAIL: User-defined or built-in mutable functions are not allowed. -- fail - non-immutable functions are not allowed. random() is volatile. ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a < random()); ERROR: invalid publication WHERE expression LINE 1: ...ION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a < random()); ^ -DETAIL: User-defined or mutable functions are not allowed +DETAIL: User-defined or built-in mutable functions are not allowed. -- ok - NULLIF is allowed ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (NULLIF(1,2) = a); -- ok - built-in operators are allowed