static void deparseConstraint()

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);
}