/* * get_relid_attribute_name * * Same as above routine get_attname(), except that error * is handled by elog() instead of returning NULL. */ char * get_relid_attribute_name(Oid relid, AttrNumber attnum) { char *attname; attname = get_attname(relid, attnum); if (attname == NULL) elog(ERROR, "cache lookup failed for attribute %d of relation %u", attnum, relid); return attname; }
/* * fixup_inherited_columns * * When user is querying on a table with children, it implicitly accesses * child tables also. So, we also need to check security label of child * tables and columns, but here is no guarantee attribute numbers are * same between the parent ans children. * It returns a bitmapset which contains attribute number of the child * table based on the given bitmapset of the parent. */ static Bitmapset * fixup_inherited_columns(Oid parentId, Oid childId, Bitmapset *columns) { AttrNumber attno; Bitmapset *tmpset; Bitmapset *result = NULL; char *attname; int index; /* * obviously, no need to do anything here */ if (parentId == childId) return columns; tmpset = bms_copy(columns); while ((index = bms_first_member(tmpset)) > 0) { attno = index + FirstLowInvalidHeapAttributeNumber; /* * whole-row-reference shall be fixed-up later */ if (attno == InvalidAttrNumber) { result = bms_add_member(result, index); continue; } attname = get_attname(parentId, attno); if (!attname) elog(ERROR, "cache lookup failed for attribute %d of relation %u", attno, parentId); attno = get_attnum(childId, attname); if (attno == InvalidAttrNumber) elog(ERROR, "cache lookup failed for attribute %s of relation %u", attname, childId); index = attno - FirstLowInvalidHeapAttributeNumber; result = bms_add_member(result, index); pfree(attname); } bms_free(tmpset); return result; }
/* * fixup_inherited_columns * * When user is querying on a table with children, it implicitly accesses * child tables also. So, we also need to check security label of child * tables and columns, but here is no guarantee attribute numbers are * same between the parent ans children. * It returns a bitmapset which contains attribute number of the child * table based on the given bitmapset of the parent. */ static Bitmapset * fixup_inherited_columns(Oid parentId, Oid childId, Bitmapset *columns) { Bitmapset *result = NULL; int index; /* * obviously, no need to do anything here */ if (parentId == childId) return columns; index = -1; while ((index = bms_next_member(columns, index)) >= 0) { /* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */ AttrNumber attno = index + FirstLowInvalidHeapAttributeNumber; char *attname; /* * whole-row-reference shall be fixed-up later */ if (attno == InvalidAttrNumber) { result = bms_add_member(result, index); continue; } attname = get_attname(parentId, attno, false); attno = get_attnum(childId, attname); if (attno == InvalidAttrNumber) elog(ERROR, "cache lookup failed for attribute %s of relation %u", attname, childId); result = bms_add_member(result, attno - FirstLowInvalidHeapAttributeNumber); pfree(attname); } return result; }
/* * create_reference_table accepts a table and then it creates a distributed * table which has one shard and replication factor is set to * shard_replication_factor configuration value. */ Datum create_reference_table(PG_FUNCTION_ARGS) { Oid relationId = PG_GETARG_OID(0); int shardCount = 1; AttrNumber firstColumnAttrNumber = 1; char *firstColumnName = get_attname(relationId, firstColumnAttrNumber); if (firstColumnName == NULL) { char *relationName = get_rel_name(relationId); ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("reference table candidate %s needs to have at" "least one column", relationName))); } CreateHashDistributedTable(relationId, firstColumnName, shardCount, ShardReplicationFactor); PG_RETURN_VOID(); }
/* * sepgsql_attribute_relabel * * It checks privileges to relabel the supplied column * by the `seclabel'. */ void sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum, const char *seclabel) { char *scontext = sepgsql_get_client_label(); char *tcontext; char audit_name[NAMEDATALEN * 2 + 10]; if (get_rel_relkind(relOid) != RELKIND_RELATION) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot set security label on non-regular columns"))); snprintf(audit_name, sizeof(audit_name), "%s.%s", get_rel_name(relOid), get_attname(relOid, attnum)); /* * check db_column:{setattr relabelfrom} permission */ tcontext = sepgsql_get_label(RelationRelationId, relOid, attnum); sepgsql_check_perms(scontext, tcontext, SEPG_CLASS_DB_COLUMN, SEPG_DB_COLUMN__SETATTR | SEPG_DB_COLUMN__RELABELFROM, audit_name, true); pfree(tcontext); /* * check db_column:{relabelto} permission */ sepgsql_check_perms(scontext, seclabel, SEPG_CLASS_DB_COLUMN, SEPG_DB_PROCEDURE__RELABELTO, audit_name, true); }