From a2536f8ae002bde4338fcf4fa04c248c5630475d Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 4 Aug 2017 10:12:25 +0200 Subject: [PATCH 1/4] Refactor syscache routines to get attribute name The existing routines are merged, and a missing_ok argument to return a NULL result instead of an error is added to give more control to the user. This unified interface will get used for object addresses. --- contrib/postgres_fdw/deparse.c | 2 +- contrib/postgres_fdw/postgres_fdw.c | 2 +- contrib/sepgsql/dml.c | 2 +- src/backend/catalog/heap.c | 3 ++- src/backend/catalog/objectaddress.c | 10 ++++++---- src/backend/parser/parse_relation.c | 2 +- src/backend/parser/parse_utilcmd.c | 11 ++++++----- src/backend/utils/adt/ruleutils.c | 28 ++++++++++++++++------------ src/backend/utils/cache/lsyscache.c | 27 +++++++-------------------- src/backend/utils/cache/relcache.c | 2 +- src/include/utils/lsyscache.h | 3 +-- 11 files changed, 43 insertions(+), 49 deletions(-) diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c index 96f804a28d..b1bce61f2c 100644 --- a/contrib/postgres_fdw/deparse.c +++ b/contrib/postgres_fdw/deparse.c @@ -2026,7 +2026,7 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, * FDW option, use attribute name. */ if (colname == NULL) - colname = get_relid_attribute_name(rte->relid, varattno); + colname = get_attname(rte->relid, varattno, false); if (qualify_col) ADD_REL_QUALIFIER(buf, varno); diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index c6e1211f8f..469e83a023 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -5128,7 +5128,7 @@ conversion_error_callback(void *arg) if (var->varattno == 0) is_wholerow = true; else - attname = get_relid_attribute_name(rte->relid, var->varattno); + attname = get_attname(rte->relid, var->varattno, false); relname = get_rel_name(rte->relid); } diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c index 36cdb27a76..10f65a071e 100644 --- a/contrib/sepgsql/dml.c +++ b/contrib/sepgsql/dml.c @@ -118,7 +118,7 @@ fixup_inherited_columns(Oid parentId, Oid childId, Bitmapset *columns) continue; } - attname = get_attname(parentId, attno); + attname = get_attname(parentId, attno, true); if (!attname) elog(ERROR, "cache lookup failed for attribute %d of relation %u", attno, parentId); diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 089b7965f2..0896079934 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -2404,7 +2404,8 @@ AddRelationNewConstraints(Relation rel, if (list_length(vars) == 1) colname = get_attname(RelationGetRelid(rel), - ((Var *) linitial(vars))->varattno); + ((Var *) linitial(vars))->varattno, + true); else colname = NULL; diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index bc999ca3c4..29147feb6b 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -2671,8 +2671,9 @@ getObjectDescription(const ObjectAddress *object) getRelationDescription(&buffer, object->objectId); if (object->objectSubId != 0) appendStringInfo(&buffer, _(" column %s"), - get_relid_attribute_name(object->objectId, - object->objectSubId)); + get_attname(object->objectId, + object->objectSubId, + false)); break; case OCLASS_PROC: @@ -4090,8 +4091,9 @@ getObjectIdentityParts(const ObjectAddress *object, { char *attr; - attr = get_relid_attribute_name(object->objectId, - object->objectSubId); + attr = get_attname(object->objectId, + object->objectSubId, + false); appendStringInfo(&buffer, ".%s", quote_identifier(attr)); if (objname) *objname = lappend(*objname, attr); diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 2625da5327..053ae02c9f 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -2687,7 +2687,7 @@ get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum) * built (which can easily happen for rules). */ if (rte->rtekind == RTE_RELATION) - return get_relid_attribute_name(rte->relid, attnum); + return get_attname(rte->relid, attnum, false); /* * Otherwise use the column name from eref. There should always be one. diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 128f1679c6..cd505a76f4 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -1458,7 +1458,7 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx, /* Simple index column */ char *attname; - attname = get_relid_attribute_name(indrelid, attnum); + attname = get_attname(indrelid, attnum, false); keycoltype = get_atttype(indrelid, attnum); iparam->name = attname; @@ -3373,8 +3373,9 @@ transformPartitionBound(ParseState *pstate, Relation parent, /* Get the only column's name in case we need to output an error */ if (key->partattrs[0] != 0) - colname = get_relid_attribute_name(RelationGetRelid(parent), - key->partattrs[0]); + colname = get_attname(RelationGetRelid(parent), + key->partattrs[0], + false); else colname = deparse_expression((Node *) linitial(partexprs), deparse_context_for(RelationGetRelationName(parent), @@ -3458,8 +3459,8 @@ transformPartitionBound(ParseState *pstate, Relation parent, /* Get the column's name in case we need to output an error */ if (key->partattrs[i] != 0) - colname = get_relid_attribute_name(RelationGetRelid(parent), - key->partattrs[i]); + colname = get_attname(RelationGetRelid(parent), + key->partattrs[i], false); else { colname = deparse_expression((Node *) list_nth(partexprs, j), diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9cdbb06add..617d024144 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -908,8 +908,9 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty) if (i > 0) appendStringInfoString(&buf, ", "); - attname = get_relid_attribute_name(trigrec->tgrelid, - trigrec->tgattr.values[i]); + attname = get_attname(trigrec->tgrelid, + trigrec->tgattr.values[i], + false); appendStringInfoString(&buf, quote_identifier(attname)); } } @@ -1290,7 +1291,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, char *attname; int32 keycoltypmod; - attname = get_relid_attribute_name(indrelid, attnum); + attname = get_attname(indrelid, attnum, false); if (!colno || colno == keyno + 1) appendStringInfoString(&buf, quote_identifier(attname)); get_atttypetypmodcoll(indrelid, attnum, @@ -1533,7 +1534,7 @@ pg_get_statisticsobj_worker(Oid statextid, bool missing_ok) if (colno > 0) appendStringInfoString(&buf, ", "); - attname = get_relid_attribute_name(statextrec->stxrelid, attnum); + attname = get_attname(statextrec->stxrelid, attnum, false); appendStringInfoString(&buf, quote_identifier(attname)); } @@ -1690,7 +1691,7 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags, char *attname; int32 keycoltypmod; - attname = get_relid_attribute_name(relid, attnum); + attname = get_attname(relid, attnum, false); appendStringInfoString(&buf, quote_identifier(attname)); get_atttypetypmodcoll(relid, attnum, &keycoltype, &keycoltypmod, @@ -2193,7 +2194,7 @@ decompile_column_index_array(Datum column_index_array, Oid relId, { char *colName; - colName = get_relid_attribute_name(relId, DatumGetInt16(keys[j])); + colName = get_attname(relId, DatumGetInt16(keys[j]), false); if (j == 0) appendStringInfoString(buf, quote_identifier(colName)); @@ -6004,8 +6005,9 @@ get_insert_query_def(Query *query, deparse_context *context) * tle->resname, since resname will fail to track RENAME. */ appendStringInfoString(buf, - quote_identifier(get_relid_attribute_name(rte->relid, - tle->resno))); + quote_identifier(get_attname(rte->relid, + tle->resno, + false))); /* * Print any indirection needed (subfields or subscripts), and strip @@ -6308,8 +6310,9 @@ get_update_query_targetlist_def(Query *query, List *targetList, * tle->resname, since resname will fail to track RENAME. */ appendStringInfoString(buf, - quote_identifier(get_relid_attribute_name(rte->relid, - tle->resno))); + quote_identifier(get_attname(rte->relid, + tle->resno, + false))); /* * Print any indirection needed (subfields or subscripts), and strip @@ -10329,8 +10332,9 @@ processIndirection(Node *node, deparse_context *context) * target lists, but this function cannot be used for that case. */ Assert(list_length(fstore->fieldnums) == 1); - fieldname = get_relid_attribute_name(typrelid, - linitial_int(fstore->fieldnums)); + fieldname = get_attname(typrelid, + linitial_int(fstore->fieldnums), + false); appendStringInfo(buf, ".%s", quote_identifier(fieldname)); /* diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index e8aa179347..21e390336e 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -768,10 +768,11 @@ get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum) * Given the relation id and the attribute number, * return the "attname" field from the attribute relation. * - * Note: returns a palloc'd copy of the string, or NULL if no such attribute. + * Note: returns a palloc'd copy of the string. In the event if an error, + * return NULL if missing_ok is true. */ char * -get_attname(Oid relid, AttrNumber attnum) +get_attname(Oid relid, AttrNumber attnum, bool missing_ok) { HeapTuple tp; @@ -787,26 +788,12 @@ get_attname(Oid relid, AttrNumber attnum) ReleaseSysCache(tp); return result; } - else - return NULL; -} -/* - * 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; + if (missing_ok) + return NULL; - attname = get_attname(relid, attnum); - if (attname == NULL) - elog(ERROR, "cache lookup failed for attribute %d of relation %u", - attnum, relid); - return attname; + elog(ERROR, "cache lookup failed for attribute %d of relation %u", + attnum, relid); } /* diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 00ba33bfb4..2a1f612a78 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -5236,7 +5236,7 @@ errtablecol(Relation rel, int attnum) if (attnum > 0 && attnum <= reldesc->natts) colname = NameStr(TupleDescAttr(reldesc, attnum - 1)->attname); else - colname = get_relid_attribute_name(RelationGetRelid(rel), attnum); + colname = get_attname(RelationGetRelid(rel), attnum, false); return errtablecolname(rel, colname); } diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index 9731e6f7ae..1f6c04a8f3 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -83,8 +83,7 @@ extern List *get_op_btree_interpretation(Oid opno); extern bool equality_ops_are_compatible(Oid opno1, Oid opno2); extern Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum); -extern char *get_attname(Oid relid, AttrNumber attnum); -extern char *get_relid_attribute_name(Oid relid, AttrNumber attnum); +extern char *get_attname(Oid relid, AttrNumber attnum, bool missing_ok); extern AttrNumber get_attnum(Oid relid, const char *attname); extern char get_attidentity(Oid relid, AttrNumber attnum); extern Oid get_atttype(Oid relid, AttrNumber attnum); -- 2.15.1