]> granicus.if.org Git - postgresql/commitdiff
Create new ParseExprKind for use by policy expressions.
authorJoe Conway <mail@joeconway.com>
Wed, 29 Jul 2015 22:37:48 +0000 (15:37 -0700)
committerJoe Conway <mail@joeconway.com>
Wed, 29 Jul 2015 22:40:24 +0000 (15:40 -0700)
Policy USING and WITH CHECK expressions were using EXPR_KIND_WHERE for
parse analysis, which results in inappropriate ERROR messages when
the expression contains unsupported constructs such as aggregates.
Create a new ParseExprKind called EXPR_KIND_POLICY and tailor the
related messages to fit.

Reported by Noah Misch. Reviewed by Dean Rasheed, Alvaro Herrera,
and Robert Haas. Back-patch to 9.5 where RLS was introduced.

src/backend/commands/policy.c
src/backend/parser/parse_agg.c
src/backend/parser/parse_expr.c
src/include/parser/parse_node.h
src/test/modules/test_rls_hooks/test_rls_hooks.c
src/test/regress/expected/rowsecurity.out
src/test/regress/sql/rowsecurity.sql

index d8b43908ec406f0bea63dd3f6ca406caf13e2e6c..bcf4a8f35d1f08587d6cf727d11c436ab9ef579a 100644 (file)
@@ -534,12 +534,12 @@ CreatePolicy(CreatePolicyStmt *stmt)
 
        qual = transformWhereClause(qual_pstate,
                                                                copyObject(stmt->qual),
-                                                               EXPR_KIND_WHERE,
+                                                               EXPR_KIND_POLICY,
                                                                "POLICY");
 
        with_check_qual = transformWhereClause(with_check_pstate,
                                                                                   copyObject(stmt->with_check),
-                                                                                  EXPR_KIND_WHERE,
+                                                                                  EXPR_KIND_POLICY,
                                                                                   "POLICY");
 
        /* Fix up collation information */
@@ -707,7 +707,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
                addRTEtoQuery(qual_pstate, rte, false, true, true);
 
                qual = transformWhereClause(qual_pstate, copyObject(stmt->qual),
-                                                                       EXPR_KIND_WHERE,
+                                                                       EXPR_KIND_POLICY,
                                                                        "POLICY");
 
                /* Fix up collation information */
@@ -730,7 +730,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
 
                with_check_qual = transformWhereClause(with_check_pstate,
                                                                                           copyObject(stmt->with_check),
-                                                                                          EXPR_KIND_WHERE,
+                                                                                          EXPR_KIND_POLICY,
                                                                                           "POLICY");
 
                /* Fix up collation information */
index 478d8ca70bdd67e8a2f36dcd739f14e852a72b09..3846b569d6fa4f23b2236be5bae157ff4644155e 100644 (file)
@@ -372,6 +372,13 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr)
                        break;
                case EXPR_KIND_WHERE:
                        errkind = true;
+                       break;
+               case EXPR_KIND_POLICY:
+                       if (isAgg)
+                               err = _("aggregate functions are not allowed in policy expressions");
+                       else
+                               err = _("grouping operations are not allowed in policy expressions");
+
                        break;
                case EXPR_KIND_HAVING:
                        /* okay */
@@ -770,6 +777,9 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc,
                case EXPR_KIND_WHERE:
                        errkind = true;
                        break;
+               case EXPR_KIND_POLICY:
+                       err = _("window functions are not allowed in policy expressions");
+                       break;
                case EXPR_KIND_HAVING:
                        errkind = true;
                        break;
index 0ff46dd457c7938bbd7ad022ea5a5f2cf115eb62..fa77ef1f8bb6a265c0a71c6735495e17a4317c56 100644 (file)
@@ -1672,6 +1672,7 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
                case EXPR_KIND_FROM_SUBSELECT:
                case EXPR_KIND_FROM_FUNCTION:
                case EXPR_KIND_WHERE:
+               case EXPR_KIND_POLICY:
                case EXPR_KIND_HAVING:
                case EXPR_KIND_FILTER:
                case EXPR_KIND_WINDOW_PARTITION:
@@ -3173,6 +3174,8 @@ ParseExprKindName(ParseExprKind exprKind)
                        return "function in FROM";
                case EXPR_KIND_WHERE:
                        return "WHERE";
+               case EXPR_KIND_POLICY:
+                       return "POLICY";
                case EXPR_KIND_HAVING:
                        return "HAVING";
                case EXPR_KIND_FILTER:
index 7ecaffc0dc37d3e8b9310513c6424e87a96fe061..52499453690d92fa7fda16c60bb79f50b98532f8 100644 (file)
@@ -63,7 +63,8 @@ typedef enum ParseExprKind
        EXPR_KIND_INDEX_PREDICATE,      /* index predicate */
        EXPR_KIND_ALTER_COL_TRANSFORM,          /* transform expr in ALTER COLUMN TYPE */
        EXPR_KIND_EXECUTE_PARAMETER,    /* parameter value in EXECUTE */
-       EXPR_KIND_TRIGGER_WHEN          /* WHEN condition in CREATE TRIGGER */
+       EXPR_KIND_TRIGGER_WHEN,         /* WHEN condition in CREATE TRIGGER */
+       EXPR_KIND_POLICY                        /* USING or WITH CHECK expr in policy */
 } ParseExprKind;
 
 
index 61b62d55b4cf948dfbd6ae21340e266c17659702..d76b17ae46a3d05ed0581fe7a5b1f02cc00a1624 100644 (file)
@@ -106,7 +106,7 @@ test_rls_hooks_permissive(CmdType cmdtype, Relation relation)
        e = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (Node *) n, (Node *) c, 0);
 
        policy->qual = (Expr *) transformWhereClause(qual_pstate, copyObject(e),
-                                                                                                EXPR_KIND_WHERE,
+                                                                                                EXPR_KIND_POLICY,
                                                                                                 "POLICY");
 
        policy->with_check_qual = copyObject(policy->qual);
@@ -160,7 +160,7 @@ test_rls_hooks_restrictive(CmdType cmdtype, Relation relation)
        e = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (Node *) n, (Node *) c, 0);
 
        policy->qual = (Expr *) transformWhereClause(qual_pstate, copyObject(e),
-                                                                                                EXPR_KIND_WHERE,
+                                                                                                EXPR_KIND_POLICY,
                                                                                                 "POLICY");
 
        policy->with_check_qual = copyObject(policy->qual);
index b146da373c37a5f89747461bd7b3011e818ffc2e..b0556c2ff1f47654aa06d02c8085cc94c27a4e04 100644 (file)
@@ -3024,6 +3024,15 @@ CREATE RULE "_RETURN" AS ON SELECT TO t DO INSTEAD
   SELECT * FROM generate_series(1,5) t0(c); -- succeeds
 ROLLBACK;
 --
+-- Policy expression handling
+--
+BEGIN;
+SET row_security = FORCE;
+CREATE TABLE t (c) AS VALUES ('bar'::text);
+CREATE POLICY p ON t USING (max(c)); -- fails: aggregate functions are not allowed in policy expressions
+ERROR:  aggregate functions are not allowed in policy expressions
+ROLLBACK;
+--
 -- Clean up objects
 --
 RESET SESSION AUTHORIZATION;
index 54f2c89eda362ce24c47c63d24e28f5a444cbb1b..300f34ad4bf219ade921d081b8dbe7dbd966eaec 100644 (file)
@@ -1289,6 +1289,15 @@ CREATE RULE "_RETURN" AS ON SELECT TO t DO INSTEAD
   SELECT * FROM generate_series(1,5) t0(c); -- succeeds
 ROLLBACK;
 
+--
+-- Policy expression handling
+--
+BEGIN;
+SET row_security = FORCE;
+CREATE TABLE t (c) AS VALUES ('bar'::text);
+CREATE POLICY p ON t USING (max(c)); -- fails: aggregate functions are not allowed in policy expressions
+ROLLBACK;
+
 --
 -- Clean up objects
 --