in ext/pg_query/pg_query_deparse.c [4112:4326]
static void deparseConstraint(StringInfo str, Constraint *constraint)
{
ListCell *lc;
if (constraint->conname != NULL)
{
appendStringInfoString(str, "CONSTRAINT ");
appendStringInfoString(str, constraint->conname);
appendStringInfoChar(str, ' ');
}
switch (constraint->contype) {
case CONSTR_NULL:
appendStringInfoString(str, "NULL ");
break;
case CONSTR_NOTNULL:
appendStringInfoString(str, "NOT NULL ");
break;
case CONSTR_DEFAULT:
appendStringInfoString(str, "DEFAULT ");
deparseExpr(str, constraint->raw_expr);
break;
case CONSTR_IDENTITY:
appendStringInfoString(str, "GENERATED ");
switch (constraint->generated_when)
{
case ATTRIBUTE_IDENTITY_ALWAYS:
appendStringInfoString(str, "ALWAYS ");
break;
case ATTRIBUTE_IDENTITY_BY_DEFAULT:
appendStringInfoString(str, "BY DEFAULT ");
break;
default:
Assert(false);
}
appendStringInfoString(str, "AS IDENTITY ");
deparseOptParenthesizedSeqOptList(str, constraint->options);
break;
case CONSTR_GENERATED:
Assert(constraint->generated_when == ATTRIBUTE_IDENTITY_ALWAYS);
appendStringInfoString(str, "GENERATED ALWAYS AS (");
deparseExpr(str, constraint->raw_expr);
appendStringInfoString(str, ") STORED ");
break;
case CONSTR_CHECK:
appendStringInfoString(str, "CHECK (");
deparseExpr(str, constraint->raw_expr);
appendStringInfoString(str, ") ");
break;
case CONSTR_PRIMARY:
appendStringInfoString(str, "PRIMARY KEY ");
break;
case CONSTR_UNIQUE:
appendStringInfoString(str, "UNIQUE ");
break;
case CONSTR_EXCLUSION:
appendStringInfoString(str, "EXCLUDE ");
if (strcmp(constraint->access_method, DEFAULT_INDEX_TYPE) != 0)
{
appendStringInfoString(str, "USING ");
appendStringInfoString(str, quote_identifier(constraint->access_method));
appendStringInfoChar(str, ' ');
}
appendStringInfoChar(str, '(');
foreach(lc, constraint->exclusions)
{
List *exclusion = castNode(List, lfirst(lc));
Assert(list_length(exclusion) == 2);
deparseIndexElem(str, castNode(IndexElem, linitial(exclusion)));
appendStringInfoString(str, " WITH ");
deparseAnyOperator(str, castNode(List, lsecond(exclusion)));
if (lnext(constraint->exclusions, lc))
appendStringInfoString(str, ", ");
}
appendStringInfoString(str, ") ");
if (constraint->where_clause != NULL)
{
appendStringInfoString(str, "WHERE (");
deparseExpr(str, constraint->where_clause);
appendStringInfoString(str, ") ");
}
break;
case CONSTR_FOREIGN:
if (list_length(constraint->fk_attrs) > 0)
appendStringInfoString(str, "FOREIGN KEY ");
break;
case CONSTR_ATTR_DEFERRABLE:
appendStringInfoString(str, "DEFERRABLE ");
break;
case CONSTR_ATTR_NOT_DEFERRABLE:
appendStringInfoString(str, "NOT DEFERRABLE ");
break;
case CONSTR_ATTR_DEFERRED:
appendStringInfoString(str, "INITIALLY DEFERRED ");
break;
case CONSTR_ATTR_IMMEDIATE:
appendStringInfoString(str, "INITIALLY IMMEDIATE ");
break;
}
if (list_length(constraint->keys) > 0)
{
appendStringInfoChar(str, '(');
deparseColumnList(str, constraint->keys);
appendStringInfoString(str, ") ");
}
if (list_length(constraint->fk_attrs) > 0)
{
appendStringInfoChar(str, '(');
deparseColumnList(str, constraint->fk_attrs);
appendStringInfoString(str, ") ");
}
if (constraint->pktable != NULL)
{
appendStringInfoString(str, "REFERENCES ");
deparseRangeVar(str, constraint->pktable, DEPARSE_NODE_CONTEXT_NONE);
appendStringInfoChar(str, ' ');
if (list_length(constraint->pk_attrs) > 0)
{
appendStringInfoChar(str, '(');
deparseColumnList(str, constraint->pk_attrs);
appendStringInfoString(str, ") ");
}
}
switch (constraint->fk_matchtype)
{
case FKCONSTR_MATCH_SIMPLE:
// Default
break;
case FKCONSTR_MATCH_FULL:
appendStringInfoString(str, "MATCH FULL ");
break;
case FKCONSTR_MATCH_PARTIAL:
// Not implemented in Postgres
Assert(false);
break;
default:
// Not specified
break;
}
switch (constraint->fk_upd_action)
{
case FKCONSTR_ACTION_NOACTION:
// Default
break;
case FKCONSTR_ACTION_RESTRICT:
appendStringInfoString(str, "ON UPDATE RESTRICT ");
break;
case FKCONSTR_ACTION_CASCADE:
appendStringInfoString(str, "ON UPDATE CASCADE ");
break;
case FKCONSTR_ACTION_SETNULL:
appendStringInfoString(str, "ON UPDATE SET NULL ");
break;
case FKCONSTR_ACTION_SETDEFAULT:
appendStringInfoString(str, "ON UPDATE SET DEFAULT ");
break;
default:
// Not specified
break;
}
switch (constraint->fk_del_action)
{
case FKCONSTR_ACTION_NOACTION:
// Default
break;
case FKCONSTR_ACTION_RESTRICT:
appendStringInfoString(str, "ON DELETE RESTRICT ");
break;
case FKCONSTR_ACTION_CASCADE:
appendStringInfoString(str, "ON DELETE CASCADE ");
break;
case FKCONSTR_ACTION_SETNULL:
appendStringInfoString(str, "ON DELETE SET NULL ");
break;
case FKCONSTR_ACTION_SETDEFAULT:
appendStringInfoString(str, "ON DELETE SET DEFAULT ");
break;
default:
// Not specified
break;
}
if (list_length(constraint->including) > 0)
{
appendStringInfoString(str, "INCLUDE (");
deparseColumnList(str, constraint->including);
appendStringInfoString(str, ") ");
}
if (constraint->indexname != NULL)
appendStringInfo(str, "USING INDEX %s ", quote_identifier(constraint->indexname));
if (constraint->indexspace != NULL)
appendStringInfo(str, "USING INDEX TABLESPACE %s ", quote_identifier(constraint->indexspace));
if (constraint->deferrable)
appendStringInfoString(str, "DEFERRABLE ");
if (constraint->initdeferred)
appendStringInfoString(str, "INITIALLY DEFERRED ");
if (constraint->is_no_inherit)
appendStringInfoString(str, "NO INHERIT ");
if (constraint->skip_validation)
appendStringInfoString(str, "NOT VALID ");
removeTrailingSpace(str);
}