1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-05 23:56:58 +03:00

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.
This commit is contained in:
Tom Lane 2002-03-29 19:06:29 +00:00
parent 7c1ff35410
commit d5e99ab4d6
68 changed files with 2074 additions and 2266 deletions

View File

@ -1,6 +1,6 @@
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers 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"> <chapter id="catalogs">
@ -2363,6 +2363,15 @@
<entry>Data type name</entry> <entry>Data type name</entry>
</row> </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> <row>
<entry>typowner</entry> <entry>typowner</entry>
<entry><type>int4</type></entry> <entry><type>int4</type></entry>

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be * some of the executor utility code such as "ExecTypeFromTL" should be
@ -322,7 +322,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
* a preallocated tuple descriptor. * a preallocated tuple descriptor.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
bool void
TupleDescInitEntry(TupleDesc desc, TupleDescInitEntry(TupleDesc desc,
AttrNumber attributeNumber, AttrNumber attributeNumber,
char *attributeName, char *attributeName,
@ -377,39 +377,11 @@ TupleDescInitEntry(TupleDesc desc,
att->attnotnull = false; att->attnotnull = false;
att->atthasdef = 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, tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(oidtypeid), ObjectIdGetDatum(oidtypeid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ elog(ERROR, "Unable to look up type id %u", oidtypeid);
/*
* 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;
}
/* /*
* type info exists so we initialize our attribute information from * type info exists so we initialize our attribute information from
@ -477,56 +449,16 @@ TupleDescInitEntry(TupleDesc desc,
} }
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
return true;
} }
/* ---------------------------------------------------------------- /*
* TupleDescMakeSelfReference * BuildDescForRelation
* *
* This function initializes a "self-referential" attribute like * Given a relation schema (list of ColumnDef nodes), build a TupleDesc.
* 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().
* ----------------------------------------------------------------
*/ */
TupleDesc TupleDesc
BuildDescForRelation(List *schema, char *relname) BuildDescForRelation(List *schema)
{ {
int natts; int natts;
AttrNumber attnum; AttrNumber attnum;
@ -535,7 +467,6 @@ BuildDescForRelation(List *schema, char *relname)
AttrDefault *attrdef = NULL; AttrDefault *attrdef = NULL;
TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr)); TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
char *attname; char *attname;
char typename[NAMEDATALEN];
int32 atttypmod; int32 atttypmod;
int attdim; int attdim;
int ndef = 0; int ndef = 0;
@ -553,7 +484,6 @@ BuildDescForRelation(List *schema, char *relname)
foreach(p, schema) foreach(p, schema)
{ {
ColumnDef *entry = lfirst(p); ColumnDef *entry = lfirst(p);
List *arry;
/* /*
* for each entry in the list, get the name and type information * for each entry in the list, get the name and type information
@ -563,39 +493,13 @@ BuildDescForRelation(List *schema, char *relname)
attnum++; attnum++;
attname = entry->colname; attname = entry->colname;
arry = entry->typename->arrayBounds;
attisset = entry->typename->setof; attisset = entry->typename->setof;
atttypmod = entry->typename->typmod; atttypmod = entry->typename->typmod;
attdim = length(entry->typename->arrayBounds);
if (arry != NIL) TupleDescInitEntry(desc, attnum, attname,
{ typenameTypeId(entry->typename),
/* array of XXX is _XXX */ atttypmod, attdim, attisset);
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);
}
/* This is for constraints */ /* This is for constraints */
if (entry->is_not_null) if (entry->is_not_null)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* See acl.h. * See acl.h.
@ -37,6 +37,7 @@
#include "parser/parse_agg.h" #include "parser/parse_agg.h"
#include "parser/parse_func.h" #include "parser/parse_func.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_type.h"
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "utils/temprel.h" #include "utils/temprel.h"
@ -300,20 +301,19 @@ find_function_with_arglist(char *name, List *arguments)
for (i = 0; i < argcount; i++) for (i = 0; i < argcount; i++)
{ {
TypeName *t = (TypeName *) lfirst(arguments); TypeName *t = (TypeName *) lfirst(arguments);
char *typnam = TypeNameToInternalName(t);
argoids[i] = LookupTypeName(t);
if (!OidIsValid(argoids[i]))
{
char *typnam = TypeNameToString(t);
if (strcmp(typnam, "opaque") == 0)
argoids[i] = InvalidOid;
else
elog(ERROR, "Type \"%s\" does not exist", typnam);
}
arguments = lnext(arguments); arguments = lnext(arguments);
if (strcmp(typnam, "opaque") == 0)
argoids[i] = InvalidOid;
else
{
argoids[i] = GetSysCacheOid(TYPENAME,
PointerGetDatum(typnam),
0, 0, 0);
if (!OidIsValid(argoids[i]))
elog(ERROR, "type '%s' not found", typnam);
}
} }
oid = GetSysCacheOid(PROCNAME, oid = GetSysCacheOid(PROCNAME,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
@ -74,8 +74,10 @@ static void DeleteRelationTuple(Relation rel);
static void DeleteTypeTuple(Relation rel); static void DeleteTypeTuple(Relation rel);
static void RelationRemoveIndexes(Relation relation); static void RelationRemoveIndexes(Relation relation);
static void RelationRemoveInheritance(Relation relation); static void RelationRemoveInheritance(Relation relation);
static void AddNewRelationType(char *typeName, Oid new_rel_oid, static void AddNewRelationType(const char *typeName,
Oid new_type_oid); Oid typeNamespace,
Oid new_rel_oid,
Oid new_type_oid);
static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin); static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin);
static void StoreRelCheck(Relation rel, char *ccname, char *ccbin); static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
static void StoreConstraints(Relation rel, TupleDesc tupdesc); 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 * have to take special care for those rels that should be nailed
* in cache and/or are shared across databases. * in cache and/or are shared across databases.
*/ */
if (relname && relnamespace == PG_CATALOG_NAMESPACE) if (relnamespace == PG_CATALOG_NAMESPACE)
{ {
if (strcmp(TypeRelationName, relname) == 0) if (strcmp(TypeRelationName, relname) == 0)
{ {
@ -622,7 +624,10 @@ AddNewRelationTuple(Relation pg_class_desc,
* -------------------------------- * --------------------------------
*/ */
static void 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 * 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. * true makes sets much easier, and it isn't used by anything else.
*/ */
TypeCreate(typeName, /* type name */ TypeCreate(typeName, /* type name */
typeNamespace, /* type namespace */
new_type_oid, /* preassigned oid for type */ new_type_oid, /* preassigned oid for type */
new_rel_oid, /* relation oid */ new_rel_oid, /* relation oid */
sizeof(Oid), /* internal size */ sizeof(Oid), /* internal size */
-1, /* external size */ -1, /* external size */
'c', /* type-type (catalog) */ 'c', /* type-type (complex) */
',', /* default array delimiter */ ',', /* default array delimiter */
"oidin", /* input procedure */ F_OIDIN, /* input procedure */
"oidout", /* output procedure */ F_OIDOUT, /* output procedure */
"oidin", /* receive procedure */ F_OIDIN, /* receive procedure */
"oidout", /* send procedure */ F_OIDOUT, /* send procedure */
NULL, /* array element type - irrelevant */ InvalidOid, /* array element type - irrelevant */
NULL, /* baseType Name -- typically for domains */ InvalidOid, /* domain base type - irrelevant */
NULL, /* default type value - none */ NULL, /* default type value - none */
NULL, /* default type binary representation */ NULL, /* default type binary representation */
true, /* passed by value */ 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 * NOTE: we could get a unique-index failure here, in case the same name
* has already been used for a type. * 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 * now add tuples to pg_attribute for the attributes in our new
@ -1002,15 +1008,13 @@ RelationTruncateIndexes(Oid heapId)
*/ */
void void
heap_truncate(const char *relname) heap_truncate(Oid rid)
{ {
Relation rel; Relation rel;
Oid rid;
/* Open relation for processing, and grab exclusive access on it. */ /* Open relation for processing, and grab exclusive access on it. */
rel = heap_openr(relname, AccessExclusiveLock); rel = heap_open(rid, AccessExclusiveLock);
rid = RelationGetRelid(rel);
/* /*
* TRUNCATE TABLE within a transaction block is dangerous, because if * TRUNCATE TABLE within a transaction block is dangerous, because if
@ -1217,21 +1221,22 @@ DeleteTypeTuple(Relation rel)
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
void void
heap_drop_with_catalog(const char *relname, heap_drop_with_catalog(Oid rid,
bool allow_system_table_mods) bool allow_system_table_mods)
{ {
Relation rel; Relation rel;
Oid rid; Oid toasttableOid;
bool has_toasttable; bool has_toasttable;
bool istemp = is_temp_rel_name(relname); bool istemp;
int i; int i;
/* /*
* Open and lock the relation. * Open and lock the relation.
*/ */
rel = heap_openr(relname, AccessExclusiveLock); rel = heap_open(rid, AccessExclusiveLock);
rid = RelationGetRelid(rel);
has_toasttable = rel->rd_rel->reltoastrelid != InvalidOid; has_toasttable = rel->rd_rel->reltoastrelid != InvalidOid;
toasttableOid = rel->rd_rel->reltoastrelid;
istemp = is_temp_rel_name(RelationGetRelationName(rel));
/* /*
* prevent deletion of system relations * prevent deletion of system relations
@ -1319,12 +1324,7 @@ heap_drop_with_catalog(const char *relname,
remove_temp_rel_by_relid(rid); remove_temp_rel_by_relid(rid);
if (has_toasttable) if (has_toasttable)
{ heap_drop_with_catalog(toasttableOid, true);
char toast_relname[NAMEDATALEN];
sprintf(toast_relname, "pg_toast_%u", rid);
heap_drop_with_catalog(toast_relname, true);
}
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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] = char *Name_pg_trigger_indices[Num_pg_trigger_indices] =
{TriggerRelidIndex, TriggerConstrNameIndex, TriggerConstrRelidIndex, TriggerOidIndex}; {TriggerRelidIndex, TriggerConstrNameIndex, TriggerConstrRelidIndex, TriggerOidIndex};
char *Name_pg_type_indices[Num_pg_type_indices] = char *Name_pg_type_indices[Num_pg_type_indices] =
{TypeNameIndex, TypeOidIndex}; {TypeNameNspIndex, TypeOidIndex};
char *Name_pg_description_indices[Num_pg_description_indices] = char *Name_pg_description_indices[Num_pg_description_indices] =
{DescriptionObjIndex}; {DescriptionObjIndex};

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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/namespace.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
@ -124,3 +125,92 @@ RelnameGetRelid(const char *relname)
/* XXX Wrong! must search search path */ /* XXX Wrong! must search search path */
return get_relname_relid(relname, PG_CATALOG_NAMESPACE); 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;
}

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 "miscadmin.h"
#include "parser/parse_coerce.h" #include "parser/parse_coerce.h"
#include "parser/parse_func.h" #include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/syscache.h" #include "utils/syscache.h"
/* ---------------- /*
* AggregateCreate * 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 void
AggregateCreate(char *aggName, AggregateCreate(const char *aggName,
Oid aggNamespace,
char *aggtransfnName, char *aggtransfnName,
char *aggfinalfnName, char *aggfinalfnName,
char *aggbasetypeName, Oid aggBaseType,
char *aggtranstypeName, Oid aggTransType,
char *agginitval) const char *agginitval)
{ {
Relation aggdesc; Relation aggdesc;
HeapTuple tup; HeapTuple tup;
@ -59,8 +46,6 @@ AggregateCreate(char *aggName,
Form_pg_proc proc; Form_pg_proc proc;
Oid transfn; Oid transfn;
Oid finalfn = InvalidOid; /* can be omitted */ Oid finalfn = InvalidOid; /* can be omitted */
Oid basetype;
Oid transtype;
Oid finaltype; Oid finaltype;
Oid fnArgs[FUNC_MAX_ARGS]; Oid fnArgs[FUNC_MAX_ARGS];
int nargs; int nargs;
@ -68,8 +53,6 @@ AggregateCreate(char *aggName,
TupleDesc tupDesc; TupleDesc tupDesc;
int i; int i;
MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid));
/* sanity checks */ /* sanity checks */
if (!aggName) if (!aggName)
elog(ERROR, "no aggregate name supplied"); elog(ERROR, "no aggregate name supplied");
@ -77,44 +60,21 @@ AggregateCreate(char *aggName,
if (!aggtransfnName) if (!aggtransfnName)
elog(ERROR, "aggregate must have a transition function"); 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 */ /* make sure there is no existing agg of same name and base type */
if (SearchSysCacheExists(AGGNAME, if (SearchSysCacheExists(AGGNAME,
PointerGetDatum(aggName), PointerGetDatum(aggName),
ObjectIdGetDatum(basetype), ObjectIdGetDatum(aggBaseType),
0, 0)) 0, 0))
elog(ERROR, elog(ERROR,
"aggregate function \"%s\" with base type %s already exists", "aggregate function \"%s\" with base type %s already exists",
aggName, aggbasetypeName); aggName, typeidTypeName(aggBaseType));
/* handle transtype */
transtype = GetSysCacheOid(TYPENAME,
PointerGetDatum(aggtranstypeName),
0, 0, 0);
if (!OidIsValid(transtype))
elog(ERROR, "data type %s does not exit",
aggtranstypeName);
/* handle transfn */ /* handle transfn */
fnArgs[0] = transtype; MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid));
if (OidIsValid(basetype)) fnArgs[0] = aggTransType;
if (OidIsValid(aggBaseType))
{ {
fnArgs[1] = basetype; fnArgs[1] = aggBaseType;
nargs = 2; nargs = 2;
} }
else else
@ -129,9 +89,9 @@ AggregateCreate(char *aggName,
transfn = tup->t_data->t_oid; transfn = tup->t_data->t_oid;
Assert(OidIsValid(transfn)); Assert(OidIsValid(transfn));
proc = (Form_pg_proc) GETSTRUCT(tup); 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", 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 * 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 (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"); elog(ERROR, "must not omit initval when transfn is strict and transtype is not compatible with input type");
} }
ReleaseSysCache(tup); ReleaseSysCache(tup);
@ -149,7 +109,7 @@ AggregateCreate(char *aggName,
/* handle finalfn, if supplied */ /* handle finalfn, if supplied */
if (aggfinalfnName) if (aggfinalfnName)
{ {
fnArgs[0] = transtype; fnArgs[0] = aggTransType;
fnArgs[1] = 0; fnArgs[1] = 0;
tup = SearchSysCache(PROCNAME, tup = SearchSysCache(PROCNAME,
PointerGetDatum(aggfinalfnName), PointerGetDatum(aggfinalfnName),
@ -169,7 +129,7 @@ AggregateCreate(char *aggName,
/* /*
* If no finalfn, aggregate result type is type of the state value * If no finalfn, aggregate result type is type of the state value
*/ */
finaltype = transtype; finaltype = aggTransType;
} }
Assert(OidIsValid(finaltype)); Assert(OidIsValid(finaltype));
@ -184,8 +144,8 @@ AggregateCreate(char *aggName,
values[Anum_pg_aggregate_aggowner - 1] = Int32GetDatum(GetUserId()); values[Anum_pg_aggregate_aggowner - 1] = Int32GetDatum(GetUserId());
values[Anum_pg_aggregate_aggtransfn - 1] = ObjectIdGetDatum(transfn); values[Anum_pg_aggregate_aggtransfn - 1] = ObjectIdGetDatum(transfn);
values[Anum_pg_aggregate_aggfinalfn - 1] = ObjectIdGetDatum(finalfn); values[Anum_pg_aggregate_aggfinalfn - 1] = ObjectIdGetDatum(finalfn);
values[Anum_pg_aggregate_aggbasetype - 1] = ObjectIdGetDatum(basetype); values[Anum_pg_aggregate_aggbasetype - 1] = ObjectIdGetDatum(aggBaseType);
values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(transtype); values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(aggTransType);
values[Anum_pg_aggregate_aggfinaltype - 1] = ObjectIdGetDatum(finaltype); values[Anum_pg_aggregate_aggfinaltype - 1] = ObjectIdGetDatum(finaltype);
if (agginitval) if (agginitval)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* these routines moved here from commands/define.c and somewhat cleaned up. * these routines moved here from commands/define.c and somewhat cleaned up.
@ -30,34 +30,28 @@
#include "utils/syscache.h" #include "utils/syscache.h"
static Oid OperatorGetWithOpenRelation(Relation pg_operator_desc, static Oid OperatorGet(const char *operatorName,
const char *operatorName, Oid leftObjectId,
Oid leftObjectId, Oid rightObjectId,
Oid rightObjectId, bool *defined);
bool *defined);
static Oid OperatorGet(char *operatorName, static Oid OperatorShellMake(const char *operatorName,
char *leftTypeName, Oid leftTypeId,
char *rightTypeName, Oid rightTypeId);
bool *defined);
static Oid OperatorShellMake(char *operatorName, static void OperatorDef(const char *operatorName,
char *leftTypeName, Oid leftTypeId,
char *rightTypeName); Oid rightTypeId,
const char *procedureName,
static void OperatorDef(char *operatorName,
char *leftTypeName,
char *rightTypeName,
char *procedureName,
uint16 precedence, uint16 precedence,
bool isLeftAssociative, bool isLeftAssociative,
char *commutatorName, const char *commutatorName,
char *negatorName, const char *negatorName,
char *restrictionName, const char *restrictionName,
char *oinName, const char *joinName,
bool canHash, bool canHash,
char *leftSortName, const char *leftSortName,
char *rightSortName); const char *rightSortName);
static void OperatorUpd(Oid baseId, Oid commId, Oid negId); 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 * finds the operator associated with the specified name
* with given name and left/right type oids. * and left and right type IDs.
* *
* pg_operator_desc -- reldesc for pg_operator * operatorName -- name of operator to fetch
* operatorName -- name of operator to fetch * leftObjectId -- left data type oid of operator to fetch
* leftObjectId -- left data type oid of operator to fetch * rightObjectId -- right data type oid of operator to fetch
* rightObjectId -- right data type oid of operator to fetch * defined -- set TRUE if defined (not a shell)
* defined -- set TRUE if defined (not a shell)
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
static Oid static Oid
OperatorGetWithOpenRelation(Relation pg_operator_desc, OperatorGet(const char *operatorName,
const char *operatorName, Oid leftObjectId,
Oid leftObjectId, Oid rightObjectId,
Oid rightObjectId, bool *defined)
bool *defined)
{ {
Relation pg_operator_desc;
HeapScanDesc pg_operator_scan; HeapScanDesc pg_operator_scan;
Oid operatorObjectId;
HeapTuple tup; HeapTuple tup;
ScanKeyData opKey[3]; 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 * form scan key
@ -192,99 +194,22 @@ OperatorGetWithOpenRelation(Relation pg_operator_desc,
* close the scan and return the oid. * close the scan and return the oid.
*/ */
heap_endscan(pg_operator_scan); 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); heap_close(pg_operator_desc, AccessShareLock);
return operatorObjectId; return operatorObjectId;
} }
/* ---------------------------------------------------------------- /*
* OperatorShellMake * OperatorShellMake
* * Make a "shell" entry for a not-yet-existing operator.
* 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.
* ----------------------------------------------------------------
*/ */
static Oid static Oid
OperatorShellMake(char *operatorName, OperatorShellMake(const char *operatorName,
char *leftTypeName, Oid leftTypeId,
char *rightTypeName) Oid rightTypeId)
{ {
Relation pg_operator_desc; Relation pg_operator_desc;
Oid operatorObjectId; Oid operatorObjectId;
Oid leftObjectId = InvalidOid;
Oid rightObjectId = InvalidOid;
bool leftDefined = false;
bool rightDefined = false;
int i; int i;
HeapTuple tup; HeapTuple tup;
Datum values[Natts_pg_operator]; Datum values[Natts_pg_operator];
@ -298,19 +223,6 @@ OperatorShellMake(char *operatorName,
if (!validOperatorName(operatorName)) if (!validOperatorName(operatorName))
elog(ERROR, "\"%s\" is not a valid operator name", 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 * open pg_operator
*/ */
@ -337,8 +249,8 @@ OperatorShellMake(char *operatorName,
values[i++] = CharGetDatum('b'); /* assume it's binary */ values[i++] = CharGetDatum('b'); /* assume it's binary */
values[i++] = BoolGetDatum(false); values[i++] = BoolGetDatum(false);
values[i++] = BoolGetDatum(false); values[i++] = BoolGetDatum(false);
values[i++] = ObjectIdGetDatum(leftObjectId); /* <-- left oid */ values[i++] = ObjectIdGetDatum(leftTypeId);
values[i++] = ObjectIdGetDatum(rightObjectId); /* <-- right oid */ values[i++] = ObjectIdGetDatum(rightTypeId);
values[i++] = ObjectIdGetDatum(InvalidOid); values[i++] = ObjectIdGetDatum(InvalidOid);
values[i++] = ObjectIdGetDatum(InvalidOid); 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) * "X" indicates an optional argument (i.e. one that can be NULL)
* operatorName; -- operator name * operatorName; -- operator name
* leftTypeName; -- X left type name * leftTypeId; -- X left type id
* rightTypeName; -- X right type name * rightTypeId; -- X right type id
* procedureName; -- procedure name for operator code * procedureName; -- procedure name for operator code
* precedence; -- operator precedence * precedence; -- operator precedence
* isLeftAssociative; -- operator is left associative? * isLeftAssociative; -- operator is left associative?
@ -458,22 +370,20 @@ OperatorShellMake(char *operatorName,
* rightSortName; -- X right sort operator (for merge join) * rightSortName; -- X right sort operator (for merge join)
*/ */
static void static void
OperatorDef(char *operatorName, OperatorDef(const char *operatorName,
char *leftTypeName, Oid leftTypeId,
char *rightTypeName, Oid rightTypeId,
char *procedureName, const char *procedureName,
uint16 precedence, uint16 precedence,
bool isLeftAssociative, bool isLeftAssociative,
char *commutatorName, const char *commutatorName,
char *negatorName, const char *negatorName,
char *restrictionName, const char *restrictionName,
char *joinName, const char *joinName,
bool canHash, bool canHash,
char *leftSortName, const char *leftSortName,
char *rightSortName) const char *rightSortName)
{ {
int i,
j;
Relation pg_operator_desc; Relation pg_operator_desc;
HeapScanDesc pg_operator_scan; HeapScanDesc pg_operator_scan;
HeapTuple tup; HeapTuple tup;
@ -482,23 +392,30 @@ OperatorDef(char *operatorName,
Datum values[Natts_pg_operator]; Datum values[Natts_pg_operator];
Oid operatorObjectId; Oid operatorObjectId;
bool operatorAlreadyDefined; bool operatorAlreadyDefined;
Oid leftTypeId = InvalidOid;
Oid rightTypeId = InvalidOid;
Oid commutatorId = InvalidOid; Oid commutatorId = InvalidOid;
Oid negatorId = InvalidOid; Oid negatorId = InvalidOid;
bool leftDefined = false;
bool rightDefined = false;
bool selfCommutator = false; bool selfCommutator = false;
char *name[4]; const char *name[4];
Oid typeId[FUNC_MAX_ARGS]; Oid typeId[FUNC_MAX_ARGS];
int nargs; int nargs;
NameData oname; NameData oname;
TupleDesc tupDesc; TupleDesc tupDesc;
ScanKeyData opKey[3]; 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, operatorObjectId = OperatorGet(operatorName,
leftTypeName, leftTypeId,
rightTypeName, rightTypeId,
&operatorAlreadyDefined); &operatorAlreadyDefined);
if (operatorAlreadyDefined) if (operatorAlreadyDefined)
@ -510,39 +427,6 @@ OperatorDef(char *operatorName,
* filling in a previously-created shell. * 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) for (i = 0; i < Natts_pg_operator; ++i)
{ {
values[i] = (Datum) NULL; values[i] = (Datum) NULL;
@ -556,12 +440,12 @@ OperatorDef(char *operatorName,
* created so we don't have to worry about deleting them later. * created so we don't have to worry about deleting them later.
*/ */
MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
if (!leftTypeName) if (!OidIsValid(leftTypeId))
{ {
typeId[0] = rightTypeId; typeId[0] = rightTypeId;
nargs = 1; nargs = 1;
} }
else if (!rightTypeName) else if (!OidIsValid(rightTypeId))
{ {
typeId[0] = leftTypeId; typeId[0] = leftTypeId;
nargs = 1; nargs = 1;
@ -645,7 +529,7 @@ OperatorDef(char *operatorName,
values[i++] = NameGetDatum(&oname); values[i++] = NameGetDatum(&oname);
values[i++] = Int32GetDatum(GetUserId()); values[i++] = Int32GetDatum(GetUserId());
values[i++] = UInt16GetDatum(precedence); 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(isLeftAssociative);
values[i++] = BoolGetDatum(canHash); values[i++] = BoolGetDatum(canHash);
values[i++] = ObjectIdGetDatum(leftTypeId); values[i++] = ObjectIdGetDatum(leftTypeId);
@ -667,8 +551,6 @@ OperatorDef(char *operatorName,
{ {
if (name[j]) if (name[j])
{ {
char *otherLeftTypeName = NULL;
char *otherRightTypeName = NULL;
Oid otherLeftTypeId = InvalidOid; Oid otherLeftTypeId = InvalidOid;
Oid otherRightTypeId = InvalidOid; Oid otherRightTypeId = InvalidOid;
Oid other_oid = InvalidOid; Oid other_oid = InvalidOid;
@ -677,46 +559,37 @@ OperatorDef(char *operatorName,
switch (j) switch (j)
{ {
case 0: /* commutator has reversed arg types */ case 0: /* commutator has reversed arg types */
otherLeftTypeName = rightTypeName;
otherRightTypeName = leftTypeName;
otherLeftTypeId = rightTypeId; otherLeftTypeId = rightTypeId;
otherRightTypeId = leftTypeId; otherRightTypeId = leftTypeId;
other_oid = OperatorGet(name[j], other_oid = OperatorGet(name[j],
otherLeftTypeName, otherLeftTypeId,
otherRightTypeName, otherRightTypeId,
&otherDefined); &otherDefined);
commutatorId = other_oid; commutatorId = other_oid;
break; break;
case 1: /* negator has same arg types */ case 1: /* negator has same arg types */
otherLeftTypeName = leftTypeName;
otherRightTypeName = rightTypeName;
otherLeftTypeId = leftTypeId; otherLeftTypeId = leftTypeId;
otherRightTypeId = rightTypeId; otherRightTypeId = rightTypeId;
other_oid = OperatorGet(name[j], other_oid = OperatorGet(name[j],
otherLeftTypeName, otherLeftTypeId,
otherRightTypeName, otherRightTypeId,
&otherDefined); &otherDefined);
negatorId = other_oid; negatorId = other_oid;
break; break;
case 2: /* left sort op takes left-side data type */ case 2: /* left sort op takes left-side data type */
otherLeftTypeName = leftTypeName;
otherRightTypeName = leftTypeName;
otherLeftTypeId = leftTypeId; otherLeftTypeId = leftTypeId;
otherRightTypeId = leftTypeId; otherRightTypeId = leftTypeId;
other_oid = OperatorGet(name[j], other_oid = OperatorGet(name[j],
otherLeftTypeName, otherLeftTypeId,
otherRightTypeName, otherRightTypeId,
&otherDefined); &otherDefined);
break; break;
case 3: /* right sort op takes right-side data case 3: /* right sort op takes right-side data type */
* type */
otherLeftTypeName = rightTypeName;
otherRightTypeName = rightTypeName;
otherLeftTypeId = rightTypeId; otherLeftTypeId = rightTypeId;
otherRightTypeId = rightTypeId; otherRightTypeId = rightTypeId;
other_oid = OperatorGet(name[j], other_oid = OperatorGet(name[j],
otherLeftTypeName, otherLeftTypeId,
otherRightTypeName, otherRightTypeId,
&otherDefined); &otherDefined);
break; break;
} }
@ -732,8 +605,8 @@ OperatorDef(char *operatorName,
{ {
/* not in catalogs, different from operator */ /* not in catalogs, different from operator */
other_oid = OperatorShellMake(name[j], other_oid = OperatorShellMake(name[j],
otherLeftTypeName, otherLeftTypeId,
otherRightTypeName); otherRightTypeId);
if (!OidIsValid(other_oid)) if (!OidIsValid(other_oid))
elog(ERROR, elog(ERROR,
"OperatorDef: can't create operator shell \"%s\"", "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 ... * 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 * operatorName; -- operator name
* leftTypeName; -- X left type name * leftTypeId; -- X left type ID
* rightTypeName; -- X right type name * rightTypeId; -- X right type ID
* procedureName; -- procedure for operator * procedureName; -- procedure for operator
* precedence; -- operator precedence * precedence; -- operator precedence
* isLeftAssociative; -- operator is left associative * isLeftAssociative; -- operator is left associative
@ -1039,24 +912,24 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
* rightSortName; -- X right sort operator (for merge join) * rightSortName; -- X right sort operator (for merge join)
*/ */
void void
OperatorCreate(char *operatorName, OperatorCreate(const char *operatorName,
char *leftTypeName, Oid leftTypeId,
char *rightTypeName, Oid rightTypeId,
char *procedureName, const char *procedureName,
uint16 precedence, uint16 precedence,
bool isLeftAssociative, bool isLeftAssociative,
char *commutatorName, const char *commutatorName,
char *negatorName, const char *negatorName,
char *restrictionName, const char *restrictionName,
char *joinName, const char *joinName,
bool canHash, bool canHash,
char *leftSortName, const char *leftSortName,
char *rightSortName) const char *rightSortName)
{ {
if (!leftTypeName && !rightTypeName) if (!OidIsValid(leftTypeId) && !OidIsValid(rightTypeId))
elog(ERROR, "at least one of leftarg or rightarg must be specified"); 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 it's not a binary op, these things mustn't be set: */
if (commutatorName) if (commutatorName)
@ -1075,8 +948,8 @@ OperatorCreate(char *operatorName,
* already exist. * already exist.
*/ */
OperatorDef(operatorName, OperatorDef(operatorName,
leftTypeName, leftTypeId,
rightTypeName, rightTypeId,
procedureName, procedureName,
precedence, precedence,
isLeftAssociative, isLeftAssociative,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 Oid
ProcedureCreate(char *procedureName, ProcedureCreate(char *procedureName,
Oid procNamespace,
bool replace, bool replace,
bool returnsSet, bool returnsSet,
char *returnTypeName, Oid returnType,
Oid languageObjectId, Oid languageObjectId,
char *prosrc, char *prosrc,
char *probin, char *probin,
@ -60,17 +61,14 @@ ProcedureCreate(char *procedureName,
Relation rel; Relation rel;
HeapTuple tup; HeapTuple tup;
HeapTuple oldtup; HeapTuple oldtup;
bool defined;
uint16 parameterCount; uint16 parameterCount;
char nulls[Natts_pg_proc]; char nulls[Natts_pg_proc];
Datum values[Natts_pg_proc]; Datum values[Natts_pg_proc];
char replaces[Natts_pg_proc]; char replaces[Natts_pg_proc];
Oid typeObjectId;
List *x; List *x;
List *querytree_list; List *querytree_list;
Oid typev[FUNC_MAX_ARGS]; Oid typev[FUNC_MAX_ARGS];
Oid relid; Oid relid;
Oid toid;
NameData procname; NameData procname;
TupleDesc tupDesc; TupleDesc tupDesc;
Oid retval; Oid retval;
@ -86,28 +84,31 @@ ProcedureCreate(char *procedureName,
foreach(x, argList) foreach(x, argList)
{ {
TypeName *t = (TypeName *) lfirst(x); TypeName *t = (TypeName *) lfirst(x);
char *typnam = TypeNameToInternalName(t); Oid toid;
if (parameterCount >= FUNC_MAX_ARGS) if (parameterCount >= FUNC_MAX_ARGS)
elog(ERROR, "functions cannot have more than %d arguments", elog(ERROR, "functions cannot have more than %d arguments",
FUNC_MAX_ARGS); FUNC_MAX_ARGS);
if (strcmp(typnam, "opaque") == 0) toid = LookupTypeName(t);
if (OidIsValid(toid))
{ {
if (languageObjectId == SQLlanguageId) if (!get_typisdefined(toid))
elog(ERROR, "SQL functions cannot have arguments of type \"opaque\""); elog(WARNING, "Argument type \"%s\" is only a shell",
toid = InvalidOid; TypeNameToString(t));
} }
else else
{ {
toid = TypeGet(typnam, &defined); char *typnam = TypeNameToString(t);
if (!OidIsValid(toid)) if (strcmp(typnam, "opaque") == 0)
elog(ERROR, "argument type %s does not exist", {
typnam); if (languageObjectId == SQLlanguageId)
if (!defined) elog(ERROR, "SQL functions cannot have arguments of type \"opaque\"");
elog(WARNING, "argument type %s is only a shell", toid = InvalidOid;
typnam); }
else
elog(ERROR, "Type \"%s\" does not exist", typnam);
} }
if (t->setof) if (t->setof)
@ -154,41 +155,21 @@ ProcedureCreate(char *procedureName,
} }
} }
if (strcmp(returnTypeName, "opaque") == 0) if (!OidIsValid(returnType))
{ {
if (languageObjectId == SQLlanguageId) if (languageObjectId == SQLlanguageId)
elog(ERROR, "SQL functions cannot return type \"opaque\""); 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 * don't allow functions of complex types that have the same name as
* existing attributes of the type * existing attributes of the type
*/ */
if (parameterCount == 1 && if (parameterCount == 1 && OidIsValid(typev[0]) &&
(toid = TypeGet(strVal(lfirst(argList)), &defined)) && (relid = typeidTypeRelid(typev[0])) != 0 &&
defined &&
(relid = typeidTypeRelid(toid)) != 0 &&
get_attnum(relid, procedureName) != InvalidAttrNumber) get_attnum(relid, procedureName) != InvalidAttrNumber)
elog(ERROR, "method %s already an attribute of type %s", 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 * 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); querytree_list = pg_parse_and_rewrite(prosrc, typev, parameterCount);
/* typecheck return value */ /* typecheck return value */
checkretval(typeObjectId, querytree_list); checkretval(returnType, querytree_list);
} }
/* /*
@ -271,7 +252,7 @@ ProcedureCreate(char *procedureName,
values[i++] = BoolGetDatum(isStrict); values[i++] = BoolGetDatum(isStrict);
values[i++] = UInt16GetDatum(parameterCount); values[i++] = UInt16GetDatum(parameterCount);
values[i++] = BoolGetDatum(returnsSet); values[i++] = BoolGetDatum(returnsSet);
values[i++] = ObjectIdGetDatum(typeObjectId); values[i++] = ObjectIdGetDatum(returnType);
values[i++] = PointerGetDatum(typev); values[i++] = PointerGetDatum(typev);
values[i++] = Int32GetDatum(byte_pct); /* probyte_pct */ values[i++] = Int32GetDatum(byte_pct); /* probyte_pct */
values[i++] = Int32GetDatum(perbyte_cpu); /* properbyte_cpu */ 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 * Not okay to change the return type of the existing proc, since
* existing rules, views, etc may depend on the return type. * existing rules, views, etc may depend on the return type.
*/ */
if (typeObjectId != oldproc->prorettype || if (returnType != oldproc->prorettype ||
returnsSet != oldproc->proretset) returnsSet != oldproc->proretset)
elog(ERROR, "ProcedureCreate: cannot change return type of existing function." elog(ERROR, "ProcedureCreate: cannot change return type of existing function."
"\n\tUse DROP FUNCTION first."); "\n\tUse DROP FUNCTION first.");

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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/indexing.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/parse_func.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/syscache.h" #include "utils/syscache.h"
static Oid TypeShellMakeWithOpenRelation(Relation pg_type_desc,
char *typeName);
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* TypeGetWithOpenRelation * TypeShellMake
* *
* preforms a scan on pg_type for a type tuple with the * This procedure inserts a "shell" tuple into the type
* given type name. * relation. The type tuple inserted has invalid values
* ---------------------------------------------------------------- * and in particular, the "typisdefined" field is false.
* 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" * This is used so that a tuple exists in the catalogs.
* is only set if the type has actually been defined, i.e., if * The invalid fields should be fixed up sometime after
* the type tuple is not a shell. * this routine is called, and then the "typeisdefined"
* * field is set to true. -cim 6/15/90
* Note: the meat of this function is now in the function
* TypeGetWithOpenRelation(). -cim 6/15/90
*
* Also called from util/remove.c
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
Oid Oid
TypeGet(char *typeName, /* name of type to be fetched */ TypeShellMake(const char *typeName, Oid typeNamespace)
bool *defined) /* has the type been defined? */
{ {
Relation pg_type_desc; Relation pg_type_desc;
Oid typeoid; TupleDesc tupDesc;
/*
* 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)
{
int i; int i;
HeapTuple tup; HeapTuple tup;
Datum values[Natts_pg_type]; Datum values[Natts_pg_type];
char nulls[Natts_pg_type]; char nulls[Natts_pg_type];
Oid typoid; Oid typoid;
NameData name; 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 * initialize our *nulls and *values arrays
@ -162,34 +70,33 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
*/ */
i = 0; i = 0;
namestrcpy(&name, typeName); namestrcpy(&name, typeName);
values[i++] = NameGetDatum(&name); /* 1 */ values[i++] = NameGetDatum(&name); /* typname */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 2 */ values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
values[i++] = Int16GetDatum(0); /* 3 */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typowner */
values[i++] = Int16GetDatum(0); /* 4 */ values[i++] = Int16GetDatum(0); /* typlen */
values[i++] = BoolGetDatum(false); /* 5 */ values[i++] = Int16GetDatum(0); /* typprtlen */
values[i++] = CharGetDatum(0); /* 6 */ values[i++] = BoolGetDatum(false); /* typbyval */
values[i++] = BoolGetDatum(false); /* 7 */ values[i++] = CharGetDatum(0); /* typtype */
values[i++] = CharGetDatum(0); /* 8 */ values[i++] = BoolGetDatum(false); /* typisdefined */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 9 */ values[i++] = CharGetDatum(0); /* typdelim */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 10 */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typrelid */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 11 */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typelem */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 12 */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typinput */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 13 */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typoutput */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 14 */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */
values[i++] = CharGetDatum('i'); /* 15 */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typsend */
values[i++] = CharGetDatum('p'); /* 16 */ values[i++] = CharGetDatum('i'); /* typalign */
values[i++] = BoolGetDatum(false); /* 17 */ values[i++] = CharGetDatum('p'); /* typstorage */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 18 */ values[i++] = BoolGetDatum(false); /* typnotnull */
values[i++] = Int32GetDatum(-1); /* 19 */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typbasetype */
values[i++] = Int32GetDatum(0); /* 20 */ values[i++] = Int32GetDatum(-1); /* typtypmod */
nulls[i++] = 'n'; /* 21 */ values[i++] = Int32GetDatum(0); /* typndims */
nulls[i++] = 'n'; /* 22 */ 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); 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); 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); heap_close(pg_type_desc, RowExclusiveLock);
return typoid; return typoid;
@ -266,77 +135,38 @@ TypeShellMake(char *typeName)
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
Oid Oid
TypeCreate(char *typeName, TypeCreate(const char *typeName,
Oid typeNamespace,
Oid assignedTypeOid, Oid assignedTypeOid,
Oid relationOid, /* only for 'c'atalog typeTypes */ Oid relationOid, /* only for 'c'atalog typeTypes */
int16 internalSize, int16 internalSize,
int16 externalSize, int16 externalSize,
char typeType, char typeType,
char typDelim, char typDelim,
char *inputProcedure, Oid inputProcedure,
char *outputProcedure, Oid outputProcedure,
char *receiveProcedure, Oid receiveProcedure,
char *sendProcedure, Oid sendProcedure,
char *elementTypeName, Oid elementType,
char *baseTypeName, Oid baseType,
char *defaultTypeValue, /* human readable rep */ const char *defaultTypeValue, /* human readable rep */
char *defaultTypeBin, /* cooked rep */ const char *defaultTypeBin, /* cooked rep */
bool passedByValue, bool passedByValue,
char alignment, char alignment,
char storage, char storage,
int32 typeMod, int32 typeMod,
int32 typNDims, /* Array dimensions for baseTypeName */ int32 typNDims, /* Array dimensions for baseType */
bool typeNotNull) bool typeNotNull)
{ {
int i,
j;
Relation pg_type_desc; Relation pg_type_desc;
HeapScanDesc pg_type_scan;
Oid typeObjectId; Oid typeObjectId;
Oid elementObjectId = InvalidOid;
Oid baseObjectId = InvalidOid;
HeapTuple tup; HeapTuple tup;
char nulls[Natts_pg_type]; char nulls[Natts_pg_type];
char replaces[Natts_pg_type]; char replaces[Natts_pg_type];
Datum values[Natts_pg_type]; Datum values[Natts_pg_type];
char *procname;
char *procs[4];
bool defined;
NameData name; NameData name;
TupleDesc tupDesc; TupleDesc tupDesc;
Oid argList[FUNC_MAX_ARGS]; int i;
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);
}
/* /*
* validate size specifications: either positive (fixed-length) or -1 * 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"); 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) for (i = 0; i < Natts_pg_type; ++i)
{ {
@ -367,94 +197,27 @@ TypeCreate(char *typeName,
*/ */
i = 0; i = 0;
namestrcpy(&name, typeName); namestrcpy(&name, typeName);
values[i++] = NameGetDatum(&name); /* 1 */ values[i++] = NameGetDatum(&name); /* typname */
values[i++] = Int32GetDatum(GetUserId()); /* 2 */ values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
values[i++] = Int16GetDatum(internalSize); /* 3 */ values[i++] = Int32GetDatum(GetUserId()); /* typowner */
values[i++] = Int16GetDatum(externalSize); /* 4 */ values[i++] = Int16GetDatum(internalSize); /* typlen */
values[i++] = BoolGetDatum(passedByValue); /* 5 */ values[i++] = Int16GetDatum(externalSize); /* typprtlen */
values[i++] = CharGetDatum(typeType); /* 6 */ values[i++] = BoolGetDatum(passedByValue); /* typbyval */
values[i++] = BoolGetDatum(true); /* 7 */ values[i++] = CharGetDatum(typeType); /* typtype */
values[i++] = CharGetDatum(typDelim); /* 8 */ values[i++] = BoolGetDatum(true); /* typisdefined */
values[i++] = ObjectIdGetDatum(typeType == 'c' ? relationOid : InvalidOid); /* 9 */ values[i++] = CharGetDatum(typDelim); /* typdelim */
values[i++] = ObjectIdGetDatum(elementObjectId); /* 10 */ values[i++] = ObjectIdGetDatum(typeType == 'c' ? relationOid : InvalidOid); /* typrelid */
values[i++] = ObjectIdGetDatum(elementType); /* typelem */
procs[0] = inputProcedure; values[i++] = ObjectIdGetDatum(inputProcedure); /* typinput */
procs[1] = outputProcedure; values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */
procs[2] = (receiveProcedure) ? receiveProcedure : inputProcedure; values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */
procs[3] = (sendProcedure) ? sendProcedure : outputProcedure; values[i++] = ObjectIdGetDatum(sendProcedure); /* typsend */
values[i++] = CharGetDatum(alignment); /* typalign */
for (j = 0; j < 4; ++j) values[i++] = CharGetDatum(storage); /* typstorage */
{ values[i++] = BoolGetDatum(typeNotNull); /* typnotnull */
Oid procOid; values[i++] = ObjectIdGetDatum(baseType); /* typbasetype */
values[i++] = Int32GetDatum(typeMod); /* typtypmod */
procname = procs[j]; values[i++] = Int32GetDatum(typNDims); /* typndims */
/*
* 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 */
/* /*
* initialize the default binary value for this type. Check for * initialize the default binary value for this type. Check for
@ -465,7 +228,7 @@ TypeCreate(char *typeName,
CStringGetDatum(defaultTypeBin)); CStringGetDatum(defaultTypeBin));
else else
nulls[i] = 'n'; nulls[i] = 'n';
i++; /* 21 */ i++; /* typdefaultbin */
/* /*
* initialize the default value for this type. * initialize the default value for this type.
@ -475,36 +238,33 @@ TypeCreate(char *typeName,
CStringGetDatum(defaultTypeValue)); CStringGetDatum(defaultTypeValue));
else else
nulls[i] = 'n'; 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); pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&typeKey[0], tup = SearchSysCacheCopy(TYPENAMENSP,
0, CStringGetDatum(typeName),
Anum_pg_type_typname, ObjectIdGetDatum(typeNamespace),
F_NAMEEQ, 0, 0);
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);
if (HeapTupleIsValid(tup)) 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); elog(ERROR, "type %s already exists", typeName);
/*
* Okay to update existing "shell" type tuple
*/
tup = heap_modifytuple(tup, tup = heap_modifytuple(tup,
pg_type_desc, pg_type_desc,
values, values,
@ -531,11 +291,7 @@ TypeCreate(char *typeName,
typeObjectId = tup->t_data->t_oid; typeObjectId = tup->t_data->t_oid;
} }
/* /* Update indices (not necessary if bootstrapping) */
* finish up
*/
heap_endscan(pg_type_scan);
if (RelationGetForm(pg_type_desc)->relhasindex) if (RelationGetForm(pg_type_desc)->relhasindex)
{ {
Relation idescs[Num_pg_type_indices]; Relation idescs[Num_pg_type_indices];
@ -545,19 +301,25 @@ TypeCreate(char *typeName,
CatalogCloseIndices(Num_pg_type_indices, idescs); CatalogCloseIndices(Num_pg_type_indices, idescs);
} }
/*
* finish up
*/
heap_close(pg_type_desc, RowExclusiveLock); heap_close(pg_type_desc, RowExclusiveLock);
return typeObjectId; return typeObjectId;
} }
/* ---------------------------------------------------------------- /*
* TypeRename * TypeRename
*
* This renames a type * 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 void
TypeRename(const char *oldTypeName, const char *newTypeName) TypeRename(const char *oldTypeName, Oid typeNamespace,
const char *newTypeName)
{ {
Relation pg_type_desc; Relation pg_type_desc;
Relation idescs[Num_pg_type_indices]; Relation idescs[Num_pg_type_indices];
@ -565,15 +327,17 @@ TypeRename(const char *oldTypeName, const char *newTypeName)
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock); pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
tuple = SearchSysCacheCopy(TYPENAME, tuple = SearchSysCacheCopy(TYPENAMENSP,
PointerGetDatum(oldTypeName), CStringGetDatum(oldTypeName),
0, 0, 0); ObjectIdGetDatum(typeNamespace),
0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "type %s does not exist", oldTypeName); elog(ERROR, "type %s does not exist", oldTypeName);
if (SearchSysCacheExists(TYPENAME, if (SearchSysCacheExists(TYPENAMENSP,
PointerGetDatum(newTypeName), CStringGetDatum(newTypeName),
0, 0, 0)) ObjectIdGetDatum(typeNamespace),
0, 0))
elog(ERROR, "type named %s already exists", newTypeName); elog(ERROR, "type named %s already exists", newTypeName);
namestrcpy(&(((Form_pg_type) GETSTRUCT(tuple))->typname), 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 * the caller is responsible for pfreeing the result
*/ */
char * char *
makeArrayTypeName(char *typeName) makeArrayTypeName(const char *typeName)
{ {
char *arr; char *arr;

View File

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * 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(); CommandCounterIncrement();
/* Destroy old heap (along with its index) and rename new. */ /* Destroy old heap (along with its index) and rename new. */
heap_drop_with_catalog(saveoldrelation->relname, allowSystemTableMods); heap_drop_with_catalog(OIDOldHeap, allowSystemTableMods);
CommandCounterIncrement(); CommandCounterIncrement();

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
@ -42,11 +42,12 @@
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "optimizer/planmain.h" #include "optimizer/planmain.h"
#include "optimizer/prep.h" #include "optimizer/prep.h"
#include "parser/analyze.h"
#include "parser/parse.h" #include "parser/parse.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_oper.h" #include "parser/parse_oper.h"
#include "parser/parse_relation.h" #include "parser/parse_relation.h"
#include "parser/analyze.h" #include "parser/parse_type.h"
#include "tcop/utility.h" #include "tcop/utility.h"
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/builtins.h" #include "utils/builtins.h"
@ -58,9 +59,9 @@
static void drop_default(Oid relid, int16 attnum); static void drop_default(Oid relid, int16 attnum);
static bool needs_toast_table(Relation rel); static bool needs_toast_table(Relation rel);
static void AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId);
static void CheckTupleType(Form_pg_class tuple_class); static void CheckTupleType(Form_pg_class tuple_class);
/* -------------------------------- /* --------------------------------
* PortalCleanup * PortalCleanup
* -------------------------------- * --------------------------------
@ -309,13 +310,13 @@ PerformPortalClose(char *name, CommandDest dest)
* ---------------- * ----------------
*/ */
void void
AlterTableAddColumn(const char *relationName, AlterTableAddColumn(Oid myrelid,
bool inherits, bool inherits,
ColumnDef *colDef) ColumnDef *colDef)
{ {
Relation rel, Relation rel,
pgclass,
attrdesc; attrdesc;
Oid myrelid;
HeapTuple reltup; HeapTuple reltup;
HeapTuple newreltup; HeapTuple newreltup;
HeapTuple attributeTuple; HeapTuple attributeTuple;
@ -326,19 +327,17 @@ AlterTableAddColumn(const char *relationName,
maxatts; maxatts;
HeapTuple typeTuple; HeapTuple typeTuple;
Form_pg_type tform; Form_pg_type tform;
char *typename;
int attndims; int attndims;
/* /*
* Grab an exclusive lock on the target table, which we will NOT * Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction. * release until end of transaction.
*/ */
rel = heap_openr(relationName, AccessExclusiveLock); rel = heap_open(myrelid, AccessExclusiveLock);
myrelid = RelationGetRelid(rel);
if (rel->rd_rel->relkind != RELKIND_RELATION) if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
relationName); RelationGetRelationName(rel));
/* /*
* permissions checking. this would normally be done in utility.c, * 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. * 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", elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
relationName); RelationGetRelationName(rel));
if (!pg_class_ownercheck(myrelid, GetUserId())) if (!pg_class_ownercheck(myrelid, GetUserId()))
elog(ERROR, "ALTER TABLE: permission denied"); elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
RelationGetRelationName(rel));
heap_close(rel, NoLock); /* close rel but keep lock! */
/* /*
* Recurse to add the column to child classes, if requested. * Recurse to add the column to child classes, if requested.
@ -377,17 +376,11 @@ AlterTableAddColumn(const char *relationName,
foreach(child, children) foreach(child, children)
{ {
Oid childrelid = lfirsti(child); Oid childrelid = lfirsti(child);
char *childrelname;
if (childrelid == myrelid) if (childrelid == myrelid)
continue; continue;
rel = heap_open(childrelid, AccessExclusiveLock);
childrelname = pstrdup(RelationGetRelationName(rel));
heap_close(rel, AccessExclusiveLock);
AlterTableAddColumn(childrelname, false, colDef); AlterTableAddColumn(childrelid, false, colDef);
pfree(childrelname);
} }
} }
@ -412,23 +405,21 @@ AlterTableAddColumn(const char *relationName,
elog(ERROR, "Adding NOT NULL columns is not implemented." elog(ERROR, "Adding NOT NULL columns is not implemented."
"\n\tAdd the column, then use ALTER TABLE ADD CONSTRAINT."); "\n\tAdd the column, then use ALTER TABLE ADD CONSTRAINT.");
pgclass = heap_openr(RelationRelationName, RowExclusiveLock);
rel = heap_openr(RelationRelationName, RowExclusiveLock);
reltup = SearchSysCache(RELOID, reltup = SearchSysCache(RELOID,
ObjectIdGetDatum(myrelid), ObjectIdGetDatum(myrelid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(reltup)) if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found", elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName); RelationGetRelationName(rel));
if (SearchSysCacheExists(ATTNAME, if (SearchSysCacheExists(ATTNAME,
ObjectIdGetDatum(myrelid), ObjectIdGetDatum(myrelid),
PointerGetDatum(colDef->colname), PointerGetDatum(colDef->colname),
0, 0)) 0, 0))
elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"", 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; minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
maxatts = minattnum + 1; maxatts = minattnum + 1;
@ -440,21 +431,11 @@ AlterTableAddColumn(const char *relationName,
attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock); attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock);
if (colDef->typename->arrayBounds) if (colDef->typename->arrayBounds)
{
attndims = length(colDef->typename->arrayBounds); attndims = length(colDef->typename->arrayBounds);
typename = makeArrayTypeName(colDef->typename->name);
}
else else
{
attndims = 0; attndims = 0;
typename = colDef->typename->name;
}
typeTuple = SearchSysCache(TYPENAME, typeTuple = typenameType(colDef->typename);
PointerGetDatum(typename),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "ALTER TABLE: type \"%s\" does not exist", typename);
tform = (Form_pg_type) GETSTRUCT(typeTuple); tform = (Form_pg_type) GETSTRUCT(typeTuple);
attributeTuple = heap_addheader(Natts_pg_attribute, attributeTuple = heap_addheader(Natts_pg_attribute,
@ -494,7 +475,7 @@ AlterTableAddColumn(const char *relationName,
CatalogCloseIndices(Num_pg_attr_indices, idescs); CatalogCloseIndices(Num_pg_attr_indices, idescs);
} }
heap_close(attrdesc, NoLock); heap_close(attrdesc, RowExclusiveLock);
/* /*
* Update number of attributes in pg_class tuple * Update number of attributes in pg_class tuple
@ -502,22 +483,24 @@ AlterTableAddColumn(const char *relationName,
newreltup = heap_copytuple(reltup); newreltup = heap_copytuple(reltup);
((Form_pg_class) GETSTRUCT(newreltup))->relnatts = maxatts; ((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 */ /* keep catalog indices current */
if (RelationGetForm(rel)->relhasindex) if (RelationGetForm(pgclass)->relhasindex)
{ {
Relation ridescs[Num_pg_class_indices]; Relation ridescs[Num_pg_class_indices];
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs); 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); CatalogCloseIndices(Num_pg_class_indices, ridescs);
} }
heap_freetuple(newreltup); heap_freetuple(newreltup);
ReleaseSysCache(reltup); 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. * Make our catalog updates visible for subsequent steps.
@ -549,29 +532,28 @@ AlterTableAddColumn(const char *relationName,
* ALTER TABLE ALTER COLUMN SET/DROP DEFAULT * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
*/ */
void void
AlterTableAlterColumnDefault(const char *relationName, AlterTableAlterColumnDefault(Oid myrelid,
bool inh, const char *colName, bool inh, const char *colName,
Node *newDefault) Node *newDefault)
{ {
Relation rel; Relation rel;
HeapTuple tuple; HeapTuple tuple;
int16 attnum; int16 attnum;
Oid myrelid;
rel = heap_openr(relationName, AccessExclusiveLock); rel = heap_open(myrelid, AccessExclusiveLock);
myrelid = RelationGetRelid(rel);
if (rel->rd_rel->relkind != RELKIND_RELATION) if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", 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", 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); if (!pg_class_ownercheck(myrelid, GetUserId()))
elog(ERROR, "ALTER TABLE: \"%s\" permission denied",
RelationGetRelationName(rel));
/* /*
* Propagate to children if desired * Propagate to children if desired
@ -595,18 +577,13 @@ AlterTableAlterColumnDefault(const char *relationName,
if (childrelid == myrelid) if (childrelid == myrelid)
continue; continue;
rel = heap_open(childrelid, AccessExclusiveLock); AlterTableAlterColumnDefault(childrelid,
AlterTableAlterColumnDefault(RelationGetRelationName(rel),
false, colName, newDefault); false, colName, newDefault);
heap_close(rel, AccessExclusiveLock);
} }
} }
/* -= now do the thing on this relation =- */ /* -= now do the thing on this relation =- */
/* reopen the business */
rel = heap_openr(relationName, AccessExclusiveLock);
/* /*
* get the number of the attribute * get the number of the attribute
*/ */
@ -616,7 +593,7 @@ AlterTableAlterColumnDefault(const char *relationName,
0, 0); 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
relationName, colName); RelationGetRelationName(rel), colName);
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
@ -718,43 +695,42 @@ drop_default(Oid relid, int16 attnum)
* ALTER TABLE ALTER COLUMN SET STATISTICS / STORAGE * ALTER TABLE ALTER COLUMN SET STATISTICS / STORAGE
*/ */
void void
AlterTableAlterColumnFlags(const char *relationName, AlterTableAlterColumnFlags(Oid myrelid,
bool inh, const char *colName, bool inh, const char *colName,
Node *flagValue, const char *flagType) Node *flagValue, const char *flagType)
{ {
Relation rel; Relation rel;
Oid myrelid;
int newtarget = 1; int newtarget = 1;
char newstorage = 'x'; char newstorage = 'x';
char *storagemode; char *storagemode;
Relation attrelation; Relation attrelation;
HeapTuple tuple; HeapTuple tuple;
rel = heap_openr(relationName, AccessExclusiveLock); rel = heap_open(myrelid, AccessExclusiveLock);
myrelid = RelationGetRelid(rel);
if (rel->rd_rel->relkind != RELKIND_RELATION) if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
relationName); RelationGetRelationName(rel));
/* we allow statistics case for system tables */ /*
if (*flagType == 'M' && * we allow statistics case for system tables
!allowSystemTableMods && IsSystemRelationName(relationName)) */
if (*flagType != 'S' &&
!allowSystemTableMods
&& IsSystemRelationName(RelationGetRelationName(rel)))
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
relationName); RelationGetRelationName(rel));
if (!pg_class_ownercheck(myrelid, GetUserId())) if (!pg_class_ownercheck(myrelid, GetUserId()))
elog(ERROR, "ALTER TABLE: permission denied"); elog(ERROR, "ALTER TABLE: \"%s\" permission denied",
RelationGetRelationName(rel));
heap_close(rel, NoLock); /* close rel, but keep lock! */
/* /*
* Check the supplied parameters before anything else * Check the supplied parameters before anything else
*/ */
if (*flagType == 'S') /* if (*flagType == 'S')
* STATISTICS
*/
{ {
/* STATISTICS */
Assert(IsA(flagValue, Integer)); Assert(IsA(flagValue, Integer));
newtarget = intVal(flagValue); newtarget = intVal(flagValue);
@ -766,10 +742,9 @@ AlterTableAlterColumnFlags(const char *relationName,
else if (newtarget > 1000) else if (newtarget > 1000)
newtarget = 1000; newtarget = 1000;
} }
else if (*flagType == 'M') /* else if (*flagType == 'M')
* STORAGE
*/
{ {
/* STORAGE */
Assert(IsA(flagValue, Value)); Assert(IsA(flagValue, Value));
storagemode = strVal(flagValue); storagemode = strVal(flagValue);
@ -813,10 +788,8 @@ AlterTableAlterColumnFlags(const char *relationName,
if (childrelid == myrelid) if (childrelid == myrelid)
continue; continue;
rel = heap_open(childrelid, AccessExclusiveLock); AlterTableAlterColumnFlags(childrelid,
AlterTableAlterColumnFlags(RelationGetRelationName(rel), false, colName, flagValue, flagType);
false, colName, flagValue, flagType);
heap_close(rel, AccessExclusiveLock);
} }
} }
@ -830,7 +803,7 @@ AlterTableAlterColumnFlags(const char *relationName,
0, 0); 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
relationName, colName); RelationGetRelationName(rel), colName);
if (((Form_pg_attribute) GETSTRUCT(tuple))->attnum < 0) if (((Form_pg_attribute) GETSTRUCT(tuple))->attnum < 0)
elog(ERROR, "ALTER TABLE: cannot change system attribute \"%s\"", elog(ERROR, "ALTER TABLE: cannot change system attribute \"%s\"",
@ -864,6 +837,7 @@ AlterTableAlterColumnFlags(const char *relationName,
heap_freetuple(tuple); heap_freetuple(tuple);
heap_close(attrelation, NoLock); 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 * ALTER TABLE DROP COLUMN
*/ */
void void
AlterTableDropColumn(const char *relationName, AlterTableDropColumn(Oid myrelid,
bool inh, const char *colName, bool inh, const char *colName,
int behavior) int behavior)
{ {
#ifdef _DROP_COLUMN_HACK__ #ifdef _DROP_COLUMN_HACK__
Relation rel, Relation rel,
attrdesc; attrdesc;
Oid myrelid;
HeapTuple reltup; HeapTuple reltup;
HeapTupleData classtuple; HeapTupleData classtuple;
Buffer buffer; Buffer buffer;
@ -1031,12 +1004,16 @@ AlterTableDropColumn(const char *relationName,
* Grab an exclusive lock on the target table, which we will NOT * Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction. * release until end of transaction.
*/ */
rel = heap_openr(relationName, AccessExclusiveLock); rel = heap_open(myrelid, AccessExclusiveLock);
myrelid = RelationGetRelid(rel);
if (rel->rd_rel->relkind != RELKIND_RELATION) if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", 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, * 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. * 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())) if (!pg_class_ownercheck(myrelid, GetUserId()))
elog(ERROR, "ALTER TABLE: permission denied"); elog(ERROR, "ALTER TABLE: permission denied");
@ -1066,8 +1040,17 @@ AlterTableDropColumn(const char *relationName,
ObjectIdGetDatum(myrelid), ObjectIdGetDatum(myrelid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(reltup)) 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", elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName); myrelname);
}
classtuple.t_self = reltup->t_self; classtuple.t_self = reltup->t_self;
ReleaseSysCache(reltup); ReleaseSysCache(reltup);
@ -1092,8 +1075,17 @@ AlterTableDropColumn(const char *relationName,
PointerGetDatum(colName), PointerGetDatum(colName),
0, 0); 0, 0);
if (!HeapTupleIsValid(tup)) 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\"", elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"",
colName, relationName); colName, myrelname);
}
attribute = (Form_pg_attribute) GETSTRUCT(tup); attribute = (Form_pg_attribute) GETSTRUCT(tup);
attnum = attribute->attnum; attnum = attribute->attnum;
@ -1164,29 +1156,30 @@ AlterTableDropColumn(const char *relationName,
* ALTER TABLE ADD CONSTRAINT * ALTER TABLE ADD CONSTRAINT
*/ */
void void
AlterTableAddConstraint(char *relationName, AlterTableAddConstraint(Oid myrelid,
bool inh, List *newConstraints) bool inh, List *newConstraints)
{ {
Relation rel; Relation rel;
Oid myrelid;
List *listptr; List *listptr;
/* /*
* Grab an exclusive lock on the target table, which we will NOT * Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction. * release until end of transaction.
*/ */
rel = heap_openr(relationName, AccessExclusiveLock); rel = heap_open(myrelid, AccessExclusiveLock);
myrelid = RelationGetRelid(rel);
if (rel->rd_rel->relkind != RELKIND_RELATION) if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", 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", elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
relationName); RelationGetRelationName(rel));
if (!pg_class_ownercheck(myrelid, GetUserId())) if (!pg_class_ownercheck(myrelid, GetUserId()))
elog(ERROR, "ALTER TABLE: permission denied"); elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
RelationGetRelationName(rel));
if (inh) if (inh)
{ {
@ -1204,16 +1197,10 @@ AlterTableAddConstraint(char *relationName,
foreach(child, children) foreach(child, children)
{ {
Oid childrelid = lfirsti(child); Oid childrelid = lfirsti(child);
char *childrelname;
Relation childrel;
if (childrelid == myrelid) if (childrelid == myrelid)
continue; continue;
childrel = heap_open(childrelid, AccessExclusiveLock); AlterTableAddConstraint(childrelid, false, newConstraints);
childrelname = pstrdup(RelationGetRelationName(childrel));
heap_close(childrel, AccessExclusiveLock);
AlterTableAddConstraint(childrelname, false, newConstraints);
pfree(childrelname);
} }
} }
@ -1262,7 +1249,7 @@ AlterTableAddConstraint(char *relationName,
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
rte = addRangeTableEntryForRelation(pstate, rte = addRangeTableEntryForRelation(pstate,
myrelid, myrelid,
makeAlias(relationName, NIL), makeAlias(RelationGetRelationName(rel), NIL),
false, false,
true); true);
addRTEtoQuery(pstate, rte, true, true); addRTEtoQuery(pstate, rte, true, true);
@ -1286,7 +1273,7 @@ AlterTableAddConstraint(char *relationName,
*/ */
if (length(pstate->p_rtable) != 1) if (length(pstate->p_rtable) != 1)
elog(ERROR, "Only relation '%s' can be referenced in CHECK", elog(ERROR, "Only relation '%s' can be referenced in CHECK",
relationName); RelationGetRelationName(rel));
/* /*
* Might as well try to reduce any * Might as well try to reduce any
@ -1358,7 +1345,7 @@ AlterTableAddConstraint(char *relationName,
int count; int count;
if (is_temp_rel_name(fkconstraint->pktable->relname) && 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."); 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; trig.tgargs[0] = fkconstraint->constr_name;
else else
trig.tgargs[0] = "<unknown>"; trig.tgargs[0] = "<unknown>";
trig.tgargs[1] = (char *) relationName; trig.tgargs[1] = pstrdup(RelationGetRelationName(rel));
trig.tgargs[2] = fkconstraint->pktable->relname; trig.tgargs[2] = fkconstraint->pktable->relname;
trig.tgargs[3] = fkconstraint->match_type; trig.tgargs[3] = fkconstraint->match_type;
count = 4; count = 4;
@ -1483,12 +1470,11 @@ AlterTableAddConstraint(char *relationName,
* Christopher Kings-Lynne * Christopher Kings-Lynne
*/ */
void void
AlterTableDropConstraint(const char *relationName, AlterTableDropConstraint(Oid myrelid,
bool inh, const char *constrName, bool inh, const char *constrName,
int behavior) int behavior)
{ {
Relation rel; Relation rel;
Oid myrelid;
int deleted; int deleted;
/* /*
@ -1502,19 +1488,21 @@ AlterTableDropConstraint(const char *relationName,
* Acquire an exclusive lock on the target relation for the duration * Acquire an exclusive lock on the target relation for the duration
* of the operation. * of the operation.
*/ */
rel = heap_openr(relationName, AccessExclusiveLock); rel = heap_open(myrelid, AccessExclusiveLock);
myrelid = RelationGetRelid(rel);
/* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */ /* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */
if (rel->rd_rel->relkind != RELKIND_RELATION) if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", 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", elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
relationName); RelationGetRelationName(rel));
if (!pg_class_ownercheck(myrelid, GetUserId())) 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 * 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 * ALTER TABLE OWNER
*/ */
void void
AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName) AlterTableOwner(Oid relationOid, int32 newOwnerSysId)
{
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)
{ {
Relation target_rel; Relation target_rel;
Relation class_rel; Relation class_rel;
@ -1629,7 +1594,7 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId)
/* For each index, recursively change its ownership */ /* For each index, recursively change its ownership */
foreach(i, index_oid_list) foreach(i, index_oid_list)
{ {
AlterTableOwnerId(lfirsti(i), newOwnerSysId); AlterTableOwner(lfirsti(i), newOwnerSysId);
} }
freeList(index_oid_list); 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 it has a toast table, recurse to change its ownership */
if (tuple_class->reltoastrelid != InvalidOid) if (tuple_class->reltoastrelid != InvalidOid)
{ {
AlterTableOwnerId(tuple_class->reltoastrelid, newOwnerSysId); AlterTableOwner(tuple_class->reltoastrelid, newOwnerSysId);
} }
} }

View File

@ -7,7 +7,7 @@
* Copyright (c) 1999-2001, PostgreSQL Global Development Group * Copyright (c) 1999-2001, PostgreSQL Global Development Group
* *
* IDENTIFICATION * 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 "catalog/pg_type.h"
#include "commands/comment.h" #include "commands/comment.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_agg.h" #include "parser/parse_agg.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h" #include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "parser/parse.h" #include "parser/parse.h"
#include "rewrite/rewriteRemove.h" #include "rewrite/rewriteRemove.h"
#include "utils/acl.h" #include "utils/acl.h"
@ -51,14 +52,16 @@
static void CommentRelation(int objtype, char * schemaname, char *relation, static void CommentRelation(int objtype, char * schemaname, char *relation,
char *comment); 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 CommentDatabase(char *database, char *comment);
static void CommentRewrite(char *rule, char *comment); static void CommentRewrite(char *rule, char *comment);
static void CommentType(char *type, char *comment); static void CommentType(char *type, char *comment);
static void CommentAggregate(char *aggregate, List *arguments, char *comment); static void CommentAggregate(char *aggregate, List *arguments, char *comment);
static void CommentProc(char *function, List *arguments, char *comment); static void CommentProc(char *function, List *arguments, char *comment);
static void CommentOperator(char *opname, 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); CommentRelation(objtype, schemaname, objname, comment);
break; break;
case COLUMN: case COLUMN:
CommentAttribute(objname, objproperty, comment); CommentAttribute(schemaname, objname, objproperty, comment);
break; break;
case DATABASE: case DATABASE:
CommentDatabase(objname, comment); CommentDatabase(objname, comment);
@ -109,7 +112,7 @@ CommentObject(int objtype, char *schemaname, char *objname, char *objproperty,
CommentOperator(objname, objlist, comment); CommentOperator(objname, objlist, comment);
break; break;
case TRIGGER: case TRIGGER:
CommentTrigger(objname, objproperty, comment); CommentTrigger(objname, schemaname, objproperty, comment);
break; break;
default: default:
elog(ERROR, "An attempt was made to comment on a unknown type: %d", 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 static void
CommentAttribute(char *relname, char *attrname, char *comment) CommentAttribute(char *schemaname, char *relname, char *attrname, char *comment)
{ {
RangeVar *rel = makeNode(RangeVar);
Relation relation; Relation relation;
AttrNumber attnum; AttrNumber attnum;
/* Open the containing relation to ensure it won't go away meanwhile */ /* 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 */ /* Check object security */
@ -539,11 +546,8 @@ CommentType(char *type, char *comment)
/* Find the type's oid */ /* Find the type's oid */
oid = GetSysCacheOid(TYPENAME, /* XXX WRONG: need to deal with qualified type names */
PointerGetDatum(type), oid = typenameTypeId(makeTypeName(type));
0, 0, 0);
if (!OidIsValid(oid))
elog(ERROR, "type '%s' does not exist", type);
/* Check object security */ /* Check object security */
@ -570,21 +574,13 @@ static void
CommentAggregate(char *aggregate, List *arguments, char *comment) CommentAggregate(char *aggregate, List *arguments, char *comment)
{ {
TypeName *aggtype = (TypeName *) lfirst(arguments); TypeName *aggtype = (TypeName *) lfirst(arguments);
char *aggtypename;
Oid baseoid, Oid baseoid,
oid; oid;
Oid classoid; Oid classoid;
bool defined;
/* First, attempt to determine the base aggregate oid */ /* First, attempt to determine the base aggregate oid */
if (aggtype) if (aggtype)
{ baseoid = typenameTypeId(aggtype);
aggtypename = TypeNameToInternalName(aggtype);
baseoid = TypeGet(aggtypename, &defined);
if (!OidIsValid(baseoid))
elog(ERROR, "type '%s' does not exist", aggtypename);
}
else else
baseoid = InvalidOid; baseoid = InvalidOid;
@ -648,20 +644,19 @@ CommentProc(char *function, List *arguments, char *comment)
for (i = 0; i < argcount; i++) for (i = 0; i < argcount; i++)
{ {
TypeName *t = (TypeName *) lfirst(arguments); TypeName *t = (TypeName *) lfirst(arguments);
char *typnam = TypeNameToInternalName(t);
argoids[i] = LookupTypeName(t);
if (!OidIsValid(argoids[i]))
{
char *typnam = TypeNameToString(t);
if (strcmp(typnam, "opaque") == 0)
argoids[i] = InvalidOid;
else
elog(ERROR, "Type \"%s\" does not exist", typnam);
}
arguments = lnext(arguments); arguments = lnext(arguments);
if (strcmp(typnam, "opaque") == 0)
argoids[i] = InvalidOid;
else
{
argoids[i] = GetSysCacheOid(TYPENAME,
PointerGetDatum(typnam),
0, 0, 0);
if (!OidIsValid(argoids[i]))
elog(ERROR, "CommentProc: type '%s' not found", typnam);
}
} }
/* Now, find the corresponding oid for this procedure */ /* 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 *typenode1 = (TypeName *) lfirst(arguments);
TypeName *typenode2 = (TypeName *) lsecond(arguments); TypeName *typenode2 = (TypeName *) lsecond(arguments);
char oprtype = 0, char oprtype = 0;
*lefttype = NULL,
*righttype = NULL;
Form_pg_operator data; Form_pg_operator data;
HeapTuple optuple; HeapTuple optuple;
Oid oid, Oid oid,
leftoid = InvalidOid, leftoid = InvalidOid,
rightoid = InvalidOid; rightoid = InvalidOid;
bool defined;
/* Initialize our left and right argument types */
/* Attempt to fetch the left type oid, if specified */
if (typenode1 != NULL) if (typenode1 != NULL)
lefttype = TypeNameToInternalName(typenode1); leftoid = typenameTypeId(typenode1);
/* Attempt to fetch the right type oid, if specified */
if (typenode2 != NULL) if (typenode2 != NULL)
righttype = TypeNameToInternalName(typenode2); rightoid = typenameTypeId(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 */
if (righttype != NULL)
{
rightoid = TypeGet(righttype, &defined);
if (!OidIsValid(rightoid))
elog(ERROR, "right type '%s' does not exist", righttype);
}
/* Determine operator type */ /* Determine operator type */
@ -797,8 +772,9 @@ CommentOperator(char *opername, List *arguments, char *comment)
*/ */
static void 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 pg_trigger,
relation; relation;
HeapTuple triggertuple; HeapTuple triggertuple;
@ -808,7 +784,10 @@ CommentTrigger(char *trigger, char *relname, char *comment)
/* First, validate the user's action */ /* 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())) if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'", elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'",

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 "access/printtup.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
@ -228,7 +229,7 @@ CopyDonePeek(FILE *fp, int c, bool pickup)
/* /*
* DoCopy executes the SQL COPY statement. * 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.) * (<from> = TRUE means we are inserting into the table.)
* *
* If <pipe> is false, transfer is between the table and the file named * 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. * the table.
*/ */
void 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) char *filename, char *delim, char *null_print)
{ {
FILE *fp; 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. * 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. */ /* Check permissions. */
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), 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_RELATION)
{ {
if (rel->rd_rel->relkind == RELKIND_VIEW) 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) 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 else
elog(ERROR, "You cannot copy object %s", relname); elog(ERROR, "You cannot copy object %s",
RelationGetRelationName(rel));
} }
if (pipe) 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_RELATION)
{ {
if (rel->rd_rel->relkind == RELKIND_VIEW) 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) 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 else
elog(ERROR, "You cannot copy object %s", relname); elog(ERROR, "You cannot copy object %s",
RelationGetRelationName(rel));
} }
if (pipe) if (pipe)
{ {

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 "commands/creatinh.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "parser/parse_type.h"
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "utils/temprel.h" #include "utils/temprel.h"
@ -108,7 +109,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
* (BuildDescForRelation takes care of the inherited defaults, but we * (BuildDescForRelation takes care of the inherited defaults, but we
* have to copy inherited constraints here.) * have to copy inherited constraints here.)
*/ */
descriptor = BuildDescForRelation(schema, relname); descriptor = BuildDescForRelation(schema);
if (old_constraints != NIL) if (old_constraints != NIL)
{ {
@ -238,10 +239,12 @@ DefineRelation(CreateStmt *stmt, char relkind)
* themselves will be destroyed, too. * themselves will be destroyed, too.
*/ */
void void
RemoveRelation(const char *name) RemoveRelation(const RangeVar *relation)
{ {
AssertArg(name); Oid relOid;
heap_drop_with_catalog(name, allowSystemTableMods);
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. * Rows are removed, indices are truncated and reconstructed.
*/ */
void void
TruncateRelation(const char *relname) TruncateRelation(const RangeVar *relation)
{ {
Oid relid;
Relation rel; Relation rel;
AssertArg(relname); relid = RangeVarGetRelid(relation, false);
/* Grab exclusive lock in preparation for truncate */ /* Grab exclusive lock in preparation for truncate */
rel = heap_openr(relname, AccessExclusiveLock); rel = heap_open(relid, AccessExclusiveLock);
if (rel->rd_rel->relkind == RELKIND_SEQUENCE) if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
elog(ERROR, "TRUNCATE cannot be used on sequences. '%s' is a sequence", elog(ERROR, "TRUNCATE cannot be used on sequences. '%s' is a sequence",
relname); RelationGetRelationName(rel));
if (rel->rd_rel->relkind == RELKIND_VIEW) if (rel->rd_rel->relkind == RELKIND_VIEW)
elog(ERROR, "TRUNCATE cannot be used on views. '%s' is a 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", elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
relname); RelationGetRelationName(rel));
if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) 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 */ /* Keep the lock until transaction commit */
heap_close(rel, NoLock); heap_close(rel, NoLock);
heap_truncate(relname); heap_truncate(relid);
} }
@ -308,12 +313,7 @@ MergeDomainAttributes(List *schema)
HeapTuple tuple; HeapTuple tuple;
Form_pg_type typeTup; Form_pg_type typeTup;
tuple = SearchSysCache(TYPENAME, tuple = typenameType(coldef->typename);
CStringGetDatum(coldef->typename->name),
0,0,0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "MergeDomainAttributes: Type %s does not exist",
coldef->typename->name);
typeTup = (Form_pg_type) GETSTRUCT(tuple); typeTup = (Form_pg_type) GETSTRUCT(tuple);
if (typeTup->typtype == 'd') if (typeTup->typtype == 'd')
@ -486,26 +486,11 @@ MergeAttributes(List *schema, List *supers, bool istemp,
parent_attno++) parent_attno++)
{ {
Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1]; Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
char *attributeName; char *attributeName = NameStr(attribute->attname);
char *attributeType;
HeapTuple tuple;
int exist_attno; int exist_attno;
ColumnDef *def; ColumnDef *def;
TypeName *typename; 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? * Does it conflict with some previously inherited column?
*/ */
@ -519,10 +504,12 @@ MergeAttributes(List *schema, List *supers, bool istemp,
elog(NOTICE, "CREATE TABLE: merging multiple inherited definitions of attribute \"%s\"", elog(NOTICE, "CREATE TABLE: merging multiple inherited definitions of attribute \"%s\"",
attributeName); attributeName);
def = (ColumnDef *) nth(exist_attno - 1, inhSchema); 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) def->typename->typmod != attribute->atttypmod)
elog(ERROR, "CREATE TABLE: inherited attribute \"%s\" type conflict (%s and %s)", 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 */ /* Merge of NOT NULL constraints = OR 'em together */
def->is_not_null |= attribute->attnotnull; def->is_not_null |= attribute->attnotnull;
/* Default and other constraints are handled below */ /* Default and other constraints are handled below */
@ -536,7 +523,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
def = makeNode(ColumnDef); def = makeNode(ColumnDef);
def->colname = pstrdup(attributeName); def->colname = pstrdup(attributeName);
typename = makeNode(TypeName); typename = makeNode(TypeName);
typename->name = attributeType; typename->typeid = attribute->atttypid;
typename->typmod = attribute->atttypmod; typename->typmod = attribute->atttypmod;
def->typename = typename; def->typename = typename;
def->is_not_null = attribute->attnotnull; def->is_not_null = attribute->attnotnull;
@ -640,7 +627,6 @@ MergeAttributes(List *schema, List *supers, bool istemp,
{ {
ColumnDef *newdef = lfirst(entry); ColumnDef *newdef = lfirst(entry);
char *attributeName = newdef->colname; char *attributeName = newdef->colname;
char *attributeType = newdef->typename->name;
int exist_attno; int exist_attno;
/* /*
@ -658,10 +644,12 @@ MergeAttributes(List *schema, List *supers, bool istemp,
elog(NOTICE, "CREATE TABLE: merging attribute \"%s\" with inherited definition", elog(NOTICE, "CREATE TABLE: merging attribute \"%s\" with inherited definition",
attributeName); attributeName);
def = (ColumnDef *) nth(exist_attno - 1, inhSchema); 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) def->typename->typmod != newdef->typename->typmod)
elog(ERROR, "CREATE TABLE: attribute \"%s\" type conflict (%s and %s)", 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 */ /* Merge of NOT NULL constraints = OR 'em together */
def->is_not_null |= newdef->is_not_null; def->is_not_null |= newdef->is_not_null;
/* If new def has a default, override previous default */ /* If new def has a default, override previous default */

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
@ -41,6 +41,7 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/heap.h" #include "catalog/heap.h"
#include "catalog/namespace.h"
#include "catalog/pg_aggregate.h" #include "catalog/pg_aggregate.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
@ -50,13 +51,19 @@
#include "fmgr.h" #include "fmgr.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "optimizer/cost.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/acl.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
static Oid findTypeIOFunction(const char *procname, bool isOutput);
static char *defGetString(DefElem *def); static char *defGetString(DefElem *def);
static double defGetNumeric(DefElem *def); static double defGetNumeric(DefElem *def);
static TypeName *defGetTypeName(DefElem *def);
static int defGetTypeLength(DefElem *def); static int defGetTypeLength(DefElem *def);
#define DEFAULT_TYPDELIM ',' #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 * Examine the "returns" clause returnType of the CREATE FUNCTION statement
* and return information about it as *prorettype_p and *returnsSet. * 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; *returnsSet_p = returnType->setof;
} }
@ -211,34 +261,31 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
void void
CreateFunction(ProcedureStmt *stmt) CreateFunction(ProcedureStmt *stmt)
{ {
/* pathname of executable file that executes this function, if any */
char *probin_str; char *probin_str;
/* SQL that executes this function, if any */
char *prosrc_str; char *prosrc_str;
/* Type of return value (or member of set of values) from function */ Oid prorettype;
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. */
bool returnsSet; bool returnsSet;
/* char languageName[NAMEDATALEN];
* The following are optional user-supplied attributes of the Oid languageOid;
* function. char *funcname;
*/ Oid namespaceId;
int32 byte_pct, int32 byte_pct,
perbyte_cpu, perbyte_cpu,
percall_cpu, percall_cpu,
outin_ratio; outin_ratio;
bool canCache, bool canCache,
isStrict; isStrict;
HeapTuple languageTuple; HeapTuple languageTuple;
Form_pg_language languageStruct; 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 */ /* Convert language name to canonical case */
case_translate_language_name(stmt->language, languageName); case_translate_language_name(stmt->language, languageName);
/* Look up the language and validate permissions */
languageTuple = SearchSysCache(LANGNAME, languageTuple = SearchSysCache(LANGNAME,
PointerGetDatum(languageName), PointerGetDatum(languageName),
0, 0, 0); 0, 0, 0);
@ -259,21 +306,22 @@ CreateFunction(ProcedureStmt *stmt)
* Convert remaining parameters of CREATE to form wanted by * Convert remaining parameters of CREATE to form wanted by
* ProcedureCreate. * ProcedureCreate.
*/ */
Assert(IsA(stmt->returnType, TypeName)); compute_return_type(stmt->returnType, languageOid,
compute_return_type((TypeName *) stmt->returnType,
&prorettype, &returnsSet); &prorettype, &returnsSet);
compute_full_attributes(stmt->withClause, compute_full_attributes(stmt->withClause,
&byte_pct, &perbyte_cpu, &percall_cpu, &byte_pct, &perbyte_cpu, &percall_cpu,
&outin_ratio, &canCache, &isStrict); &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 * And now that we have all the parameters, and know we're permitted
* to do so, go ahead and create the function. * to do so, go ahead and create the function.
*/ */
ProcedureCreate(stmt->funcname, ProcedureCreate(funcname,
namespaceId,
stmt->replace, stmt->replace,
returnsSet, returnsSet,
prorettype, prorettype,
@ -292,27 +340,28 @@ CreateFunction(ProcedureStmt *stmt)
/* -------------------------------- /*
* DefineOperator * DefineOperator
*
* this function extracts all the information from the * this function extracts all the information from the
* parameter list generated by the parser and then has * parameter list generated by the parser and then has
* OperatorCreate() do all the actual work. * OperatorCreate() do all the actual work.
* *
* 'parameters' is a list of DefElem * 'parameters' is a list of DefElem
* --------------------------------
*/ */
void void
DefineOperator(char *oprName, DefineOperator(List *names, List *parameters)
List *parameters)
{ {
char *oprName;
Oid oprNamespace;
uint16 precedence = 0; /* operator precedence */ uint16 precedence = 0; /* operator precedence */
bool canHash = false; /* operator hashes */ bool canHash = false; /* operator hashes */
bool isLeftAssociative = true; /* operator is left bool isLeftAssociative = true; /* operator is left
* associative */ * associative */
char *functionName = NULL; /* function for operator */ char *functionName = NULL; /* function for operator */
char *typeName1 = NULL; /* first type name */ TypeName *typeName1 = NULL; /* first type name */
char *typeName2 = NULL; /* second type name */ TypeName *typeName2 = NULL; /* second type name */
Oid typeId1 = InvalidOid; /* types converted to OID */
Oid typeId2 = InvalidOid;
char *commutatorName = NULL; /* optional commutator operator char *commutatorName = NULL; /* optional commutator operator
* name */ * name */
char *negatorName = NULL; /* optional negator operator name */ char *negatorName = NULL; /* optional negator operator name */
@ -323,6 +372,9 @@ DefineOperator(char *oprName,
char *sortName2 = NULL; /* optional second sort operator */ char *sortName2 = NULL; /* optional second sort operator */
List *pl; 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. * loop over the definition list and extract the information we need.
*/ */
@ -332,16 +384,14 @@ DefineOperator(char *oprName,
if (strcasecmp(defel->defname, "leftarg") == 0) if (strcasecmp(defel->defname, "leftarg") == 0)
{ {
typeName1 = defGetString(defel); typeName1 = defGetTypeName(defel);
if (IsA(defel->arg, TypeName) && if (typeName1->setof)
((TypeName *) defel->arg)->setof)
elog(ERROR, "setof type not implemented for leftarg"); elog(ERROR, "setof type not implemented for leftarg");
} }
else if (strcasecmp(defel->defname, "rightarg") == 0) else if (strcasecmp(defel->defname, "rightarg") == 0)
{ {
typeName2 = defGetString(defel); typeName2 = defGetTypeName(defel);
if (IsA(defel->arg, TypeName) && if (typeName2->setof)
((TypeName *) defel->arg)->setof)
elog(ERROR, "setof type not implemented for rightarg"); elog(ERROR, "setof type not implemented for rightarg");
} }
else if (strcasecmp(defel->defname, "procedure") == 0) else if (strcasecmp(defel->defname, "procedure") == 0)
@ -367,15 +417,7 @@ DefineOperator(char *oprName,
else if (strcasecmp(defel->defname, "hashes") == 0) else if (strcasecmp(defel->defname, "hashes") == 0)
canHash = TRUE; canHash = TRUE;
else if (strcasecmp(defel->defname, "sort1") == 0) 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); sortName1 = defGetString(defel);
}
else if (strcasecmp(defel->defname, "sort2") == 0) else if (strcasecmp(defel->defname, "sort2") == 0)
sortName2 = defGetString(defel); sortName2 = defGetString(defel);
else else
@ -391,12 +433,18 @@ DefineOperator(char *oprName,
if (functionName == NULL) if (functionName == NULL)
elog(ERROR, "Define: \"procedure\" unspecified"); 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.. * now have OperatorCreate do all the work..
*/ */
OperatorCreate(oprName, /* operator name */ OperatorCreate(oprName, /* operator name */
typeName1, /* first type name */ typeId1, /* left type id */
typeName2, /* second type name */ typeId2, /* right type id */
functionName, /* function for operator */ functionName, /* function for operator */
precedence, /* operator precedence */ precedence, /* operator precedence */
isLeftAssociative, /* operator is left associative */ isLeftAssociative, /* operator is left associative */
@ -412,20 +460,26 @@ DefineOperator(char *oprName,
} }
/* ------------------- /*
* DefineAggregate * DefineAggregate
* ------------------
*/ */
void void
DefineAggregate(char *aggName, List *parameters) DefineAggregate(List *names, List *parameters)
{ {
char *aggName;
Oid aggNamespace;
char *transfuncName = NULL; char *transfuncName = NULL;
char *finalfuncName = NULL; char *finalfuncName = NULL;
char *baseType = NULL; TypeName *baseType = NULL;
char *transType = NULL; TypeName *transType = NULL;
char *initval = NULL; char *initval = NULL;
Oid baseTypeId;
Oid transTypeId;
List *pl; List *pl;
/* Convert list of names to a name and namespace */
aggNamespace = QualifiedNameGetCreationNamespace(names, &aggName);
foreach(pl, parameters) foreach(pl, parameters)
{ {
DefElem *defel = (DefElem *) lfirst(pl); DefElem *defel = (DefElem *) lfirst(pl);
@ -441,11 +495,11 @@ DefineAggregate(char *aggName, List *parameters)
else if (strcasecmp(defel->defname, "finalfunc") == 0) else if (strcasecmp(defel->defname, "finalfunc") == 0)
finalfuncName = defGetString(defel); finalfuncName = defGetString(defel);
else if (strcasecmp(defel->defname, "basetype") == 0) else if (strcasecmp(defel->defname, "basetype") == 0)
baseType = defGetString(defel); baseType = defGetTypeName(defel);
else if (strcasecmp(defel->defname, "stype") == 0) else if (strcasecmp(defel->defname, "stype") == 0)
transType = defGetString(defel); transType = defGetTypeName(defel);
else if (strcasecmp(defel->defname, "stype1") == 0) else if (strcasecmp(defel->defname, "stype1") == 0)
transType = defGetString(defel); transType = defGetTypeName(defel);
else if (strcasecmp(defel->defname, "initcond") == 0) else if (strcasecmp(defel->defname, "initcond") == 0)
initval = defGetString(defel); initval = defGetString(defel);
else if (strcasecmp(defel->defname, "initcond1") == 0) else if (strcasecmp(defel->defname, "initcond1") == 0)
@ -465,14 +519,40 @@ DefineAggregate(char *aggName, List *parameters)
if (transfuncName == NULL) if (transfuncName == NULL)
elog(ERROR, "Define: \"sfunc\" unspecified"); 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 * Most of the argument-checking is done inside of AggregateCreate
*/ */
AggregateCreate(aggName, /* aggregate name */ AggregateCreate(aggName, /* aggregate name */
aggNamespace, /* namespace */
transfuncName, /* step function name */ transfuncName, /* step function name */
finalfuncName, /* final function name */ finalfuncName, /* final function name */
baseType, /* type of data being aggregated */ baseTypeId, /* type of data being aggregated */
transType, /* transition data type */ transTypeId, /* transition data type */
initval); /* initial condition */ initval); /* initial condition */
} }
@ -483,12 +563,14 @@ DefineAggregate(char *aggName, List *parameters)
void void
DefineDomain(CreateDomainStmt *stmt) DefineDomain(CreateDomainStmt *stmt)
{ {
char *domainName;
Oid domainNamespace;
int16 internalLength; int16 internalLength;
int16 externalLength; int16 externalLength;
char *inputName; Oid inputProcedure;
char *outputName; Oid outputProcedure;
char *sendName; Oid receiveProcedure;
char *receiveName; Oid sendProcedure;
bool byValue; bool byValue;
char delimiter; char delimiter;
char alignment; char alignment;
@ -500,46 +582,27 @@ DefineDomain(CreateDomainStmt *stmt)
char *defaultValueBin = NULL; char *defaultValueBin = NULL;
bool typNotNull = false; bool typNotNull = false;
Oid basetypelem; Oid basetypelem;
char *elemName = NULL; int32 typNDims = length(stmt->typename->arrayBounds);
int32 typNDims = 0; /* No array dimensions by default */
HeapTuple typeTup; HeapTuple typeTup;
char *typeName = stmt->typename->name;
List *schema = stmt->constraints; List *schema = stmt->constraints;
List *listptr; 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 '_' * Domainnames, unlike typenames don't need to account for the '_'
* prefix. So they can be one character longer. * 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", elog(ERROR, "CREATE DOMAIN: domain names must be %d characters or less",
NAMEDATALEN - 1); 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 * Look up the base type.
* the name here. We receive the base types name. Lets set Dims while
* were at it.
*/ */
if (stmt->typename->arrayBounds > 0) { typeTup = typenameType(stmt->typename);
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);
/* /*
* What we really don't want is domains of domains. This could cause all sorts * 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; typtype = ((Form_pg_type) GETSTRUCT(typeTup))->typtype;
if (typtype != 'b') if (typtype != 'b')
elog(ERROR, "DefineDomain: %s is not a basetype", elog(ERROR, "DefineDomain: %s is not a basetype",
stmt->typename->name); TypeNameToString(stmt->typename));
/* passed by value */ /* passed by value */
byValue = ((Form_pg_type) GETSTRUCT(typeTup))->typbyval; byValue = ((Form_pg_type) GETSTRUCT(typeTup))->typbyval;
@ -570,43 +633,20 @@ DefineDomain(CreateDomainStmt *stmt)
/* Array element Delimiter */ /* Array element Delimiter */
delimiter = ((Form_pg_type) GETSTRUCT(typeTup))->typdelim; delimiter = ((Form_pg_type) GETSTRUCT(typeTup))->typdelim;
/* /* I/O Functions */
* XXX this is pretty bogus: should be passing function OIDs to inputProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typinput;
* TypeCreate, not names which aren't unique. outputProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typoutput;
*/ receiveProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typreceive;
sendProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typsend;
/* 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));
/* Inherited default value */ /* Inherited default value */
datum = SysCacheGetAttr(TYPENAME, typeTup, datum = SysCacheGetAttr(TYPEOID, typeTup,
Anum_pg_type_typdefault, &isnull); Anum_pg_type_typdefault, &isnull);
if (!isnull) if (!isnull)
defaultValue = DatumGetCString(DirectFunctionCall1(textout, datum)); defaultValue = DatumGetCString(DirectFunctionCall1(textout, datum));
/* Inherited default binary value */ /* Inherited default binary value */
datum = SysCacheGetAttr(TYPENAME, typeTup, datum = SysCacheGetAttr(TYPEOID, typeTup,
Anum_pg_type_typdefaultbin, &isnull); Anum_pg_type_typdefaultbin, &isnull);
if (!isnull) if (!isnull)
defaultValueBin = DatumGetCString(DirectFunctionCall1(textout, datum)); defaultValueBin = DatumGetCString(DirectFunctionCall1(textout, datum));
@ -617,16 +657,6 @@ DefineDomain(CreateDomainStmt *stmt)
* This is what enables us to make a domain of an array * This is what enables us to make a domain of an array
*/ */
basetypelem = ((Form_pg_type) GETSTRUCT(typeTup))->typelem; 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 * Run through constraints manually to avoid the additional
@ -661,14 +691,14 @@ DefineDomain(CreateDomainStmt *stmt)
expr = cookDefault(pstate, colDef->raw_expr, expr = cookDefault(pstate, colDef->raw_expr,
typeTup->t_data->t_oid, typeTup->t_data->t_oid,
stmt->typename->typmod, stmt->typename->typmod,
stmt->typename->name); domainName);
/* /*
* Expression must be stored as a nodeToString result, * Expression must be stored as a nodeToString result,
* but we also require a valid textual representation * but we also require a valid textual representation
* (mainly to make life easier for pg_dump). * (mainly to make life easier for pg_dump).
*/ */
defaultValue = deparse_expression(expr, defaultValue = deparse_expression(expr,
deparse_context_for(stmt->domainname, deparse_context_for(domainName,
InvalidOid), InvalidOid),
false); false);
defaultValueBin = nodeToString(expr); defaultValueBin = nodeToString(expr);
@ -723,19 +753,20 @@ DefineDomain(CreateDomainStmt *stmt)
/* /*
* Have TypeCreate do all the real work. * 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, /* preassigned type oid (not done here) */
InvalidOid, /* relation oid (n/a here) */ InvalidOid, /* relation oid (n/a here) */
internalLength, /* internal size */ internalLength, /* internal size */
externalLength, /* external size */ externalLength, /* external size */
'd', /* type-type (domain type) */ 'd', /* type-type (domain type) */
delimiter, /* array element delimiter */ delimiter, /* array element delimiter */
inputName, /* input procedure */ inputProcedure, /* input procedure */
outputName, /* output procedure */ outputProcedure, /* output procedure */
receiveName, /* receive procedure */ receiveProcedure, /* receive procedure */
sendName, /* send procedure */ sendProcedure, /* send procedure */
elemName, /* element type name */ basetypelem, /* element type ID */
typeName, /* base type name */ typeTup->t_data->t_oid, /* base type ID */
defaultValue, /* default type value (text) */ defaultValue, /* default type value (text) */
defaultValueBin, /* default type value (binary) */ defaultValueBin, /* default type value (binary) */
byValue, /* passed by value */ byValue, /* passed by value */
@ -743,7 +774,7 @@ DefineDomain(CreateDomainStmt *stmt)
storage, /* TOAST strategy */ storage, /* TOAST strategy */
stmt->typename->typmod, /* typeMod value */ stmt->typename->typmod, /* typeMod value */
typNDims, /* Array dimensions for base type */ typNDims, /* Array dimensions for base type */
typNotNull); /* Type NOT NULL */ typNotNull); /* Type NOT NULL */
/* /*
* Now we can clean up. * Now we can clean up.
@ -756,11 +787,13 @@ DefineDomain(CreateDomainStmt *stmt)
* Registers a new type. * Registers a new type.
*/ */
void void
DefineType(char *typeName, List *parameters) DefineType(List *names, List *parameters)
{ {
char *typeName;
Oid typeNamespace;
int16 internalLength = -1; /* int2 */ int16 internalLength = -1; /* int2 */
int16 externalLength = -1; /* int2 */ int16 externalLength = -1; /* int2 */
char *elemName = NULL; Oid elemType = InvalidOid;
char *inputName = NULL; char *inputName = NULL;
char *outputName = NULL; char *outputName = NULL;
char *sendName = NULL; char *sendName = NULL;
@ -768,10 +801,18 @@ DefineType(char *typeName, List *parameters)
char *defaultValue = NULL; char *defaultValue = NULL;
bool byValue = false; bool byValue = false;
char delimiter = DEFAULT_TYPDELIM; char delimiter = DEFAULT_TYPDELIM;
char *shadow_type;
List *pl;
char alignment = 'i'; /* default alignment */ char alignment = 'i'; /* default alignment */
char storage = 'p'; /* default TOAST storage method */ 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 * Type names must be one character shorter than other names, allowing
@ -796,16 +837,16 @@ DefineType(char *typeName, List *parameters)
outputName = defGetString(defel); outputName = defGetString(defel);
else if (strcasecmp(defel->defname, "send") == 0) else if (strcasecmp(defel->defname, "send") == 0)
sendName = defGetString(defel); sendName = defGetString(defel);
else if (strcasecmp(defel->defname, "receive") == 0)
receiveName = defGetString(defel);
else if (strcasecmp(defel->defname, "delimiter") == 0) else if (strcasecmp(defel->defname, "delimiter") == 0)
{ {
char *p = defGetString(defel); char *p = defGetString(defel);
delimiter = p[0]; delimiter = p[0];
} }
else if (strcasecmp(defel->defname, "receive") == 0)
receiveName = defGetString(defel);
else if (strcasecmp(defel->defname, "element") == 0) else if (strcasecmp(defel->defname, "element") == 0)
elemName = defGetString(defel); elemType = typenameTypeId(defGetTypeName(defel));
else if (strcasecmp(defel->defname, "default") == 0) else if (strcasecmp(defel->defname, "default") == 0)
defaultValue = defGetString(defel); defaultValue = defGetString(defel);
else if (strcasecmp(defel->defname, "passedbyvalue") == 0) else if (strcasecmp(defel->defname, "passedbyvalue") == 0)
@ -867,30 +908,44 @@ DefineType(char *typeName, List *parameters)
if (outputName == NULL) if (outputName == NULL)
elog(ERROR, "Define: \"output\" unspecified"); 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. * now have TypeCreate do all the real work.
*/ */
TypeCreate(typeName, /* type name */ typoid =
InvalidOid, /* preassigned type oid (not done here) */ TypeCreate(typeName, /* type name */
InvalidOid, /* relation oid (n/a here) */ typeNamespace, /* namespace */
internalLength, /* internal size */ InvalidOid, /* preassigned type oid (not done here) */
externalLength, /* external size */ InvalidOid, /* relation oid (n/a here) */
'b', /* type-type (base type) */ internalLength, /* internal size */
delimiter, /* array element delimiter */ externalLength, /* external size */
inputName, /* input procedure */ 'b', /* type-type (base type) */
outputName, /* output procedure */ delimiter, /* array element delimiter */
receiveName, /* receive procedure */ inputOid, /* input procedure */
sendName, /* send procedure */ outputOid, /* output procedure */
elemName, /* element type name */ receiveOid, /* receive procedure */
NULL, /* base type name (only for domains) */ sendOid, /* send procedure */
defaultValue, /* default type value */ elemType, /* element type ID */
NULL, /* no binary form available */ InvalidOid, /* base type ID (only for domains) */
byValue, /* passed by value */ defaultValue, /* default type value */
alignment, /* required alignment */ NULL, /* no binary form available */
storage, /* TOAST strategy */ byValue, /* passed by value */
-1, /* typMod (Domains only) */ alignment, /* required alignment */
0, /* Array Dimensions of typbasetype */ storage, /* TOAST strategy */
'f'); /* Type NOT NULL */ -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 * 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'; alignment = (alignment == 'd') ? 'd' : 'i';
TypeCreate(shadow_type, /* type name */ TypeCreate(shadow_type, /* type name */
typeNamespace, /* namespace */
InvalidOid, /* preassigned type oid (not done here) */ InvalidOid, /* preassigned type oid (not done here) */
InvalidOid, /* relation oid (n/a here) */ InvalidOid, /* relation oid (n/a here) */
-1, /* internal size */ -1, /* internal size */
-1, /* external size */ -1, /* external size */
'b', /* type-type (base type) */ 'b', /* type-type (base type) */
DEFAULT_TYPDELIM, /* array element delimiter */ DEFAULT_TYPDELIM, /* array element delimiter */
"array_in", /* input procedure */ F_ARRAY_IN, /* input procedure */
"array_out", /* output procedure */ F_ARRAY_OUT, /* output procedure */
"array_in", /* receive procedure */ F_ARRAY_IN, /* receive procedure */
"array_out", /* send procedure */ F_ARRAY_OUT, /* send procedure */
typeName, /* element type name */ typoid, /* element type ID */
NULL, /* base type name */ InvalidOid, /* base type ID */
NULL, /* never a default type value */ NULL, /* never a default type value */
NULL, /* binary default isn't sent either */ NULL, /* binary default isn't sent either */
false, /* never passed by value */ false, /* never passed by value */
@ -921,11 +977,65 @@ DefineType(char *typeName, List *parameters)
'x', /* ARRAY is always toastable */ 'x', /* ARRAY is always toastable */
-1, /* typMod (Domains only) */ -1, /* typMod (Domains only) */
0, /* Array dimensions of typbasetype */ 0, /* Array dimensions of typbasetype */
'f'); /* Type NOT NULL */ false); /* Type NOT NULL */
pfree(shadow_type); 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 * static char *
defGetString(DefElem *def) defGetString(DefElem *def)
{ {
@ -951,7 +1061,7 @@ defGetString(DefElem *def)
case T_String: case T_String:
return strVal(def->arg); return strVal(def->arg);
case T_TypeName: case T_TypeName:
return TypeNameToInternalName((TypeName *) def->arg); return TypeNameToString((TypeName *) def->arg);
default: default:
elog(ERROR, "Define: cannot interpret argument of \"%s\"", elog(ERROR, "Define: cannot interpret argument of \"%s\"",
def->defname); def->defname);
@ -978,6 +1088,32 @@ defGetNumeric(DefElem *def)
return 0; /* keep compiler quiet */ 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 static int
defGetTypeLength(DefElem *def) defGetTypeLength(DefElem *def)
{ {
@ -998,7 +1134,7 @@ defGetTypeLength(DefElem *def)
break; break;
case T_TypeName: case T_TypeName:
/* cope if grammar chooses to believe "variable" is a 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) "variable") == 0)
return -1; /* variable length */ return -1; /* variable length */
break; break;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 "miscadmin.h"
#include "parser/parse.h" #include "parser/parse.h"
#include "parser/parse_agg.h" #include "parser/parse_agg.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h" #include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/syscache.h" #include "utils/syscache.h"
@ -43,29 +43,20 @@
*/ */
void void
RemoveOperator(char *operatorName, /* operator name */ RemoveOperator(char *operatorName, /* operator name */
char *typeName1, /* left argument type name */ TypeName *typeName1, /* left argument type name */
char *typeName2) /* right argument type name */ TypeName *typeName2) /* right argument type name */
{ {
Relation relation; Relation relation;
HeapTuple tup; HeapTuple tup;
Oid typeId1 = InvalidOid; Oid typeId1 = InvalidOid;
Oid typeId2 = InvalidOid; Oid typeId2 = InvalidOid;
bool defined;
char oprtype; char oprtype;
if (typeName1) if (typeName1)
{ typeId1 = typenameTypeId(typeName1);
typeId1 = TypeGet(typeName1, &defined);
if (!OidIsValid(typeId1))
elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName1);
}
if (typeName2) if (typeName2)
{ typeId2 = typenameTypeId(typeName2);
typeId2 = TypeGet(typeName2, &defined);
if (!OidIsValid(typeId2))
elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName2);
}
if (OidIsValid(typeId1) && OidIsValid(typeId2)) if (OidIsValid(typeId1) && OidIsValid(typeId2))
oprtype = 'b'; oprtype = 'b';
@ -99,20 +90,20 @@ RemoveOperator(char *operatorName, /* operator name */
{ {
elog(ERROR, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist", elog(ERROR, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
operatorName, operatorName,
typeName1, TypeNameToString(typeName1),
typeName2); TypeNameToString(typeName2));
} }
else if (OidIsValid(typeId1)) else if (OidIsValid(typeId1))
{ {
elog(ERROR, "RemoveOperator: right unary operator '%s' taking '%s' does not exist", elog(ERROR, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
operatorName, operatorName,
typeName1); TypeNameToString(typeName1));
} }
else else
{ {
elog(ERROR, "RemoveOperator: left unary operator '%s' taking '%s' does not exist", elog(ERROR, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
operatorName, operatorName,
typeName2); TypeNameToString(typeName2));
} }
} }
heap_freetuple(tup); heap_freetuple(tup);
@ -213,16 +204,13 @@ AttributeAndRelationRemove(Oid typeOid)
rel = heap_openr(RelationRelationName, RowExclusiveLock); rel = heap_openr(RelationRelationName, RowExclusiveLock);
while (PointerIsValid((char *) optr->next)) 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); scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
tup = heap_getnext(scan, 0); tup = heap_getnext(scan, 0);
if (HeapTupleIsValid(tup)) if (HeapTupleIsValid(tup))
{ heap_drop_with_catalog(relOid, allowSystemTableMods);
char *name;
name = NameStr(((Form_pg_class) GETSTRUCT(tup))->relname);
heap_drop_with_catalog(name, allowSystemTableMods);
}
heap_endscan(scan); heap_endscan(scan);
} }
heap_close(rel, RowExclusiveLock); heap_close(rel, RowExclusiveLock);
@ -231,42 +219,68 @@ AttributeAndRelationRemove(Oid typeOid)
/* /*
* TypeRemove * TypeRemove
* Removes the type 'typeName' and all attributes and relations that * Removes a datatype.
* use it. *
* NOTE: since this tries to remove the associated array type too, it'll
* only work on scalar types.
*/ */
void void
RemoveType(char *typeName) /* type name to be removed */ RemoveType(List *names)
{ {
TypeName *typename;
Relation relation; Relation relation;
Oid typeoid;
HeapTuple tup; 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); relation = heap_openr(TypeRelationName, RowExclusiveLock);
tup = SearchSysCache(TYPENAME, /* Use LookupTypeName here so that shell types can be removed. */
PointerGetDatum(typeName), typeoid = LookupTypeName(typename);
if (!OidIsValid(typeoid))
elog(ERROR, "Type \"%s\" does not exist",
TypeNameToString(typename));
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typeoid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) 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", elog(ERROR, "RemoveType: type '%s': permission denied",
typeName); TypeNameToString(typename));
/* Delete any comments associated with this type */ /* 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); simple_heap_delete(relation, &tup->t_self);
ReleaseSysCache(tup); ReleaseSysCache(tup);
/* Also, delete the "array of" that type */ /* Now, delete the "array of" that type */
shadow_type = makeArrayTypeName(typeName); typename->arrayBounds = makeList1(makeInteger(1));
tup = SearchSysCache(TYPENAME,
PointerGetDatum(shadow_type), typeoid = LookupTypeName(typename);
if (!OidIsValid(typeoid))
elog(ERROR, "Type \"%s\" does not exist",
TypeNameToString(typename));
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typeoid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) 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); simple_heap_delete(relation, &tup->t_self);
@ -277,13 +291,14 @@ RemoveType(char *typeName) /* type name to be removed */
/* /*
* RemoveDomain * RemoveDomain
* Removes the domain 'typeName' and all attributes and relations that * Removes a domain.
* use it.
*/ */
void void
RemoveDomain(char *domainName, int behavior) RemoveDomain(List *names, int behavior)
{ {
TypeName *typename;
Relation relation; Relation relation;
Oid typeoid;
HeapTuple tup; HeapTuple tup;
char typtype; char typtype;
@ -291,31 +306,44 @@ RemoveDomain(char *domainName, int behavior)
if (behavior == CASCADE) if (behavior == CASCADE)
elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword"); 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); relation = heap_openr(TypeRelationName, RowExclusiveLock);
tup = SearchSysCache(TYPENAME, typeoid = typenameTypeId(typename);
PointerGetDatum(domainName),
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typeoid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) 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", elog(ERROR, "RemoveDomain: type '%s': permission denied",
domainName); TypeNameToString(typename));
/* Check that this is actually a domain */ /* Check that this is actually a domain */
typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype; typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype;
if (typtype != 'd') 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 */ /* 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); simple_heap_delete(relation, &tup->t_self);
ReleaseSysCache(tup); ReleaseSysCache(tup);
/* At present, domains don't have associated array types */
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
} }
@ -345,20 +373,19 @@ RemoveFunction(char *functionName, /* function name to be removed */
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
{ {
TypeName *t = (TypeName *) lfirst(argTypes); TypeName *t = (TypeName *) lfirst(argTypes);
char *typnam = TypeNameToInternalName(t);
argList[i] = LookupTypeName(t);
if (!OidIsValid(argList[i]))
{
char *typnam = TypeNameToString(t);
if (strcmp(typnam, "opaque") == 0)
argList[i] = InvalidOid;
else
elog(ERROR, "Type \"%s\" does not exist", typnam);
}
argTypes = lnext(argTypes); argTypes = lnext(argTypes);
if (strcmp(typnam, "opaque") == 0)
argList[i] = InvalidOid;
else
{
argList[i] = GetSysCacheOid(TYPENAME,
PointerGetDatum(typnam),
0, 0, 0);
if (!OidIsValid(argList[i]))
elog(ERROR, "RemoveFunction: type '%s' not found", typnam);
}
} }
relation = heap_openr(ProcedureRelationName, RowExclusiveLock); relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
@ -393,12 +420,11 @@ RemoveFunction(char *functionName, /* function name to be removed */
} }
void void
RemoveAggregate(char *aggName, char *aggType) RemoveAggregate(char *aggName, TypeName *aggType)
{ {
Relation relation; Relation relation;
HeapTuple tup; HeapTuple tup;
Oid basetypeID; Oid basetypeID;
bool defined;
/* /*
* if a basetype is passed in, then attempt to find an aggregate for * if a basetype is passed in, then attempt to find an aggregate for
@ -410,11 +436,7 @@ RemoveAggregate(char *aggName, char *aggType)
*/ */
if (aggType) if (aggType)
{ basetypeID = typenameTypeId(aggType);
basetypeID = TypeGet(aggType, &defined);
if (!OidIsValid(basetypeID))
elog(ERROR, "RemoveAggregate: type '%s' does not exist", aggType);
}
else else
basetypeID = InvalidOid; basetypeID = InvalidOid;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * delete original attribute from attribute catalog
*/ */
void void
renameatt(char *relname, renameatt(Oid relid,
char *oldattname, char *oldattname,
char *newattname, char *newattname,
int recurse) bool recurse)
{ {
Relation targetrelation; Relation targetrelation;
Relation attrelation; Relation attrelation;
HeapTuple reltup, HeapTuple atttup;
atttup;
Oid relid;
List *indexoidlist; List *indexoidlist;
List *indexoidscan; List *indexoidscan;
@ -86,8 +84,7 @@ renameatt(char *relname,
* Grab an exclusive lock on the target table, which we will NOT * Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction. * release until end of transaction.
*/ */
targetrelation = heap_openr(relname, AccessExclusiveLock); targetrelation = heap_open(relid, AccessExclusiveLock);
relid = RelationGetRelid(targetrelation);
/* /*
* permissions checking. this would normally be done in utility.c, * 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. * 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", elog(ERROR, "renameatt: class \"%s\" is a system catalog",
relname); RelationGetRelationName(targetrelation));
if (!pg_class_ownercheck(relid, GetUserId())) if (!pg_class_ownercheck(relid, GetUserId()))
elog(ERROR, "renameatt: you do not own class \"%s\"", 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 * if the 'recurse' flag is set then we are supposed to rename this
@ -127,25 +125,11 @@ renameatt(char *relname,
foreach(child, children) foreach(child, children)
{ {
Oid childrelid = lfirsti(child); Oid childrelid = lfirsti(child);
char childname[NAMEDATALEN];
if (childrelid == relid) if (childrelid == relid)
continue; 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! */ /* 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. * Also rename the associated type, if any.
*/ */
if (relkind != RELKIND_INDEX) 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. * If it's a view, must also rename the associated ON SELECT rule.

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 <ctype.h>
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/pg_type.h"
#include "commands/creatinh.h" #include "commands/creatinh.h"
#include "commands/sequence.h" #include "commands/sequence.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -85,8 +86,6 @@ DefineSequence(CreateSeqStmt *seq)
{ {
FormData_pg_sequence new; FormData_pg_sequence new;
CreateStmt *stmt = makeNode(CreateStmt); CreateStmt *stmt = makeNode(CreateStmt);
ColumnDef *coldef;
TypeName *typnam;
Oid seqoid; Oid seqoid;
Relation rel; Relation rel;
Buffer buf; Buffer buf;
@ -108,9 +107,12 @@ DefineSequence(CreateSeqStmt *seq)
stmt->tableElts = NIL; stmt->tableElts = NIL;
for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++) for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
{ {
ColumnDef *coldef;
TypeName *typnam;
typnam = makeNode(TypeName); typnam = makeNode(TypeName);
typnam->setof = FALSE; typnam->setof = FALSE;
typnam->arrayBounds = NULL; typnam->arrayBounds = NIL;
typnam->typmod = -1; typnam->typmod = -1;
coldef = makeNode(ColumnDef); coldef = makeNode(ColumnDef);
coldef->typename = typnam; coldef->typename = typnam;
@ -122,48 +124,48 @@ DefineSequence(CreateSeqStmt *seq)
switch (i) switch (i)
{ {
case SEQ_COL_NAME: case SEQ_COL_NAME:
typnam->name = "name"; typnam->typeid = NAMEOID;
coldef->colname = "sequence_name"; coldef->colname = "sequence_name";
namestrcpy(&name, seq->sequence->relname); namestrcpy(&name, seq->sequence->relname);
value[i - 1] = NameGetDatum(&name); value[i - 1] = NameGetDatum(&name);
break; break;
case SEQ_COL_LASTVAL: case SEQ_COL_LASTVAL:
typnam->name = "int8"; typnam->typeid = INT8OID;
coldef->colname = "last_value"; coldef->colname = "last_value";
value[i - 1] = Int64GetDatumFast(new.last_value); value[i - 1] = Int64GetDatumFast(new.last_value);
break; break;
case SEQ_COL_INCBY: case SEQ_COL_INCBY:
typnam->name = "int8"; typnam->typeid = INT8OID;
coldef->colname = "increment_by"; coldef->colname = "increment_by";
value[i - 1] = Int64GetDatumFast(new.increment_by); value[i - 1] = Int64GetDatumFast(new.increment_by);
break; break;
case SEQ_COL_MAXVALUE: case SEQ_COL_MAXVALUE:
typnam->name = "int8"; typnam->typeid = INT8OID;
coldef->colname = "max_value"; coldef->colname = "max_value";
value[i - 1] = Int64GetDatumFast(new.max_value); value[i - 1] = Int64GetDatumFast(new.max_value);
break; break;
case SEQ_COL_MINVALUE: case SEQ_COL_MINVALUE:
typnam->name = "int8"; typnam->typeid = INT8OID;
coldef->colname = "min_value"; coldef->colname = "min_value";
value[i - 1] = Int64GetDatumFast(new.min_value); value[i - 1] = Int64GetDatumFast(new.min_value);
break; break;
case SEQ_COL_CACHE: case SEQ_COL_CACHE:
typnam->name = "int8"; typnam->typeid = INT8OID;
coldef->colname = "cache_value"; coldef->colname = "cache_value";
value[i - 1] = Int64GetDatumFast(new.cache_value); value[i - 1] = Int64GetDatumFast(new.cache_value);
break; break;
case SEQ_COL_LOG: case SEQ_COL_LOG:
typnam->name = "int8"; typnam->typeid = INT8OID;
coldef->colname = "log_cnt"; coldef->colname = "log_cnt";
value[i - 1] = Int64GetDatum((int64) 1); value[i - 1] = Int64GetDatum((int64) 1);
break; break;
case SEQ_COL_CYCLE: case SEQ_COL_CYCLE:
typnam->name = "bool"; typnam->typeid = BOOLOID;
coldef->colname = "is_cycled"; coldef->colname = "is_cycled";
value[i - 1] = BoolGetDatum(new.is_cycled); value[i - 1] = BoolGetDatum(new.is_cycled);
break; break;
case SEQ_COL_CALLED: case SEQ_COL_CALLED:
typnam->name = "bool"; typnam->typeid = BOOLOID;
coldef->colname = "is_called"; coldef->colname = "is_called";
value[i - 1] = BoolGetDatum(false); value[i - 1] = BoolGetDatum(false);
break; break;

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 "access/xact.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
#include "catalog/pg_type.h"
#include "commands/variable.h" #include "commands/variable.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "optimizer/cost.h" #include "optimizer/cost.h"
#include "optimizer/paths.h" #include "optimizer/paths.h"
#include "parser/parse_expr.h" #include "parser/parse_type.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/date.h" #include "utils/date.h"
#include "utils/guc.h" #include "utils/guc.h"
@ -390,7 +391,9 @@ parse_timezone(List *args)
type = p->typename; type = p->typename;
if (type != NULL) if (type != NULL)
{ {
if (strcmp(type->name, "interval") == 0) Oid typeOid = typenameTypeId(type);
if (typeOid == INTERVALOID)
{ {
Interval *interval; Interval *interval;
@ -402,7 +405,7 @@ parse_timezone(List *args)
elog(ERROR, "SET TIME ZONE illegal INTERVAL; month not allowed"); elog(ERROR, "SET TIME ZONE illegal INTERVAL; month not allowed");
CTimeZone = interval->time; CTimeZone = interval->time;
} }
else if (strcmp(type->name, "float8") == 0) else if (typeOid == FLOAT8OID)
{ {
float8 time; float8 time;
@ -414,7 +417,7 @@ parse_timezone(List *args)
* We do not actually generate an integer constant in gram.y * We do not actually generate an integer constant in gram.y
* so this is not used... * so this is not used...
*/ */
else if (strcmp(type->name, "int4") == 0) else if (typeOid == INT4OID)
{ {
int32 time; int32 time;

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 "access/xact.h"
#include "catalog/heap.h" #include "catalog/heap.h"
#include "catalog/namespace.h"
#include "commands/creatinh.h" #include "commands/creatinh.h"
#include "commands/view.h" #include "commands/view.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -24,6 +25,7 @@
#include "rewrite/rewriteManip.h" #include "rewrite/rewriteManip.h"
#include "rewrite/rewriteRemove.h" #include "rewrite/rewriteRemove.h"
#include "rewrite/rewriteSupport.h" #include "rewrite/rewriteSupport.h"
#include "utils/syscache.h"
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
@ -38,10 +40,9 @@
*--------------------------------------------------------------------- *---------------------------------------------------------------------
*/ */
static Oid static Oid
DefineVirtualRelation(char *relname, List *tlist) DefineVirtualRelation(const RangeVar *relation, List *tlist)
{ {
CreateStmt *createStmt = makeNode(CreateStmt); CreateStmt *createStmt = makeNode(CreateStmt);
RangeVar *rel = makeNode(RangeVar);
List *attrList, List *attrList,
*t; *t;
@ -57,14 +58,12 @@ DefineVirtualRelation(char *relname, List *tlist)
if (!res->resjunk) if (!res->resjunk)
{ {
char *resname = res->resname;
char *restypename = typeidTypeName(res->restype);
ColumnDef *def = makeNode(ColumnDef); ColumnDef *def = makeNode(ColumnDef);
TypeName *typename = makeNode(TypeName); 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; typename->typmod = res->restypmod;
def->typename = typename; def->typename = typename;
@ -84,10 +83,7 @@ DefineVirtualRelation(char *relname, List *tlist)
* now create the parameters for keys/inheritance etc. All of them are * now create the parameters for keys/inheritance etc. All of them are
* nil... * nil...
*/ */
rel->relname = relname; createStmt->relation = (RangeVar *) relation;
rel->schemaname = NULL; /* XXX wrong */
rel->istemp = false;
createStmt->relation = rel;
createStmt->tableElts = attrList; createStmt->tableElts = attrList;
createStmt->inhRelations = NIL; createStmt->inhRelations = NIL;
createStmt->constraints = NIL; createStmt->constraints = NIL;
@ -100,25 +96,19 @@ DefineVirtualRelation(char *relname, List *tlist)
} }
static RuleStmt * static RuleStmt *
FormViewRetrieveRule(char *viewName, Query *viewParse) FormViewRetrieveRule(const RangeVar *view, Query *viewParse)
{ {
RuleStmt *rule; RuleStmt *rule;
char *rname; char *rname;
RangeVar *rel;
/* /*
* Create a RuleStmt that corresponds to the suitable rewrite rule * Create a RuleStmt that corresponds to the suitable rewrite rule
* args for DefineQueryRewrite(); * args for DefineQueryRewrite();
*/ */
rname = MakeRetrieveViewRuleName(viewName); rname = MakeRetrieveViewRuleName(view->relname);
rel = makeNode(RangeVar);
rel->relname = pstrdup(viewName);
rel->inhOpt = INH_NO;
rel->alias = NULL;
rule = makeNode(RuleStmt); rule = makeNode(RuleStmt);
rule->relation = rel; rule->relation = copyObject((RangeVar *) view);
rule->rulename = pstrdup(rname); rule->rulename = pstrdup(rname);
rule->whereClause = NULL; rule->whereClause = NULL;
rule->event = CMD_SELECT; rule->event = CMD_SELECT;
@ -129,7 +119,7 @@ FormViewRetrieveRule(char *viewName, Query *viewParse)
} }
static void static void
DefineViewRules(char *viewName, Query *viewParse) DefineViewRules(const RangeVar *view, Query *viewParse)
{ {
RuleStmt *retrieve_rule; RuleStmt *retrieve_rule;
@ -139,13 +129,13 @@ DefineViewRules(char *viewName, Query *viewParse)
RuleStmt *delete_rule; RuleStmt *delete_rule;
#endif #endif
retrieve_rule = FormViewRetrieveRule(viewName, viewParse); retrieve_rule = FormViewRetrieveRule(view, viewParse);
#ifdef NOTYET #ifdef NOTYET
replace_rule = FormViewReplaceRule(viewName, viewParse); replace_rule = FormViewReplaceRule(view, viewParse);
append_rule = FormViewAppendRule(viewName, viewParse); append_rule = FormViewAppendRule(view, viewParse);
delete_rule = FormViewDeleteRule(viewName, viewParse); delete_rule = FormViewDeleteRule(view, viewParse);
#endif #endif
DefineQueryRewrite(retrieve_rule); DefineQueryRewrite(retrieve_rule);
@ -231,7 +221,7 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
*------------------------------------------------------------------- *-------------------------------------------------------------------
*/ */
void void
DefineView(char *viewName, Query *viewParse) DefineView(const RangeVar *view, Query *viewParse)
{ {
Oid viewOid; Oid viewOid;
@ -240,7 +230,7 @@ DefineView(char *viewName, Query *viewParse)
* *
* NOTE: if it already exists, the xact will be aborted. * 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 * 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. * Now create the rules associated with the view.
*/ */
DefineViewRules(viewName, viewParse); DefineViewRules(view, viewParse);
} }
/*------------------------------------------------------------------ /*------------------------------------------------------------------
@ -268,11 +258,14 @@ DefineView(char *viewName, Query *viewParse)
*------------------------------------------------------------------ *------------------------------------------------------------------
*/ */
void 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 * We just have to drop the relation; the associated rules will be
* cleaned up automatically. * cleaned up automatically.
*/ */
heap_drop_with_catalog(viewName, allowSystemTableMods); heap_drop_with_catalog(viewOid, allowSystemTableMods);
} }

View File

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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); TypeName *newnode = makeNode(TypeName);
if (from->name) Node_Copy(from, newnode, names);
newnode->name = pstrdup(from->name); newnode->typeid = from->typeid;
newnode->timezone = from->timezone; newnode->timezone = from->timezone;
newnode->setof = from->setof; newnode->setof = from->setof;
newnode->pct_type = from->pct_type;
newnode->typmod = from->typmod; newnode->typmod = from->typmod;
Node_Copy(from, newnode, arrayBounds); Node_Copy(from, newnode, arrayBounds);
@ -2008,7 +2009,7 @@ _copyDefineStmt(DefineStmt *from)
DefineStmt *newnode = makeNode(DefineStmt); DefineStmt *newnode = makeNode(DefineStmt);
newnode->defType = from->defType; newnode->defType = from->defType;
newnode->defname = pstrdup(from->defname); Node_Copy(from, newnode, defnames);
Node_Copy(from, newnode, definition); Node_Copy(from, newnode, definition);
return newnode; return newnode;
@ -2089,7 +2090,7 @@ _copyProcedureStmt(ProcedureStmt *from)
ProcedureStmt *newnode = makeNode(ProcedureStmt); ProcedureStmt *newnode = makeNode(ProcedureStmt);
newnode->replace = from->replace; newnode->replace = from->replace;
newnode->funcname = pstrdup(from->funcname); Node_Copy(from, newnode, funcname);
Node_Copy(from, newnode, argTypes); Node_Copy(from, newnode, argTypes);
Node_Copy(from, newnode, returnType); Node_Copy(from, newnode, returnType);
Node_Copy(from, newnode, withClause); Node_Copy(from, newnode, withClause);
@ -2229,8 +2230,7 @@ _copyCreateDomainStmt(CreateDomainStmt *from)
{ {
CreateDomainStmt *newnode = makeNode(CreateDomainStmt); CreateDomainStmt *newnode = makeNode(CreateDomainStmt);
if (from->domainname) Node_Copy(from, newnode, domainname);
newnode->domainname = pstrdup(from->domainname);
Node_Copy(from, newnode, typename); Node_Copy(from, newnode, typename);
Node_Copy(from, newnode, constraints); Node_Copy(from, newnode, constraints);

View File

@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) if (a->defType != b->defType)
return false; return false;
if (!equalstr(a->defname, b->defname)) if (!equal(a->defnames, b->defnames))
return false; return false;
if (!equal(a->definition, b->definition)) if (!equal(a->definition, b->definition))
return false; return false;
@ -928,7 +928,7 @@ _equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
{ {
if (a->replace != b->replace) if (a->replace != b->replace)
return false; return false;
if (!equalstr(a->funcname, b->funcname)) if (!equal(a->funcname, b->funcname))
return false; return false;
if (!equal(a->argTypes, b->argTypes)) if (!equal(a->argTypes, b->argTypes))
return false; return false;
@ -1071,7 +1071,7 @@ _equalLoadStmt(LoadStmt *a, LoadStmt *b)
static bool static bool
_equalCreateDomainStmt(CreateDomainStmt *a, CreateDomainStmt *b) _equalCreateDomainStmt(CreateDomainStmt *a, CreateDomainStmt *b)
{ {
if (!equalstr(a->domainname, b->domainname)) if (!equal(a->domainname, b->domainname))
return false; return false;
if (!equal(a->typename, b->typename)) if (!equal(a->typename, b->typename))
return false; return false;
@ -1572,12 +1572,16 @@ _equalRangeSubselect(RangeSubselect *a, RangeSubselect *b)
static bool static bool
_equalTypeName(TypeName *a, TypeName *b) _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; return false;
if (a->timezone != b->timezone) if (a->timezone != b->timezone)
return false; return false;
if (a->setof != b->setof) if (a->setof != b->setof)
return false; return false;
if (a->pct_type != b->pct_type)
return false;
if (a->typmod != b->typmod) if (a->typmod != b->typmod)
return false; return false;
if (!equal(a->arrayBounds, b->arrayBounds)) if (!equal(a->arrayBounds, b->arrayBounds))

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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" #include "postgres.h"
@ -209,3 +209,17 @@ makeRangeVar(char *schemaname, char *relname)
return r; 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;
}

View File

@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
@ -187,11 +187,14 @@ _outColumnDef(StringInfo str, ColumnDef *node)
static void static void
_outTypeName(StringInfo str, TypeName *node) _outTypeName(StringInfo str, TypeName *node)
{ {
appendStringInfo(str, " TYPENAME :name "); appendStringInfo(str, " TYPENAME :names ");
_outToken(str, node->name); _outNode(str, node->names);
appendStringInfo(str, " :timezone %s :setof %s typmod %d :arrayBounds ", appendStringInfo(str, " :typeid %u :timezone %s :setof %s"
" :pct_type %s typmod %d :arrayBounds ",
node->typeid,
booltostr(node->timezone), booltostr(node->timezone),
booltostr(node->setof), booltostr(node->setof),
booltostr(node->pct_type),
node->typmod); node->typmod);
_outNode(str, node->arrayBounds); _outNode(str, node->arrayBounds);
} }

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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); CreateStmtContext *cxt);
static void transformFKConstraints(ParseState *pstate, static void transformFKConstraints(ParseState *pstate,
CreateStmtContext *cxt); CreateStmtContext *cxt);
static Node *transformTypeRefs(ParseState *pstate, Node *stmt);
static void applyColumnNames(List *dst, List *src); 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 List *getSetColTypes(ParseState *pstate, Node *node);
static void transformForUpdate(Query *qry, List *forUpdate); static void transformForUpdate(Query *qry, List *forUpdate);
static void transformConstraintAttrs(List *constraintList); static void transformConstraintAttrs(List *constraintList);
@ -309,18 +305,6 @@ transformStmt(ParseState *pstate, Node *parseTree,
(SelectStmt *) parseTree); (SelectStmt *) parseTree);
break; 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: default:
/* /*
@ -792,17 +776,24 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
/* Check for SERIAL pseudo-types */ /* Check for SERIAL pseudo-types */
is_serial = false; is_serial = false;
if (strcmp(column->typename->name, "serial") == 0 || if (length(column->typename->names) == 1)
strcmp(column->typename->name, "serial4") == 0)
{ {
is_serial = true; char *typname = strVal(lfirst(column->typename->names));
column->typename->name = pstrdup("int4");
} if (strcmp(typname, "serial") == 0 ||
else if (strcmp(column->typename->name, "bigserial") == 0 || strcmp(typname, "serial4") == 0)
strcmp(column->typename->name, "serial8") == 0) {
{ is_serial = true;
is_serial = true; column->typename->names = NIL;
column->typename->name = pstrdup("int8"); 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 */ /* Do necessary work on the column type declaration */
@ -2634,110 +2625,6 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
return qry; 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 */ /* exported so planner can check again after rewriting, query pullup, etc */
void void
CheckSelectForUpdate(Query *qry) CheckSelectForUpdate(Query *qry)
@ -3059,15 +2946,7 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
ColumnDef *col = lfirst(cols); ColumnDef *col = lfirst(cols);
if (strcmp(col->colname, colname) == 0) if (strcmp(col->colname, colname) == 0)
{ return typenameTypeId(col->typename);
char *buff = TypeNameToInternalName(col->typename);
result = typenameTypeId(buff);
if (!OidIsValid(result))
elog(ERROR, "Unable to lookup type %s",
col->typename->name);
return result;
}
} }
/* Perhaps it's a system column name */ /* Perhaps it's a system column name */
sysatt = SystemAttributeByName(colname, cxt->hasoids); sysatt = SystemAttributeByName(colname, cxt->hasoids);
@ -3092,7 +2971,6 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
if (strcmp(name, colname) == 0) if (strcmp(name, colname) == 0)
{ {
result = rel->rd_att->attrs[count]->atttypid; result = rel->rd_att->attrs[count]->atttypid;
heap_close(rel, NoLock); heap_close(rel, NoLock);
return result; return result;
} }
@ -3111,7 +2989,6 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
if (HeapTupleIsValid(atttuple)) if (HeapTupleIsValid(atttuple))
{ {
result = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid; result = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
ReleaseSysCache(atttuple); ReleaseSysCache(atttuple);
return result; return result;
} }
@ -3233,7 +3110,7 @@ static void
transformColumnType(ParseState *pstate, ColumnDef *column) transformColumnType(ParseState *pstate, ColumnDef *column)
{ {
TypeName *typename = column->typename; 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. * Is this the name of a complex type? If so, implement it as a set.

View File

@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -53,6 +53,7 @@
#include "access/htup.h" #include "access/htup.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "nodes/params.h" #include "nodes/params.h"
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "parser/gramparse.h" #include "parser/gramparse.h"
@ -122,8 +123,6 @@ static void doNegateFloat(Value *v);
ResTarget *target; ResTarget *target;
PrivTarget *privtarget; PrivTarget *privtarget;
DefineStmt *dstmt;
RuleStmt *rstmt;
InsertStmt *istmt; InsertStmt *istmt;
} }
@ -175,7 +174,8 @@ static void doNegateFloat(Value *v);
%type <str> relation_name, copy_file_name, copy_delimiter, copy_null, %type <str> relation_name, copy_file_name, copy_delimiter, copy_null,
database_name, access_method_clause, access_method, attr_name, 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 %type <range> qualified_name, OptConstrFromTable
@ -200,8 +200,8 @@ static void doNegateFloat(Value *v);
opt_column_list, columnList, opt_name_list, opt_column_list, columnList, opt_name_list,
sort_clause, sortby_list, index_params, index_list, name_list, sort_clause, sortby_list, index_params, index_list, name_list,
from_clause, from_list, opt_array_bounds, qualified_name_list, from_clause, from_list, opt_array_bounds, qualified_name_list,
expr_list, attrs, opt_attrs, target_list, update_target_list, any_name, any_name_list, expr_list, dotted_name, attrs,
insert_column_list, target_list, update_target_list, insert_column_list,
def_list, opt_indirection, group_clause, TriggerFuncArgs, def_list, opt_indirection, group_clause, TriggerFuncArgs,
select_limit, opt_select_limit select_limit, opt_select_limit
@ -411,10 +411,10 @@ static void doNegateFloat(Value *v);
/* Unary Operators */ /* Unary Operators */
%left AT ZONE /* sets precedence for AT TIME ZONE */ %left AT ZONE /* sets precedence for AT TIME ZONE */
%right UMINUS %right UMINUS
%left '.'
%left '[' ']' %left '[' ']'
%left '(' ')' %left '(' ')'
%left TYPECAST %left TYPECAST
%left '.'
%% %%
/* /*
@ -1812,7 +1812,7 @@ IntegerOnly: Iconst
*****************************************************************************/ *****************************************************************************/
CreatePLangStmt: CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst CreatePLangStmt: CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
HANDLER func_name opt_lancompiler HANDLER handler_name opt_lancompiler
{ {
CreatePLangStmt *n = makeNode(CreatePLangStmt); CreatePLangStmt *n = makeNode(CreatePLangStmt);
n->plname = $5; n->plname = $5;
@ -1827,6 +1827,16 @@ opt_trusted: TRUSTED { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; } | /*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; } opt_lancompiler: LANCOMPILER Sconst { $$ = $2; }
| /*EMPTY*/ { $$ = ""; } | /*EMPTY*/ { $$ = ""; }
; ;
@ -1853,7 +1863,7 @@ opt_procedural: PROCEDURAL { $$ = TRUE; }
CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
qualified_name TriggerForSpec EXECUTE PROCEDURE qualified_name TriggerForSpec EXECUTE PROCEDURE
name '(' TriggerFuncArgs ')' func_name '(' TriggerFuncArgs ')'
{ {
CreateTrigStmt *n = makeNode(CreateTrigStmt); CreateTrigStmt *n = makeNode(CreateTrigStmt);
n->trigname = $3; n->trigname = $3;
@ -1877,7 +1887,8 @@ CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
| CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
qualified_name OptConstrFromTable qualified_name OptConstrFromTable
ConstraintAttributeSpec ConstraintAttributeSpec
FOR EACH ROW EXECUTE PROCEDURE name '(' TriggerFuncArgs ')' FOR EACH ROW EXECUTE PROCEDURE
func_name '(' TriggerFuncArgs ')'
{ {
CreateTrigStmt *n = makeNode(CreateTrigStmt); CreateTrigStmt *n = makeNode(CreateTrigStmt);
n->trigname = $4; n->trigname = $4;
@ -2043,7 +2054,7 @@ DefineStmt: CREATE AGGREGATE func_name definition
{ {
DefineStmt *n = makeNode(DefineStmt); DefineStmt *n = makeNode(DefineStmt);
n->defType = AGGREGATE; n->defType = AGGREGATE;
n->defname = $3; n->defnames = makeList1(makeString($3)); /* XXX */
n->definition = $4; n->definition = $4;
$$ = (Node *)n; $$ = (Node *)n;
} }
@ -2051,15 +2062,15 @@ DefineStmt: CREATE AGGREGATE func_name definition
{ {
DefineStmt *n = makeNode(DefineStmt); DefineStmt *n = makeNode(DefineStmt);
n->defType = OPERATOR; n->defType = OPERATOR;
n->defname = $3; n->defnames = makeList1(makeString($3)); /* XXX */
n->definition = $4; n->definition = $4;
$$ = (Node *)n; $$ = (Node *)n;
} }
| CREATE TYPE_P name definition | CREATE TYPE_P any_name definition
{ {
DefineStmt *n = makeNode(DefineStmt); DefineStmt *n = makeNode(DefineStmt);
n->defType = TYPE_P; n->defType = TYPE_P;
n->defname = $3; n->defnames = $3;
n->definition = $4; n->definition = $4;
$$ = (Node *)n; $$ = (Node *)n;
} }
@ -2102,10 +2113,7 @@ def_arg: func_return { $$ = (Node *)$1; }
* *
*****************************************************************************/ *****************************************************************************/
/* DropStmt needs to use qualified_name_list as many of the objects DropStmt: DROP drop_type any_name_list opt_drop_behavior
* are relations or other schema objects (names can be schema-qualified) */
DropStmt: DROP drop_type qualified_name_list opt_drop_behavior
{ {
DropStmt *n = makeNode(DropStmt); DropStmt *n = makeNode(DropStmt);
n->removeType = $2; n->removeType = $2;
@ -2124,6 +2132,18 @@ drop_type: TABLE { $$ = DROP_TABLE; }
| DOMAIN_P { $$ = DROP_DOMAIN; } | 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: * QUERY:
@ -2192,7 +2212,7 @@ CommentStmt: COMMENT ON comment_type name IS comment_text
n->comment = $10; n->comment = $10;
$$ = (Node *) n; $$ = (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); CommentStmt *n = makeNode(CommentStmt);
n->objtype = AGGREGATE; n->objtype = AGGREGATE;
@ -2203,18 +2223,6 @@ CommentStmt: COMMENT ON comment_type name IS comment_text
n->comment = $9; n->comment = $9;
$$ = (Node *) n; $$ = (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 | COMMENT ON FUNCTION func_name func_args IS comment_text
{ {
CommentStmt *n = makeNode(CommentStmt); CommentStmt *n = makeNode(CommentStmt);
@ -2691,9 +2699,9 @@ ProcedureStmt: CREATE opt_or_replace FUNCTION func_name func_args
{ {
ProcedureStmt *n = makeNode(ProcedureStmt); ProcedureStmt *n = makeNode(ProcedureStmt);
n->replace = $2; n->replace = $2;
n->funcname = $4; n->funcname = makeList1(makeString($4)); /* XXX */
n->argTypes = $5; n->argTypes = $5;
n->returnType = (Node *) $7; n->returnType = $7;
n->withClause = $12; n->withClause = $12;
n->as = $9; n->as = $9;
n->language = $11; 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. * but that causes reduce/reduce conflicts. type_name is next best choice.
*/ */
func_type: Typename func_type: Typename
{ {
$$ = $1; $$ = $1;
} }
| type_name '.' ColId '%' TYPE_P | type_name attrs '%' TYPE_P
{ {
$$ = makeNode(TypeName); $$ = makeNode(TypeName);
$$->name = $1; $$->names = lcons(makeString($1), $2);
$$->pct_type = true;
$$->typmod = -1; $$->typmod = -1;
$$->attrname = $3;
} }
; ;
@ -2804,15 +2812,7 @@ RemoveAggrStmt: DROP AGGREGATE func_name '(' aggr_argtype ')'
{ {
RemoveAggrStmt *n = makeNode(RemoveAggrStmt); RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
n->aggname = $3; n->aggname = $3;
n->aggtype = (Node *) $5; n->aggtype = $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;
$$ = (Node *)n; $$ = (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); CreateDomainStmt *n = makeNode(CreateDomainStmt);
n->domainname = $3; n->domainname = $3;
@ -4237,6 +4237,14 @@ opt_array_bounds: opt_array_bounds '[' ']'
{ $$ = NIL; } { $$ = 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 SimpleTypename: ConstTypename
| ConstInterval opt_interval | ConstInterval opt_interval
{ {
@ -4249,6 +4257,12 @@ SimpleTypename: ConstTypename
$$ = $1; $$ = $1;
$$->typmod = ((($5 & 0x7FFF) << 16) | $3); $$->typmod = ((($5 & 0x7FFF) << 16) | $3);
} }
| type_name attrs
{
$$ = makeNode(TypeName);
$$->names = lcons(makeString($1), $2);
$$->typmod = -1;
}
; ;
ConstTypename: GenericType ConstTypename: GenericType
@ -4260,9 +4274,7 @@ ConstTypename: GenericType
GenericType: type_name GenericType: type_name
{ {
$$ = makeNode(TypeName); $$ = makeTypeName(xlateSqlType($1));
$$->name = xlateSqlType($1);
$$->typmod = -1;
} }
; ;
@ -4273,32 +4285,25 @@ GenericType: type_name
*/ */
Numeric: FLOAT opt_float Numeric: FLOAT opt_float
{ {
$$ = makeNode(TypeName); $$ = makeTypeName($2); /* already xlated */
$$->name = $2; /* already xlated */
$$->typmod = -1;
} }
| DOUBLE PRECISION | DOUBLE PRECISION
{ {
$$ = makeNode(TypeName); $$ = makeTypeName(xlateSqlType("float8"));
$$->name = xlateSqlType("float8");
$$->typmod = -1;
} }
| DECIMAL opt_decimal | DECIMAL opt_decimal
{ {
$$ = makeNode(TypeName); $$ = makeTypeName(xlateSqlType("decimal"));
$$->name = xlateSqlType("decimal");
$$->typmod = $2; $$->typmod = $2;
} }
| DEC opt_decimal | DEC opt_decimal
{ {
$$ = makeNode(TypeName); $$ = makeTypeName(xlateSqlType("decimal"));
$$->name = xlateSqlType("decimal");
$$->typmod = $2; $$->typmod = $2;
} }
| NUMERIC opt_numeric | NUMERIC opt_numeric
{ {
$$ = makeNode(TypeName); $$ = makeTypeName(xlateSqlType("numeric"));
$$->name = xlateSqlType("numeric");
$$->typmod = $2; $$->typmod = $2;
} }
; ;
@ -4379,8 +4384,7 @@ opt_decimal: '(' Iconst ',' Iconst ')'
*/ */
Bit: bit '(' Iconst ')' Bit: bit '(' Iconst ')'
{ {
$$ = makeNode(TypeName); $$ = makeTypeName($1);
$$->name = $1;
if ($3 < 1) if ($3 < 1)
elog(ERROR,"length for type '%s' must be at least 1", elog(ERROR,"length for type '%s' must be at least 1",
$1); $1);
@ -4391,8 +4395,7 @@ Bit: bit '(' Iconst ')'
} }
| bit | bit
{ {
$$ = makeNode(TypeName); $$ = makeTypeName($1);
$$->name = $1;
/* bit defaults to bit(1), varbit to no limit */ /* bit defaults to bit(1), varbit to no limit */
if (strcmp($1, "bit") == 0) if (strcmp($1, "bit") == 0)
$$->typmod = 1; $$->typmod = 1;
@ -4418,8 +4421,19 @@ bit: BIT opt_varying
*/ */
Character: character '(' Iconst ')' opt_charset Character: character '(' Iconst ')' opt_charset
{ {
$$ = makeNode(TypeName); if (($5 != NULL) && (strcmp($5, "sql_text") != 0))
$$->name = $1; {
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) if ($3 < 1)
elog(ERROR,"length for type '%s' must be at least 1", elog(ERROR,"length for type '%s' must be at least 1",
$1); $1);
@ -4433,36 +4447,27 @@ Character: character '(' Iconst ')' opt_charset
* truncate where necessary) * truncate where necessary)
*/ */
$$->typmod = VARHDRSZ + $3; $$->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 | character opt_charset
{ {
$$ = makeNode(TypeName); if (($2 != NULL) && (strcmp($2, "sql_text") != 0))
$$->name = $1; {
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 */ /* char defaults to char(1), varchar to no limit */
if (strcmp($1, "bpchar") == 0) if (strcmp($1, "bpchar") == 0)
$$->typmod = VARHDRSZ + 1; $$->typmod = VARHDRSZ + 1;
else else
$$->typmod = -1; $$->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 ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
{ {
$$ = makeNode(TypeName);
if ($5) if ($5)
$$->name = xlateSqlType("timestamptz"); $$ = makeTypeName(xlateSqlType("timestamptz"));
else else
$$->name = xlateSqlType("timestamp"); $$ = makeTypeName(xlateSqlType("timestamp"));
/* XXX the timezone field seems to be unused /* XXX the timezone field seems to be unused
* - thomas 2001-09-06 * - thomas 2001-09-06
*/ */
@ -4504,11 +4508,10 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
} }
| TIMESTAMP opt_timezone_x | TIMESTAMP opt_timezone_x
{ {
$$ = makeNode(TypeName);
if ($2) if ($2)
$$->name = xlateSqlType("timestamptz"); $$ = makeTypeName(xlateSqlType("timestamptz"));
else else
$$->name = xlateSqlType("timestamp"); $$ = makeTypeName(xlateSqlType("timestamp"));
/* XXX the timezone field seems to be unused /* XXX the timezone field seems to be unused
* - thomas 2001-09-06 * - thomas 2001-09-06
*/ */
@ -4524,11 +4527,10 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
} }
| TIME '(' Iconst ')' opt_timezone | TIME '(' Iconst ')' opt_timezone
{ {
$$ = makeNode(TypeName);
if ($5) if ($5)
$$->name = xlateSqlType("timetz"); $$ = makeTypeName(xlateSqlType("timetz"));
else else
$$->name = xlateSqlType("time"); $$ = makeTypeName(xlateSqlType("time"));
if (($3 < 0) || ($3 > 13)) if (($3 < 0) || ($3 > 13))
elog(ERROR,"TIME(%d)%s precision must be between %d and %d", elog(ERROR,"TIME(%d)%s precision must be between %d and %d",
$3, ($5 ? " WITH TIME ZONE": ""), 0, 13); $3, ($5 ? " WITH TIME ZONE": ""), 0, 13);
@ -4536,11 +4538,10 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
} }
| TIME opt_timezone | TIME opt_timezone
{ {
$$ = makeNode(TypeName);
if ($2) if ($2)
$$->name = xlateSqlType("timetz"); $$ = makeTypeName(xlateSqlType("timetz"));
else else
$$->name = xlateSqlType("time"); $$ = makeTypeName(xlateSqlType("time"));
/* SQL99 specified a default precision of zero. /* SQL99 specified a default precision of zero.
* See comments for timestamp above on why we will * See comments for timestamp above on why we will
* leave this unspecified for now. - thomas 2001-12-07 * leave this unspecified for now. - thomas 2001-12-07
@ -4551,9 +4552,7 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
ConstInterval: INTERVAL ConstInterval: INTERVAL
{ {
$$ = makeNode(TypeName); $$ = makeTypeName(xlateSqlType("interval"));
$$->name = xlateSqlType("interval");
$$->typmod = -1;
} }
; ;
@ -5161,7 +5160,7 @@ c_expr: columnref
| CURRENT_DATE opt_empty_parentheses | CURRENT_DATE opt_empty_parentheses
{ {
/* /*
* Translate as "date('now'::text)". * Translate as "'now'::text::date".
* *
* We cannot use "'now'::date" because coerce_type() will * We cannot use "'now'::date" because coerce_type() will
* immediately reduce that to a constant representing * immediately reduce that to a constant representing
@ -5174,43 +5173,30 @@ c_expr: columnref
* of type-input conversion functions... * of type-input conversion functions...
*/ */
A_Const *s = makeNode(A_Const); A_Const *s = makeNode(A_Const);
TypeName *t = makeNode(TypeName); TypeName *d;
TypeName *d = makeNode(TypeName);
s->val.type = T_String; s->val.type = T_String;
s->val.val.str = "now"; s->val.val.str = "now";
s->typename = t; s->typename = makeTypeName(xlateSqlType("text"));
t->name = xlateSqlType("text"); d = makeTypeName(xlateSqlType("date"));
t->setof = FALSE;
t->typmod = -1;
d->name = xlateSqlType("date");
d->setof = FALSE;
d->typmod = -1;
$$ = (Node *)makeTypeCast((Node *)s, d); $$ = (Node *)makeTypeCast((Node *)s, d);
} }
| CURRENT_TIME opt_empty_parentheses | CURRENT_TIME opt_empty_parentheses
{ {
/* /*
* Translate as "timetz('now'::text)". * Translate as "'now'::text::timetz".
* See comments for CURRENT_DATE. * See comments for CURRENT_DATE.
*/ */
A_Const *s = makeNode(A_Const); A_Const *s = makeNode(A_Const);
TypeName *t = makeNode(TypeName); TypeName *d;
TypeName *d = makeNode(TypeName);
s->val.type = T_String; s->val.type = T_String;
s->val.val.str = "now"; s->val.val.str = "now";
s->typename = t; s->typename = makeTypeName(xlateSqlType("text"));
t->name = xlateSqlType("text"); d = makeTypeName(xlateSqlType("timetz"));
t->setof = FALSE;
t->typmod = -1;
d->name = xlateSqlType("timetz");
d->setof = FALSE;
/* SQL99 mandates a default precision of zero for TIME /* SQL99 mandates a default precision of zero for TIME
* fields in schemas. However, for CURRENT_TIME * fields in schemas. However, for CURRENT_TIME
* let's preserve the microsecond precision we * let's preserve the microsecond precision we
@ -5223,23 +5209,17 @@ c_expr: columnref
| CURRENT_TIME '(' Iconst ')' | CURRENT_TIME '(' Iconst ')'
{ {
/* /*
* Translate as "timetz('now'::text)". * Translate as "'now'::text::timetz(n)".
* See comments for CURRENT_DATE. * See comments for CURRENT_DATE.
*/ */
A_Const *s = makeNode(A_Const); A_Const *s = makeNode(A_Const);
TypeName *t = makeNode(TypeName); TypeName *d;
TypeName *d = makeNode(TypeName);
s->val.type = T_String; s->val.type = T_String;
s->val.val.str = "now"; s->val.val.str = "now";
s->typename = t; s->typename = makeTypeName(xlateSqlType("text"));
t->name = xlateSqlType("text"); d = makeTypeName(xlateSqlType("timetz"));
t->setof = FALSE;
t->typmod = -1;
d->name = xlateSqlType("timetz");
d->setof = FALSE;
if (($3 < 0) || ($3 > 13)) if (($3 < 0) || ($3 > 13))
elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d", elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d",
$3, 0, 13); $3, 0, 13);
@ -5250,23 +5230,17 @@ c_expr: columnref
| CURRENT_TIMESTAMP opt_empty_parentheses | CURRENT_TIMESTAMP opt_empty_parentheses
{ {
/* /*
* Translate as "timestamptz('now'::text)". * Translate as "'now'::text::timestamptz".
* See comments for CURRENT_DATE. * See comments for CURRENT_DATE.
*/ */
A_Const *s = makeNode(A_Const); A_Const *s = makeNode(A_Const);
TypeName *t = makeNode(TypeName); TypeName *d;
TypeName *d = makeNode(TypeName);
s->val.type = T_String; s->val.type = T_String;
s->val.val.str = "now"; s->val.val.str = "now";
s->typename = t; s->typename = makeTypeName(xlateSqlType("text"));
t->name = xlateSqlType("text"); d = makeTypeName(xlateSqlType("timestamptz"));
t->setof = FALSE;
t->typmod = -1;
d->name = xlateSqlType("timestamptz");
d->setof = FALSE;
/* SQL99 mandates a default precision of 6 for timestamp. /* SQL99 mandates a default precision of 6 for timestamp.
* Also, that is about as precise as we will get since * Also, that is about as precise as we will get since
* we are using a microsecond time interface. * we are using a microsecond time interface.
@ -5279,23 +5253,17 @@ c_expr: columnref
| CURRENT_TIMESTAMP '(' Iconst ')' | CURRENT_TIMESTAMP '(' Iconst ')'
{ {
/* /*
* Translate as "timestamptz('now'::text)". * Translate as "'now'::text::timestamptz(n)".
* See comments for CURRENT_DATE. * See comments for CURRENT_DATE.
*/ */
A_Const *s = makeNode(A_Const); A_Const *s = makeNode(A_Const);
TypeName *t = makeNode(TypeName); TypeName *d;
TypeName *d = makeNode(TypeName);
s->val.type = T_String; s->val.type = T_String;
s->val.val.str = "now"; s->val.val.str = "now";
s->typename = t; s->typename = makeTypeName(xlateSqlType("text"));
t->name = xlateSqlType("text"); d = makeTypeName(xlateSqlType("timestamptz"));
t->setof = FALSE;
t->typmod = -1;
d->name = xlateSqlType("timestamptz");
d->setof = FALSE;
if (($3 < 0) || ($3 > 13)) if (($3 < 0) || ($3 > 13))
elog(ERROR,"CURRENT_TIMESTAMP(%d) precision must be between %d and %d", elog(ERROR,"CURRENT_TIMESTAMP(%d) precision must be between %d and %d",
$3, 0, 13); $3, 0, 13);
@ -5645,24 +5613,24 @@ columnref: relation_name opt_indirection
$$->fields = makeList1(makeString($1)); $$->fields = makeList1(makeString($1));
$$->indirection = $2; $$->indirection = $2;
} }
| relation_name attrs opt_indirection | dotted_name opt_indirection
{ {
$$ = makeNode(ColumnRef); $$ = makeNode(ColumnRef);
$$->fields = lcons(makeString($1), $2); $$->fields = $1;
$$->indirection = $3; $$->indirection = $2;
} }
; ;
attrs: opt_attrs '.' attr_name dotted_name: relation_name attrs
{ $$ = lappend($1, makeString($3)); } { $$ = lcons(makeString($1), $2); }
| opt_attrs '.' '*'
{ $$ = lappend($1, makeString("*")); }
; ;
opt_attrs: /*EMPTY*/ attrs: '.' attr_name
{ $$ = NIL; } { $$ = makeList1(makeString($2)); }
| opt_attrs '.' attr_name | '.' '*'
{ $$ = lappend($1, makeString($3)); } { $$ = makeList1(makeString("*")); }
| '.' attr_name attrs
{ $$ = lcons(makeString($2), $3); }
; ;
opt_empty_parentheses: '(' ')' { $$ = TRUE; } opt_empty_parentheses: '(' ')' { $$ = TRUE; }
@ -5742,11 +5710,11 @@ relation_name: SpecialRuleRelation
$$ = $1; $$ = $1;
} }
; ;
qualified_name_list: qualified_name qualified_name_list: qualified_name
{ $$ = makeList1($1); } { $$ = makeList1($1); }
| qualified_name_list ',' qualified_name | qualified_name_list ',' qualified_name
{ $$ = lappend($1, $3); } { $$ = lappend($1, $3); }
; ;
qualified_name: ColId qualified_name: ColId
@ -5787,6 +5755,21 @@ class: ColId { $$ = $1; };
index_name: ColId { $$ = $1; }; index_name: ColId { $$ = $1; };
file_name: Sconst { $$ = $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 /* Constants
* Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
*/ */
@ -5867,9 +5850,7 @@ AexprConst: Iconst
A_Const *n = makeNode(A_Const); A_Const *n = makeNode(A_Const);
n->val.type = T_String; n->val.type = T_String;
n->val.val.str = "t"; n->val.val.str = "t";
n->typename = makeNode(TypeName); n->typename = makeTypeName(xlateSqlType("bool"));
n->typename->name = xlateSqlType("bool");
n->typename->typmod = -1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| FALSE_P | FALSE_P
@ -5877,9 +5858,7 @@ AexprConst: Iconst
A_Const *n = makeNode(A_Const); A_Const *n = makeNode(A_Const);
n->val.type = T_String; n->val.type = T_String;
n->val.val.str = "f"; n->val.val.str = "f";
n->typename = makeNode(TypeName); n->typename = makeTypeName(xlateSqlType("bool"));
n->typename->name = xlateSqlType("bool");
n->typename->typmod = -1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| NULL_P | NULL_P
@ -5920,7 +5899,7 @@ type_name: IDENT { $$ = $1; }
/* Function identifier --- names that can be function names. /* Function identifier --- names that can be function names.
*/ */
func_name: IDENT { $$ = xlateSqlFunc($1); } function_name: IDENT { $$ = xlateSqlFunc($1); }
| unreserved_keyword { $$ = xlateSqlFunc($1); } | unreserved_keyword { $$ = xlateSqlFunc($1); }
| func_name_keyword { $$ = xlateSqlFunc($1); } | func_name_keyword { $$ = xlateSqlFunc($1); }
; ;
@ -6304,6 +6283,7 @@ static Node *
makeStringConst(char *str, TypeName *typename) makeStringConst(char *str, TypeName *typename)
{ {
A_Const *n = makeNode(A_Const); A_Const *n = makeNode(A_Const);
n->val.type = T_String; n->val.type = T_String;
n->val.val.str = str; n->val.val.str = str;
n->typename = typename; n->typename = typename;
@ -6315,12 +6295,10 @@ static Node *
makeFloatConst(char *str) makeFloatConst(char *str)
{ {
A_Const *n = makeNode(A_Const); A_Const *n = makeNode(A_Const);
TypeName *t = makeNode(TypeName);
n->val.type = T_Float; n->val.type = T_Float;
n->val.val.str = str; n->val.val.str = str;
t->name = xlateSqlType("float"); n->typename = makeTypeName(xlateSqlType("float"));
t->typmod = -1;
n->typename = t;
return (Node *)n; return (Node *)n;
} }
@ -6435,7 +6413,6 @@ makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg)
return (Node *) n; return (Node *) n;
} }
/* xlateSqlFunc() /* xlateSqlFunc()
* Convert alternate function names to internal Postgres functions. * Convert alternate function names to internal Postgres functions.
* *

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 string_palloced = false;
bool isNull = false; bool isNull = false;
tp = typenameType(TypeNameToInternalName(typename)); tp = typenameType(typename);
switch (nodeTag(expr)) switch (nodeTag(expr))
{ {
@ -1161,7 +1161,7 @@ parser_typecast_expression(ParseState *pstate,
Oid inputType = exprType(expr); Oid inputType = exprType(expr);
Oid targetType; Oid targetType;
targetType = typenameTypeId(TypeNameToInternalName(typename)); targetType = typenameTypeId(typename);
if (inputType == InvalidOid) if (inputType == InvalidOid)
return expr; /* do nothing if NULL input */ return expr; /* do nothing if NULL input */
@ -1185,27 +1185,3 @@ parser_typecast_expression(ParseState *pstate,
return expr; 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;
}

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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/indexing.h"
#include "catalog/pg_aggregate.h" #include "catalog/pg_aggregate.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "parser/parse_agg.h" #include "parser/parse_agg.h"
@ -969,9 +970,14 @@ func_get_detail(char *funcname,
{ {
Oid targetType; 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), PointerGetDatum(funcname),
0, 0, 0); ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
0, 0);
if (OidIsValid(targetType) && if (OidIsValid(targetType) &&
!ISCOMPLEX(targetType)) !ISCOMPLEX(targetType))
{ {
@ -1222,13 +1228,11 @@ find_inheritors(Oid relid, Oid **supervec)
{ {
/* return the type id, rather than the relation id */ /* return the type id, rather than the relation id */
Relation rd; Relation rd;
Oid trelid;
relid = lfirsti(elt); relid = lfirsti(elt);
rd = heap_open(relid, NoLock); rd = heap_open(relid, NoLock);
trelid = typenameTypeId(RelationGetRelationName(rd)); *relidvec++ = rd->rd_rel->reltype;
heap_close(rd, NoLock); heap_close(rd, NoLock);
*relidvec++ = trelid;
} }
} }
else else
@ -1473,7 +1477,9 @@ ParseComplexProjection(ParseState *pstate,
* argument types * argument types
*/ */
void 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], char p[(NAMEDATALEN + 2) * FUNC_MAX_ARGS],
*ptr; *ptr;
@ -1488,9 +1494,9 @@ func_error(char *caller, char *funcname, int nargs, Oid *argtypes, char *msg)
*ptr++ = ','; *ptr++ = ',';
*ptr++ = ' '; *ptr++ = ' ';
} }
if (argtypes[i] != 0) if (OidIsValid(argtypes[i]))
{ {
strcpy(ptr, typeidTypeName(argtypes[i])); strncpy(ptr, typeidTypeName(argtypes[i]), NAMEDATALEN);
*(ptr + NAMEDATALEN) = '\0'; *(ptr + NAMEDATALEN) = '\0';
} }
else else

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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: case T_A_Const:
if (((A_Const *) node)->typename != NULL) if (((A_Const *) node)->typename != NULL)
{ {
*name = ((A_Const *) node)->typename->name; List *names = ((A_Const *) node)->typename->names;
return 1;
if (names != NIL)
{
while (lnext(names) != NIL)
names = lnext(names);
*name = strVal(lfirst(names));
return 1;
}
} }
break; break;
case T_TypeCast: case T_TypeCast:
@ -536,8 +543,15 @@ FigureColnameInternal(Node *node, char **name)
{ {
if (((TypeCast *) node)->typename != NULL) if (((TypeCast *) node)->typename != NULL)
{ {
*name = ((TypeCast *) node)->typename->name; List *names = ((TypeCast *) node)->typename->names;
return 1;
if (names != NIL)
{
while (lnext(names) != NIL)
names = lnext(names);
*name = strVal(lfirst(names));
return 1;
}
} }
} }
break; break;

View File

@ -8,20 +8,250 @@
* *
* *
* IDENTIFICATION * 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 "postgres.h"
#include "catalog/namespace.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "parser/parser.h" #include "parser/parser.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "utils/lsyscache.h"
#include "utils/syscache.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, /* check to see if a type id is valid,
* returns true if it is. By using this call before calling * returns true if it is. By using this call before calling
* typeidType or typeidTypeName, more meaningful error messages * typeidType or typeidTypeName, more meaningful error messages
@ -51,24 +281,6 @@ typeidType(Oid id)
return (Type) tup; 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 */ /* given type (as type struct), return the type OID */
Oid Oid
typeTypeId(Type tp) typeTypeId(Type tp)
@ -207,6 +419,7 @@ typeidOutfunc(Oid type_id)
#endif #endif
/* return a type name, given a typeid */ /* return a type name, given a typeid */
/* nb: type name is NOT unique; use this only for error messages */
char * char *
typeidTypeName(Oid id) typeidTypeName(Oid id)
{ {
@ -251,18 +464,6 @@ typeidTypeRelid(Oid type_id)
return result; 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, * Given a string that is supposed to be a SQL-compatible type declaration,
* such as "int4" or "integer" or "character varying(32)", parse * 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)) !IsA(typename, TypeName))
elog(ERROR, "Invalid type name '%s'", str); elog(ERROR, "Invalid type name '%s'", str);
*type_id = typenameTypeId(TypeNameToInternalName(typename)); *type_id = typenameTypeId(typename);
*typmod = typename->typmod; *typmod = typename->typmod;
pfree(buf); pfree(buf);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * RemoveRewriteRule
* *
* Delete a rule given its rulename. * Delete a rule given its (possibly qualified) rulename.
*/ */
void void
RemoveRewriteRule(char *ruleName) RemoveRewriteRule(List *names)
{ {
char *ruleName;
Relation RewriteRelation; Relation RewriteRelation;
Relation event_relation; Relation event_relation;
HeapTuple tuple; HeapTuple tuple;
@ -43,6 +44,13 @@ RemoveRewriteRule(char *ruleName)
bool hasMoreRules; bool hasMoreRules;
int32 aclcheck_result; 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. * Open the pg_rewrite relation.
*/ */

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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/variable.h"
#include "commands/view.h" #include "commands/view.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse.h" #include "parser/parse.h"
#include "parser/parse_clause.h" #include "parser/parse_clause.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_type.h"
#include "rewrite/rewriteDefine.h" #include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteRemove.h" #include "rewrite/rewriteRemove.h"
#include "tcop/utility.h" #include "tcop/utility.h"
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "utils/temprel.h" #include "utils/temprel.h"
#include "access/xlog.h" #include "access/xlog.h"
@ -280,45 +283,48 @@ ProcessUtility(Node *parsetree,
foreach(arg, stmt->objects) foreach(arg, stmt->objects)
{ {
RangeVar *rel = (RangeVar *) lfirst(arg); List *names = (List *) lfirst(arg);
RangeVar *rel;
relname = rel->relname;
switch (stmt->removeType) switch (stmt->removeType)
{ {
case DROP_TABLE: case DROP_TABLE:
rel = makeRangeVarFromNameList(names);
CheckDropPermissions(rel, RELKIND_RELATION); CheckDropPermissions(rel, RELKIND_RELATION);
RemoveRelation(relname); RemoveRelation(rel);
break; break;
case DROP_SEQUENCE: case DROP_SEQUENCE:
rel = makeRangeVarFromNameList(names);
CheckDropPermissions(rel, RELKIND_SEQUENCE); CheckDropPermissions(rel, RELKIND_SEQUENCE);
RemoveRelation(relname); RemoveRelation(rel);
break; break;
case DROP_VIEW: case DROP_VIEW:
rel = makeRangeVarFromNameList(names);
CheckDropPermissions(rel, RELKIND_VIEW); CheckDropPermissions(rel, RELKIND_VIEW);
RemoveView(relname); RemoveView(rel);
break; break;
case DROP_INDEX: case DROP_INDEX:
rel = makeRangeVarFromNameList(names);
CheckDropPermissions(rel, RELKIND_INDEX); CheckDropPermissions(rel, RELKIND_INDEX);
RemoveIndex(rel); RemoveIndex(rel);
break; break;
case DROP_RULE: case DROP_RULE:
/* RemoveRewriteRule checks permissions */ /* RemoveRewriteRule checks permissions */
RemoveRewriteRule(relname); RemoveRewriteRule(names);
break; break;
case DROP_TYPE: case DROP_TYPE:
/* RemoveType does its own permissions checks */ /* RemoveType does its own permissions checks */
RemoveType(relname); RemoveType(names);
break; break;
case DROP_DOMAIN: case DROP_DOMAIN:
/* RemoveDomain does its own permissions checks */ /* RemoveDomain does its own permissions checks */
RemoveDomain(relname, stmt->behavior); RemoveDomain(names, stmt->behavior);
break; break;
} }
@ -334,16 +340,15 @@ ProcessUtility(Node *parsetree,
case T_TruncateStmt: case T_TruncateStmt:
{ {
relname = ((TruncateStmt *) parsetree)->relation->relname; TruncateStmt *stmt = (TruncateStmt *) parsetree;
TruncateRelation(relname);
TruncateRelation(stmt->relation);
} }
break; break;
case T_CommentStmt: case T_CommentStmt:
{ {
CommentStmt *stmt; CommentStmt *stmt = (CommentStmt *) parsetree;
stmt = ((CommentStmt *) parsetree);
CommentObject(stmt->objtype, stmt->objschema, stmt->objname, CommentObject(stmt->objtype, stmt->objschema, stmt->objname,
stmt->objproperty, stmt->objlist, stmt->comment); stmt->objproperty, stmt->objlist, stmt->comment);
@ -357,7 +362,7 @@ ProcessUtility(Node *parsetree,
if (stmt->direction != FROM) if (stmt->direction != FROM)
SetQuerySnapshot(); SetQuerySnapshot();
DoCopy(stmt->relation->relname, DoCopy(stmt->relation,
stmt->binary, stmt->binary,
stmt->oids, stmt->oids,
(bool) (stmt->direction == FROM), (bool) (stmt->direction == FROM),
@ -408,7 +413,7 @@ ProcessUtility(Node *parsetree,
/* /*
* rename attribute * rename attribute
*/ */
renameatt(relname, /* relname */ renameatt(RangeVarGetRelid(stmt->relation, false), /* relation */
stmt->column, /* old att name */ stmt->column, /* old att name */
stmt->newname, /* new att name */ stmt->newname, /* new att name */
interpretInhOption(stmt->relation->inhOpt)); /* recursive? */ interpretInhOption(stmt->relation->inhOpt)); /* recursive? */
@ -429,38 +434,63 @@ ProcessUtility(Node *parsetree,
switch (stmt->subtype) switch (stmt->subtype)
{ {
case 'A': /* ADD COLUMN */ 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); (ColumnDef *) stmt->def);
break; break;
case 'T': /* ALTER COLUMN DEFAULT */ 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->name,
stmt->def); stmt->def);
break; break;
case 'S': /* ALTER COLUMN STATISTICS */ case 'S': /* ALTER COLUMN STATISTICS */
case 'M': /* ALTER COLUMN STORAGE */ case 'M': /* ALTER COLUMN STORAGE */
AlterTableAlterColumnFlags(stmt->relation->relname, /*
interpretInhOption(stmt->relation->inhOpt), * Recursively alter column statistics for table and,
stmt->name, * if requested, for descendants
stmt->def, */
&(stmt->subtype)); AlterTableAlterColumnFlags(RangeVarGetRelid(stmt->relation, false),
interpretInhOption(stmt->relation->inhOpt),
stmt->name,
stmt->def,
&(stmt->subtype));
break; break;
case 'D': /* DROP COLUMN */ 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->name,
stmt->behavior); stmt->behavior);
break; break;
case 'C': /* ADD CONSTRAINT */ 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); (List *) stmt->def);
break; break;
case 'X': /* DROP CONSTRAINT */ 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->name,
stmt->behavior); stmt->behavior);
break; break;
@ -469,8 +499,12 @@ ProcessUtility(Node *parsetree,
false); false);
break; break;
case 'U': /* ALTER OWNER */ case 'U': /* ALTER OWNER */
AlterTableOwner(stmt->relation, /* check that we are the superuser */
stmt->name); 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; break;
default: /* oops */ default: /* oops */
elog(ERROR, "T_AlterTableStmt: unknown subtype"); elog(ERROR, "T_AlterTableStmt: unknown subtype");
@ -500,15 +534,13 @@ ProcessUtility(Node *parsetree,
switch (stmt->defType) switch (stmt->defType)
{ {
case OPERATOR: case OPERATOR:
DefineOperator(stmt->defname, /* operator name */ DefineOperator(stmt->defnames, stmt->definition);
stmt->definition); /* rest */
break; break;
case TYPE_P: case TYPE_P:
DefineType(stmt->defname, stmt->definition); DefineType(stmt->defnames, stmt->definition);
break; break;
case AGGREGATE: case AGGREGATE:
DefineAggregate(stmt->defname, /* aggregate name */ DefineAggregate(stmt->defnames, stmt->definition);
stmt->definition); /* rest */
break; break;
} }
} }
@ -518,7 +550,7 @@ ProcessUtility(Node *parsetree,
{ {
ViewStmt *stmt = (ViewStmt *) parsetree; ViewStmt *stmt = (ViewStmt *) parsetree;
DefineView(stmt->view->relname, stmt->query); /* retrieve parsetree */ DefineView(stmt->view, stmt->query);
} }
break; break;
@ -554,12 +586,8 @@ ProcessUtility(Node *parsetree,
case T_RemoveAggrStmt: case T_RemoveAggrStmt:
{ {
RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree; RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
char *typename = (char *) NULL;
if (stmt->aggtype != NULL) RemoveAggregate(stmt->aggname, stmt->aggtype);
typename = TypeNameToInternalName((TypeName *) stmt->aggtype);
RemoveAggregate(stmt->aggname, typename);
} }
break; break;
@ -576,15 +604,8 @@ ProcessUtility(Node *parsetree,
RemoveOperStmt *stmt = (RemoveOperStmt *) parsetree; RemoveOperStmt *stmt = (RemoveOperStmt *) parsetree;
TypeName *typenode1 = (TypeName *) lfirst(stmt->args); TypeName *typenode1 = (TypeName *) lfirst(stmt->args);
TypeName *typenode2 = (TypeName *) lsecond(stmt->args); TypeName *typenode2 = (TypeName *) lsecond(stmt->args);
char *typename1 = (char *) NULL;
char *typename2 = (char *) NULL;
if (typenode1 != NULL) RemoveOperator(stmt->opname, typenode1, typenode2);
typename1 = TypeNameToInternalName(typenode1);
if (typenode2 != NULL)
typename2 = TypeNameToInternalName(typenode2);
RemoveOperator(stmt->opname, typename1, typename2);
} }
break; break;

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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/catname.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "executor/executor.h" #include "executor/executor.h"
#include "utils/fcache.h" #include "utils/fcache.h"
@ -36,7 +37,7 @@
* in pg_proc. * in pg_proc.
*/ */
Oid Oid
SetDefine(char *querystr, char *typename) SetDefine(char *querystr, Oid elemType)
{ {
Oid setoid; Oid setoid;
char *procname = GENERICSETNAME; char *procname = GENERICSETNAME;
@ -52,9 +53,10 @@ SetDefine(char *querystr, char *typename)
char repl[Natts_pg_proc]; char repl[Natts_pg_proc];
setoid = ProcedureCreate(procname, /* changed below, after oid known */ setoid = ProcedureCreate(procname, /* changed below, after oid known */
PG_CATALOG_NAMESPACE, /* XXX wrong */
false, /* don't replace */ false, /* don't replace */
true, /* returnsSet */ true, /* returnsSet */
typename, /* returnTypeName */ elemType, /* returnType */
SQLlanguageId, /* language */ SQLlanguageId, /* language */
querystr, /* sourceCode */ querystr, /* sourceCode */
fileName, /* fileName */ fileName, /* fileName */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
@ -738,6 +738,33 @@ get_rel_type_id(Oid relid)
/* ---------- TYPE CACHE ---------- */ /* ---------- 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 * get_typlen
* *

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
@ -384,13 +384,13 @@ static const struct cachedesc cacheinfo[] = {
0, 0,
0 0
}}, }},
{TypeRelationName, /* TYPENAME */ {TypeRelationName, /* TYPENAMENSP */
TypeNameIndex, TypeNameNspIndex,
Anum_pg_type_typrelid, Anum_pg_type_typrelid,
1, 2,
{ {
Anum_pg_type_typname, Anum_pg_type_typname,
0, Anum_pg_type_typnamespace,
0, 0,
0 0
}}, }},
@ -515,7 +515,7 @@ SearchSysCache(int cacheId,
* when sought. This is a kluge ... temp table substitution should be * when sought. This is a kluge ... temp table substitution should be
* happening at a higher level ... * happening at a higher level ...
*/ */
if (cacheId == RELNAMENSP || cacheId == TYPENAME) if (cacheId == RELNAMENSP || cacheId == TYPENAMENSP)
{ {
char *nontemp_relname; char *nontemp_relname;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 */ continue; /* ignore it if deleted already */
if (temp_rel->relkind != RELKIND_INDEX) if (temp_rel->relkind != RELKIND_INDEX)
{ heap_drop_with_catalog(temp_rel->relid, allowSystemTableMods);
char relname[NAMEDATALEN];
/* safe from deallocation */
strcpy(relname, NameStr(temp_rel->user_relname));
heap_drop_with_catalog(relname, allowSystemTableMods);
}
else else
index_drop(temp_rel->relid); index_drop(temp_rel->relid);
/* advance cmd counter to make catalog changes visible */ /* advance cmd counter to make catalog changes visible */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2);
extern bool TupleDescInitEntry(TupleDesc desc, extern void TupleDescInitEntry(TupleDesc desc,
AttrNumber attributeNumber, AttrNumber attributeNumber,
char *attributeName, char *attributeName,
Oid oidtypeid, Oid oidtypeid,
@ -73,6 +73,6 @@ extern bool TupleDescInitEntry(TupleDesc desc,
int attdim, int attdim,
bool attisset); bool attisset);
extern TupleDesc BuildDescForRelation(List *schema, char *relname); extern TupleDesc BuildDescForRelation(List *schema);
#endif /* TUPDESC_H */ #endif /* TUPDESC_H */

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200203251 #define CATALOG_VERSION_NO 200203261
#endif #endif

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, char relkind, bool relhasoids, bool istemp,
bool allow_system_table_mods); bool allow_system_table_mods);
extern void heap_drop_with_catalog(const char *relname, extern void heap_drop_with_catalog(Oid rid, bool allow_system_table_mods);
bool allow_system_table_mods);
extern void heap_truncate(const char *relname); extern void heap_truncate(Oid rid);
extern void AddRelationRawConstraints(Relation rel, extern void AddRelationRawConstraints(Relation rel,
List *rawColDefaults, List *rawColDefaults,

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 TriggerConstrRelidIndex "pg_trigger_tgconstrrelid_index"
#define TriggerRelidIndex "pg_trigger_tgrelid_index" #define TriggerRelidIndex "pg_trigger_tgrelid_index"
#define TriggerOidIndex "pg_trigger_oid_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" #define TypeOidIndex "pg_type_oid_index"
/* Arrays of names of indices for each system catalog */ /* 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_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_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_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 */ /* last step of initialization script: build the indices declared above */
BUILD_INDICES BUILD_INDICES

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 RelnameGetRelid(const char *relname);
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
extern RangeVar *makeRangeVarFromNameList(List *names);
#endif /* NAMESPACE_H */ #endif /* NAMESPACE_H */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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 * prototypes for functions in pg_aggregate.c
*/ */
extern void AggregateCreate(char *aggName, extern void AggregateCreate(const char *aggName,
char *aggtransfnName, Oid aggNamespace,
char *aggfinalfnName, char *aggtransfnName,
char *aggbasetypeName, char *aggfinalfnName,
char *aggtranstypeName, Oid aggBaseType,
char *agginitval); Oid aggTransType,
const char *agginitval);
extern Datum AggNameGetInitVal(char *aggName, Oid basetype, extern Datum AggNameGetInitVal(char *aggName, Oid basetype,
bool *isNull); bool *isNull);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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 \ #define Schema_pg_type \
{ 1247, {"typname"}, 19, DEFAULT_ATTSTATTARGET, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \ { 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, {"typnamespace"}, 26, 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, {"typowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typprtlen"}, 21, 0, 2, 4, 0, -1, -1, true, 'p', false, 's', false, false }, \ { 1247, {"typlen"}, 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, {"typprtlen"}, 21, 0, 2, 5, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1247, {"typtype"}, 18, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \ { 1247, {"typbyval"}, 16, 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, {"typtype"}, 18, 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, {"typisdefined"}, 16, 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, {"typdelim"}, 18, 0, 1, 9, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typelem"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \ { 1247, {"typrelid"}, 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, {"typelem"}, 26, 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, {"typinput"}, 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, {"typoutput"}, 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, {"typreceive"}, 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, {"typsend"}, 24, 0, 4, 15, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typstorage"}, 18, 0, 1, 16, 0, -1, -1, true, 'p', false, 'c', false, false }, \ { 1247, {"typalign"}, 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, {"typstorage"}, 18, 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, {"typnotnull"}, 16, 0, 1, 18, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typtypmod"}, 23, 0, 4, 19, 0, -1, -1, true, 'p', false, 'i', false, false }, \ { 1247, {"typbasetype"}, 26, 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, {"typtypmod"}, 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, {"typndims"}, 23, 0, 4, 21, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typdefault"}, 25, 0, -1, 22, 0, -1, -1, false, 'x', 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 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 typnamespace 26 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 typowner 23 0 4 3 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typprtlen 21 0 2 4 0 -1 -1 t p f s f f)); DATA(insert ( 1247 typlen 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 typprtlen 21 0 2 5 0 -1 -1 t p f s f f));
DATA(insert ( 1247 typtype 18 0 1 6 0 -1 -1 t p f c f f)); DATA(insert ( 1247 typbyval 16 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 typtype 18 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 typisdefined 16 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 typdelim 18 0 1 9 0 -1 -1 t p f c f f));
DATA(insert ( 1247 typelem 26 0 4 10 0 -1 -1 t p f i f f)); DATA(insert ( 1247 typrelid 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 typelem 26 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 typinput 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 typoutput 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 typreceive 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 typsend 24 0 4 15 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typstorage 18 0 1 16 0 -1 -1 t p f c f f)); DATA(insert ( 1247 typalign 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 typstorage 18 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 typnotnull 16 0 1 18 0 -1 -1 t p f c f f));
DATA(insert ( 1247 typtypmod 23 0 4 19 0 -1 -1 t p f i f f)); DATA(insert ( 1247 typbasetype 26 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 typtypmod 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 typndims 23 0 4 21 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typdefault 25 0 -1 22 0 -1 -1 f x 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 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 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)); DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p f i f f));

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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(""); 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_ )); 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(""); DESCR("");

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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 * function prototypes
*/ */
extern void OperatorCreate(char *operatorName, extern void OperatorCreate(const char *operatorName,
char *leftTypeName, Oid leftTypeId,
char *rightTypeName, Oid rightTypeId,
char *procedureName, const char *procedureName,
uint16 precedence, uint16 precedence,
bool isLeftAssociative, bool isLeftAssociative,
char *commutatorName, const char *commutatorName,
char *negatorName, const char *negatorName,
char *restrictionName, const char *restrictionName,
char *joinName, const char *joinName,
bool canHash, bool canHash,
char *leftSortName, const char *leftSortName,
char *rightSortName); const char *rightSortName);
#endif /* PG_OPERATOR_H */ #endif /* PG_OPERATOR_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * 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, extern Oid ProcedureCreate(char *procedureName,
Oid procNamespace,
bool replace, bool replace,
bool returnsSet, bool returnsSet,
char *returnTypeName, Oid returnType,
Oid languageObjectId, Oid languageObjectId,
char *prosrc, char *prosrc,
char *probin, char *probin,

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -38,8 +38,9 @@
*/ */
CATALOG(pg_type) BOOTSTRAP CATALOG(pg_type) BOOTSTRAP
{ {
NameData typname; NameData typname; /* type name */
int4 typowner; 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 * 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 * 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_typname 1
#define Anum_pg_type_typowner 2 #define Anum_pg_type_typnamespace 2
#define Anum_pg_type_typlen 3 #define Anum_pg_type_typowner 3
#define Anum_pg_type_typprtlen 4 #define Anum_pg_type_typlen 4
#define Anum_pg_type_typbyval 5 #define Anum_pg_type_typprtlen 5
#define Anum_pg_type_typtype 6 #define Anum_pg_type_typbyval 6
#define Anum_pg_type_typisdefined 7 #define Anum_pg_type_typtype 7
#define Anum_pg_type_typdelim 8 #define Anum_pg_type_typisdefined 8
#define Anum_pg_type_typrelid 9 #define Anum_pg_type_typdelim 9
#define Anum_pg_type_typelem 10 #define Anum_pg_type_typrelid 10
#define Anum_pg_type_typinput 11 #define Anum_pg_type_typelem 11
#define Anum_pg_type_typoutput 12 #define Anum_pg_type_typinput 12
#define Anum_pg_type_typreceive 13 #define Anum_pg_type_typoutput 13
#define Anum_pg_type_typsend 14 #define Anum_pg_type_typreceive 14
#define Anum_pg_type_typalign 15 #define Anum_pg_type_typsend 15
#define Anum_pg_type_typstorage 16 #define Anum_pg_type_typalign 16
#define Anum_pg_type_typnotnull 17 #define Anum_pg_type_typstorage 17
#define Anum_pg_type_typbasetype 18 #define Anum_pg_type_typnotnull 18
#define Anum_pg_type_typtypmod 19 #define Anum_pg_type_typbasetype 19
#define Anum_pg_type_typndims 20 #define Anum_pg_type_typtypmod 20
#define Anum_pg_type_typdefaultbin 21 #define Anum_pg_type_typndims 21
#define Anum_pg_type_typdefault 22 #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 */ /* 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'"); DESCR("boolean, 'true'/'false'");
#define BOOLOID 16 #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"); DESCR("variable-length string, binary values escaped");
#define BYTEAOID 17 #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"); DESCR("single character");
#define CHAROID 18 #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"); DESCR("31-character type for storing system identifiers");
#define NAMEOID 19 #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"); DESCR("~18 digit integer, 8-byte storage");
#define INT8OID 20 #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"); DESCR("-32 thousand to 32 thousand, 2-byte storage");
#define INT2OID 21 #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"); DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables");
#define INT2VECTOROID 22 #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"); DESCR("-2 billion to 2 billion integer, 4-byte storage");
#define INT4OID 23 #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"); DESCR("registered procedure");
#define REGPROCOID 24 #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"); DESCR("variable-length string, no limit specified");
#define TEXTOID 25 #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"); DESCR("object identifier(oid), maximum 4 billion");
#define OIDOID 26 #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"); DESCR("(Block, offset), physical location of tuple");
#define TIDOID 27 #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"); DESCR("transaction id");
#define XIDOID 28 #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"); DESCR("command identifier type, sequence in transaction id");
#define CIDOID 29 #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"); DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
#define OIDVECTOROID 30 #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"); 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 = 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 PGUID 4 4 t c t \054 1249 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 PGUID 4 4 t c t \054 1255 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 PGUID 4 4 t c t \054 1259 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 PGUID 4 4 t c t \054 1260 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 PGUID 4 4 t c t \054 1261 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 PGUID 4 4 t c t \054 1262 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 100 - 199 */
/* OIDS 200 - 299 */ /* 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"); DESCR("storage manager");
/* OIDS 300 - 399 */ /* OIDS 300 - 399 */
@ -325,192 +327,194 @@ DESCR("storage manager");
/* OIDS 500 - 599 */ /* OIDS 500 - 599 */
/* OIDS 600 - 699 */ /* 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)'"); DESCR("geometric point '(x, y)'");
#define POINTOID 600 #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)'"); DESCR("geometric line segment '(pt1,pt2)'");
#define LSEGOID 601 #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,...)'"); DESCR("geometric path '(pt1,...)'");
#define PATHOID 602 #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)'"); DESCR("geometric box '(lower left,upper right)'");
#define BOXOID 603 #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,...)'"); DESCR("geometric polygon '(pt1,...)'");
#define POLYGONOID 604 #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)'"); DESCR("geometric line '(pt1,pt2)'");
#define LINEOID 628 #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(""); DESCR("");
/* OIDS 700 - 799 */ /* 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"); DESCR("single-precision floating point number, 4-byte storage");
#define FLOAT4OID 700 #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"); DESCR("double-precision floating point number, 8-byte storage");
#define FLOAT8OID 701 #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)"); DESCR("absolute, limited-range date and time (Unix system time)");
#define ABSTIMEOID 702 #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)"); DESCR("relative, limited-range time interval (Unix delta time)");
#define RELTIMEOID 703 #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"); DESCR("(abstime,abstime), time interval");
#define TINTERVALOID 704 #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(""); DESCR("");
#define UNKNOWNOID 705 #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)'"); DESCR("geometric circle '(center,radius)'");
#define CIRCLEOID 718 #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 = 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 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 = 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"); DESCR("$d,ddd.cc, money");
#define CASHOID 790 #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 */ /* 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"); DESCR("XX:XX:XX:XX:XX:XX, MAC address");
#define MACADDROID 829 #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"); DESCR("IP address/netmask, host address, netmask optional");
#define INETOID 869 #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"); DESCR("network IP address/netmask, network address");
#define CIDROID 650 #define CIDROID 650
/* OIDS 900 - 999 */ /* OIDS 900 - 999 */
/* OIDS 1000 - 1099 */ /* 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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 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 = 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. * Note: the size of aclitem needs to match sizeof(AclItem) in acl.h.
* Thanks to some padding, this will be 8 on all platforms. * Thanks to some padding, this will be 8 on all platforms.
* We also have an Assert to make sure. * We also have an Assert to make sure.
*/ */
#define ACLITEMSIZE 8 #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"); 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 = 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 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 = 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 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 = 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 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 = 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 PGUID -1 -1 f b t \054 0 0 bpcharin bpcharout bpcharin bpcharout 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"); DESCR("char(length), blank-padded string, fixed storage length");
#define BPCHAROID 1042 #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"); DESCR("varchar(length), non-blank-padded string, variable storage length");
#define VARCHAROID 1043 #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"); DESCR("ANSI SQL date");
#define DATEOID 1082 #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"); DESCR("hh:mm:ss, ANSI SQL time");
#define TIMEOID 1083 #define TIMEOID 1083
/* OIDS 1100 - 1199 */ /* 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"); DESCR("date and time");
#define TIMESTAMPOID 1114 #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 = 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 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 = 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 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 = 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 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 = 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"); DESCR("date and time with time zone");
#define TIMESTAMPTZOID 1184 #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 = 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 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 = 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"); DESCR("@ <number> <units>, time interval");
#define INTERVALOID 1186 #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 */ /* 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 = 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 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 = 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"); DESCR("hh:mm:ss, ANSI SQL time");
#define TIMETZOID 1266 #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 */ /* 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"); DESCR("fixed-length bit string");
#define BITOID 1560 #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 = 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 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 = 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"); DESCR("variable-length bit string");
#define VARBITOID 1562 #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 1600 - 1699 */
/* OIDS 1700 - 1799 */ /* 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"); DESCR("numeric(precision, decimal), arbitrary precision number");
#define NUMERICOID 1700 #define NUMERICOID 1700
/* OID 1790 */ 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_ ));
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_ ));
DESCR("reference cursor (portal name)"); DESCR("reference cursor (portal name)");
#define REFCURSOROID 1790 #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 * prototypes for functions in pg_type.c
*/ */
extern Oid TypeGet(char *typeName, bool *defined); extern Oid TypeShellMake(const char *typeName, Oid typeNamespace);
extern Oid TypeShellMake(char *typeName);
extern Oid TypeCreate(char *typeName, extern Oid TypeCreate(const char *typeName,
Oid typeNamespace,
Oid assignedTypeOid, Oid assignedTypeOid,
Oid relationOid, Oid relationOid,
int16 internalSize, int16 internalSize,
int16 externalSize, int16 externalSize,
char typeType, char typeType,
char typDelim, char typDelim,
char *inputProcedure, Oid inputProcedure,
char *outputProcedure, Oid outputProcedure,
char *receiveProcedure, Oid receiveProcedure,
char *sendProcedure, Oid sendProcedure,
char *elementTypeName, Oid elementType,
char *baseTypeName, Oid baseType,
char *defaultTypeValue, const char *defaultTypeValue,
char *defaultTypeBin, const char *defaultTypeBin,
bool passedByValue, bool passedByValue,
char alignment, char alignment,
char storage, char storage,
@ -519,7 +523,8 @@ extern Oid TypeCreate(char *typeName,
bool typeNotNull); bool typeNotNull);
extern void TypeRename(const char *oldTypeName, const char *newTypeName); extern void TypeRename(const char *oldTypeName, Oid typeNamespace,
extern char *makeArrayTypeName(char *typeName); const char *newTypeName);
extern char *makeArrayTypeName(const char *typeName);
#endif /* PG_TYPE_H */ #endif /* PG_TYPE_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * ALTER TABLE variants
*/ */
extern void AlterTableAddColumn(const char *relationName, extern void AlterTableAddColumn(Oid myrelid, bool inherits, ColumnDef *colDef);
bool inh, ColumnDef *colDef);
extern void AlterTableAlterColumnDefault(const char *relationName, extern void AlterTableAlterColumnDefault(Oid myrelid, bool inh,
bool inh, const char *colName, const char *colName, Node *newDefault);
Node *newDefault);
extern void AlterTableAlterColumnFlags(const char *relationName, extern void AlterTableAlterColumnFlags(Oid myrelid,
bool inh, const char *colName, bool inh, const char *colName,
Node *flagValue, const char *flagType); Node *flagValue, const char *flagType);
extern void AlterTableDropColumn(const char *relationName, extern void AlterTableDropColumn(Oid myrelid, bool inh,
bool inh, const char *colName, const char *colName, int behavior);
int behavior);
extern void AlterTableAddConstraint(char *relationName, extern void AlterTableAddConstraint(Oid myrelid,
bool inh, List *newConstraints); bool inh, List *newConstraints);
extern void AlterTableDropConstraint(const char *relationName, extern void AlterTableDropConstraint(Oid myrelid,
bool inh, const char *constrName, bool inh, const char *constrName, int behavior);
int behavior);
extern void AlterTableCreateToastTable(Oid relOid, bool silent); extern void AlterTableCreateToastTable(Oid relOid, bool silent);
extern void AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName); extern void AlterTableOwner(Oid relationOid, int32 newOwnerSysId);
/* /*
* LOCK * LOCK

View File

@ -7,16 +7,19 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 #ifndef COPY_H
#define COPY_H #define COPY_H
#include "nodes/primnodes.h"
extern int copy_lineno; extern int copy_lineno;
void DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, void DoCopy(const RangeVar *relation, bool binary, bool oids,
char *filename, char *delim, char *null_print); bool from, bool pipe,
char *filename, char *delim, char *null_print);
#endif /* COPY_H */ #endif /* COPY_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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" #include "nodes/parsenodes.h"
extern Oid DefineRelation(CreateStmt *stmt, char relkind); extern Oid DefineRelation(CreateStmt *stmt, char relkind);
extern void RemoveRelation(const char *name); extern void RemoveRelation(const RangeVar *relation);
extern void TruncateRelation(const char *name); extern void TruncateRelation(const RangeVar *relation);
#endif /* CREATINH_H */ #endif /* CREATINH_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * prototypes in define.c
*/ */
extern void CreateFunction(ProcedureStmt *stmt); extern void CreateFunction(ProcedureStmt *stmt);
extern void DefineOperator(char *name, List *parameters); extern void DefineOperator(List *names, List *parameters);
extern void DefineAggregate(char *name, List *parameters); extern void DefineAggregate(List *names, List *parameters);
extern void DefineType(char *name, List *parameters); extern void DefineType(List *names, List *parameters);
extern void DefineDomain(CreateDomainStmt *stmt); extern void DefineDomain(CreateDomainStmt *stmt);
/* /*
* prototypes in remove.c * 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 RemoveFunction(char *functionName, List *argTypes);
extern void RemoveOperator(char *operatorName, extern void RemoveOperator(char *operatorName,
char *typeName1, char *typeName2); TypeName *typeName1, TypeName *typeName2);
extern void RemoveType(char *typeName); extern void RemoveType(List *names);
extern void RemoveAggregate(char *aggName, char *aggType); extern void RemoveAggregate(char *aggName, TypeName *aggType);
#endif /* DEFREM_H */ #endif /* DEFREM_H */

View File

@ -7,17 +7,17 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 #ifndef RENAME_H
#define RENAME_H #define RENAME_H
extern void renameatt(char *relname, extern void renameatt(Oid relid,
char *oldattname, char *oldattname,
char *newattname, char *newattname,
int recurse); bool recurse);
extern void renamerel(const RangeVar *relation, extern void renamerel(const RangeVar *relation,
const char *newrelname); const char *newrelname);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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" #include "nodes/parsenodes.h"
extern void DefineView(char *view_name, Query *view_parse); extern void DefineView(const RangeVar *view, Query *view_parse);
extern void RemoveView(char *view_name); extern void RemoveView(const RangeVar *view);
#endif /* VIEW_H */ #endif /* VIEW_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 RangeVar *makeRangeVar(char *schemaname, char *relname);
extern TypeName *makeTypeName(char *typnam);
#endif /* MAKEFUNC_H */ #endif /* MAKEFUNC_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * 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 typedef struct TypeName
{ {
NodeTag type; 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 timezone; /* timezone specified? */
bool setof; /* is a set? */ bool setof; /* is a set? */
bool pct_type; /* %TYPE specified? */
int32 typmod; /* type modifier */ int32 typmod; /* type modifier */
List *arrayBounds; /* array bounds */ List *arrayBounds; /* array bounds */
char *attrname; /* field name when using %TYPE */
} TypeName; } TypeName;
/* /*
@ -1023,7 +1032,7 @@ typedef struct DefineStmt
{ {
NodeTag type; NodeTag type;
int defType; /* OPERATOR|TYPE_P|AGGREGATE */ int defType; /* OPERATOR|TYPE_P|AGGREGATE */
char *defname; List *defnames; /* qualified name (list of Value strings) */
List *definition; /* a list of DefElem */ List *definition; /* a list of DefElem */
} DefineStmt; } DefineStmt;
@ -1034,9 +1043,9 @@ typedef struct DefineStmt
typedef struct CreateDomainStmt typedef struct CreateDomainStmt
{ {
NodeTag type; NodeTag type;
char *domainname; /* name of domain to create */ List *domainname; /* qualified name (list of Value strings) */
TypeName *typename; /* the base type */ TypeName *typename; /* the base type */
List *constraints; /* constraints (list of Constraint nodes) */ List *constraints; /* constraints (list of Constraint nodes) */
} CreateDomainStmt; } CreateDomainStmt;
/* ---------------------- /* ----------------------
@ -1055,7 +1064,7 @@ typedef struct CreateDomainStmt
typedef struct DropStmt typedef struct DropStmt
{ {
NodeTag type; NodeTag type;
List *objects; List *objects; /* list of sublists of names (as Values) */
int removeType; int removeType;
int behavior; /* CASCADE or RESTRICT drop behavior */ int behavior; /* CASCADE or RESTRICT drop behavior */
} DropStmt; } DropStmt;
@ -1135,9 +1144,9 @@ typedef struct ProcedureStmt
{ {
NodeTag type; NodeTag type;
bool replace; /* T => replace if already exists */ 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) */ 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 *withClause; /* a list of DefElem */
List *as; /* definition of function body */ List *as; /* definition of function body */
char *language; /* C, SQL, etc */ char *language; /* C, SQL, etc */
@ -1151,7 +1160,7 @@ typedef struct RemoveAggrStmt
{ {
NodeTag type; NodeTag type;
char *aggname; /* aggregate to drop */ char *aggname; /* aggregate to drop */
Node *aggtype; /* TypeName for input datatype, or NULL */ TypeName *aggtype; /* TypeName for input datatype, or NULL */
} RemoveAggrStmt; } RemoveAggrStmt;
/* ---------------------- /* ----------------------

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 int32 exprTypmod(Node *expr);
extern bool exprIsLengthCoercion(Node *expr, int32 *coercedTypmod); extern bool exprIsLengthCoercion(Node *expr, int32 *coercedTypmod);
extern void parse_expr_init(void); extern void parse_expr_init(void);
extern char *TypeNameToInternalName(TypeName *typename);
#endif /* PARSE_EXPR_H */ #endif /* PARSE_EXPR_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId);
extern void func_error(char *caller, char *funcname, extern void func_error(const char *caller, const char *funcname,
int nargs, Oid *argtypes, char *msg); int nargs, const Oid *argtypes,
const char *msg);
#endif /* PARSE_FUNC_H */ #endif /* PARSE_FUNC_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 #define PARSE_TYPE_H
#include "access/htup.h" #include "access/htup.h"
#include "parser/parse_node.h"
typedef HeapTuple Type; 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 bool typeidIsValid(Oid id);
extern Type typeidType(Oid id); extern Type typeidType(Oid id);
extern Type typenameType(char *s);
extern Oid typeTypeId(Type tp); extern Oid typeTypeId(Type tp);
extern int16 typeLen(Type t); extern int16 typeLen(Type t);
@ -32,7 +38,6 @@ extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod);
extern char *typeidTypeName(Oid id); extern char *typeidTypeName(Oid id);
extern Oid typeidTypeRelid(Oid type_id); extern Oid typeidTypeRelid(Oid type_id);
extern Oid typenameTypeId(char *s);
extern void parseTypeString(const char *str, Oid *type_id, int32 *typmod); extern void parseTypeString(const char *str, Oid *type_id, int32 *typmod);

View File

@ -7,14 +7,14 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 #ifndef REWRITEREMOVE_H
#define REWRITEREMOVE_H #define REWRITEREMOVE_H
extern void RemoveRewriteRule(char *ruleName); extern void RemoveRewriteRule(List *names);
extern void RelationRemoveRules(Oid relid); extern void RelationRemoveRules(Oid relid);
#endif /* REWRITEREMOVE_H */ #endif /* REWRITEREMOVE_H */

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 Oid get_relname_relid(const char *relname, Oid relnamespace);
extern char *get_rel_name(Oid relid); extern char *get_rel_name(Oid relid);
extern Oid get_rel_type_id(Oid relid); extern Oid get_rel_type_id(Oid relid);
extern bool get_typisdefined(Oid typid);
extern int16 get_typlen(Oid typid); extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid); extern bool get_typbyval(Oid typid);
extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval); extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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. */ /* Temporary name of a set function, before SetDefine changes it. */
#define GENERICSETNAME "ZYX#Set#ZYX" #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); extern Datum seteval(PG_FUNCTION_ARGS);

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 SHADOWNAME 26
#define SHADOWSYSID 27 #define SHADOWSYSID 27
#define STATRELATT 28 #define STATRELATT 28
#define TYPENAME 29 #define TYPENAMENSP 29
#define TYPEOID 30 #define TYPEOID 30

View File

@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
@ -47,14 +47,15 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/namespace.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_attribute.h"
#include "catalog/pg_attrdef.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 "commands/trigger.h"
#include "executor/spi.h" #include "executor/spi.h"
#include "fmgr.h" #include "fmgr.h"
#include "nodes/makefuncs.h"
#include "parser/gramparse.h" #include "parser/gramparse.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "tcop/tcopprot.h" #include "tcop/tcopprot.h"
@ -851,10 +852,8 @@ plpgsql_parse_wordtype(char *word)
{ {
PLpgSQL_nsitem *nse; PLpgSQL_nsitem *nse;
char *cp; char *cp;
HeapTuple typeTup;
Form_pg_type typeStruct;
char *typeXlated;
bool old_nsstate; bool old_nsstate;
Oid typeOid;
/* /*
* We do our lookups case insensitive * 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 * 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. * 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); typeOid = LookupTypeName(makeTypeName(xlateSqlType(cp)));
typeTup = SearchSysCache(TYPENAME, if (OidIsValid(typeOid))
PointerGetDatum(typeXlated),
0, 0, 0);
if (HeapTupleIsValid(typeTup))
{ {
PLpgSQL_type *typ; HeapTuple typeTup;
typeStruct = (Form_pg_type) GETSTRUCT(typeTup); typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typeOid),
if (typeStruct->typrelid != InvalidOid) 0, 0, 0);
if (HeapTupleIsValid(typeTup))
{ {
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->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;
ReleaseSysCache(typeTup); ReleaseSysCache(typeTup);
pfree(cp); pfree(cp);
return T_ERROR; return T_DTYPE;
} }
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;
plpgsql_yylval.dtype = typ;
ReleaseSysCache(typeTup);
pfree(cp);
return T_DTYPE;
} }
/* /*

View File

@ -29,7 +29,7 @@
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * 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 /* postgreSQL stuff
*/ */
#include "executor/spi.h"
#include "commands/trigger.h"
#include "utils/elog.h"
#include "fmgr.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "tcop/tcopprot.h"
#include "utils/syscache.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "executor/spi.h"
#include "fmgr.h"
#include "nodes/makefuncs.h"
#include "parser/parse_type.h"
#include "tcop/tcopprot.h"
#include "utils/syscache.h"
#include <Python.h> #include <Python.h>
#include "plpython.h" #include "plpython.h"
@ -2086,16 +2086,8 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
RAISE_EXC(1); RAISE_EXC(1);
} }
sptr = PyString_AsString(optr); sptr = PyString_AsString(optr);
typeTup = SearchSysCache(TYPENAME, PointerGetDatum(sptr), /* XXX should extend this to allow qualified type names */
0, 0, 0); typeTup = typenameType(makeTypeName(sptr));
if (!HeapTupleIsValid(typeTup))
{
PLy_exception_set(PLy_exc_spi_error,
"Cache lookup for type `%s' failed.",
sptr);
RAISE_EXC(1);
}
Py_DECREF(optr); Py_DECREF(optr);
optr = NULL; /* this is important */ optr = NULL; /* this is important */

View File

@ -31,7 +31,7 @@
* ENHANCEMENTS, OR MODIFICATIONS. * ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * 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 <string.h>
#include <setjmp.h> #include <setjmp.h>
#include "executor/spi.h"
#include "commands/trigger.h"
#include "utils/builtins.h"
#include "fmgr.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "tcop/tcopprot.h"
#include "utils/syscache.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "executor/spi.h"
#include "fmgr.h"
#include "nodes/makefuncs.h"
#include "parser/parse_type.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
#if defined(UNICODE_CONVERSION) && TCL_MAJOR_VERSION == 8 \ #if defined(UNICODE_CONVERSION) && TCL_MAJOR_VERSION == 8 \
&& TCL_MINOR_VERSION > 0 && TCL_MINOR_VERSION > 0
@ -1750,11 +1751,8 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
************************************************************/ ************************************************************/
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
{ {
typeTup = SearchSysCache(TYPENAME, /* XXX should extend this to allow qualified type names */
PointerGetDatum(args[i]), typeTup = typenameType(makeTypeName(args[i]));
0, 0, 0);
if (!HeapTupleIsValid(typeTup))
elog(ERROR, "pltcl: Cache lookup of type %s failed", args[i]);
qdesc->argtypes[i] = typeTup->t_data->t_oid; qdesc->argtypes[i] = typeTup->t_data->t_oid;
perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput, perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput,
&(qdesc->arginfuncs[i])); &(qdesc->arginfuncs[i]));

View File

@ -137,7 +137,7 @@ drop aggregate 314159 (int);
ERROR: parser: parse error at or near "314159" ERROR: parser: parse error at or near "314159"
-- bad aggregate type -- bad aggregate type
drop aggregate newcnt (nonesuch); drop aggregate newcnt (nonesuch);
ERROR: RemoveAggregate: type 'nonesuch' does not exist ERROR: Type "nonesuch" does not exist
-- no such aggregate -- no such aggregate
drop aggregate nonesuch (int4); drop aggregate nonesuch (int4);
ERROR: RemoveAggregate: aggregate 'nonesuch' for type integer does not exist 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" ERROR: parser: parse error at or near "314159"
-- no such type -- no such type
drop type nonesuch; drop type nonesuch;
ERROR: RemoveType: type 'nonesuch' does not exist ERROR: Type "nonesuch" does not exist
-- --
-- DROP OPERATOR -- DROP OPERATOR
@ -203,10 +203,10 @@ drop operator = ( , int4);
ERROR: parser: parse error at or near "," ERROR: parser: parse error at or near ","
-- no such type1 -- no such type1
drop operator = (nonesuch, int4); drop operator = (nonesuch, int4);
ERROR: RemoveOperator: type 'nonesuch' does not exist ERROR: Type "nonesuch" does not exist
-- no such type2 -- no such type2
drop operator = (int4, nonesuch); drop operator = (int4, nonesuch);
ERROR: RemoveOperator: type 'nonesuch' does not exist ERROR: Type "nonesuch" does not exist
-- no such type2 -- no such type2
drop operator = (int4, ); drop operator = (int4, );
ERROR: parser: parse error at or near ")" ERROR: parser: parse error at or near ")"

View File

@ -13,8 +13,8 @@ CREATE FUNCTION hobbies_by_name(hobbies_r.name%TYPE)
RETURNS hobbies_r.person%TYPE RETURNS hobbies_r.person%TYPE
AS 'select person from hobbies_r where name = $1' AS 'select person from hobbies_r where name = $1'
LANGUAGE 'sql'; LANGUAGE 'sql';
NOTICE: hobbies_r.name%TYPE converted to text
NOTICE: hobbies_r.person%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) CREATE FUNCTION equipment(hobbies_r)
RETURNS setof equipment_r RETURNS setof equipment_r
AS 'select * from equipment_r where hobby = $1.name' AS 'select * from equipment_r where hobby = $1.name'