summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan')
-rw-r--r--src/backend/optimizer/plan/planagg.c2
-rw-r--r--src/backend/optimizer/plan/planner.c37
2 files changed, 36 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index 64605be3178..2ef0bb7f663 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -410,7 +410,7 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo,
parse->limitCount = (Node *) makeConst(INT8OID, -1, InvalidOid,
sizeof(int64),
Int64GetDatum(1), false,
- FLOAT8PASSBYVAL);
+ true);
/*
* Generate the best paths for this query, telling query_planner that we
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index d59d6e4c6a0..0d5a692e5fd 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -58,6 +58,7 @@
#include "parser/parsetree.h"
#include "partitioning/partdesc.h"
#include "rewrite/rewriteManip.h"
+#include "utils/acl.h"
#include "utils/backend_status.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
@@ -838,6 +839,38 @@ subquery_planner(PlannerGlobal *glob, Query *parse, PlannerInfo *parent_root,
}
/*
+ * This would be a convenient time to check access permissions for all
+ * relations mentioned in the query, since it would be better to fail now,
+ * before doing any detailed planning. However, for historical reasons,
+ * we leave this to be done at executor startup.
+ *
+ * Note, however, that we do need to check access permissions for any view
+ * relations mentioned in the query, in order to prevent information being
+ * leaked by selectivity estimation functions, which only check view owner
+ * permissions on underlying tables (see all_rows_selectable() and its
+ * callers). This is a little ugly, because it means that access
+ * permissions for views will be checked twice, which is another reason
+ * why it would be better to do all the ACL checks here.
+ */
+ foreach(l, parse->rtable)
+ {
+ RangeTblEntry *rte = lfirst_node(RangeTblEntry, l);
+
+ if (rte->perminfoindex != 0 &&
+ rte->relkind == RELKIND_VIEW)
+ {
+ RTEPermissionInfo *perminfo;
+ bool result;
+
+ perminfo = getRTEPermissionInfo(parse->rteperminfos, rte);
+ result = ExecCheckOneRelPerms(perminfo);
+ if (!result)
+ aclcheck_error(ACLCHECK_NO_PRIV, OBJECT_VIEW,
+ get_rel_name(perminfo->relid));
+ }
+ }
+
+ /*
* Preprocess RowMark information. We need to do this after subquery
* pullup, so that all base relations are present.
*/
@@ -4882,7 +4915,7 @@ create_partial_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel,
limitCount = (Node *) makeConst(INT8OID, -1, InvalidOid,
sizeof(int64),
Int64GetDatum(1), false,
- FLOAT8PASSBYVAL);
+ true);
/*
* Apply a LimitPath onto the partial path to restrict the
@@ -5085,7 +5118,7 @@ create_final_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel,
limitCount = (Node *) makeConst(INT8OID, -1, InvalidOid,
sizeof(int64),
Int64GetDatum(1), false,
- FLOAT8PASSBYVAL);
+ true);
/*
* If the query already has a LIMIT clause, then we could