1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-22 23:02:54 +03:00

Add TupleDescGetDefault()

This unifies some repetitive code.

Note: I didn't push the "not found" error message into the new
function, even though all existing callers would be able to make use
of it.  Using the existing error handling as-is would probably require
exposing the Relation type via tupdesc.h, which doesn't seem
desirable.  (Or even if we changed it to just report the OID, it would
inject the concept of a relation containing the tuple descriptor into
tupdesc.h, which might be a layering violation.  Perhaps some further
improvements could be considered here separately.)

Discussion: https://www.postgresql.org/message-id/flat/52a125e4-ff9a-95f5-9f61-b87cf447e4da%40eisentraut.org
This commit is contained in:
Peter Eisentraut 2023-09-27 18:52:40 +01:00
parent 9dce22033d
commit ebf76f2753
5 changed files with 32 additions and 41 deletions

View File

@ -927,3 +927,28 @@ BuildDescFromLists(const List *names, const List *types, const List *typmods, co
return desc;
}
/*
* Get default expression (or NULL if none) for the given attribute number.
*/
Node *
TupleDescGetDefault(TupleDesc tupdesc, AttrNumber attnum)
{
Node *result = NULL;
if (tupdesc->constr)
{
AttrDefault *attrdef = tupdesc->constr->defval;
for (int i = 0; i < tupdesc->constr->num_defval; i++)
{
if (attrdef[i].adnum == attnum)
{
result = stringToNode(attrdef[i].adbin);
break;
}
}
}
return result;
}

View File

@ -2795,22 +2795,9 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
*/
if (attribute->atthasdef)
{
Node *this_default = NULL;
Node *this_default;
/* Find default in constraint structure */
if (constr != NULL)
{
AttrDefault *attrdef = constr->defval;
for (int i = 0; i < constr->num_defval; i++)
{
if (attrdef[i].adnum == parent_attno)
{
this_default = stringToNode(attrdef[i].adbin);
break;
}
}
}
this_default = TupleDescGetDefault(tupleDesc, parent_attno);
if (this_default == NULL)
elog(ERROR, "default expression not found for attribute %d of relation \"%s\"",
parent_attno, RelationGetRelationName(relation));

View File

@ -1358,20 +1358,11 @@ expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause)
(table_like_clause->options & CREATE_TABLE_LIKE_GENERATED) :
(table_like_clause->options & CREATE_TABLE_LIKE_DEFAULTS)))
{
Node *this_default = NULL;
AttrDefault *attrdef = constr->defval;
Node *this_default;
AlterTableCmd *atsubcmd;
bool found_whole_row;
/* Find default in constraint structure */
for (int i = 0; i < constr->num_defval; i++)
{
if (attrdef[i].adnum == parent_attno)
{
this_default = stringToNode(attrdef[i].adbin);
break;
}
}
this_default = TupleDescGetDefault(tupleDesc, parent_attno);
if (this_default == NULL)
elog(ERROR, "default expression not found for attribute %d of relation \"%s\"",
parent_attno, RelationGetRelationName(relation));

View File

@ -1246,21 +1246,7 @@ build_column_default(Relation rel, int attrno)
*/
if (att_tup->atthasdef)
{
if (rd_att->constr && rd_att->constr->num_defval > 0)
{
AttrDefault *defval = rd_att->constr->defval;
int ndef = rd_att->constr->num_defval;
while (--ndef >= 0)
{
if (attrno == defval[ndef].adnum)
{
/* Found it, convert string representation to node tree. */
expr = stringToNode(defval[ndef].adbin);
break;
}
}
}
expr = TupleDescGetDefault(rd_att, attrno);
if (expr == NULL)
elog(ERROR, "default expression not found for attribute %d of relation \"%s\"",
attrno, RelationGetRelationName(rel));

View File

@ -151,4 +151,6 @@ extern TupleDesc BuildDescForRelation(const List *columns);
extern TupleDesc BuildDescFromLists(const List *names, const List *types, const List *typmods, const List *collations);
extern Node *TupleDescGetDefault(TupleDesc tupdesc, AttrNumber attnum);
#endif /* TUPDESC_H */