aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/analyze.c4
-rw-r--r--src/backend/commands/dbcommands.c4
-rw-r--r--src/backend/commands/functioncmds.c4
-rw-r--r--src/backend/commands/indexcmds.c26
-rw-r--r--src/backend/commands/seclabel.c3
-rw-r--r--src/backend/commands/sequence.c20
-rw-r--r--src/backend/commands/tablecmds.c54
-rw-r--r--src/backend/commands/typecmds.c31
-rw-r--r--src/backend/commands/view.c3
9 files changed, 113 insertions, 36 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 4c106dd8c57..bafdc80d584 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -862,11 +862,13 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr)
{
stats->attrtypid = exprType(index_expr);
stats->attrtypmod = exprTypmod(index_expr);
+ stats->attrcollation = exprCollation(index_expr);
}
else
{
stats->attrtypid = attr->atttypid;
stats->attrtypmod = attr->atttypmod;
+ stats->attrcollation = attr->attcollation;
}
typtuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(stats->attrtypid));
@@ -1929,6 +1931,7 @@ compute_minimal_stats(VacAttrStatsP stats,
track_cnt = 0;
fmgr_info(mystats->eqfunc, &f_cmpeq);
+ fmgr_info_collation(stats->attrcollation, &f_cmpeq);
for (i = 0; i < samplerows; i++)
{
@@ -2250,6 +2253,7 @@ compute_scalar_stats(VacAttrStatsP stats,
SelectSortFunction(mystats->ltopr, false, &cmpFn, &cmpFlags);
fmgr_info(cmpFn, &f_cmpfn);
+ fmgr_info_collation(stats->attrcollation, &f_cmpfn);
/* Initial scan to find sortable values */
for (i = 0; i < samplerows; i++)
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 9a9b4cbf3d9..c7e0c6a8778 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -356,8 +356,8 @@ createdb(const CreatedbStmt *stmt)
*
* Note: if you change this policy, fix initdb to match.
*/
- ctype_encoding = pg_get_encoding_from_locale(dbctype);
- collate_encoding = pg_get_encoding_from_locale(dbcollate);
+ ctype_encoding = pg_get_encoding_from_locale(dbctype, true);
+ collate_encoding = pg_get_encoding_from_locale(dbcollate, true);
if (!(ctype_encoding == encoding ||
ctype_encoding == PG_SQL_ASCII ||
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 2a2b7c732e8..dad65ee8ffa 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);
+ typtup = LookupTypeName(NULL, returnType, NULL, NULL);
if (typtup)
{
@@ -207,7 +207,7 @@ examine_parameter_list(List *parameters, Oid languageOid,
Oid toid;
Type typtup;
- typtup = LookupTypeName(NULL, t, NULL);
+ typtup = LookupTypeName(NULL, t, NULL, NULL);
if (typtup)
{
if (!((Form_pg_type) GETSTRUCT(typtup))->typisdefined)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 94ed4370023..c8e21b68f58 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -58,6 +58,7 @@
/* non-export function prototypes */
static void CheckPredicate(Expr *predicate);
static void ComputeIndexAttrs(IndexInfo *indexInfo,
+ Oid *collationOidP,
Oid *classOidP,
int16 *colOptionP,
List *attList,
@@ -124,6 +125,7 @@ DefineIndex(RangeVar *heapRelation,
bool quiet,
bool concurrent)
{
+ Oid *collationObjectId;
Oid *classObjectId;
Oid accessMethodId;
Oid relationId;
@@ -345,9 +347,10 @@ DefineIndex(RangeVar *heapRelation,
indexInfo->ii_Concurrent = concurrent;
indexInfo->ii_BrokenHotChain = false;
+ collationObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16));
- ComputeIndexAttrs(indexInfo, classObjectId, coloptions, attributeList,
+ ComputeIndexAttrs(indexInfo, collationObjectId, classObjectId, coloptions, attributeList,
exclusionOpNames, relationId,
accessMethodName, accessMethodId,
amcanorder, isconstraint);
@@ -392,7 +395,7 @@ DefineIndex(RangeVar *heapRelation,
indexRelationId =
index_create(rel, indexRelationName, indexRelationId,
indexInfo, indexColNames,
- accessMethodId, tablespaceId, classObjectId,
+ accessMethodId, tablespaceId, collationObjectId, classObjectId,
coloptions, reloptions, primary,
isconstraint, deferrable, initdeferred,
allowSystemTableMods,
@@ -764,6 +767,7 @@ CheckPredicate(Expr *predicate)
*/
static void
ComputeIndexAttrs(IndexInfo *indexInfo,
+ Oid *collationOidP,
Oid *classOidP,
int16 *colOptionP,
List *attList, /* list of IndexElem's */
@@ -800,6 +804,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
{
IndexElem *attribute = (IndexElem *) lfirst(lc);
Oid atttype;
+ Oid attcollation;
/*
* Process the column-or-expression to be indexed.
@@ -829,6 +834,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
attform = (Form_pg_attribute) GETSTRUCT(atttuple);
indexInfo->ii_KeyAttrNumbers[attn] = attform->attnum;
atttype = attform->atttypid;
+ attcollation = attform->attcollation;
ReleaseSysCache(atttuple);
}
else if (attribute->expr && IsA(attribute->expr, Var) &&
@@ -839,6 +845,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
indexInfo->ii_KeyAttrNumbers[attn] = var->varattno;
atttype = get_atttype(relId, var->varattno);
+ attcollation = var->varcollid;
}
else
{
@@ -848,6 +855,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
indexInfo->ii_Expressions = lappend(indexInfo->ii_Expressions,
attribute->expr);
atttype = exprType(attribute->expr);
+ attcollation = exprCollation(attribute->expr);
/*
* We don't currently support generation of an actual query plan
@@ -875,6 +883,20 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
}
/*
+ * Collation override
+ */
+ if (attribute->collation)
+ {
+ if (!type_is_collatable(atttype))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("collations are not supported by type %s",
+ format_type_be(atttype))));
+ attcollation = get_collation_oid(attribute->collation, false);
+ }
+ collationOidP[attn] = attcollation;
+
+ /*
* Identify the opclass to use.
*/
classOidP[attn] = GetIndexOpClass(attribute->opclass,
diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c
index b927e76abd2..27917fc6c00 100644
--- a/src/backend/commands/seclabel.c
+++ b/src/backend/commands/seclabel.c
@@ -15,6 +15,7 @@
#include "catalog/catalog.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
+#include "catalog/pg_collation.h"
#include "catalog/pg_seclabel.h"
#include "commands/seclabel.h"
#include "miscadmin.h"
@@ -194,6 +195,7 @@ GetSecurityLabel(const ObjectAddress *object, const char *provider)
Anum_pg_seclabel_provider,
BTEqualStrategyNumber, F_TEXTEQ,
CStringGetTextDatum(provider));
+ ScanKeyEntryInitializeCollation(&keys[3], DEFAULT_COLLATION_OID);
pg_seclabel = heap_open(SecLabelRelationId, AccessShareLock);
@@ -263,6 +265,7 @@ SetSecurityLabel(const ObjectAddress *object,
Anum_pg_seclabel_provider,
BTEqualStrategyNumber, F_TEXTEQ,
CStringGetTextDatum(provider));
+ ScanKeyEntryInitializeCollation(&keys[3], DEFAULT_COLLATION_OID);
pg_seclabel = heap_open(SecLabelRelationId, RowExclusiveLock);
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 0ff722d6f8a..80ad516de1f 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -143,53 +143,53 @@ DefineSequence(CreateSeqStmt *seq)
switch (i)
{
case SEQ_COL_NAME:
- coldef->typeName = makeTypeNameFromOid(NAMEOID, -1);
+ coldef->typeName = makeTypeNameFromOid(NAMEOID, -1, InvalidOid);
coldef->colname = "sequence_name";
namestrcpy(&name, seq->sequence->relname);
value[i - 1] = NameGetDatum(&name);
break;
case SEQ_COL_LASTVAL:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
coldef->colname = "last_value";
value[i - 1] = Int64GetDatumFast(new.last_value);
break;
case SEQ_COL_STARTVAL:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
coldef->colname = "start_value";
value[i - 1] = Int64GetDatumFast(new.start_value);
break;
case SEQ_COL_INCBY:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
coldef->colname = "increment_by";
value[i - 1] = Int64GetDatumFast(new.increment_by);
break;
case SEQ_COL_MAXVALUE:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
coldef->colname = "max_value";
value[i - 1] = Int64GetDatumFast(new.max_value);
break;
case SEQ_COL_MINVALUE:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
coldef->colname = "min_value";
value[i - 1] = Int64GetDatumFast(new.min_value);
break;
case SEQ_COL_CACHE:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
coldef->colname = "cache_value";
value[i - 1] = Int64GetDatumFast(new.cache_value);
break;
case SEQ_COL_LOG:
- coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
+ coldef->typeName = makeTypeNameFromOid(INT8OID, -1, InvalidOid);
coldef->colname = "log_cnt";
value[i - 1] = Int64GetDatum((int64) 1);
break;
case SEQ_COL_CYCLE:
- coldef->typeName = makeTypeNameFromOid(BOOLOID, -1);
+ coldef->typeName = makeTypeNameFromOid(BOOLOID, -1, InvalidOid);
coldef->colname = "is_cycled";
value[i - 1] = BoolGetDatum(new.is_cycled);
break;
case SEQ_COL_CALLED:
- coldef->typeName = makeTypeNameFromOid(BOOLOID, -1);
+ coldef->typeName = makeTypeNameFromOid(BOOLOID, -1, InvalidOid);
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 eac72106fdc..c0a4e6f954a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1422,6 +1422,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
{
Oid defTypeId;
int32 deftypmod;
+ Oid defCollId;
/*
* Yes, try to merge the two column definitions. They must
@@ -1431,7 +1432,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);
- typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
+ typenameTypeIdModColl(NULL, def->typeName, &defTypeId, &deftypmod, &defCollId);
if (defTypeId != attribute->atttypid ||
deftypmod != attribute->atttypmod)
ereport(ERROR,
@@ -1441,6 +1442,14 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
errdetail("%s versus %s",
TypeNameToString(def->typeName),
format_type_be(attribute->atttypid))));
+ if (defCollId != attribute->attcollation)
+ ereport(ERROR,
+ (errcode(ERRCODE_COLLATION_MISMATCH),
+ errmsg("inherited column \"%s\" has a collation conflict",
+ attributeName),
+ errdetail("\"%s\" versus \"%s\"",
+ get_collation_name(defCollId),
+ get_collation_name(attribute->attcollation))));
/* Copy storage parameter */
if (def->storage == 0)
@@ -1468,7 +1477,8 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
def = makeNode(ColumnDef);
def->colname = pstrdup(attributeName);
def->typeName = makeTypeNameFromOid(attribute->atttypid,
- attribute->atttypmod);
+ attribute->atttypmod,
+ attribute->attcollation);
def->inhcount = 1;
def->is_local = false;
def->is_not_null = attribute->attnotnull;
@@ -1594,6 +1604,8 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
newTypeId;
int32 deftypmod,
newtypmod;
+ Oid defcollid,
+ newcollid;
/*
* Yes, try to merge the two column definitions. They must
@@ -1603,8 +1615,8 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
(errmsg("merging column \"%s\" with inherited definition",
attributeName)));
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
- typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
- typenameTypeIdAndMod(NULL, newdef->typeName, &newTypeId, &newtypmod);
+ typenameTypeIdModColl(NULL, def->typeName, &defTypeId, &deftypmod, &defcollid);
+ typenameTypeIdModColl(NULL, newdef->typeName, &newTypeId, &newtypmod, &newcollid);
if (defTypeId != newTypeId || deftypmod != newtypmod)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -1613,6 +1625,14 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
errdetail("%s versus %s",
TypeNameToString(def->typeName),
TypeNameToString(newdef->typeName))));
+ if (defcollid != newcollid)
+ ereport(ERROR,
+ (errcode(ERRCODE_COLLATION_MISMATCH),
+ errmsg("column \"%s\" has a collation conflict",
+ attributeName),
+ errdetail("\"%s\" versus \"%s\"",
+ get_collation_name(defcollid),
+ get_collation_name(newcollid))));
/* Copy storage parameter */
if (def->storage == 0)
@@ -4065,6 +4085,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
HeapTuple typeTuple;
Oid typeOid;
int32 typmod;
+ Oid collOid;
Form_pg_type tform;
Expr *defval;
@@ -4085,15 +4106,24 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
Oid ctypeId;
int32 ctypmod;
+ Oid ccollid;
/* Child column must match by type */
- typenameTypeIdAndMod(NULL, colDef->typeName, &ctypeId, &ctypmod);
+ typenameTypeIdModColl(NULL, colDef->typeName, &ctypeId, &ctypmod, &ccollid);
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)));
+ if (ccollid != childatt->attcollation)
+ ereport(ERROR,
+ (errcode(ERRCODE_COLLATION_MISMATCH),
+ errmsg("child table \"%s\" has different collation for column \"%s\"",
+ RelationGetRelationName(rel), colDef->colname),
+ errdetail("\"%s\" versus \"%s\"",
+ get_collation_name(ccollid),
+ get_collation_name(childatt->attcollation))));
/* If it's OID, child column must actually be OID */
if (isOid && childatt->attnum != ObjectIdAttributeNumber)
@@ -4151,7 +4181,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
MaxHeapAttributeNumber)));
}
- typeTuple = typenameType(NULL, colDef->typeName, &typmod);
+ typeTuple = typenameType(NULL, colDef->typeName, &typmod, &collOid);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
typeOid = HeapTupleGetOid(typeTuple);
@@ -4176,6 +4206,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
attribute.attisdropped = false;
attribute.attislocal = colDef->is_local;
attribute.attinhcount = colDef->inhcount;
+ attribute.attcollation = collOid;
/* attribute.attacl is handled by InsertPgAttributeTuple */
ReleaseSysCache(typeTuple);
@@ -4353,7 +4384,7 @@ ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOC
ColumnDef *cdef = makeNode(ColumnDef);
cdef->colname = pstrdup("oid");
- cdef->typeName = makeTypeNameFromOid(OIDOID, -1);
+ cdef->typeName = makeTypeNameFromOid(OIDOID, -1, InvalidOid);
cdef->inhcount = 0;
cdef->is_local = true;
cdef->is_not_null = true;
@@ -6415,6 +6446,7 @@ ATPrepAlterColumnType(List **wqueue,
AttrNumber attnum;
Oid targettype;
int32 targettypmod;
+ Oid targetcollid;
Node *transform;
NewColumnValue *newval;
ParseState *pstate = make_parsestate(NULL);
@@ -6449,7 +6481,7 @@ ATPrepAlterColumnType(List **wqueue,
colName)));
/* Look up the target type */
- typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod);
+ typenameTypeIdModColl(NULL, typeName, &targettype, &targettypmod, &targetcollid);
/* make sure datatype is legal for a column */
CheckAttributeType(colName, targettype, false);
@@ -6501,7 +6533,7 @@ ATPrepAlterColumnType(List **wqueue,
else
{
transform = (Node *) makeVar(1, attnum,
- attTup->atttypid, attTup->atttypmod,
+ attTup->atttypid, attTup->atttypmod, attTup->attcollation,
0);
}
@@ -6578,6 +6610,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
Form_pg_type tform;
Oid targettype;
int32 targettypmod;
+ Oid targetcollid;
Node *defaultexpr;
Relation attrelation;
Relation depRel;
@@ -6606,7 +6639,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
colName)));
/* Look up the target type (should not fail, since prep found it) */
- typeTuple = typenameType(NULL, typeName, &targettypmod);
+ typeTuple = typenameType(NULL, typeName, &targettypmod, &targetcollid);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
targettype = HeapTupleGetOid(typeTuple);
@@ -6880,6 +6913,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
*/
attTup->atttypid = targettype;
attTup->atttypmod = targettypmod;
+ attTup->attcollation = targetcollid;
attTup->attndims = list_length(typeName->arrayBounds);
attTup->attlen = tform->typlen;
attTup->attbyval = tform->typbyval;
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 5500df03ab4..25d0f3596e1 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -38,6 +38,7 @@
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/indexing.h"
+#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_depend.h"
#include "catalog/pg_enum.h"
@@ -118,6 +119,7 @@ DefineType(List *names, List *parameters)
bool byValue = false;
char alignment = 'i'; /* default alignment */
char storage = 'p'; /* default TOAST storage method */
+ Oid collation = InvalidOid;
DefElem *likeTypeEl = NULL;
DefElem *internalLengthEl = NULL;
DefElem *inputNameEl = NULL;
@@ -135,6 +137,7 @@ DefineType(List *names, List *parameters)
DefElem *byValueEl = NULL;
DefElem *alignmentEl = NULL;
DefElem *storageEl = NULL;
+ DefElem *collatableEl = NULL;
Oid inputOid;
Oid outputOid;
Oid receiveOid = InvalidOid;
@@ -261,6 +264,8 @@ DefineType(List *names, List *parameters)
defelp = &alignmentEl;
else if (pg_strcasecmp(defel->defname, "storage") == 0)
defelp = &storageEl;
+ else if (pg_strcasecmp(defel->defname, "collatable") == 0)
+ defelp = &collatableEl;
else
{
/* WARNING, not ERROR, for historical backwards-compatibility */
@@ -287,7 +292,7 @@ DefineType(List *names, List *parameters)
Type likeType;
Form_pg_type likeForm;
- likeType = typenameType(NULL, defGetTypeName(likeTypeEl), NULL);
+ likeType = typenameType(NULL, defGetTypeName(likeTypeEl), NULL, NULL);
likeForm = (Form_pg_type) GETSTRUCT(likeType);
internalLength = likeForm->typlen;
byValue = likeForm->typbyval;
@@ -390,6 +395,8 @@ DefineType(List *names, List *parameters)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("storage \"%s\" not recognized", a)));
}
+ if (collatableEl)
+ collation = defGetBoolean(collatableEl) ? DEFAULT_COLLATION_OID : InvalidOid;
/*
* make sure we have our required definitions
@@ -562,7 +569,8 @@ DefineType(List *names, List *parameters)
storage, /* TOAST strategy */
-1, /* typMod (Domains only) */
0, /* Array Dimensions of typbasetype */
- false); /* Type NOT NULL */
+ false, /* Type NOT NULL */
+ collation);
/*
* Create the array type that goes with it.
@@ -601,7 +609,8 @@ DefineType(List *names, List *parameters)
'x', /* ARRAY is always toastable */
-1, /* typMod (Domains only) */
0, /* Array dimensions of typbasetype */
- false); /* Type NOT NULL */
+ false, /* Type NOT NULL */
+ collation);
pfree(array_type);
}
@@ -640,7 +649,7 @@ RemoveTypes(DropStmt *drop)
typename = makeTypeNameFromNameList(names);
/* Use LookupTypeName here so that shell types can be removed. */
- tup = LookupTypeName(NULL, typename, NULL);
+ tup = LookupTypeName(NULL, typename, NULL, NULL);
if (tup == NULL)
{
if (!drop->missing_ok)
@@ -767,6 +776,7 @@ DefineDomain(CreateDomainStmt *stmt)
Oid old_type_oid;
Form_pg_type baseType;
int32 basetypeMod;
+ Oid baseColl;
/* Convert list of names to a name and namespace */
domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname,
@@ -797,7 +807,7 @@ DefineDomain(CreateDomainStmt *stmt)
/*
* Look up the base type.
*/
- typeTup = typenameType(NULL, stmt->typeName, &basetypeMod);
+ typeTup = typenameType(NULL, stmt->typeName, &basetypeMod, &baseColl);
baseType = (Form_pg_type) GETSTRUCT(typeTup);
basetypeoid = HeapTupleGetOid(typeTup);
@@ -1040,7 +1050,8 @@ DefineDomain(CreateDomainStmt *stmt)
storage, /* TOAST strategy */
basetypeMod, /* typeMod value */
typNDims, /* Array dimensions for base type */
- typNotNull); /* Type NOT NULL */
+ typNotNull, /* Type NOT NULL */
+ baseColl);
/*
* Process constraints which refer to the domain ID returned by TypeCreate
@@ -1149,7 +1160,8 @@ DefineEnum(CreateEnumStmt *stmt)
'p', /* TOAST strategy always plain */
-1, /* typMod (Domains only) */
0, /* Array dimensions of typbasetype */
- false); /* Type NOT NULL */
+ false, /* Type NOT NULL */
+ InvalidOid); /* typcollation */
/* Enter the enum's values into pg_enum */
EnumValuesCreate(enumTypeOid, stmt->vals);
@@ -1188,7 +1200,8 @@ DefineEnum(CreateEnumStmt *stmt)
'x', /* ARRAY is always toastable */
-1, /* typMod (Domains only) */
0, /* Array dimensions of typbasetype */
- false); /* Type NOT NULL */
+ false, /* Type NOT NULL */
+ InvalidOid); /* typcollation */
pfree(enumArrayName);
}
@@ -2615,7 +2628,7 @@ AlterTypeOwner(List *names, Oid newOwnerId)
typename = makeTypeNameFromNameList(names);
/* Use LookupTypeName here so that shell types can be processed */
- tup = LookupTypeName(NULL, typename, NULL);
+ tup = LookupTypeName(NULL, typename, NULL, 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 a684172c8a5..22dfc923cf6 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -120,7 +120,8 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
def->colname = pstrdup(tle->resname);
def->typeName = makeTypeNameFromOid(exprType((Node *) tle->expr),
- exprTypmod((Node *) tle->expr));
+ exprTypmod((Node *) tle->expr),
+ exprCollation((Node *) tle->expr));
def->inhcount = 0;
def->is_local = true;
def->is_not_null = false;