diff --git a/contrib/pg_upgrade/function.c b/contrib/pg_upgrade/function.c index d9b54b8..9b3c64c 100644 --- a/contrib/pg_upgrade/function.c +++ b/contrib/pg_upgrade/function.c @@ -58,25 +58,25 @@ install_support_functions(migratorContext *ctx) "LANGUAGE C STRICT;")); PQclear(executeQueryOrDie(ctx, conn, "CREATE OR REPLACE FUNCTION " - " binary_upgrade.set_next_heap_relfilenode(OID) " + " binary_upgrade.set_next_pg_enum_oid(OID) " "RETURNS VOID " "AS '$libdir/pg_upgrade_support' " "LANGUAGE C STRICT;")); PQclear(executeQueryOrDie(ctx, conn, "CREATE OR REPLACE FUNCTION " - " binary_upgrade.set_next_toast_relfilenode(OID) " + " binary_upgrade.set_next_heap_relfilenode(OID) " "RETURNS VOID " "AS '$libdir/pg_upgrade_support' " "LANGUAGE C STRICT;")); PQclear(executeQueryOrDie(ctx, conn, "CREATE OR REPLACE FUNCTION " - " binary_upgrade.set_next_index_relfilenode(OID) " + " binary_upgrade.set_next_toast_relfilenode(OID) " "RETURNS VOID " "AS '$libdir/pg_upgrade_support' " "LANGUAGE C STRICT;")); PQclear(executeQueryOrDie(ctx, conn, "CREATE OR REPLACE FUNCTION " - " binary_upgrade.add_pg_enum_label(OID, OID, NAME) " + " binary_upgrade.set_next_index_relfilenode(OID) " "RETURNS VOID " "AS '$libdir/pg_upgrade_support' " "LANGUAGE C STRICT;")); diff --git a/contrib/pg_upgrade_support/pg_upgrade_support.c b/contrib/pg_upgrade_support/pg_upgrade_support.c index 50f9efd..7af7d4d 100644 --- a/contrib/pg_upgrade_support/pg_upgrade_support.c +++ b/contrib/pg_upgrade_support/pg_upgrade_support.c @@ -27,6 +27,7 @@ PG_MODULE_MAGIC; extern PGDLLIMPORT Oid binary_upgrade_next_pg_type_oid; extern PGDLLIMPORT Oid binary_upgrade_next_pg_type_array_oid; extern PGDLLIMPORT Oid binary_upgrade_next_pg_type_toast_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_pg_enum_oid; extern PGDLLIMPORT Oid binary_upgrade_next_heap_relfilenode; extern PGDLLIMPORT Oid binary_upgrade_next_toast_relfilenode; extern PGDLLIMPORT Oid binary_upgrade_next_index_relfilenode; @@ -34,18 +35,18 @@ extern PGDLLIMPORT Oid binary_upgrade_next_index_relfilenode; Datum set_next_pg_type_oid(PG_FUNCTION_ARGS); Datum set_next_pg_type_array_oid(PG_FUNCTION_ARGS); Datum set_next_pg_type_toast_oid(PG_FUNCTION_ARGS); +Datum set_next_pg_enum_oid(PG_FUNCTION_ARGS); Datum set_next_heap_relfilenode(PG_FUNCTION_ARGS); Datum set_next_toast_relfilenode(PG_FUNCTION_ARGS); Datum set_next_index_relfilenode(PG_FUNCTION_ARGS); -Datum add_pg_enum_label(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(set_next_pg_type_oid); PG_FUNCTION_INFO_V1(set_next_pg_type_array_oid); PG_FUNCTION_INFO_V1(set_next_pg_type_toast_oid); +PG_FUNCTION_INFO_V1(set_next_pg_enum_oid); PG_FUNCTION_INFO_V1(set_next_heap_relfilenode); PG_FUNCTION_INFO_V1(set_next_toast_relfilenode); PG_FUNCTION_INFO_V1(set_next_index_relfilenode); -PG_FUNCTION_INFO_V1(add_pg_enum_label); Datum set_next_pg_type_oid(PG_FUNCTION_ARGS) @@ -78,6 +79,16 @@ set_next_pg_type_toast_oid(PG_FUNCTION_ARGS) } Datum +set_next_pg_enum_oid(PG_FUNCTION_ARGS) +{ + Oid enumoid = PG_GETARG_OID(0); + + binary_upgrade_next_pg_enum_oid = enumoid; + + PG_RETURN_VOID(); +} + +Datum set_next_heap_relfilenode(PG_FUNCTION_ARGS) { Oid relfilenode = PG_GETARG_OID(0); @@ -106,17 +117,3 @@ set_next_index_relfilenode(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } - -Datum -add_pg_enum_label(PG_FUNCTION_ARGS) -{ - Oid enumoid = PG_GETARG_OID(0); - Oid typoid = PG_GETARG_OID(1); - Name label = PG_GETARG_NAME(2); - - EnumValuesCreate(typoid, list_make1(makeString(NameStr(*label))), - enumoid); - - PG_RETURN_VOID(); -} - diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index a1d951a..3ef4e2d 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -854,7 +854,9 @@ AddNewRelationType(const char *typeName, 'x', /* fully TOASTable */ -1, /* typmod */ 0, /* array dimensions for typBaseType */ - false); /* Type NOT NULL */ + false, /* Type NOT NULL */ + -1, /* no enum labels */ + false); /* type is not an enum, so not sorted */ } /* -------------------------------- @@ -1086,7 +1088,9 @@ heap_create_with_catalog(const char *relname, 'x', /* fully TOASTable */ -1, /* typmod */ 0, /* array dimensions for typBaseType */ - false); /* Type NOT NULL */ + false, /* Type NOT NULL */ + -1, /* no enum labels */ + false); /* type is not an enum, so not sorted */ pfree(relarrayname); } diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c index 578f8c5..d104d77 100644 --- a/src/backend/catalog/pg_enum.c +++ b/src/backend/catalog/pg_enum.c @@ -18,12 +18,202 @@ #include "catalog/catalog.h" #include "catalog/indexing.h" #include "catalog/pg_enum.h" +#include "catalog/pg_type.h" +#include "utils/lsyscache.h" +#include "utils/syscache.h" #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/rel.h" #include "utils/tqual.h" static int oid_cmp(const void *p1, const void *p2); +static int sort_order_cmp(const void *p1, const void *p2); + +Oid binary_upgrade_next_pg_enum_oid = InvalidOid; + +/* + * AddEnumLabel + * Add a new label to the enum set. By default it goes at + * the end, but the user can choose to place it before or + * after any existing set member. + * + * Returns true iff the labels are sorted by oid after the addition. + */ + +bool +AddEnumLabel(Oid enumTypeOid, + char *newVal, + char *neighbour, + bool newValIsAfter, + int nelems, + bool elems_are_sorted) +{ + Oid newOid; + Relation pg_enum; + TupleDesc tupDesc; + Datum values[Natts_pg_enum]; + bool nulls[Natts_pg_enum]; + NameData enumlabel; + HeapTuple enum_tup; + bool result = elems_are_sorted; + int newelemorder; + + /* check length of new label is ok */ + if (strlen(newVal) > (NAMEDATALEN - 1)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("invalid enum label \"%s\"", newVal), + errdetail("Labels must be %d characters or less.", + NAMEDATALEN - 1))); + + /* get a new OID for the label */ + pg_enum = heap_open(EnumRelationId, RowExclusiveLock); + + if (OidIsValid(binary_upgrade_next_pg_enum_oid)) + { + if (neighbour != NULL) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("BEFORE/AFTER incompatible with binary upgrade."))); + + newOid = binary_upgrade_next_pg_enum_oid; + binary_upgrade_next_pg_enum_oid = InvalidOid; + } + else + { + /* non upgrade case */ + newOid = GetNewOid(pg_enum); + } + + if (neighbour == NULL) + { + /* + * Put the new label at the end of the list. + * No change to existing tuples is required. + */ + newelemorder = nelems + 1; + /* are the elements still sorted? */ + if (elems_are_sorted) + { + CatCList *list; + int i; + bool still_sorted = true; + + list = SearchSysCacheList1(ENUMTYPOIDNAME, + ObjectIdGetDatum(enumTypeOid)); + for (i = 0; i < nelems; i++) + { + HeapTuple tup = &(list->members[i]->tuple); + Form_pg_enum en = (Form_pg_enum) GETSTRUCT(tup); + + if (en->enumsortorder == nelems) + { + if (HeapTupleGetOid(tup) > newOid) + still_sorted = false; + break; + } + } + ReleaseCatCacheList(list); + if (! still_sorted) + result = false; + } + } + else + { + /* BEFORE or AFTER specified */ + CatCList *list; + int i; + HeapTuple *existing; + HeapTuple nbr = NULL; + Form_pg_enum nbr_en; + + /* get a list of the existing elements and sort them by enumsortorder */ + list = SearchSysCacheList1(ENUMTYPOIDNAME, + ObjectIdGetDatum(enumTypeOid)); + existing = palloc(nelems * sizeof(HeapTuple)); + + for (i = 0; i < nelems; i++) + existing[i] = &(list->members[i]->tuple); + + qsort(existing, nelems, sizeof(HeapTuple), sort_order_cmp); + + /* locate the neighbour element */ + for (i = 0; i < nelems; i++) + { + Form_pg_enum exists_en; + exists_en = (Form_pg_enum) GETSTRUCT(existing[i]); + if (strcmp(NameStr(exists_en->enumlabel),neighbour) == 0) + nbr = existing[i]; + + } + + if (nbr == NULL) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("\"%s\" is not an existing label.", neighbour))); + } + + nbr_en = (Form_pg_enum) GETSTRUCT(nbr); + + /* + * If BEFORE was specified, the new label goes in the neighbour's + * position. Otherwise, it goes in the position after that. + */ + newelemorder = nbr_en->enumsortorder; + if (newValIsAfter) + newelemorder++; + + /* + * Add 1 to the sortorder of all the labels after where the + * new label goes. Do it from the end back so we don't get + * uniqueness violations. + */ + for (i = nelems - 1; i>= 0; i--) + { + HeapTuple newtup; + Form_pg_enum exst_en = (Form_pg_enum) GETSTRUCT(existing[i]); + if (exst_en->enumsortorder < newelemorder) + break; + + newtup = heap_copytuple(existing[i]); + exst_en = (Form_pg_enum) GETSTRUCT(newtup); + exst_en->enumsortorder ++; + + simple_heap_update(pg_enum, &newtup->t_self, newtup); + + CatalogUpdateIndexes(pg_enum, newtup); + + } + + ReleaseCatCacheList(list); + + /* are the labels sorted by OID? */ + if (result && newelemorder > 1) + result = newOid > HeapTupleGetOid(existing[newelemorder-2]); + if (result && newelemorder < nelems + 1) + result = newOid < HeapTupleGetOid(existing[newelemorder-1]); + + } + + /* set up the new entry */ + tupDesc = pg_enum->rd_att; + memset(nulls, false, sizeof(nulls)); + values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid); + namestrcpy(&enumlabel, newVal); + values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel); + values[Anum_pg_enum_enumsortorder -1] = Int32GetDatum(newelemorder); + enum_tup = heap_form_tuple(tupDesc, values, nulls); + HeapTupleSetOid(enum_tup, newOid); + simple_heap_insert(pg_enum, enum_tup); + CatalogUpdateIndexes(pg_enum, enum_tup); + heap_freetuple(enum_tup); + + heap_close(pg_enum, RowExclusiveLock); + + return result; + +} /* @@ -33,8 +223,7 @@ static int oid_cmp(const void *p1, const void *p2); * vals is a list of Value strings. */ void -EnumValuesCreate(Oid enumTypeOid, List *vals, - Oid binary_upgrade_next_pg_enum_oid) +EnumValuesCreate(Oid enumTypeOid, List *vals) { Relation pg_enum; TupleDesc tupDesc; @@ -50,9 +239,9 @@ EnumValuesCreate(Oid enumTypeOid, List *vals, num_elems = list_length(vals); /* - * XXX we do not bother to check the list of values for duplicates --- if + * We do not bother to check the list of values for duplicates --- if * you have any, you'll get a less-than-friendly unique-index violation. - * Is it worth trying harder? + * It is probably not worth trying harder. */ pg_enum = heap_open(EnumRelationId, RowExclusiveLock); @@ -62,35 +251,24 @@ EnumValuesCreate(Oid enumTypeOid, List *vals, * Allocate oids */ oids = (Oid *) palloc(num_elems * sizeof(Oid)); - if (OidIsValid(binary_upgrade_next_pg_enum_oid)) - { - if (num_elems != 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("EnumValuesCreate() can only set a single OID"))); - oids[0] = binary_upgrade_next_pg_enum_oid; - binary_upgrade_next_pg_enum_oid = InvalidOid; - } - else + + /* + * While this method does not absolutely guarantee that we generate no + * duplicate oids (since we haven't entered each oid into the table + * before allocating the next), trouble could only occur if the oid + * counter wraps all the way around before we finish. Which seems + * unlikely. + */ + for (elemno = 0; elemno < num_elems; elemno++) { /* - * While this method does not absolutely guarantee that we generate no - * duplicate oids (since we haven't entered each oid into the table - * before allocating the next), trouble could only occur if the oid - * counter wraps all the way around before we finish. Which seems - * unlikely. + * The pg_enum.oid is stored in user tables. This oid must be + * preserved by binary upgrades. */ - for (elemno = 0; elemno < num_elems; elemno++) - { - /* - * The pg_enum.oid is stored in user tables. This oid must be - * preserved by binary upgrades. - */ - oids[elemno] = GetNewOid(pg_enum); - } - /* sort them, just in case counter wrapped from high to low */ - qsort(oids, num_elems, sizeof(Oid), oid_cmp); + oids[elemno] = GetNewOid(pg_enum); } + /* sort them, just in case counter wrapped from high to low */ + qsort(oids, num_elems, sizeof(Oid), oid_cmp); /* and make the entries */ memset(nulls, false, sizeof(nulls)); @@ -114,6 +292,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals, values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid); namestrcpy(&enumlabel, lab); values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel); + values[Anum_pg_enum_enumsortorder -1] = Int32GetDatum(elemno+1); tup = heap_form_tuple(tupDesc, values, nulls); HeapTupleSetOid(tup, oids[elemno]); @@ -164,7 +343,7 @@ EnumValuesDelete(Oid enumTypeOid) } -/* qsort comparison function */ +/* qsort comparison for oids */ static int oid_cmp(const void *p1, const void *p2) { @@ -177,3 +356,16 @@ oid_cmp(const void *p1, const void *p2) return 1; return 0; } + +/* qsort comparison function for tuples by sort order */ +static int +sort_order_cmp(const void *p1, const void *p2) +{ + HeapTuple v1 = *((const HeapTuple *) p1); + HeapTuple v2 = *((const HeapTuple *) p2); + Form_pg_enum en1 = (Form_pg_enum) GETSTRUCT(v1); + Form_pg_enum en2 = (Form_pg_enum) GETSTRUCT(v2); + + return en1->enumsortorder - en2->enumsortorder; +} + diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index c7efd6d..109ee0e 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -112,6 +112,8 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) values[i++] = ObjectIdGetDatum(InvalidOid); /* typbasetype */ values[i++] = Int32GetDatum(-1); /* typtypmod */ values[i++] = Int32GetDatum(0); /* typndims */ + values[i++] = Int32GetDatum(-1); /* typnlabels */ + values[i++] = BoolGetDatum(false); /* typsorted */ nulls[i++] = true; /* typdefaultbin */ nulls[i++] = true; /* typdefault */ @@ -204,7 +206,9 @@ TypeCreate(Oid newTypeOid, char storage, int32 typeMod, int32 typNDims, /* Array dimensions for baseType */ - bool typeNotNull) + bool typeNotNull, + int32 typeNLabels, + bool typeSorted) { Relation pg_type_desc; Oid typeObjectId; @@ -342,6 +346,8 @@ TypeCreate(Oid newTypeOid, values[i++] = ObjectIdGetDatum(baseType); /* typbasetype */ values[i++] = Int32GetDatum(typeMod); /* typtypmod */ values[i++] = Int32GetDatum(typNDims); /* typndims */ + values[i++] = Int32GetDatum(typeNLabels); /* typnlabels */ + values[i++] = BoolGetDatum(typeSorted); /* typsorted */ /* * initialize the default binary value for this type. Check for nulls of diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index fc80175..2ed8278 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -85,12 +85,11 @@ static Oid findTypeTypmodoutFunction(List *procname); static Oid findTypeAnalyzeFunction(List *procname, Oid typeOid); static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode); static void checkDomainOwner(HeapTuple tup, TypeName *typename); +static void checkEnumOwner(HeapTuple tup, TypeName *typename); static char *domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, int typMod, Constraint *constr, char *domainName); - - /* * DefineType * Registers a new base type. @@ -562,8 +561,9 @@ 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 */ + -1, /* no enum labels */ + false); /* type is not an enum, so not sorted */ /* * Create the array type that goes with it. */ @@ -601,7 +601,9 @@ 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 */ + -1, /* no enum labels */ + false); /* type is not an enum, so not sorted */ pfree(array_type); } @@ -1044,7 +1046,9 @@ DefineDomain(CreateDomainStmt *stmt) storage, /* TOAST strategy */ basetypeMod, /* typeMod value */ typNDims, /* Array dimensions for base type */ - typNotNull); /* Type NOT NULL */ + typNotNull, /* Type NOT NULL */ + -1, /* no enum labels */ + false); /* type is not an enum, so not sorted */ /* * Process constraints which refer to the domain ID returned by TypeCreate @@ -1094,6 +1098,9 @@ DefineEnum(CreateEnumStmt *stmt) AclResult aclresult; Oid old_type_oid; Oid enumArrayOid; + int num_labels; + + num_labels = list_length(stmt->vals); /* Convert list of names to a name and namespace */ enumNamespace = QualifiedNameGetCreationNamespace(stmt->typeName, @@ -1153,10 +1160,12 @@ 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 */ + num_labels, /* count enum labels */ + true); /* enums always start sorted */ /* Enter the enum's values into pg_enum */ - EnumValuesCreate(enumTypeOid, stmt->vals, InvalidOid); + EnumValuesCreate(enumTypeOid, stmt->vals); /* * Create the array type that goes with it. @@ -1192,11 +1201,88 @@ 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 */ + -1, /* no enum labels */ + false); /* type is not an enum, so not sorted */ pfree(enumArrayName); } +/* + * AlterEnum + * Registers a new label for an existing enum. + */ +void +AlterEnum (AlterEnumStmt *stmt) +{ + Oid enum_type_oid; + TypeName *typename; + bool sorted; + HeapTuple tup, newtup; + Relation rel; + Form_pg_type typTup; + + /* Make a TypeName so we can use standard type lookup machinery */ + typename = makeTypeNameFromNameList(stmt->typeName); + enum_type_oid = typenameTypeId(NULL, typename, NULL); + + /* Look up the row in the type table */ + rel = heap_open(TypeRelationId, RowExclusiveLock); + + tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(enum_type_oid)); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for type %u", enum_type_oid); + + /* Copy the syscache entry so we can scribble on it below */ + newtup = heap_copytuple(tup); + ReleaseSysCache(tup); + tup = newtup; + typTup = (Form_pg_type) GETSTRUCT(tup); + + /* Check it's an enum and check user has permission to ALTER the enum */ + checkEnumOwner(tup, typename); + + /* Add the new label */ + sorted = AddEnumLabel (enum_type_oid, stmt->newVal, + stmt->newValNeighbour, stmt->newValIsAfter, + typTup->typnlabels, typTup->typsorted); + + /* Update the row in pg_type */ + typTup->typnlabels += 1; + typTup->typsorted = sorted; + + simple_heap_update(rel, &tup->t_self, tup); + + CatalogUpdateIndexes(rel, tup); + + /* Clean up */ + heap_close(rel, RowExclusiveLock); +} + + +/* + * checkEnumOwner + * + * Check that the type is actually an enum and that the current user + * has permission to do ALTER TYPE on it. Throw an error if not. + */ +static void +checkEnumOwner(HeapTuple tup, TypeName *typename) +{ + Form_pg_type typTup = (Form_pg_type) GETSTRUCT(tup); + + /* Check that this is actually a domain */ + if (typTup->typtype != TYPTYPE_ENUM) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not an enum", + TypeNameToString(typename)))); + + /* Permission check: must own type */ + if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, + format_type_be(HeapTupleGetOid(tup))); +} /* * Find suitable I/O functions for a type. diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index b3e907a..59cfe96 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -2836,6 +2836,19 @@ _copyCreateEnumStmt(CreateEnumStmt *from) return newnode; } +static AlterEnumStmt * +_copyAlterEnumStmt(AlterEnumStmt *from) +{ + AlterEnumStmt *newnode = makeNode(AlterEnumStmt); + + COPY_NODE_FIELD(typeName); + COPY_STRING_FIELD(newVal); + COPY_STRING_FIELD(newValNeighbour); + COPY_SCALAR_FIELD(newValIsAfter); + + return newnode; +} + static ViewStmt * _copyViewStmt(ViewStmt *from) { @@ -3989,6 +4002,9 @@ copyObject(void *from) case T_CreateEnumStmt: retval = _copyCreateEnumStmt(from); break; + case T_AlterEnumStmt: + retval = _copyAlterEnumStmt(from); + break; case T_ViewStmt: retval = _copyViewStmt(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 7ec0923..900bf37 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1375,6 +1375,17 @@ _equalCreateEnumStmt(CreateEnumStmt *a, CreateEnumStmt *b) } static bool +_equalAlterEnumStmt(AlterEnumStmt *a, AlterEnumStmt *b) +{ + COMPARE_NODE_FIELD(typeName); + COMPARE_STRING_FIELD(newVal); + COMPARE_STRING_FIELD(newValNeighbour); + COMPARE_SCALAR_FIELD(newValIsAfter); + + return true; +} + +static bool _equalViewStmt(ViewStmt *a, ViewStmt *b) { COMPARE_NODE_FIELD(view); @@ -2678,6 +2689,9 @@ equal(void *a, void *b) case T_CreateEnumStmt: retval = _equalCreateEnumStmt(a, b); break; + case T_AlterEnumStmt: + retval = _equalAlterEnumStmt(a, b); + break; case T_ViewStmt: retval = _equalViewStmt(a, b); break; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index d5a0f29..9ef84aa 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -181,8 +181,8 @@ static TypeName *TableFuncTypeName(List *columns); } %type stmt schema_stmt - AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterFdwStmt - AlterForeignServerStmt AlterGroupStmt + AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterEnumStmt + AlterFdwStmt AlterForeignServerStmt AlterGroupStmt AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt AlterUserStmt AlterUserMappingStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt @@ -648,6 +648,7 @@ stmt : | AlterDatabaseSetStmt | AlterDefaultPrivilegesStmt | AlterDomainStmt + | AlterEnumStmt | AlterFdwStmt | AlterForeignServerStmt | AlterFunctionStmt @@ -3781,6 +3782,46 @@ enum_val_list: Sconst { $$ = lappend($1, makeString($3)); } ; +/***************************************************************************** + * + * ALTER TYPE enumtype ADD ... + * + *****************************************************************************/ + +AlterEnumStmt: + ALTER TYPE_P any_name ADD_P Sconst + { + AlterEnumStmt *n = makeNode(AlterEnumStmt); + n->typeName = $3; + n->newVal = $5; + n->newValNeighbour = NULL; + n->newValIsAfter = true; + + $$ = (Node *) n; + } + | ALTER TYPE_P any_name ADD_P Sconst BEFORE Sconst + { + AlterEnumStmt *n = makeNode(AlterEnumStmt); + n->typeName = $3; + n->newVal = $5; + n->newValNeighbour = $7; + n->newValIsAfter = false; + + $$ = (Node *) n; + } + | ALTER TYPE_P any_name ADD_P Sconst AFTER Sconst + { + AlterEnumStmt *n = makeNode(AlterEnumStmt); + n->typeName = $3; + n->newVal = $5; + n->newValNeighbour = $7; + n->newValIsAfter = true; + + $$ = (Node *) n; + } + ; + + /***************************************************************************** * diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 77ee926..39ea03e 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -189,6 +189,7 @@ check_xact_readonly(Node *parsetree) case T_CreateTrigStmt: case T_CompositeTypeStmt: case T_CreateEnumStmt: + case T_AlterEnumStmt: case T_ViewStmt: case T_DropCastStmt: case T_DropStmt: @@ -846,6 +847,10 @@ standard_ProcessUtility(Node *parsetree, DefineEnum((CreateEnumStmt *) parsetree); break; + case T_AlterEnumStmt: /* ALTER TYPE (enum) */ + AlterEnum((AlterEnumStmt *) parsetree); + break; + case T_ViewStmt: /* CREATE VIEW */ DefineView((ViewStmt *) parsetree, queryString); break; @@ -1846,6 +1851,10 @@ CreateCommandTag(Node *parsetree) tag = "CREATE TYPE"; break; + case T_AlterEnumStmt: + tag = "ALTER TYPE"; + break; + case T_ViewStmt: tag = "CREATE VIEW"; break; @@ -2384,6 +2393,10 @@ GetCommandLogLevel(Node *parsetree) lev = LOGSTMT_DDL; break; + case T_AlterEnumStmt: + lev = LOGSTMT_DDL; + break; + case T_ViewStmt: lev = LOGSTMT_DDL; break; diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c index 74cc0c2..63eab09 100644 --- a/src/backend/utils/adt/enum.c +++ b/src/backend/utils/adt/enum.c @@ -14,6 +14,7 @@ #include "postgres.h" #include "catalog/pg_enum.h" +#include "catalog/pg_type.h" #include "fmgr.h" #include "utils/array.h" #include "utils/builtins.h" @@ -22,9 +23,26 @@ #include "libpq/pqformat.h" #include "miscadmin.h" +typedef struct +{ + Oid enum_oid; + int32 sort_order; +} enum_sort; + +typedef struct +{ + Oid enumtypoid; + bool oids_are_sorted; + int sort_list_length; + int label_count; + enum_sort sort_order_list[1]; +} enum_sort_cache; + + static ArrayType *enum_range_internal(Oid enumtypoid, Oid lower, Oid upper); -static int enum_elem_cmp(const void *left, const void *right); +static int enum_sort_cmp(const void *left, const void *right); +static int enum_oid_cmp(const void *left, const void *right); /* Basic I/O support */ @@ -155,13 +173,142 @@ enum_send(PG_FUNCTION_ARGS) /* Comparison functions and related */ +static inline int +enum_ccmp(Oid arg1, Oid arg2, FunctionCallInfo fcinfo) +{ + + enum_sort_cache * mycache; + enum_sort *es1, *es2, srch; + int sort1, sort2; + bool added = false; + HeapTuple enum_tup, type_tup; + Form_pg_enum en; + Oid typeoid; + Form_pg_type typ; + + if (arg1 == arg2) + return 0; + + mycache = (enum_sort_cache *) fcinfo->flinfo->fn_extra; + if (mycache == NULL ) + { + enum_tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(arg1)); + en = (Form_pg_enum) GETSTRUCT(enum_tup); + typeoid = en->enumtypid; + type_tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeoid)); + typ = (Form_pg_type) GETSTRUCT(type_tup); + if (typ->typtype != 'e') + elog(ERROR,"wrong type for oid %u",typeoid); + fcinfo->flinfo->fn_extra = + MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, + sizeof(enum_sort_cache) + + (typ->typnlabels * sizeof(enum_sort))); + mycache = (enum_sort_cache *) fcinfo->flinfo->fn_extra; + mycache->enumtypoid = typeoid; + mycache->sort_list_length = 1; + mycache->label_count = typ->typnlabels; + mycache->oids_are_sorted = typ->typsorted; + mycache->sort_order_list[0].enum_oid = arg1; + mycache->sort_order_list[0].sort_order = en->enumsortorder; + ReleaseSysCache(type_tup); + ReleaseSysCache(enum_tup); + } + + if (mycache->oids_are_sorted) + return arg1 - arg2; + + srch.enum_oid = arg1; + es1 = bsearch(&srch, + mycache->sort_order_list, + mycache->sort_list_length, + sizeof(enum_sort), + enum_oid_cmp); + srch.enum_oid = arg2; + es2 = bsearch(&srch, + mycache->sort_order_list, + mycache->sort_list_length, + sizeof(enum_sort), + enum_oid_cmp); + + if (es1 == NULL) + { + + enum_tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(arg1)); + en = (Form_pg_enum) GETSTRUCT(enum_tup); + mycache->sort_order_list[mycache->sort_list_length].enum_oid = arg1; + sort1 = en->enumsortorder; + mycache->sort_order_list[mycache->sort_list_length].sort_order = + sort1; + ReleaseSysCache(enum_tup); + mycache->sort_list_length ++; + added = true; + } + else + { + /* already in cache */ + sort1 = es1->sort_order; + } + + if (es2 == NULL) + { + + enum_tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(arg2)); + en = (Form_pg_enum) GETSTRUCT(enum_tup); + sort2 = en->enumsortorder; + mycache->sort_order_list[mycache->sort_list_length].enum_oid = arg2; + mycache->sort_order_list[mycache->sort_list_length].sort_order = + sort2; + ReleaseSysCache(enum_tup); + mycache->sort_list_length ++; + added = true; + } + else + { + /* already in cache */ + sort2 = es2->sort_order; + } + + if (added) + { + /* + * If we have more than a handful, just fetch them all, so we limit + * the number of sort operations required. + */ + if (mycache->sort_list_length > 10 && + mycache->sort_list_length < mycache->label_count) + { + CatCList *nlist; + int num, i; + + nlist = SearchSysCacheList1(ENUMTYPOIDNAME, + ObjectIdGetDatum(mycache->enumtypoid)); + num = nlist->n_members; + for (i = 0; i < num; i++) + { + HeapTuple tup = &(nlist->members[i]->tuple); + Form_pg_enum en = (Form_pg_enum) GETSTRUCT(tup); + + mycache->sort_order_list[i].enum_oid = HeapTupleGetOid(tup); + mycache->sort_order_list[i].sort_order = en->enumsortorder; + } + + ReleaseCatCacheList(nlist); + } + + qsort(mycache->sort_order_list,mycache->sort_list_length, + sizeof(enum_sort),enum_oid_cmp); + } + + return sort1 - sort2; +} + Datum enum_lt(PG_FUNCTION_ARGS) { Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); - PG_RETURN_BOOL(a < b); + PG_RETURN_BOOL(enum_ccmp(a,b,fcinfo) < 0); } Datum @@ -170,7 +317,7 @@ enum_le(PG_FUNCTION_ARGS) Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); - PG_RETURN_BOOL(a <= b); + PG_RETURN_BOOL(enum_ccmp(a,b,fcinfo) <= 0); } Datum @@ -197,7 +344,7 @@ enum_ge(PG_FUNCTION_ARGS) Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); - PG_RETURN_BOOL(a >= b); + PG_RETURN_BOOL(enum_ccmp(a,b,fcinfo) >= 0); } Datum @@ -206,7 +353,7 @@ enum_gt(PG_FUNCTION_ARGS) Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); - PG_RETURN_BOOL(a > b); + PG_RETURN_BOOL(enum_ccmp(a,b,fcinfo) > 0); } Datum @@ -215,7 +362,7 @@ enum_smaller(PG_FUNCTION_ARGS) Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); - PG_RETURN_OID(a <= b ? a : b); + PG_RETURN_OID(enum_ccmp(a,b,fcinfo) < 0 ? a : b); } Datum @@ -224,7 +371,7 @@ enum_larger(PG_FUNCTION_ARGS) Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); - PG_RETURN_OID(a >= b ? a : b); + PG_RETURN_OID(enum_ccmp(a,b,fcinfo) > 0 ? a : b); } Datum @@ -233,10 +380,10 @@ enum_cmp(PG_FUNCTION_ARGS) Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); - if (a > b) - PG_RETURN_INT32(1); - else if (a == b) + if (a == b) PG_RETURN_INT32(0); + else if (enum_ccmp(a,b,fcinfo) > 0) + PG_RETURN_INT32(1); else PG_RETURN_INT32(-1); } @@ -248,6 +395,7 @@ enum_first(PG_FUNCTION_ARGS) { Oid enumtypoid; Oid min = InvalidOid; + int min_sort = -1; /* value will never in fact be used */ CatCList *list; int num, i; @@ -267,10 +415,14 @@ enum_first(PG_FUNCTION_ARGS) num = list->n_members; for (i = 0; i < num; i++) { - Oid valoid = HeapTupleHeaderGetOid(list->members[i]->tuple.t_data); - - if (!OidIsValid(min) || valoid < min) - min = valoid; + HeapTuple tup = &(list->members[i]->tuple); + Form_pg_enum en = (Form_pg_enum) GETSTRUCT(tup); + + if (!OidIsValid(min) || en->enumsortorder < min_sort) + { + min = HeapTupleGetOid(tup); + min_sort = en->enumsortorder; + } } ReleaseCatCacheList(list); @@ -287,6 +439,7 @@ enum_last(PG_FUNCTION_ARGS) { Oid enumtypoid; Oid max = InvalidOid; + int max_sort = -1; /* value will never in fact be used */ CatCList *list; int num, i; @@ -306,10 +459,14 @@ enum_last(PG_FUNCTION_ARGS) num = list->n_members; for (i = 0; i < num; i++) { - Oid valoid = HeapTupleHeaderGetOid(list->members[i]->tuple.t_data); - - if (!OidIsValid(max) || valoid > max) - max = valoid; + HeapTuple tup = &(list->members[i]->tuple); + Form_pg_enum en = (Form_pg_enum) GETSTRUCT(tup); + + if (!OidIsValid(max) || en->enumsortorder > max_sort) + { + max = HeapTupleGetOid(tup); + max_sort = en->enumsortorder; + } } ReleaseCatCacheList(list); @@ -382,46 +539,76 @@ enum_range_internal(Oid enumtypoid, Oid lower, Oid upper) i, j; Datum *elems; + enum_sort *sort_items; + bool left_found; list = SearchSysCacheList1(ENUMTYPOIDNAME, ObjectIdGetDatum(enumtypoid)); total = list->n_members; elems = (Datum *) palloc(total * sizeof(Datum)); + sort_items = (enum_sort *) palloc(total * sizeof(enum_sort)); - j = 0; for (i = 0; i < total; i++) { - Oid val = HeapTupleGetOid(&(list->members[i]->tuple)); + HeapTuple tup = &(list->members[i]->tuple); + Form_pg_enum en = (Form_pg_enum) GETSTRUCT(tup); + + sort_items[i].enum_oid = HeapTupleGetOid(tup); + sort_items[i].sort_order = en->enumsortorder; - if ((!OidIsValid(lower) || lower <= val) && - (!OidIsValid(upper) || val <= upper)) - elems[j++] = ObjectIdGetDatum(val); } /* shouldn't need the cache anymore */ ReleaseCatCacheList(list); - /* sort results into OID order */ - qsort(elems, j, sizeof(Datum), enum_elem_cmp); + /* sort results into sort_order sequence */ + qsort(sort_items, total, sizeof(enum_sort), enum_sort_cmp); + + j = 0; + left_found = !OidIsValid(lower); + for (i=0; i < total; i++) + { + if (! left_found && lower == sort_items[i].enum_oid) + left_found = true; + + if (left_found) + elems[j++] = ObjectIdGetDatum(sort_items[i].enum_oid); + + if (OidIsValid(upper) && upper == sort_items[i].enum_oid) + break; + } /* note this hardwires some details about the representation of Oid */ result = construct_array(elems, j, enumtypoid, sizeof(Oid), true, 'i'); pfree(elems); + pfree(sort_items); return result; } -/* qsort comparison function for Datums that are OIDs */ +/* + * qsort comparison using sort order, for range routines + */ static int -enum_elem_cmp(const void *left, const void *right) +enum_sort_cmp(const void *left, const void *right) { - Oid l = DatumGetObjectId(*((const Datum *) left)); - Oid r = DatumGetObjectId(*((const Datum *) right)); - - if (l < r) - return -1; - if (l > r) - return 1; - return 0; + enum_sort *l = (enum_sort *) left; + enum_sort *r = (enum_sort *) right; + + return l->sort_order - r->sort_order; } + +/* + * qsort comparison using OID order for comparison search cache + */ +static int +enum_oid_cmp(const void *es1, const void *es2) +{ + enum_sort *p1, *p2; + p1 = (enum_sort *)es1; + p2 = (enum_sort *)es2; + return p1->enum_oid - p2->enum_oid; +} + + diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 01e1a48..94ae650 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -6605,17 +6605,24 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo) PQExpBuffer query = createPQExpBuffer(); PGresult *res; int num, - i; + i; Oid enum_oid; char *label; /* Set proper schema search path so regproc references list correctly */ selectSourceSchema(tyinfo->dobj.namespace->dobj.name); - appendPQExpBuffer(query, "SELECT oid, enumlabel " - "FROM pg_catalog.pg_enum " - "WHERE enumtypid = '%u'" - "ORDER BY oid", + if (fout->remoteVersion > 90000) + appendPQExpBuffer(query, "SELECT oid, enumlabel " + "FROM pg_catalog.pg_enum " + "WHERE enumtypid = '%u'" + "ORDER BY enumsortorder", + tyinfo->dobj.catId.oid); + else + appendPQExpBuffer(query, "SELECT oid, enumlabel " + "FROM pg_catalog.pg_enum " + "WHERE enumtypid = '%u'" + "ORDER BY oid", tyinfo->dobj.catId.oid); res = PQexec(g_conn, query->data); @@ -6661,17 +6668,19 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo) { enum_oid = atooid(PQgetvalue(res, i, PQfnumber(res, "oid"))); label = PQgetvalue(res, i, PQfnumber(res, "enumlabel")); - + if (i == 0) appendPQExpBuffer(q, "\n-- For binary upgrade, must preserve pg_enum oids\n"); appendPQExpBuffer(q, - "SELECT binary_upgrade.add_pg_enum_label('%u'::pg_catalog.oid, " - "'%u'::pg_catalog.oid, ", - enum_oid, tyinfo->dobj.catId.oid); - appendStringLiteralAH(q, label, fout); - appendPQExpBuffer(q, ");\n"); + "SELECT binary_upgrade.set_next_pg_enum_oid('%u'::pg_catalog.oid);\n", + enum_oid); + appendPQExpBuffer(q, "ALTER TYPE %s.", + fmtId(tyinfo->dobj.namespace->dobj.name)); + appendPQExpBuffer(q, "%s ADD ", + fmtId(tyinfo->dobj.name)); + appendStringLiteralAH(q, label, fout); + appendPQExpBuffer(q, ";\n\n"); } - appendPQExpBuffer(q, "\n"); } ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index e56e15f..8db3800 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -147,6 +147,8 @@ DECLARE_UNIQUE_INDEX(pg_enum_oid_index, 3502, on pg_enum using btree(oid oid_ops #define EnumOidIndexId 3502 DECLARE_UNIQUE_INDEX(pg_enum_typid_label_index, 3503, on pg_enum using btree(enumtypid oid_ops, enumlabel name_ops)); #define EnumTypIdLabelIndexId 3503 +DECLARE_UNIQUE_INDEX(pg_enum_typid_sortorder_index, 3539, on pg_enum using btree(enumtypid oid_ops, enumsortorder int4_ops)); +#define EnumTypIdSortOrderIndexId 3539 /* This following index is not used for a cache and is not unique */ DECLARE_INDEX(pg_index_indrelid_index, 2678, on pg_index using btree(indrelid oid_ops)); diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index de34576..184cfb3 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -132,7 +132,7 @@ typedef FormData_pg_class *Form_pg_class; */ /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */ -DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f f r 28 0 t f f f f f 3 _null_ _null_ )); +DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f f r 30 0 t f f f f f 3 _null_ _null_ )); DESCR(""); DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f f r 19 0 f f f f f f 3 _null_ _null_ )); DESCR(""); diff --git a/src/include/catalog/pg_enum.h b/src/include/catalog/pg_enum.h index 3a1df77..b85f9cf 100644 --- a/src/include/catalog/pg_enum.h +++ b/src/include/catalog/pg_enum.h @@ -35,6 +35,7 @@ CATALOG(pg_enum,3501) { Oid enumtypid; /* OID of owning enum type */ NameData enumlabel; /* text representation of enum value */ + int4 enumsortorder; /* sort order for this enum label */ } FormData_pg_enum; /* ---------------- @@ -48,9 +49,10 @@ typedef FormData_pg_enum *Form_pg_enum; * compiler constants for pg_enum * ---------------- */ -#define Natts_pg_enum 2 +#define Natts_pg_enum 3 #define Anum_pg_enum_enumtypid 1 #define Anum_pg_enum_enumlabel 2 +#define Anum_pg_enum_enumsortorder 3 /* ---------------- * pg_enum has no initial contents @@ -60,8 +62,9 @@ typedef FormData_pg_enum *Form_pg_enum; /* * prototypes for functions in pg_enum.c */ -extern void EnumValuesCreate(Oid enumTypeOid, List *vals, - Oid binary_upgrade_next_pg_enum_oid); +extern void EnumValuesCreate(Oid enumTypeOid, List *vals); extern void EnumValuesDelete(Oid enumTypeOid); +extern bool AddEnumLabel(Oid enumTypeOid, char *newVal, char *neighbour, + bool newValIsAfter, int nelems, bool elems_are_sorted); #endif /* PG_ENUM_H */ diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index b2e14ce..3ea2118 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -194,6 +194,18 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO */ int4 typndims; + /* + * typnlabels, contains a count on the number of labels an enum type has, + * -1 for a non-enum type. + */ + int4 typnlabels; + + /* + * typsorted is true if the oids of an enum type reflect the type's sort + * order, false otherwise including for a non-enum type. + */ + bool typsorted; + /* * If typdefaultbin is not NULL, it is the nodeToString representation of * a default expression for the type. Currently this is only used for @@ -224,7 +236,7 @@ typedef FormData_pg_type *Form_pg_type; * compiler constants for pg_type * ---------------- */ -#define Natts_pg_type 28 +#define Natts_pg_type 30 #define Anum_pg_type_typname 1 #define Anum_pg_type_typnamespace 2 #define Anum_pg_type_typowner 3 @@ -251,8 +263,10 @@ typedef FormData_pg_type *Form_pg_type; #define Anum_pg_type_typbasetype 24 #define Anum_pg_type_typtypmod 25 #define Anum_pg_type_typndims 26 -#define Anum_pg_type_typdefaultbin 27 -#define Anum_pg_type_typdefault 28 +#define Anum_pg_type_typnlabels 27 +#define Anum_pg_type_typsorted 28 +#define Anum_pg_type_typdefaultbin 29 +#define Anum_pg_type_typdefault 30 /* ---------------- @@ -269,83 +283,83 @@ typedef FormData_pg_type *Form_pg_type; */ /* OIDS 1 - 99 */ -DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b B t t \054 0 0 1000 boolin boolout boolrecv boolsend - - - c p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b B t t \054 0 0 1000 boolin boolout boolrecv boolsend - - - c p f 0 -1 0 -1 f _null_ _null_ )); DESCR("boolean, 'true'/'false'"); #define BOOLOID 16 -DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b U f t \054 0 0 1001 byteain byteaout bytearecv byteasend - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b U f t \054 0 0 1001 byteain byteaout bytearecv byteasend - - - i x f 0 -1 0 -1 f _null_ _null_ )); DESCR("variable-length string, binary values escaped"); #define BYTEAOID 17 -DATA(insert OID = 18 ( char PGNSP PGUID 1 t b S f t \054 0 0 1002 charin charout charrecv charsend - - - c p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 18 ( char PGNSP PGUID 1 t b S f t \054 0 0 1002 charin charout charrecv charsend - - - c p f 0 -1 0 -1 f _null_ _null_ )); DESCR("single character"); #define CHAROID 18 -DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 -1 f _null_ _null_ )); DESCR("63-character type for storing system identifiers"); #define NAMEOID 19 -DATA(insert OID = 20 ( int8 PGNSP PGUID 8 FLOAT8PASSBYVAL b N f t \054 0 0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 20 ( int8 PGNSP PGUID 8 FLOAT8PASSBYVAL b N f t \054 0 0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("~18 digit integer, 8-byte storage"); #define INT8OID 20 -DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b N f t \054 0 0 1005 int2in int2out int2recv int2send - - - s p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b N f t \054 0 0 1005 int2in int2out int2recv int2send - - - s p f 0 -1 0 -1 f _null_ _null_ )); DESCR("-32 thousand to 32 thousand, 2-byte storage"); #define INT2OID 21 -DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b A f t \054 0 21 1006 int2vectorin int2vectorout int2vectorrecv int2vectorsend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b A f t \054 0 21 1006 int2vectorin int2vectorout int2vectorrecv int2vectorsend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("array of int2, used in system tables"); #define INT2VECTOROID 22 -DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b N f t \054 0 0 1007 int4in int4out int4recv int4send - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b N f t \054 0 0 1007 int4in int4out int4recv int4send - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("-2 billion to 2 billion integer, 4-byte storage"); #define INT4OID 23 -DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b N f t \054 0 0 1008 regprocin regprocout regprocrecv regprocsend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b N f t \054 0 0 1008 regprocin regprocout regprocrecv regprocsend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("registered procedure"); #define REGPROCOID 24 -DATA(insert OID = 25 ( text PGNSP PGUID -1 f b S t t \054 0 0 1009 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 25 ( text PGNSP PGUID -1 f b S t t \054 0 0 1009 textin textout textrecv textsend - - - i x f 0 -1 0 -1 f _null_ _null_ )); DESCR("variable-length string, no limit specified"); #define TEXTOID 25 -DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b N t t \054 0 0 1028 oidin oidout oidrecv oidsend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b N t t \054 0 0 1028 oidin oidout oidrecv oidsend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("object identifier(oid), maximum 4 billion"); #define OIDOID 26 -DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b U f t \054 0 0 1010 tidin tidout tidrecv tidsend - - - s p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b U f t \054 0 0 1010 tidin tidout tidrecv tidsend - - - s p f 0 -1 0 -1 f _null_ _null_ )); DESCR("(block, offset), physical location of tuple"); #define TIDOID 27 -DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b U f t \054 0 0 1011 xidin xidout xidrecv xidsend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b U f t \054 0 0 1011 xidin xidout xidrecv xidsend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("transaction id"); #define XIDOID 28 -DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b U f t \054 0 0 1012 cidin cidout cidrecv cidsend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b U f t \054 0 0 1012 cidin cidout cidrecv cidsend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("command identifier type, sequence in transaction id"); #define CIDOID 29 -DATA(insert OID = 30 ( oidvector PGNSP PGUID -1 f b A f t \054 0 26 1013 oidvectorin oidvectorout oidvectorrecv oidvectorsend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 30 ( oidvector PGNSP PGUID -1 f b A f t \054 0 26 1013 oidvectorin oidvectorout oidvectorrecv oidvectorsend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("array of oids, used in system tables"); #define OIDVECTOROID 30 /* hand-built rowtype entries for bootstrapped catalogs */ /* NB: OIDs assigned here must match the BKI_ROWTYPE_OID declarations */ -DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c C f t \054 1247 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 75 ( pg_attribute PGNSP PGUID -1 f c C f t \054 1249 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c C f t \054 1255 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c C f t \054 1259 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c C f t \054 1247 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 75 ( pg_attribute PGNSP PGUID -1 f c C f t \054 1249 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c C f t \054 1255 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c C f t \054 1259 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); /* OIDS 100 - 199 */ -DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b U f t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b U f t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); DESCR("XML content"); #define XMLOID 142 -DATA(insert OID = 143 ( _xml PGNSP PGUID -1 f b A f t \054 0 142 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 143 ( _xml PGNSP PGUID -1 f b A f t \054 0 142 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); /* OIDS 200 - 299 */ -DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b U f t \054 0 0 0 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b U f t \054 0 0 0 smgrin smgrout - - - - - s p f 0 -1 0 -1 f _null_ _null_ )); DESCR("storage manager"); /* OIDS 300 - 399 */ @@ -355,231 +369,231 @@ DESCR("storage manager"); /* OIDS 500 - 599 */ /* OIDS 600 - 699 */ -DATA(insert OID = 600 ( point PGNSP PGUID 16 f b G f t \054 0 701 1017 point_in point_out point_recv point_send - - - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 600 ( point PGNSP PGUID 16 f b G f t \054 0 701 1017 point_in point_out point_recv point_send - - - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("geometric point '(x, y)'"); #define POINTOID 600 -DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b G f t \054 0 600 1018 lseg_in lseg_out lseg_recv lseg_send - - - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b G f t \054 0 600 1018 lseg_in lseg_out lseg_recv lseg_send - - - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("geometric line segment '(pt1,pt2)'"); #define LSEGOID 601 -DATA(insert OID = 602 ( path PGNSP PGUID -1 f b G f t \054 0 0 1019 path_in path_out path_recv path_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 602 ( path PGNSP PGUID -1 f b G f t \054 0 0 1019 path_in path_out path_recv path_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); DESCR("geometric path '(pt1,...)'"); #define PATHOID 602 -DATA(insert OID = 603 ( box PGNSP PGUID 32 f b G f t \073 0 600 1020 box_in box_out box_recv box_send - - - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 603 ( box PGNSP PGUID 32 f b G f t \073 0 600 1020 box_in box_out box_recv box_send - - - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("geometric box '(lower left,upper right)'"); #define BOXOID 603 -DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b G f t \054 0 0 1027 poly_in poly_out poly_recv poly_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b G f t \054 0 0 1027 poly_in poly_out poly_recv poly_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); DESCR("geometric polygon '(pt1,...)'"); #define POLYGONOID 604 -DATA(insert OID = 628 ( line PGNSP PGUID 32 f b G f t \054 0 701 629 line_in line_out line_recv line_send - - - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 628 ( line PGNSP PGUID 32 f b G f t \054 0 701 629 line_in line_out line_recv line_send - - - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("geometric line (not implemented)"); #define LINEOID 628 -DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b A f t \054 0 628 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b A f t \054 0 628 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); DESCR(""); /* OIDS 700 - 799 */ -DATA(insert OID = 700 ( float4 PGNSP PGUID 4 FLOAT4PASSBYVAL b N f t \054 0 0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 700 ( float4 PGNSP PGUID 4 FLOAT4PASSBYVAL b N f t \054 0 0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("single-precision floating point number, 4-byte storage"); #define FLOAT4OID 700 -DATA(insert OID = 701 ( float8 PGNSP PGUID 8 FLOAT8PASSBYVAL b N t t \054 0 0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 701 ( float8 PGNSP PGUID 8 FLOAT8PASSBYVAL b N t t \054 0 0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("double-precision floating point number, 8-byte storage"); #define FLOAT8OID 701 -DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b D f t \054 0 0 1023 abstimein abstimeout abstimerecv abstimesend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b D f t \054 0 0 1023 abstimein abstimeout abstimerecv abstimesend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("absolute, limited-range date and time (Unix system time)"); #define ABSTIMEOID 702 -DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b T f t \054 0 0 1024 reltimein reltimeout reltimerecv reltimesend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b T f t \054 0 0 1024 reltimein reltimeout reltimerecv reltimesend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("relative, limited-range time interval (Unix delta time)"); #define RELTIMEOID 703 -DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b T f t \054 0 0 1025 tintervalin tintervalout tintervalrecv tintervalsend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b T f t \054 0 0 1025 tintervalin tintervalout tintervalrecv tintervalsend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("(abstime,abstime), time interval"); #define TINTERVALOID 704 -DATA(insert OID = 705 ( unknown PGNSP PGUID -2 f b X f t \054 0 0 0 unknownin unknownout unknownrecv unknownsend - - - c p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 705 ( unknown PGNSP PGUID -2 f b X f t \054 0 0 0 unknownin unknownout unknownrecv unknownsend - - - c p f 0 -1 0 -1 f _null_ _null_ )); DESCR(""); #define UNKNOWNOID 705 -DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b G f t \054 0 0 719 circle_in circle_out circle_recv circle_send - - - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b G f t \054 0 0 719 circle_in circle_out circle_recv circle_send - - - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("geometric circle '(center,radius)'"); #define CIRCLEOID 718 -DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b A f t \054 0 718 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 790 ( money PGNSP PGUID 8 FLOAT8PASSBYVAL b N f t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b A f t \054 0 718 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 790 ( money PGNSP PGUID 8 FLOAT8PASSBYVAL b N f t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("monetary amounts, $d,ddd.cc"); #define CASHOID 790 -DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b A f t \054 0 790 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b A f t \054 0 790 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); /* OIDS 800 - 899 */ -DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b U f t \054 0 0 1040 macaddr_in macaddr_out macaddr_recv macaddr_send - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b U f t \054 0 0 1040 macaddr_in macaddr_out macaddr_recv macaddr_send - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("XX:XX:XX:XX:XX:XX, MAC address"); #define MACADDROID 829 -DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b I t t \054 0 0 1041 inet_in inet_out inet_recv inet_send - - - i m f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b I t t \054 0 0 1041 inet_in inet_out inet_recv inet_send - - - i m f 0 -1 0 -1 f _null_ _null_ )); DESCR("IP address/netmask, host address, netmask optional"); #define INETOID 869 -DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b I f t \054 0 0 651 cidr_in cidr_out cidr_recv cidr_send - - - i m f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b I f t \054 0 0 651 cidr_in cidr_out cidr_recv cidr_send - - - i m f 0 -1 0 -1 f _null_ _null_ )); DESCR("network IP address/netmask, network address"); #define CIDROID 650 /* OIDS 900 - 999 */ /* OIDS 1000 - 1099 */ -DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b A f t \054 0 16 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b A f t \054 0 17 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b A f t \054 0 18 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b A f t \054 0 19 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b A f t \054 0 21 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b A f t \054 0 22 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b A f t \054 0 23 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b A f t \054 0 16 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b A f t \054 0 17 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b A f t \054 0 18 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b A f t \054 0 19 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b A f t \054 0 21 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b A f t \054 0 22 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b A f t \054 0 23 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); #define INT4ARRAYOID 1007 -DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b A f t \054 0 24 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b A f t \054 0 25 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b A f t \054 0 24 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b A f t \054 0 25 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); #define TEXTARRAYOID 1009 -DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b A f t \054 0 26 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b A f t \054 0 27 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b A f t \054 0 28 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b A f t \054 0 29 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b A f t \054 0 30 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b A f t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b A f t \054 0 1043 0 array_in array_out array_recv array_send varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b A f t \054 0 20 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b A f t \054 0 600 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b A f t \054 0 601 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b A f t \054 0 602 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b A f t \073 0 603 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 f b A f t \054 0 700 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b A f t \054 0 26 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b A f t \054 0 27 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b A f t \054 0 28 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b A f t \054 0 29 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b A f t \054 0 30 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b A f t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodin bpchartypmodout - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b A f t \054 0 1043 0 array_in array_out array_recv array_send varchartypmodin varchartypmodout - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b A f t \054 0 20 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b A f t \054 0 600 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b A f t \054 0 601 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b A f t \054 0 602 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b A f t \073 0 603 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 f b A f t \054 0 700 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); #define FLOAT4ARRAYOID 1021 -DATA(insert OID = 1022 ( _float8 PGNSP PGUID -1 f b A f t \054 0 701 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b A f t \054 0 702 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 f b A f t \054 0 703 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b A f t \054 0 704 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b A f t \054 0 604 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1033 ( aclitem PGNSP PGUID 12 f b U f t \054 0 0 1034 aclitemin aclitemout - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1022 ( _float8 PGNSP PGUID -1 f b A f t \054 0 701 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b A f t \054 0 702 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 f b A f t \054 0 703 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b A f t \054 0 704 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b A f t \054 0 604 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1033 ( aclitem PGNSP PGUID 12 f b U f t \054 0 0 1034 aclitemin aclitemout - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("access control list"); #define ACLITEMOID 1033 -DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b A f t \054 0 1033 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b A f t \054 0 829 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b A f t \054 0 869 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b A f t \054 0 650 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1263 ( _cstring PGNSP PGUID -1 f b A f t \054 0 2275 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b A f t \054 0 1033 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b A f t \054 0 829 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b A f t \054 0 869 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b A f t \054 0 650 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1263 ( _cstring PGNSP PGUID -1 f b A f t \054 0 2275 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); #define CSTRINGARRAYOID 1263 -DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b S f t \054 0 0 1014 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b S f t \054 0 0 1014 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodin bpchartypmodout - i x f 0 -1 0 -1 f _null_ _null_ )); DESCR("char(length), blank-padded string, fixed storage length"); #define BPCHAROID 1042 -DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b S f t \054 0 0 1015 varcharin varcharout varcharrecv varcharsend varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b S f t \054 0 0 1015 varcharin varcharout varcharrecv varcharsend varchartypmodin varchartypmodout - i x f 0 -1 0 -1 f _null_ _null_ )); DESCR("varchar(length), non-blank-padded string, variable storage length"); #define VARCHAROID 1043 -DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b D f t \054 0 0 1182 date_in date_out date_recv date_send - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b D f t \054 0 0 1182 date_in date_out date_recv date_send - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("date"); #define DATEOID 1082 -DATA(insert OID = 1083 ( time PGNSP PGUID 8 FLOAT8PASSBYVAL b D f t \054 0 0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1083 ( time PGNSP PGUID 8 FLOAT8PASSBYVAL b D f t \054 0 0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("time of day"); #define TIMEOID 1083 /* OIDS 1100 - 1199 */ -DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 FLOAT8PASSBYVAL b D f t \054 0 0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 FLOAT8PASSBYVAL b D f t \054 0 0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("date and time"); #define TIMESTAMPOID 1114 -DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b A f t \054 0 1114 0 array_in array_out array_recv array_send timestamptypmodin timestamptypmodout - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1182 ( _date PGNSP PGUID -1 f b A f t \054 0 1082 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1183 ( _time PGNSP PGUID -1 f b A f t \054 0 1083 0 array_in array_out array_recv array_send timetypmodin timetypmodout - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 FLOAT8PASSBYVAL b D t t \054 0 0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b A f t \054 0 1114 0 array_in array_out array_recv array_send timestamptypmodin timestamptypmodout - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1182 ( _date PGNSP PGUID -1 f b A f t \054 0 1082 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1183 ( _time PGNSP PGUID -1 f b A f t \054 0 1083 0 array_in array_out array_recv array_send timetypmodin timetypmodout - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 FLOAT8PASSBYVAL b D t t \054 0 0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("date and time with time zone"); #define TIMESTAMPTZOID 1184 -DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b A f t \054 0 1184 0 array_in array_out array_recv array_send timestamptztypmodin timestamptztypmodout - d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1186 ( interval PGNSP PGUID 16 f b T t t \054 0 0 1187 interval_in interval_out interval_recv interval_send intervaltypmodin intervaltypmodout - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b A f t \054 0 1184 0 array_in array_out array_recv array_send timestamptztypmodin timestamptztypmodout - d x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1186 ( interval PGNSP PGUID 16 f b T t t \054 0 0 1187 interval_in interval_out interval_recv interval_send intervaltypmodin intervaltypmodout - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("@ , time interval"); #define INTERVALOID 1186 -DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b A f t \054 0 1186 0 array_in array_out array_recv array_send intervaltypmodin intervaltypmodout - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b A f t \054 0 1186 0 array_in array_out array_recv array_send intervaltypmodin intervaltypmodout - d x f 0 -1 0 -1 f _null_ _null_ )); /* OIDS 1200 - 1299 */ -DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b A f t \054 0 1700 0 array_in array_out array_recv array_send numerictypmodin numerictypmodout - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 f b D f t \054 0 0 1270 timetz_in timetz_out timetz_recv timetz_send timetztypmodin timetztypmodout - d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b A f t \054 0 1700 0 array_in array_out array_recv array_send numerictypmodin numerictypmodout - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 f b D f t \054 0 0 1270 timetz_in timetz_out timetz_recv timetz_send timetztypmodin timetztypmodout - d p f 0 -1 0 -1 f _null_ _null_ )); DESCR("time of day with time zone"); #define TIMETZOID 1266 -DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b A f t \054 0 1266 0 array_in array_out array_recv array_send timetztypmodin timetztypmodout - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b A f t \054 0 1266 0 array_in array_out array_recv array_send timetztypmodin timetztypmodout - d x f 0 -1 0 -1 f _null_ _null_ )); /* OIDS 1500 - 1599 */ -DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b V f t \054 0 0 1561 bit_in bit_out bit_recv bit_send bittypmodin bittypmodout - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b V f t \054 0 0 1561 bit_in bit_out bit_recv bit_send bittypmodin bittypmodout - i x f 0 -1 0 -1 f _null_ _null_ )); DESCR("fixed-length bit string"); #define BITOID 1560 -DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b A f t \054 0 1560 0 array_in array_out array_recv array_send bittypmodin bittypmodout - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 f b V t t \054 0 0 1563 varbit_in varbit_out varbit_recv varbit_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b A f t \054 0 1560 0 array_in array_out array_recv array_send bittypmodin bittypmodout - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 f b V t t \054 0 0 1563 varbit_in varbit_out varbit_recv varbit_send varbittypmodin varbittypmodout - i x f 0 -1 0 -1 f _null_ _null_ )); DESCR("variable-length bit string"); #define VARBITOID 1562 -DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b A f t \054 0 1562 0 array_in array_out array_recv array_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b A f t \054 0 1562 0 array_in array_out array_recv array_send varbittypmodin varbittypmodout - i x f 0 -1 0 -1 f _null_ _null_ )); /* OIDS 1600 - 1699 */ /* OIDS 1700 - 1799 */ -DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b N f t \054 0 0 1231 numeric_in numeric_out numeric_recv numeric_send numerictypmodin numerictypmodout - i m f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b N f t \054 0 0 1231 numeric_in numeric_out numeric_recv numeric_send numerictypmodin numerictypmodout - i m f 0 -1 0 -1 f _null_ _null_ )); DESCR("numeric(precision, decimal), arbitrary precision number"); #define NUMERICOID 1700 -DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b U f t \054 0 0 2201 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b U f t \054 0 0 2201 textin textout textrecv textsend - - - i x f 0 -1 0 -1 f _null_ _null_ )); DESCR("reference to cursor (portal name)"); #define REFCURSOROID 1790 /* OIDS 2200 - 2299 */ -DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b A f t \054 0 1790 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b A f t \054 0 1790 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); -DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b N f t \054 0 0 2207 regprocedurein regprocedureout regprocedurerecv regproceduresend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b N f t \054 0 0 2207 regprocedurein regprocedureout regprocedurerecv regproceduresend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("registered procedure (with args)"); #define REGPROCEDUREOID 2202 -DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b N f t \054 0 0 2208 regoperin regoperout regoperrecv regopersend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b N f t \054 0 0 2208 regoperin regoperout regoperrecv regopersend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("registered operator"); #define REGOPEROID 2203 -DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b N f t \054 0 0 2209 regoperatorin regoperatorout regoperatorrecv regoperatorsend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b N f t \054 0 0 2209 regoperatorin regoperatorout regoperatorrecv regoperatorsend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("registered operator (with args)"); #define REGOPERATOROID 2204 -DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b N f t \054 0 0 2210 regclassin regclassout regclassrecv regclasssend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b N f t \054 0 0 2210 regclassin regclassout regclassrecv regclasssend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("registered class"); #define REGCLASSOID 2205 -DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b N f t \054 0 0 2211 regtypein regtypeout regtyperecv regtypesend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b N f t \054 0 0 2211 regtypein regtypeout regtyperecv regtypesend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("registered type"); #define REGTYPEOID 2206 -DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b A f t \054 0 2202 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b A f t \054 0 2203 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b A f t \054 0 2204 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b A f t \054 0 2205 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b A f t \054 0 2206 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b A f t \054 0 2202 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b A f t \054 0 2203 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b A f t \054 0 2204 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b A f t \054 0 2205 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b A f t \054 0 2206 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); #define REGTYPEARRAYOID 2211 /* uuid */ -DATA(insert OID = 2950 ( uuid PGNSP PGUID 16 f b U f t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - - c p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2950 ( uuid PGNSP PGUID 16 f b U f t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - - c p f 0 -1 0 -1 f _null_ _null_ )); DESCR("UUID datatype"); -DATA(insert OID = 2951 ( _uuid PGNSP PGUID -1 f b A f t \054 0 2950 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2951 ( _uuid PGNSP PGUID -1 f b A f t \054 0 2950 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); /* text search */ -DATA(insert OID = 3614 ( tsvector PGNSP PGUID -1 f b U f t \054 0 0 3643 tsvectorin tsvectorout tsvectorrecv tsvectorsend - - ts_typanalyze i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 3614 ( tsvector PGNSP PGUID -1 f b U f t \054 0 0 3643 tsvectorin tsvectorout tsvectorrecv tsvectorsend - - ts_typanalyze i x f 0 -1 0 -1 f _null_ _null_ )); DESCR("text representation for text search"); #define TSVECTOROID 3614 -DATA(insert OID = 3642 ( gtsvector PGNSP PGUID -1 f b U f t \054 0 0 3644 gtsvectorin gtsvectorout - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 3642 ( gtsvector PGNSP PGUID -1 f b U f t \054 0 0 3644 gtsvectorin gtsvectorout - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("GiST index internal text representation for text search"); #define GTSVECTOROID 3642 -DATA(insert OID = 3615 ( tsquery PGNSP PGUID -1 f b U f t \054 0 0 3645 tsqueryin tsqueryout tsqueryrecv tsquerysend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 3615 ( tsquery PGNSP PGUID -1 f b U f t \054 0 0 3645 tsqueryin tsqueryout tsqueryrecv tsquerysend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("query representation for text search"); #define TSQUERYOID 3615 -DATA(insert OID = 3734 ( regconfig PGNSP PGUID 4 t b N f t \054 0 0 3735 regconfigin regconfigout regconfigrecv regconfigsend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 3734 ( regconfig PGNSP PGUID 4 t b N f t \054 0 0 3735 regconfigin regconfigout regconfigrecv regconfigsend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("registered text search configuration"); #define REGCONFIGOID 3734 -DATA(insert OID = 3769 ( regdictionary PGNSP PGUID 4 t b N f t \054 0 0 3770 regdictionaryin regdictionaryout regdictionaryrecv regdictionarysend - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 3769 ( regdictionary PGNSP PGUID 4 t b N f t \054 0 0 3770 regdictionaryin regdictionaryout regdictionaryrecv regdictionarysend - - - i p f 0 -1 0 -1 f _null_ _null_ )); DESCR("registered text search dictionary"); #define REGDICTIONARYOID 3769 -DATA(insert OID = 3643 ( _tsvector PGNSP PGUID -1 f b A f t \054 0 3614 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 3644 ( _gtsvector PGNSP PGUID -1 f b A f t \054 0 3642 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 3645 ( _tsquery PGNSP PGUID -1 f b A f t \054 0 3615 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 3735 ( _regconfig PGNSP PGUID -1 f b A f t \054 0 3734 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 3770 ( _regdictionary PGNSP PGUID -1 f b A f t \054 0 3769 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 3643 ( _tsvector PGNSP PGUID -1 f b A f t \054 0 3614 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 3644 ( _gtsvector PGNSP PGUID -1 f b A f t \054 0 3642 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 3645 ( _tsquery PGNSP PGUID -1 f b A f t \054 0 3615 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 3735 ( _regconfig PGNSP PGUID -1 f b A f t \054 0 3734 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); +DATA(insert OID = 3770 ( _regdictionary PGNSP PGUID -1 f b A f t \054 0 3769 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 -1 f _null_ _null_ )); -DATA(insert OID = 2970 ( txid_snapshot PGNSP PGUID -1 f b U f t \054 0 0 2949 txid_snapshot_in txid_snapshot_out txid_snapshot_recv txid_snapshot_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2970 ( txid_snapshot PGNSP PGUID -1 f b U f t \054 0 0 2949 txid_snapshot_in txid_snapshot_out txid_snapshot_recv txid_snapshot_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); DESCR("txid snapshot"); -DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b A f t \054 0 2970 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b A f t \054 0 2970 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); /* * pseudo-types @@ -594,31 +608,31 @@ DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b A f t \054 0 2970 0 a * but there is now support for it in records and arrays. Perhaps we should * just treat it as a regular base type? */ -DATA(insert OID = 2249 ( record PGNSP PGUID -1 f p P f t \054 0 0 2287 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2249 ( record PGNSP PGUID -1 f p P f t \054 0 0 2287 record_in record_out record_recv record_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); #define RECORDOID 2249 -DATA(insert OID = 2287 ( _record PGNSP PGUID -1 f p P f t \054 0 2249 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2287 ( _record PGNSP PGUID -1 f p P f t \054 0 2249 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); #define RECORDARRAYOID 2287 -DATA(insert OID = 2275 ( cstring PGNSP PGUID -2 f p P f t \054 0 0 1263 cstring_in cstring_out cstring_recv cstring_send - - - c p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2275 ( cstring PGNSP PGUID -2 f p P f t \054 0 0 1263 cstring_in cstring_out cstring_recv cstring_send - - - c p f 0 -1 0 -1 f _null_ _null_ )); #define CSTRINGOID 2275 -DATA(insert OID = 2276 ( any PGNSP PGUID 4 t p P f t \054 0 0 0 any_in any_out - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2276 ( any PGNSP PGUID 4 t p P f t \054 0 0 0 any_in any_out - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); #define ANYOID 2276 -DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p P f t \054 0 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send - - - d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p P f t \054 0 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send - - - d x f 0 -1 0 -1 f _null_ _null_ )); #define ANYARRAYOID 2277 -DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p P f t \054 0 0 0 void_in void_out - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p P f t \054 0 0 0 void_in void_out - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); #define VOIDOID 2278 -DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p P f t \054 0 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p P f t \054 0 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); #define TRIGGEROID 2279 -DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p P f t \054 0 0 0 language_handler_in language_handler_out - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p P f t \054 0 0 0 language_handler_in language_handler_out - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); #define LANGUAGE_HANDLEROID 2280 -DATA(insert OID = 2281 ( internal PGNSP PGUID SIZEOF_POINTER t p P f t \054 0 0 0 internal_in internal_out - - - - - ALIGNOF_POINTER p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2281 ( internal PGNSP PGUID SIZEOF_POINTER t p P f t \054 0 0 0 internal_in internal_out - - - - - ALIGNOF_POINTER p f 0 -1 0 -1 f _null_ _null_ )); #define INTERNALOID 2281 -DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p P f t \054 0 0 0 opaque_in opaque_out - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p P f t \054 0 0 0 opaque_in opaque_out - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); #define OPAQUEOID 2282 -DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p P f t \054 0 0 0 anyelement_in anyelement_out - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p P f t \054 0 0 0 anyelement_in anyelement_out - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); #define ANYELEMENTOID 2283 -DATA(insert OID = 2776 ( anynonarray PGNSP PGUID 4 t p P f t \054 0 0 0 anynonarray_in anynonarray_out - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 2776 ( anynonarray PGNSP PGUID 4 t p P f t \054 0 0 0 anynonarray_in anynonarray_out - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); #define ANYNONARRAYOID 2776 -DATA(insert OID = 3500 ( anyenum PGNSP PGUID 4 t p P f t \054 0 0 0 anyenum_in anyenum_out - - - - - i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 3500 ( anyenum PGNSP PGUID 4 t p P f t \054 0 0 0 anyenum_in anyenum_out - - - - - i p f 0 -1 0 -1 f _null_ _null_ )); #define ANYENUMOID 3500 diff --git a/src/include/catalog/pg_type_fn.h b/src/include/catalog/pg_type_fn.h index e5b5a96..1769af1 100644 --- a/src/include/catalog/pg_type_fn.h +++ b/src/include/catalog/pg_type_fn.h @@ -50,7 +50,9 @@ extern Oid TypeCreate(Oid newTypeOid, char storage, int32 typeMod, int32 typNDims, - bool typeNotNull); + bool typeNotNull, + int32 typeNLabels, + bool typeSorted); extern void GenerateTypeDependencies(Oid typeNamespace, Oid typeObjectId, diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index 809143c..fb890b8 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -24,6 +24,7 @@ extern void RemoveTypes(DropStmt *drop); extern void RemoveTypeById(Oid typeOid); extern void DefineDomain(CreateDomainStmt *stmt); extern void DefineEnum(CreateEnumStmt *stmt); +extern void AlterEnum (AlterEnumStmt *stmt); extern Oid DefineCompositeType(const RangeVar *typevar, List *coldeflist); extern Oid AssignTypeArrayOid(void); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index ebec0eb..b61938c 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -346,6 +346,7 @@ typedef enum NodeTag T_AlterUserMappingStmt, T_DropUserMappingStmt, T_AlterTableSpaceOptionsStmt, + T_AlterEnumStmt, /* * TAGS FOR PARSE TREE NODES (parsenodes.h) diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index ce3da66..d06dfb8 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2171,6 +2171,20 @@ typedef struct CreateEnumStmt /* ---------------------- + * Alter Type Statement, enum types + * ---------------------- + */ +typedef struct AlterEnumStmt +{ + NodeTag type; + List *typeName; /* qualified name (list of Value strings) */ + char *newVal; /* new enum value */ + char *newValNeighbour;/* neighbouring enum value */ + bool newValIsAfter; /* new enum value is after neighbour? */ +} AlterEnumStmt; + + +/* ---------------------- * Create View Statement * ---------------------- */ diff --git a/src/test/regress/expected/enum.out b/src/test/regress/expected/enum.out index 56240c0..ae595af 100644 --- a/src/test/regress/expected/enum.out +++ b/src/test/regress/expected/enum.out @@ -25,6 +25,84 @@ ERROR: invalid input value for enum rainbow: "mauve" LINE 1: SELECT 'mauve'::rainbow; ^ -- +-- adding new values +-- +CREATE TYPE planets AS ENUM ( 'venus', 'earth', 'mars' ); +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER by 2; + enumlabel | enumsortorder +-----------+--------------- + venus | 1 + earth | 2 + mars | 3 +(3 rows) + +ALTER TYPE planets ADD 'uranus'; +SELECT typnlabels, typsorted +FROM pg_type +WHERE oid = 'planets'::regtype; + typnlabels | typsorted +------------+----------- + 4 | t +(1 row) + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER by 2; + enumlabel | enumsortorder +-----------+--------------- + venus | 1 + earth | 2 + mars | 3 + uranus | 4 +(4 rows) + +ALTER TYPE planets ADD 'mercury' BEFORE 'venus'; +ALTER TYPE planets ADD 'saturn' BEFORE 'uranus'; +ALTER TYPE planets ADD 'jupiter' AFTER 'mars'; +ALTER TYPE planets ADD 'neptune' AFTER 'uranus'; +SELECT typnlabels, typsorted +FROM pg_type +WHERE oid = 'planets'::regtype; + typnlabels | typsorted +------------+----------- + 8 | f +(1 row) + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER by 2; + enumlabel | enumsortorder +-----------+--------------- + mercury | 1 + venus | 2 + earth | 3 + mars | 4 + jupiter | 5 + saturn | 6 + uranus | 7 + neptune | 8 +(8 rows) + +select 'mars'::planets > 'mercury' as using_sortorder; + using_sortorder +----------------- + t +(1 row) + +-- errors for adding labels +ALTER TYPE planets ADD + 'plutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutopluto'; +ERROR: invalid enum label "plutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutopluto" +DETAIL: Labels must be 63 characters or less. +ALTER TYPE planets ADD 'pluto' AFTER 'zeus'; +ERROR: "zeus" is not an existing label. +DROP TYPE planets; +-- -- Basic table creation, row selection -- CREATE TABLE enumtest (col rainbow); @@ -403,7 +481,7 @@ SELECT COUNT(*) FROM pg_type WHERE typname = 'rainbow'; SELECT * FROM pg_enum WHERE NOT EXISTS (SELECT 1 FROM pg_type WHERE pg_type.oid = enumtypid); - enumtypid | enumlabel ------------+----------- + enumtypid | enumlabel | enumsortorder +-----------+-----------+--------------- (0 rows) diff --git a/src/test/regress/sql/enum.sql b/src/test/regress/sql/enum.sql index 387e8e7..0e240b2 100644 --- a/src/test/regress/sql/enum.sql +++ b/src/test/regress/sql/enum.sql @@ -16,6 +16,54 @@ SELECT 'red'::rainbow; SELECT 'mauve'::rainbow; -- +-- adding new values +-- + +CREATE TYPE planets AS ENUM ( 'venus', 'earth', 'mars' ); + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER by 2; + +ALTER TYPE planets ADD 'uranus'; + +SELECT typnlabels, typsorted +FROM pg_type +WHERE oid = 'planets'::regtype; + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER by 2; + +ALTER TYPE planets ADD 'mercury' BEFORE 'venus'; + +ALTER TYPE planets ADD 'saturn' BEFORE 'uranus'; + +ALTER TYPE planets ADD 'jupiter' AFTER 'mars'; + +ALTER TYPE planets ADD 'neptune' AFTER 'uranus'; + +SELECT typnlabels, typsorted +FROM pg_type +WHERE oid = 'planets'::regtype; + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER by 2; + +select 'mars'::planets > 'mercury' as using_sortorder; + +-- errors for adding labels +ALTER TYPE planets ADD + 'plutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutopluto'; + +ALTER TYPE planets ADD 'pluto' AFTER 'zeus'; + +DROP TYPE planets; +-- -- Basic table creation, row selection -- CREATE TABLE enumtest (col rainbow);