aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_utilcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r--src/backend/parser/parse_utilcmd.c311
1 files changed, 242 insertions, 69 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 23c60eec318..10f52954c11 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -65,6 +65,7 @@
/* State shared by transformCreateStmt and its subroutines */
typedef struct
{
+ ParseState *pstate; /* overall parser state */
const char *stmtType; /* "CREATE [FOREIGN] TABLE" or "ALTER TABLE" */
RangeVar *relation; /* relation to create */
Relation rel; /* opened/locked rel, if ALTER */
@@ -98,30 +99,27 @@ typedef struct
} CreateSchemaStmtContext;
-static void transformColumnDefinition(ParseState *pstate,
- CreateStmtContext *cxt,
+static void transformColumnDefinition(CreateStmtContext *cxt,
ColumnDef *column);
-static void transformTableConstraint(ParseState *pstate,
- CreateStmtContext *cxt,
+static void transformTableConstraint(CreateStmtContext *cxt,
Constraint *constraint);
-static void transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
+static void transformInhRelation(CreateStmtContext *cxt,
InhRelation *inhrelation);
-static void transformOfType(ParseState *pstate, CreateStmtContext *cxt,
+static void transformOfType(CreateStmtContext *cxt,
TypeName *ofTypename);
static char *chooseIndexName(const RangeVar *relation, IndexStmt *index_stmt);
static IndexStmt *generateClonedIndexStmt(CreateStmtContext *cxt,
Relation parent_index, AttrNumber *attmap);
static List *get_opclass(Oid opclass, Oid actual_datatype);
-static void transformIndexConstraints(ParseState *pstate,
- CreateStmtContext *cxt);
+static void transformIndexConstraints(CreateStmtContext *cxt);
static IndexStmt *transformIndexConstraint(Constraint *constraint,
CreateStmtContext *cxt);
-static void transformFKConstraints(ParseState *pstate,
- CreateStmtContext *cxt,
+static void transformFKConstraints(CreateStmtContext *cxt,
bool skipValidation,
bool isAddConstraint);
-static void transformConstraintAttrs(ParseState *pstate, List *constraintList);
-static void transformColumnType(ParseState *pstate, ColumnDef *column);
+static void transformConstraintAttrs(CreateStmtContext *cxt,
+ List *constraintList);
+static void transformColumnType(CreateStmtContext *cxt, ColumnDef *column);
static void setSchemaName(char *context_schema, char **stmt_schema_name);
@@ -169,10 +167,11 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
stmt->relation->schemaname = get_namespace_name(namespaceid);
}
- /* Set up pstate */
+ /* Set up pstate and CreateStmtContext */
pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString;
+ cxt.pstate = pstate;
if (IsA(stmt, CreateForeignTableStmt))
cxt.stmtType = "CREATE FOREIGN TABLE";
else
@@ -194,7 +193,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
Assert(!stmt->ofTypename || !stmt->inhRelations); /* grammar enforces */
if (stmt->ofTypename)
- transformOfType(pstate, &cxt, stmt->ofTypename);
+ transformOfType(&cxt, stmt->ofTypename);
/*
* Run through each primary element in the table creation clause. Separate
@@ -207,18 +206,15 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
switch (nodeTag(element))
{
case T_ColumnDef:
- transformColumnDefinition(pstate, &cxt,
- (ColumnDef *) element);
+ transformColumnDefinition(&cxt, (ColumnDef *) element);
break;
case T_Constraint:
- transformTableConstraint(pstate, &cxt,
- (Constraint *) element);
+ transformTableConstraint(&cxt, (Constraint *) element);
break;
case T_InhRelation:
- transformInhRelation(pstate, &cxt,
- (InhRelation *) element);
+ transformInhRelation(&cxt, (InhRelation *) element);
break;
default:
@@ -240,12 +236,12 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
/*
* Postprocess constraints that give rise to index definitions.
*/
- transformIndexConstraints(pstate, &cxt);
+ transformIndexConstraints(&cxt);
/*
* Postprocess foreign-key constraints.
*/
- transformFKConstraints(pstate, &cxt, true, false);
+ transformFKConstraints(&cxt, true, false);
/*
* Output results.
@@ -266,8 +262,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
* Also used in ALTER TABLE ADD COLUMN
*/
static void
-transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
- ColumnDef *column)
+transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
{
bool is_serial;
bool saw_nullable;
@@ -309,12 +304,13 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("array of serial is not implemented"),
- parser_errposition(pstate, column->typeName->location)));
+ parser_errposition(cxt->pstate,
+ column->typeName->location)));
}
/* Do necessary work on the column type declaration */
if (column->typeName)
- transformColumnType(pstate, column);
+ transformColumnType(cxt, column);
/* Special actions for SERIAL pseudo-types */
if (is_serial)
@@ -437,7 +433,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
}
/* Process column constraints, if any... */
- transformConstraintAttrs(pstate, column->constraints);
+ transformConstraintAttrs(cxt, column->constraints);
saw_nullable = false;
saw_default = false;
@@ -455,7 +451,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
- parser_errposition(pstate,
+ parser_errposition(cxt->pstate,
constraint->location)));
column->is_not_null = FALSE;
saw_nullable = true;
@@ -467,7 +463,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
- parser_errposition(pstate,
+ parser_errposition(cxt->pstate,
constraint->location)));
column->is_not_null = TRUE;
saw_nullable = true;
@@ -479,7 +475,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("multiple default values specified for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
- parser_errposition(pstate,
+ parser_errposition(cxt->pstate,
constraint->location)));
column->raw_default = constraint->raw_expr;
Assert(constraint->cooked_expr == NULL);
@@ -532,8 +528,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
* transform a Constraint node within CREATE TABLE or ALTER TABLE
*/
static void
-transformTableConstraint(ParseState *pstate, CreateStmtContext *cxt,
- Constraint *constraint)
+transformTableConstraint(CreateStmtContext *cxt, Constraint *constraint)
{
switch (constraint->contype)
{
@@ -577,8 +572,7 @@ transformTableConstraint(ParseState *pstate, CreateStmtContext *cxt,
* <subtable>.
*/
static void
-transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
- InhRelation *inhRelation)
+transformInhRelation(CreateStmtContext *cxt, InhRelation *inhRelation)
{
AttrNumber parent_attno;
Relation relation;
@@ -587,7 +581,8 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
AclResult aclresult;
char *comment;
- relation = parserOpenTable(pstate, inhRelation->relation, AccessShareLock);
+ relation = parserOpenTable(cxt->pstate, inhRelation->relation,
+ AccessShareLock);
if (relation->rd_rel->relkind != RELKIND_RELATION)
ereport(ERROR,
@@ -816,7 +811,7 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
}
static void
-transformOfType(ParseState *pstate, CreateStmtContext *cxt, TypeName *ofTypename)
+transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
{
HeapTuple tuple;
Form_pg_type typ;
@@ -937,6 +932,7 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
index->tableSpace = get_tablespace_name(idxrelrec->reltablespace);
else
index->tableSpace = NULL;
+ index->indexOid = InvalidOid;
index->unique = idxrec->indisunique;
index->primary = idxrec->indisprimary;
index->concurrent = false;
@@ -1181,7 +1177,7 @@ get_opclass(Oid opclass, Oid actual_datatype)
* LIKE ... INCLUDING INDEXES.
*/
static void
-transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
+transformIndexConstraints(CreateStmtContext *cxt)
{
IndexStmt *index;
List *indexlist = NIL;
@@ -1304,7 +1300,8 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("multiple primary keys for table \"%s\" are not allowed",
- cxt->relation->relname)));
+ cxt->relation->relname),
+ parser_errposition(cxt->pstate, constraint->location)));
cxt->pkey = index;
/*
@@ -1328,9 +1325,183 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
index->whereClause = constraint->where_clause;
index->indexParams = NIL;
index->excludeOpNames = NIL;
+ index->indexOid = InvalidOid;
index->concurrent = false;
/*
+ * If it's ALTER TABLE ADD CONSTRAINT USING INDEX, look up the index and
+ * verify it's usable, then extract the implied column name list. (We
+ * will not actually need the column name list at runtime, but we need
+ * it now to check for duplicate column entries below.)
+ */
+ if (constraint->indexname != NULL)
+ {
+ char *index_name = constraint->indexname;
+ Relation heap_rel = cxt->rel;
+ Oid index_oid;
+ Relation index_rel;
+ Form_pg_index index_form;
+ oidvector *indclass;
+ Datum indclassDatum;
+ bool isnull;
+ int i;
+
+ /* Grammar should not allow this with explicit column list */
+ Assert(constraint->keys == NIL);
+
+ /* Grammar should only allow PRIMARY and UNIQUE constraints */
+ Assert(constraint->contype == CONSTR_PRIMARY ||
+ constraint->contype == CONSTR_UNIQUE);
+
+ /* Must be ALTER, not CREATE, but grammar doesn't enforce that */
+ if (!cxt->isalter)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot use an existing index in CREATE TABLE"),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ /* Look for the index in the same schema as the table */
+ index_oid = get_relname_relid(index_name, RelationGetNamespace(heap_rel));
+
+ if (!OidIsValid(index_oid))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("index \"%s\" does not exist", index_name),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ /* Open the index (this will throw an error if it is not an index) */
+ index_rel = index_open(index_oid, AccessShareLock);
+ index_form = index_rel->rd_index;
+
+ /* Check that it does not have an associated constraint already */
+ if (OidIsValid(get_index_constraint(index_oid)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("index \"%s\" is already associated with a constraint",
+ index_name),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ /* Perform validity checks on the index */
+ if (index_form->indrelid != RelationGetRelid(heap_rel))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("index \"%s\" does not belong to table \"%s\"",
+ index_name, RelationGetRelationName(heap_rel)),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ if (!index_form->indisvalid)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("index \"%s\" is not valid", index_name),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ if (!index_form->indisready)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("index \"%s\" is not ready", index_name),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ if (!index_form->indisunique)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a unique index", index_name),
+ errdetail("Cannot create a PRIMARY KEY or UNIQUE constraint using such an index."),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ if (RelationGetIndexExpressions(index_rel) != NIL)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("index \"%s\" contains expressions", index_name),
+ errdetail("Cannot create a PRIMARY KEY or UNIQUE constraint using such an index."),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ if (RelationGetIndexPredicate(index_rel) != NIL)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a partial index", index_name),
+ errdetail("Cannot create a PRIMARY KEY or UNIQUE constraint using such an index."),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ /*
+ * It's probably unsafe to change a deferred index to non-deferred.
+ * (A non-constraint index couldn't be deferred anyway, so this case
+ * should never occur; no need to sweat, but let's check it.)
+ */
+ if (!index_form->indimmediate && !constraint->deferrable)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a deferrable index", index_name),
+ errdetail("Cannot create a non-deferrable constraint using a deferrable index."),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ /*
+ * Insist on it being a btree. That's the only kind that supports
+ * uniqueness at the moment anyway; but we must have an index that
+ * exactly matches what you'd get from plain ADD CONSTRAINT syntax,
+ * else dump and reload will produce a different index (breaking
+ * pg_upgrade in particular).
+ */
+ if (index_rel->rd_rel->relam != get_am_oid(DEFAULT_INDEX_TYPE, false))
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("index \"%s\" is not a b-tree", index_name),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ /* Must get indclass the hard way */
+ indclassDatum = SysCacheGetAttr(INDEXRELID, index_rel->rd_indextuple,
+ Anum_pg_index_indclass, &isnull);
+ Assert(!isnull);
+ indclass = (oidvector *) DatumGetPointer(indclassDatum);
+
+ for (i = 0; i < index_form->indnatts; i++)
+ {
+ int2 attnum = index_form->indkey.values[i];
+ Form_pg_attribute attform;
+ char *attname;
+ Oid defopclass;
+
+ /*
+ * We shouldn't see attnum == 0 here, since we already rejected
+ * expression indexes. If we do, SystemAttributeDefinition
+ * will throw an error.
+ */
+ if (attnum > 0)
+ {
+ Assert(attnum <= heap_rel->rd_att->natts);
+ attform = heap_rel->rd_att->attrs[attnum - 1];
+ }
+ else
+ attform = SystemAttributeDefinition(attnum,
+ heap_rel->rd_rel->relhasoids);
+ attname = pstrdup(NameStr(attform->attname));
+
+ /*
+ * Insist on default opclass and sort options. While the index
+ * would still work as a constraint with non-default settings, it
+ * might not provide exactly the same uniqueness semantics as
+ * you'd get from a normally-created constraint; and there's also
+ * the dump/reload problem mentioned above.
+ */
+ defopclass = GetDefaultOpClass(attform->atttypid,
+ index_rel->rd_rel->relam);
+ if (indclass->values[i] != defopclass ||
+ index_rel->rd_indoption[i] != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("index \"%s\" does not have default sorting behavior", index_name),
+ errdetail("Cannot create a PRIMARY KEY or UNIQUE constraint using such an index."),
+ parser_errposition(cxt->pstate, constraint->location)));
+
+ constraint->keys = lappend(constraint->keys, makeString(attname));
+ }
+
+ /* Close the index relation but keep the lock */
+ relation_close(index_rel, NoLock);
+
+ index->indexOid = index_oid;
+ }
+
+ /*
* If it's an EXCLUDE constraint, the grammar returns a list of pairs of
* IndexElems and operator names. We have to break that apart into
* separate lists.
@@ -1450,8 +1621,8 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
if (!found && !cxt->isalter)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("column \"%s\" named in key does not exist",
- key)));
+ errmsg("column \"%s\" named in key does not exist", key),
+ parser_errposition(cxt->pstate, constraint->location)));
/* Check for PRIMARY KEY(foo, foo) */
foreach(columns, index->indexParams)
@@ -1463,12 +1634,14 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("column \"%s\" appears twice in primary key constraint",
- key)));
+ key),
+ parser_errposition(cxt->pstate, constraint->location)));
else
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("column \"%s\" appears twice in unique constraint",
- key)));
+ key),
+ parser_errposition(cxt->pstate, constraint->location)));
}
}
@@ -1491,7 +1664,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
* handle FOREIGN KEY constraints
*/
static void
-transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt,
+transformFKConstraints(CreateStmtContext *cxt,
bool skipValidation, bool isAddConstraint)
{
ListCell *fkclist;
@@ -1978,7 +2151,7 @@ transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString)
stmt = (AlterTableStmt *) copyObject(stmt);
/*
- * Assign the appropriate lock level for this list of subcommands.
+ * Determine the appropriate lock level for this list of subcommands.
*/
lockmode = AlterTableGetLockLevel(stmt->cmds);
@@ -1992,10 +2165,11 @@ transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString)
*/
rel = relation_openrv(stmt->relation, lockmode);
- /* Set up pstate */
+ /* Set up pstate and CreateStmtContext */
pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString;
+ cxt.pstate = pstate;
cxt.stmtType = "ALTER TABLE";
cxt.relation = stmt->relation;
cxt.rel = rel;
@@ -2028,7 +2202,7 @@ transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString)
ColumnDef *def = (ColumnDef *) cmd->def;
Assert(IsA(def, ColumnDef));
- transformColumnDefinition(pstate, &cxt, def);
+ transformColumnDefinition(&cxt, def);
/*
* If the column has a non-null default, we can't skip
@@ -2053,8 +2227,7 @@ transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString)
*/
if (IsA(cmd->def, Constraint))
{
- transformTableConstraint(pstate, &cxt,
- (Constraint *) cmd->def);
+ transformTableConstraint(&cxt, (Constraint *) cmd->def);
if (((Constraint *) cmd->def)->contype == CONSTR_FOREIGN)
skipValidation = false;
}
@@ -2088,25 +2261,25 @@ transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString)
cxt.alist = NIL;
/* Postprocess index and FK constraints */
- transformIndexConstraints(pstate, &cxt);
+ transformIndexConstraints(&cxt);
- transformFKConstraints(pstate, &cxt, skipValidation, true);
+ transformFKConstraints(&cxt, skipValidation, true);
/*
* Push any index-creation commands into the ALTER, so that they can be
* scheduled nicely by tablecmds.c. Note that tablecmds.c assumes that
- * the IndexStmt attached to an AT_AddIndex subcommand has already been
- * through transformIndexStmt.
+ * the IndexStmt attached to an AT_AddIndex or AT_AddIndexConstraint
+ * subcommand has already been through transformIndexStmt.
*/
foreach(l, cxt.alist)
{
- Node *idxstmt = (Node *) lfirst(l);
+ IndexStmt *idxstmt = (IndexStmt *) lfirst(l);
Assert(IsA(idxstmt, IndexStmt));
+ idxstmt = transformIndexStmt(idxstmt, queryString);
newcmd = makeNode(AlterTableCmd);
- newcmd->subtype = AT_AddIndex;
- newcmd->def = (Node *) transformIndexStmt((IndexStmt *) idxstmt,
- queryString);
+ newcmd->subtype = OidIsValid(idxstmt->indexOid) ? AT_AddIndexConstraint : AT_AddIndex;
+ newcmd->def = (Node *) idxstmt;
newcmds = lappend(newcmds, newcmd);
}
cxt.alist = NIL;
@@ -2153,7 +2326,7 @@ transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString)
* for other constraint types.
*/
static void
-transformConstraintAttrs(ParseState *pstate, List *constraintList)
+transformConstraintAttrs(CreateStmtContext *cxt, List *constraintList)
{
Constraint *lastprimarycon = NULL;
bool saw_deferrability = false;
@@ -2181,12 +2354,12 @@ transformConstraintAttrs(ParseState *pstate, List *constraintList)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("misplaced DEFERRABLE clause"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
if (saw_deferrability)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
saw_deferrability = true;
lastprimarycon->deferrable = true;
break;
@@ -2196,12 +2369,12 @@ transformConstraintAttrs(ParseState *pstate, List *constraintList)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("misplaced NOT DEFERRABLE clause"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
if (saw_deferrability)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
saw_deferrability = true;
lastprimarycon->deferrable = false;
if (saw_initially &&
@@ -2209,7 +2382,7 @@ transformConstraintAttrs(ParseState *pstate, List *constraintList)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
break;
case CONSTR_ATTR_DEFERRED:
@@ -2217,12 +2390,12 @@ transformConstraintAttrs(ParseState *pstate, List *constraintList)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("misplaced INITIALLY DEFERRED clause"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
if (saw_initially)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
saw_initially = true;
lastprimarycon->initdeferred = true;
@@ -2235,7 +2408,7 @@ transformConstraintAttrs(ParseState *pstate, List *constraintList)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
break;
case CONSTR_ATTR_IMMEDIATE:
@@ -2243,12 +2416,12 @@ transformConstraintAttrs(ParseState *pstate, List *constraintList)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("misplaced INITIALLY IMMEDIATE clause"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
if (saw_initially)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed"),
- parser_errposition(pstate, con->location)));
+ parser_errposition(cxt->pstate, con->location)));
saw_initially = true;
lastprimarycon->initdeferred = false;
break;
@@ -2268,12 +2441,12 @@ transformConstraintAttrs(ParseState *pstate, List *constraintList)
* Special handling of type definition for a column
*/
static void
-transformColumnType(ParseState *pstate, ColumnDef *column)
+transformColumnType(CreateStmtContext *cxt, ColumnDef *column)
{
/*
* All we really need to do here is verify that the type is valid.
*/
- Type ctype = typenameType(pstate, column->typeName, NULL);
+ Type ctype = typenameType(cxt->pstate, column->typeName, NULL);
ReleaseSysCache(ctype);
}