diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-29 19:06:29 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-29 19:06:29 +0000 |
commit | d5e99ab4d6718e8ef515575e33fb5c6181cdcc96 (patch) | |
tree | 6c817d6358f50ae920207245c3b862b2cdd74ceb | |
parent | 7c1ff354105e2256d7904497d8e282ccec53d2e6 (diff) | |
download | postgresql-d5e99ab4d6718e8ef515575e33fb5c6181cdcc96.tar.gz postgresql-d5e99ab4d6718e8ef515575e33fb5c6181cdcc96.zip |
pg_type has a typnamespace column; system now supports creating types
in different namespaces. Also, cleanup work on relation namespace
support: drop, alter, rename commands work for tables in non-default
namespaces.
68 files changed, 2069 insertions, 2261 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 950d2016df6..31f82d12370 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,6 +1,6 @@ <!-- Documentation of the system catalogs, directed toward PostgreSQL developers - $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.38 2002/03/26 19:15:10 tgl Exp $ + $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.39 2002/03/29 19:05:57 tgl Exp $ --> <chapter id="catalogs"> @@ -2364,6 +2364,15 @@ </row> <row> + <entry>typnamespace</entry> + <entry><type>oid</type></entry> + <entry>pg_namespace.oid</entry> + <entry> + The OID of the namespace that contains this type + </entry> + </row> + + <row> <entry>typowner</entry> <entry><type>int4</type></entry> <entry>pg_shadow.usesysid</entry> diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index 81f996b8a03..605ffb1bed7 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.77 2002/02/27 19:34:11 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.78 2002/03/29 19:05:59 tgl Exp $ * * NOTES * some of the executor utility code such as "ExecTypeFromTL" should be @@ -322,7 +322,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) * a preallocated tuple descriptor. * ---------------------------------------------------------------- */ -bool +void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, char *attributeName, @@ -377,39 +377,11 @@ TupleDescInitEntry(TupleDesc desc, att->attnotnull = false; att->atthasdef = false; - /* ---------------- - * search the system cache for the type tuple of the attribute - * we are creating so that we can get the typeid and some other - * stuff. - * - * Note: in the special case of - * - * create EMP (name = text, manager = EMP) - * - * RelationNameCreateHeapRelation() calls BuildDesc() which - * calls this routine and since EMP does not exist yet, the - * system cache lookup below fails. That's fine, but rather - * then doing a elog(ERROR) we just leave that information - * uninitialized, return false, then fix things up later. - * -cim 6/14/90 - * ---------------- - */ tuple = SearchSysCache(TYPEOID, ObjectIdGetDatum(oidtypeid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) - { - /* - * here type info does not exist yet so we just fill the attribute - * with dummy information and return false. - */ - att->atttypid = InvalidOid; - att->attlen = (int16) 0; - att->attbyval = (bool) 0; - att->attalign = 'i'; - att->attstorage = 'p'; - return false; - } + elog(ERROR, "Unable to look up type id %u", oidtypeid); /* * type info exists so we initialize our attribute information from @@ -477,56 +449,16 @@ TupleDescInitEntry(TupleDesc desc, } ReleaseSysCache(tuple); - - return true; } -/* ---------------------------------------------------------------- - * TupleDescMakeSelfReference +/* + * BuildDescForRelation * - * This function initializes a "self-referential" attribute like - * manager in "create EMP (name=text, manager = EMP)". - * It calls TypeShellMake() which inserts a "shell" type - * tuple into pg_type. A self-reference is one kind of set, so - * its size and byval are the same as for a set. See the comments - * above in TupleDescInitEntry. - * ---------------------------------------------------------------- - */ -static void -TupleDescMakeSelfReference(TupleDesc desc, - AttrNumber attnum, - char *relname) -{ - Form_pg_attribute att; - - att = desc->attrs[attnum - 1]; - att->atttypid = TypeShellMake(relname); - att->attlen = sizeof(Oid); - att->attbyval = true; - att->attalign = 'i'; - att->attstorage = 'p'; - att->attndims = 0; -} - -/* ---------------------------------------------------------------- - * BuildDescForRelation - * - * This is a general purpose function identical to BuildDesc - * but is used by the DefineRelation() code to catch the - * special case where you - * - * create FOO ( ..., x = FOO ) - * - * here, the initial type lookup for "x = FOO" will fail - * because FOO isn't in the catalogs yet. But since we - * are creating FOO, instead of doing an elog() we add - * a shell type tuple to pg_type and fix things later - * in amcreate(). - * ---------------------------------------------------------------- + * Given a relation schema (list of ColumnDef nodes), build a TupleDesc. */ TupleDesc -BuildDescForRelation(List *schema, char *relname) +BuildDescForRelation(List *schema) { int natts; AttrNumber attnum; @@ -535,7 +467,6 @@ BuildDescForRelation(List *schema, char *relname) AttrDefault *attrdef = NULL; TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr)); char *attname; - char typename[NAMEDATALEN]; int32 atttypmod; int attdim; int ndef = 0; @@ -553,7 +484,6 @@ BuildDescForRelation(List *schema, char *relname) foreach(p, schema) { ColumnDef *entry = lfirst(p); - List *arry; /* * for each entry in the list, get the name and type information @@ -563,39 +493,13 @@ BuildDescForRelation(List *schema, char *relname) attnum++; attname = entry->colname; - arry = entry->typename->arrayBounds; attisset = entry->typename->setof; atttypmod = entry->typename->typmod; + attdim = length(entry->typename->arrayBounds); - if (arry != NIL) - { - /* array of XXX is _XXX */ - snprintf(typename, NAMEDATALEN, - "_%.*s", NAMEDATALEN - 2, entry->typename->name); - attdim = length(arry); - } - else - { - StrNCpy(typename, entry->typename->name, NAMEDATALEN); - attdim = 0; - } - - if (!TupleDescInitEntry(desc, attnum, attname, - typenameTypeId(typename), - atttypmod, attdim, attisset)) - { - /* - * if TupleDescInitEntry() fails, it means there is no type in - * the system catalogs. So now we check if the type name - * equals the relation name. If so we have a self reference, - * otherwise it's an error. - */ - if (strcmp(typename, relname) == 0) - TupleDescMakeSelfReference(desc, attnum, relname); - else - elog(ERROR, "DefineRelation: no such type %s", - typename); - } + TupleDescInitEntry(desc, attnum, attname, + typenameTypeId(entry->typename), + atttypmod, attdim, attisset); /* This is for constraints */ if (entry->is_not_null) diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index bead0959d93..3269964aa07 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.59 2002/03/26 19:15:22 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.60 2002/03/29 19:05:59 tgl Exp $ * * NOTES * See acl.h. @@ -37,6 +37,7 @@ #include "parser/parse_agg.h" #include "parser/parse_func.h" #include "parser/parse_expr.h" +#include "parser/parse_type.h" #include "utils/acl.h" #include "utils/syscache.h" #include "utils/temprel.h" @@ -300,20 +301,19 @@ find_function_with_arglist(char *name, List *arguments) for (i = 0; i < argcount; i++) { TypeName *t = (TypeName *) lfirst(arguments); - char *typnam = TypeNameToInternalName(t); - arguments = lnext(arguments); - - if (strcmp(typnam, "opaque") == 0) - argoids[i] = InvalidOid; - else + argoids[i] = LookupTypeName(t); + if (!OidIsValid(argoids[i])) { - argoids[i] = GetSysCacheOid(TYPENAME, - PointerGetDatum(typnam), - 0, 0, 0); - if (!OidIsValid(argoids[i])) - elog(ERROR, "type '%s' not found", typnam); + char *typnam = TypeNameToString(t); + + if (strcmp(typnam, "opaque") == 0) + argoids[i] = InvalidOid; + else + elog(ERROR, "Type \"%s\" does not exist", typnam); } + + arguments = lnext(arguments); } oid = GetSysCacheOid(PROCNAME, diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 0b367e3daba..fa64676e349 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.192 2002/03/26 19:15:25 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.193 2002/03/29 19:05:59 tgl Exp $ * * * INTERFACE ROUTINES @@ -74,8 +74,10 @@ static void DeleteRelationTuple(Relation rel); static void DeleteTypeTuple(Relation rel); static void RelationRemoveIndexes(Relation relation); static void RelationRemoveInheritance(Relation relation); -static void AddNewRelationType(char *typeName, Oid new_rel_oid, - Oid new_type_oid); +static void AddNewRelationType(const char *typeName, + Oid typeNamespace, + Oid new_rel_oid, + Oid new_type_oid); static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin); static void StoreRelCheck(Relation rel, char *ccname, char *ccbin); static void StoreConstraints(Relation rel, TupleDesc tupdesc); @@ -242,7 +244,7 @@ heap_create(char *relname, * have to take special care for those rels that should be nailed * in cache and/or are shared across databases. */ - if (relname && relnamespace == PG_CATALOG_NAMESPACE) + if (relnamespace == PG_CATALOG_NAMESPACE) { if (strcmp(TypeRelationName, relname) == 0) { @@ -622,7 +624,10 @@ AddNewRelationTuple(Relation pg_class_desc, * -------------------------------- */ static void -AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid) +AddNewRelationType(const char *typeName, + Oid typeNamespace, + Oid new_rel_oid, + Oid new_type_oid) { /* * The sizes are set to oid size because it makes implementing sets @@ -634,18 +639,19 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid) * true makes sets much easier, and it isn't used by anything else. */ TypeCreate(typeName, /* type name */ + typeNamespace, /* type namespace */ new_type_oid, /* preassigned oid for type */ new_rel_oid, /* relation oid */ sizeof(Oid), /* internal size */ -1, /* external size */ - 'c', /* type-type (catalog) */ + 'c', /* type-type (complex) */ ',', /* default array delimiter */ - "oidin", /* input procedure */ - "oidout", /* output procedure */ - "oidin", /* receive procedure */ - "oidout", /* send procedure */ - NULL, /* array element type - irrelevant */ - NULL, /* baseType Name -- typically for domains */ + F_OIDIN, /* input procedure */ + F_OIDOUT, /* output procedure */ + F_OIDIN, /* receive procedure */ + F_OIDOUT, /* send procedure */ + InvalidOid, /* array element type - irrelevant */ + InvalidOid, /* domain base type - irrelevant */ NULL, /* default type value - none */ NULL, /* default type binary representation */ true, /* passed by value */ @@ -744,7 +750,7 @@ heap_create_with_catalog(char *relname, * NOTE: we could get a unique-index failure here, in case the same name * has already been used for a type. */ - AddNewRelationType(relname, new_rel_oid, new_type_oid); + AddNewRelationType(relname, relnamespace, new_rel_oid, new_type_oid); /* * now add tuples to pg_attribute for the attributes in our new @@ -1002,15 +1008,13 @@ RelationTruncateIndexes(Oid heapId) */ void -heap_truncate(const char *relname) +heap_truncate(Oid rid) { Relation rel; - Oid rid; /* Open relation for processing, and grab exclusive access on it. */ - rel = heap_openr(relname, AccessExclusiveLock); - rid = RelationGetRelid(rel); + rel = heap_open(rid, AccessExclusiveLock); /* * TRUNCATE TABLE within a transaction block is dangerous, because if @@ -1217,21 +1221,22 @@ DeleteTypeTuple(Relation rel) * ---------------------------------------------------------------- */ void -heap_drop_with_catalog(const char *relname, +heap_drop_with_catalog(Oid rid, bool allow_system_table_mods) { Relation rel; - Oid rid; + Oid toasttableOid; bool has_toasttable; - bool istemp = is_temp_rel_name(relname); + bool istemp; int i; /* * Open and lock the relation. */ - rel = heap_openr(relname, AccessExclusiveLock); - rid = RelationGetRelid(rel); + rel = heap_open(rid, AccessExclusiveLock); has_toasttable = rel->rd_rel->reltoastrelid != InvalidOid; + toasttableOid = rel->rd_rel->reltoastrelid; + istemp = is_temp_rel_name(RelationGetRelationName(rel)); /* * prevent deletion of system relations @@ -1319,12 +1324,7 @@ heap_drop_with_catalog(const char *relname, remove_temp_rel_by_relid(rid); if (has_toasttable) - { - char toast_relname[NAMEDATALEN]; - - sprintf(toast_relname, "pg_toast_%u", rid); - heap_drop_with_catalog(toast_relname, true); - } + heap_drop_with_catalog(toasttableOid, true); } diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index da269d28415..ac556eff647 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.85 2002/03/26 19:15:30 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.86 2002/03/29 19:06:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -76,7 +76,7 @@ char *Name_pg_statistic_indices[Num_pg_statistic_indices] = char *Name_pg_trigger_indices[Num_pg_trigger_indices] = {TriggerRelidIndex, TriggerConstrNameIndex, TriggerConstrRelidIndex, TriggerOidIndex}; char *Name_pg_type_indices[Num_pg_type_indices] = -{TypeNameIndex, TypeOidIndex}; +{TypeNameNspIndex, TypeOidIndex}; char *Name_pg_description_indices[Num_pg_description_indices] = {DescriptionObjIndex}; diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index c9d8d21f929..a1ea6ed24fe 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -13,7 +13,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.1 2002/03/26 19:15:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.2 2002/03/29 19:06:01 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,6 +22,7 @@ #include "catalog/namespace.h" #include "catalog/pg_namespace.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -124,3 +125,92 @@ RelnameGetRelid(const char *relname) /* XXX Wrong! must search search path */ return get_relname_relid(relname, PG_CATALOG_NAMESPACE); } + +/* + * QualifiedNameGetCreationNamespace + * Given a possibly-qualified name for an object (in List-of-Values + * format), determine what namespace the object should be created in. + * Also extract and return the object name (last component of list). + */ +Oid +QualifiedNameGetCreationNamespace(List *names, char **objname_p) +{ + char *catalogname; + char *schemaname = NULL; + char *objname = NULL; + Oid namespaceId; + + /* deconstruct the name list */ + switch (length(names)) + { + case 1: + objname = strVal(lfirst(names)); + break; + case 2: + schemaname = strVal(lfirst(names)); + objname = strVal(lsecond(names)); + break; + case 3: + catalogname = strVal(lfirst(names)); + schemaname = strVal(lsecond(names)); + objname = strVal(lfirst(lnext(lnext(names)))); + /* + * We check the catalog name and then ignore it. + */ + if (strcmp(catalogname, DatabaseName) != 0) + elog(ERROR, "Cross-database references are not implemented"); + break; + default: + elog(ERROR, "Improper qualified name (too many dotted names)"); + break; + } + + if (schemaname) + { + namespaceId = GetSysCacheOid(NAMESPACENAME, + CStringGetDatum(schemaname), + 0, 0, 0); + if (!OidIsValid(namespaceId)) + elog(ERROR, "Namespace \"%s\" does not exist", + schemaname); + } + else + { + /* XXX Wrong! Need to get a default schema from somewhere */ + namespaceId = PG_CATALOG_NAMESPACE; + } + + *objname_p = objname; + return namespaceId; +} + +/* + * makeRangeVarFromNameList + * Utility routine to convert a qualified-name list into RangeVar form. + */ +RangeVar * +makeRangeVarFromNameList(List *names) +{ + RangeVar *rel = makeRangeVar(NULL, NULL); + + switch (length(names)) + { + case 1: + rel->relname = strVal(lfirst(names)); + break; + case 2: + rel->schemaname = strVal(lfirst(names)); + rel->relname = strVal(lsecond(names)); + break; + case 3: + rel->catalogname = strVal(lfirst(names)); + rel->schemaname = strVal(lsecond(names)); + rel->relname = strVal(lfirst(lnext(lnext(names)))); + break; + default: + elog(ERROR, "Improper relation name (too many dotted names)"); + break; + } + + return rel; +} diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index 8de1a52c3fa..1a73f42c334 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.41 2002/03/20 19:43:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.42 2002/03/29 19:06:01 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,34 +23,21 @@ #include "miscadmin.h" #include "parser/parse_coerce.h" #include "parser/parse_func.h" +#include "parser/parse_type.h" #include "utils/builtins.h" #include "utils/syscache.h" -/* ---------------- +/* * AggregateCreate - * - * aggregates overloading has been added. Instead of the full - * overload support we have for functions, aggregate overloading only - * applies to exact basetype matches. That is, we don't check the - * inheritance hierarchy - * - * OLD COMMENTS: - * Currently, redefining aggregates using the same name is not - * supported. In such a case, a warning is printed that the - * aggregate already exists. If such is not the case, a new tuple - * is created and inserted in the aggregate relation. - * All types and functions must have been defined - * prior to defining the aggregate. - * - * --------------- */ void -AggregateCreate(char *aggName, +AggregateCreate(const char *aggName, + Oid aggNamespace, char *aggtransfnName, char *aggfinalfnName, - char *aggbasetypeName, - char *aggtranstypeName, - char *agginitval) + Oid aggBaseType, + Oid aggTransType, + const char *agginitval) { Relation aggdesc; HeapTuple tup; @@ -59,8 +46,6 @@ AggregateCreate(char *aggName, Form_pg_proc proc; Oid transfn; Oid finalfn = InvalidOid; /* can be omitted */ - Oid basetype; - Oid transtype; Oid finaltype; Oid fnArgs[FUNC_MAX_ARGS]; int nargs; @@ -68,8 +53,6 @@ AggregateCreate(char *aggName, TupleDesc tupDesc; int i; - MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid)); - /* sanity checks */ if (!aggName) elog(ERROR, "no aggregate name supplied"); @@ -77,44 +60,21 @@ AggregateCreate(char *aggName, if (!aggtransfnName) elog(ERROR, "aggregate must have a transition function"); - /* - * Handle the aggregate's base type (input data type). This can be - * specified as 'ANY' for a data-independent transition function, such - * as COUNT(*). - */ - basetype = GetSysCacheOid(TYPENAME, - PointerGetDatum(aggbasetypeName), - 0, 0, 0); - if (!OidIsValid(basetype)) - { - if (strcasecmp(aggbasetypeName, "ANY") != 0) - elog(ERROR, "data type %s does not exist", - aggbasetypeName); - basetype = InvalidOid; - } - /* make sure there is no existing agg of same name and base type */ if (SearchSysCacheExists(AGGNAME, PointerGetDatum(aggName), - ObjectIdGetDatum(basetype), + ObjectIdGetDatum(aggBaseType), 0, 0)) elog(ERROR, "aggregate function \"%s\" with base type %s already exists", - aggName, aggbasetypeName); - - /* handle transtype */ - transtype = GetSysCacheOid(TYPENAME, - PointerGetDatum(aggtranstypeName), - 0, 0, 0); - if (!OidIsValid(transtype)) - elog(ERROR, "data type %s does not exit", - aggtranstypeName); + aggName, typeidTypeName(aggBaseType)); /* handle transfn */ - fnArgs[0] = transtype; - if (OidIsValid(basetype)) + MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid)); + fnArgs[0] = aggTransType; + if (OidIsValid(aggBaseType)) { - fnArgs[1] = basetype; + fnArgs[1] = aggBaseType; nargs = 2; } else @@ -129,9 +89,9 @@ AggregateCreate(char *aggName, transfn = tup->t_data->t_oid; Assert(OidIsValid(transfn)); proc = (Form_pg_proc) GETSTRUCT(tup); - if (proc->prorettype != transtype) + if (proc->prorettype != aggTransType) elog(ERROR, "return type of transition function %s is not %s", - aggtransfnName, aggtranstypeName); + aggtransfnName, typeidTypeName(aggTransType)); /* * If the transfn is strict and the initval is NULL, make sure input @@ -141,7 +101,7 @@ AggregateCreate(char *aggName, */ if (proc->proisstrict && agginitval == NULL) { - if (!IsBinaryCompatible(basetype, transtype)) + if (!IsBinaryCompatible(aggBaseType, aggTransType)) elog(ERROR, "must not omit initval when transfn is strict and transtype is not compatible with input type"); } ReleaseSysCache(tup); @@ -149,7 +109,7 @@ AggregateCreate(char *aggName, /* handle finalfn, if supplied */ if (aggfinalfnName) { - fnArgs[0] = transtype; + fnArgs[0] = aggTransType; fnArgs[1] = 0; tup = SearchSysCache(PROCNAME, PointerGetDatum(aggfinalfnName), @@ -169,7 +129,7 @@ AggregateCreate(char *aggName, /* * If no finalfn, aggregate result type is type of the state value */ - finaltype = transtype; + finaltype = aggTransType; } Assert(OidIsValid(finaltype)); @@ -184,8 +144,8 @@ AggregateCreate(char *aggName, values[Anum_pg_aggregate_aggowner - 1] = Int32GetDatum(GetUserId()); values[Anum_pg_aggregate_aggtransfn - 1] = ObjectIdGetDatum(transfn); values[Anum_pg_aggregate_aggfinalfn - 1] = ObjectIdGetDatum(finalfn); - values[Anum_pg_aggregate_aggbasetype - 1] = ObjectIdGetDatum(basetype); - values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(transtype); + values[Anum_pg_aggregate_aggbasetype - 1] = ObjectIdGetDatum(aggBaseType); + values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(aggTransType); values[Anum_pg_aggregate_aggfinaltype - 1] = ObjectIdGetDatum(finaltype); if (agginitval) diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index efd98b546f1..8942c266fd6 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.63 2001/10/25 05:49:23 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.64 2002/03/29 19:06:01 tgl Exp $ * * NOTES * these routines moved here from commands/define.c and somewhat cleaned up. @@ -30,34 +30,28 @@ #include "utils/syscache.h" -static Oid OperatorGetWithOpenRelation(Relation pg_operator_desc, - const char *operatorName, - Oid leftObjectId, - Oid rightObjectId, - bool *defined); +static Oid OperatorGet(const char *operatorName, + Oid leftObjectId, + Oid rightObjectId, + bool *defined); -static Oid OperatorGet(char *operatorName, - char *leftTypeName, - char *rightTypeName, - bool *defined); +static Oid OperatorShellMake(const char *operatorName, + Oid leftTypeId, + Oid rightTypeId); -static Oid OperatorShellMake(char *operatorName, - char *leftTypeName, - char *rightTypeName); - -static void OperatorDef(char *operatorName, - char *leftTypeName, - char *rightTypeName, - char *procedureName, +static void OperatorDef(const char *operatorName, + Oid leftTypeId, + Oid rightTypeId, + const char *procedureName, uint16 precedence, bool isLeftAssociative, - char *commutatorName, - char *negatorName, - char *restrictionName, - char *oinName, + const char *commutatorName, + const char *negatorName, + const char *restrictionName, + const char *joinName, bool canHash, - char *leftSortName, - char *rightSortName); + const char *leftSortName, + const char *rightSortName); static void OperatorUpd(Oid baseId, Oid commId, Oid negId); @@ -120,29 +114,37 @@ validOperatorName(const char *name) /* ---------------------------------------------------------------- - * OperatorGetWithOpenRelation + * OperatorGet * - * performs a scan on pg_operator for an operator tuple - * with given name and left/right type oids. + * finds the operator associated with the specified name + * and left and right type IDs. * - * pg_operator_desc -- reldesc for pg_operator - * operatorName -- name of operator to fetch - * leftObjectId -- left data type oid of operator to fetch - * rightObjectId -- right data type oid of operator to fetch - * defined -- set TRUE if defined (not a shell) + * operatorName -- name of operator to fetch + * leftObjectId -- left data type oid of operator to fetch + * rightObjectId -- right data type oid of operator to fetch + * defined -- set TRUE if defined (not a shell) * ---------------------------------------------------------------- */ static Oid -OperatorGetWithOpenRelation(Relation pg_operator_desc, - const char *operatorName, - Oid leftObjectId, - Oid rightObjectId, - bool *defined) +OperatorGet(const char *operatorName, + Oid leftObjectId, + Oid rightObjectId, + bool *defined) { + Relation pg_operator_desc; HeapScanDesc pg_operator_scan; - Oid operatorObjectId; HeapTuple tup; ScanKeyData opKey[3]; + Oid operatorObjectId; + + if (!(OidIsValid(leftObjectId) || OidIsValid(rightObjectId))) + elog(ERROR, "operator %s must have at least one operand type", + operatorName); + + /* + * open the pg_operator relation + */ + pg_operator_desc = heap_openr(OperatorRelationName, AccessShareLock); /* * form scan key @@ -192,99 +194,22 @@ OperatorGetWithOpenRelation(Relation pg_operator_desc, * close the scan and return the oid. */ heap_endscan(pg_operator_scan); - - return operatorObjectId; -} - -/* ---------------------------------------------------------------- - * OperatorGet - * - * finds the operator associated with the specified name - * and left and right type names. - * ---------------------------------------------------------------- - */ -static Oid -OperatorGet(char *operatorName, - char *leftTypeName, - char *rightTypeName, - bool *defined) -{ - Relation pg_operator_desc; - Oid operatorObjectId; - Oid leftObjectId = InvalidOid; - Oid rightObjectId = InvalidOid; - bool leftDefined = false; - bool rightDefined = false; - - /* - * look up the operator data types. - * - * Note: types must be defined before operators - */ - if (leftTypeName) - { - leftObjectId = TypeGet(leftTypeName, &leftDefined); - - if (!OidIsValid(leftObjectId) || !leftDefined) - elog(ERROR, "left type \"%s\" of operator %s does not exist", - leftTypeName, operatorName); - } - - if (rightTypeName) - { - rightObjectId = TypeGet(rightTypeName, &rightDefined); - - if (!OidIsValid(rightObjectId) || !rightDefined) - elog(ERROR, "right type \"%s\" of operator %s does not exist", - rightTypeName, operatorName); - } - - if (!((OidIsValid(leftObjectId) && leftDefined) || - (OidIsValid(rightObjectId) && rightDefined))) - elog(ERROR, "operator %s must have at least one operand type", operatorName); - - /* - * open the pg_operator relation - */ - pg_operator_desc = heap_openr(OperatorRelationName, AccessShareLock); - - /* - * get the oid for the operator with the appropriate name and - * left/right types. - */ - operatorObjectId = OperatorGetWithOpenRelation(pg_operator_desc, - operatorName, - leftObjectId, - rightObjectId, - defined); - - /* - * close the relation and return the operator oid. - */ heap_close(pg_operator_desc, AccessShareLock); return operatorObjectId; } -/* ---------------------------------------------------------------- - * OperatorShellMake - * - * Specify operator name and left and right type names, - * fill an operator struct with this info and NULL's, - * call heap_insert and return the Oid to the caller. - * ---------------------------------------------------------------- +/* + * OperatorShellMake + * Make a "shell" entry for a not-yet-existing operator. */ static Oid -OperatorShellMake(char *operatorName, - char *leftTypeName, - char *rightTypeName) +OperatorShellMake(const char *operatorName, + Oid leftTypeId, + Oid rightTypeId) { Relation pg_operator_desc; Oid operatorObjectId; - Oid leftObjectId = InvalidOid; - Oid rightObjectId = InvalidOid; - bool leftDefined = false; - bool rightDefined = false; int i; HeapTuple tup; Datum values[Natts_pg_operator]; @@ -299,19 +224,6 @@ OperatorShellMake(char *operatorName, elog(ERROR, "\"%s\" is not a valid operator name", operatorName); /* - * get the left and right type oid's for this operator - */ - if (leftTypeName) - leftObjectId = TypeGet(leftTypeName, &leftDefined); - - if (rightTypeName) - rightObjectId = TypeGet(rightTypeName, &rightDefined); - - if (!((OidIsValid(leftObjectId) && leftDefined) || - (OidIsValid(rightObjectId) && rightDefined))) - elog(ERROR, "OperatorShellMake: the operand types are not valid"); - - /* * open pg_operator */ pg_operator_desc = heap_openr(OperatorRelationName, RowExclusiveLock); @@ -337,8 +249,8 @@ OperatorShellMake(char *operatorName, values[i++] = CharGetDatum('b'); /* assume it's binary */ values[i++] = BoolGetDatum(false); values[i++] = BoolGetDatum(false); - values[i++] = ObjectIdGetDatum(leftObjectId); /* <-- left oid */ - values[i++] = ObjectIdGetDatum(rightObjectId); /* <-- right oid */ + values[i++] = ObjectIdGetDatum(leftTypeId); + values[i++] = ObjectIdGetDatum(rightTypeId); values[i++] = ObjectIdGetDatum(InvalidOid); values[i++] = ObjectIdGetDatum(InvalidOid); values[i++] = ObjectIdGetDatum(InvalidOid); @@ -444,8 +356,8 @@ OperatorShellMake(char *operatorName, * -------------------------------- * "X" indicates an optional argument (i.e. one that can be NULL) * operatorName; -- operator name - * leftTypeName; -- X left type name - * rightTypeName; -- X right type name + * leftTypeId; -- X left type id + * rightTypeId; -- X right type id * procedureName; -- procedure name for operator code * precedence; -- operator precedence * isLeftAssociative; -- operator is left associative? @@ -458,22 +370,20 @@ OperatorShellMake(char *operatorName, * rightSortName; -- X right sort operator (for merge join) */ static void -OperatorDef(char *operatorName, - char *leftTypeName, - char *rightTypeName, - char *procedureName, +OperatorDef(const char *operatorName, + Oid leftTypeId, + Oid rightTypeId, + const char *procedureName, uint16 precedence, bool isLeftAssociative, - char *commutatorName, - char *negatorName, - char *restrictionName, - char *joinName, + const char *commutatorName, + const char *negatorName, + const char *restrictionName, + const char *joinName, bool canHash, - char *leftSortName, - char *rightSortName) + const char *leftSortName, + const char *rightSortName) { - int i, - j; Relation pg_operator_desc; HeapScanDesc pg_operator_scan; HeapTuple tup; @@ -482,23 +392,30 @@ OperatorDef(char *operatorName, Datum values[Natts_pg_operator]; Oid operatorObjectId; bool operatorAlreadyDefined; - Oid leftTypeId = InvalidOid; - Oid rightTypeId = InvalidOid; Oid commutatorId = InvalidOid; Oid negatorId = InvalidOid; - bool leftDefined = false; - bool rightDefined = false; bool selfCommutator = false; - char *name[4]; + const char *name[4]; Oid typeId[FUNC_MAX_ARGS]; int nargs; NameData oname; TupleDesc tupDesc; ScanKeyData opKey[3]; + int i, + j; + + /* + * validate operator name + */ + if (!validOperatorName(operatorName)) + elog(ERROR, "\"%s\" is not a valid operator name", operatorName); + + if (!(OidIsValid(leftTypeId) || OidIsValid(rightTypeId))) + elog(ERROR, "operator must have at least one operand type"); operatorObjectId = OperatorGet(operatorName, - leftTypeName, - rightTypeName, + leftTypeId, + rightTypeId, &operatorAlreadyDefined); if (operatorAlreadyDefined) @@ -510,39 +427,6 @@ OperatorDef(char *operatorName, * filling in a previously-created shell. */ - /* - * validate operator name - */ - if (!validOperatorName(operatorName)) - elog(ERROR, "\"%s\" is not a valid operator name", operatorName); - - /* - * look up the operator data types. - * - * Note: types must be defined before operators - */ - if (leftTypeName) - { - leftTypeId = TypeGet(leftTypeName, &leftDefined); - - if (!OidIsValid(leftTypeId) || !leftDefined) - elog(ERROR, "left type \"%s\" does not exist", - leftTypeName); - } - - if (rightTypeName) - { - rightTypeId = TypeGet(rightTypeName, &rightDefined); - - if (!OidIsValid(rightTypeId) || !rightDefined) - elog(ERROR, "right type \"%s\" does not exist", - rightTypeName); - } - - if (!((OidIsValid(leftTypeId) && leftDefined) || - (OidIsValid(rightTypeId) && rightDefined))) - elog(ERROR, "operator must have at least one operand type"); - for (i = 0; i < Natts_pg_operator; ++i) { values[i] = (Datum) NULL; @@ -556,12 +440,12 @@ OperatorDef(char *operatorName, * created so we don't have to worry about deleting them later. */ MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid)); - if (!leftTypeName) + if (!OidIsValid(leftTypeId)) { typeId[0] = rightTypeId; nargs = 1; } - else if (!rightTypeName) + else if (!OidIsValid(rightTypeId)) { typeId[0] = leftTypeId; nargs = 1; @@ -645,7 +529,7 @@ OperatorDef(char *operatorName, values[i++] = NameGetDatum(&oname); values[i++] = Int32GetDatum(GetUserId()); values[i++] = UInt16GetDatum(precedence); - values[i++] = CharGetDatum(leftTypeName ? (rightTypeName ? 'b' : 'r') : 'l'); + values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); values[i++] = BoolGetDatum(isLeftAssociative); values[i++] = BoolGetDatum(canHash); values[i++] = ObjectIdGetDatum(leftTypeId); @@ -667,8 +551,6 @@ OperatorDef(char *operatorName, { if (name[j]) { - char *otherLeftTypeName = NULL; - char *otherRightTypeName = NULL; Oid otherLeftTypeId = InvalidOid; Oid otherRightTypeId = InvalidOid; Oid other_oid = InvalidOid; @@ -677,46 +559,37 @@ OperatorDef(char *operatorName, switch (j) { case 0: /* commutator has reversed arg types */ - otherLeftTypeName = rightTypeName; - otherRightTypeName = leftTypeName; otherLeftTypeId = rightTypeId; otherRightTypeId = leftTypeId; other_oid = OperatorGet(name[j], - otherLeftTypeName, - otherRightTypeName, + otherLeftTypeId, + otherRightTypeId, &otherDefined); commutatorId = other_oid; break; case 1: /* negator has same arg types */ - otherLeftTypeName = leftTypeName; - otherRightTypeName = rightTypeName; otherLeftTypeId = leftTypeId; otherRightTypeId = rightTypeId; other_oid = OperatorGet(name[j], - otherLeftTypeName, - otherRightTypeName, + otherLeftTypeId, + otherRightTypeId, &otherDefined); negatorId = other_oid; break; case 2: /* left sort op takes left-side data type */ - otherLeftTypeName = leftTypeName; - otherRightTypeName = leftTypeName; otherLeftTypeId = leftTypeId; otherRightTypeId = leftTypeId; other_oid = OperatorGet(name[j], - otherLeftTypeName, - otherRightTypeName, + otherLeftTypeId, + otherRightTypeId, &otherDefined); break; - case 3: /* right sort op takes right-side data - * type */ - otherLeftTypeName = rightTypeName; - otherRightTypeName = rightTypeName; + case 3: /* right sort op takes right-side data type */ otherLeftTypeId = rightTypeId; otherRightTypeId = rightTypeId; other_oid = OperatorGet(name[j], - otherLeftTypeName, - otherRightTypeName, + otherLeftTypeId, + otherRightTypeId, &otherDefined); break; } @@ -732,8 +605,8 @@ OperatorDef(char *operatorName, { /* not in catalogs, different from operator */ other_oid = OperatorShellMake(name[j], - otherLeftTypeName, - otherRightTypeName); + otherLeftTypeId, + otherRightTypeId); if (!OidIsValid(other_oid)) elog(ERROR, "OperatorDef: can't create operator shell \"%s\"", @@ -1023,10 +896,10 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId) * * This is now just an interface procedure for OperatorDef ... * - * "X" indicates an optional argument (i.e. one that can be NULL) + * "X" indicates an optional argument (i.e. one that can be NULL or 0) * operatorName; -- operator name - * leftTypeName; -- X left type name - * rightTypeName; -- X right type name + * leftTypeId; -- X left type ID + * rightTypeId; -- X right type ID * procedureName; -- procedure for operator * precedence; -- operator precedence * isLeftAssociative; -- operator is left associative @@ -1039,24 +912,24 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId) * rightSortName; -- X right sort operator (for merge join) */ void -OperatorCreate(char *operatorName, - char *leftTypeName, - char *rightTypeName, - char *procedureName, +OperatorCreate(const char *operatorName, + Oid leftTypeId, + Oid rightTypeId, + const char *procedureName, uint16 precedence, bool isLeftAssociative, - char *commutatorName, - char *negatorName, - char *restrictionName, - char *joinName, + const char *commutatorName, + const char *negatorName, + const char *restrictionName, + const char *joinName, bool canHash, - char *leftSortName, - char *rightSortName) + const char *leftSortName, + const char *rightSortName) { - if (!leftTypeName && !rightTypeName) + if (!OidIsValid(leftTypeId) && !OidIsValid(rightTypeId)) elog(ERROR, "at least one of leftarg or rightarg must be specified"); - if (!(leftTypeName && rightTypeName)) + if (!(OidIsValid(leftTypeId) && OidIsValid(rightTypeId))) { /* If it's not a binary op, these things mustn't be set: */ if (commutatorName) @@ -1075,8 +948,8 @@ OperatorCreate(char *operatorName, * already exist. */ OperatorDef(operatorName, - leftTypeName, - rightTypeName, + leftTypeId, + rightTypeId, procedureName, precedence, isLeftAssociative, diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 78041ac585a..3c88a777793 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.66 2002/03/20 19:43:36 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.67 2002/03/29 19:06:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -41,9 +41,10 @@ static void checkretval(Oid rettype, List *queryTreeList); */ Oid ProcedureCreate(char *procedureName, + Oid procNamespace, bool replace, bool returnsSet, - char *returnTypeName, + Oid returnType, Oid languageObjectId, char *prosrc, char *probin, @@ -60,17 +61,14 @@ ProcedureCreate(char *procedureName, Relation rel; HeapTuple tup; HeapTuple oldtup; - bool defined; uint16 parameterCount; char nulls[Natts_pg_proc]; Datum values[Natts_pg_proc]; char replaces[Natts_pg_proc]; - Oid typeObjectId; List *x; List *querytree_list; Oid typev[FUNC_MAX_ARGS]; Oid relid; - Oid toid; NameData procname; TupleDesc tupDesc; Oid retval; @@ -86,28 +84,31 @@ ProcedureCreate(char *procedureName, foreach(x, argList) { TypeName *t = (TypeName *) lfirst(x); - char *typnam = TypeNameToInternalName(t); + Oid toid; if (parameterCount >= FUNC_MAX_ARGS) elog(ERROR, "functions cannot have more than %d arguments", FUNC_MAX_ARGS); - if (strcmp(typnam, "opaque") == 0) + toid = LookupTypeName(t); + if (OidIsValid(toid)) { - if (languageObjectId == SQLlanguageId) - elog(ERROR, "SQL functions cannot have arguments of type \"opaque\""); - toid = InvalidOid; + if (!get_typisdefined(toid)) + elog(WARNING, "Argument type \"%s\" is only a shell", + TypeNameToString(t)); } else { - toid = TypeGet(typnam, &defined); - - if (!OidIsValid(toid)) - elog(ERROR, "argument type %s does not exist", - typnam); - if (!defined) - elog(WARNING, "argument type %s is only a shell", - typnam); + char *typnam = TypeNameToString(t); + + if (strcmp(typnam, "opaque") == 0) + { + if (languageObjectId == SQLlanguageId) + elog(ERROR, "SQL functions cannot have arguments of type \"opaque\""); + toid = InvalidOid; + } + else + elog(ERROR, "Type \"%s\" does not exist", typnam); } if (t->setof) @@ -154,41 +155,21 @@ ProcedureCreate(char *procedureName, } } - if (strcmp(returnTypeName, "opaque") == 0) + if (!OidIsValid(returnType)) { if (languageObjectId == SQLlanguageId) elog(ERROR, "SQL functions cannot return type \"opaque\""); - typeObjectId = InvalidOid; - } - else - { - typeObjectId = TypeGet(returnTypeName, &defined); - - if (!OidIsValid(typeObjectId)) - { - elog(WARNING, "ProcedureCreate: type %s is not yet defined", - returnTypeName); - typeObjectId = TypeShellMake(returnTypeName); - if (!OidIsValid(typeObjectId)) - elog(ERROR, "could not create type %s", - returnTypeName); - } - else if (!defined) - elog(WARNING, "return type %s is only a shell", - returnTypeName); } /* * don't allow functions of complex types that have the same name as * existing attributes of the type */ - if (parameterCount == 1 && - (toid = TypeGet(strVal(lfirst(argList)), &defined)) && - defined && - (relid = typeidTypeRelid(toid)) != 0 && + if (parameterCount == 1 && OidIsValid(typev[0]) && + (relid = typeidTypeRelid(typev[0])) != 0 && get_attnum(relid, procedureName) != InvalidAttrNumber) elog(ERROR, "method %s already an attribute of type %s", - procedureName, strVal(lfirst(argList))); + procedureName, typeidTypeName(typev[0])); /* * If this is a postquel procedure, we parse it here in order to be @@ -201,7 +182,7 @@ ProcedureCreate(char *procedureName, { querytree_list = pg_parse_and_rewrite(prosrc, typev, parameterCount); /* typecheck return value */ - checkretval(typeObjectId, querytree_list); + checkretval(returnType, querytree_list); } /* @@ -271,7 +252,7 @@ ProcedureCreate(char *procedureName, values[i++] = BoolGetDatum(isStrict); values[i++] = UInt16GetDatum(parameterCount); values[i++] = BoolGetDatum(returnsSet); - values[i++] = ObjectIdGetDatum(typeObjectId); + values[i++] = ObjectIdGetDatum(returnType); values[i++] = PointerGetDatum(typev); values[i++] = Int32GetDatum(byte_pct); /* probyte_pct */ values[i++] = Int32GetDatum(perbyte_cpu); /* properbyte_cpu */ @@ -308,7 +289,7 @@ ProcedureCreate(char *procedureName, * Not okay to change the return type of the existing proc, since * existing rules, views, etc may depend on the return type. */ - if (typeObjectId != oldproc->prorettype || + if (returnType != oldproc->prorettype || returnsSet != oldproc->proretset) elog(ERROR, "ProcedureCreate: cannot change return type of existing function." "\n\tUse DROP FUNCTION first."); diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index 6878691241d..15c24c077ad 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.69 2002/03/20 19:43:38 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.70 2002/03/29 19:06:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,134 +19,42 @@ #include "catalog/indexing.h" #include "catalog/pg_type.h" #include "miscadmin.h" -#include "parser/parse_func.h" #include "utils/builtins.h" -#include "utils/fmgroids.h" #include "utils/syscache.h" -static Oid TypeShellMakeWithOpenRelation(Relation pg_type_desc, - char *typeName); - /* ---------------------------------------------------------------- - * TypeGetWithOpenRelation - * - * preforms a scan on pg_type for a type tuple with the - * given type name. - * ---------------------------------------------------------------- - * pg_type_desc -- reldesc for pg_type - * typeName -- name of type to be fetched - * defined -- has the type been defined? - */ -static Oid -TypeGetWithOpenRelation(Relation pg_type_desc, - char *typeName, - bool *defined) -{ - HeapScanDesc scan; - HeapTuple tup; - Oid typoid; - ScanKeyData typeKey[1]; - - /* - * initialize the scan key and begin a scan of pg_type - */ - ScanKeyEntryInitialize(&typeKey[0], - 0, - Anum_pg_type_typname, - F_NAMEEQ, - PointerGetDatum(typeName)); - - scan = heap_beginscan(pg_type_desc, - 0, - SnapshotSelf, /* cache? */ - 1, - typeKey); - - /* - * get the type tuple, if it exists. - */ - tup = heap_getnext(scan, 0); - - /* - * if no type tuple exists for the given type name, then end the scan - * and return appropriate information. - */ - if (!HeapTupleIsValid(tup)) - { - heap_endscan(scan); - *defined = false; - return InvalidOid; - } - - /* - * here, the type tuple does exist so we pull information from the - * typisdefined field of the tuple and return the tuple's oid, which - * is the oid of the type. - */ - *defined = (bool) ((Form_pg_type) GETSTRUCT(tup))->typisdefined; - typoid = tup->t_data->t_oid; - - heap_endscan(scan); - - return typoid; -} - -/* ---------------------------------------------------------------- - * TypeGet - * - * Finds the ObjectId of a type, even if uncommitted; "defined" - * is only set if the type has actually been defined, i.e., if - * the type tuple is not a shell. + * TypeShellMake * - * Note: the meat of this function is now in the function - * TypeGetWithOpenRelation(). -cim 6/15/90 + * This procedure inserts a "shell" tuple into the type + * relation. The type tuple inserted has invalid values + * and in particular, the "typisdefined" field is false. * - * Also called from util/remove.c + * This is used so that a tuple exists in the catalogs. + * The invalid fields should be fixed up sometime after + * this routine is called, and then the "typeisdefined" + * field is set to true. -cim 6/15/90 * ---------------------------------------------------------------- */ Oid -TypeGet(char *typeName, /* name of type to be fetched */ - bool *defined) /* has the type been defined? */ +TypeShellMake(const char *typeName, Oid typeNamespace) { Relation pg_type_desc; - Oid typeoid; - - /* - * open the pg_type relation - */ - pg_type_desc = heap_openr(TypeRelationName, AccessShareLock); - - /* - * scan the type relation for the information we want - */ - typeoid = TypeGetWithOpenRelation(pg_type_desc, - typeName, - defined); - - /* - * close the type relation and return the type oid. - */ - heap_close(pg_type_desc, AccessShareLock); - - return typeoid; -} - -/* ---------------------------------------------------------------- - * TypeShellMakeWithOpenRelation - * - * ---------------------------------------------------------------- - */ -static Oid -TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName) -{ + TupleDesc tupDesc; int i; HeapTuple tup; Datum values[Natts_pg_type]; char nulls[Natts_pg_type]; Oid typoid; NameData name; - TupleDesc tupDesc; + + Assert(PointerIsValid(typeName)); + + /* + * open pg_type + */ + pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock); + tupDesc = pg_type_desc->rd_att; /* * initialize our *nulls and *values arrays @@ -162,34 +70,33 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName) */ i = 0; namestrcpy(&name, typeName); - values[i++] = NameGetDatum(&name); /* 1 */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* 2 */ - values[i++] = Int16GetDatum(0); /* 3 */ - values[i++] = Int16GetDatum(0); /* 4 */ - values[i++] = BoolGetDatum(false); /* 5 */ - values[i++] = CharGetDatum(0); /* 6 */ - values[i++] = BoolGetDatum(false); /* 7 */ - values[i++] = CharGetDatum(0); /* 8 */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* 9 */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* 10 */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* 11 */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* 12 */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* 13 */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* 14 */ - values[i++] = CharGetDatum('i'); /* 15 */ - values[i++] = CharGetDatum('p'); /* 16 */ - values[i++] = BoolGetDatum(false); /* 17 */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* 18 */ - values[i++] = Int32GetDatum(-1); /* 19 */ - values[i++] = Int32GetDatum(0); /* 20 */ - nulls[i++] = 'n'; /* 21 */ - nulls[i++] = 'n'; /* 22 */ + values[i++] = NameGetDatum(&name); /* typname */ + values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typowner */ + values[i++] = Int16GetDatum(0); /* typlen */ + values[i++] = Int16GetDatum(0); /* typprtlen */ + values[i++] = BoolGetDatum(false); /* typbyval */ + values[i++] = CharGetDatum(0); /* typtype */ + values[i++] = BoolGetDatum(false); /* typisdefined */ + values[i++] = CharGetDatum(0); /* typdelim */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typrelid */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typelem */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typinput */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typoutput */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typsend */ + values[i++] = CharGetDatum('i'); /* typalign */ + values[i++] = CharGetDatum('p'); /* typstorage */ + values[i++] = BoolGetDatum(false); /* typnotnull */ + values[i++] = ObjectIdGetDatum(InvalidOid); /* typbasetype */ + values[i++] = Int32GetDatum(-1); /* typtypmod */ + values[i++] = Int32GetDatum(0); /* typndims */ + nulls[i++] = 'n'; /* typdefaultbin */ + nulls[i++] = 'n'; /* typdefault */ /* - * create a new type tuple with FormHeapTuple + * create a new type tuple */ - tupDesc = pg_type_desc->rd_att; - tup = heap_formtuple(tupDesc, values, nulls); /* @@ -208,47 +115,9 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName) } /* - * free the tuple and return the type-oid + * clean up and return the type-oid */ heap_freetuple(tup); - - return typoid; -} - -/* ---------------------------------------------------------------- - * TypeShellMake - * - * This procedure inserts a "shell" tuple into the type - * relation. The type tuple inserted has invalid values - * and in particular, the "typisdefined" field is false. - * - * This is used so that a tuple exists in the catalogs. - * The invalid fields should be fixed up sometime after - * this routine is called, and then the "typeisdefined" - * field is set to true. -cim 6/15/90 - * ---------------------------------------------------------------- - */ -Oid -TypeShellMake(char *typeName) -{ - Relation pg_type_desc; - Oid typoid; - - Assert(PointerIsValid(typeName)); - - /* - * open pg_type - */ - pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock); - - /* - * insert the shell tuple - */ - typoid = TypeShellMakeWithOpenRelation(pg_type_desc, typeName); - - /* - * close pg_type and return the tuple's oid. - */ heap_close(pg_type_desc, RowExclusiveLock); return typoid; @@ -266,77 +135,38 @@ TypeShellMake(char *typeName) * ---------------------------------------------------------------- */ Oid -TypeCreate(char *typeName, +TypeCreate(const char *typeName, + Oid typeNamespace, Oid assignedTypeOid, Oid relationOid, /* only for 'c'atalog typeTypes */ int16 internalSize, int16 externalSize, char typeType, char typDelim, - char *inputProcedure, - char *outputProcedure, - char *receiveProcedure, - char *sendProcedure, - char *elementTypeName, - char *baseTypeName, - char *defaultTypeValue, /* human readable rep */ - char *defaultTypeBin, /* cooked rep */ + Oid inputProcedure, + Oid outputProcedure, + Oid receiveProcedure, + Oid sendProcedure, + Oid elementType, + Oid baseType, + const char *defaultTypeValue, /* human readable rep */ + const char *defaultTypeBin, /* cooked rep */ bool passedByValue, char alignment, char storage, int32 typeMod, - int32 typNDims, /* Array dimensions for baseTypeName */ + int32 typNDims, /* Array dimensions for baseType */ bool typeNotNull) { - int i, - j; Relation pg_type_desc; - HeapScanDesc pg_type_scan; Oid typeObjectId; - Oid elementObjectId = InvalidOid; - Oid baseObjectId = InvalidOid; HeapTuple tup; char nulls[Natts_pg_type]; char replaces[Natts_pg_type]; Datum values[Natts_pg_type]; - char *procname; - char *procs[4]; - bool defined; NameData name; TupleDesc tupDesc; - Oid argList[FUNC_MAX_ARGS]; - ScanKeyData typeKey[1]; - - /* - * check that the type is not already defined. It might exist as a - * shell type, however (but only if assignedTypeOid is not given). - */ - typeObjectId = TypeGet(typeName, &defined); - if (OidIsValid(typeObjectId) && - (defined || assignedTypeOid != InvalidOid)) - elog(ERROR, "type named %s already exists", typeName); - - /* - * if this type has an associated elementType, then we check that it - * is defined. - */ - if (elementTypeName) - { - elementObjectId = TypeGet(elementTypeName, &defined); - if (!defined) - elog(ERROR, "type %s does not exist", elementTypeName); - } - - /* - * if this type has an associated baseType, then we check that it - * is defined. - */ - if (baseTypeName) - { - baseObjectId = TypeGet(baseTypeName, &defined); - if (!defined) - elog(ERROR, "type %s does not exist", baseTypeName); - } + int i; /* * validate size specifications: either positive (fixed-length) or -1 @@ -353,7 +183,7 @@ TypeCreate(char *typeName, elog(ERROR, "TypeCreate: fixed size types must have storage PLAIN"); /* - * initialize arrays needed by FormHeapTuple + * initialize arrays needed for heap_formtuple or heap_modifytuple */ for (i = 0; i < Natts_pg_type; ++i) { @@ -367,94 +197,27 @@ TypeCreate(char *typeName, */ i = 0; namestrcpy(&name, typeName); - values[i++] = NameGetDatum(&name); /* 1 */ - values[i++] = Int32GetDatum(GetUserId()); /* 2 */ - values[i++] = Int16GetDatum(internalSize); /* 3 */ - values[i++] = Int16GetDatum(externalSize); /* 4 */ - values[i++] = BoolGetDatum(passedByValue); /* 5 */ - values[i++] = CharGetDatum(typeType); /* 6 */ - values[i++] = BoolGetDatum(true); /* 7 */ - values[i++] = CharGetDatum(typDelim); /* 8 */ - values[i++] = ObjectIdGetDatum(typeType == 'c' ? relationOid : InvalidOid); /* 9 */ - values[i++] = ObjectIdGetDatum(elementObjectId); /* 10 */ - - procs[0] = inputProcedure; - procs[1] = outputProcedure; - procs[2] = (receiveProcedure) ? receiveProcedure : inputProcedure; - procs[3] = (sendProcedure) ? sendProcedure : outputProcedure; - - for (j = 0; j < 4; ++j) - { - Oid procOid; - - procname = procs[j]; - - /* - * First look for a 1-argument func with all argtypes 0. This is - * valid for all four kinds of procedure. - */ - MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); - - procOid = GetSysCacheOid(PROCNAME, - PointerGetDatum(procname), - Int32GetDatum(1), - PointerGetDatum(argList), - 0); - - if (!OidIsValid(procOid)) - { - /* - * For array types, the input procedures may take 3 args (data - * value, element OID, atttypmod); the pg_proc argtype - * signature is 0,OIDOID,INT4OID. The output procedures may - * take 2 args (data value, element OID). - */ - if (OidIsValid(elementObjectId) || OidIsValid(baseObjectId)) - { - int nargs; - - if (j % 2) - { - /* output proc */ - nargs = 2; - argList[1] = OIDOID; - } - else - { - /* input proc */ - nargs = 3; - argList[1] = OIDOID; - argList[2] = INT4OID; - } - procOid = GetSysCacheOid(PROCNAME, - PointerGetDatum(procname), - Int32GetDatum(nargs), - PointerGetDatum(argList), - 0); - } - - if (!OidIsValid(procOid)) - func_error("TypeCreate", procname, 1, argList, NULL); - } - - values[i++] = ObjectIdGetDatum(procOid); /* 11 - 14 */ - } - - /* - * set default alignment - */ - values[i++] = CharGetDatum(alignment); /* 15 */ - - /* - * set default storage for TOAST - */ - values[i++] = CharGetDatum(storage); /* 16 */ - - /* set typnotnull, typbasetype, typtypmod, typndims */ - values[i++] = BoolGetDatum(typeNotNull); /* 17 */ - values[i++] = ObjectIdGetDatum(baseObjectId); /* 18 */ - values[i++] = Int32GetDatum(typeMod); /* 19 */ - values[i++] = Int32GetDatum(typNDims); /* 20 */ + values[i++] = NameGetDatum(&name); /* typname */ + values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */ + values[i++] = Int32GetDatum(GetUserId()); /* typowner */ + values[i++] = Int16GetDatum(internalSize); /* typlen */ + values[i++] = Int16GetDatum(externalSize); /* typprtlen */ + values[i++] = BoolGetDatum(passedByValue); /* typbyval */ + values[i++] = CharGetDatum(typeType); /* typtype */ + values[i++] = BoolGetDatum(true); /* typisdefined */ + values[i++] = CharGetDatum(typDelim); /* typdelim */ + values[i++] = ObjectIdGetDatum(typeType == 'c' ? relationOid : InvalidOid); /* typrelid */ + values[i++] = ObjectIdGetDatum(elementType); /* typelem */ + values[i++] = ObjectIdGetDatum(inputProcedure); /* typinput */ + values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */ + values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */ + values[i++] = ObjectIdGetDatum(sendProcedure); /* typsend */ + values[i++] = CharGetDatum(alignment); /* typalign */ + values[i++] = CharGetDatum(storage); /* typstorage */ + values[i++] = BoolGetDatum(typeNotNull); /* typnotnull */ + values[i++] = ObjectIdGetDatum(baseType); /* typbasetype */ + values[i++] = Int32GetDatum(typeMod); /* typtypmod */ + values[i++] = Int32GetDatum(typNDims); /* typndims */ /* * initialize the default binary value for this type. Check for @@ -465,7 +228,7 @@ TypeCreate(char *typeName, CStringGetDatum(defaultTypeBin)); else nulls[i] = 'n'; - i++; /* 21 */ + i++; /* typdefaultbin */ /* * initialize the default value for this type. @@ -475,36 +238,33 @@ TypeCreate(char *typeName, CStringGetDatum(defaultTypeValue)); else nulls[i] = 'n'; - i++; /* 22 */ + i++; /* typdefault */ /* - * open pg_type and begin a scan for the type name. + * open pg_type and prepare to insert or update a row. + * + * NOTE: updating will not work correctly in bootstrap mode; but we don't + * expect to be overwriting any shell types in bootstrap mode. */ pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&typeKey[0], - 0, - Anum_pg_type_typname, - F_NAMEEQ, - PointerGetDatum(typeName)); - - pg_type_scan = heap_beginscan(pg_type_desc, - 0, - SnapshotSelf, /* cache? */ - 1, - typeKey); - - /* - * define the type either by adding a tuple to the type relation, or - * by updating the fields of the "shell" tuple already there. - */ - tup = heap_getnext(pg_type_scan, 0); + tup = SearchSysCacheCopy(TYPENAMENSP, + CStringGetDatum(typeName), + ObjectIdGetDatum(typeNamespace), + 0, 0); if (HeapTupleIsValid(tup)) { - /* should not happen given prior test? */ - if (assignedTypeOid != InvalidOid) + /* + * check that the type is not already defined. It may exist as a + * shell type, however (but only if assignedTypeOid is not given). + */ + if (((Form_pg_type) GETSTRUCT(tup))->typisdefined || + assignedTypeOid != InvalidOid) elog(ERROR, "type %s already exists", typeName); + /* + * Okay to update existing "shell" type tuple + */ tup = heap_modifytuple(tup, pg_type_desc, values, @@ -531,11 +291,7 @@ TypeCreate(char *typeName, typeObjectId = tup->t_data->t_oid; } - /* - * finish up - */ - heap_endscan(pg_type_scan); - + /* Update indices (not necessary if bootstrapping) */ if (RelationGetForm(pg_type_desc)->relhasindex) { Relation idescs[Num_pg_type_indices]; @@ -545,19 +301,25 @@ TypeCreate(char *typeName, CatalogCloseIndices(Num_pg_type_indices, idescs); } + /* + * finish up + */ heap_close(pg_type_desc, RowExclusiveLock); return typeObjectId; } -/* ---------------------------------------------------------------- - * TypeRename - * +/* + * TypeRename * This renames a type - * ---------------------------------------------------------------- + * + * Note: any associated array type is *not* renamed; caller must make + * another call to handle that case. Currently this is only used for + * renaming types associated with tables, for which there are no arrays. */ void -TypeRename(const char *oldTypeName, const char *newTypeName) +TypeRename(const char *oldTypeName, Oid typeNamespace, + const char *newTypeName) { Relation pg_type_desc; Relation idescs[Num_pg_type_indices]; @@ -565,15 +327,17 @@ TypeRename(const char *oldTypeName, const char *newTypeName) pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock); - tuple = SearchSysCacheCopy(TYPENAME, - PointerGetDatum(oldTypeName), - 0, 0, 0); + tuple = SearchSysCacheCopy(TYPENAMENSP, + CStringGetDatum(oldTypeName), + ObjectIdGetDatum(typeNamespace), + 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "type %s does not exist", oldTypeName); - if (SearchSysCacheExists(TYPENAME, - PointerGetDatum(newTypeName), - 0, 0, 0)) + if (SearchSysCacheExists(TYPENAMENSP, + CStringGetDatum(newTypeName), + ObjectIdGetDatum(typeNamespace), + 0, 0)) elog(ERROR, "type named %s already exists", newTypeName); namestrcpy(&(((Form_pg_type) GETSTRUCT(tuple))->typname), newTypeName); @@ -596,7 +360,7 @@ TypeRename(const char *oldTypeName, const char *newTypeName) * the caller is responsible for pfreeing the result */ char * -makeArrayTypeName(char *typeName) +makeArrayTypeName(const char *typeName) { char *arr; diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 0bd64232d1a..151577ae2d2 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.73 2002/03/26 19:15:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.74 2002/03/29 19:06:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -129,7 +129,7 @@ cluster(RangeVar *oldrelation, char *oldindexname) CommandCounterIncrement(); /* Destroy old heap (along with its index) and rename new. */ - heap_drop_with_catalog(saveoldrelation->relname, allowSystemTableMods); + heap_drop_with_catalog(OIDOldHeap, allowSystemTableMods); CommandCounterIncrement(); diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index bf7980d42c8..9180c539ff2 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.166 2002/03/26 19:15:36 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.167 2002/03/29 19:06:03 tgl Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -42,11 +42,12 @@ #include "optimizer/clauses.h" #include "optimizer/planmain.h" #include "optimizer/prep.h" +#include "parser/analyze.h" #include "parser/parse.h" #include "parser/parse_expr.h" #include "parser/parse_oper.h" #include "parser/parse_relation.h" -#include "parser/analyze.h" +#include "parser/parse_type.h" #include "tcop/utility.h" #include "utils/acl.h" #include "utils/builtins.h" @@ -58,9 +59,9 @@ static void drop_default(Oid relid, int16 attnum); static bool needs_toast_table(Relation rel); -static void AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId); static void CheckTupleType(Form_pg_class tuple_class); + /* -------------------------------- * PortalCleanup * -------------------------------- @@ -309,13 +310,13 @@ PerformPortalClose(char *name, CommandDest dest) * ---------------- */ void -AlterTableAddColumn(const char *relationName, +AlterTableAddColumn(Oid myrelid, bool inherits, ColumnDef *colDef) { Relation rel, + pgclass, attrdesc; - Oid myrelid; HeapTuple reltup; HeapTuple newreltup; HeapTuple attributeTuple; @@ -326,19 +327,17 @@ AlterTableAddColumn(const char *relationName, maxatts; HeapTuple typeTuple; Form_pg_type tform; - char *typename; int attndims; /* * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. */ - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); /* * permissions checking. this would normally be done in utility.c, @@ -346,13 +345,13 @@ AlterTableAddColumn(const char *relationName, * * normally, only the owner of a class can change its schema. */ - if (!allowSystemTableMods && IsSystemRelationName(relationName)) + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); + RelationGetRelationName(rel)); if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); - - heap_close(rel, NoLock); /* close rel but keep lock! */ + elog(ERROR, "ALTER TABLE: \"%s\": permission denied", + RelationGetRelationName(rel)); /* * Recurse to add the column to child classes, if requested. @@ -377,17 +376,11 @@ AlterTableAddColumn(const char *relationName, foreach(child, children) { Oid childrelid = lfirsti(child); - char *childrelname; if (childrelid == myrelid) continue; - rel = heap_open(childrelid, AccessExclusiveLock); - childrelname = pstrdup(RelationGetRelationName(rel)); - heap_close(rel, AccessExclusiveLock); - - AlterTableAddColumn(childrelname, false, colDef); - pfree(childrelname); + AlterTableAddColumn(childrelid, false, colDef); } } @@ -412,23 +405,21 @@ AlterTableAddColumn(const char *relationName, elog(ERROR, "Adding NOT NULL columns is not implemented." "\n\tAdd the column, then use ALTER TABLE ADD CONSTRAINT."); - - rel = heap_openr(RelationRelationName, RowExclusiveLock); + pgclass = heap_openr(RelationRelationName, RowExclusiveLock); reltup = SearchSysCache(RELOID, ObjectIdGetDatum(myrelid), 0, 0, 0); - if (!HeapTupleIsValid(reltup)) elog(ERROR, "ALTER TABLE: relation \"%s\" not found", - relationName); + RelationGetRelationName(rel)); if (SearchSysCacheExists(ATTNAME, ObjectIdGetDatum(myrelid), PointerGetDatum(colDef->colname), 0, 0)) elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"", - colDef->colname, relationName); + colDef->colname, RelationGetRelationName(rel)); minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts; maxatts = minattnum + 1; @@ -440,21 +431,11 @@ AlterTableAddColumn(const char *relationName, attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock); if (colDef->typename->arrayBounds) - { attndims = length(colDef->typename->arrayBounds); - typename = makeArrayTypeName(colDef->typename->name); - } else - { attndims = 0; - typename = colDef->typename->name; - } - typeTuple = SearchSysCache(TYPENAME, - PointerGetDatum(typename), - 0, 0, 0); - if (!HeapTupleIsValid(typeTuple)) - elog(ERROR, "ALTER TABLE: type \"%s\" does not exist", typename); + typeTuple = typenameType(colDef->typename); tform = (Form_pg_type) GETSTRUCT(typeTuple); attributeTuple = heap_addheader(Natts_pg_attribute, @@ -494,7 +475,7 @@ AlterTableAddColumn(const char *relationName, CatalogCloseIndices(Num_pg_attr_indices, idescs); } - heap_close(attrdesc, NoLock); + heap_close(attrdesc, RowExclusiveLock); /* * Update number of attributes in pg_class tuple @@ -502,22 +483,24 @@ AlterTableAddColumn(const char *relationName, newreltup = heap_copytuple(reltup); ((Form_pg_class) GETSTRUCT(newreltup))->relnatts = maxatts; - simple_heap_update(rel, &newreltup->t_self, newreltup); + simple_heap_update(pgclass, &newreltup->t_self, newreltup); /* keep catalog indices current */ - if (RelationGetForm(rel)->relhasindex) + if (RelationGetForm(pgclass)->relhasindex) { Relation ridescs[Num_pg_class_indices]; CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs); - CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, newreltup); + CatalogIndexInsert(ridescs, Num_pg_class_indices, pgclass, newreltup); CatalogCloseIndices(Num_pg_class_indices, ridescs); } heap_freetuple(newreltup); ReleaseSysCache(reltup); - heap_close(rel, NoLock); + heap_close(pgclass, NoLock); + + heap_close(rel, NoLock); /* close rel but keep lock! */ /* * Make our catalog updates visible for subsequent steps. @@ -549,29 +532,28 @@ AlterTableAddColumn(const char *relationName, * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT */ void -AlterTableAlterColumnDefault(const char *relationName, +AlterTableAlterColumnDefault(Oid myrelid, bool inh, const char *colName, Node *newDefault) { Relation rel; HeapTuple tuple; int16 attnum; - Oid myrelid; - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); - if (!allowSystemTableMods && IsSystemRelationName(relationName)) + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); - if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); + RelationGetRelationName(rel)); - heap_close(rel, NoLock); + if (!pg_class_ownercheck(myrelid, GetUserId())) + elog(ERROR, "ALTER TABLE: \"%s\" permission denied", + RelationGetRelationName(rel)); /* * Propagate to children if desired @@ -595,18 +577,13 @@ AlterTableAlterColumnDefault(const char *relationName, if (childrelid == myrelid) continue; - rel = heap_open(childrelid, AccessExclusiveLock); - AlterTableAlterColumnDefault(RelationGetRelationName(rel), + AlterTableAlterColumnDefault(childrelid, false, colName, newDefault); - heap_close(rel, AccessExclusiveLock); } } /* -= now do the thing on this relation =- */ - /* reopen the business */ - rel = heap_openr(relationName, AccessExclusiveLock); - /* * get the number of the attribute */ @@ -616,7 +593,7 @@ AlterTableAlterColumnDefault(const char *relationName, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", - relationName, colName); + RelationGetRelationName(rel), colName); attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; ReleaseSysCache(tuple); @@ -718,43 +695,42 @@ drop_default(Oid relid, int16 attnum) * ALTER TABLE ALTER COLUMN SET STATISTICS / STORAGE */ void -AlterTableAlterColumnFlags(const char *relationName, +AlterTableAlterColumnFlags(Oid myrelid, bool inh, const char *colName, Node *flagValue, const char *flagType) { Relation rel; - Oid myrelid; int newtarget = 1; char newstorage = 'x'; char *storagemode; Relation attrelation; HeapTuple tuple; - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); - /* we allow statistics case for system tables */ - if (*flagType == 'M' && - !allowSystemTableMods && IsSystemRelationName(relationName)) + /* + * we allow statistics case for system tables + */ + if (*flagType != 'S' && + !allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); - if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); - - heap_close(rel, NoLock); /* close rel, but keep lock! */ + RelationGetRelationName(rel)); + if (!pg_class_ownercheck(myrelid, GetUserId())) + elog(ERROR, "ALTER TABLE: \"%s\" permission denied", + RelationGetRelationName(rel)); /* * Check the supplied parameters before anything else */ - if (*flagType == 'S') /* - * STATISTICS - */ + if (*flagType == 'S') { + /* STATISTICS */ Assert(IsA(flagValue, Integer)); newtarget = intVal(flagValue); @@ -766,10 +742,9 @@ AlterTableAlterColumnFlags(const char *relationName, else if (newtarget > 1000) newtarget = 1000; } - else if (*flagType == 'M') /* - * STORAGE - */ + else if (*flagType == 'M') { + /* STORAGE */ Assert(IsA(flagValue, Value)); storagemode = strVal(flagValue); @@ -813,10 +788,8 @@ AlterTableAlterColumnFlags(const char *relationName, if (childrelid == myrelid) continue; - rel = heap_open(childrelid, AccessExclusiveLock); - AlterTableAlterColumnFlags(RelationGetRelationName(rel), - false, colName, flagValue, flagType); - heap_close(rel, AccessExclusiveLock); + AlterTableAlterColumnFlags(childrelid, + false, colName, flagValue, flagType); } } @@ -830,7 +803,7 @@ AlterTableAlterColumnFlags(const char *relationName, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", - relationName, colName); + RelationGetRelationName(rel), colName); if (((Form_pg_attribute) GETSTRUCT(tuple))->attnum < 0) elog(ERROR, "ALTER TABLE: cannot change system attribute \"%s\"", @@ -864,6 +837,7 @@ AlterTableAlterColumnFlags(const char *relationName, heap_freetuple(tuple); heap_close(attrelation, NoLock); + heap_close(rel, NoLock); /* close rel, but keep lock! */ } @@ -1006,14 +980,13 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup) * ALTER TABLE DROP COLUMN */ void -AlterTableDropColumn(const char *relationName, +AlterTableDropColumn(Oid myrelid, bool inh, const char *colName, int behavior) { #ifdef _DROP_COLUMN_HACK__ Relation rel, attrdesc; - Oid myrelid; HeapTuple reltup; HeapTupleData classtuple; Buffer buffer; @@ -1031,12 +1004,16 @@ AlterTableDropColumn(const char *relationName, * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. */ - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); + + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel)) + elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", + RelationGetRelationName(rel)); /* * permissions checking. this would normally be done in utility.c, @@ -1044,9 +1021,6 @@ AlterTableDropColumn(const char *relationName, * * normally, only the owner of a class can change its schema. */ - if (!allowSystemTableMods && IsSystemRelationName(relationName)) - elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); if (!pg_class_ownercheck(myrelid, GetUserId())) elog(ERROR, "ALTER TABLE: permission denied"); @@ -1066,8 +1040,17 @@ AlterTableDropColumn(const char *relationName, ObjectIdGetDatum(myrelid), 0, 0, 0); if (!HeapTupleIsValid(reltup)) + { + Relation myrel; + char *myrelname; + + myrel = heap_open(myrelid, AccessExclusiveLock); + myrelname = pstrdup(RelationGetRelationName(myrel)); + heap_close(myrel, AccessExclusiveLock); + elog(ERROR, "ALTER TABLE: relation \"%s\" not found", - relationName); + myrelname); + } classtuple.t_self = reltup->t_self; ReleaseSysCache(reltup); @@ -1092,8 +1075,17 @@ AlterTableDropColumn(const char *relationName, PointerGetDatum(colName), 0, 0); if (!HeapTupleIsValid(tup)) + { + Relation myrel; + char *myrelname; + + myrel = heap_open(myrelid, AccessExclusiveLock); + myrelname = pstrdup(RelationGetRelationName(myrel)); + heap_close(myrel, AccessExclusiveLock); + elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"", - colName, relationName); + colName, myrelname); + } attribute = (Form_pg_attribute) GETSTRUCT(tup); attnum = attribute->attnum; @@ -1164,29 +1156,30 @@ AlterTableDropColumn(const char *relationName, * ALTER TABLE ADD CONSTRAINT */ void -AlterTableAddConstraint(char *relationName, +AlterTableAddConstraint(Oid myrelid, bool inh, List *newConstraints) { Relation rel; - Oid myrelid; List *listptr; /* * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. */ - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); - if (!allowSystemTableMods && IsSystemRelationName(relationName)) + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); + RelationGetRelationName(rel)); + if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); + elog(ERROR, "ALTER TABLE: \"%s\": permission denied", + RelationGetRelationName(rel)); if (inh) { @@ -1204,16 +1197,10 @@ AlterTableAddConstraint(char *relationName, foreach(child, children) { Oid childrelid = lfirsti(child); - char *childrelname; - Relation childrel; if (childrelid == myrelid) continue; - childrel = heap_open(childrelid, AccessExclusiveLock); - childrelname = pstrdup(RelationGetRelationName(childrel)); - heap_close(childrel, AccessExclusiveLock); - AlterTableAddConstraint(childrelname, false, newConstraints); - pfree(childrelname); + AlterTableAddConstraint(childrelid, false, newConstraints); } } @@ -1262,7 +1249,7 @@ AlterTableAddConstraint(char *relationName, pstate = make_parsestate(NULL); rte = addRangeTableEntryForRelation(pstate, myrelid, - makeAlias(relationName, NIL), + makeAlias(RelationGetRelationName(rel), NIL), false, true); addRTEtoQuery(pstate, rte, true, true); @@ -1286,7 +1273,7 @@ AlterTableAddConstraint(char *relationName, */ if (length(pstate->p_rtable) != 1) elog(ERROR, "Only relation '%s' can be referenced in CHECK", - relationName); + RelationGetRelationName(rel)); /* * Might as well try to reduce any @@ -1358,7 +1345,7 @@ AlterTableAddConstraint(char *relationName, int count; if (is_temp_rel_name(fkconstraint->pktable->relname) && - !is_temp_rel_name(relationName)) + !is_temp_rel_name(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint."); /* @@ -1408,7 +1395,7 @@ AlterTableAddConstraint(char *relationName, trig.tgargs[0] = fkconstraint->constr_name; else trig.tgargs[0] = "<unknown>"; - trig.tgargs[1] = (char *) relationName; + trig.tgargs[1] = pstrdup(RelationGetRelationName(rel)); trig.tgargs[2] = fkconstraint->pktable->relname; trig.tgargs[3] = fkconstraint->match_type; count = 4; @@ -1483,12 +1470,11 @@ AlterTableAddConstraint(char *relationName, * Christopher Kings-Lynne */ void -AlterTableDropConstraint(const char *relationName, +AlterTableDropConstraint(Oid myrelid, bool inh, const char *constrName, int behavior) { Relation rel; - Oid myrelid; int deleted; /* @@ -1502,19 +1488,21 @@ AlterTableDropConstraint(const char *relationName, * Acquire an exclusive lock on the target relation for the duration * of the operation. */ - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); /* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */ if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); - if (!allowSystemTableMods && IsSystemRelationName(relationName)) + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); + RelationGetRelationName(rel)); + if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); + elog(ERROR, "ALTER TABLE: \"%s\": permission denied", + RelationGetRelationName(rel)); /* * Since all we have is the name of the constraint, we have to look @@ -1554,30 +1542,7 @@ AlterTableDropConstraint(const char *relationName, * ALTER TABLE OWNER */ void -AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName) -{ - Relation rel; - Oid myrelid; - int32 newOwnerSysId; - - /* check that we are the superuser */ - if (!superuser()) - elog(ERROR, "ALTER TABLE: permission denied"); - - /* lookup the OID of the target relation */ - rel = relation_openrv(tgtrel, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); - heap_close(rel, NoLock); /* close rel but keep lock! */ - - /* lookup the sysid of the new owner */ - newOwnerSysId = get_usesysid(newOwnerName); - - /* do all the actual work */ - AlterTableOwnerId(myrelid, newOwnerSysId); -} - -static void -AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) +AlterTableOwner(Oid relationOid, int32 newOwnerSysId) { Relation target_rel; Relation class_rel; @@ -1629,7 +1594,7 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) /* For each index, recursively change its ownership */ foreach(i, index_oid_list) { - AlterTableOwnerId(lfirsti(i), newOwnerSysId); + AlterTableOwner(lfirsti(i), newOwnerSysId); } freeList(index_oid_list); @@ -1640,7 +1605,7 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) /* If it has a toast table, recurse to change its ownership */ if (tuple_class->reltoastrelid != InvalidOid) { - AlterTableOwnerId(tuple_class->reltoastrelid, newOwnerSysId); + AlterTableOwner(tuple_class->reltoastrelid, newOwnerSysId); } } diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index cdc8ce35be3..f8e5bc6fc6f 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -7,7 +7,7 @@ * Copyright (c) 1999-2001, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.37 2002/03/26 19:15:38 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.38 2002/03/29 19:06:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -27,9 +27,10 @@ #include "catalog/pg_type.h" #include "commands/comment.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "parser/parse_agg.h" -#include "parser/parse_expr.h" #include "parser/parse_func.h" +#include "parser/parse_type.h" #include "parser/parse.h" #include "rewrite/rewriteRemove.h" #include "utils/acl.h" @@ -51,14 +52,16 @@ static void CommentRelation(int objtype, char * schemaname, char *relation, char *comment); -static void CommentAttribute(char *relation, char *attrib, char *comment); +static void CommentAttribute(char * schemaname, char *relation, + char *attrib, char *comment); static void CommentDatabase(char *database, char *comment); static void CommentRewrite(char *rule, char *comment); static void CommentType(char *type, char *comment); static void CommentAggregate(char *aggregate, List *arguments, char *comment); static void CommentProc(char *function, List *arguments, char *comment); static void CommentOperator(char *opname, List *arguments, char *comment); -static void CommentTrigger(char *trigger, char *relation, char *comments); +static void CommentTrigger(char *trigger, char *schemaname, char *relation, + char *comments); /*------------------------------------------------------------------ @@ -88,7 +91,7 @@ CommentObject(int objtype, char *schemaname, char *objname, char *objproperty, CommentRelation(objtype, schemaname, objname, comment); break; case COLUMN: - CommentAttribute(objname, objproperty, comment); + CommentAttribute(schemaname, objname, objproperty, comment); break; case DATABASE: CommentDatabase(objname, comment); @@ -109,7 +112,7 @@ CommentObject(int objtype, char *schemaname, char *objname, char *objproperty, CommentOperator(objname, objlist, comment); break; case TRIGGER: - CommentTrigger(objname, objproperty, comment); + CommentTrigger(objname, schemaname, objproperty, comment); break; default: elog(ERROR, "An attempt was made to comment on a unknown type: %d", @@ -391,14 +394,18 @@ CommentRelation(int reltype, char *schemaname, char *relname, char *comment) */ static void -CommentAttribute(char *relname, char *attrname, char *comment) +CommentAttribute(char *schemaname, char *relname, char *attrname, char *comment) { + RangeVar *rel = makeNode(RangeVar); Relation relation; AttrNumber attnum; /* Open the containing relation to ensure it won't go away meanwhile */ - relation = heap_openr(relname, AccessShareLock); + rel->relname = relname; + rel->schemaname = schemaname; + rel->istemp = false; + relation = heap_openrv(rel, AccessShareLock); /* Check object security */ @@ -539,11 +546,8 @@ CommentType(char *type, char *comment) /* Find the type's oid */ - oid = GetSysCacheOid(TYPENAME, - PointerGetDatum(type), - 0, 0, 0); - if (!OidIsValid(oid)) - elog(ERROR, "type '%s' does not exist", type); + /* XXX WRONG: need to deal with qualified type names */ + oid = typenameTypeId(makeTypeName(type)); /* Check object security */ @@ -570,21 +574,13 @@ static void CommentAggregate(char *aggregate, List *arguments, char *comment) { TypeName *aggtype = (TypeName *) lfirst(arguments); - char *aggtypename; Oid baseoid, oid; Oid classoid; - bool defined; /* First, attempt to determine the base aggregate oid */ - if (aggtype) - { - aggtypename = TypeNameToInternalName(aggtype); - baseoid = TypeGet(aggtypename, &defined); - if (!OidIsValid(baseoid)) - elog(ERROR, "type '%s' does not exist", aggtypename); - } + baseoid = typenameTypeId(aggtype); else baseoid = InvalidOid; @@ -648,20 +644,19 @@ CommentProc(char *function, List *arguments, char *comment) for (i = 0; i < argcount; i++) { TypeName *t = (TypeName *) lfirst(arguments); - char *typnam = TypeNameToInternalName(t); - - arguments = lnext(arguments); - if (strcmp(typnam, "opaque") == 0) - argoids[i] = InvalidOid; - else + argoids[i] = LookupTypeName(t); + if (!OidIsValid(argoids[i])) { - argoids[i] = GetSysCacheOid(TYPENAME, - PointerGetDatum(typnam), - 0, 0, 0); - if (!OidIsValid(argoids[i])) - elog(ERROR, "CommentProc: type '%s' not found", typnam); + char *typnam = TypeNameToString(t); + + if (strcmp(typnam, "opaque") == 0) + argoids[i] = InvalidOid; + else + elog(ERROR, "Type \"%s\" does not exist", typnam); } + + arguments = lnext(arguments); } /* Now, find the corresponding oid for this procedure */ @@ -707,40 +702,20 @@ CommentOperator(char *opername, List *arguments, char *comment) { TypeName *typenode1 = (TypeName *) lfirst(arguments); TypeName *typenode2 = (TypeName *) lsecond(arguments); - char oprtype = 0, - *lefttype = NULL, - *righttype = NULL; + char oprtype = 0; Form_pg_operator data; HeapTuple optuple; Oid oid, leftoid = InvalidOid, rightoid = InvalidOid; - bool defined; - - /* Initialize our left and right argument types */ + /* Attempt to fetch the left type oid, if specified */ if (typenode1 != NULL) - lefttype = TypeNameToInternalName(typenode1); - if (typenode2 != NULL) - righttype = TypeNameToInternalName(typenode2); - - /* Attempt to fetch the left oid, if specified */ - - if (lefttype != NULL) - { - leftoid = TypeGet(lefttype, &defined); - if (!OidIsValid(leftoid)) - elog(ERROR, "left type '%s' does not exist", lefttype); - } - - /* Attempt to fetch the right oid, if specified */ + leftoid = typenameTypeId(typenode1); - if (righttype != NULL) - { - rightoid = TypeGet(righttype, &defined); - if (!OidIsValid(rightoid)) - elog(ERROR, "right type '%s' does not exist", righttype); - } + /* Attempt to fetch the right type oid, if specified */ + if (typenode2 != NULL) + rightoid = typenameTypeId(typenode2); /* Determine operator type */ @@ -797,8 +772,9 @@ CommentOperator(char *opername, List *arguments, char *comment) */ static void -CommentTrigger(char *trigger, char *relname, char *comment) +CommentTrigger(char *trigger, char *schemaname, char *relname, char *comment) { + RangeVar *rel = makeNode(RangeVar); Relation pg_trigger, relation; HeapTuple triggertuple; @@ -808,7 +784,10 @@ CommentTrigger(char *trigger, char *relname, char *comment) /* First, validate the user's action */ - relation = heap_openr(relname, AccessShareLock); + rel->relname = relname; + rel->schemaname = schemaname; + rel->istemp = false; + relation = heap_openrv(rel, AccessShareLock); if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId())) elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'", diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index fc4f80468cd..45e108027fd 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.151 2002/03/21 23:27:20 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.152 2002/03/29 19:06:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ #include "access/printtup.h" #include "catalog/catname.h" #include "catalog/index.h" +#include "catalog/namespace.h" #include "catalog/pg_index.h" #include "catalog/pg_shadow.h" #include "catalog/pg_type.h" @@ -228,7 +229,7 @@ CopyDonePeek(FILE *fp, int c, bool pickup) /* * DoCopy executes the SQL COPY statement. * - * Either unload or reload contents of table <relname>, depending on <from>. + * Either unload or reload contents of table <relation>, depending on <from>. * (<from> = TRUE means we are inserting into the table.) * * If <pipe> is false, transfer is between the table and the file named @@ -260,7 +261,7 @@ CopyDonePeek(FILE *fp, int c, bool pickup) * the table. */ void -DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, +DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe, char *filename, char *delim, char *null_print) { FILE *fp; @@ -271,7 +272,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, /* * Open and lock the relation, using the appropriate lock type. */ - rel = heap_openr(relname, (from ? RowExclusiveLock : AccessShareLock)); + rel = heap_openrv(relation, (from ? RowExclusiveLock : AccessShareLock)); /* Check permissions. */ aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), @@ -312,11 +313,14 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, if (rel->rd_rel->relkind != RELKIND_RELATION) { if (rel->rd_rel->relkind == RELKIND_VIEW) - elog(ERROR, "You cannot copy view %s", relname); + elog(ERROR, "You cannot copy view %s", + RelationGetRelationName(rel)); else if (rel->rd_rel->relkind == RELKIND_SEQUENCE) - elog(ERROR, "You cannot change sequence relation %s", relname); + elog(ERROR, "You cannot change sequence relation %s", + RelationGetRelationName(rel)); else - elog(ERROR, "You cannot copy object %s", relname); + elog(ERROR, "You cannot copy object %s", + RelationGetRelationName(rel)); } if (pipe) { @@ -354,11 +358,14 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, if (rel->rd_rel->relkind != RELKIND_RELATION) { if (rel->rd_rel->relkind == RELKIND_VIEW) - elog(ERROR, "You cannot copy view %s", relname); + elog(ERROR, "You cannot copy view %s", + RelationGetRelationName(rel)); else if (rel->rd_rel->relkind == RELKIND_SEQUENCE) - elog(ERROR, "You cannot copy sequence %s", relname); + elog(ERROR, "You cannot copy sequence %s", + RelationGetRelationName(rel)); else - elog(ERROR, "You cannot copy object %s", relname); + elog(ERROR, "You cannot copy object %s", + RelationGetRelationName(rel)); } if (pipe) { diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index 2d68d5d6e7f..1cf84f17a3e 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.92 2002/03/26 19:15:40 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.93 2002/03/29 19:06:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ #include "commands/creatinh.h" #include "miscadmin.h" #include "optimizer/clauses.h" +#include "parser/parse_type.h" #include "utils/acl.h" #include "utils/syscache.h" #include "utils/temprel.h" @@ -108,7 +109,7 @@ DefineRelation(CreateStmt *stmt, char relkind) * (BuildDescForRelation takes care of the inherited defaults, but we * have to copy inherited constraints here.) */ - descriptor = BuildDescForRelation(schema, relname); + descriptor = BuildDescForRelation(schema); if (old_constraints != NIL) { @@ -238,10 +239,12 @@ DefineRelation(CreateStmt *stmt, char relkind) * themselves will be destroyed, too. */ void -RemoveRelation(const char *name) +RemoveRelation(const RangeVar *relation) { - AssertArg(name); - heap_drop_with_catalog(name, allowSystemTableMods); + Oid relOid; + + relOid = RangeVarGetRelid(relation, false); + heap_drop_with_catalog(relOid, allowSystemTableMods); } /* @@ -255,34 +258,36 @@ RemoveRelation(const char *name) * Rows are removed, indices are truncated and reconstructed. */ void -TruncateRelation(const char *relname) +TruncateRelation(const RangeVar *relation) { + Oid relid; Relation rel; - AssertArg(relname); + relid = RangeVarGetRelid(relation, false); /* Grab exclusive lock in preparation for truncate */ - rel = heap_openr(relname, AccessExclusiveLock); + rel = heap_open(relid, AccessExclusiveLock); if (rel->rd_rel->relkind == RELKIND_SEQUENCE) elog(ERROR, "TRUNCATE cannot be used on sequences. '%s' is a sequence", - relname); + RelationGetRelationName(rel)); if (rel->rd_rel->relkind == RELKIND_VIEW) elog(ERROR, "TRUNCATE cannot be used on views. '%s' is a view", - relname); + RelationGetRelationName(rel)); - if (!allowSystemTableMods && IsSystemRelationName(relname)) + if (!allowSystemTableMods && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table", - relname); + RelationGetRelationName(rel)); if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) - elog(ERROR, "you do not own relation \"%s\"", relname); + elog(ERROR, "you do not own relation \"%s\"", + RelationGetRelationName(rel)); /* Keep the lock until transaction commit */ heap_close(rel, NoLock); - heap_truncate(relname); + heap_truncate(relid); } @@ -308,12 +313,7 @@ MergeDomainAttributes(List *schema) HeapTuple tuple; Form_pg_type typeTup; - tuple = SearchSysCache(TYPENAME, - CStringGetDatum(coldef->typename->name), - 0,0,0); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "MergeDomainAttributes: Type %s does not exist", - coldef->typename->name); + tuple = typenameType(coldef->typename); typeTup = (Form_pg_type) GETSTRUCT(tuple); if (typeTup->typtype == 'd') @@ -486,27 +486,12 @@ MergeAttributes(List *schema, List *supers, bool istemp, parent_attno++) { Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1]; - char *attributeName; - char *attributeType; - HeapTuple tuple; + char *attributeName = NameStr(attribute->attname); int exist_attno; ColumnDef *def; TypeName *typename; /* - * Get name and type name of attribute - */ - attributeName = NameStr(attribute->attname); - tuple = SearchSysCache(TYPEOID, - ObjectIdGetDatum(attribute->atttypid), - 0, 0, 0); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "CREATE TABLE: cache lookup failed for type %u", - attribute->atttypid); - attributeType = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname)); - ReleaseSysCache(tuple); - - /* * Does it conflict with some previously inherited column? */ exist_attno = findAttrByName(attributeName, inhSchema); @@ -519,10 +504,12 @@ MergeAttributes(List *schema, List *supers, bool istemp, elog(NOTICE, "CREATE TABLE: merging multiple inherited definitions of attribute \"%s\"", attributeName); def = (ColumnDef *) nth(exist_attno - 1, inhSchema); - if (strcmp(def->typename->name, attributeType) != 0 || + if (typenameTypeId(def->typename) != attribute->atttypid || def->typename->typmod != attribute->atttypmod) elog(ERROR, "CREATE TABLE: inherited attribute \"%s\" type conflict (%s and %s)", - attributeName, def->typename->name, attributeType); + attributeName, + TypeNameToString(def->typename), + typeidTypeName(attribute->atttypid)); /* Merge of NOT NULL constraints = OR 'em together */ def->is_not_null |= attribute->attnotnull; /* Default and other constraints are handled below */ @@ -536,7 +523,7 @@ MergeAttributes(List *schema, List *supers, bool istemp, def = makeNode(ColumnDef); def->colname = pstrdup(attributeName); typename = makeNode(TypeName); - typename->name = attributeType; + typename->typeid = attribute->atttypid; typename->typmod = attribute->atttypmod; def->typename = typename; def->is_not_null = attribute->attnotnull; @@ -640,7 +627,6 @@ MergeAttributes(List *schema, List *supers, bool istemp, { ColumnDef *newdef = lfirst(entry); char *attributeName = newdef->colname; - char *attributeType = newdef->typename->name; int exist_attno; /* @@ -658,10 +644,12 @@ MergeAttributes(List *schema, List *supers, bool istemp, elog(NOTICE, "CREATE TABLE: merging attribute \"%s\" with inherited definition", attributeName); def = (ColumnDef *) nth(exist_attno - 1, inhSchema); - if (strcmp(def->typename->name, attributeType) != 0 || + if (typenameTypeId(def->typename) != typenameTypeId(newdef->typename) || def->typename->typmod != newdef->typename->typmod) elog(ERROR, "CREATE TABLE: attribute \"%s\" type conflict (%s and %s)", - attributeName, def->typename->name, attributeType); + attributeName, + TypeNameToString(def->typename), + TypeNameToString(newdef->typename)); /* Merge of NOT NULL constraints = OR 'em together */ def->is_not_null |= newdef->is_not_null; /* If new def has a default, override previous default */ diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index 2441e49bcaa..1d1139bd362 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.71 2002/03/20 19:43:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.72 2002/03/29 19:06:06 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -41,6 +41,7 @@ #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/heap.h" +#include "catalog/namespace.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_language.h" #include "catalog/pg_operator.h" @@ -50,13 +51,19 @@ #include "fmgr.h" #include "miscadmin.h" #include "optimizer/cost.h" -#include "parser/parse_expr.h" +#include "parser/parse_func.h" +#include "parser/parse_type.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/fmgroids.h" +#include "utils/lsyscache.h" #include "utils/syscache.h" + +static Oid findTypeIOFunction(const char *procname, bool isOutput); static char *defGetString(DefElem *def); static double defGetNumeric(DefElem *def); +static TypeName *defGetTypeName(DefElem *def); static int defGetTypeLength(DefElem *def); #define DEFAULT_TYPDELIM ',' @@ -77,16 +84,59 @@ case_translate_language_name(const char *input, char *output) } - -static void -compute_return_type(TypeName *returnType, - char **prorettype_p, bool *returnsSet_p) -{ /* * Examine the "returns" clause returnType of the CREATE FUNCTION statement * and return information about it as *prorettype_p and *returnsSet. + * + * This is more complex than the average typename lookup because we want to + * allow a shell type to be used, or even created if the specified return type + * doesn't exist yet. (Without this, there's no way to define the I/O procs + * for a new type.) But SQL function creation won't cope, so error out if + * the target language is SQL. */ - *prorettype_p = TypeNameToInternalName(returnType); +static void +compute_return_type(TypeName *returnType, Oid languageOid, + Oid *prorettype_p, bool *returnsSet_p) +{ + Oid rettype; + + rettype = LookupTypeName(returnType); + + if (OidIsValid(rettype)) + { + if (!get_typisdefined(rettype)) + { + if (languageOid == SQLlanguageId) + elog(ERROR, "SQL functions cannot return shell types"); + else + elog(WARNING, "Return type \"%s\" is only a shell", + TypeNameToString(returnType)); + } + } + else + { + char *typnam = TypeNameToString(returnType); + + if (strcmp(typnam, "opaque") == 0) + rettype = InvalidOid; + else + { + Oid namespaceId; + char *typname; + + if (languageOid == SQLlanguageId) + elog(ERROR, "Type \"%s\" does not exist", typnam); + elog(WARNING, "ProcedureCreate: type %s is not yet defined", + typnam); + namespaceId = QualifiedNameGetCreationNamespace(returnType->names, + &typname); + rettype = TypeShellMake(typname, namespaceId); + if (!OidIsValid(rettype)) + elog(ERROR, "could not create type %s", typnam); + } + } + + *prorettype_p = rettype; *returnsSet_p = returnType->setof; } @@ -211,34 +261,31 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as, void CreateFunction(ProcedureStmt *stmt) { - /* pathname of executable file that executes this function, if any */ char *probin_str; - /* SQL that executes this function, if any */ char *prosrc_str; - /* Type of return value (or member of set of values) from function */ - char *prorettype; - /* name of language of function, with case adjusted */ - char languageName[NAMEDATALEN]; - /* The function returns a set of values, as opposed to a singleton. */ + Oid prorettype; bool returnsSet; - /* - * The following are optional user-supplied attributes of the - * function. - */ + char languageName[NAMEDATALEN]; + Oid languageOid; + char *funcname; + Oid namespaceId; int32 byte_pct, perbyte_cpu, percall_cpu, outin_ratio; bool canCache, isStrict; - HeapTuple languageTuple; Form_pg_language languageStruct; - Oid languageOid; + + /* Convert list of names to a name and namespace */ + namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname, + &funcname); /* Convert language name to canonical case */ case_translate_language_name(stmt->language, languageName); + /* Look up the language and validate permissions */ languageTuple = SearchSysCache(LANGNAME, PointerGetDatum(languageName), 0, 0, 0); @@ -259,21 +306,22 @@ CreateFunction(ProcedureStmt *stmt) * Convert remaining parameters of CREATE to form wanted by * ProcedureCreate. */ - Assert(IsA(stmt->returnType, TypeName)); - compute_return_type((TypeName *) stmt->returnType, + compute_return_type(stmt->returnType, languageOid, &prorettype, &returnsSet); compute_full_attributes(stmt->withClause, &byte_pct, &perbyte_cpu, &percall_cpu, &outin_ratio, &canCache, &isStrict); - interpret_AS_clause(languageOid, languageName, stmt->as, &prosrc_str, &probin_str); + interpret_AS_clause(languageOid, languageName, stmt->as, + &prosrc_str, &probin_str); /* * And now that we have all the parameters, and know we're permitted * to do so, go ahead and create the function. */ - ProcedureCreate(stmt->funcname, + ProcedureCreate(funcname, + namespaceId, stmt->replace, returnsSet, prorettype, @@ -292,27 +340,28 @@ CreateFunction(ProcedureStmt *stmt) -/* -------------------------------- +/* * DefineOperator - * * this function extracts all the information from the * parameter list generated by the parser and then has * OperatorCreate() do all the actual work. * * 'parameters' is a list of DefElem - * -------------------------------- */ void -DefineOperator(char *oprName, - List *parameters) +DefineOperator(List *names, List *parameters) { + char *oprName; + Oid oprNamespace; uint16 precedence = 0; /* operator precedence */ bool canHash = false; /* operator hashes */ bool isLeftAssociative = true; /* operator is left * associative */ char *functionName = NULL; /* function for operator */ - char *typeName1 = NULL; /* first type name */ - char *typeName2 = NULL; /* second type name */ + TypeName *typeName1 = NULL; /* first type name */ + TypeName *typeName2 = NULL; /* second type name */ + Oid typeId1 = InvalidOid; /* types converted to OID */ + Oid typeId2 = InvalidOid; char *commutatorName = NULL; /* optional commutator operator * name */ char *negatorName = NULL; /* optional negator operator name */ @@ -323,6 +372,9 @@ DefineOperator(char *oprName, char *sortName2 = NULL; /* optional second sort operator */ List *pl; + /* Convert list of names to a name and namespace */ + oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName); + /* * loop over the definition list and extract the information we need. */ @@ -332,16 +384,14 @@ DefineOperator(char *oprName, if (strcasecmp(defel->defname, "leftarg") == 0) { - typeName1 = defGetString(defel); - if (IsA(defel->arg, TypeName) && - ((TypeName *) defel->arg)->setof) + typeName1 = defGetTypeName(defel); + if (typeName1->setof) elog(ERROR, "setof type not implemented for leftarg"); } else if (strcasecmp(defel->defname, "rightarg") == 0) { - typeName2 = defGetString(defel); - if (IsA(defel->arg, TypeName) && - ((TypeName *) defel->arg)->setof) + typeName2 = defGetTypeName(defel); + if (typeName2->setof) elog(ERROR, "setof type not implemented for rightarg"); } else if (strcasecmp(defel->defname, "procedure") == 0) @@ -367,15 +417,7 @@ DefineOperator(char *oprName, else if (strcasecmp(defel->defname, "hashes") == 0) canHash = TRUE; else if (strcasecmp(defel->defname, "sort1") == 0) - { - /* ---------------- - * XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... ) - * XXX is undocumented in the reference manual source as of - * 89/8/22. - * ---------------- - */ sortName1 = defGetString(defel); - } else if (strcasecmp(defel->defname, "sort2") == 0) sortName2 = defGetString(defel); else @@ -391,12 +433,18 @@ DefineOperator(char *oprName, if (functionName == NULL) elog(ERROR, "Define: \"procedure\" unspecified"); + /* Transform type names to type OIDs */ + if (typeName1) + typeId1 = typenameTypeId(typeName1); + if (typeName2) + typeId2 = typenameTypeId(typeName2); + /* * now have OperatorCreate do all the work.. */ OperatorCreate(oprName, /* operator name */ - typeName1, /* first type name */ - typeName2, /* second type name */ + typeId1, /* left type id */ + typeId2, /* right type id */ functionName, /* function for operator */ precedence, /* operator precedence */ isLeftAssociative, /* operator is left associative */ @@ -412,20 +460,26 @@ DefineOperator(char *oprName, } -/* ------------------- +/* * DefineAggregate - * ------------------ */ void -DefineAggregate(char *aggName, List *parameters) +DefineAggregate(List *names, List *parameters) { + char *aggName; + Oid aggNamespace; char *transfuncName = NULL; char *finalfuncName = NULL; - char *baseType = NULL; - char *transType = NULL; + TypeName *baseType = NULL; + TypeName *transType = NULL; char *initval = NULL; + Oid baseTypeId; + Oid transTypeId; List *pl; + /* Convert list of names to a name and namespace */ + aggNamespace = QualifiedNameGetCreationNamespace(names, &aggName); + foreach(pl, parameters) { DefElem *defel = (DefElem *) lfirst(pl); @@ -441,11 +495,11 @@ DefineAggregate(char *aggName, List *parameters) else if (strcasecmp(defel->defname, "finalfunc") == 0) finalfuncName = defGetString(defel); else if (strcasecmp(defel->defname, "basetype") == 0) - baseType = defGetString(defel); + baseType = defGetTypeName(defel); else if (strcasecmp(defel->defname, "stype") == 0) - transType = defGetString(defel); + transType = defGetTypeName(defel); else if (strcasecmp(defel->defname, "stype1") == 0) - transType = defGetString(defel); + transType = defGetTypeName(defel); else if (strcasecmp(defel->defname, "initcond") == 0) initval = defGetString(defel); else if (strcasecmp(defel->defname, "initcond1") == 0) @@ -466,13 +520,39 @@ DefineAggregate(char *aggName, List *parameters) elog(ERROR, "Define: \"sfunc\" unspecified"); /* + * Handle the aggregate's base type (input data type). This can be + * specified as 'ANY' for a data-independent transition function, such + * as COUNT(*). + */ + baseTypeId = LookupTypeName(baseType); + if (OidIsValid(baseTypeId)) + { + /* no need to allow aggregates on as-yet-undefined types */ + if (!get_typisdefined(baseTypeId)) + elog(ERROR, "Type \"%s\" is only a shell", + TypeNameToString(baseType)); + } + else + { + char *typnam = TypeNameToString(baseType); + + if (strcasecmp(typnam, "ANY") != 0) + elog(ERROR, "Type \"%s\" does not exist", typnam); + baseTypeId = InvalidOid; + } + + /* handle transtype --- no special cases here */ + transTypeId = typenameTypeId(transType); + + /* * Most of the argument-checking is done inside of AggregateCreate */ AggregateCreate(aggName, /* aggregate name */ + aggNamespace, /* namespace */ transfuncName, /* step function name */ finalfuncName, /* final function name */ - baseType, /* type of data being aggregated */ - transType, /* transition data type */ + baseTypeId, /* type of data being aggregated */ + transTypeId, /* transition data type */ initval); /* initial condition */ } @@ -483,12 +563,14 @@ DefineAggregate(char *aggName, List *parameters) void DefineDomain(CreateDomainStmt *stmt) { + char *domainName; + Oid domainNamespace; int16 internalLength; int16 externalLength; - char *inputName; - char *outputName; - char *sendName; - char *receiveName; + Oid inputProcedure; + Oid outputProcedure; + Oid receiveProcedure; + Oid sendProcedure; bool byValue; char delimiter; char alignment; @@ -500,46 +582,27 @@ DefineDomain(CreateDomainStmt *stmt) char *defaultValueBin = NULL; bool typNotNull = false; Oid basetypelem; - char *elemName = NULL; - int32 typNDims = 0; /* No array dimensions by default */ + int32 typNDims = length(stmt->typename->arrayBounds); HeapTuple typeTup; - char *typeName = stmt->typename->name; List *schema = stmt->constraints; List *listptr; + /* Convert list of names to a name and namespace */ + domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname, + &domainName); + /* * Domainnames, unlike typenames don't need to account for the '_' * prefix. So they can be one character longer. */ - if (strlen(stmt->domainname) > (NAMEDATALEN - 1)) + if (strlen(domainName) > (NAMEDATALEN - 1)) elog(ERROR, "CREATE DOMAIN: domain names must be %d characters or less", NAMEDATALEN - 1); - /* Test for existing Domain (or type) of that name */ - typeTup = SearchSysCache(TYPENAME, - PointerGetDatum(stmt->domainname), - 0, 0, 0); - if (HeapTupleIsValid(typeTup)) - elog(ERROR, "CREATE DOMAIN: domain or type %s already exists", - stmt->domainname); - /* - * When the type is an array for some reason we don't actually receive - * the name here. We receive the base types name. Lets set Dims while - * were at it. + * Look up the base type. */ - if (stmt->typename->arrayBounds > 0) { - typeName = makeArrayTypeName(stmt->typename->name); - - typNDims = length(stmt->typename->arrayBounds); - } - - typeTup = SearchSysCache(TYPENAME, - PointerGetDatum(typeName), - 0, 0, 0); - if (!HeapTupleIsValid(typeTup)) - elog(ERROR, "CREATE DOMAIN: type %s does not exist", - stmt->typename->name); + typeTup = typenameType(stmt->typename); /* * What we really don't want is domains of domains. This could cause all sorts @@ -550,7 +613,7 @@ DefineDomain(CreateDomainStmt *stmt) typtype = ((Form_pg_type) GETSTRUCT(typeTup))->typtype; if (typtype != 'b') elog(ERROR, "DefineDomain: %s is not a basetype", - stmt->typename->name); + TypeNameToString(stmt->typename)); /* passed by value */ byValue = ((Form_pg_type) GETSTRUCT(typeTup))->typbyval; @@ -570,43 +633,20 @@ DefineDomain(CreateDomainStmt *stmt) /* Array element Delimiter */ delimiter = ((Form_pg_type) GETSTRUCT(typeTup))->typdelim; - /* - * XXX this is pretty bogus: should be passing function OIDs to - * TypeCreate, not names which aren't unique. - */ - - /* Input Function Name */ - datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typinput, &isnull); - Assert(!isnull); - - inputName = DatumGetCString(DirectFunctionCall1(regprocout, datum)); - - /* Output Function Name */ - datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typoutput, &isnull); - Assert(!isnull); - - outputName = DatumGetCString(DirectFunctionCall1(regprocout, datum)); - - /* ReceiveName */ - datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typreceive, &isnull); - Assert(!isnull); - - receiveName = DatumGetCString(DirectFunctionCall1(regprocout, datum)); - - /* SendName */ - datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typsend, &isnull); - Assert(!isnull); - - sendName = DatumGetCString(DirectFunctionCall1(regprocout, datum)); + /* I/O Functions */ + inputProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typinput; + outputProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typoutput; + receiveProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typreceive; + sendProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typsend; /* Inherited default value */ - datum = SysCacheGetAttr(TYPENAME, typeTup, + datum = SysCacheGetAttr(TYPEOID, typeTup, Anum_pg_type_typdefault, &isnull); if (!isnull) defaultValue = DatumGetCString(DirectFunctionCall1(textout, datum)); /* Inherited default binary value */ - datum = SysCacheGetAttr(TYPENAME, typeTup, + datum = SysCacheGetAttr(TYPEOID, typeTup, Anum_pg_type_typdefaultbin, &isnull); if (!isnull) defaultValueBin = DatumGetCString(DirectFunctionCall1(textout, datum)); @@ -617,16 +657,6 @@ DefineDomain(CreateDomainStmt *stmt) * This is what enables us to make a domain of an array */ basetypelem = ((Form_pg_type) GETSTRUCT(typeTup))->typelem; - if (basetypelem != InvalidOid) - { - HeapTuple tup; - - tup = SearchSysCache(TYPEOID, - ObjectIdGetDatum(basetypelem), - 0, 0, 0); - elemName = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(tup))->typname)); - ReleaseSysCache(tup); - } /* * Run through constraints manually to avoid the additional @@ -661,14 +691,14 @@ DefineDomain(CreateDomainStmt *stmt) expr = cookDefault(pstate, colDef->raw_expr, typeTup->t_data->t_oid, stmt->typename->typmod, - stmt->typename->name); + domainName); /* * Expression must be stored as a nodeToString result, * but we also require a valid textual representation * (mainly to make life easier for pg_dump). */ defaultValue = deparse_expression(expr, - deparse_context_for(stmt->domainname, + deparse_context_for(domainName, InvalidOid), false); defaultValueBin = nodeToString(expr); @@ -723,19 +753,20 @@ DefineDomain(CreateDomainStmt *stmt) /* * Have TypeCreate do all the real work. */ - TypeCreate(stmt->domainname, /* type name */ + TypeCreate(domainName, /* type name */ + domainNamespace, /* namespace */ InvalidOid, /* preassigned type oid (not done here) */ InvalidOid, /* relation oid (n/a here) */ internalLength, /* internal size */ externalLength, /* external size */ 'd', /* type-type (domain type) */ delimiter, /* array element delimiter */ - inputName, /* input procedure */ - outputName, /* output procedure */ - receiveName, /* receive procedure */ - sendName, /* send procedure */ - elemName, /* element type name */ - typeName, /* base type name */ + inputProcedure, /* input procedure */ + outputProcedure, /* output procedure */ + receiveProcedure, /* receive procedure */ + sendProcedure, /* send procedure */ + basetypelem, /* element type ID */ + typeTup->t_data->t_oid, /* base type ID */ defaultValue, /* default type value (text) */ defaultValueBin, /* default type value (binary) */ byValue, /* passed by value */ @@ -743,7 +774,7 @@ DefineDomain(CreateDomainStmt *stmt) storage, /* TOAST strategy */ stmt->typename->typmod, /* typeMod value */ typNDims, /* Array dimensions for base type */ - typNotNull); /* Type NOT NULL */ + typNotNull); /* Type NOT NULL */ /* * Now we can clean up. @@ -756,11 +787,13 @@ DefineDomain(CreateDomainStmt *stmt) * Registers a new type. */ void -DefineType(char *typeName, List *parameters) +DefineType(List *names, List *parameters) { + char *typeName; + Oid typeNamespace; int16 internalLength = -1; /* int2 */ int16 externalLength = -1; /* int2 */ - char *elemName = NULL; + Oid elemType = InvalidOid; char *inputName = NULL; char *outputName = NULL; char *sendName = NULL; @@ -768,10 +801,18 @@ DefineType(char *typeName, List *parameters) char *defaultValue = NULL; bool byValue = false; char delimiter = DEFAULT_TYPDELIM; - char *shadow_type; - List *pl; char alignment = 'i'; /* default alignment */ char storage = 'p'; /* default TOAST storage method */ + Oid inputOid; + Oid outputOid; + Oid sendOid; + Oid receiveOid; + char *shadow_type; + List *pl; + Oid typoid; + + /* Convert list of names to a name and namespace */ + typeNamespace = QualifiedNameGetCreationNamespace(names, &typeName); /* * Type names must be one character shorter than other names, allowing @@ -796,16 +837,16 @@ DefineType(char *typeName, List *parameters) outputName = defGetString(defel); else if (strcasecmp(defel->defname, "send") == 0) sendName = defGetString(defel); + else if (strcasecmp(defel->defname, "receive") == 0) + receiveName = defGetString(defel); else if (strcasecmp(defel->defname, "delimiter") == 0) { char *p = defGetString(defel); delimiter = p[0]; } - else if (strcasecmp(defel->defname, "receive") == 0) - receiveName = defGetString(defel); else if (strcasecmp(defel->defname, "element") == 0) - elemName = defGetString(defel); + elemType = typenameTypeId(defGetTypeName(defel)); else if (strcasecmp(defel->defname, "default") == 0) defaultValue = defGetString(defel); else if (strcasecmp(defel->defname, "passedbyvalue") == 0) @@ -867,30 +908,44 @@ DefineType(char *typeName, List *parameters) if (outputName == NULL) elog(ERROR, "Define: \"output\" unspecified"); + /* Convert I/O proc names to OIDs */ + inputOid = findTypeIOFunction(inputName, false); + outputOid = findTypeIOFunction(outputName, true); + if (sendName) + sendOid = findTypeIOFunction(sendName, true); + else + sendOid = outputOid; + if (receiveName) + receiveOid = findTypeIOFunction(receiveName, false); + else + receiveOid = inputOid; + /* * now have TypeCreate do all the real work. */ - TypeCreate(typeName, /* type name */ - InvalidOid, /* preassigned type oid (not done here) */ - InvalidOid, /* relation oid (n/a here) */ - internalLength, /* internal size */ - externalLength, /* external size */ - 'b', /* type-type (base type) */ - delimiter, /* array element delimiter */ - inputName, /* input procedure */ - outputName, /* output procedure */ - receiveName, /* receive procedure */ - sendName, /* send procedure */ - elemName, /* element type name */ - NULL, /* base type name (only for domains) */ - defaultValue, /* default type value */ - NULL, /* no binary form available */ - byValue, /* passed by value */ - alignment, /* required alignment */ - storage, /* TOAST strategy */ - -1, /* typMod (Domains only) */ - 0, /* Array Dimensions of typbasetype */ - 'f'); /* Type NOT NULL */ + typoid = + TypeCreate(typeName, /* type name */ + typeNamespace, /* namespace */ + InvalidOid, /* preassigned type oid (not done here) */ + InvalidOid, /* relation oid (n/a here) */ + internalLength, /* internal size */ + externalLength, /* external size */ + 'b', /* type-type (base type) */ + delimiter, /* array element delimiter */ + inputOid, /* input procedure */ + outputOid, /* output procedure */ + receiveOid, /* receive procedure */ + sendOid, /* send procedure */ + elemType, /* element type ID */ + InvalidOid, /* base type ID (only for domains) */ + defaultValue, /* default type value */ + NULL, /* no binary form available */ + byValue, /* passed by value */ + alignment, /* required alignment */ + storage, /* TOAST strategy */ + -1, /* typMod (Domains only) */ + 0, /* Array Dimensions of typbasetype */ + false); /* Type NOT NULL */ /* * When we create a base type (as opposed to a complex type) we need @@ -902,18 +957,19 @@ DefineType(char *typeName, List *parameters) alignment = (alignment == 'd') ? 'd' : 'i'; TypeCreate(shadow_type, /* type name */ + typeNamespace, /* namespace */ InvalidOid, /* preassigned type oid (not done here) */ InvalidOid, /* relation oid (n/a here) */ -1, /* internal size */ -1, /* external size */ 'b', /* type-type (base type) */ DEFAULT_TYPDELIM, /* array element delimiter */ - "array_in", /* input procedure */ - "array_out", /* output procedure */ - "array_in", /* receive procedure */ - "array_out", /* send procedure */ - typeName, /* element type name */ - NULL, /* base type name */ + F_ARRAY_IN, /* input procedure */ + F_ARRAY_OUT, /* output procedure */ + F_ARRAY_IN, /* receive procedure */ + F_ARRAY_OUT, /* send procedure */ + typoid, /* element type ID */ + InvalidOid, /* base type ID */ NULL, /* never a default type value */ NULL, /* binary default isn't sent either */ false, /* never passed by value */ @@ -921,11 +977,65 @@ DefineType(char *typeName, List *parameters) 'x', /* ARRAY is always toastable */ -1, /* typMod (Domains only) */ 0, /* Array dimensions of typbasetype */ - 'f'); /* Type NOT NULL */ + false); /* Type NOT NULL */ pfree(shadow_type); } +static Oid +findTypeIOFunction(const char *procname, bool isOutput) +{ + Oid argList[FUNC_MAX_ARGS]; + int nargs; + Oid procOid; + + /* + * First look for a 1-argument func with all argtypes 0. This is + * valid for all kinds of procedure. + */ + MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); + + procOid = GetSysCacheOid(PROCNAME, + PointerGetDatum(procname), + Int32GetDatum(1), + PointerGetDatum(argList), + 0); + + if (!OidIsValid(procOid)) + { + /* + * Alternatively, input procedures may take 3 args (data + * value, element OID, atttypmod); the pg_proc argtype + * signature is 0,OIDOID,INT4OID. Output procedures may + * take 2 args (data value, element OID). + */ + if (isOutput) + { + /* output proc */ + nargs = 2; + argList[1] = OIDOID; + } + else + { + /* input proc */ + nargs = 3; + argList[1] = OIDOID; + argList[2] = INT4OID; + } + procOid = GetSysCacheOid(PROCNAME, + PointerGetDatum(procname), + Int32GetDatum(nargs), + PointerGetDatum(argList), + 0); + + if (!OidIsValid(procOid)) + func_error("TypeCreate", procname, 1, argList, NULL); + } + + return procOid; +} + + static char * defGetString(DefElem *def) { @@ -951,7 +1061,7 @@ defGetString(DefElem *def) case T_String: return strVal(def->arg); case T_TypeName: - return TypeNameToInternalName((TypeName *) def->arg); + return TypeNameToString((TypeName *) def->arg); default: elog(ERROR, "Define: cannot interpret argument of \"%s\"", def->defname); @@ -978,6 +1088,32 @@ defGetNumeric(DefElem *def) return 0; /* keep compiler quiet */ } +static TypeName * +defGetTypeName(DefElem *def) +{ + if (def->arg == NULL) + elog(ERROR, "Define: \"%s\" requires a parameter", + def->defname); + switch (nodeTag(def->arg)) + { + case T_TypeName: + return (TypeName *) def->arg; + case T_String: + { + /* Allow quoted typename for backwards compatibility */ + TypeName *n = makeNode(TypeName); + + n->names = makeList1(def->arg); + n->typmod = -1; + return n; + } + default: + elog(ERROR, "Define: argument of \"%s\" must be a type name", + def->defname); + } + return NULL; /* keep compiler quiet */ +} + static int defGetTypeLength(DefElem *def) { @@ -998,7 +1134,7 @@ defGetTypeLength(DefElem *def) break; case T_TypeName: /* cope if grammar chooses to believe "variable" is a typename */ - if (strcasecmp(TypeNameToInternalName((TypeName *) def->arg), + if (strcasecmp(TypeNameToString((TypeName *) def->arg), "variable") == 0) return -1; /* variable length */ break; diff --git a/src/backend/commands/remove.c b/src/backend/commands/remove.c index 0dbadd95779..fb73fe3bd02 100644 --- a/src/backend/commands/remove.c +++ b/src/backend/commands/remove.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.71 2002/03/21 23:27:21 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.72 2002/03/29 19:06:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -24,8 +24,8 @@ #include "miscadmin.h" #include "parser/parse.h" #include "parser/parse_agg.h" -#include "parser/parse_expr.h" #include "parser/parse_func.h" +#include "parser/parse_type.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/syscache.h" @@ -43,29 +43,20 @@ */ void RemoveOperator(char *operatorName, /* operator name */ - char *typeName1, /* left argument type name */ - char *typeName2) /* right argument type name */ + TypeName *typeName1, /* left argument type name */ + TypeName *typeName2) /* right argument type name */ { Relation relation; HeapTuple tup; Oid typeId1 = InvalidOid; Oid typeId2 = InvalidOid; - bool defined; char oprtype; if (typeName1) - { - typeId1 = TypeGet(typeName1, &defined); - if (!OidIsValid(typeId1)) - elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName1); - } + typeId1 = typenameTypeId(typeName1); if (typeName2) - { - typeId2 = TypeGet(typeName2, &defined); - if (!OidIsValid(typeId2)) - elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName2); - } + typeId2 = typenameTypeId(typeName2); if (OidIsValid(typeId1) && OidIsValid(typeId2)) oprtype = 'b'; @@ -99,20 +90,20 @@ RemoveOperator(char *operatorName, /* operator name */ { elog(ERROR, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist", operatorName, - typeName1, - typeName2); + TypeNameToString(typeName1), + TypeNameToString(typeName2)); } else if (OidIsValid(typeId1)) { elog(ERROR, "RemoveOperator: right unary operator '%s' taking '%s' does not exist", operatorName, - typeName1); + TypeNameToString(typeName1)); } else { elog(ERROR, "RemoveOperator: left unary operator '%s' taking '%s' does not exist", operatorName, - typeName2); + TypeNameToString(typeName2)); } } heap_freetuple(tup); @@ -213,16 +204,13 @@ AttributeAndRelationRemove(Oid typeOid) rel = heap_openr(RelationRelationName, RowExclusiveLock); while (PointerIsValid((char *) optr->next)) { - key[0].sk_argument = (Datum) (optr++)->reloid; + Oid relOid = (optr++)->reloid; + + key[0].sk_argument = ObjectIdGetDatum(relOid); scan = heap_beginscan(rel, 0, SnapshotNow, 1, key); tup = heap_getnext(scan, 0); if (HeapTupleIsValid(tup)) - { - char *name; - - name = NameStr(((Form_pg_class) GETSTRUCT(tup))->relname); - heap_drop_with_catalog(name, allowSystemTableMods); - } + heap_drop_with_catalog(relOid, allowSystemTableMods); heap_endscan(scan); } heap_close(rel, RowExclusiveLock); @@ -231,42 +219,68 @@ AttributeAndRelationRemove(Oid typeOid) /* * TypeRemove - * Removes the type 'typeName' and all attributes and relations that - * use it. + * Removes a datatype. + * + * NOTE: since this tries to remove the associated array type too, it'll + * only work on scalar types. */ void -RemoveType(char *typeName) /* type name to be removed */ +RemoveType(List *names) { + TypeName *typename; Relation relation; + Oid typeoid; HeapTuple tup; - char *shadow_type; + + /* Make a TypeName so we can use standard type lookup machinery */ + typename = makeNode(TypeName); + typename->names = names; + typename->typmod = -1; + typename->arrayBounds = NIL; relation = heap_openr(TypeRelationName, RowExclusiveLock); - tup = SearchSysCache(TYPENAME, - PointerGetDatum(typeName), + /* Use LookupTypeName here so that shell types can be removed. */ + typeoid = LookupTypeName(typename); + if (!OidIsValid(typeoid)) + elog(ERROR, "Type \"%s\" does not exist", + TypeNameToString(typename)); + + tup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(typeoid), 0, 0, 0); if (!HeapTupleIsValid(tup)) - elog(ERROR, "RemoveType: type '%s' does not exist", typeName); + elog(ERROR, "Type \"%s\" does not exist", + TypeNameToString(typename)); - if (!pg_type_ownercheck(tup->t_data->t_oid, GetUserId())) + if (!pg_type_ownercheck(typeoid, GetUserId())) elog(ERROR, "RemoveType: type '%s': permission denied", - typeName); + TypeNameToString(typename)); /* Delete any comments associated with this type */ - DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation)); + DeleteComments(typeoid, RelationGetRelid(relation)); + /* Remove the type tuple from pg_type */ simple_heap_delete(relation, &tup->t_self); ReleaseSysCache(tup); - /* Also, delete the "array of" that type */ - shadow_type = makeArrayTypeName(typeName); - tup = SearchSysCache(TYPENAME, - PointerGetDatum(shadow_type), + /* Now, delete the "array of" that type */ + typename->arrayBounds = makeList1(makeInteger(1)); + + typeoid = LookupTypeName(typename); + if (!OidIsValid(typeoid)) + elog(ERROR, "Type \"%s\" does not exist", + TypeNameToString(typename)); + + tup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(typeoid), 0, 0, 0); if (!HeapTupleIsValid(tup)) - elog(ERROR, "RemoveType: type '%s' does not exist", shadow_type); + elog(ERROR, "Type \"%s\" does not exist", + TypeNameToString(typename)); + + DeleteComments(typeoid, RelationGetRelid(relation)); simple_heap_delete(relation, &tup->t_self); @@ -277,13 +291,14 @@ RemoveType(char *typeName) /* type name to be removed */ /* * RemoveDomain - * Removes the domain 'typeName' and all attributes and relations that - * use it. + * Removes a domain. */ void -RemoveDomain(char *domainName, int behavior) +RemoveDomain(List *names, int behavior) { + TypeName *typename; Relation relation; + Oid typeoid; HeapTuple tup; char typtype; @@ -291,31 +306,44 @@ RemoveDomain(char *domainName, int behavior) if (behavior == CASCADE) elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword"); + /* Make a TypeName so we can use standard type lookup machinery */ + typename = makeNode(TypeName); + typename->names = names; + typename->typmod = -1; + typename->arrayBounds = NIL; + relation = heap_openr(TypeRelationName, RowExclusiveLock); - tup = SearchSysCache(TYPENAME, - PointerGetDatum(domainName), + typeoid = typenameTypeId(typename); + + tup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(typeoid), 0, 0, 0); if (!HeapTupleIsValid(tup)) - elog(ERROR, "RemoveType: type '%s' does not exist", domainName); + elog(ERROR, "RemoveDomain: type '%s' does not exist", + TypeNameToString(typename)); - if (!pg_type_ownercheck(tup->t_data->t_oid, GetUserId())) + if (!pg_type_ownercheck(typeoid, GetUserId())) elog(ERROR, "RemoveDomain: type '%s': permission denied", - domainName); + TypeNameToString(typename)); /* Check that this is actually a domain */ typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype; if (typtype != 'd') - elog(ERROR, "%s is not a domain", domainName); + elog(ERROR, "%s is not a domain", + TypeNameToString(typename)); /* Delete any comments associated with this type */ - DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation)); + DeleteComments(typeoid, RelationGetRelid(relation)); + /* Remove the type tuple from pg_type */ simple_heap_delete(relation, &tup->t_self); ReleaseSysCache(tup); + /* At present, domains don't have associated array types */ + heap_close(relation, RowExclusiveLock); } @@ -345,20 +373,19 @@ RemoveFunction(char *functionName, /* function name to be removed */ for (i = 0; i < nargs; i++) { TypeName *t = (TypeName *) lfirst(argTypes); - char *typnam = TypeNameToInternalName(t); - - argTypes = lnext(argTypes); - if (strcmp(typnam, "opaque") == 0) - argList[i] = InvalidOid; - else + argList[i] = LookupTypeName(t); + if (!OidIsValid(argList[i])) { - argList[i] = GetSysCacheOid(TYPENAME, - PointerGetDatum(typnam), - 0, 0, 0); - if (!OidIsValid(argList[i])) - elog(ERROR, "RemoveFunction: type '%s' not found", typnam); + char *typnam = TypeNameToString(t); + + if (strcmp(typnam, "opaque") == 0) + argList[i] = InvalidOid; + else + elog(ERROR, "Type \"%s\" does not exist", typnam); } + + argTypes = lnext(argTypes); } relation = heap_openr(ProcedureRelationName, RowExclusiveLock); @@ -393,12 +420,11 @@ RemoveFunction(char *functionName, /* function name to be removed */ } void -RemoveAggregate(char *aggName, char *aggType) +RemoveAggregate(char *aggName, TypeName *aggType) { Relation relation; HeapTuple tup; Oid basetypeID; - bool defined; /* * if a basetype is passed in, then attempt to find an aggregate for @@ -410,11 +436,7 @@ RemoveAggregate(char *aggName, char *aggType) */ if (aggType) - { - basetypeID = TypeGet(aggType, &defined); - if (!OidIsValid(basetypeID)) - elog(ERROR, "RemoveAggregate: type '%s' does not exist", aggType); - } + basetypeID = typenameTypeId(aggType); else basetypeID = InvalidOid; diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c index f050aa9f7fc..0f4c83fbebf 100644 --- a/src/backend/commands/rename.c +++ b/src/backend/commands/rename.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.65 2002/03/26 19:15:43 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.66 2002/03/29 19:06:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -69,16 +69,14 @@ static void update_ri_trigger_args(Oid relid, * delete original attribute from attribute catalog */ void -renameatt(char *relname, +renameatt(Oid relid, char *oldattname, char *newattname, - int recurse) + bool recurse) { Relation targetrelation; Relation attrelation; - HeapTuple reltup, - atttup; - Oid relid; + HeapTuple atttup; List *indexoidlist; List *indexoidscan; @@ -86,8 +84,7 @@ renameatt(char *relname, * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. */ - targetrelation = heap_openr(relname, AccessExclusiveLock); - relid = RelationGetRelid(targetrelation); + targetrelation = heap_open(relid, AccessExclusiveLock); /* * permissions checking. this would normally be done in utility.c, @@ -95,12 +92,13 @@ renameatt(char *relname, * * normally, only the owner of a class can change its schema. */ - if (!allowSystemTableMods && IsSystemRelationName(relname)) + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(targetrelation))) elog(ERROR, "renameatt: class \"%s\" is a system catalog", - relname); + RelationGetRelationName(targetrelation)); if (!pg_class_ownercheck(relid, GetUserId())) elog(ERROR, "renameatt: you do not own class \"%s\"", - relname); + RelationGetRelationName(targetrelation)); /* * if the 'recurse' flag is set then we are supposed to rename this @@ -127,25 +125,11 @@ renameatt(char *relname, foreach(child, children) { Oid childrelid = lfirsti(child); - char childname[NAMEDATALEN]; if (childrelid == relid) continue; - reltup = SearchSysCache(RELOID, - ObjectIdGetDatum(childrelid), - 0, 0, 0); - if (!HeapTupleIsValid(reltup)) - { - elog(ERROR, "renameatt: can't find catalog entry for inheriting class with oid %u", - childrelid); - } - /* make copy of cache value, could disappear in call */ - StrNCpy(childname, - NameStr(((Form_pg_class) GETSTRUCT(reltup))->relname), - NAMEDATALEN); - ReleaseSysCache(reltup); /* note we need not recurse again! */ - renameatt(childname, oldattname, newattname, 0); + renameatt(childrelid, oldattname, newattname, false); } } @@ -356,7 +340,7 @@ renamerel(const RangeVar *relation, const char *newrelname) * Also rename the associated type, if any. */ if (relkind != RELKIND_INDEX) - TypeRename(relation->relname, newrelname); + TypeRename(relation->relname, namespaceId, newrelname); /* * If it's a view, must also rename the associated ON SELECT rule. diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index d0b1f7d4d58..54ca1d19a10 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.74 2002/03/22 02:56:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.75 2002/03/29 19:06:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,6 +17,7 @@ #include <ctype.h> #include "access/heapam.h" +#include "catalog/pg_type.h" #include "commands/creatinh.h" #include "commands/sequence.h" #include "miscadmin.h" @@ -85,8 +86,6 @@ DefineSequence(CreateSeqStmt *seq) { FormData_pg_sequence new; CreateStmt *stmt = makeNode(CreateStmt); - ColumnDef *coldef; - TypeName *typnam; Oid seqoid; Relation rel; Buffer buf; @@ -108,9 +107,12 @@ DefineSequence(CreateSeqStmt *seq) stmt->tableElts = NIL; for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++) { + ColumnDef *coldef; + TypeName *typnam; + typnam = makeNode(TypeName); typnam->setof = FALSE; - typnam->arrayBounds = NULL; + typnam->arrayBounds = NIL; typnam->typmod = -1; coldef = makeNode(ColumnDef); coldef->typename = typnam; @@ -122,48 +124,48 @@ DefineSequence(CreateSeqStmt *seq) switch (i) { case SEQ_COL_NAME: - typnam->name = "name"; + typnam->typeid = NAMEOID; coldef->colname = "sequence_name"; namestrcpy(&name, seq->sequence->relname); value[i - 1] = NameGetDatum(&name); break; case SEQ_COL_LASTVAL: - typnam->name = "int8"; + typnam->typeid = INT8OID; coldef->colname = "last_value"; value[i - 1] = Int64GetDatumFast(new.last_value); break; case SEQ_COL_INCBY: - typnam->name = "int8"; + typnam->typeid = INT8OID; coldef->colname = "increment_by"; value[i - 1] = Int64GetDatumFast(new.increment_by); break; case SEQ_COL_MAXVALUE: - typnam->name = "int8"; + typnam->typeid = INT8OID; coldef->colname = "max_value"; value[i - 1] = Int64GetDatumFast(new.max_value); break; case SEQ_COL_MINVALUE: - typnam->name = "int8"; + typnam->typeid = INT8OID; coldef->colname = "min_value"; value[i - 1] = Int64GetDatumFast(new.min_value); break; case SEQ_COL_CACHE: - typnam->name = "int8"; + typnam->typeid = INT8OID; coldef->colname = "cache_value"; value[i - 1] = Int64GetDatumFast(new.cache_value); break; case SEQ_COL_LOG: - typnam->name = "int8"; + typnam->typeid = INT8OID; coldef->colname = "log_cnt"; value[i - 1] = Int64GetDatum((int64) 1); break; case SEQ_COL_CYCLE: - typnam->name = "bool"; + typnam->typeid = BOOLOID; coldef->colname = "is_cycled"; value[i - 1] = BoolGetDatum(new.is_cycled); break; case SEQ_COL_CALLED: - typnam->name = "bool"; + typnam->typeid = BOOLOID; coldef->colname = "is_called"; value[i - 1] = BoolGetDatum(false); break; diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 466bfec202f..1794d2bda73 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.60 2002/03/06 06:09:39 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.61 2002/03/29 19:06:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,11 +21,12 @@ #include "access/xact.h" #include "catalog/pg_shadow.h" +#include "catalog/pg_type.h" #include "commands/variable.h" #include "miscadmin.h" #include "optimizer/cost.h" #include "optimizer/paths.h" -#include "parser/parse_expr.h" +#include "parser/parse_type.h" #include "utils/builtins.h" #include "utils/date.h" #include "utils/guc.h" @@ -390,7 +391,9 @@ parse_timezone(List *args) type = p->typename; if (type != NULL) { - if (strcmp(type->name, "interval") == 0) + Oid typeOid = typenameTypeId(type); + + if (typeOid == INTERVALOID) { Interval *interval; @@ -402,7 +405,7 @@ parse_timezone(List *args) elog(ERROR, "SET TIME ZONE illegal INTERVAL; month not allowed"); CTimeZone = interval->time; } - else if (strcmp(type->name, "float8") == 0) + else if (typeOid == FLOAT8OID) { float8 time; @@ -414,7 +417,7 @@ parse_timezone(List *args) * We do not actually generate an integer constant in gram.y * so this is not used... */ - else if (strcmp(type->name, "int4") == 0) + else if (typeOid == INT4OID) { int32 time; diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 3b4bf7da13f..6b8652db5b7 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: view.c,v 1.60 2002/03/22 02:56:31 tgl Exp $ + * $Id: view.c,v 1.61 2002/03/29 19:06:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -14,6 +14,7 @@ #include "access/xact.h" #include "catalog/heap.h" +#include "catalog/namespace.h" #include "commands/creatinh.h" #include "commands/view.h" #include "miscadmin.h" @@ -24,6 +25,7 @@ #include "rewrite/rewriteManip.h" #include "rewrite/rewriteRemove.h" #include "rewrite/rewriteSupport.h" +#include "utils/syscache.h" /*--------------------------------------------------------------------- @@ -38,10 +40,9 @@ *--------------------------------------------------------------------- */ static Oid -DefineVirtualRelation(char *relname, List *tlist) +DefineVirtualRelation(const RangeVar *relation, List *tlist) { CreateStmt *createStmt = makeNode(CreateStmt); - RangeVar *rel = makeNode(RangeVar); List *attrList, *t; @@ -57,14 +58,12 @@ DefineVirtualRelation(char *relname, List *tlist) if (!res->resjunk) { - char *resname = res->resname; - char *restypename = typeidTypeName(res->restype); ColumnDef *def = makeNode(ColumnDef); TypeName *typename = makeNode(TypeName); - def->colname = pstrdup(resname); + def->colname = pstrdup(res->resname); - typename->name = pstrdup(restypename); + typename->typeid = res->restype; typename->typmod = res->restypmod; def->typename = typename; @@ -84,10 +83,7 @@ DefineVirtualRelation(char *relname, List *tlist) * now create the parameters for keys/inheritance etc. All of them are * nil... */ - rel->relname = relname; - rel->schemaname = NULL; /* XXX wrong */ - rel->istemp = false; - createStmt->relation = rel; + createStmt->relation = (RangeVar *) relation; createStmt->tableElts = attrList; createStmt->inhRelations = NIL; createStmt->constraints = NIL; @@ -100,25 +96,19 @@ DefineVirtualRelation(char *relname, List *tlist) } static RuleStmt * -FormViewRetrieveRule(char *viewName, Query *viewParse) +FormViewRetrieveRule(const RangeVar *view, Query *viewParse) { RuleStmt *rule; char *rname; - RangeVar *rel; /* * Create a RuleStmt that corresponds to the suitable rewrite rule * args for DefineQueryRewrite(); */ - rname = MakeRetrieveViewRuleName(viewName); - - rel = makeNode(RangeVar); - rel->relname = pstrdup(viewName); - rel->inhOpt = INH_NO; - rel->alias = NULL; + rname = MakeRetrieveViewRuleName(view->relname); rule = makeNode(RuleStmt); - rule->relation = rel; + rule->relation = copyObject((RangeVar *) view); rule->rulename = pstrdup(rname); rule->whereClause = NULL; rule->event = CMD_SELECT; @@ -129,7 +119,7 @@ FormViewRetrieveRule(char *viewName, Query *viewParse) } static void -DefineViewRules(char *viewName, Query *viewParse) +DefineViewRules(const RangeVar *view, Query *viewParse) { RuleStmt *retrieve_rule; @@ -139,13 +129,13 @@ DefineViewRules(char *viewName, Query *viewParse) RuleStmt *delete_rule; #endif - retrieve_rule = FormViewRetrieveRule(viewName, viewParse); + retrieve_rule = FormViewRetrieveRule(view, viewParse); #ifdef NOTYET - replace_rule = FormViewReplaceRule(viewName, viewParse); - append_rule = FormViewAppendRule(viewName, viewParse); - delete_rule = FormViewDeleteRule(viewName, viewParse); + replace_rule = FormViewReplaceRule(view, viewParse); + append_rule = FormViewAppendRule(view, viewParse); + delete_rule = FormViewDeleteRule(view, viewParse); #endif DefineQueryRewrite(retrieve_rule); @@ -231,7 +221,7 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse) *------------------------------------------------------------------- */ void -DefineView(char *viewName, Query *viewParse) +DefineView(const RangeVar *view, Query *viewParse) { Oid viewOid; @@ -240,7 +230,7 @@ DefineView(char *viewName, Query *viewParse) * * NOTE: if it already exists, the xact will be aborted. */ - viewOid = DefineVirtualRelation(viewName, viewParse->targetList); + viewOid = DefineVirtualRelation(view, viewParse->targetList); /* * The relation we have just created is not visible to any other @@ -258,7 +248,7 @@ DefineView(char *viewName, Query *viewParse) /* * Now create the rules associated with the view. */ - DefineViewRules(viewName, viewParse); + DefineViewRules(view, viewParse); } /*------------------------------------------------------------------ @@ -268,11 +258,14 @@ DefineView(char *viewName, Query *viewParse) *------------------------------------------------------------------ */ void -RemoveView(char *viewName) +RemoveView(const RangeVar *view) { + Oid viewOid; + + viewOid = RangeVarGetRelid(view, false); /* * We just have to drop the relation; the associated rules will be * cleaned up automatically. */ - heap_drop_with_catalog(viewName, allowSystemTableMods); + heap_drop_with_catalog(viewOid, allowSystemTableMods); } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 2c1e5b675f9..055e3c371e2 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.173 2002/03/22 02:56:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.174 2002/03/29 19:06:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1637,10 +1637,11 @@ _copyTypeName(TypeName *from) { TypeName *newnode = makeNode(TypeName); - if (from->name) - newnode->name = pstrdup(from->name); + Node_Copy(from, newnode, names); + newnode->typeid = from->typeid; newnode->timezone = from->timezone; newnode->setof = from->setof; + newnode->pct_type = from->pct_type; newnode->typmod = from->typmod; Node_Copy(from, newnode, arrayBounds); @@ -2008,7 +2009,7 @@ _copyDefineStmt(DefineStmt *from) DefineStmt *newnode = makeNode(DefineStmt); newnode->defType = from->defType; - newnode->defname = pstrdup(from->defname); + Node_Copy(from, newnode, defnames); Node_Copy(from, newnode, definition); return newnode; @@ -2089,7 +2090,7 @@ _copyProcedureStmt(ProcedureStmt *from) ProcedureStmt *newnode = makeNode(ProcedureStmt); newnode->replace = from->replace; - newnode->funcname = pstrdup(from->funcname); + Node_Copy(from, newnode, funcname); Node_Copy(from, newnode, argTypes); Node_Copy(from, newnode, returnType); Node_Copy(from, newnode, withClause); @@ -2229,8 +2230,7 @@ _copyCreateDomainStmt(CreateDomainStmt *from) { CreateDomainStmt *newnode = makeNode(CreateDomainStmt); - if (from->domainname) - newnode->domainname = pstrdup(from->domainname); + Node_Copy(from, newnode, domainname); Node_Copy(from, newnode, typename); Node_Copy(from, newnode, constraints); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 6adc87c4040..fee607419a5 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.121 2002/03/22 02:56:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.122 2002/03/29 19:06:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -836,7 +836,7 @@ _equalDefineStmt(DefineStmt *a, DefineStmt *b) { if (a->defType != b->defType) return false; - if (!equalstr(a->defname, b->defname)) + if (!equal(a->defnames, b->defnames)) return false; if (!equal(a->definition, b->definition)) return false; @@ -928,7 +928,7 @@ _equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b) { if (a->replace != b->replace) return false; - if (!equalstr(a->funcname, b->funcname)) + if (!equal(a->funcname, b->funcname)) return false; if (!equal(a->argTypes, b->argTypes)) return false; @@ -1071,7 +1071,7 @@ _equalLoadStmt(LoadStmt *a, LoadStmt *b) static bool _equalCreateDomainStmt(CreateDomainStmt *a, CreateDomainStmt *b) { - if (!equalstr(a->domainname, b->domainname)) + if (!equal(a->domainname, b->domainname)) return false; if (!equal(a->typename, b->typename)) return false; @@ -1572,12 +1572,16 @@ _equalRangeSubselect(RangeSubselect *a, RangeSubselect *b) static bool _equalTypeName(TypeName *a, TypeName *b) { - if (!equalstr(a->name, b->name)) + if (!equal(a->names, b->names)) + return false; + if (a->typeid != b->typeid) return false; if (a->timezone != b->timezone) return false; if (a->setof != b->setof) return false; + if (a->pct_type != b->pct_type) + return false; if (a->typmod != b->typmod) return false; if (!equal(a->arrayBounds, b->arrayBounds)) diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 649fb38c111..6d649ba9d1f 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.29 2002/03/22 02:56:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.30 2002/03/29 19:06:09 tgl Exp $ */ #include "postgres.h" @@ -209,3 +209,17 @@ makeRangeVar(char *schemaname, char *relname) return r; } + +/* + * makeTypeName - + * build a TypeName node for an unqualified name. + */ +TypeName * +makeTypeName(char *typnam) +{ + TypeName *n = makeNode(TypeName); + + n->names = makeList1(makeString(typnam)); + n->typmod = -1; + return n; +} diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 195db0165db..20d25c64397 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.151 2002/03/22 02:56:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.152 2002/03/29 19:06:09 tgl Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -187,11 +187,14 @@ _outColumnDef(StringInfo str, ColumnDef *node) static void _outTypeName(StringInfo str, TypeName *node) { - appendStringInfo(str, " TYPENAME :name "); - _outToken(str, node->name); - appendStringInfo(str, " :timezone %s :setof %s typmod %d :arrayBounds ", + appendStringInfo(str, " TYPENAME :names "); + _outNode(str, node->names); + appendStringInfo(str, " :typeid %u :timezone %s :setof %s" + " :pct_type %s typmod %d :arrayBounds ", + node->typeid, booltostr(node->timezone), booltostr(node->setof), + booltostr(node->pct_type), node->typmod); _outNode(str, node->arrayBounds); } diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 270637d451a..d02b0bf58ed 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.223 2002/03/26 19:15:56 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.224 2002/03/29 19:06:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -108,11 +108,7 @@ static void transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt); static void transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt); -static Node *transformTypeRefs(ParseState *pstate, Node *stmt); - static void applyColumnNames(List *dst, List *src); -static void transformTypeRefsList(ParseState *pstate, List *l); -static void transformTypeRef(ParseState *pstate, TypeName *tn); static List *getSetColTypes(ParseState *pstate, Node *node); static void transformForUpdate(Query *qry, List *forUpdate); static void transformConstraintAttrs(List *constraintList); @@ -309,18 +305,6 @@ transformStmt(ParseState *pstate, Node *parseTree, (SelectStmt *) parseTree); break; - /* - * Convert use of %TYPE in statements where it is permitted. - */ - case T_ProcedureStmt: - case T_CommentStmt: - case T_RemoveFuncStmt: - case T_DefineStmt: - result = makeNode(Query); - result->commandType = CMD_UTILITY; - result->utilityStmt = transformTypeRefs(pstate, parseTree); - break; - default: /* @@ -792,17 +776,24 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt, /* Check for SERIAL pseudo-types */ is_serial = false; - if (strcmp(column->typename->name, "serial") == 0 || - strcmp(column->typename->name, "serial4") == 0) - { - is_serial = true; - column->typename->name = pstrdup("int4"); - } - else if (strcmp(column->typename->name, "bigserial") == 0 || - strcmp(column->typename->name, "serial8") == 0) + if (length(column->typename->names) == 1) { - is_serial = true; - column->typename->name = pstrdup("int8"); + char *typname = strVal(lfirst(column->typename->names)); + + if (strcmp(typname, "serial") == 0 || + strcmp(typname, "serial4") == 0) + { + is_serial = true; + column->typename->names = NIL; + column->typename->typeid = INT4OID; + } + else if (strcmp(typname, "bigserial") == 0 || + strcmp(typname, "serial8") == 0) + { + is_serial = true; + column->typename->names = NIL; + column->typename->typeid = INT8OID; + } } /* Do necessary work on the column type declaration */ @@ -2634,110 +2625,6 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, return qry; } -/* - * Transform uses of %TYPE in a statement. - */ -static Node * -transformTypeRefs(ParseState *pstate, Node *stmt) -{ - switch (nodeTag(stmt)) - { - case T_ProcedureStmt: - { - ProcedureStmt *ps = (ProcedureStmt *) stmt; - - transformTypeRefsList(pstate, ps->argTypes); - transformTypeRef(pstate, (TypeName *) ps->returnType); - transformTypeRefsList(pstate, ps->withClause); - } - break; - - case T_CommentStmt: - { - CommentStmt *cs = (CommentStmt *) stmt; - - transformTypeRefsList(pstate, cs->objlist); - } - break; - - case T_RemoveFuncStmt: - { - RemoveFuncStmt *rs = (RemoveFuncStmt *) stmt; - - transformTypeRefsList(pstate, rs->args); - } - break; - - case T_DefineStmt: - { - DefineStmt *ds = (DefineStmt *) stmt; - List *ele; - - foreach(ele, ds->definition) - { - DefElem *de = (DefElem *) lfirst(ele); - - if (de->arg != NULL - && IsA(de->arg, TypeName)) - transformTypeRef(pstate, (TypeName *) de->arg); - } - } - break; - - default: - elog(ERROR, "Unsupported type %d in transformTypeRefs", - nodeTag(stmt)); - break; - } - - return stmt; -} - -/* - * Transform uses of %TYPE in a list. - */ -static void -transformTypeRefsList(ParseState *pstate, List *l) -{ - List *ele; - - foreach(ele, l) - { - Node *elem = lfirst(ele); - - if (elem && IsA(elem, TypeName)) - transformTypeRef(pstate, (TypeName *) elem); - } -} - -/* - * Transform a TypeName to not use %TYPE. - */ -static void -transformTypeRef(ParseState *pstate, TypeName *tn) -{ - ColumnRef *cref; - Node *n; - Var *v; - char *tyn; - - if (tn->attrname == NULL) - return; - /* XXX this needs work; can't type name be qualified? */ - cref = makeNode(ColumnRef); - cref->fields = makeList2(makeString(tn->name), makeString(tn->attrname)); - cref->indirection = NIL; - n = transformExpr(pstate, (Node *) cref); - if (!IsA(n, Var)) - elog(ERROR, "unsupported expression in %%TYPE"); - v = (Var *) n; - tyn = typeidTypeName(v->vartype); - elog(NOTICE, "%s.%s%%TYPE converted to %s", tn->name, tn->attrname, tyn); - tn->name = tyn; - tn->typmod = v->vartypmod; - tn->attrname = NULL; -} - /* exported so planner can check again after rewriting, query pullup, etc */ void CheckSelectForUpdate(Query *qry) @@ -3059,15 +2946,7 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname) ColumnDef *col = lfirst(cols); if (strcmp(col->colname, colname) == 0) - { - char *buff = TypeNameToInternalName(col->typename); - - result = typenameTypeId(buff); - if (!OidIsValid(result)) - elog(ERROR, "Unable to lookup type %s", - col->typename->name); - return result; - } + return typenameTypeId(col->typename); } /* Perhaps it's a system column name */ sysatt = SystemAttributeByName(colname, cxt->hasoids); @@ -3092,7 +2971,6 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname) if (strcmp(name, colname) == 0) { result = rel->rd_att->attrs[count]->atttypid; - heap_close(rel, NoLock); return result; } @@ -3111,7 +2989,6 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname) if (HeapTupleIsValid(atttuple)) { result = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid; - ReleaseSysCache(atttuple); return result; } @@ -3233,7 +3110,7 @@ static void transformColumnType(ParseState *pstate, ColumnDef *column) { TypeName *typename = column->typename; - Type ctype = typenameType(typename->name); + Type ctype = typenameType(typename); /* * Is this the name of a complex type? If so, implement it as a set. diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index fa6bf35fb97..4ebddde891b 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.296 2002/03/22 02:56:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.297 2002/03/29 19:06:10 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -53,6 +53,7 @@ #include "access/htup.h" #include "catalog/index.h" #include "catalog/pg_type.h" +#include "nodes/makefuncs.h" #include "nodes/params.h" #include "nodes/parsenodes.h" #include "parser/gramparse.h" @@ -122,8 +123,6 @@ static void doNegateFloat(Value *v); ResTarget *target; PrivTarget *privtarget; - DefineStmt *dstmt; - RuleStmt *rstmt; InsertStmt *istmt; } @@ -175,7 +174,8 @@ static void doNegateFloat(Value *v); %type <str> relation_name, copy_file_name, copy_delimiter, copy_null, database_name, access_method_clause, access_method, attr_name, - class, index_name, name, func_name, file_name + class, index_name, name, function_name, file_name, + func_name, handler_name %type <range> qualified_name, OptConstrFromTable @@ -200,8 +200,8 @@ static void doNegateFloat(Value *v); opt_column_list, columnList, opt_name_list, sort_clause, sortby_list, index_params, index_list, name_list, from_clause, from_list, opt_array_bounds, qualified_name_list, - expr_list, attrs, opt_attrs, target_list, update_target_list, - insert_column_list, + any_name, any_name_list, expr_list, dotted_name, attrs, + target_list, update_target_list, insert_column_list, def_list, opt_indirection, group_clause, TriggerFuncArgs, select_limit, opt_select_limit @@ -411,10 +411,10 @@ static void doNegateFloat(Value *v); /* Unary Operators */ %left AT ZONE /* sets precedence for AT TIME ZONE */ %right UMINUS -%left '.' %left '[' ']' %left '(' ')' %left TYPECAST +%left '.' %% /* @@ -1812,7 +1812,7 @@ IntegerOnly: Iconst *****************************************************************************/ CreatePLangStmt: CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst - HANDLER func_name opt_lancompiler + HANDLER handler_name opt_lancompiler { CreatePLangStmt *n = makeNode(CreatePLangStmt); n->plname = $5; @@ -1827,6 +1827,16 @@ opt_trusted: TRUSTED { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; +/* This ought to be just func_name, but that causes reduce/reduce conflicts + * (CREATE LANGUAGE is the only place where func_name isn't followed by '('). + * Work around by using name and dotted_name separately. + */ +handler_name: name + { $$ = $1; } + | dotted_name + { $$ = strVal(lfirst($1)); /* XXX changing soon */ } + ; + opt_lancompiler: LANCOMPILER Sconst { $$ = $2; } | /*EMPTY*/ { $$ = ""; } ; @@ -1853,7 +1863,7 @@ opt_procedural: PROCEDURAL { $$ = TRUE; } CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON qualified_name TriggerForSpec EXECUTE PROCEDURE - name '(' TriggerFuncArgs ')' + func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); n->trigname = $3; @@ -1877,7 +1887,8 @@ CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON qualified_name OptConstrFromTable ConstraintAttributeSpec - FOR EACH ROW EXECUTE PROCEDURE name '(' TriggerFuncArgs ')' + FOR EACH ROW EXECUTE PROCEDURE + func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); n->trigname = $4; @@ -2043,7 +2054,7 @@ DefineStmt: CREATE AGGREGATE func_name definition { DefineStmt *n = makeNode(DefineStmt); n->defType = AGGREGATE; - n->defname = $3; + n->defnames = makeList1(makeString($3)); /* XXX */ n->definition = $4; $$ = (Node *)n; } @@ -2051,15 +2062,15 @@ DefineStmt: CREATE AGGREGATE func_name definition { DefineStmt *n = makeNode(DefineStmt); n->defType = OPERATOR; - n->defname = $3; + n->defnames = makeList1(makeString($3)); /* XXX */ n->definition = $4; $$ = (Node *)n; } - | CREATE TYPE_P name definition + | CREATE TYPE_P any_name definition { DefineStmt *n = makeNode(DefineStmt); n->defType = TYPE_P; - n->defname = $3; + n->defnames = $3; n->definition = $4; $$ = (Node *)n; } @@ -2102,10 +2113,7 @@ def_arg: func_return { $$ = (Node *)$1; } * *****************************************************************************/ -/* DropStmt needs to use qualified_name_list as many of the objects - * are relations or other schema objects (names can be schema-qualified) */ - -DropStmt: DROP drop_type qualified_name_list opt_drop_behavior +DropStmt: DROP drop_type any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = $2; @@ -2124,6 +2132,18 @@ drop_type: TABLE { $$ = DROP_TABLE; } | DOMAIN_P { $$ = DROP_DOMAIN; } ; +any_name_list: any_name + { $$ = makeList1($1); } + | any_name_list ',' any_name + { $$ = lappend($1, $3); } + ; + +any_name: ColId + { $$ = makeList1(makeString($1)); } + | dotted_name + { $$ = $1; } + ; + /***************************************************************************** * * QUERY: @@ -2192,7 +2212,7 @@ CommentStmt: COMMENT ON comment_type name IS comment_text n->comment = $10; $$ = (Node *) n; } - | COMMENT ON AGGREGATE name '(' aggr_argtype ')' IS comment_text + | COMMENT ON AGGREGATE func_name '(' aggr_argtype ')' IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = AGGREGATE; @@ -2203,18 +2223,6 @@ CommentStmt: COMMENT ON comment_type name IS comment_text n->comment = $9; $$ = (Node *) n; } - | COMMENT ON AGGREGATE name aggr_argtype IS comment_text - { - /* Obsolete syntax, but must support for awhile */ - CommentStmt *n = makeNode(CommentStmt); - n->objtype = AGGREGATE; - n->objschema = NULL; - n->objname = $4; - n->objproperty = NULL; - n->objlist = makeList1($5); - n->comment = $7; - $$ = (Node *) n; - } | COMMENT ON FUNCTION func_name func_args IS comment_text { CommentStmt *n = makeNode(CommentStmt); @@ -2691,9 +2699,9 @@ ProcedureStmt: CREATE opt_or_replace FUNCTION func_name func_args { ProcedureStmt *n = makeNode(ProcedureStmt); n->replace = $2; - n->funcname = $4; + n->funcname = makeList1(makeString($4)); /* XXX */ n->argTypes = $5; - n->returnType = (Node *) $7; + n->returnType = $7; n->withClause = $12; n->as = $9; n->language = $11; @@ -2765,19 +2773,19 @@ func_return: func_type ; /* - * We would like to make the second production here be ColId '.' ColId etc, + * We would like to make the second production here be ColId attrs etc, * but that causes reduce/reduce conflicts. type_name is next best choice. */ func_type: Typename { $$ = $1; } - | type_name '.' ColId '%' TYPE_P + | type_name attrs '%' TYPE_P { $$ = makeNode(TypeName); - $$->name = $1; + $$->names = lcons(makeString($1), $2); + $$->pct_type = true; $$->typmod = -1; - $$->attrname = $3; } ; @@ -2804,15 +2812,7 @@ RemoveAggrStmt: DROP AGGREGATE func_name '(' aggr_argtype ')' { RemoveAggrStmt *n = makeNode(RemoveAggrStmt); n->aggname = $3; - n->aggtype = (Node *) $5; - $$ = (Node *)n; - } - | DROP AGGREGATE func_name aggr_argtype - { - /* Obsolete syntax, but must support for awhile */ - RemoveAggrStmt *n = makeNode(RemoveAggrStmt); - n->aggname = $3; - n->aggtype = (Node *) $4; + n->aggtype = $5; $$ = (Node *)n; } ; @@ -3293,7 +3293,7 @@ DropdbStmt: DROP DATABASE database_name * *****************************************************************************/ -CreateDomainStmt: CREATE DOMAIN_P name opt_as Typename ColQualList opt_collate +CreateDomainStmt: CREATE DOMAIN_P any_name opt_as Typename ColQualList opt_collate { CreateDomainStmt *n = makeNode(CreateDomainStmt); n->domainname = $3; @@ -4237,6 +4237,14 @@ opt_array_bounds: opt_array_bounds '[' ']' { $$ = NIL; } ; +/* + * XXX ideally, the production for a qualified typename should be ColId attrs + * (there's no obvious reason why the first name should need to be restricted) + * and should be an alternative of GenericType (so that it can be used to + * specify a type for a literal in AExprConst). However doing either causes + * reduce/reduce conflicts that I haven't been able to find a workaround + * for. FIXME later. + */ SimpleTypename: ConstTypename | ConstInterval opt_interval { @@ -4249,6 +4257,12 @@ SimpleTypename: ConstTypename $$ = $1; $$->typmod = ((($5 & 0x7FFF) << 16) | $3); } + | type_name attrs + { + $$ = makeNode(TypeName); + $$->names = lcons(makeString($1), $2); + $$->typmod = -1; + } ; ConstTypename: GenericType @@ -4260,9 +4274,7 @@ ConstTypename: GenericType GenericType: type_name { - $$ = makeNode(TypeName); - $$->name = xlateSqlType($1); - $$->typmod = -1; + $$ = makeTypeName(xlateSqlType($1)); } ; @@ -4273,32 +4285,25 @@ GenericType: type_name */ Numeric: FLOAT opt_float { - $$ = makeNode(TypeName); - $$->name = $2; /* already xlated */ - $$->typmod = -1; + $$ = makeTypeName($2); /* already xlated */ } | DOUBLE PRECISION { - $$ = makeNode(TypeName); - $$->name = xlateSqlType("float8"); - $$->typmod = -1; + $$ = makeTypeName(xlateSqlType("float8")); } | DECIMAL opt_decimal { - $$ = makeNode(TypeName); - $$->name = xlateSqlType("decimal"); + $$ = makeTypeName(xlateSqlType("decimal")); $$->typmod = $2; } | DEC opt_decimal { - $$ = makeNode(TypeName); - $$->name = xlateSqlType("decimal"); + $$ = makeTypeName(xlateSqlType("decimal")); $$->typmod = $2; } | NUMERIC opt_numeric { - $$ = makeNode(TypeName); - $$->name = xlateSqlType("numeric"); + $$ = makeTypeName(xlateSqlType("numeric")); $$->typmod = $2; } ; @@ -4379,8 +4384,7 @@ opt_decimal: '(' Iconst ',' Iconst ')' */ Bit: bit '(' Iconst ')' { - $$ = makeNode(TypeName); - $$->name = $1; + $$ = makeTypeName($1); if ($3 < 1) elog(ERROR,"length for type '%s' must be at least 1", $1); @@ -4391,8 +4395,7 @@ Bit: bit '(' Iconst ')' } | bit { - $$ = makeNode(TypeName); - $$->name = $1; + $$ = makeTypeName($1); /* bit defaults to bit(1), varbit to no limit */ if (strcmp($1, "bit") == 0) $$->typmod = 1; @@ -4418,8 +4421,19 @@ bit: BIT opt_varying */ Character: character '(' Iconst ')' opt_charset { - $$ = makeNode(TypeName); - $$->name = $1; + if (($5 != NULL) && (strcmp($5, "sql_text") != 0)) + { + char *type; + + type = palloc(strlen($1) + 1 + strlen($5) + 1); + strcpy(type, $1); + strcat(type, "_"); + strcat(type, $5); + $1 = xlateSqlType(type); + } + + $$ = makeTypeName($1); + if ($3 < 1) elog(ERROR,"length for type '%s' must be at least 1", $1); @@ -4433,36 +4447,27 @@ Character: character '(' Iconst ')' opt_charset * truncate where necessary) */ $$->typmod = VARHDRSZ + $3; - - if (($5 != NULL) && (strcmp($5, "sql_text") != 0)) { - char *type; - - type = palloc(strlen($$->name) + 1 + strlen($5) + 1); - strcpy(type, $$->name); - strcat(type, "_"); - strcat(type, $5); - $$->name = xlateSqlType(type); - }; } | character opt_charset { - $$ = makeNode(TypeName); - $$->name = $1; + if (($2 != NULL) && (strcmp($2, "sql_text") != 0)) + { + char *type; + + type = palloc(strlen($1) + 1 + strlen($2) + 1); + strcpy(type, $1); + strcat(type, "_"); + strcat(type, $2); + $1 = xlateSqlType(type); + } + + $$ = makeTypeName($1); + /* char defaults to char(1), varchar to no limit */ if (strcmp($1, "bpchar") == 0) $$->typmod = VARHDRSZ + 1; else $$->typmod = -1; - - if (($2 != NULL) && (strcmp($2, "sql_text") != 0)) { - char *type; - - type = palloc(strlen($$->name) + 1 + strlen($2) + 1); - strcpy(type, $$->name); - strcat(type, "_"); - strcat(type, $2); - $$->name = xlateSqlType(type); - }; } ; @@ -4488,11 +4493,10 @@ opt_collate: COLLATE ColId { $$ = $2; } ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x { - $$ = makeNode(TypeName); if ($5) - $$->name = xlateSqlType("timestamptz"); + $$ = makeTypeName(xlateSqlType("timestamptz")); else - $$->name = xlateSqlType("timestamp"); + $$ = makeTypeName(xlateSqlType("timestamp")); /* XXX the timezone field seems to be unused * - thomas 2001-09-06 */ @@ -4504,11 +4508,10 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x } | TIMESTAMP opt_timezone_x { - $$ = makeNode(TypeName); if ($2) - $$->name = xlateSqlType("timestamptz"); + $$ = makeTypeName(xlateSqlType("timestamptz")); else - $$->name = xlateSqlType("timestamp"); + $$ = makeTypeName(xlateSqlType("timestamp")); /* XXX the timezone field seems to be unused * - thomas 2001-09-06 */ @@ -4524,11 +4527,10 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x } | TIME '(' Iconst ')' opt_timezone { - $$ = makeNode(TypeName); if ($5) - $$->name = xlateSqlType("timetz"); + $$ = makeTypeName(xlateSqlType("timetz")); else - $$->name = xlateSqlType("time"); + $$ = makeTypeName(xlateSqlType("time")); if (($3 < 0) || ($3 > 13)) elog(ERROR,"TIME(%d)%s precision must be between %d and %d", $3, ($5 ? " WITH TIME ZONE": ""), 0, 13); @@ -4536,11 +4538,10 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x } | TIME opt_timezone { - $$ = makeNode(TypeName); if ($2) - $$->name = xlateSqlType("timetz"); + $$ = makeTypeName(xlateSqlType("timetz")); else - $$->name = xlateSqlType("time"); + $$ = makeTypeName(xlateSqlType("time")); /* SQL99 specified a default precision of zero. * See comments for timestamp above on why we will * leave this unspecified for now. - thomas 2001-12-07 @@ -4551,9 +4552,7 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x ConstInterval: INTERVAL { - $$ = makeNode(TypeName); - $$->name = xlateSqlType("interval"); - $$->typmod = -1; + $$ = makeTypeName(xlateSqlType("interval")); } ; @@ -5161,7 +5160,7 @@ c_expr: columnref | CURRENT_DATE opt_empty_parentheses { /* - * Translate as "date('now'::text)". + * Translate as "'now'::text::date". * * We cannot use "'now'::date" because coerce_type() will * immediately reduce that to a constant representing @@ -5174,43 +5173,30 @@ c_expr: columnref * of type-input conversion functions... */ A_Const *s = makeNode(A_Const); - TypeName *t = makeNode(TypeName); - TypeName *d = makeNode(TypeName); + TypeName *d; s->val.type = T_String; s->val.val.str = "now"; - s->typename = t; + s->typename = makeTypeName(xlateSqlType("text")); - t->name = xlateSqlType("text"); - t->setof = FALSE; - t->typmod = -1; - - d->name = xlateSqlType("date"); - d->setof = FALSE; - d->typmod = -1; + d = makeTypeName(xlateSqlType("date")); $$ = (Node *)makeTypeCast((Node *)s, d); } | CURRENT_TIME opt_empty_parentheses { /* - * Translate as "timetz('now'::text)". + * Translate as "'now'::text::timetz". * See comments for CURRENT_DATE. */ A_Const *s = makeNode(A_Const); - TypeName *t = makeNode(TypeName); - TypeName *d = makeNode(TypeName); + TypeName *d; s->val.type = T_String; s->val.val.str = "now"; - s->typename = t; - - t->name = xlateSqlType("text"); - t->setof = FALSE; - t->typmod = -1; + s->typename = makeTypeName(xlateSqlType("text")); - d->name = xlateSqlType("timetz"); - d->setof = FALSE; + d = makeTypeName(xlateSqlType("timetz")); /* SQL99 mandates a default precision of zero for TIME * fields in schemas. However, for CURRENT_TIME * let's preserve the microsecond precision we @@ -5223,23 +5209,17 @@ c_expr: columnref | CURRENT_TIME '(' Iconst ')' { /* - * Translate as "timetz('now'::text)". + * Translate as "'now'::text::timetz(n)". * See comments for CURRENT_DATE. */ A_Const *s = makeNode(A_Const); - TypeName *t = makeNode(TypeName); - TypeName *d = makeNode(TypeName); + TypeName *d; s->val.type = T_String; s->val.val.str = "now"; - s->typename = t; + s->typename = makeTypeName(xlateSqlType("text")); - t->name = xlateSqlType("text"); - t->setof = FALSE; - t->typmod = -1; - - d->name = xlateSqlType("timetz"); - d->setof = FALSE; + d = makeTypeName(xlateSqlType("timetz")); if (($3 < 0) || ($3 > 13)) elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d", $3, 0, 13); @@ -5250,23 +5230,17 @@ c_expr: columnref | CURRENT_TIMESTAMP opt_empty_parentheses { /* - * Translate as "timestamptz('now'::text)". + * Translate as "'now'::text::timestamptz". * See comments for CURRENT_DATE. */ A_Const *s = makeNode(A_Const); - TypeName *t = makeNode(TypeName); - TypeName *d = makeNode(TypeName); + TypeName *d; s->val.type = T_String; s->val.val.str = "now"; - s->typename = t; - - t->name = xlateSqlType("text"); - t->setof = FALSE; - t->typmod = -1; + s->typename = makeTypeName(xlateSqlType("text")); - d->name = xlateSqlType("timestamptz"); - d->setof = FALSE; + d = makeTypeName(xlateSqlType("timestamptz")); /* SQL99 mandates a default precision of 6 for timestamp. * Also, that is about as precise as we will get since * we are using a microsecond time interface. @@ -5279,23 +5253,17 @@ c_expr: columnref | CURRENT_TIMESTAMP '(' Iconst ')' { /* - * Translate as "timestamptz('now'::text)". + * Translate as "'now'::text::timestamptz(n)". * See comments for CURRENT_DATE. */ A_Const *s = makeNode(A_Const); - TypeName *t = makeNode(TypeName); - TypeName *d = makeNode(TypeName); + TypeName *d; s->val.type = T_String; s->val.val.str = "now"; - s->typename = t; - - t->name = xlateSqlType("text"); - t->setof = FALSE; - t->typmod = -1; + s->typename = makeTypeName(xlateSqlType("text")); - d->name = xlateSqlType("timestamptz"); - d->setof = FALSE; + d = makeTypeName(xlateSqlType("timestamptz")); if (($3 < 0) || ($3 > 13)) elog(ERROR,"CURRENT_TIMESTAMP(%d) precision must be between %d and %d", $3, 0, 13); @@ -5645,24 +5613,24 @@ columnref: relation_name opt_indirection $$->fields = makeList1(makeString($1)); $$->indirection = $2; } - | relation_name attrs opt_indirection + | dotted_name opt_indirection { $$ = makeNode(ColumnRef); - $$->fields = lcons(makeString($1), $2); - $$->indirection = $3; + $$->fields = $1; + $$->indirection = $2; } ; -attrs: opt_attrs '.' attr_name - { $$ = lappend($1, makeString($3)); } - | opt_attrs '.' '*' - { $$ = lappend($1, makeString("*")); } +dotted_name: relation_name attrs + { $$ = lcons(makeString($1), $2); } ; -opt_attrs: /*EMPTY*/ - { $$ = NIL; } - | opt_attrs '.' attr_name - { $$ = lappend($1, makeString($3)); } +attrs: '.' attr_name + { $$ = makeList1(makeString($2)); } + | '.' '*' + { $$ = makeList1(makeString("*")); } + | '.' attr_name attrs + { $$ = lcons(makeString($2), $3); } ; opt_empty_parentheses: '(' ')' { $$ = TRUE; } @@ -5742,11 +5710,11 @@ relation_name: SpecialRuleRelation $$ = $1; } ; - + qualified_name_list: qualified_name - { $$ = makeList1($1); } + { $$ = makeList1($1); } | qualified_name_list ',' qualified_name - { $$ = lappend($1, $3); } + { $$ = lappend($1, $3); } ; qualified_name: ColId @@ -5787,6 +5755,21 @@ class: ColId { $$ = $1; }; index_name: ColId { $$ = $1; }; file_name: Sconst { $$ = $1; }; +/* func_name will soon return a List ... but not yet */ +/* +func_name: function_name + { $$ = makeList1(makeString($1)); } + | dotted_name + { $$ = $1; } + ; +*/ +func_name: function_name + { $$ = $1; } + | dotted_name + { $$ = strVal(lfirst($1)); } + ; + + /* Constants * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24 */ @@ -5867,9 +5850,7 @@ AexprConst: Iconst A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = "t"; - n->typename = makeNode(TypeName); - n->typename->name = xlateSqlType("bool"); - n->typename->typmod = -1; + n->typename = makeTypeName(xlateSqlType("bool")); $$ = (Node *)n; } | FALSE_P @@ -5877,9 +5858,7 @@ AexprConst: Iconst A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = "f"; - n->typename = makeNode(TypeName); - n->typename->name = xlateSqlType("bool"); - n->typename->typmod = -1; + n->typename = makeTypeName(xlateSqlType("bool")); $$ = (Node *)n; } | NULL_P @@ -5920,7 +5899,7 @@ type_name: IDENT { $$ = $1; } /* Function identifier --- names that can be function names. */ -func_name: IDENT { $$ = xlateSqlFunc($1); } +function_name: IDENT { $$ = xlateSqlFunc($1); } | unreserved_keyword { $$ = xlateSqlFunc($1); } | func_name_keyword { $$ = xlateSqlFunc($1); } ; @@ -6304,6 +6283,7 @@ static Node * makeStringConst(char *str, TypeName *typename) { A_Const *n = makeNode(A_Const); + n->val.type = T_String; n->val.val.str = str; n->typename = typename; @@ -6315,12 +6295,10 @@ static Node * makeFloatConst(char *str) { A_Const *n = makeNode(A_Const); - TypeName *t = makeNode(TypeName); + n->val.type = T_Float; n->val.val.str = str; - t->name = xlateSqlType("float"); - t->typmod = -1; - n->typename = t; + n->typename = makeTypeName(xlateSqlType("float")); return (Node *)n; } @@ -6435,7 +6413,6 @@ makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg) return (Node *) n; } - /* xlateSqlFunc() * Convert alternate function names to internal Postgres functions. * diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 73cd89fd3d8..2a5a7698d85 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.111 2002/03/21 16:01:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.112 2002/03/29 19:06:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1103,7 +1103,7 @@ parser_typecast_constant(Value *expr, TypeName *typename) bool string_palloced = false; bool isNull = false; - tp = typenameType(TypeNameToInternalName(typename)); + tp = typenameType(typename); switch (nodeTag(expr)) { @@ -1161,7 +1161,7 @@ parser_typecast_expression(ParseState *pstate, Oid inputType = exprType(expr); Oid targetType; - targetType = typenameTypeId(TypeNameToInternalName(typename)); + targetType = typenameTypeId(typename); if (inputType == InvalidOid) return expr; /* do nothing if NULL input */ @@ -1185,27 +1185,3 @@ parser_typecast_expression(ParseState *pstate, return expr; } - -/* - * Given a TypeName node as returned by the grammar, generate the internal - * name of the corresponding type. Note this does NOT check if the type - * exists or not. - */ -char * -TypeNameToInternalName(TypeName *typename) -{ - Assert(typename->attrname == NULL); - if (typename->arrayBounds != NIL) - { - /* - * By convention, the name of an array type is the name of its - * element type with "_" prepended. - */ - char *arrayname = palloc(strlen(typename->name) + 2); - - sprintf(arrayname, "_%s", typename->name); - return arrayname; - } - else - return typename->name; -} diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index f02ee04b696..9436bd645bd 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.120 2002/03/22 02:56:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.121 2002/03/29 19:06:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,6 +20,7 @@ #include "catalog/indexing.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_inherits.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_proc.h" #include "nodes/makefuncs.h" #include "parser/parse_agg.h" @@ -969,9 +970,14 @@ func_get_detail(char *funcname, { Oid targetType; - targetType = GetSysCacheOid(TYPENAME, + /* XXX WRONG: need to search searchpath for name; but little + * point in fixing before we revise this code for qualified + * funcnames too. + */ + targetType = GetSysCacheOid(TYPENAMENSP, PointerGetDatum(funcname), - 0, 0, 0); + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); if (OidIsValid(targetType) && !ISCOMPLEX(targetType)) { @@ -1222,13 +1228,11 @@ find_inheritors(Oid relid, Oid **supervec) { /* return the type id, rather than the relation id */ Relation rd; - Oid trelid; relid = lfirsti(elt); rd = heap_open(relid, NoLock); - trelid = typenameTypeId(RelationGetRelationName(rd)); + *relidvec++ = rd->rd_rel->reltype; heap_close(rd, NoLock); - *relidvec++ = trelid; } } else @@ -1473,7 +1477,9 @@ ParseComplexProjection(ParseState *pstate, * argument types */ void -func_error(char *caller, char *funcname, int nargs, Oid *argtypes, char *msg) +func_error(const char *caller, const char *funcname, + int nargs, const Oid *argtypes, + const char *msg) { char p[(NAMEDATALEN + 2) * FUNC_MAX_ARGS], *ptr; @@ -1488,9 +1494,9 @@ func_error(char *caller, char *funcname, int nargs, Oid *argtypes, char *msg) *ptr++ = ','; *ptr++ = ' '; } - if (argtypes[i] != 0) + if (OidIsValid(argtypes[i])) { - strcpy(ptr, typeidTypeName(argtypes[i])); + strncpy(ptr, typeidTypeName(argtypes[i]), NAMEDATALEN); *(ptr + NAMEDATALEN) = '\0'; } else diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index cc56cb6d183..1df2d285a5b 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.79 2002/03/22 02:56:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.80 2002/03/29 19:06:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -525,8 +525,15 @@ FigureColnameInternal(Node *node, char **name) case T_A_Const: if (((A_Const *) node)->typename != NULL) { - *name = ((A_Const *) node)->typename->name; - return 1; + List *names = ((A_Const *) node)->typename->names; + + if (names != NIL) + { + while (lnext(names) != NIL) + names = lnext(names); + *name = strVal(lfirst(names)); + return 1; + } } break; case T_TypeCast: @@ -536,8 +543,15 @@ FigureColnameInternal(Node *node, char **name) { if (((TypeCast *) node)->typename != NULL) { - *name = ((TypeCast *) node)->typename->name; - return 1; + List *names = ((TypeCast *) node)->typename->names; + + if (names != NIL) + { + while (lnext(names) != NIL) + names = lnext(names); + *name = strVal(lfirst(names)); + return 1; + } } } break; diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c index 732974a96fc..22db859ed2b 100644 --- a/src/backend/parser/parse_type.c +++ b/src/backend/parser/parse_type.c @@ -8,20 +8,250 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.37 2001/10/25 05:49:40 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.38 2002/03/29 19:06:12 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" +#include "catalog/namespace.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_type.h" +#include "lib/stringinfo.h" +#include "miscadmin.h" +#include "nodes/makefuncs.h" #include "nodes/parsenodes.h" #include "parser/parser.h" #include "parser/parse_expr.h" #include "parser/parse_type.h" +#include "utils/lsyscache.h" #include "utils/syscache.h" +/* + * LookupTypeName + * Given a TypeName object, get the OID of the referenced type. + * Returns InvalidOid if no such type can be found. + * + * NB: even if the returned OID is not InvalidOid, the type might be + * just a shell. Caller should check typisdefined before using the type. + */ +Oid +LookupTypeName(const TypeName *typename) +{ + Oid restype; + + /* Easy if it's an internally generated TypeName */ + if (typename->names == NIL) + return typename->typeid; + + if (typename->pct_type) + { + /* Handle %TYPE reference to type of an existing field */ + RangeVar *rel = makeRangeVar(NULL, NULL); + char *field = NULL; + Oid relid; + AttrNumber attnum; + + /* deconstruct the name list */ + switch (length(typename->names)) + { + case 1: + elog(ERROR, "Improper %%TYPE reference (too few dotted names)"); + break; + case 2: + rel->relname = strVal(lfirst(typename->names)); + field = strVal(lsecond(typename->names)); + break; + case 3: + rel->schemaname = strVal(lfirst(typename->names)); + rel->relname = strVal(lsecond(typename->names)); + field = strVal(lfirst(lnext(lnext(typename->names)))); + break; + case 4: + rel->catalogname = strVal(lfirst(typename->names)); + rel->schemaname = strVal(lsecond(typename->names)); + rel->relname = strVal(lfirst(lnext(lnext(typename->names)))); + field = strVal(lfirst(lnext(lnext(lnext(typename->names))))); + break; + default: + elog(ERROR, "Improper %%TYPE reference (too many dotted names)"); + break; + } + + /* look up the field */ + relid = RangeVarGetRelid(rel, false); + attnum = get_attnum(relid, field); + if (attnum == InvalidAttrNumber) + elog(ERROR, "'%s' is not an attribute of class '%s'", + field, rel->relname); + restype = get_atttype(relid, attnum); + + /* this construct should never have an array indicator */ + Assert(typename->arrayBounds == NIL); + + /* emit nuisance warning */ + elog(NOTICE, "%s converted to %s", + TypeNameToString(typename), typeidTypeName(restype)); + } + else + { + /* Normal reference to a type name */ + char *catalogname; + char *schemaname = NULL; + char *typname = NULL; + + /* deconstruct the name list */ + switch (length(typename->names)) + { + case 1: + typname = strVal(lfirst(typename->names)); + break; + case 2: + schemaname = strVal(lfirst(typename->names)); + typname = strVal(lsecond(typename->names)); + break; + case 3: + catalogname = strVal(lfirst(typename->names)); + schemaname = strVal(lsecond(typename->names)); + typname = strVal(lfirst(lnext(lnext(typename->names)))); + /* + * We check the catalog name and then ignore it. + */ + if (strcmp(catalogname, DatabaseName) != 0) + elog(ERROR, "Cross-database references are not implemented"); + break; + default: + elog(ERROR, "Improper type name (too many dotted names)"); + break; + } + + /* If an array reference, look up the array type instead */ + if (typename->arrayBounds != NIL) + typname = makeArrayTypeName(typname); + + if (schemaname) + { + Oid namespaceId; + + namespaceId = GetSysCacheOid(NAMESPACENAME, + CStringGetDatum(schemaname), + 0, 0, 0); + if (!OidIsValid(namespaceId)) + elog(ERROR, "Namespace \"%s\" does not exist", + schemaname); + restype = GetSysCacheOid(TYPENAMENSP, + PointerGetDatum(typname), + ObjectIdGetDatum(namespaceId), + 0, 0); + } + else + { + /* XXX wrong, should use namespace search */ + restype = GetSysCacheOid(TYPENAMENSP, + PointerGetDatum(typname), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + } + } + + return restype; +} + +/* + * TypeNameToString + * Produce a string representing the name of a TypeName. + * + * NB: this must work on TypeNames that do not describe any actual type; + * it is mostly used for reporting lookup errors. + */ +char * +TypeNameToString(const TypeName *typename) +{ + StringInfoData string; + + initStringInfo(&string); + + if (typename->names != NIL) + { + /* Emit possibly-qualified name as-is */ + List *l; + + foreach(l, typename->names) + { + if (l != typename->names) + appendStringInfoChar(&string, '.'); + appendStringInfo(&string, "%s", strVal(lfirst(l))); + } + } + else + { + /* Look up internally-specified type */ + appendStringInfo(&string, "%s", typeidTypeName(typename->typeid)); + } + + /* + * Add decoration as needed, but only for fields considered by + * LookupTypeName + */ + if (typename->pct_type) + appendStringInfo(&string, "%%TYPE"); + + if (typename->arrayBounds != NIL) + appendStringInfo(&string, "[]"); + + return string.data; +} + +/* + * typenameTypeId - given a TypeName, return the type's OID + * + * This is equivalent to LookupTypeName, except that this will report + * a suitable error message if the type cannot be found or is not defined. + */ +Oid +typenameTypeId(const TypeName *typename) +{ + Oid typoid; + + typoid = LookupTypeName(typename); + if (!OidIsValid(typoid)) + elog(ERROR, "Type \"%s\" does not exist", + TypeNameToString(typename)); + if (!get_typisdefined(typoid)) + elog(ERROR, "Type \"%s\" is only a shell", + TypeNameToString(typename)); + return typoid; +} + +/* + * typenameType - given a TypeName, return a Type structure + * + * This is equivalent to typenameTypeId + syscache fetch of Type tuple. + * NB: caller must ReleaseSysCache the type tuple when done with it. + */ +Type +typenameType(const TypeName *typename) +{ + Oid typoid; + HeapTuple tup; + + typoid = LookupTypeName(typename); + if (!OidIsValid(typoid)) + elog(ERROR, "Type \"%s\" does not exist", + TypeNameToString(typename)); + tup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(typoid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "Type \"%s\" does not exist", + TypeNameToString(typename)); + if (! ((Form_pg_type) GETSTRUCT(tup))->typisdefined) + elog(ERROR, "Type \"%s\" is only a shell", + TypeNameToString(typename)); + return (Type) tup; +} + /* check to see if a type id is valid, * returns true if it is. By using this call before calling * typeidType or typeidTypeName, more meaningful error messages @@ -51,24 +281,6 @@ typeidType(Oid id) return (Type) tup; } -/* return a Type structure, given type name */ -/* NB: caller must ReleaseSysCache the type tuple when done with it */ -Type -typenameType(char *s) -{ - HeapTuple tup; - - if (s == NULL) - elog(ERROR, "typenameType: Null typename"); - - tup = SearchSysCache(TYPENAME, - PointerGetDatum(s), - 0, 0, 0); - if (!HeapTupleIsValid(tup)) - elog(ERROR, "Unable to locate type name '%s' in catalog", s); - return (Type) tup; -} - /* given type (as type struct), return the type OID */ Oid typeTypeId(Type tp) @@ -207,6 +419,7 @@ typeidOutfunc(Oid type_id) #endif /* return a type name, given a typeid */ +/* nb: type name is NOT unique; use this only for error messages */ char * typeidTypeName(Oid id) { @@ -251,18 +464,6 @@ typeidTypeRelid(Oid type_id) return result; } -/* given a type name, return the type's typeid */ -Oid -typenameTypeId(char *s) -{ - Type typ = typenameType(s); - Oid result; - - result = typ->t_data->t_oid; - ReleaseSysCache(typ); - return result; -} - /* * Given a string that is supposed to be a SQL-compatible type declaration, * such as "int4" or "integer" or "character varying(32)", parse @@ -327,7 +528,7 @@ parseTypeString(const char *str, Oid *type_id, int32 *typmod) !IsA(typename, TypeName)) elog(ERROR, "Invalid type name '%s'", str); - *type_id = typenameTypeId(TypeNameToInternalName(typename)); + *type_id = typenameTypeId(typename); *typmod = typename->typmod; pfree(buf); diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c index 6d251b78343..da8f1b8e540 100644 --- a/src/backend/rewrite/rewriteRemove.c +++ b/src/backend/rewrite/rewriteRemove.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.46 2002/03/21 23:27:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.47 2002/03/29 19:06:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -30,11 +30,12 @@ /* * RemoveRewriteRule * - * Delete a rule given its rulename. + * Delete a rule given its (possibly qualified) rulename. */ void -RemoveRewriteRule(char *ruleName) +RemoveRewriteRule(List *names) { + char *ruleName; Relation RewriteRelation; Relation event_relation; HeapTuple tuple; @@ -44,6 +45,13 @@ RemoveRewriteRule(char *ruleName) int32 aclcheck_result; /* + * XXX temporary until rules become schema-tized + */ + if (length(names) != 1) + elog(ERROR, "Qualified rule names not supported yet"); + ruleName = strVal(lfirst(names)); + + /* * Open the pg_rewrite relation. */ RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock); diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 84f3325256a..e383290fa4d 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.140 2002/03/26 19:16:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.141 2002/03/29 19:06:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -38,13 +38,16 @@ #include "commands/variable.h" #include "commands/view.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "parser/parse.h" #include "parser/parse_clause.h" #include "parser/parse_expr.h" +#include "parser/parse_type.h" #include "rewrite/rewriteDefine.h" #include "rewrite/rewriteRemove.h" #include "tcop/utility.h" #include "utils/acl.h" +#include "utils/lsyscache.h" #include "utils/syscache.h" #include "utils/temprel.h" #include "access/xlog.h" @@ -280,45 +283,48 @@ ProcessUtility(Node *parsetree, foreach(arg, stmt->objects) { - RangeVar *rel = (RangeVar *) lfirst(arg); - - relname = rel->relname; + List *names = (List *) lfirst(arg); + RangeVar *rel; switch (stmt->removeType) { case DROP_TABLE: + rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_RELATION); - RemoveRelation(relname); + RemoveRelation(rel); break; case DROP_SEQUENCE: + rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_SEQUENCE); - RemoveRelation(relname); + RemoveRelation(rel); break; case DROP_VIEW: + rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_VIEW); - RemoveView(relname); + RemoveView(rel); break; case DROP_INDEX: + rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_INDEX); RemoveIndex(rel); break; case DROP_RULE: /* RemoveRewriteRule checks permissions */ - RemoveRewriteRule(relname); + RemoveRewriteRule(names); break; case DROP_TYPE: /* RemoveType does its own permissions checks */ - RemoveType(relname); + RemoveType(names); break; case DROP_DOMAIN: /* RemoveDomain does its own permissions checks */ - RemoveDomain(relname, stmt->behavior); + RemoveDomain(names, stmt->behavior); break; } @@ -334,16 +340,15 @@ ProcessUtility(Node *parsetree, case T_TruncateStmt: { - relname = ((TruncateStmt *) parsetree)->relation->relname; - TruncateRelation(relname); + TruncateStmt *stmt = (TruncateStmt *) parsetree; + + TruncateRelation(stmt->relation); } break; case T_CommentStmt: { - CommentStmt *stmt; - - stmt = ((CommentStmt *) parsetree); + CommentStmt *stmt = (CommentStmt *) parsetree; CommentObject(stmt->objtype, stmt->objschema, stmt->objname, stmt->objproperty, stmt->objlist, stmt->comment); @@ -357,7 +362,7 @@ ProcessUtility(Node *parsetree, if (stmt->direction != FROM) SetQuerySnapshot(); - DoCopy(stmt->relation->relname, + DoCopy(stmt->relation, stmt->binary, stmt->oids, (bool) (stmt->direction == FROM), @@ -408,7 +413,7 @@ ProcessUtility(Node *parsetree, /* * rename attribute */ - renameatt(relname, /* relname */ + renameatt(RangeVarGetRelid(stmt->relation, false), /* relation */ stmt->column, /* old att name */ stmt->newname, /* new att name */ interpretInhOption(stmt->relation->inhOpt)); /* recursive? */ @@ -429,38 +434,63 @@ ProcessUtility(Node *parsetree, switch (stmt->subtype) { case 'A': /* ADD COLUMN */ - AlterTableAddColumn(stmt->relation->relname, - interpretInhOption((stmt->relation)->inhOpt), + /* + * Recursively add column to table and, + * if requested, to descendants + */ + AlterTableAddColumn(RangeVarGetRelid(stmt->relation, false), + interpretInhOption(stmt->relation->inhOpt), (ColumnDef *) stmt->def); break; case 'T': /* ALTER COLUMN DEFAULT */ - AlterTableAlterColumnDefault(stmt->relation->relname, - interpretInhOption((stmt->relation)->inhOpt), + /* + * Recursively alter column default for table and, + * if requested, for descendants + */ + AlterTableAlterColumnDefault(RangeVarGetRelid(stmt->relation, false), + interpretInhOption(stmt->relation->inhOpt), stmt->name, stmt->def); break; case 'S': /* ALTER COLUMN STATISTICS */ case 'M': /* ALTER COLUMN STORAGE */ - AlterTableAlterColumnFlags(stmt->relation->relname, - interpretInhOption(stmt->relation->inhOpt), - stmt->name, - stmt->def, - &(stmt->subtype)); + /* + * Recursively alter column statistics for table and, + * if requested, for descendants + */ + AlterTableAlterColumnFlags(RangeVarGetRelid(stmt->relation, false), + interpretInhOption(stmt->relation->inhOpt), + stmt->name, + stmt->def, + &(stmt->subtype)); break; case 'D': /* DROP COLUMN */ - AlterTableDropColumn(stmt->relation->relname, - interpretInhOption(stmt->relation->inhOpt), + /* + * XXX We don't actually recurse yet, but what we should do would be: + * Recursively drop column from table and, + * if requested, from descendants + */ + AlterTableDropColumn(RangeVarGetRelid(stmt->relation, false), + interpretInhOption(stmt->relation->inhOpt), stmt->name, stmt->behavior); break; case 'C': /* ADD CONSTRAINT */ - AlterTableAddConstraint(stmt->relation->relname, - interpretInhOption(stmt->relation->inhOpt), + /* + * Recursively add constraint to table and, + * if requested, to descendants + */ + AlterTableAddConstraint(RangeVarGetRelid(stmt->relation, false), + interpretInhOption(stmt->relation->inhOpt), (List *) stmt->def); break; case 'X': /* DROP CONSTRAINT */ - AlterTableDropConstraint(stmt->relation->relname, - interpretInhOption(stmt->relation->inhOpt), + /* + * Recursively drop constraint from table and, + * if requested, from descendants + */ + AlterTableDropConstraint(RangeVarGetRelid(stmt->relation, false), + interpretInhOption(stmt->relation->inhOpt), stmt->name, stmt->behavior); break; @@ -469,8 +499,12 @@ ProcessUtility(Node *parsetree, false); break; case 'U': /* ALTER OWNER */ - AlterTableOwner(stmt->relation, - stmt->name); + /* check that we are the superuser */ + if (!superuser()) + elog(ERROR, "ALTER TABLE: permission denied"); + /* get_usesysid raises an error if no such user */ + AlterTableOwner(RangeVarGetRelid(stmt->relation, false), + get_usesysid(stmt->name)); break; default: /* oops */ elog(ERROR, "T_AlterTableStmt: unknown subtype"); @@ -500,15 +534,13 @@ ProcessUtility(Node *parsetree, switch (stmt->defType) { case OPERATOR: - DefineOperator(stmt->defname, /* operator name */ - stmt->definition); /* rest */ + DefineOperator(stmt->defnames, stmt->definition); break; case TYPE_P: - DefineType(stmt->defname, stmt->definition); + DefineType(stmt->defnames, stmt->definition); break; case AGGREGATE: - DefineAggregate(stmt->defname, /* aggregate name */ - stmt->definition); /* rest */ + DefineAggregate(stmt->defnames, stmt->definition); break; } } @@ -518,7 +550,7 @@ ProcessUtility(Node *parsetree, { ViewStmt *stmt = (ViewStmt *) parsetree; - DefineView(stmt->view->relname, stmt->query); /* retrieve parsetree */ + DefineView(stmt->view, stmt->query); } break; @@ -554,12 +586,8 @@ ProcessUtility(Node *parsetree, case T_RemoveAggrStmt: { RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree; - char *typename = (char *) NULL; - if (stmt->aggtype != NULL) - typename = TypeNameToInternalName((TypeName *) stmt->aggtype); - - RemoveAggregate(stmt->aggname, typename); + RemoveAggregate(stmt->aggname, stmt->aggtype); } break; @@ -576,15 +604,8 @@ ProcessUtility(Node *parsetree, RemoveOperStmt *stmt = (RemoveOperStmt *) parsetree; TypeName *typenode1 = (TypeName *) lfirst(stmt->args); TypeName *typenode2 = (TypeName *) lsecond(stmt->args); - char *typename1 = (char *) NULL; - char *typename2 = (char *) NULL; - - if (typenode1 != NULL) - typename1 = TypeNameToInternalName(typenode1); - if (typenode2 != NULL) - typename2 = TypeNameToInternalName(typenode2); - RemoveOperator(stmt->opname, typename1, typename2); + RemoveOperator(stmt->opname, typenode1, typenode2); } break; diff --git a/src/backend/utils/adt/sets.c b/src/backend/utils/adt/sets.c index 15210f0c841..eff24bd8911 100644 --- a/src/backend/utils/adt/sets.c +++ b/src/backend/utils/adt/sets.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.40 2002/02/18 23:11:23 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.41 2002/03/29 19:06:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ #include "catalog/catname.h" #include "catalog/indexing.h" #include "catalog/pg_language.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_proc.h" #include "executor/executor.h" #include "utils/fcache.h" @@ -36,7 +37,7 @@ * in pg_proc. */ Oid -SetDefine(char *querystr, char *typename) +SetDefine(char *querystr, Oid elemType) { Oid setoid; char *procname = GENERICSETNAME; @@ -52,9 +53,10 @@ SetDefine(char *querystr, char *typename) char repl[Natts_pg_proc]; setoid = ProcedureCreate(procname, /* changed below, after oid known */ + PG_CATALOG_NAMESPACE, /* XXX wrong */ false, /* don't replace */ true, /* returnsSet */ - typename, /* returnTypeName */ + elemType, /* returnType */ SQLlanguageId, /* language */ querystr, /* sourceCode */ fileName, /* fileName */ diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 82be75ac799..6ec682f5206 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.66 2002/03/26 19:16:09 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.67 2002/03/29 19:06:15 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -739,6 +739,33 @@ get_rel_type_id(Oid relid) /* ---------- TYPE CACHE ---------- */ /* + * get_typisdefined + * + * Given the type OID, determine whether the type is defined + * (if not, it's only a shell). + */ +bool +get_typisdefined(Oid typid) +{ + HeapTuple tp; + + tp = SearchSysCache(TYPEOID, + ObjectIdGetDatum(typid), + 0, 0, 0); + if (HeapTupleIsValid(tp)) + { + Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); + bool result; + + result = typtup->typisdefined; + ReleaseSysCache(tp); + return result; + } + else + return false; +} + +/* * get_typlen * * Given the type OID, return the length of the type. diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 57d4719b294..a160e4fb1bd 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.70 2002/03/26 19:16:14 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.71 2002/03/29 19:06:15 tgl Exp $ * * NOTES * These routines allow the parser/planner/executor to perform @@ -384,13 +384,13 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }}, - {TypeRelationName, /* TYPENAME */ - TypeNameIndex, + {TypeRelationName, /* TYPENAMENSP */ + TypeNameNspIndex, Anum_pg_type_typrelid, - 1, + 2, { Anum_pg_type_typname, - 0, + Anum_pg_type_typnamespace, 0, 0 }}, @@ -515,7 +515,7 @@ SearchSysCache(int cacheId, * when sought. This is a kluge ... temp table substitution should be * happening at a higher level ... */ - if (cacheId == RELNAMENSP || cacheId == TYPENAME) + if (cacheId == RELNAMENSP || cacheId == TYPENAMENSP) { char *nontemp_relname; diff --git a/src/backend/utils/cache/temprel.c b/src/backend/utils/cache/temprel.c index 88dc606cb0e..7ab609eaf36 100644 --- a/src/backend/utils/cache/temprel.c +++ b/src/backend/utils/cache/temprel.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.35 2001/03/22 03:59:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.36 2002/03/29 19:06:16 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -227,13 +227,7 @@ remove_all_temp_relations(void) continue; /* ignore it if deleted already */ if (temp_rel->relkind != RELKIND_INDEX) - { - char relname[NAMEDATALEN]; - - /* safe from deallocation */ - strcpy(relname, NameStr(temp_rel->user_relname)); - heap_drop_with_catalog(relname, allowSystemTableMods); - } + heap_drop_with_catalog(temp_rel->relid, allowSystemTableMods); else index_drop(temp_rel->relid); /* advance cmd counter to make catalog changes visible */ diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h index 9b532c9e2e4..b1cee7197f8 100644 --- a/src/include/access/tupdesc.h +++ b/src/include/access/tupdesc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: tupdesc.h,v 1.33 2001/11/05 17:46:31 momjian Exp $ + * $Id: tupdesc.h,v 1.34 2002/03/29 19:06:16 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -65,7 +65,7 @@ extern void FreeTupleDesc(TupleDesc tupdesc); extern bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2); -extern bool TupleDescInitEntry(TupleDesc desc, +extern void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, char *attributeName, Oid oidtypeid, @@ -73,6 +73,6 @@ extern bool TupleDescInitEntry(TupleDesc desc, int attdim, bool attisset); -extern TupleDesc BuildDescForRelation(List *schema, char *relname); +extern TupleDesc BuildDescForRelation(List *schema); #endif /* TUPDESC_H */ diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 0d9c280fb0d..d41c0a4c318 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.111 2002/03/26 19:16:22 tgl Exp $ + * $Id: catversion.h,v 1.112 2002/03/29 19:06:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200203251 +#define CATALOG_VERSION_NO 200203261 #endif diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index eb34ee1404f..b7313c64253 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: heap.h,v 1.47 2002/03/26 19:16:23 tgl Exp $ + * $Id: heap.h,v 1.48 2002/03/29 19:06:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -39,10 +39,9 @@ extern Oid heap_create_with_catalog(char *relname, Oid relnamespace, char relkind, bool relhasoids, bool istemp, bool allow_system_table_mods); -extern void heap_drop_with_catalog(const char *relname, - bool allow_system_table_mods); +extern void heap_drop_with_catalog(Oid rid, bool allow_system_table_mods); -extern void heap_truncate(const char *relname); +extern void heap_truncate(Oid rid); extern void AddRelationRawConstraints(Relation rel, List *rawColDefaults, diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 222e0da51e9..1cc15cedf87 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: indexing.h,v 1.59 2002/03/26 19:16:26 tgl Exp $ + * $Id: indexing.h,v 1.60 2002/03/29 19:06:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -89,7 +89,7 @@ #define TriggerConstrRelidIndex "pg_trigger_tgconstrrelid_index" #define TriggerRelidIndex "pg_trigger_tgrelid_index" #define TriggerOidIndex "pg_trigger_oid_index" -#define TypeNameIndex "pg_type_typname_index" +#define TypeNameNspIndex "pg_type_typname_nsp_index" #define TypeOidIndex "pg_type_oid_index" /* Arrays of names of indices for each system catalog */ @@ -189,7 +189,7 @@ DECLARE_INDEX(pg_trigger_tgconstrrelid_index on pg_trigger using btree(tgconstrr DECLARE_INDEX(pg_trigger_tgrelid_index on pg_trigger using btree(tgrelid oid_ops)); DECLARE_UNIQUE_INDEX(pg_trigger_oid_index on pg_trigger using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_type_oid_index on pg_type using btree(oid oid_ops)); -DECLARE_UNIQUE_INDEX(pg_type_typname_index on pg_type using btree(typname name_ops)); +DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index on pg_type using btree(typname name_ops, typnamespace oid_ops)); /* last step of initialization script: build the indices declared above */ BUILD_INDICES diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index cbe65a07f55..f6f359813cd 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: namespace.h,v 1.1 2002/03/26 19:16:28 tgl Exp $ + * $Id: namespace.h,v 1.2 2002/03/29 19:06:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,4 +23,8 @@ extern Oid RangeVarGetCreationNamespace(const RangeVar *newRelation); extern Oid RelnameGetRelid(const char *relname); +extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p); + +extern RangeVar *makeRangeVarFromNameList(List *names); + #endif /* NAMESPACE_H */ diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index f0bf81dedcd..65494e8afe2 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_aggregate.h,v 1.35 2001/11/05 17:46:32 momjian Exp $ + * $Id: pg_aggregate.h,v 1.36 2002/03/29 19:06:18 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -155,12 +155,13 @@ DATA(insert OID = 0 ( stddev PGUID numeric_accum numeric_stddev 1700 1231 1700 /* * prototypes for functions in pg_aggregate.c */ -extern void AggregateCreate(char *aggName, - char *aggtransfnName, - char *aggfinalfnName, - char *aggbasetypeName, - char *aggtranstypeName, - char *agginitval); +extern void AggregateCreate(const char *aggName, + Oid aggNamespace, + char *aggtransfnName, + char *aggfinalfnName, + Oid aggBaseType, + Oid aggTransType, + const char *agginitval); extern Datum AggNameGetInitVal(char *aggName, Oid basetype, bool *isNull); diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index e8166960d28..d075e49aca0 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_attribute.h,v 1.86 2002/03/26 19:16:29 tgl Exp $ + * $Id: pg_attribute.h,v 1.87 2002/03/29 19:06:18 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -225,51 +225,53 @@ typedef FormData_pg_attribute *Form_pg_attribute; */ #define Schema_pg_type \ { 1247, {"typname"}, 19, DEFAULT_ATTSTATTARGET, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \ -{ 1247, {"typowner"}, 23, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typlen"}, 21, 0, 2, 3, 0, -1, -1, true, 'p', false, 's', false, false }, \ -{ 1247, {"typprtlen"}, 21, 0, 2, 4, 0, -1, -1, true, 'p', false, 's', false, false }, \ -{ 1247, {"typbyval"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1247, {"typtype"}, 18, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1247, {"typisdefined"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1247, {"typdelim"}, 18, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1247, {"typrelid"}, 26, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typelem"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typinput"}, 24, 0, 4, 11, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typoutput"}, 24, 0, 4, 12, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typreceive"}, 24, 0, 4, 13, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typsend"}, 24, 0, 4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typalign"}, 18, 0, 1, 15, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1247, {"typstorage"}, 18, 0, 1, 16, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1247, {"typnotnull"}, 16, 0, 1, 17, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1247, {"typbasetype"}, 26, 0, 4, 18, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typtypmod"}, 23, 0, 4, 19, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typndims"}, 23, 0, 4, 20, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1247, {"typdefaultbin"}, 25, 0, -1, 21, 0, -1, -1, false, 'x', false, 'i', false, false }, \ -{ 1247, {"typdefault"}, 25, 0, -1, 22, 0, -1, -1, false, 'x', false, 'i', false, false } +{ 1247, {"typnamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typlen"}, 21, 0, 2, 4, 0, -1, -1, true, 'p', false, 's', false, false }, \ +{ 1247, {"typprtlen"}, 21, 0, 2, 5, 0, -1, -1, true, 'p', false, 's', false, false }, \ +{ 1247, {"typbyval"}, 16, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1247, {"typtype"}, 18, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1247, {"typisdefined"}, 16, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1247, {"typdelim"}, 18, 0, 1, 9, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1247, {"typrelid"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typelem"}, 26, 0, 4, 11, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typinput"}, 24, 0, 4, 12, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typoutput"}, 24, 0, 4, 13, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typreceive"}, 24, 0, 4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typsend"}, 24, 0, 4, 15, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typalign"}, 18, 0, 1, 16, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1247, {"typstorage"}, 18, 0, 1, 17, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1247, {"typnotnull"}, 16, 0, 1, 18, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1247, {"typbasetype"}, 26, 0, 4, 19, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typtypmod"}, 23, 0, 4, 20, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typndims"}, 23, 0, 4, 21, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1247, {"typdefaultbin"}, 25, 0, -1, 22, 0, -1, -1, false, 'x', false, 'i', false, false }, \ +{ 1247, {"typdefault"}, 25, 0, -1, 23, 0, -1, -1, false, 'x', false, 'i', false, false } DATA(insert ( 1247 typname 19 DEFAULT_ATTSTATTARGET NAMEDATALEN 1 0 -1 -1 f p f i f f)); -DATA(insert ( 1247 typowner 23 0 4 2 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typlen 21 0 2 3 0 -1 -1 t p f s f f)); -DATA(insert ( 1247 typprtlen 21 0 2 4 0 -1 -1 t p f s f f)); -DATA(insert ( 1247 typbyval 16 0 1 5 0 -1 -1 t p f c f f)); -DATA(insert ( 1247 typtype 18 0 1 6 0 -1 -1 t p f c f f)); -DATA(insert ( 1247 typisdefined 16 0 1 7 0 -1 -1 t p f c f f)); -DATA(insert ( 1247 typdelim 18 0 1 8 0 -1 -1 t p f c f f)); -DATA(insert ( 1247 typrelid 26 0 4 9 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typelem 26 0 4 10 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typinput 24 0 4 11 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typoutput 24 0 4 12 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typreceive 24 0 4 13 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typsend 24 0 4 14 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typalign 18 0 1 15 0 -1 -1 t p f c f f)); -DATA(insert ( 1247 typstorage 18 0 1 16 0 -1 -1 t p f c f f)); -DATA(insert ( 1247 typnotnull 16 0 1 17 0 -1 -1 t p f c f f)); -DATA(insert ( 1247 typbasetype 26 0 4 18 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typtypmod 23 0 4 19 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typndims 23 0 4 20 0 -1 -1 t p f i f f)); -DATA(insert ( 1247 typdefaultbin 25 0 -1 21 0 -1 -1 f x f i f f)); -DATA(insert ( 1247 typdefault 25 0 -1 22 0 -1 -1 f x f i f f)); +DATA(insert ( 1247 typnamespace 26 0 4 2 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typowner 23 0 4 3 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typlen 21 0 2 4 0 -1 -1 t p f s f f)); +DATA(insert ( 1247 typprtlen 21 0 2 5 0 -1 -1 t p f s f f)); +DATA(insert ( 1247 typbyval 16 0 1 6 0 -1 -1 t p f c f f)); +DATA(insert ( 1247 typtype 18 0 1 7 0 -1 -1 t p f c f f)); +DATA(insert ( 1247 typisdefined 16 0 1 8 0 -1 -1 t p f c f f)); +DATA(insert ( 1247 typdelim 18 0 1 9 0 -1 -1 t p f c f f)); +DATA(insert ( 1247 typrelid 26 0 4 10 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typelem 26 0 4 11 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typinput 24 0 4 12 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typoutput 24 0 4 13 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typreceive 24 0 4 14 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typsend 24 0 4 15 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typalign 18 0 1 16 0 -1 -1 t p f c f f)); +DATA(insert ( 1247 typstorage 18 0 1 17 0 -1 -1 t p f c f f)); +DATA(insert ( 1247 typnotnull 16 0 1 18 0 -1 -1 t p f c f f)); +DATA(insert ( 1247 typbasetype 26 0 4 19 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typtypmod 23 0 4 20 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typndims 23 0 4 21 0 -1 -1 t p f i f f)); +DATA(insert ( 1247 typdefaultbin 25 0 -1 22 0 -1 -1 f x f i f f)); +DATA(insert ( 1247 typdefault 25 0 -1 23 0 -1 -1 f x f i f f)); DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p f i f f)); DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p f i f f)); DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p f i f f)); diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index 60f524b2a62..0bd1256e1df 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_class.h,v 1.63 2002/03/26 19:16:35 tgl Exp $ + * $Id: pg_class.h,v 1.64 2002/03/29 19:06:18 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -134,7 +134,7 @@ typedef FormData_pg_class *Form_pg_class; * ---------------- */ -DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 f f r 22 0 0 0 0 0 t f f f _null_ )); +DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 f f r 23 0 0 0 0 0 t f f f _null_ )); DESCR(""); DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ )); DESCR(""); diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index bff7c6691b3..00ba73cd762 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_operator.h,v 1.99 2001/11/05 17:46:32 momjian Exp $ + * $Id: pg_operator.h,v 1.100 2002/03/29 19:06:19 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -843,18 +843,18 @@ DATA(insert OID = 2068 ( "-" PGUID 0 b t f 1114 1186 1114 0 0 0 0 timesta /* * function prototypes */ -extern void OperatorCreate(char *operatorName, - char *leftTypeName, - char *rightTypeName, - char *procedureName, +extern void OperatorCreate(const char *operatorName, + Oid leftTypeId, + Oid rightTypeId, + const char *procedureName, uint16 precedence, bool isLeftAssociative, - char *commutatorName, - char *negatorName, - char *restrictionName, - char *joinName, + const char *commutatorName, + const char *negatorName, + const char *restrictionName, + const char *joinName, bool canHash, - char *leftSortName, - char *rightSortName); + const char *leftSortName, + const char *rightSortName); #endif /* PG_OPERATOR_H */ diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index bd5c6045df6..ac32bd69aa0 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_proc.h,v 1.223 2002/02/18 23:11:36 petere Exp $ + * $Id: pg_proc.h,v 1.224 2002/03/29 19:06:19 tgl Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -2873,12 +2873,13 @@ DESCR("time zone"); /* - * prototypes for functions pg_proc.c + * prototypes for functions in pg_proc.c */ extern Oid ProcedureCreate(char *procedureName, + Oid procNamespace, bool replace, bool returnsSet, - char *returnTypeName, + Oid returnType, Oid languageObjectId, char *prosrc, char *probin, diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index d1d2c02f781..bd4bf0063a4 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_type.h,v 1.118 2002/03/20 19:44:57 tgl Exp $ + * $Id: pg_type.h,v 1.119 2002/03/29 19:06:20 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -38,8 +38,9 @@ */ CATALOG(pg_type) BOOTSTRAP { - NameData typname; - int4 typowner; + NameData typname; /* type name */ + Oid typnamespace; /* OID of namespace containing this type */ + int4 typowner; /* type owner */ /* * For a fixed-size type, typlen is the number of bytes we use to @@ -202,29 +203,30 @@ typedef FormData_pg_type *Form_pg_type; * compiler constants for pg_type * ---------------- */ -#define Natts_pg_type 22 +#define Natts_pg_type 23 #define Anum_pg_type_typname 1 -#define Anum_pg_type_typowner 2 -#define Anum_pg_type_typlen 3 -#define Anum_pg_type_typprtlen 4 -#define Anum_pg_type_typbyval 5 -#define Anum_pg_type_typtype 6 -#define Anum_pg_type_typisdefined 7 -#define Anum_pg_type_typdelim 8 -#define Anum_pg_type_typrelid 9 -#define Anum_pg_type_typelem 10 -#define Anum_pg_type_typinput 11 -#define Anum_pg_type_typoutput 12 -#define Anum_pg_type_typreceive 13 -#define Anum_pg_type_typsend 14 -#define Anum_pg_type_typalign 15 -#define Anum_pg_type_typstorage 16 -#define Anum_pg_type_typnotnull 17 -#define Anum_pg_type_typbasetype 18 -#define Anum_pg_type_typtypmod 19 -#define Anum_pg_type_typndims 20 -#define Anum_pg_type_typdefaultbin 21 -#define Anum_pg_type_typdefault 22 +#define Anum_pg_type_typnamespace 2 +#define Anum_pg_type_typowner 3 +#define Anum_pg_type_typlen 4 +#define Anum_pg_type_typprtlen 5 +#define Anum_pg_type_typbyval 6 +#define Anum_pg_type_typtype 7 +#define Anum_pg_type_typisdefined 8 +#define Anum_pg_type_typdelim 9 +#define Anum_pg_type_typrelid 10 +#define Anum_pg_type_typelem 11 +#define Anum_pg_type_typinput 12 +#define Anum_pg_type_typoutput 13 +#define Anum_pg_type_typreceive 14 +#define Anum_pg_type_typsend 15 +#define Anum_pg_type_typalign 16 +#define Anum_pg_type_typstorage 17 +#define Anum_pg_type_typnotnull 18 +#define Anum_pg_type_typbasetype 19 +#define Anum_pg_type_typtypmod 20 +#define Anum_pg_type_typndims 21 +#define Anum_pg_type_typdefaultbin 22 +#define Anum_pg_type_typdefault 23 /* ---------------- @@ -240,82 +242,82 @@ typedef FormData_pg_type *Form_pg_type; */ /* OIDS 1 - 99 */ -DATA(insert OID = 16 ( bool PGUID 1 1 t b t \054 0 0 boolin boolout boolin boolout c p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 16 ( bool PGNSP PGUID 1 1 t b t \054 0 0 boolin boolout boolin boolout c p f 0 -1 0 _null_ _null_ )); DESCR("boolean, 'true'/'false'"); #define BOOLOID 16 -DATA(insert OID = 17 ( bytea PGUID -1 -1 f b t \054 0 0 byteain byteaout byteain byteaout i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 17 ( bytea PGNSP PGUID -1 -1 f b t \054 0 0 byteain byteaout byteain byteaout i x f 0 -1 0 _null_ _null_ )); DESCR("variable-length string, binary values escaped"); #define BYTEAOID 17 -DATA(insert OID = 18 ( char PGUID 1 1 t b t \054 0 0 charin charout charin charout c p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 18 ( char PGNSP PGUID 1 1 t b t \054 0 0 charin charout charin charout c p f 0 -1 0 _null_ _null_ )); DESCR("single character"); #define CHAROID 18 -DATA(insert OID = 19 ( name PGUID NAMEDATALEN NAMEDATALEN f b t \054 0 18 namein nameout namein nameout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN NAMEDATALEN f b t \054 0 18 namein nameout namein nameout i p f 0 -1 0 _null_ _null_ )); DESCR("31-character type for storing system identifiers"); #define NAMEOID 19 -DATA(insert OID = 20 ( int8 PGUID 8 20 f b t \054 0 0 int8in int8out int8in int8out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 20 ( int8 PGNSP PGUID 8 20 f b t \054 0 0 int8in int8out int8in int8out d p f 0 -1 0 _null_ _null_ )); DESCR("~18 digit integer, 8-byte storage"); #define INT8OID 20 -DATA(insert OID = 21 ( int2 PGUID 2 5 t b t \054 0 0 int2in int2out int2in int2out s p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 21 ( int2 PGNSP PGUID 2 5 t b t \054 0 0 int2in int2out int2in int2out s p f 0 -1 0 _null_ _null_ )); DESCR("-32 thousand to 32 thousand, 2-byte storage"); #define INT2OID 21 -DATA(insert OID = 22 ( int2vector PGUID INDEX_MAX_KEYS*2 -1 f b t \054 0 21 int2vectorin int2vectorout int2vectorin int2vectorout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 22 ( int2vector PGNSP PGUID INDEX_MAX_KEYS*2 -1 f b t \054 0 21 int2vectorin int2vectorout int2vectorin int2vectorout i p f 0 -1 0 _null_ _null_ )); DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables"); #define INT2VECTOROID 22 -DATA(insert OID = 23 ( int4 PGUID 4 10 t b t \054 0 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 23 ( int4 PGNSP PGUID 4 10 t b t \054 0 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); DESCR("-2 billion to 2 billion integer, 4-byte storage"); #define INT4OID 23 -DATA(insert OID = 24 ( regproc PGUID 4 16 t b t \054 0 0 regprocin regprocout regprocin regprocout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 24 ( regproc PGNSP PGUID 4 16 t b t \054 0 0 regprocin regprocout regprocin regprocout i p f 0 -1 0 _null_ _null_ )); DESCR("registered procedure"); #define REGPROCOID 24 -DATA(insert OID = 25 ( text PGUID -1 -1 f b t \054 0 0 textin textout textin textout i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 25 ( text PGNSP PGUID -1 -1 f b t \054 0 0 textin textout textin textout i x f 0 -1 0 _null_ _null_ )); DESCR("variable-length string, no limit specified"); #define TEXTOID 25 -DATA(insert OID = 26 ( oid PGUID 4 10 t b t \054 0 0 oidin oidout oidin oidout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 26 ( oid PGNSP PGUID 4 10 t b t \054 0 0 oidin oidout oidin oidout i p f 0 -1 0 _null_ _null_ )); DESCR("object identifier(oid), maximum 4 billion"); #define OIDOID 26 -DATA(insert OID = 27 ( tid PGUID 6 19 f b t \054 0 0 tidin tidout tidin tidout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 27 ( tid PGNSP PGUID 6 19 f b t \054 0 0 tidin tidout tidin tidout i p f 0 -1 0 _null_ _null_ )); DESCR("(Block, offset), physical location of tuple"); #define TIDOID 27 -DATA(insert OID = 28 ( xid PGUID 4 12 t b t \054 0 0 xidin xidout xidin xidout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 28 ( xid PGNSP PGUID 4 12 t b t \054 0 0 xidin xidout xidin xidout i p f 0 -1 0 _null_ _null_ )); DESCR("transaction id"); #define XIDOID 28 -DATA(insert OID = 29 ( cid PGUID 4 10 t b t \054 0 0 cidin cidout cidin cidout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 29 ( cid PGNSP PGUID 4 10 t b t \054 0 0 cidin cidout cidin cidout i p f 0 -1 0 _null_ _null_ )); DESCR("command identifier type, sequence in transaction id"); #define CIDOID 29 -DATA(insert OID = 30 ( oidvector PGUID INDEX_MAX_KEYS*4 -1 f b t \054 0 26 oidvectorin oidvectorout oidvectorin oidvectorout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 30 ( oidvector PGNSP PGUID INDEX_MAX_KEYS*4 -1 f b t \054 0 26 oidvectorin oidvectorout oidvectorin oidvectorout i p f 0 -1 0 _null_ _null_ )); DESCR("array of INDEX_MAX_KEYS oids, used in system tables"); #define OIDVECTOROID 30 -DATA(insert OID = 32 ( SET PGUID -1 -1 f b t \054 0 0 textin textout textin textout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 32 ( SET PGNSP PGUID -1 -1 f b t \054 0 0 textin textout textin textout i p f 0 -1 0 _null_ _null_ )); DESCR("set of tuples"); -DATA(insert OID = 71 ( pg_type PGUID 4 4 t c t \054 1247 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 75 ( pg_attribute PGUID 4 4 t c t \054 1249 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 81 ( pg_proc PGUID 4 4 t c t \054 1255 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 83 ( pg_class PGUID 4 4 t c t \054 1259 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 86 ( pg_shadow PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 87 ( pg_group PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 88 ( pg_database PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 71 ( pg_type PGNSP PGUID 4 4 t c t \054 1247 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 75 ( pg_attribute PGNSP PGUID 4 4 t c t \054 1249 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 81 ( pg_proc PGNSP PGUID 4 4 t c t \054 1255 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 83 ( pg_class PGNSP PGUID 4 4 t c t \054 1259 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 86 ( pg_shadow PGNSP PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 87 ( pg_group PGNSP PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 88 ( pg_database PGNSP PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ )); /* OIDS 100 - 199 */ /* OIDS 200 - 299 */ -DATA(insert OID = 210 ( smgr PGUID 2 12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 210 ( smgr PGNSP PGUID 2 12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p f 0 -1 0 _null_ _null_ )); DESCR("storage manager"); /* OIDS 300 - 399 */ @@ -325,192 +327,194 @@ DESCR("storage manager"); /* OIDS 500 - 599 */ /* OIDS 600 - 699 */ -DATA(insert OID = 600 ( point PGUID 16 24 f b t \054 0 701 point_in point_out point_in point_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 600 ( point PGNSP PGUID 16 24 f b t \054 0 701 point_in point_out point_in point_out d p f 0 -1 0 _null_ _null_ )); DESCR("geometric point '(x, y)'"); #define POINTOID 600 -DATA(insert OID = 601 ( lseg PGUID 32 48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 601 ( lseg PGNSP PGUID 32 48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d p f 0 -1 0 _null_ _null_ )); DESCR("geometric line segment '(pt1,pt2)'"); #define LSEGOID 601 -DATA(insert OID = 602 ( path PGUID -1 -1 f b t \054 0 0 path_in path_out path_in path_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 602 ( path PGNSP PGUID -1 -1 f b t \054 0 0 path_in path_out path_in path_out d x f 0 -1 0 _null_ _null_ )); DESCR("geometric path '(pt1,...)'"); #define PATHOID 602 -DATA(insert OID = 603 ( box PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 603 ( box PGNSP PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d p f 0 -1 0 _null_ _null_ )); DESCR("geometric box '(lower left,upper right)'"); #define BOXOID 603 -DATA(insert OID = 604 ( polygon PGUID -1 -1 f b t \054 0 0 poly_in poly_out poly_in poly_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 604 ( polygon PGNSP PGUID -1 -1 f b t \054 0 0 poly_in poly_out poly_in poly_out d x f 0 -1 0 _null_ _null_ )); DESCR("geometric polygon '(pt1,...)'"); #define POLYGONOID 604 -DATA(insert OID = 628 ( line PGUID 32 48 f b t \054 0 701 line_in line_out line_in line_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 628 ( line PGNSP PGUID 32 48 f b t \054 0 701 line_in line_out line_in line_out d p f 0 -1 0 _null_ _null_ )); DESCR("geometric line '(pt1,pt2)'"); #define LINEOID 628 -DATA(insert OID = 629 ( _line PGUID -1 -1 f b t \054 0 628 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 629 ( _line PGNSP PGUID -1 -1 f b t \054 0 628 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); DESCR(""); /* OIDS 700 - 799 */ -DATA(insert OID = 700 ( float4 PGUID 4 12 f b t \054 0 0 float4in float4out float4in float4out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 700 ( float4 PGNSP PGUID 4 12 f b t \054 0 0 float4in float4out float4in float4out i p f 0 -1 0 _null_ _null_ )); DESCR("single-precision floating point number, 4-byte storage"); #define FLOAT4OID 700 -DATA(insert OID = 701 ( float8 PGUID 8 24 f b t \054 0 0 float8in float8out float8in float8out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 701 ( float8 PGNSP PGUID 8 24 f b t \054 0 0 float8in float8out float8in float8out d p f 0 -1 0 _null_ _null_ )); DESCR("double-precision floating point number, 8-byte storage"); #define FLOAT8OID 701 -DATA(insert OID = 702 ( abstime PGUID 4 20 t b t \054 0 0 nabstimein nabstimeout nabstimein nabstimeout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 702 ( abstime PGNSP PGUID 4 20 t b t \054 0 0 nabstimein nabstimeout nabstimein nabstimeout i p f 0 -1 0 _null_ _null_ )); DESCR("absolute, limited-range date and time (Unix system time)"); #define ABSTIMEOID 702 -DATA(insert OID = 703 ( reltime PGUID 4 20 t b t \054 0 0 reltimein reltimeout reltimein reltimeout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 703 ( reltime PGNSP PGUID 4 20 t b t \054 0 0 reltimein reltimeout reltimein reltimeout i p f 0 -1 0 _null_ _null_ )); DESCR("relative, limited-range time interval (Unix delta time)"); #define RELTIMEOID 703 -DATA(insert OID = 704 ( tinterval PGUID 12 47 f b t \054 0 0 tintervalin tintervalout tintervalin tintervalout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 47 f b t \054 0 0 tintervalin tintervalout tintervalin tintervalout i p f 0 -1 0 _null_ _null_ )); DESCR("(abstime,abstime), time interval"); #define TINTERVALOID 704 -DATA(insert OID = 705 ( unknown PGUID -1 -1 f b t \054 0 0 textin textout textin textout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 705 ( unknown PGNSP PGUID -1 -1 f b t \054 0 0 textin textout textin textout i p f 0 -1 0 _null_ _null_ )); DESCR(""); #define UNKNOWNOID 705 -DATA(insert OID = 718 ( circle PGUID 24 47 f b t \054 0 0 circle_in circle_out circle_in circle_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 718 ( circle PGNSP PGUID 24 47 f b t \054 0 0 circle_in circle_out circle_in circle_out d p f 0 -1 0 _null_ _null_ )); DESCR("geometric circle '(center,radius)'"); #define CIRCLEOID 718 -DATA(insert OID = 719 ( _circle PGUID -1 -1 f b t \054 0 718 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 790 ( money PGUID 4 24 f b t \054 0 0 cash_in cash_out cash_in cash_out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 719 ( _circle PGNSP PGUID -1 -1 f b t \054 0 718 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 790 ( money PGNSP PGUID 4 24 f b t \054 0 0 cash_in cash_out cash_in cash_out i p f 0 -1 0 _null_ _null_ )); DESCR("$d,ddd.cc, money"); #define CASHOID 790 -DATA(insert OID = 791 ( _money PGUID -1 -1 f b t \054 0 790 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 791 ( _money PGNSP PGUID -1 -1 f b t \054 0 790 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); /* OIDS 800 - 899 */ -DATA(insert OID = 829 ( macaddr PGUID 6 -1 f b t \054 0 0 macaddr_in macaddr_out macaddr_in macaddr_out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 -1 f b t \054 0 0 macaddr_in macaddr_out macaddr_in macaddr_out i p f 0 -1 0 _null_ _null_ )); DESCR("XX:XX:XX:XX:XX:XX, MAC address"); #define MACADDROID 829 -DATA(insert OID = 869 ( inet PGUID -1 -1 f b t \054 0 0 inet_in inet_out inet_in inet_out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 869 ( inet PGNSP PGUID -1 -1 f b t \054 0 0 inet_in inet_out inet_in inet_out i p f 0 -1 0 _null_ _null_ )); DESCR("IP address/netmask, host address, netmask optional"); #define INETOID 869 -DATA(insert OID = 650 ( cidr PGUID -1 -1 f b t \054 0 0 cidr_in cidr_out cidr_in cidr_out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 650 ( cidr PGNSP PGUID -1 -1 f b t \054 0 0 cidr_in cidr_out cidr_in cidr_out i p f 0 -1 0 _null_ _null_ )); DESCR("network IP address/netmask, network address"); #define CIDROID 650 /* OIDS 900 - 999 */ /* OIDS 1000 - 1099 */ -DATA(insert OID = 1000 ( _bool PGUID -1 -1 f b t \054 0 16 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1001 ( _bytea PGUID -1 -1 f b t \054 0 17 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1002 ( _char PGUID -1 -1 f b t \054 0 18 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1003 ( _name PGUID -1 -1 f b t \054 0 19 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1005 ( _int2 PGUID -1 -1 f b t \054 0 21 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1006 ( _int2vector PGUID -1 -1 f b t \054 0 22 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1007 ( _int4 PGUID -1 -1 f b t \054 0 23 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1008 ( _regproc PGUID -1 -1 f b t \054 0 24 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1009 ( _text PGUID -1 -1 f b t \054 0 25 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1028 ( _oid PGUID -1 -1 f b t \054 0 26 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1010 ( _tid PGUID -1 -1 f b t \054 0 27 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1011 ( _xid PGUID -1 -1 f b t \054 0 28 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1012 ( _cid PGUID -1 -1 f b t \054 0 29 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1013 ( _oidvector PGUID -1 -1 f b t \054 0 30 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1014 ( _bpchar PGUID -1 -1 f b t \054 0 1042 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1015 ( _varchar PGUID -1 -1 f b t \054 0 1043 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1016 ( _int8 PGUID -1 -1 f b t \054 0 20 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1017 ( _point PGUID -1 -1 f b t \054 0 600 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1018 ( _lseg PGUID -1 -1 f b t \054 0 601 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1019 ( _path PGUID -1 -1 f b t \054 0 602 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1020 ( _box PGUID -1 -1 f b t \073 0 603 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1021 ( _float4 PGUID -1 -1 f b t \054 0 700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1022 ( _float8 PGUID -1 -1 f b t \054 0 701 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1023 ( _abstime PGUID -1 -1 f b t \054 0 702 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1024 ( _reltime PGUID -1 -1 f b t \054 0 703 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1025 ( _tinterval PGUID -1 -1 f b t \054 0 704 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1027 ( _polygon PGUID -1 -1 f b t \054 0 604 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 -1 f b t \054 0 16 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 -1 f b t \054 0 17 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1002 ( _char PGNSP PGUID -1 -1 f b t \054 0 18 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1003 ( _name PGNSP PGUID -1 -1 f b t \054 0 19 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 -1 f b t \054 0 21 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 -1 f b t \054 0 22 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 -1 f b t \054 0 23 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 -1 f b t \054 0 24 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1009 ( _text PGNSP PGUID -1 -1 f b t \054 0 25 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 -1 f b t \054 0 26 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 -1 f b t \054 0 27 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 -1 f b t \054 0 28 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 -1 f b t \054 0 29 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 -1 f b t \054 0 30 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 -1 f b t \054 0 1042 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 -1 f b t \054 0 1043 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 -1 f b t \054 0 20 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1017 ( _point PGNSP PGUID -1 -1 f b t \054 0 600 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 -1 f b t \054 0 601 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1019 ( _path PGNSP PGUID -1 -1 f b t \054 0 602 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1020 ( _box PGNSP PGUID -1 -1 f b t \073 0 603 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 -1 f b t \054 0 700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1022 ( _float8 PGNSP PGUID -1 -1 f b t \054 0 701 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 -1 f b t \054 0 702 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 -1 f b t \054 0 703 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 -1 f b t \054 0 704 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 -1 f b t \054 0 604 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); /* * Note: the size of aclitem needs to match sizeof(AclItem) in acl.h. * Thanks to some padding, this will be 8 on all platforms. * We also have an Assert to make sure. */ #define ACLITEMSIZE 8 -DATA(insert OID = 1033 ( aclitem PGUID 8 -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1033 ( aclitem PGNSP PGUID 8 -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i p f 0 -1 0 _null_ _null_ )); DESCR("access control list"); -DATA(insert OID = 1034 ( _aclitem PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1040 ( _macaddr PGUID -1 -1 f b t \054 0 829 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1041 ( _inet PGUID -1 -1 f b t \054 0 869 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 651 ( _cidr PGUID -1 -1 f b t \054 0 650 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1042 ( bpchar PGUID -1 -1 f b t \054 0 0 bpcharin bpcharout bpcharin bpcharout i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 -1 f b t \054 0 829 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 -1 f b t \054 0 869 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 -1 f b t \054 0 650 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 -1 f b t \054 0 0 bpcharin bpcharout bpcharin bpcharout i x f 0 -1 0 _null_ _null_ )); DESCR("char(length), blank-padded string, fixed storage length"); #define BPCHAROID 1042 -DATA(insert OID = 1043 ( varchar PGUID -1 -1 f b t \054 0 0 varcharin varcharout varcharin varcharout i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 -1 f b t \054 0 0 varcharin varcharout varcharin varcharout i x f 0 -1 0 _null_ _null_ )); DESCR("varchar(length), non-blank-padded string, variable storage length"); #define VARCHAROID 1043 -DATA(insert OID = 1082 ( date PGUID 4 10 t b t \054 0 0 date_in date_out date_in date_out i p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1082 ( date PGNSP PGUID 4 10 t b t \054 0 0 date_in date_out date_in date_out i p f 0 -1 0 _null_ _null_ )); DESCR("ANSI SQL date"); #define DATEOID 1082 -DATA(insert OID = 1083 ( time PGUID 8 16 f b t \054 0 0 time_in time_out time_in time_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1083 ( time PGNSP PGUID 8 16 f b t \054 0 0 time_in time_out time_in time_out d p f 0 -1 0 _null_ _null_ )); DESCR("hh:mm:ss, ANSI SQL time"); #define TIMEOID 1083 /* OIDS 1100 - 1199 */ -DATA(insert OID = 1114 ( timestamp PGUID 8 47 f b t \054 0 0 timestamp_in timestamp_out timestamp_in timestamp_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 47 f b t \054 0 0 timestamp_in timestamp_out timestamp_in timestamp_out d p f 0 -1 0 _null_ _null_ )); DESCR("date and time"); #define TIMESTAMPOID 1114 -DATA(insert OID = 1115 ( _timestamp PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1182 ( _date PGUID -1 -1 f b t \054 0 1082 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1183 ( _time PGUID -1 -1 f b t \054 0 1083 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1184 ( timestamptz PGUID 8 47 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_in timestamptz_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1182 ( _date PGNSP PGUID -1 -1 f b t \054 0 1082 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1183 ( _time PGNSP PGUID -1 -1 f b t \054 0 1083 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 47 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_in timestamptz_out d p f 0 -1 0 _null_ _null_ )); DESCR("date and time with time zone"); #define TIMESTAMPTZOID 1184 -DATA(insert OID = 1185 ( _timestamptz PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1186 ( interval PGUID 12 47 f b t \054 0 0 interval_in interval_out interval_in interval_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1186 ( interval PGNSP PGUID 12 47 f b t \054 0 0 interval_in interval_out interval_in interval_out d p f 0 -1 0 _null_ _null_ )); DESCR("@ <number> <units>, time interval"); #define INTERVALOID 1186 -DATA(insert OID = 1187 ( _interval PGUID -1 -1 f b t \054 0 1186 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 -1 f b t \054 0 1186 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); /* OIDS 1200 - 1299 */ -DATA(insert OID = 1231 ( _numeric PGUID -1 -1 f b t \054 0 1700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1266 ( timetz PGUID 12 22 f b t \054 0 0 timetz_in timetz_out timetz_in timetz_out d p f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 -1 f b t \054 0 1700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 22 f b t \054 0 0 timetz_in timetz_out timetz_in timetz_out d p f 0 -1 0 _null_ _null_ )); DESCR("hh:mm:ss, ANSI SQL time"); #define TIMETZOID 1266 -DATA(insert OID = 1270 ( _timetz PGUID -1 -1 f b t \054 0 1266 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 -1 f b t \054 0 1266 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ )); /* OIDS 1500 - 1599 */ -DATA(insert OID = 1560 ( bit PGUID -1 -1 f b t \054 0 0 bit_in bit_out bit_in bit_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1560 ( bit PGNSP PGUID -1 -1 f b t \054 0 0 bit_in bit_out bit_in bit_out i x f 0 -1 0 _null_ _null_ )); DESCR("fixed-length bit string"); #define BITOID 1560 -DATA(insert OID = 1561 ( _bit PGUID -1 -1 f b t \054 0 1560 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); -DATA(insert OID = 1562 ( varbit PGUID -1 -1 f b t \054 0 0 varbit_in varbit_out varbit_in varbit_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 -1 f b t \054 0 1560 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 -1 f b t \054 0 0 varbit_in varbit_out varbit_in varbit_out i x f 0 -1 0 _null_ _null_ )); DESCR("variable-length bit string"); #define VARBITOID 1562 -DATA(insert OID = 1563 ( _varbit PGUID -1 -1 f b t \054 0 1562 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 -1 f b t \054 0 1562 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); /* OIDS 1600 - 1699 */ /* OIDS 1700 - 1799 */ -DATA(insert OID = 1700 ( numeric PGUID -1 -1 f b t \054 0 0 numeric_in numeric_out numeric_in numeric_out i m f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 -1 f b t \054 0 0 numeric_in numeric_out numeric_in numeric_out i m f 0 -1 0 _null_ _null_ )); DESCR("numeric(precision, decimal), arbitrary precision number"); #define NUMERICOID 1700 -/* OID 1790 */ -DATA(insert OID = 1790 ( refcursor PGUID -1 -1 f b t \054 0 0 textin textout textin textout i x f 0 -1 0 _null_ _null_ )); +DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 -1 f b t \054 0 0 textin textout textin textout i x f 0 -1 0 _null_ _null_ )); DESCR("reference cursor (portal name)"); #define REFCURSOROID 1790 +/* OIDS 2000 - 2099 */ +DATA(insert OID = 2019 ( _refcursor PGNSP PGUID -1 -1 f b t \054 0 1790 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ )); + /* * prototypes for functions in pg_type.c */ -extern Oid TypeGet(char *typeName, bool *defined); -extern Oid TypeShellMake(char *typeName); +extern Oid TypeShellMake(const char *typeName, Oid typeNamespace); -extern Oid TypeCreate(char *typeName, +extern Oid TypeCreate(const char *typeName, + Oid typeNamespace, Oid assignedTypeOid, Oid relationOid, int16 internalSize, int16 externalSize, char typeType, char typDelim, - char *inputProcedure, - char *outputProcedure, - char *receiveProcedure, - char *sendProcedure, - char *elementTypeName, - char *baseTypeName, - char *defaultTypeValue, - char *defaultTypeBin, + Oid inputProcedure, + Oid outputProcedure, + Oid receiveProcedure, + Oid sendProcedure, + Oid elementType, + Oid baseType, + const char *defaultTypeValue, + const char *defaultTypeBin, bool passedByValue, char alignment, char storage, @@ -519,7 +523,8 @@ extern Oid TypeCreate(char *typeName, bool typeNotNull); -extern void TypeRename(const char *oldTypeName, const char *newTypeName); -extern char *makeArrayTypeName(char *typeName); +extern void TypeRename(const char *oldTypeName, Oid typeNamespace, + const char *newTypeName); +extern char *makeArrayTypeName(const char *typeName); #endif /* PG_TYPE_H */ diff --git a/src/include/commands/command.h b/src/include/commands/command.h index 1601898b405..73c33ac3c7e 100644 --- a/src/include/commands/command.h +++ b/src/include/commands/command.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: command.h,v 1.35 2002/03/26 19:16:40 tgl Exp $ + * $Id: command.h,v 1.36 2002/03/29 19:06:21 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -40,31 +40,27 @@ extern void PortalCleanup(Portal portal); /* * ALTER TABLE variants */ -extern void AlterTableAddColumn(const char *relationName, - bool inh, ColumnDef *colDef); +extern void AlterTableAddColumn(Oid myrelid, bool inherits, ColumnDef *colDef); -extern void AlterTableAlterColumnDefault(const char *relationName, - bool inh, const char *colName, - Node *newDefault); +extern void AlterTableAlterColumnDefault(Oid myrelid, bool inh, + const char *colName, Node *newDefault); -extern void AlterTableAlterColumnFlags(const char *relationName, - bool inh, const char *colName, - Node *flagValue, const char *flagType); +extern void AlterTableAlterColumnFlags(Oid myrelid, + bool inh, const char *colName, + Node *flagValue, const char *flagType); -extern void AlterTableDropColumn(const char *relationName, - bool inh, const char *colName, - int behavior); +extern void AlterTableDropColumn(Oid myrelid, bool inh, + const char *colName, int behavior); -extern void AlterTableAddConstraint(char *relationName, - bool inh, List *newConstraints); +extern void AlterTableAddConstraint(Oid myrelid, + bool inh, List *newConstraints); -extern void AlterTableDropConstraint(const char *relationName, - bool inh, const char *constrName, - int behavior); +extern void AlterTableDropConstraint(Oid myrelid, + bool inh, const char *constrName, int behavior); extern void AlterTableCreateToastTable(Oid relOid, bool silent); -extern void AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName); +extern void AlterTableOwner(Oid relationOid, int32 newOwnerSysId); /* * LOCK diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h index 555c5c4d5c8..e0a4ecdcd40 100644 --- a/src/include/commands/copy.h +++ b/src/include/commands/copy.h @@ -7,16 +7,19 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: copy.h,v 1.16 2001/11/05 17:46:33 momjian Exp $ + * $Id: copy.h,v 1.17 2002/03/29 19:06:21 tgl Exp $ * *------------------------------------------------------------------------- */ #ifndef COPY_H #define COPY_H +#include "nodes/primnodes.h" + extern int copy_lineno; -void DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, - char *filename, char *delim, char *null_print); +void DoCopy(const RangeVar *relation, bool binary, bool oids, + bool from, bool pipe, + char *filename, char *delim, char *null_print); #endif /* COPY_H */ diff --git a/src/include/commands/creatinh.h b/src/include/commands/creatinh.h index 90f5df63d33..fe0f2bc3512 100644 --- a/src/include/commands/creatinh.h +++ b/src/include/commands/creatinh.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: creatinh.h,v 1.19 2002/03/22 02:56:36 tgl Exp $ + * $Id: creatinh.h,v 1.20 2002/03/29 19:06:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,7 +17,7 @@ #include "nodes/parsenodes.h" extern Oid DefineRelation(CreateStmt *stmt, char relkind); -extern void RemoveRelation(const char *name); -extern void TruncateRelation(const char *name); +extern void RemoveRelation(const RangeVar *relation); +extern void TruncateRelation(const RangeVar *relation); #endif /* CREATINH_H */ diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 97924979c28..69f180ec162 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: defrem.h,v 1.32 2002/03/26 19:16:47 tgl Exp $ + * $Id: defrem.h,v 1.33 2002/03/29 19:06:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,19 +36,19 @@ extern void ReindexDatabase(const char *databaseName, bool force, bool all); * prototypes in define.c */ extern void CreateFunction(ProcedureStmt *stmt); -extern void DefineOperator(char *name, List *parameters); -extern void DefineAggregate(char *name, List *parameters); -extern void DefineType(char *name, List *parameters); +extern void DefineOperator(List *names, List *parameters); +extern void DefineAggregate(List *names, List *parameters); +extern void DefineType(List *names, List *parameters); extern void DefineDomain(CreateDomainStmt *stmt); /* * prototypes in remove.c */ -extern void RemoveDomain(char *domainName, int behavior); +extern void RemoveDomain(List *names, int behavior); extern void RemoveFunction(char *functionName, List *argTypes); extern void RemoveOperator(char *operatorName, - char *typeName1, char *typeName2); -extern void RemoveType(char *typeName); -extern void RemoveAggregate(char *aggName, char *aggType); + TypeName *typeName1, TypeName *typeName2); +extern void RemoveType(List *names); +extern void RemoveAggregate(char *aggName, TypeName *aggType); #endif /* DEFREM_H */ diff --git a/src/include/commands/rename.h b/src/include/commands/rename.h index 7bfd0479167..28aebc01d91 100644 --- a/src/include/commands/rename.h +++ b/src/include/commands/rename.h @@ -7,17 +7,17 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: rename.h,v 1.14 2002/03/26 19:16:49 tgl Exp $ + * $Id: rename.h,v 1.15 2002/03/29 19:06:22 tgl Exp $ * *------------------------------------------------------------------------- */ #ifndef RENAME_H #define RENAME_H -extern void renameatt(char *relname, +extern void renameatt(Oid relid, char *oldattname, char *newattname, - int recurse); + bool recurse); extern void renamerel(const RangeVar *relation, const char *newrelname); diff --git a/src/include/commands/view.h b/src/include/commands/view.h index de6fdcee97f..f021cb24fd6 100644 --- a/src/include/commands/view.h +++ b/src/include/commands/view.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: view.h,v 1.13 2001/11/05 17:46:33 momjian Exp $ + * $Id: view.h,v 1.14 2002/03/29 19:06:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,7 +16,7 @@ #include "nodes/parsenodes.h" -extern void DefineView(char *view_name, Query *view_parse); -extern void RemoveView(char *view_name); +extern void DefineView(const RangeVar *view, Query *view_parse); +extern void RemoveView(const RangeVar *view); #endif /* VIEW_H */ diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index 52c224b18f9..905f803891a 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: makefuncs.h,v 1.33 2002/03/22 02:56:36 tgl Exp $ + * $Id: makefuncs.h,v 1.34 2002/03/29 19:06:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -50,4 +50,6 @@ extern RelabelType *makeRelabelType(Node *arg, Oid rtype, int32 rtypmod); extern RangeVar *makeRangeVar(char *schemaname, char *relname); +extern TypeName *makeTypeName(char *typnam); + #endif /* MAKEFUNC_H */ diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index e66e7b8b646..4e08940f7b5 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.165 2002/03/26 19:16:53 tgl Exp $ + * $Id: parsenodes.h,v 1.166 2002/03/29 19:06:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -104,16 +104,25 @@ typedef struct Query /* * TypeName - specifies a type in definitions + * + * For TypeName structures generated internally, it is often easier to + * specify the type by OID than by name. If "names" is NIL then the + * actual type OID is given by typeid, otherwise typeid is unused. + * + * If pct_type is TRUE, then names is actually a field name and we look up + * the type of that field. Otherwise (the normal case), names is a type + * name possibly qualified with schema and database name. */ typedef struct TypeName { NodeTag type; - char *name; /* name of the type */ + List *names; /* qualified name (list of Value strings) */ + Oid typeid; /* type identified by OID */ bool timezone; /* timezone specified? */ bool setof; /* is a set? */ + bool pct_type; /* %TYPE specified? */ int32 typmod; /* type modifier */ List *arrayBounds; /* array bounds */ - char *attrname; /* field name when using %TYPE */ } TypeName; /* @@ -1023,7 +1032,7 @@ typedef struct DefineStmt { NodeTag type; int defType; /* OPERATOR|TYPE_P|AGGREGATE */ - char *defname; + List *defnames; /* qualified name (list of Value strings) */ List *definition; /* a list of DefElem */ } DefineStmt; @@ -1034,9 +1043,9 @@ typedef struct DefineStmt typedef struct CreateDomainStmt { NodeTag type; - char *domainname; /* name of domain to create */ - TypeName *typename; /* the base type */ - List *constraints; /* constraints (list of Constraint nodes) */ + List *domainname; /* qualified name (list of Value strings) */ + TypeName *typename; /* the base type */ + List *constraints; /* constraints (list of Constraint nodes) */ } CreateDomainStmt; /* ---------------------- @@ -1055,7 +1064,7 @@ typedef struct CreateDomainStmt typedef struct DropStmt { NodeTag type; - List *objects; + List *objects; /* list of sublists of names (as Values) */ int removeType; int behavior; /* CASCADE or RESTRICT drop behavior */ } DropStmt; @@ -1135,9 +1144,9 @@ typedef struct ProcedureStmt { NodeTag type; bool replace; /* T => replace if already exists */ - char *funcname; /* name of function to create */ + List *funcname; /* name of function to create */ List *argTypes; /* list of argument types (TypeName nodes) */ - Node *returnType; /* the return type (a TypeName node) */ + TypeName *returnType; /* the return type */ List *withClause; /* a list of DefElem */ List *as; /* definition of function body */ char *language; /* C, SQL, etc */ @@ -1151,7 +1160,7 @@ typedef struct RemoveAggrStmt { NodeTag type; char *aggname; /* aggregate to drop */ - Node *aggtype; /* TypeName for input datatype, or NULL */ + TypeName *aggtype; /* TypeName for input datatype, or NULL */ } RemoveAggrStmt; /* ---------------------- diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h index e330f8c249a..1f05a7c0d5c 100644 --- a/src/include/parser/parse_expr.h +++ b/src/include/parser/parse_expr.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parse_expr.h,v 1.26 2002/03/21 16:01:59 tgl Exp $ + * $Id: parse_expr.h,v 1.27 2002/03/29 19:06:24 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,6 +26,5 @@ extern Oid exprType(Node *expr); extern int32 exprTypmod(Node *expr); extern bool exprIsLengthCoercion(Node *expr, int32 *coercedTypmod); extern void parse_expr_init(void); -extern char *TypeNameToInternalName(TypeName *typename); #endif /* PARSE_EXPR_H */ diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h index 603ea9369c6..01e5b16e2b5 100644 --- a/src/include/parser/parse_func.h +++ b/src/include/parser/parse_func.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parse_func.h,v 1.36 2002/03/21 16:02:01 tgl Exp $ + * $Id: parse_func.h,v 1.37 2002/03/29 19:06:24 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -58,7 +58,8 @@ extern FuncDetailCode func_get_detail(char *funcname, List *fargs, extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId); -extern void func_error(char *caller, char *funcname, - int nargs, Oid *argtypes, char *msg); +extern void func_error(const char *caller, const char *funcname, + int nargs, const Oid *argtypes, + const char *msg); #endif /* PARSE_FUNC_H */ diff --git a/src/include/parser/parse_type.h b/src/include/parser/parse_type.h index 3d46601e980..d883a2b3316 100644 --- a/src/include/parser/parse_type.h +++ b/src/include/parser/parse_type.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parse_type.h,v 1.20 2001/11/05 17:46:35 momjian Exp $ + * $Id: parse_type.h,v 1.21 2002/03/29 19:06:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -15,12 +15,18 @@ #define PARSE_TYPE_H #include "access/htup.h" +#include "parser/parse_node.h" + typedef HeapTuple Type; +extern Oid LookupTypeName(const TypeName *typename); +extern char *TypeNameToString(const TypeName *typename); +extern Oid typenameTypeId(const TypeName *typename); +extern Type typenameType(const TypeName *typename); + extern bool typeidIsValid(Oid id); extern Type typeidType(Oid id); -extern Type typenameType(char *s); extern Oid typeTypeId(Type tp); extern int16 typeLen(Type t); @@ -32,7 +38,6 @@ extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod); extern char *typeidTypeName(Oid id); extern Oid typeidTypeRelid(Oid type_id); -extern Oid typenameTypeId(char *s); extern void parseTypeString(const char *str, Oid *type_id, int32 *typmod); diff --git a/src/include/rewrite/rewriteRemove.h b/src/include/rewrite/rewriteRemove.h index ccfc2dbb12b..ac79e6c919b 100644 --- a/src/include/rewrite/rewriteRemove.h +++ b/src/include/rewrite/rewriteRemove.h @@ -7,14 +7,14 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: rewriteRemove.h,v 1.11 2002/03/21 23:27:24 tgl Exp $ + * $Id: rewriteRemove.h,v 1.12 2002/03/29 19:06:26 tgl Exp $ * *------------------------------------------------------------------------- */ #ifndef REWRITEREMOVE_H #define REWRITEREMOVE_H -extern void RemoveRewriteRule(char *ruleName); +extern void RemoveRewriteRule(List *names); extern void RelationRemoveRules(Oid relid); #endif /* REWRITEREMOVE_H */ diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index a18ed521074..90130178ca1 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: lsyscache.h,v 1.46 2002/03/26 19:16:57 tgl Exp $ + * $Id: lsyscache.h,v 1.47 2002/03/29 19:06:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -42,6 +42,7 @@ extern bool func_iscachable(Oid funcid); extern Oid get_relname_relid(const char *relname, Oid relnamespace); extern char *get_rel_name(Oid relid); extern Oid get_rel_type_id(Oid relid); +extern bool get_typisdefined(Oid typid); extern int16 get_typlen(Oid typid); extern bool get_typbyval(Oid typid); extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval); diff --git a/src/include/utils/sets.h b/src/include/utils/sets.h index cf4ebd2b150..4a134c9ce55 100644 --- a/src/include/utils/sets.h +++ b/src/include/utils/sets.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: sets.h,v 1.12 2001/11/05 17:46:36 momjian Exp $ + * $Id: sets.h,v 1.13 2002/03/29 19:06:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,7 +20,7 @@ /* Temporary name of a set function, before SetDefine changes it. */ #define GENERICSETNAME "ZYX#Set#ZYX" -extern Oid SetDefine(char *querystr, char *typename); +extern Oid SetDefine(char *querystr, Oid elemType); extern Datum seteval(PG_FUNCTION_ARGS); diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index 49af9690758..d08dfadda49 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: syscache.h,v 1.40 2002/03/26 19:16:59 tgl Exp $ + * $Id: syscache.h,v 1.41 2002/03/29 19:06:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -57,7 +57,7 @@ #define SHADOWNAME 26 #define SHADOWSYSID 27 #define STATRELATT 28 -#define TYPENAME 29 +#define TYPENAMENSP 29 #define TYPEOID 30 diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 44c5146eb63..b648c163369 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.39 2002/03/26 19:17:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.40 2002/03/29 19:06:27 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -47,14 +47,15 @@ #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/namespace.h" -#include "catalog/pg_proc.h" -#include "catalog/pg_type.h" -#include "catalog/pg_class.h" #include "catalog/pg_attribute.h" #include "catalog/pg_attrdef.h" +#include "catalog/pg_class.h" +#include "catalog/pg_proc.h" +#include "catalog/pg_type.h" #include "commands/trigger.h" #include "executor/spi.h" #include "fmgr.h" +#include "nodes/makefuncs.h" #include "parser/gramparse.h" #include "parser/parse_type.h" #include "tcop/tcopprot.h" @@ -851,10 +852,8 @@ plpgsql_parse_wordtype(char *word) { PLpgSQL_nsitem *nse; char *cp; - HeapTuple typeTup; - Form_pg_type typeStruct; - char *typeXlated; bool old_nsstate; + Oid typeOid; /* * We do our lookups case insensitive @@ -887,39 +886,46 @@ plpgsql_parse_wordtype(char *word) /* * Word wasn't found on the namestack. Try to find a data type with * that name, but ignore pg_type entries that are in fact class types. + * + * XXX this should be improved to handle qualified-type-name references. */ - typeXlated = xlateSqlType(cp); - typeTup = SearchSysCache(TYPENAME, - PointerGetDatum(typeXlated), - 0, 0, 0); - if (HeapTupleIsValid(typeTup)) + typeOid = LookupTypeName(makeTypeName(xlateSqlType(cp))); + if (OidIsValid(typeOid)) { - PLpgSQL_type *typ; + HeapTuple typeTup; - typeStruct = (Form_pg_type) GETSTRUCT(typeTup); - - if (typeStruct->typrelid != InvalidOid) + typeTup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(typeOid), + 0, 0, 0); + if (HeapTupleIsValid(typeTup)) { - ReleaseSysCache(typeTup); - pfree(cp); - return T_ERROR; - } + Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup); + PLpgSQL_type *typ; + + if (!typeStruct->typisdefined || + typeStruct->typrelid != InvalidOid) + { + ReleaseSysCache(typeTup); + pfree(cp); + return T_ERROR; + } - typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type)); + typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type)); - typ->typname = strdup(NameStr(typeStruct->typname)); - typ->typoid = typeTup->t_data->t_oid; - perm_fmgr_info(typeStruct->typinput, &(typ->typinput)); - typ->typelem = typeStruct->typelem; - typ->typbyval = typeStruct->typbyval; - typ->typlen = typeStruct->typlen; - typ->atttypmod = -1; + typ->typname = strdup(NameStr(typeStruct->typname)); + typ->typoid = typeOid; + perm_fmgr_info(typeStruct->typinput, &(typ->typinput)); + typ->typelem = typeStruct->typelem; + typ->typbyval = typeStruct->typbyval; + typ->typlen = typeStruct->typlen; + typ->atttypmod = -1; - plpgsql_yylval.dtype = typ; + plpgsql_yylval.dtype = typ; - ReleaseSysCache(typeTup); - pfree(cp); - return T_DTYPE; + ReleaseSysCache(typeTup); + pfree(cp); + return T_DTYPE; + } } /* diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index e56f9254cff..9821f75335b 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -29,7 +29,7 @@ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.16 2002/03/06 18:50:32 momjian Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.17 2002/03/29 19:06:27 tgl Exp $ * ********************************************************************* */ @@ -49,16 +49,16 @@ /* postgreSQL stuff */ -#include "executor/spi.h" +#include "access/heapam.h" +#include "catalog/pg_proc.h" +#include "catalog/pg_type.h" #include "commands/trigger.h" -#include "utils/elog.h" +#include "executor/spi.h" #include "fmgr.h" -#include "access/heapam.h" - +#include "nodes/makefuncs.h" +#include "parser/parse_type.h" #include "tcop/tcopprot.h" #include "utils/syscache.h" -#include "catalog/pg_proc.h" -#include "catalog/pg_type.h" #include <Python.h> #include "plpython.h" @@ -2086,16 +2086,8 @@ PLy_spi_prepare(PyObject * self, PyObject * args) RAISE_EXC(1); } sptr = PyString_AsString(optr); - typeTup = SearchSysCache(TYPENAME, PointerGetDatum(sptr), - 0, 0, 0); - if (!HeapTupleIsValid(typeTup)) - { - PLy_exception_set(PLy_exc_spi_error, - "Cache lookup for type `%s' failed.", - sptr); - RAISE_EXC(1); - } - + /* XXX should extend this to allow qualified type names */ + typeTup = typenameType(makeTypeName(sptr)); Py_DECREF(optr); optr = NULL; /* this is important */ diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 34bc731e9ab..3335e8ed176 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -31,7 +31,7 @@ * ENHANCEMENTS, OR MODIFICATIONS. * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.52 2002/03/06 18:50:33 momjian Exp $ + * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.53 2002/03/29 19:06:28 tgl Exp $ * **********************************************************************/ @@ -47,17 +47,18 @@ #include <string.h> #include <setjmp.h> -#include "executor/spi.h" +#include "access/heapam.h" +#include "catalog/pg_language.h" +#include "catalog/pg_proc.h" +#include "catalog/pg_type.h" #include "commands/trigger.h" -#include "utils/builtins.h" +#include "executor/spi.h" #include "fmgr.h" -#include "access/heapam.h" - +#include "nodes/makefuncs.h" +#include "parser/parse_type.h" #include "tcop/tcopprot.h" +#include "utils/builtins.h" #include "utils/syscache.h" -#include "catalog/pg_proc.h" -#include "catalog/pg_language.h" -#include "catalog/pg_type.h" #if defined(UNICODE_CONVERSION) && TCL_MAJOR_VERSION == 8 \ && TCL_MINOR_VERSION > 0 @@ -1750,11 +1751,8 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, ************************************************************/ for (i = 0; i < nargs; i++) { - typeTup = SearchSysCache(TYPENAME, - PointerGetDatum(args[i]), - 0, 0, 0); - if (!HeapTupleIsValid(typeTup)) - elog(ERROR, "pltcl: Cache lookup of type %s failed", args[i]); + /* XXX should extend this to allow qualified type names */ + typeTup = typenameType(makeTypeName(args[i])); qdesc->argtypes[i] = typeTup->t_data->t_oid; perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput, &(qdesc->arginfuncs[i])); diff --git a/src/test/regress/expected/errors.out b/src/test/regress/expected/errors.out index bd9707c2bdb..56c8939c6f0 100644 --- a/src/test/regress/expected/errors.out +++ b/src/test/regress/expected/errors.out @@ -137,7 +137,7 @@ drop aggregate 314159 (int); ERROR: parser: parse error at or near "314159" -- bad aggregate type drop aggregate newcnt (nonesuch); -ERROR: RemoveAggregate: type 'nonesuch' does not exist +ERROR: Type "nonesuch" does not exist -- no such aggregate drop aggregate nonesuch (int4); ERROR: RemoveAggregate: aggregate 'nonesuch' for type integer does not exist @@ -167,7 +167,7 @@ drop type 314159; ERROR: parser: parse error at or near "314159" -- no such type drop type nonesuch; -ERROR: RemoveType: type 'nonesuch' does not exist +ERROR: Type "nonesuch" does not exist -- -- DROP OPERATOR @@ -203,10 +203,10 @@ drop operator = ( , int4); ERROR: parser: parse error at or near "," -- no such type1 drop operator = (nonesuch, int4); -ERROR: RemoveOperator: type 'nonesuch' does not exist +ERROR: Type "nonesuch" does not exist -- no such type2 drop operator = (int4, nonesuch); -ERROR: RemoveOperator: type 'nonesuch' does not exist +ERROR: Type "nonesuch" does not exist -- no such type2 drop operator = (int4, ); ERROR: parser: parse error at or near ")" diff --git a/src/test/regress/output/create_function_2.source b/src/test/regress/output/create_function_2.source index 137242da705..4d508497cf6 100644 --- a/src/test/regress/output/create_function_2.source +++ b/src/test/regress/output/create_function_2.source @@ -13,8 +13,8 @@ CREATE FUNCTION hobbies_by_name(hobbies_r.name%TYPE) RETURNS hobbies_r.person%TYPE AS 'select person from hobbies_r where name = $1' LANGUAGE 'sql'; -NOTICE: hobbies_r.name%TYPE converted to text NOTICE: hobbies_r.person%TYPE converted to text +NOTICE: hobbies_r.name%TYPE converted to text CREATE FUNCTION equipment(hobbies_r) RETURNS setof equipment_r AS 'select * from equipment_r where hobby = $1.name' |