The initial patch for RLS mistakenly included headers associated with
the executor and planner bits in rewrite/rowsecurity.h. Per policy and
general good sense, executor headers should not be included in planner
headers or vice versa.
The include of execnodes.h was a mistaken holdover from previous
versions, while the include of relation.h was used for Relation's
definition, which should have been coming from utils/relcache.h. This
patch cleans these issues up, adds comments to the RowSecurityPolicy
struct and the RowSecurityConfigType enum, and changes Relation->rsdesc
to Relation->rd_rsdesc to follow Relation field naming convention.
Additionally, utils/rel.h was including rewrite/rowsecurity.h, which
wasn't a great idea since that was pulling in things not really needed
in utils/rel.h (which gets included in quite a few places). Instead,
use 'struct RowSecurityDesc' for the rd_rsdesc field and add comments
explaining why.
Lastly, add an include into access/nbtree/nbtsort.c for
utils/sortsupport.h, which was evidently missed due to the above mess.
Pointed out by Tom in 16970.
1415838651@sss.pgh.pa.us; note that the
concerns regarding a similar situation in the custom-path commit still
need to be addressed.
#include "storage/smgr.h"
#include "tcop/tcopprot.h"
#include "utils/rel.h"
+#include "utils/sortsupport.h"
#include "utils/tuplesort.h"
#include "parser/parse_clause.h"
#include "parser/parse_node.h"
#include "parser/parse_relation.h"
+#include "rewrite/rowsecurity.h"
#include "storage/lock.h"
#include "utils/acl.h"
#include "utils/array.h"
systable_endscan(sscan);
heap_close(catalog, AccessShareLock);
- relation->rsdesc = rsdesc;
+ relation->rd_rsdesc = rsdesc;
}
/*
* There must always be at least one policy defined (may be the simple
* 'default-deny' policy, if none are explicitly defined on the table).
*/
- foreach(item, relation->rsdesc->policies)
+ foreach(item, relation->rd_rsdesc->policies)
{
policy = (RowSecurityPolicy *) lfirst(item);
#include "optimizer/prep.h"
#include "optimizer/var.h"
#include "rewrite/rewriteDefine.h"
+#include "rewrite/rowsecurity.h"
#include "storage/lmgr.h"
#include "storage/smgr.h"
#include "utils/array.h"
if (relation->rd_rel->relrowsecurity)
RelationBuildRowSecurity(relation);
else
- relation->rsdesc = NULL;
+ relation->rd_rsdesc = NULL;
/*
* if it's an index, initialize index-related information
MemoryContextDelete(relation->rd_indexcxt);
if (relation->rd_rulescxt)
MemoryContextDelete(relation->rd_rulescxt);
- if (relation->rsdesc)
- MemoryContextDelete(relation->rsdesc->rscxt);
+ if (relation->rd_rsdesc)
+ MemoryContextDelete(relation->rd_rsdesc->rscxt);
if (relation->rd_fdwroutine)
pfree(relation->rd_fdwroutine);
pfree(relation);
keep_tupdesc = equalTupleDescs(relation->rd_att, newrel->rd_att);
keep_rules = equalRuleLocks(relation->rd_rules, newrel->rd_rules);
- keep_policies = equalRSDesc(relation->rsdesc, newrel->rsdesc);
+ keep_policies = equalRSDesc(relation->rd_rsdesc, newrel->rd_rsdesc);
/*
* Perform swapping of the relcache entry contents. Within this
SWAPFIELD(MemoryContext, rd_rulescxt);
}
if (keep_policies)
- SWAPFIELD(RowSecurityDesc *, rsdesc);
+ SWAPFIELD(RowSecurityDesc *, rd_rsdesc);
/* toast OID override must be preserved */
SWAPFIELD(Oid, rd_toastoid);
/* pgstat_info must be preserved */
* RelationBuildRowSecurity will create a single default-deny policy
* if there is no policy defined in pg_rowsecurity.
*/
- if (relation->rd_rel->relrowsecurity && relation->rsdesc == NULL)
+ if (relation->rd_rel->relrowsecurity && relation->rd_rsdesc == NULL)
{
RelationBuildRowSecurity(relation);
- Assert (relation->rsdesc != NULL);
+ Assert (relation->rd_rsdesc != NULL);
restart = true;
}
rel->rd_rules = NULL;
rel->rd_rulescxt = NULL;
rel->trigdesc = NULL;
- rel->rsdesc = NULL;
+ rel->rd_rsdesc = NULL;
rel->rd_indexprs = NIL;
rel->rd_indpred = NIL;
rel->rd_exclops = NULL;
/* -------------------------------------------------------------------------
*
* rowsecurity.h
- * prototypes for optimizer/rowsecurity.c
+ *
+ * prototypes for rewrite/rowsecurity.c and the structures for managing
+ * the row security policies for relations in relcache.
*
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
#ifndef ROWSECURITY_H
#define ROWSECURITY_H
-#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
-#include "nodes/relation.h"
#include "utils/array.h"
+#include "utils/relcache.h"
typedef struct RowSecurityPolicy
{
- Oid rsecid;
- char *policy_name;
- char cmd;
- ArrayType *roles;
- Expr *qual;
- Expr *with_check_qual;
- bool hassublinks;
+ Oid rsecid; /* OID of the policy */
+ char *policy_name; /* Name of the policy */
+ char cmd; /* Type of command policy is for */
+ ArrayType *roles; /* Array of roles policy is for */
+ Expr *qual; /* Expression to filter rows */
+ Expr *with_check_qual; /* Expression to limit rows allowed */
+ bool hassublinks; /* If expression has sublinks */
} RowSecurityPolicy;
typedef struct RowSecurityDesc
/* Possible values for row_security GUC */
typedef enum RowSecurityConfigType
{
- ROW_SECURITY_OFF,
- ROW_SECURITY_ON,
- ROW_SECURITY_FORCE
+ ROW_SECURITY_OFF, /* RLS never applied- error thrown if no priv */
+ ROW_SECURITY_ON, /* normal case, RLS applied for regular users */
+ ROW_SECURITY_FORCE /* RLS applied for superusers and table owners */
} RowSecurityConfigType;
/*
#include "fmgr.h"
#include "nodes/bitmapset.h"
#include "rewrite/prs2lock.h"
-#include "rewrite/rowsecurity.h"
#include "storage/block.h"
#include "storage/relfilenode.h"
#include "utils/relcache.h"
RuleLock *rd_rules; /* rewrite rules */
MemoryContext rd_rulescxt; /* private memory cxt for rd_rules, if any */
TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none */
- RowSecurityDesc *rsdesc; /* Row-security policy, or NULL */
+ /* use "struct" here to avoid needing to include rowsecurity.h: */
+ struct RowSecurityDesc *rd_rsdesc; /* Row-security policies, or NULL */
/* data managed by RelationGetIndexList: */
List *rd_indexlist; /* list of OIDs of indexes on relation */