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
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;
+}
*/
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));
(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));
*/
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));
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 */