aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/collationcmds.c2
-rw-r--r--src/backend/commands/functioncmds.c4
-rw-r--r--src/backend/commands/sequence.c23
-rw-r--r--src/backend/commands/tablecmds.c65
-rw-r--r--src/backend/commands/typecmds.c27
-rw-r--r--src/backend/commands/view.c13
6 files changed, 88 insertions, 46 deletions
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 18e88d2653f..a52cb351ac8 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -98,7 +98,7 @@ DefineCollation(List *names, List *parameters)
Oid collid;
HeapTuple tp;
- collid = LookupCollation(NULL, defGetQualifiedName(fromEl), -1);
+ collid = get_collation_oid(defGetQualifiedName(fromEl), false);
tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for collation %u", collid);
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 3f25b3bf02a..a8ef947240e 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -87,7 +87,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
Oid rettype;
Type typtup;
- typtup = LookupTypeName(NULL, returnType, NULL, NULL);
+ typtup = LookupTypeName(NULL, returnType, NULL);
if (typtup)
{
@@ -207,7 +207,7 @@ examine_parameter_list(List *parameters, Oid languageOid,
Oid toid;
Type typtup;
- typtup = LookupTypeName(NULL, t, NULL, NULL);
+ typtup = LookupTypeName(NULL, t, NULL);
if (typtup)
{
if (!((Form_pg_type) GETSTRUCT(typtup))->typisdefined)
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index e71c311faf7..5c6212c64cd 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -139,9 +139,12 @@ DefineSequence(CreateSeqStmt *seq)
coldef->inhcount = 0;
coldef->is_local = true;
coldef->is_not_null = true;
+ coldef->is_from_type = false;
coldef->storage = 0;
coldef->raw_default = NULL;
coldef->cooked_default = NULL;
+ coldef->collClause = NULL;
+ coldef->collOid = InvalidOid;
coldef->constraints = NIL;
null[i - 1] = false;
@@ -149,53 +152,53 @@ DefineSequence(CreateSeqStmt *seq)
switch (i)
{
case SEQ_COL_NAME:
- coldef->typeName = makeTypeNameFromOid(NAMEOID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(NAMEOID, -1);
coldef->colname = "sequence_name";
namestrcpy(&name, seq->sequence->relname);
value[i - 1] = NameGetDatum(&name);
break;
case SEQ_COL_LASTVAL:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "last_value";
value[i - 1] = Int64GetDatumFast(new.last_value);
break;
case SEQ_COL_STARTVAL:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "start_value";
value[i - 1] = Int64GetDatumFast(new.start_value);
break;
case SEQ_COL_INCBY:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "increment_by";
value[i - 1] = Int64GetDatumFast(new.increment_by);
break;
case SEQ_COL_MAXVALUE:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "max_value";
value[i - 1] = Int64GetDatumFast(new.max_value);
break;
case SEQ_COL_MINVALUE:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "min_value";
value[i - 1] = Int64GetDatumFast(new.min_value);
break;
case SEQ_COL_CACHE:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "cache_value";
value[i - 1] = Int64GetDatumFast(new.cache_value);
break;
case SEQ_COL_LOG:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "log_cnt";
value[i - 1] = Int64GetDatum((int64) 1);
break;
case SEQ_COL_CYCLE:
- coldef->typeName = makeTypeNameFromOid(BOOLOID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(BOOLOID, -1);
coldef->colname = "is_cycled";
value[i - 1] = BoolGetDatum(new.is_cycled);
break;
case SEQ_COL_CALLED:
- coldef->typeName = makeTypeNameFromOid(BOOLOID, -1, InvalidOid);
+ coldef->typeName = makeTypeNameFromOid(BOOLOID, -1);
coldef->colname = "is_called";
value[i - 1] = BoolGetDatum(false);
break;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 3be9a6f3481..f1264bfb66d 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -339,7 +339,7 @@ static void ATPrepAlterColumnType(List **wqueue,
AlterTableCmd *cmd, LOCKMODE lockmode);
static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno);
static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
- const char *colName, TypeName *typeName, LOCKMODE lockmode);
+ AlterTableCmd *cmd, LOCKMODE lockmode);
static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode);
static void ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode);
static void change_owner_recurse_to_sequences(Oid relationOid,
@@ -1433,7 +1433,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
(errmsg("merging multiple inherited definitions of column \"%s\"",
attributeName)));
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
- typenameTypeIdModColl(NULL, def->typeName, &defTypeId, &deftypmod, &defCollId);
+ typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
if (defTypeId != attribute->atttypid ||
deftypmod != attribute->atttypmod)
ereport(ERROR,
@@ -1443,6 +1443,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
errdetail("%s versus %s",
TypeNameToString(def->typeName),
format_type_be(attribute->atttypid))));
+ defCollId = GetColumnDefCollation(NULL, def, defTypeId);
if (defCollId != attribute->attcollation)
ereport(ERROR,
(errcode(ERRCODE_COLLATION_MISMATCH),
@@ -1478,14 +1479,16 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
def = makeNode(ColumnDef);
def->colname = pstrdup(attributeName);
def->typeName = makeTypeNameFromOid(attribute->atttypid,
- attribute->atttypmod,
- attribute->attcollation);
+ attribute->atttypmod);
def->inhcount = 1;
def->is_local = false;
def->is_not_null = attribute->attnotnull;
+ def->is_from_type = false;
def->storage = attribute->attstorage;
def->raw_default = NULL;
def->cooked_default = NULL;
+ def->collClause = NULL;
+ def->collOid = attribute->attcollation;
def->constraints = NIL;
inhSchema = lappend(inhSchema, def);
newattno[parent_attno - 1] = ++child_attno;
@@ -1616,8 +1619,8 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
(errmsg("merging column \"%s\" with inherited definition",
attributeName)));
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
- typenameTypeIdModColl(NULL, def->typeName, &defTypeId, &deftypmod, &defcollid);
- typenameTypeIdModColl(NULL, newdef->typeName, &newTypeId, &newtypmod, &newcollid);
+ typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
+ typenameTypeIdAndMod(NULL, newdef->typeName, &newTypeId, &newtypmod);
if (defTypeId != newTypeId || deftypmod != newtypmod)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -1626,6 +1629,8 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
errdetail("%s versus %s",
TypeNameToString(def->typeName),
TypeNameToString(newdef->typeName))));
+ defcollid = GetColumnDefCollation(NULL, def, defTypeId);
+ newcollid = GetColumnDefCollation(NULL, newdef, newTypeId);
if (defcollid != newcollid)
ereport(ERROR,
(errcode(ERRCODE_COLLATION_MISMATCH),
@@ -3092,7 +3097,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
cmd->missing_ok, lockmode);
break;
case AT_AlterColumnType: /* ALTER COLUMN TYPE */
- ATExecAlterColumnType(tab, rel, cmd->name, (TypeName *) cmd->def, lockmode);
+ ATExecAlterColumnType(tab, rel, cmd, lockmode);
break;
case AT_ChangeOwner: /* ALTER OWNER */
ATExecChangeOwner(RelationGetRelid(rel),
@@ -4129,13 +4134,14 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
Oid ccollid;
/* Child column must match by type */
- typenameTypeIdModColl(NULL, colDef->typeName, &ctypeId, &ctypmod, &ccollid);
+ typenameTypeIdAndMod(NULL, colDef->typeName, &ctypeId, &ctypmod);
if (ctypeId != childatt->atttypid ||
ctypmod != childatt->atttypmod)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("child table \"%s\" has different type for column \"%s\"",
RelationGetRelationName(rel), colDef->colname)));
+ ccollid = GetColumnDefCollation(NULL, colDef, ctypeId);
if (ccollid != childatt->attcollation)
ereport(ERROR,
(errcode(ERRCODE_COLLATION_MISMATCH),
@@ -4201,9 +4207,10 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
MaxHeapAttributeNumber)));
}
- typeTuple = typenameType(NULL, colDef->typeName, &typmod, &collOid);
+ typeTuple = typenameType(NULL, colDef->typeName, &typmod);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
typeOid = HeapTupleGetOid(typeTuple);
+ collOid = GetColumnDefCollation(NULL, colDef, typeOid);
/* make sure datatype is legal for a column */
CheckAttributeType(colDef->colname, typeOid, collOid, false);
@@ -4413,7 +4420,7 @@ ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOC
ColumnDef *cdef = makeNode(ColumnDef);
cdef->colname = pstrdup("oid");
- cdef->typeName = makeTypeNameFromOid(OIDOID, -1, InvalidOid);
+ cdef->typeName = makeTypeNameFromOid(OIDOID, -1);
cdef->inhcount = 0;
cdef->is_local = true;
cdef->is_not_null = true;
@@ -6471,14 +6478,15 @@ ATPrepAlterColumnType(List **wqueue,
AlterTableCmd *cmd, LOCKMODE lockmode)
{
char *colName = cmd->name;
- TypeName *typeName = (TypeName *) cmd->def;
+ ColumnDef *def = (ColumnDef *) cmd->def;
+ TypeName *typeName = def->typeName;
+ Node *transform = def->raw_default;
HeapTuple tuple;
Form_pg_attribute attTup;
AttrNumber attnum;
Oid targettype;
int32 targettypmod;
Oid targetcollid;
- Node *transform;
NewColumnValue *newval;
ParseState *pstate = make_parsestate(NULL);
@@ -6512,7 +6520,10 @@ ATPrepAlterColumnType(List **wqueue,
colName)));
/* Look up the target type */
- typenameTypeIdModColl(NULL, typeName, &targettype, &targettypmod, &targetcollid);
+ typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod);
+
+ /* And the collation */
+ targetcollid = GetColumnDefCollation(NULL, def, targettype);
/* make sure datatype is legal for a column */
CheckAttributeType(colName, targettype, targetcollid, false);
@@ -6527,7 +6538,7 @@ ATPrepAlterColumnType(List **wqueue,
* because we need the expression to be parsed against the original table
* rowtype.
*/
- if (cmd->transform)
+ if (transform)
{
RangeTblEntry *rte;
@@ -6539,7 +6550,7 @@ ATPrepAlterColumnType(List **wqueue,
true);
addRTEtoQuery(pstate, rte, false, true, true);
- transform = transformExpr(pstate, cmd->transform);
+ transform = transformExpr(pstate, transform);
/* It can't return a set */
if (expression_returns_set(transform))
@@ -6592,16 +6603,13 @@ ATPrepAlterColumnType(List **wqueue,
if (ATColumnChangeRequiresRewrite(transform, attnum))
tab->rewrite = true;
}
- else if (tab->relkind == RELKIND_FOREIGN_TABLE)
- {
- if (cmd->transform)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("ALTER TYPE USING is not supported on foreign tables")));
- }
+ else if (transform)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("ALTER TYPE USING is only supported on plain tables")));
- if (tab->relkind == RELKIND_COMPOSITE_TYPE
- || tab->relkind == RELKIND_FOREIGN_TABLE)
+ if (tab->relkind == RELKIND_COMPOSITE_TYPE ||
+ tab->relkind == RELKIND_FOREIGN_TABLE)
{
/*
* For composite types, do this check now. Tables will check
@@ -6667,8 +6675,11 @@ ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno)
static void
ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
- const char *colName, TypeName *typeName, LOCKMODE lockmode)
+ AlterTableCmd *cmd, LOCKMODE lockmode)
{
+ char *colName = cmd->name;
+ ColumnDef *def = (ColumnDef *) cmd->def;
+ TypeName *typeName = def->typeName;
HeapTuple heapTup;
Form_pg_attribute attTup;
AttrNumber attnum;
@@ -6705,9 +6716,11 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
colName)));
/* Look up the target type (should not fail, since prep found it) */
- typeTuple = typenameType(NULL, typeName, &targettypmod, &targetcollid);
+ typeTuple = typenameType(NULL, typeName, &targettypmod);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
targettype = HeapTupleGetOid(typeTuple);
+ /* And the collation */
+ targetcollid = GetColumnDefCollation(NULL, def, targettype);
/*
* If there is a default expression for the column, get it and ensure we
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index be1f1d791fd..3513256b9a5 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -292,7 +292,7 @@ DefineType(List *names, List *parameters)
Type likeType;
Form_pg_type likeForm;
- likeType = typenameType(NULL, defGetTypeName(likeTypeEl), NULL, NULL);
+ likeType = typenameType(NULL, defGetTypeName(likeTypeEl), NULL);
likeForm = (Form_pg_type) GETSTRUCT(likeType);
internalLength = likeForm->typlen;
byValue = likeForm->typbyval;
@@ -649,7 +649,7 @@ RemoveTypes(DropStmt *drop)
typename = makeTypeNameFromNameList(names);
/* Use LookupTypeName here so that shell types can be removed. */
- tup = LookupTypeName(NULL, typename, NULL, NULL);
+ tup = LookupTypeName(NULL, typename, NULL);
if (tup == NULL)
{
if (!drop->missing_ok)
@@ -774,6 +774,7 @@ DefineDomain(CreateDomainStmt *stmt)
Oid basetypeoid;
Oid domainoid;
Oid old_type_oid;
+ Oid domaincoll;
Form_pg_type baseType;
int32 basetypeMod;
Oid baseColl;
@@ -807,7 +808,7 @@ DefineDomain(CreateDomainStmt *stmt)
/*
* Look up the base type.
*/
- typeTup = typenameType(NULL, stmt->typeName, &basetypeMod, &baseColl);
+ typeTup = typenameType(NULL, stmt->typeName, &basetypeMod);
baseType = (Form_pg_type) GETSTRUCT(typeTup);
basetypeoid = HeapTupleGetOid(typeTup);
@@ -825,6 +826,22 @@ DefineDomain(CreateDomainStmt *stmt)
errmsg("\"%s\" is not a valid base type for a domain",
TypeNameToString(stmt->typeName))));
+ /*
+ * Identify the collation if any
+ */
+ baseColl = baseType->typcollation;
+ if (stmt->collClause)
+ domaincoll = get_collation_oid(stmt->collClause->collnames, false);
+ else
+ domaincoll = baseColl;
+
+ /* Complain if COLLATE is applied to an uncollatable type */
+ if (OidIsValid(domaincoll) && !OidIsValid(baseColl))
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("collations are not supported by type %s",
+ format_type_be(basetypeoid))));
+
/* passed by value */
byValue = baseType->typbyval;
@@ -1051,7 +1068,7 @@ DefineDomain(CreateDomainStmt *stmt)
basetypeMod, /* typeMod value */
typNDims, /* Array dimensions for base type */
typNotNull, /* Type NOT NULL */
- baseColl);
+ domaincoll);
/*
* Process constraints which refer to the domain ID returned by TypeCreate
@@ -2629,7 +2646,7 @@ AlterTypeOwner(List *names, Oid newOwnerId)
typename = makeTypeNameFromNameList(names);
/* Use LookupTypeName here so that shell types can be processed */
- tup = LookupTypeName(NULL, typename, NULL, NULL);
+ tup = LookupTypeName(NULL, typename, NULL);
if (tup == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index 5576ea259f4..794a56e84de 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -120,14 +120,23 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
def->colname = pstrdup(tle->resname);
def->typeName = makeTypeNameFromOid(exprType((Node *) tle->expr),
- exprTypmod((Node *) tle->expr),
- exprCollation((Node *) tle->expr));
+ exprTypmod((Node *) tle->expr));
def->inhcount = 0;
def->is_local = true;
def->is_not_null = false;
+ def->is_from_type = false;
def->storage = 0;
def->raw_default = NULL;
def->cooked_default = NULL;
+ def->collClause = NULL;
+ /*
+ * XXX Temporary kluge to make regression tests pass. We should
+ * be able to trust the result of exprCollation more than this.
+ */
+ if (type_is_collatable(exprType((Node *) tle->expr)))
+ def->collOid = exprCollation((Node *) tle->expr);
+ else
+ def->collOid = InvalidOid;
def->constraints = NIL;
attrList = lappend(attrList, def);