Alvaro Herrera wrote: > I didn't check the rest of the code, so don't count this as a review.
I had a look at aclchk.c and didn't like your change to objectNamesToOids; seems rather baroque. I changed it per the attached patch. Moreover I didn't very much like the way aclcheck_error_col is dealing with two or one % escapes. I think you should have a separate routine for the column case, and prepend a dummy string to no_priv_msg. Why is there a InternalGrantStmt.rel_level? Doesn't it suffice to check whether col_privs is NIL? Is there enough common code in ExecGrant_Relation to justify the way you have it? Can the common be refactored in a better way that separates the two cases more clearly? -- Alvaro Herrera http://www.CommandPrompt.com/ PostgreSQL Replication, Consulting, Custom Development, 24x7 support
diff -u src/backend/catalog/aclchk.c src/backend/catalog/aclchk.c --- src/backend/catalog/aclchk.c 14 Nov 2008 12:24:15 -0000 +++ src/backend/catalog/aclchk.c 14 Nov 2008 20:46:06 -0000 @@ -55,7 +55,8 @@ static void ExecGrant_Namespace(InternalGrant *grantStmt); static void ExecGrant_Tablespace(InternalGrant *grantStmt); -static List *objectNamesToOids(GrantObjectType objtype, List *objnames, Oid in_relOid); +static List *objectNamesToOids(GrantObjectType objtype, List *objnames); +static List *columnNamesToAttnums(List *colnames, Oid relid); static AclMode string_to_privilege(const char *privname); static const char *privilege_to_string(AclMode privilege); static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions, @@ -264,7 +265,7 @@ */ istmt.is_grant = stmt->is_grant; istmt.objtype = stmt->objtype; - istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects, 0); + istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects); /* all_privs to be filled below */ /* privileges to be filled below */ istmt.col_privs = NIL; @@ -402,23 +403,24 @@ foreach(cell_obj, istmt.objects) { Oid relOid = lfirst_oid(cell_obj); - List *cols_oids = NIL; + List *colnums; ListCell *cell_coloid; /* Get the attribute numbers for this relation for the columns affected */ - cols_oids = objectNamesToOids(ACL_OBJECT_COLUMN, privnode->cols, relOid); + colnums = columnNamesToAttnums(privnode->cols, relOid); /* Loop through the columns listed for this privilege and * add them to the col_privs list of privileges */ - foreach(cell_coloid, cols_oids) + foreach(cell_coloid, colnums) { - ListCell *cell_colprivs; - int found = false; - AttrNumber curr_attnum = lfirst_int(cell_coloid); + AttrNumber curr_attnum = lfirst_int(cell_coloid); + ListCell *cell_colprivs; + int found = false; /* Check if we have already seen this column, and if * so then just add to its aclmask. */ - foreach(cell_colprivs, istmt.col_privs) { + foreach(cell_colprivs, istmt.col_privs) + { ColPrivs *col_privs = (ColPrivs *) lfirst(cell_colprivs); if (col_privs->relOid == relOid && col_privs->attnum == curr_attnum) @@ -487,50 +489,18 @@ * objectNamesToOids * * Turn a list of object names of a given type into an Oid list. - * For columns, turn a list of column names into a list of - * attribute numbers, for a given relation in_relOid. */ static List * -objectNamesToOids(GrantObjectType objtype, List *objnames, Oid in_relOid) +objectNamesToOids(GrantObjectType objtype, List *objnames) { List *objects = NIL; ListCell *cell; Assert(objnames != NIL); + AssertArg(objtype != ACL_OBJECT_COLUMN); switch (objtype) { - case ACL_OBJECT_COLUMN: - foreach(cell, objnames) - { - AttrNumber attnum; - - attnum = get_attnum(in_relOid,strVal(lfirst(cell))); - if (attnum == InvalidAttrNumber) - { - HeapTuple tuple; - Form_pg_class pg_class_tuple; - - tuple = SearchSysCache(RELOID, - ObjectIdGetDatum(in_relOid), - 0, 0, 0); - - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", in_relOid); - - pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple); - - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" of relation %s does not exist.", - strVal(lfirst(cell)), NameStr(pg_class_tuple->relname)))); - - ReleaseSysCache(tuple); - } - - objects = lappend_int(objects, attnum); - } - break; case ACL_OBJECT_RELATION: case ACL_OBJECT_SEQUENCE: foreach(cell, objnames) @@ -647,6 +617,39 @@ } /* + * columnNamesToAttnums + * + * Turn a list of column names into a list of attribute numbers, for the given + * relation. + */ +static List * +columnNamesToAttnums(List *colnames, Oid relid) +{ + ListCell *cell; + List *colnums = NIL; + + foreach(cell, colnames) + { + AttrNumber attnum; + + attnum = get_attnum(relid, strVal(lfirst(cell))); + if (attnum == InvalidAttrNumber) + { + Relation rel = relation_open(relid, AccessShareLock); + + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + strVal(lfirst(cell)), RelationGetRelationName(rel)))); + } + + colnums = lappend_int(colnums, attnum); + } + + return colnums; +} + +/* * This processes both sequences and non-sequences. */ static void
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers