Commit d5e99ab4 authored by Tom Lane's avatar Tom Lane

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.
parent 7c1ff354
<!--
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">
......@@ -2363,6 +2363,15 @@
<entry>Data type name</entry>
</row>
<row>
<entry>typnamespace</entry>
<entry><type>oid</type></entry>
<entry>pg_namespace.oid</entry>
<entry>
The OID of the namespace that contains this type
</entry>
</row>
<row>
<entry>typowner</entry>
<entry><type>int4</type></entry>
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.77 2002/02/27 19:34:11 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.78 2002/03/29 19:05:59 tgl Exp $
*
* NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be
......@@ -322,7 +322,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
* a preallocated tuple descriptor.
* ----------------------------------------------------------------
*/
bool
void
TupleDescInitEntry(TupleDesc desc,
AttrNumber attributeNumber,
char *attributeName,
......@@ -377,39 +377,11 @@ TupleDescInitEntry(TupleDesc desc,
att->attnotnull = false;
att->atthasdef = false;
/* ----------------
* search the system cache for the type tuple of the attribute
* we are creating so that we can get the typeid and some other
* stuff.
*
* Note: in the special case of
*
* create EMP (name = text, manager = EMP)
*
* RelationNameCreateHeapRelation() calls BuildDesc() which
* calls this routine and since EMP does not exist yet, the
* system cache lookup below fails. That's fine, but rather
* then doing a elog(ERROR) we just leave that information
* uninitialized, return false, then fix things up later.
* -cim 6/14/90
* ----------------
*/
tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(oidtypeid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
/*
* here type info does not exist yet so we just fill the attribute
* with dummy information and return false.
*/
att->atttypid = InvalidOid;
att->attlen = (int16) 0;
att->attbyval = (bool) 0;
att->attalign = 'i';
att->attstorage = 'p';
return false;
}
elog(ERROR, "Unable to look up type id %u", oidtypeid);
/*
* type info exists so we initialize our attribute information from
......@@ -477,56 +449,16 @@ TupleDescInitEntry(TupleDesc desc,
}
ReleaseSysCache(tuple);
return true;
}
/* ----------------------------------------------------------------
* TupleDescMakeSelfReference
/*
* BuildDescForRelation
*
* This function initializes a "self-referential" attribute like
* manager in "create EMP (name=text, manager = EMP)".
* It calls TypeShellMake() which inserts a "shell" type
* tuple into pg_type. A self-reference is one kind of set, so
* its size and byval are the same as for a set. See the comments
* above in TupleDescInitEntry.
* ----------------------------------------------------------------
*/
static void
TupleDescMakeSelfReference(TupleDesc desc,
AttrNumber attnum,
char *relname)
{
Form_pg_attribute att;
att = desc->attrs[attnum - 1];
att->atttypid = TypeShellMake(relname);
att->attlen = sizeof(Oid);
att->attbyval = true;
att->attalign = 'i';
att->attstorage = 'p';
att->attndims = 0;
}
/* ----------------------------------------------------------------
* BuildDescForRelation
*
* This is a general purpose function identical to BuildDesc
* but is used by the DefineRelation() code to catch the
* special case where you
*
* create FOO ( ..., x = FOO )
*
* here, the initial type lookup for "x = FOO" will fail
* because FOO isn't in the catalogs yet. But since we
* are creating FOO, instead of doing an elog() we add
* a shell type tuple to pg_type and fix things later
* in amcreate().
* ----------------------------------------------------------------
* Given a relation schema (list of ColumnDef nodes), build a TupleDesc.
*/
TupleDesc
BuildDescForRelation(List *schema, char *relname)
BuildDescForRelation(List *schema)
{
int natts;
AttrNumber attnum;
......@@ -535,7 +467,6 @@ BuildDescForRelation(List *schema, char *relname)
AttrDefault *attrdef = NULL;
TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
char *attname;
char typename[NAMEDATALEN];
int32 atttypmod;
int attdim;
int ndef = 0;
......@@ -553,7 +484,6 @@ BuildDescForRelation(List *schema, char *relname)
foreach(p, schema)
{
ColumnDef *entry = lfirst(p);
List *arry;
/*
* for each entry in the list, get the name and type information
......@@ -563,39 +493,13 @@ BuildDescForRelation(List *schema, char *relname)
attnum++;
attname = entry->colname;
arry = entry->typename->arrayBounds;
attisset = entry->typename->setof;
atttypmod = entry->typename->typmod;
attdim = length(entry->typename->arrayBounds);
if (arry != NIL)
{
/* array of XXX is _XXX */
snprintf(typename, NAMEDATALEN,
"_%.*s", NAMEDATALEN - 2, entry->typename->name);
attdim = length(arry);
}
else
{
StrNCpy(typename, entry->typename->name, NAMEDATALEN);
attdim = 0;
}
if (!TupleDescInitEntry(desc, attnum, attname,
typenameTypeId(typename),
atttypmod, attdim, attisset))
{
/*
* if TupleDescInitEntry() fails, it means there is no type in
* the system catalogs. So now we check if the type name
* equals the relation name. If so we have a self reference,
* otherwise it's an error.
*/
if (strcmp(typename, relname) == 0)
TupleDescMakeSelfReference(desc, attnum, relname);
else
elog(ERROR, "DefineRelation: no such type %s",
typename);
}
TupleDescInitEntry(desc, attnum, attname,
typenameTypeId(entry->typename),
atttypmod, attdim, attisset);
/* This is for constraints */
if (entry->is_not_null)
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.59 2002/03/26 19:15:22 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.60 2002/03/29 19:05:59 tgl Exp $
*
* NOTES
* See acl.h.
......@@ -37,6 +37,7 @@
#include "parser/parse_agg.h"
#include "parser/parse_func.h"
#include "parser/parse_expr.h"
#include "parser/parse_type.h"
#include "utils/acl.h"
#include "utils/syscache.h"
#include "utils/temprel.h"
......@@ -300,20 +301,19 @@ find_function_with_arglist(char *name, List *arguments)
for (i = 0; i < argcount; i++)
{
TypeName *t = (TypeName *) lfirst(arguments);
char *typnam = TypeNameToInternalName(t);
arguments = lnext(arguments);
if (strcmp(typnam, "opaque") == 0)
argoids[i] = InvalidOid;
else
argoids[i] = LookupTypeName(t);
if (!OidIsValid(argoids[i]))
{
argoids[i] = GetSysCacheOid(TYPENAME,
PointerGetDatum(typnam),
0, 0, 0);
if (!OidIsValid(argoids[i]))
elog(ERROR, "type '%s' not found", typnam);
char *typnam = TypeNameToString(t);
if (strcmp(typnam, "opaque") == 0)
argoids[i] = InvalidOid;
else
elog(ERROR, "Type \"%s\" does not exist", typnam);
}
arguments = lnext(arguments);
}
oid = GetSysCacheOid(PROCNAME,
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.192 2002/03/26 19:15:25 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.193 2002/03/29 19:05:59 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -74,8 +74,10 @@ static void DeleteRelationTuple(Relation rel);
static void DeleteTypeTuple(Relation rel);
static void RelationRemoveIndexes(Relation relation);
static void RelationRemoveInheritance(Relation relation);
static void AddNewRelationType(char *typeName, Oid new_rel_oid,
Oid new_type_oid);
static void AddNewRelationType(const char *typeName,
Oid typeNamespace,
Oid new_rel_oid,
Oid new_type_oid);
static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin);
static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
static void StoreConstraints(Relation rel, TupleDesc tupdesc);
......@@ -242,7 +244,7 @@ heap_create(char *relname,
* have to take special care for those rels that should be nailed
* in cache and/or are shared across databases.
*/
if (relname && relnamespace == PG_CATALOG_NAMESPACE)
if (relnamespace == PG_CATALOG_NAMESPACE)
{
if (strcmp(TypeRelationName, relname) == 0)
{
......@@ -622,7 +624,10 @@ AddNewRelationTuple(Relation pg_class_desc,
* --------------------------------
*/
static void
AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
AddNewRelationType(const char *typeName,
Oid typeNamespace,
Oid new_rel_oid,
Oid new_type_oid)
{
/*
* The sizes are set to oid size because it makes implementing sets
......@@ -634,18 +639,19 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
* true makes sets much easier, and it isn't used by anything else.
*/
TypeCreate(typeName, /* type name */
typeNamespace, /* type namespace */
new_type_oid, /* preassigned oid for type */
new_rel_oid, /* relation oid */
sizeof(Oid), /* internal size */
-1, /* external size */
'c', /* type-type (catalog) */
'c', /* type-type (complex) */
',', /* default array delimiter */
"oidin", /* input procedure */
"oidout", /* output procedure */
"oidin", /* receive procedure */
"oidout", /* send procedure */
NULL, /* array element type - irrelevant */
NULL, /* baseType Name -- typically for domains */
F_OIDIN, /* input procedure */
F_OIDOUT, /* output procedure */
F_OIDIN, /* receive procedure */
F_OIDOUT, /* send procedure */
InvalidOid, /* array element type - irrelevant */
InvalidOid, /* domain base type - irrelevant */
NULL, /* default type value - none */
NULL, /* default type binary representation */
true, /* passed by value */
......@@ -744,7 +750,7 @@ heap_create_with_catalog(char *relname,
* NOTE: we could get a unique-index failure here, in case the same name
* has already been used for a type.
*/
AddNewRelationType(relname, new_rel_oid, new_type_oid);
AddNewRelationType(relname, relnamespace, new_rel_oid, new_type_oid);
/*
* now add tuples to pg_attribute for the attributes in our new
......@@ -1002,15 +1008,13 @@ RelationTruncateIndexes(Oid heapId)
*/
void
heap_truncate(const char *relname)
heap_truncate(Oid rid)
{
Relation rel;
Oid rid;
/* Open relation for processing, and grab exclusive access on it. */
rel = heap_openr(relname, AccessExclusiveLock);
rid = RelationGetRelid(rel);
rel = heap_open(rid, AccessExclusiveLock);
/*
* TRUNCATE TABLE within a transaction block is dangerous, because if
......@@ -1217,21 +1221,22 @@ DeleteTypeTuple(Relation rel)
* ----------------------------------------------------------------
*/
void
heap_drop_with_catalog(const char *relname,
heap_drop_with_catalog(Oid rid,
bool allow_system_table_mods)
{
Relation rel;
Oid rid;
Oid toasttableOid;
bool has_toasttable;
bool istemp = is_temp_rel_name(relname);
bool istemp;
int i;
/*
* Open and lock the relation.
*/
rel = heap_openr(relname, AccessExclusiveLock);
rid = RelationGetRelid(rel);
rel = heap_open(rid, AccessExclusiveLock);
has_toasttable = rel->rd_rel->reltoastrelid != InvalidOid;
toasttableOid = rel->rd_rel->reltoastrelid;
istemp = is_temp_rel_name(RelationGetRelationName(rel));
/*
* prevent deletion of system relations
......@@ -1319,12 +1324,7 @@ heap_drop_with_catalog(const char *relname,
remove_temp_rel_by_relid(rid);
if (has_toasttable)
{
char toast_relname[NAMEDATALEN];
sprintf(toast_relname, "pg_toast_%u", rid);
heap_drop_with_catalog(toast_relname, true);
}
heap_drop_with_catalog(toasttableOid, true);
}
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.85 2002/03/26 19:15:30 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.86 2002/03/29 19:06:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -76,7 +76,7 @@ char *Name_pg_statistic_indices[Num_pg_statistic_indices] =
char *Name_pg_trigger_indices[Num_pg_trigger_indices] =
{TriggerRelidIndex, TriggerConstrNameIndex, TriggerConstrRelidIndex, TriggerOidIndex};
char *Name_pg_type_indices[Num_pg_type_indices] =
{TypeNameIndex, TypeOidIndex};
{TypeNameNspIndex, TypeOidIndex};
char *Name_pg_description_indices[Num_pg_description_indices] =
{DescriptionObjIndex};
......
......@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.1 2002/03/26 19:15:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.2 2002/03/29 19:06:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -22,6 +22,7 @@
#include "catalog/namespace.h"
#include "catalog/pg_namespace.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
......@@ -124,3 +125,92 @@ RelnameGetRelid(const char *relname)
/* XXX Wrong! must search search path */
return get_relname_relid(relname, PG_CATALOG_NAMESPACE);
}
/*
* QualifiedNameGetCreationNamespace
* Given a possibly-qualified name for an object (in List-of-Values
* format), determine what namespace the object should be created in.
* Also extract and return the object name (last component of list).
*/
Oid
QualifiedNameGetCreationNamespace(List *names, char **objname_p)
{
char *catalogname;
char *schemaname = NULL;
char *objname = NULL;
Oid namespaceId;
/* deconstruct the name list */
switch (length(names))
{
case 1:
objname = strVal(lfirst(names));
break;
case 2:
schemaname = strVal(lfirst(names));
objname = strVal(lsecond(names));
break;
case 3:
catalogname = strVal(lfirst(names));
schemaname = strVal(lsecond(names));
objname = strVal(lfirst(lnext(lnext(names))));
/*
* We check the catalog name and then ignore it.
*/
if (strcmp(catalogname, DatabaseName) != 0)
elog(ERROR, "Cross-database references are not implemented");
break;
default:
elog(ERROR, "Improper qualified name (too many dotted names)");
break;
}
if (schemaname)
{
namespaceId = GetSysCacheOid(NAMESPACENAME,
CStringGetDatum(schemaname),
0, 0, 0);
if (!OidIsValid(namespaceId))
elog(ERROR, "Namespace \"%s\" does not exist",
schemaname);
}
else
{
/* XXX Wrong! Need to get a default schema from somewhere */
namespaceId = PG_CATALOG_NAMESPACE;
}
*objname_p = objname;
return namespaceId;
}
/*
* makeRangeVarFromNameList
* Utility routine to convert a qualified-name list into RangeVar form.
*/
RangeVar *
makeRangeVarFromNameList(List *names)
{
RangeVar *rel = makeRangeVar(NULL, NULL);
switch (length(names))
{
case 1:
rel->relname = strVal(lfirst(names));
break;
case 2:
rel->schemaname = strVal(lfirst(names));
rel->relname = strVal(lsecond(names));
break;
case 3:
rel->catalogname = strVal(lfirst(names));
rel->schemaname = strVal(lsecond(names));
rel->relname = strVal(lfirst(lnext(lnext(names))));
break;
default:
elog(ERROR, "Improper relation name (too many dotted names)");
break;
}
return rel;
}
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.41 2002/03/20 19:43:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.42 2002/03/29 19:06:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -23,34 +23,21 @@
#include "miscadmin.h"
#include "parser/parse_coerce.h"
#include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
/* ----------------
/*
* AggregateCreate
*
* aggregates overloading has been added. Instead of the full
* overload support we have for functions, aggregate overloading only
* applies to exact basetype matches. That is, we don't check the
* inheritance hierarchy
*
* OLD COMMENTS:
* Currently, redefining aggregates using the same name is not
* supported. In such a case, a warning is printed that the
* aggregate already exists. If such is not the case, a new tuple
* is created and inserted in the aggregate relation.
* All types and functions must have been defined
* prior to defining the aggregate.
*
* ---------------
*/
void
AggregateCreate(char *aggName,
AggregateCreate(const char *aggName,
Oid aggNamespace,
char *aggtransfnName,
char *aggfinalfnName,
char *aggbasetypeName,
char *aggtranstypeName,
char *agginitval)
Oid aggBaseType,
Oid aggTransType,
const char *agginitval)
{
Relation aggdesc;
HeapTuple tup;
......@@ -59,8 +46,6 @@ AggregateCreate(char *aggName,
Form_pg_proc proc;
Oid transfn;
Oid finalfn = InvalidOid; /* can be omitted */
Oid basetype;
Oid transtype;
Oid finaltype;
Oid fnArgs[FUNC_MAX_ARGS];
int nargs;
......@@ -68,8 +53,6 @@ AggregateCreate(char *aggName,
TupleDesc tupDesc;
int i;
MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid));
/* sanity checks */
if (!aggName)
elog(ERROR, "no aggregate name supplied");
......@@ -77,44 +60,21 @@ AggregateCreate(char *aggName,
if (!aggtransfnName)
elog(ERROR, "aggregate must have a transition function");
/*
* Handle the aggregate's base type (input data type). This can be
* specified as 'ANY' for a data-independent transition function, such
* as COUNT(*).
*/
basetype = GetSysCacheOid(TYPENAME,
PointerGetDatum(aggbasetypeName),
0, 0, 0);
if (!OidIsValid(basetype))
{
if (strcasecmp(aggbasetypeName, "ANY") != 0)
elog(ERROR, "data type %s does not exist",
aggbasetypeName);
basetype = InvalidOid;
}
/* make sure there is no existing agg of same name and base type */
if (SearchSysCacheExists(AGGNAME,
PointerGetDatum(aggName),
ObjectIdGetDatum(basetype),
ObjectIdGetDatum(aggBaseType),
0, 0))
elog(ERROR,
"aggregate function \"%s\" with base type %s already exists",
aggName, aggbasetypeName);
/* handle transtype */
transtype = GetSysCacheOid(TYPENAME,
PointerGetDatum(aggtranstypeName),
0, 0, 0);
if (!OidIsValid(transtype))
elog(ERROR, "data type %s does not exit",
aggtranstypeName);
aggName, typeidTypeName(aggBaseType));
/* handle transfn */
fnArgs[0] = transtype;
if (OidIsValid(basetype))
MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid));
fnArgs[0] = aggTransType;
if (OidIsValid(aggBaseType))
{
fnArgs[1] = basetype;
fnArgs[1] = aggBaseType;
nargs = 2;
}
else
......@@ -129,9 +89,9 @@ AggregateCreate(char *aggName,
transfn = tup->t_data->t_oid;
Assert(OidIsValid(transfn));
proc = (Form_pg_proc) GETSTRUCT(tup);
if (proc->prorettype != transtype)
if (proc->prorettype != aggTransType)
elog(ERROR, "return type of transition function %s is not %s",
aggtransfnName, aggtranstypeName);
aggtransfnName, typeidTypeName(aggTransType));
/*
* If the transfn is strict and the initval is NULL, make sure input
......@@ -141,7 +101,7 @@ AggregateCreate(char *aggName,
*/
if (proc->proisstrict && agginitval == NULL)
{
if (!IsBinaryCompatible(basetype, transtype))
if (!IsBinaryCompatible(aggBaseType, aggTransType))
elog(ERROR, "must not omit initval when transfn is strict and transtype is not compatible with input type");
}
ReleaseSysCache(tup);
......@@ -149,7 +109,7 @@ AggregateCreate(char *aggName,
/* handle finalfn, if supplied */
if (aggfinalfnName)
{
fnArgs[0] = transtype;
fnArgs[0] = aggTransType;
fnArgs[1] = 0;
tup = SearchSysCache(PROCNAME,
PointerGetDatum(aggfinalfnName),
......@@ -169,7 +129,7 @@ AggregateCreate(char *aggName,
/*
* If no finalfn, aggregate result type is type of the state value
*/
finaltype = transtype;
finaltype = aggTransType;
}
Assert(OidIsValid(finaltype));
......@@ -184,8 +144,8 @@ AggregateCreate(char *aggName,
values[Anum_pg_aggregate_aggowner - 1] = Int32GetDatum(GetUserId());
values[Anum_pg_aggregate_aggtransfn - 1] = ObjectIdGetDatum(transfn);
values[Anum_pg_aggregate_aggfinalfn - 1] = ObjectIdGetDatum(finalfn);
values[Anum_pg_aggregate_aggbasetype - 1] = ObjectIdGetDatum(basetype);
values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(transtype);
values[Anum_pg_aggregate_aggbasetype - 1] = ObjectIdGetDatum(aggBaseType);
values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(aggTransType);
values[Anum_pg_aggregate_aggfinaltype - 1] = ObjectIdGetDatum(finaltype);
if (agginitval)
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.66 2002/03/20 19:43:36 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.67 2002/03/29 19:06:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -41,9 +41,10 @@ static void checkretval(Oid rettype, List *queryTreeList);
*/
Oid
ProcedureCreate(char *procedureName,
Oid procNamespace,
bool replace,
bool returnsSet,
char *returnTypeName,
Oid returnType,
Oid languageObjectId,
char *prosrc,
char *probin,
......@@ -60,17 +61,14 @@ ProcedureCreate(char *procedureName,
Relation rel;
HeapTuple tup;
HeapTuple oldtup;
bool defined;
uint16 parameterCount;
char nulls[Natts_pg_proc];
Datum values[Natts_pg_proc];
char replaces[Natts_pg_proc];
Oid typeObjectId;
List *x;
List *querytree_list;
Oid typev[FUNC_MAX_ARGS];
Oid relid;
Oid toid;
NameData procname;
TupleDesc tupDesc;
Oid retval;
......@@ -86,28 +84,31 @@ ProcedureCreate(char *procedureName,
foreach(x, argList)
{
TypeName *t = (TypeName *) lfirst(x);
char *typnam = TypeNameToInternalName(t);
Oid toid;
if (parameterCount >= FUNC_MAX_ARGS)
elog(ERROR, "functions cannot have more than %d arguments",
FUNC_MAX_ARGS);
if (strcmp(typnam, "opaque") == 0)
toid = LookupTypeName(t);
if (OidIsValid(toid))
{
if (languageObjectId == SQLlanguageId)
elog(ERROR, "SQL functions cannot have arguments of type \"opaque\"");
toid = InvalidOid;
if (!get_typisdefined(toid))
elog(WARNING, "Argument type \"%s\" is only a shell",
TypeNameToString(t));
}
else
{
toid = TypeGet(typnam, &defined);
if (!OidIsValid(toid))
elog(ERROR, "argument type %s does not exist",
typnam);
if (!defined)
elog(WARNING, "argument type %s is only a shell",
typnam);
char *typnam = TypeNameToString(t);
if (strcmp(typnam, "opaque") == 0)
{
if (languageObjectId == SQLlanguageId)
elog(ERROR, "SQL functions cannot have arguments of type \"opaque\"");
toid = InvalidOid;
}
else
elog(ERROR, "Type \"%s\" does not exist", typnam);
}
if (t->setof)
......@@ -154,41 +155,21 @@ ProcedureCreate(char *procedureName,
}
}
if (strcmp(returnTypeName, "opaque") == 0)
if (!OidIsValid(returnType))
{
if (languageObjectId == SQLlanguageId)
elog(ERROR, "SQL functions cannot return type \"opaque\"");
typeObjectId = InvalidOid;
}
else
{
typeObjectId = TypeGet(returnTypeName, &defined);
if (!OidIsValid(typeObjectId))
{
elog(WARNING, "ProcedureCreate: type %s is not yet defined",
returnTypeName);
typeObjectId = TypeShellMake(returnTypeName);
if (!OidIsValid(typeObjectId))
elog(ERROR, "could not create type %s",
returnTypeName);
}
else if (!defined)
elog(WARNING, "return type %s is only a shell",
returnTypeName);
}
/*
* don't allow functions of complex types that have the same name as
* existing attributes of the type
*/
if (parameterCount == 1 &&
(toid = TypeGet(strVal(lfirst(argList)), &defined)) &&
defined &&
(relid = typeidTypeRelid(toid)) != 0 &&
if (parameterCount == 1 && OidIsValid(typev[0]) &&
(relid = typeidTypeRelid(typev[0])) != 0 &&
get_attnum(relid, procedureName) != InvalidAttrNumber)
elog(ERROR, "method %s already an attribute of type %s",
procedureName, strVal(lfirst(argList)));
procedureName, typeidTypeName(typev[0]));
/*
* If this is a postquel procedure, we parse it here in order to be
......@@ -201,7 +182,7 @@ ProcedureCreate(char *procedureName,
{
querytree_list = pg_parse_and_rewrite(prosrc, typev, parameterCount);
/* typecheck return value */
checkretval(typeObjectId, querytree_list);
checkretval(returnType, querytree_list);
}
/*
......@@ -271,7 +252,7 @@ ProcedureCreate(char *procedureName,
values[i++] = BoolGetDatum(isStrict);
values[i++] = UInt16GetDatum(parameterCount);
values[i++] = BoolGetDatum(returnsSet);
values[i++] = ObjectIdGetDatum(typeObjectId);
values[i++] = ObjectIdGetDatum(returnType);
values[i++] = PointerGetDatum(typev);
values[i++] = Int32GetDatum(byte_pct); /* probyte_pct */
values[i++] = Int32GetDatum(perbyte_cpu); /* properbyte_cpu */
......@@ -308,7 +289,7 @@ ProcedureCreate(char *procedureName,
* Not okay to change the return type of the existing proc, since
* existing rules, views, etc may depend on the return type.
*/
if (typeObjectId != oldproc->prorettype ||
if (returnType != oldproc->prorettype ||
returnsSet != oldproc->proretset)
elog(ERROR, "ProcedureCreate: cannot change return type of existing function."
"\n\tUse DROP FUNCTION first.");
......
This diff is collapsed.
......@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.73 2002/03/26 19:15:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.74 2002/03/29 19:06:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -129,7 +129,7 @@ cluster(RangeVar *oldrelation, char *oldindexname)
CommandCounterIncrement();
/* Destroy old heap (along with its index) and rename new. */
heap_drop_with_catalog(saveoldrelation->relname, allowSystemTableMods);
heap_drop_with_catalog(OIDOldHeap, allowSystemTableMods);
CommandCounterIncrement();
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
* Copyright (c) 1999-2001, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.37 2002/03/26 19:15:38 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.38 2002/03/29 19:06:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -27,9 +27,10 @@
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_agg.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "parser/parse.h"
#include "rewrite/rewriteRemove.h"
#include "utils/acl.h"
......@@ -51,14 +52,16 @@
static void CommentRelation(int objtype, char * schemaname, char *relation,
char *comment);
static void CommentAttribute(char *relation, char *attrib, char *comment);
static void CommentAttribute(char * schemaname, char *relation,
char *attrib, char *comment);
static void CommentDatabase(char *database, char *comment);
static void CommentRewrite(char *rule, char *comment);
static void CommentType(char *type, char *comment);
static void CommentAggregate(char *aggregate, List *arguments, char *comment);
static void CommentProc(char *function, List *arguments, char *comment);
static void CommentOperator(char *opname, List *arguments, char *comment);
static void CommentTrigger(char *trigger, char *relation, char *comments);
static void CommentTrigger(char *trigger, char *schemaname, char *relation,
char *comments);
/*------------------------------------------------------------------
......@@ -88,7 +91,7 @@ CommentObject(int objtype, char *schemaname, char *objname, char *objproperty,
CommentRelation(objtype, schemaname, objname, comment);
break;
case COLUMN:
CommentAttribute(objname, objproperty, comment);
CommentAttribute(schemaname, objname, objproperty, comment);
break;
case DATABASE:
CommentDatabase(objname, comment);
......@@ -109,7 +112,7 @@ CommentObject(int objtype, char *schemaname, char *objname, char *objproperty,
CommentOperator(objname, objlist, comment);
break;
case TRIGGER:
CommentTrigger(objname, objproperty, comment);
CommentTrigger(objname, schemaname, objproperty, comment);
break;
default:
elog(ERROR, "An attempt was made to comment on a unknown type: %d",
......@@ -391,14 +394,18 @@ CommentRelation(int reltype, char *schemaname, char *relname, char *comment)
*/
static void
CommentAttribute(char *relname, char *attrname, char *comment)
CommentAttribute(char *schemaname, char *relname, char *attrname, char *comment)
{
RangeVar *rel = makeNode(RangeVar);
Relation relation;
AttrNumber attnum;
/* Open the containing relation to ensure it won't go away meanwhile */
relation = heap_openr(relname, AccessShareLock);
rel->relname = relname;
rel->schemaname = schemaname;
rel->istemp = false;
relation = heap_openrv(rel, AccessShareLock);
/* Check object security */
......@@ -539,11 +546,8 @@ CommentType(char *type, char *comment)
/* Find the type's oid */
oid = GetSysCacheOid(TYPENAME,
PointerGetDatum(type),
0, 0, 0);
if (!OidIsValid(oid))
elog(ERROR, "type '%s' does not exist", type);
/* XXX WRONG: need to deal with qualified type names */
oid = typenameTypeId(makeTypeName(type));
/* Check object security */
......@@ -570,21 +574,13 @@ static void
CommentAggregate(char *aggregate, List *arguments, char *comment)
{
TypeName *aggtype = (TypeName *) lfirst(arguments);
char *aggtypename;
Oid baseoid,
oid;
Oid classoid;
bool defined;
/* First, attempt to determine the base aggregate oid */
if (aggtype)
{
aggtypename = TypeNameToInternalName(aggtype);
baseoid = TypeGet(aggtypename, &defined);
if (!OidIsValid(baseoid))
elog(ERROR, "type '%s' does not exist", aggtypename);
}
baseoid = typenameTypeId(aggtype);
else
baseoid = InvalidOid;
......@@ -648,20 +644,19 @@ CommentProc(char *function, List *arguments, char *comment)
for (i = 0; i < argcount; i++)
{
TypeName *t = (TypeName *) lfirst(arguments);
char *typnam = TypeNameToInternalName(t);
arguments = lnext(arguments);
if (strcmp(typnam, "opaque") == 0)
argoids[i] = InvalidOid;
else
argoids[i] = LookupTypeName(t);
if (!OidIsValid(argoids[i]))
{
argoids[i] = GetSysCacheOid(TYPENAME,
PointerGetDatum(typnam),
0, 0, 0);
if (!OidIsValid(argoids[i]))
elog(ERROR, "CommentProc: type '%s' not found", typnam);
char *typnam = TypeNameToString(t);
if (strcmp(typnam, "opaque") == 0)
argoids[i] = InvalidOid;
else
elog(ERROR, "Type \"%s\" does not exist", typnam);
}
arguments = lnext(arguments);
}
/* Now, find the corresponding oid for this procedure */
......@@ -707,40 +702,20 @@ CommentOperator(char *opername, List *arguments, char *comment)
{
TypeName *typenode1 = (TypeName *) lfirst(arguments);
TypeName *typenode2 = (TypeName *) lsecond(arguments);
char oprtype = 0,
*lefttype = NULL,
*righttype = NULL;
char oprtype = 0;
Form_pg_operator data;
HeapTuple optuple;
Oid oid,
leftoid = InvalidOid,
rightoid = InvalidOid;
bool defined;
/* Initialize our left and right argument types */
/* Attempt to fetch the left type oid, if specified */
if (typenode1 != NULL)
lefttype = TypeNameToInternalName(typenode1);
if (typenode2 != NULL)
righttype = TypeNameToInternalName(typenode2);
/* Attempt to fetch the left oid, if specified */
if (lefttype != NULL)
{
leftoid = TypeGet(lefttype, &defined);
if (!OidIsValid(leftoid))
elog(ERROR, "left type '%s' does not exist", lefttype);
}
/* Attempt to fetch the right oid, if specified */
leftoid = typenameTypeId(typenode1);
if (righttype != NULL)
{
rightoid = TypeGet(righttype, &defined);
if (!OidIsValid(rightoid))
elog(ERROR, "right type '%s' does not exist", righttype);
}
/* Attempt to fetch the right type oid, if specified */
if (typenode2 != NULL)
rightoid = typenameTypeId(typenode2);
/* Determine operator type */
......@@ -797,8 +772,9 @@ CommentOperator(char *opername, List *arguments, char *comment)
*/
static void
CommentTrigger(char *trigger, char *relname, char *comment)
CommentTrigger(char *trigger, char *schemaname, char *relname, char *comment)
{
RangeVar *rel = makeNode(RangeVar);
Relation pg_trigger,
relation;
HeapTuple triggertuple;
......@@ -808,7 +784,10 @@ CommentTrigger(char *trigger, char *relname, char *comment)
/* First, validate the user's action */
relation = heap_openr(relname, AccessShareLock);
rel->relname = relname;
rel->schemaname = schemaname;
rel->istemp = false;
relation = heap_openrv(rel, AccessShareLock);
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'",
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.151 2002/03/21 23:27:20 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.152 2002/03/29 19:06:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -21,6 +21,7 @@
#include "access/printtup.h"
#include "catalog/catname.h"
#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_index.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_type.h"
......@@ -228,7 +229,7 @@ CopyDonePeek(FILE *fp, int c, bool pickup)
/*
* DoCopy executes the SQL COPY statement.
*
* Either unload or reload contents of table <relname>, depending on <from>.
* Either unload or reload contents of table <relation>, depending on <from>.
* (<from> = TRUE means we are inserting into the table.)
*
* If <pipe> is false, transfer is between the table and the file named
......@@ -260,7 +261,7 @@ CopyDonePeek(FILE *fp, int c, bool pickup)
* the table.
*/
void
DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe,
char *filename, char *delim, char *null_print)
{
FILE *fp;
......@@ -271,7 +272,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
/*
* Open and lock the relation, using the appropriate lock type.
*/
rel = heap_openr(relname, (from ? RowExclusiveLock : AccessShareLock));
rel = heap_openrv(relation, (from ? RowExclusiveLock : AccessShareLock));
/* Check permissions. */
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
......@@ -312,11 +313,14 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
if (rel->rd_rel->relkind != RELKIND_RELATION)
{
if (rel->rd_rel->relkind == RELKIND_VIEW)
elog(ERROR, "You cannot copy view %s", relname);
elog(ERROR, "You cannot copy view %s",
RelationGetRelationName(rel));
else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
elog(ERROR, "You cannot change sequence relation %s", relname);
elog(ERROR, "You cannot change sequence relation %s",
RelationGetRelationName(rel));
else
elog(ERROR, "You cannot copy object %s", relname);
elog(ERROR, "You cannot copy object %s",
RelationGetRelationName(rel));
}
if (pipe)
{
......@@ -354,11 +358,14 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
if (rel->rd_rel->relkind != RELKIND_RELATION)
{
if (rel->rd_rel->relkind == RELKIND_VIEW)
elog(ERROR, "You cannot copy view %s", relname);
elog(ERROR, "You cannot copy view %s",
RelationGetRelationName(rel));
else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
elog(ERROR, "You cannot copy sequence %s", relname);
elog(ERROR, "You cannot copy sequence %s",
RelationGetRelationName(rel));
else
elog(ERROR, "You cannot copy object %s", relname);
elog(ERROR, "You cannot copy object %s",
RelationGetRelationName(rel));
}
if (pipe)
{
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.92 2002/03/26 19:15:40 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.93 2002/03/29 19:06:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -27,6 +27,7 @@
#include "commands/creatinh.h"
#include "miscadmin.h"
#include "optimizer/clauses.h"
#include "parser/parse_type.h"
#include "utils/acl.h"
#include "utils/syscache.h"
#include "utils/temprel.h"
......@@ -108,7 +109,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
* (BuildDescForRelation takes care of the inherited defaults, but we
* have to copy inherited constraints here.)
*/
descriptor = BuildDescForRelation(schema, relname);
descriptor = BuildDescForRelation(schema);
if (old_constraints != NIL)
{
......@@ -238,10 +239,12 @@ DefineRelation(CreateStmt *stmt, char relkind)
* themselves will be destroyed, too.
*/
void
RemoveRelation(const char *name)
RemoveRelation(const RangeVar *relation)
{
AssertArg(name);
heap_drop_with_catalog(name, allowSystemTableMods);
Oid relOid;
relOid = RangeVarGetRelid(relation, false);
heap_drop_with_catalog(relOid, allowSystemTableMods);
}
/*
......@@ -255,34 +258,36 @@ RemoveRelation(const char *name)
* Rows are removed, indices are truncated and reconstructed.
*/
void
TruncateRelation(const char *relname)
TruncateRelation(const RangeVar *relation)
{
Oid relid;
Relation rel;
AssertArg(relname);
relid = RangeVarGetRelid(relation, false);
/* Grab exclusive lock in preparation for truncate */
rel = heap_openr(relname, AccessExclusiveLock);
rel = heap_open(relid, AccessExclusiveLock);
if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
elog(ERROR, "TRUNCATE cannot be used on sequences. '%s' is a sequence",
relname);
RelationGetRelationName(rel));
if (rel->rd_rel->relkind == RELKIND_VIEW)
elog(ERROR, "TRUNCATE cannot be used on views. '%s' is a view",
relname);
RelationGetRelationName(rel));
if (!allowSystemTableMods && IsSystemRelationName(relname))
if (!allowSystemTableMods && IsSystemRelationName(RelationGetRelationName(rel)))
elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
relname);
RelationGetRelationName(rel));
if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
elog(ERROR, "you do not own relation \"%s\"", relname);
elog(ERROR, "you do not own relation \"%s\"",
RelationGetRelationName(rel));
/* Keep the lock until transaction commit */
heap_close(rel, NoLock);
heap_truncate(relname);
heap_truncate(relid);
}
......@@ -308,12 +313,7 @@ MergeDomainAttributes(List *schema)
HeapTuple tuple;
Form_pg_type typeTup;
tuple = SearchSysCache(TYPENAME,
CStringGetDatum(coldef->typename->name),
0,0,0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "MergeDomainAttributes: Type %s does not exist",
coldef->typename->name);
tuple = typenameType(coldef->typename);
typeTup = (Form_pg_type) GETSTRUCT(tuple);
if (typeTup->typtype == 'd')
......@@ -486,26 +486,11 @@ MergeAttributes(List *schema, List *supers, bool istemp,
parent_attno++)
{
Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
char *attributeName;
char *attributeType;
HeapTuple tuple;
char *attributeName = NameStr(attribute->attname);
int exist_attno;
ColumnDef *def;
TypeName *typename;
/*
* Get name and type name of attribute
*/
attributeName = NameStr(attribute->attname);
tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(attribute->atttypid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "CREATE TABLE: cache lookup failed for type %u",
attribute->atttypid);
attributeType = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname));
ReleaseSysCache(tuple);
/*
* Does it conflict with some previously inherited column?
*/
......@@ -519,10 +504,12 @@ MergeAttributes(List *schema, List *supers, bool istemp,
elog(NOTICE, "CREATE TABLE: merging multiple inherited definitions of attribute \"%s\"",
attributeName);
def = (ColumnDef *) nth(exist_attno - 1, inhSchema);
if (strcmp(def->typename->name, attributeType) != 0 ||
if (typenameTypeId(def->typename) != attribute->atttypid ||
def->typename->typmod != attribute->atttypmod)
elog(ERROR, "CREATE TABLE: inherited attribute \"%s\" type conflict (%s and %s)",
attributeName, def->typename->name, attributeType);
attributeName,
TypeNameToString(def->typename),
typeidTypeName(attribute->atttypid));
/* Merge of NOT NULL constraints = OR 'em together */
def->is_not_null |= attribute->attnotnull;
/* Default and other constraints are handled below */
......@@ -536,7 +523,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
def = makeNode(ColumnDef);
def->colname = pstrdup(attributeName);
typename = makeNode(TypeName);
typename->name = attributeType;
typename->typeid = attribute->atttypid;
typename->typmod = attribute->atttypmod;
def->typename = typename;
def->is_not_null = attribute->attnotnull;
......@@ -640,7 +627,6 @@ MergeAttributes(List *schema, List *supers, bool istemp,
{
ColumnDef *newdef = lfirst(entry);
char *attributeName = newdef->colname;
char *attributeType = newdef->typename->name;
int exist_attno;
/*
......@@ -658,10 +644,12 @@ MergeAttributes(List *schema, List *supers, bool istemp,
elog(NOTICE, "CREATE TABLE: merging attribute \"%s\" with inherited definition",
attributeName);
def = (ColumnDef *) nth(exist_attno - 1, inhSchema);
if (strcmp(def->typename->name, attributeType) != 0 ||
if (typenameTypeId(def->typename) != typenameTypeId(newdef->typename) ||
def->typename->typmod != newdef->typename->typmod)
elog(ERROR, "CREATE TABLE: attribute \"%s\" type conflict (%s and %s)",
attributeName, def->typename->name, attributeType);
attributeName,
TypeNameToString(def->typename),
TypeNameToString(newdef->typename));
/* Merge of NOT NULL constraints = OR 'em together */
def->is_not_null |= newdef->is_not_null;
/* If new def has a default, override previous default */
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.71 2002/03/21 23:27:21 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.72 2002/03/29 19:06:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -24,8 +24,8 @@
#include "miscadmin.h"
#include "parser/parse.h"
#include "parser/parse_agg.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
......@@ -43,29 +43,20 @@
*/
void
RemoveOperator(char *operatorName, /* operator name */
char *typeName1, /* left argument type name */
char *typeName2) /* right argument type name */
TypeName *typeName1, /* left argument type name */
TypeName *typeName2) /* right argument type name */
{
Relation relation;
HeapTuple tup;
Oid typeId1 = InvalidOid;
Oid typeId2 = InvalidOid;
bool defined;
char oprtype;
if (typeName1)
{
typeId1 = TypeGet(typeName1, &defined);
if (!OidIsValid(typeId1))
elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName1);
}
typeId1 = typenameTypeId(typeName1);
if (typeName2)
{
typeId2 = TypeGet(typeName2, &defined);
if (!OidIsValid(typeId2))
elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName2);
}
typeId2 = typenameTypeId(typeName2);
if (OidIsValid(typeId1) && OidIsValid(typeId2))
oprtype = 'b';
......@@ -99,20 +90,20 @@ RemoveOperator(char *operatorName, /* operator name */
{
elog(ERROR, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
operatorName,
typeName1,
typeName2);
TypeNameToString(typeName1),
TypeNameToString(typeName2));
}
else if (OidIsValid(typeId1))
{
elog(ERROR, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
operatorName,
typeName1);
TypeNameToString(typeName1));
}
else
{
elog(ERROR, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
operatorName,
typeName2);
TypeNameToString(typeName2));
}
}
heap_freetuple(tup);
......@@ -213,16 +204,13 @@ AttributeAndRelationRemove(Oid typeOid)
rel = heap_openr(RelationRelationName, RowExclusiveLock);
while (PointerIsValid((char *) optr->next))
{
key[0].sk_argument = (Datum) (optr++)->reloid;
Oid relOid = (optr++)->reloid;
key[0].sk_argument = ObjectIdGetDatum(relOid);
scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
tup = heap_getnext(scan, 0);
if (HeapTupleIsValid(tup))
{
char *name;
name = NameStr(((Form_pg_class) GETSTRUCT(tup))->relname);
heap_drop_with_catalog(name, allowSystemTableMods);
}
heap_drop_with_catalog(relOid, allowSystemTableMods);
heap_endscan(scan);
}
heap_close(rel, RowExclusiveLock);
......@@ -231,42 +219,68 @@ AttributeAndRelationRemove(Oid typeOid)
/*
* TypeRemove
* Removes the type 'typeName' and all attributes and relations that
* use it.
* Removes a datatype.
*
* NOTE: since this tries to remove the associated array type too, it'll
* only work on scalar types.
*/
void
RemoveType(char *typeName) /* type name to be removed */
RemoveType(List *names)
{
TypeName *typename;
Relation relation;
Oid typeoid;
HeapTuple tup;
char *shadow_type;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeNode(TypeName);
typename->names = names;
typename->typmod = -1;
typename->arrayBounds = NIL;
relation = heap_openr(TypeRelationName, RowExclusiveLock);
tup = SearchSysCache(TYPENAME,
PointerGetDatum(typeName),
/* Use LookupTypeName here so that shell types can be removed. */
typeoid = LookupTypeName(typename);
if (!OidIsValid(typeoid))
elog(ERROR, "Type \"%s\" does not exist",
TypeNameToString(typename));
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typeoid),
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
elog(ERROR, "Type \"%s\" does not exist",
TypeNameToString(typename));
if (!pg_type_ownercheck(tup->t_data->t_oid, GetUserId()))
if (!pg_type_ownercheck(typeoid, GetUserId()))
elog(ERROR, "RemoveType: type '%s': permission denied",
typeName);
TypeNameToString(typename));
/* Delete any comments associated with this type */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
DeleteComments(typeoid, RelationGetRelid(relation));
/* Remove the type tuple from pg_type */
simple_heap_delete(relation, &tup->t_self);
ReleaseSysCache(tup);
/* Also, delete the "array of" that type */
shadow_type = makeArrayTypeName(typeName);
tup = SearchSysCache(TYPENAME,
PointerGetDatum(shadow_type),
/* Now, delete the "array of" that type */
typename->arrayBounds = makeList1(makeInteger(1));
typeoid = LookupTypeName(typename);
if (!OidIsValid(typeoid))
elog(ERROR, "Type \"%s\" does not exist",
TypeNameToString(typename));
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typeoid),
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "RemoveType: type '%s' does not exist", shadow_type);
elog(ERROR, "Type \"%s\" does not exist",
TypeNameToString(typename));
DeleteComments(typeoid, RelationGetRelid(relation));
simple_heap_delete(relation, &tup->t_self);
......@@ -277,13 +291,14 @@ RemoveType(char *typeName) /* type name to be removed */
/*
* RemoveDomain
* Removes the domain 'typeName' and all attributes and relations that
* use it.
* Removes a domain.
*/
void
RemoveDomain(char *domainName, int behavior)
RemoveDomain(List *names, int behavior)
{
TypeName *typename;
Relation relation;
Oid typeoid;
HeapTuple tup;
char typtype;
......@@ -291,31 +306,44 @@ RemoveDomain(char *domainName, int behavior)
if (behavior == CASCADE)
elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword");
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeNode(TypeName);
typename->names = names;
typename->typmod = -1;
typename->arrayBounds = NIL;
relation = heap_openr(TypeRelationName, RowExclusiveLock);
tup = SearchSysCache(TYPENAME,
PointerGetDatum(domainName),
typeoid = typenameTypeId(typename);
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typeoid),
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "RemoveType: type '%s' does not exist", domainName);
elog(ERROR, "RemoveDomain: type '%s' does not exist",
TypeNameToString(typename));
if (!pg_type_ownercheck(tup->t_data->t_oid, GetUserId()))
if (!pg_type_ownercheck(typeoid, GetUserId()))
elog(ERROR, "RemoveDomain: type '%s': permission denied",
domainName);
TypeNameToString(typename));
/* Check that this is actually a domain */
typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype;
if (typtype != 'd')
elog(ERROR, "%s is not a domain", domainName);
elog(ERROR, "%s is not a domain",
TypeNameToString(typename));
/* Delete any comments associated with this type */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
DeleteComments(typeoid, RelationGetRelid(relation));
/* Remove the type tuple from pg_type */
simple_heap_delete(relation, &tup->t_self);
ReleaseSysCache(tup);
/* At present, domains don't have associated array types */
heap_close(relation, RowExclusiveLock);
}
......@@ -345,20 +373,19 @@ RemoveFunction(char *functionName, /* function name to be removed */
for (i = 0; i < nargs; i++)
{
TypeName *t = (TypeName *) lfirst(argTypes);
char *typnam = TypeNameToInternalName(t);
argTypes = lnext(argTypes);
if (strcmp(typnam, "opaque") == 0)
argList[i] = InvalidOid;
else
argList[i] = LookupTypeName(t);
if (!OidIsValid(argList[i]))
{
argList[i] = GetSysCacheOid(TYPENAME,
PointerGetDatum(typnam),
0, 0, 0);
if (!OidIsValid(argList[i]))
elog(ERROR, "RemoveFunction: type '%s' not found", typnam);
char *typnam = TypeNameToString(t);
if (strcmp(typnam, "opaque") == 0)
argList[i] = InvalidOid;
else
elog(ERROR, "Type \"%s\" does not exist", typnam);
}
argTypes = lnext(argTypes);
}
relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
......@@ -393,12 +420,11 @@ RemoveFunction(char *functionName, /* function name to be removed */
}
void
RemoveAggregate(char *aggName, char *aggType)
RemoveAggregate(char *aggName, TypeName *aggType)
{
Relation relation;
HeapTuple tup;
Oid basetypeID;
bool defined;
/*
* if a basetype is passed in, then attempt to find an aggregate for
......@@ -410,11 +436,7 @@ RemoveAggregate(char *aggName, char *aggType)
*/
if (aggType)
{
basetypeID = TypeGet(aggType, &defined);
if (!OidIsValid(basetypeID))
elog(ERROR, "RemoveAggregate: type '%s' does not exist", aggType);
}
basetypeID = typenameTypeId(aggType);
else
basetypeID = InvalidOid;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.65 2002/03/26 19:15:43 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.66 2002/03/29 19:06:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -69,16 +69,14 @@ static void update_ri_trigger_args(Oid relid,
* delete original attribute from attribute catalog
*/
void
renameatt(char *relname,
renameatt(Oid relid,
char *oldattname,
char *newattname,
int recurse)
bool recurse)
{
Relation targetrelation;
Relation attrelation;
HeapTuple reltup,
atttup;
Oid relid;
HeapTuple atttup;
List *indexoidlist;
List *indexoidscan;
......@@ -86,8 +84,7 @@ renameatt(char *relname,
* Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction.
*/
targetrelation = heap_openr(relname, AccessExclusiveLock);
relid = RelationGetRelid(targetrelation);
targetrelation = heap_open(relid, AccessExclusiveLock);
/*
* permissions checking. this would normally be done in utility.c,
......@@ -95,12 +92,13 @@ renameatt(char *relname,
*
* normally, only the owner of a class can change its schema.
*/
if (!allowSystemTableMods && IsSystemRelationName(relname))
if (!allowSystemTableMods
&& IsSystemRelationName(RelationGetRelationName(targetrelation)))
elog(ERROR, "renameatt: class \"%s\" is a system catalog",
relname);
RelationGetRelationName(targetrelation));
if (!pg_class_ownercheck(relid, GetUserId()))
elog(ERROR, "renameatt: you do not own class \"%s\"",
relname);
RelationGetRelationName(targetrelation));
/*
* if the 'recurse' flag is set then we are supposed to rename this
......@@ -127,25 +125,11 @@ renameatt(char *relname,
foreach(child, children)
{
Oid childrelid = lfirsti(child);
char childname[NAMEDATALEN];
if (childrelid == relid)
continue;
reltup = SearchSysCache(RELOID,
ObjectIdGetDatum(childrelid),
0, 0, 0);
if (!HeapTupleIsValid(reltup))
{
elog(ERROR, "renameatt: can't find catalog entry for inheriting class with oid %u",
childrelid);
}
/* make copy of cache value, could disappear in call */
StrNCpy(childname,
NameStr(((Form_pg_class) GETSTRUCT(reltup))->relname),
NAMEDATALEN);
ReleaseSysCache(reltup);
/* note we need not recurse again! */
renameatt(childname, oldattname, newattname, 0);
renameatt(childrelid, oldattname, newattname, false);
}
}
......@@ -356,7 +340,7 @@ renamerel(const RangeVar *relation, const char *newrelname)
* Also rename the associated type, if any.
*/
if (relkind != RELKIND_INDEX)
TypeRename(relation->relname, newrelname);
TypeRename(relation->relname, namespaceId, newrelname);
/*
* If it's a view, must also rename the associated ON SELECT rule.
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.74 2002/03/22 02:56:31 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.75 2002/03/29 19:06:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -17,6 +17,7 @@
#include <ctype.h>
#include "access/heapam.h"
#include "catalog/pg_type.h"
#include "commands/creatinh.h"
#include "commands/sequence.h"
#include "miscadmin.h"
......@@ -85,8 +86,6 @@ DefineSequence(CreateSeqStmt *seq)
{
FormData_pg_sequence new;
CreateStmt *stmt = makeNode(CreateStmt);
ColumnDef *coldef;
TypeName *typnam;
Oid seqoid;
Relation rel;
Buffer buf;
......@@ -108,9 +107,12 @@ DefineSequence(CreateSeqStmt *seq)
stmt->tableElts = NIL;
for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
{
ColumnDef *coldef;
TypeName *typnam;
typnam = makeNode(TypeName);
typnam->setof = FALSE;
typnam->arrayBounds = NULL;
typnam->arrayBounds = NIL;
typnam->typmod = -1;
coldef = makeNode(ColumnDef);
coldef->typename = typnam;
......@@ -122,48 +124,48 @@ DefineSequence(CreateSeqStmt *seq)
switch (i)
{
case SEQ_COL_NAME:
typnam->name = "name";
typnam->typeid = NAMEOID;
coldef->colname = "sequence_name";
namestrcpy(&name, seq->sequence->relname);
value[i - 1] = NameGetDatum(&name);
break;
case SEQ_COL_LASTVAL:
typnam->name = "int8";
typnam->typeid = INT8OID;
coldef->colname = "last_value";
value[i - 1] = Int64GetDatumFast(new.last_value);
break;
case SEQ_COL_INCBY:
typnam->name = "int8";
typnam->typeid = INT8OID;
coldef->colname = "increment_by";
value[i - 1] = Int64GetDatumFast(new.increment_by);
break;
case SEQ_COL_MAXVALUE:
typnam->name = "int8";
typnam->typeid = INT8OID;
coldef->colname = "max_value";
value[i - 1] = Int64GetDatumFast(new.max_value);
break;
case SEQ_COL_MINVALUE:
typnam->name = "int8";
typnam->typeid = INT8OID;
coldef->colname = "min_value";
value[i - 1] = Int64GetDatumFast(new.min_value);
break;
case SEQ_COL_CACHE:
typnam->name = "int8";
typnam->typeid = INT8OID;
coldef->colname = "cache_value";
value[i - 1] = Int64GetDatumFast(new.cache_value);
break;
case SEQ_COL_LOG:
typnam->name = "int8";
typnam->typeid = INT8OID;
coldef->colname = "log_cnt";
value[i - 1] = Int64GetDatum((int64) 1);
break;
case SEQ_COL_CYCLE:
typnam->name = "bool";
typnam->typeid = BOOLOID;
coldef->colname = "is_cycled";
value[i - 1] = BoolGetDatum(new.is_cycled);
break;
case SEQ_COL_CALLED:
typnam->name = "bool";
typnam->typeid = BOOLOID;
coldef->colname = "is_called";
value[i - 1] = BoolGetDatum(false);
break;
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.60 2002/03/06 06:09:39 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.61 2002/03/29 19:06:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -21,11 +21,12 @@
#include "access/xact.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_type.h"
#include "commands/variable.h"
#include "miscadmin.h"
#include "optimizer/cost.h"
#include "optimizer/paths.h"
#include "parser/parse_expr.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/guc.h"
......@@ -390,7 +391,9 @@ parse_timezone(List *args)
type = p->typename;
if (type != NULL)
{
if (strcmp(type->name, "interval") == 0)
Oid typeOid = typenameTypeId(type);
if (typeOid == INTERVALOID)
{
Interval *interval;
......@@ -402,7 +405,7 @@ parse_timezone(List *args)
elog(ERROR, "SET TIME ZONE illegal INTERVAL; month not allowed");
CTimeZone = interval->time;
}
else if (strcmp(type->name, "float8") == 0)
else if (typeOid == FLOAT8OID)
{
float8 time;
......@@ -414,7 +417,7 @@ parse_timezone(List *args)
* We do not actually generate an integer constant in gram.y
* so this is not used...
*/
else if (strcmp(type->name, "int4") == 0)
else if (typeOid == INT4OID)
{
int32 time;
......
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: view.c,v 1.60 2002/03/22 02:56:31 tgl Exp $
* $Id: view.c,v 1.61 2002/03/29 19:06:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -14,6 +14,7 @@
#include "access/xact.h"
#include "catalog/heap.h"
#include "catalog/namespace.h"
#include "commands/creatinh.h"
#include "commands/view.h"
#include "miscadmin.h"
......@@ -24,6 +25,7 @@
#include "rewrite/rewriteManip.h"
#include "rewrite/rewriteRemove.h"
#include "rewrite/rewriteSupport.h"
#include "utils/syscache.h"
/*---------------------------------------------------------------------
......@@ -38,10 +40,9 @@
*---------------------------------------------------------------------
*/
static Oid
DefineVirtualRelation(char *relname, List *tlist)
DefineVirtualRelation(const RangeVar *relation, List *tlist)
{
CreateStmt *createStmt = makeNode(CreateStmt);
RangeVar *rel = makeNode(RangeVar);
List *attrList,
*t;
......@@ -57,14 +58,12 @@ DefineVirtualRelation(char *relname, List *tlist)
if (!res->resjunk)
{
char *resname = res->resname;
char *restypename = typeidTypeName(res->restype);
ColumnDef *def = makeNode(ColumnDef);
TypeName *typename = makeNode(TypeName);
def->colname = pstrdup(resname);
def->colname = pstrdup(res->resname);
typename->name = pstrdup(restypename);
typename->typeid = res->restype;
typename->typmod = res->restypmod;
def->typename = typename;
......@@ -84,10 +83,7 @@ DefineVirtualRelation(char *relname, List *tlist)
* now create the parameters for keys/inheritance etc. All of them are
* nil...
*/
rel->relname = relname;
rel->schemaname = NULL; /* XXX wrong */
rel->istemp = false;
createStmt->relation = rel;
createStmt->relation = (RangeVar *) relation;
createStmt->tableElts = attrList;
createStmt->inhRelations = NIL;
createStmt->constraints = NIL;
......@@ -100,25 +96,19 @@ DefineVirtualRelation(char *relname, List *tlist)
}
static RuleStmt *
FormViewRetrieveRule(char *viewName, Query *viewParse)
FormViewRetrieveRule(const RangeVar *view, Query *viewParse)
{
RuleStmt *rule;
char *rname;
RangeVar *rel;
/*
* Create a RuleStmt that corresponds to the suitable rewrite rule
* args for DefineQueryRewrite();
*/
rname = MakeRetrieveViewRuleName(viewName);
rel = makeNode(RangeVar);
rel->relname = pstrdup(viewName);
rel->inhOpt = INH_NO;
rel->alias = NULL;
rname = MakeRetrieveViewRuleName(view->relname);
rule = makeNode(RuleStmt);
rule->relation = rel;
rule->relation = copyObject((RangeVar *) view);
rule->rulename = pstrdup(rname);
rule->whereClause = NULL;
rule->event = CMD_SELECT;
......@@ -129,7 +119,7 @@ FormViewRetrieveRule(char *viewName, Query *viewParse)
}
static void
DefineViewRules(char *viewName, Query *viewParse)
DefineViewRules(const RangeVar *view, Query *viewParse)
{
RuleStmt *retrieve_rule;
......@@ -139,13 +129,13 @@ DefineViewRules(char *viewName, Query *viewParse)
RuleStmt *delete_rule;
#endif
retrieve_rule = FormViewRetrieveRule(viewName, viewParse);
retrieve_rule = FormViewRetrieveRule(view, viewParse);
#ifdef NOTYET
replace_rule = FormViewReplaceRule(viewName, viewParse);
append_rule = FormViewAppendRule(viewName, viewParse);
delete_rule = FormViewDeleteRule(viewName, viewParse);
replace_rule = FormViewReplaceRule(view, viewParse);
append_rule = FormViewAppendRule(view, viewParse);
delete_rule = FormViewDeleteRule(view, viewParse);
#endif
DefineQueryRewrite(retrieve_rule);
......@@ -231,7 +221,7 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
*-------------------------------------------------------------------
*/
void
DefineView(char *viewName, Query *viewParse)
DefineView(const RangeVar *view, Query *viewParse)
{
Oid viewOid;
......@@ -240,7 +230,7 @@ DefineView(char *viewName, Query *viewParse)
*
* NOTE: if it already exists, the xact will be aborted.
*/
viewOid = DefineVirtualRelation(viewName, viewParse->targetList);
viewOid = DefineVirtualRelation(view, viewParse->targetList);
/*
* The relation we have just created is not visible to any other
......@@ -258,7 +248,7 @@ DefineView(char *viewName, Query *viewParse)
/*
* Now create the rules associated with the view.
*/
DefineViewRules(viewName, viewParse);
DefineViewRules(view, viewParse);
}
/*------------------------------------------------------------------
......@@ -268,11 +258,14 @@ DefineView(char *viewName, Query *viewParse)
*------------------------------------------------------------------
*/
void
RemoveView(char *viewName)
RemoveView(const RangeVar *view)
{
Oid viewOid;
viewOid = RangeVarGetRelid(view, false);
/*
* We just have to drop the relation; the associated rules will be
* cleaned up automatically.
*/
heap_drop_with_catalog(viewName, allowSystemTableMods);
heap_drop_with_catalog(viewOid, allowSystemTableMods);
}
......@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.173 2002/03/22 02:56:31 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.174 2002/03/29 19:06:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1637,10 +1637,11 @@ _copyTypeName(TypeName *from)
{
TypeName *newnode = makeNode(TypeName);
if (from->name)
newnode->name = pstrdup(from->name);
Node_Copy(from, newnode, names);
newnode->typeid = from->typeid;
newnode->timezone = from->timezone;
newnode->setof = from->setof;
newnode->pct_type = from->pct_type;
newnode->typmod = from->typmod;
Node_Copy(from, newnode, arrayBounds);
......@@ -2008,7 +2009,7 @@ _copyDefineStmt(DefineStmt *from)
DefineStmt *newnode = makeNode(DefineStmt);
newnode->defType = from->defType;
newnode->defname = pstrdup(from->defname);
Node_Copy(from, newnode, defnames);
Node_Copy(from, newnode, definition);
return newnode;
......@@ -2089,7 +2090,7 @@ _copyProcedureStmt(ProcedureStmt *from)
ProcedureStmt *newnode = makeNode(ProcedureStmt);
newnode->replace = from->replace;
newnode->funcname = pstrdup(from->funcname);
Node_Copy(from, newnode, funcname);
Node_Copy(from, newnode, argTypes);
Node_Copy(from, newnode, returnType);
Node_Copy(from, newnode, withClause);
......@@ -2229,8 +2230,7 @@ _copyCreateDomainStmt(CreateDomainStmt *from)
{
CreateDomainStmt *newnode = makeNode(CreateDomainStmt);
if (from->domainname)
newnode->domainname = pstrdup(from->domainname);
Node_Copy(from, newnode, domainname);
Node_Copy(from, newnode, typename);
Node_Copy(from, newnode, constraints);
......
......@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.121 2002/03/22 02:56:31 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.122 2002/03/29 19:06:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -836,7 +836,7 @@ _equalDefineStmt(DefineStmt *a, DefineStmt *b)
{
if (a->defType != b->defType)
return false;
if (!equalstr(a->defname, b->defname))
if (!equal(a->defnames, b->defnames))
return false;
if (!equal(a->definition, b->definition))
return false;
......@@ -928,7 +928,7 @@ _equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
{
if (a->replace != b->replace)
return false;
if (!equalstr(a->funcname, b->funcname))
if (!equal(a->funcname, b->funcname))
return false;
if (!equal(a->argTypes, b->argTypes))
return false;
......@@ -1071,7 +1071,7 @@ _equalLoadStmt(LoadStmt *a, LoadStmt *b)
static bool
_equalCreateDomainStmt(CreateDomainStmt *a, CreateDomainStmt *b)
{
if (!equalstr(a->domainname, b->domainname))
if (!equal(a->domainname, b->domainname))
return false;
if (!equal(a->typename, b->typename))
return false;
......@@ -1572,12 +1572,16 @@ _equalRangeSubselect(RangeSubselect *a, RangeSubselect *b)
static bool
_equalTypeName(TypeName *a, TypeName *b)
{
if (!equalstr(a->name, b->name))
if (!equal(a->names, b->names))
return false;
if (a->typeid != b->typeid)
return false;
if (a->timezone != b->timezone)
return false;
if (a->setof != b->setof)
return false;
if (a->pct_type != b->pct_type)
return false;
if (a->typmod != b->typmod)
return false;
if (!equal(a->arrayBounds, b->arrayBounds))
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.29 2002/03/22 02:56:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.30 2002/03/29 19:06:09 tgl Exp $
*/
#include "postgres.h"
......@@ -209,3 +209,17 @@ makeRangeVar(char *schemaname, char *relname)
return r;
}
/*
* makeTypeName -
* build a TypeName node for an unqualified name.
*/
TypeName *
makeTypeName(char *typnam)
{
TypeName *n = makeNode(TypeName);
n->names = makeList1(makeString(typnam));
n->typmod = -1;
return n;
}
......@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.151 2002/03/22 02:56:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.152 2002/03/29 19:06:09 tgl Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
......@@ -187,11 +187,14 @@ _outColumnDef(StringInfo str, ColumnDef *node)
static void
_outTypeName(StringInfo str, TypeName *node)
{
appendStringInfo(str, " TYPENAME :name ");
_outToken(str, node->name);
appendStringInfo(str, " :timezone %s :setof %s typmod %d :arrayBounds ",
appendStringInfo(str, " TYPENAME :names ");
_outNode(str, node->names);
appendStringInfo(str, " :typeid %u :timezone %s :setof %s"
" :pct_type %s typmod %d :arrayBounds ",
node->typeid,
booltostr(node->timezone),
booltostr(node->setof),
booltostr(node->pct_type),
node->typmod);
_outNode(str, node->arrayBounds);
}
......
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.223 2002/03/26 19:15:56 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.224 2002/03/29 19:06:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -108,11 +108,7 @@ static void transformIndexConstraints(ParseState *pstate,
CreateStmtContext *cxt);
static void transformFKConstraints(ParseState *pstate,
CreateStmtContext *cxt);
static Node *transformTypeRefs(ParseState *pstate, Node *stmt);
static void applyColumnNames(List *dst, List *src);
static void transformTypeRefsList(ParseState *pstate, List *l);
static void transformTypeRef(ParseState *pstate, TypeName *tn);
static List *getSetColTypes(ParseState *pstate, Node *node);
static void transformForUpdate(Query *qry, List *forUpdate);
static void transformConstraintAttrs(List *constraintList);
......@@ -309,18 +305,6 @@ transformStmt(ParseState *pstate, Node *parseTree,
(SelectStmt *) parseTree);
break;
/*
* Convert use of %TYPE in statements where it is permitted.
*/
case T_ProcedureStmt:
case T_CommentStmt:
case T_RemoveFuncStmt:
case T_DefineStmt:
result = makeNode(Query);
result->commandType = CMD_UTILITY;
result->utilityStmt = transformTypeRefs(pstate, parseTree);
break;
default:
/*
......@@ -792,17 +776,24 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
/* Check for SERIAL pseudo-types */
is_serial = false;
if (strcmp(column->typename->name, "serial") == 0 ||
strcmp(column->typename->name, "serial4") == 0)
{
is_serial = true;
column->typename->name = pstrdup("int4");
}
else if (strcmp(column->typename->name, "bigserial") == 0 ||
strcmp(column->typename->name, "serial8") == 0)
if (length(column->typename->names) == 1)
{
is_serial = true;
column->typename->name = pstrdup("int8");
char *typname = strVal(lfirst(column->typename->names));
if (strcmp(typname, "serial") == 0 ||
strcmp(typname, "serial4") == 0)
{
is_serial = true;
column->typename->names = NIL;
column->typename->typeid = INT4OID;
}
else if (strcmp(typname, "bigserial") == 0 ||
strcmp(typname, "serial8") == 0)
{
is_serial = true;
column->typename->names = NIL;
column->typename->typeid = INT8OID;
}
}
/* Do necessary work on the column type declaration */
......@@ -2634,110 +2625,6 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
return qry;
}
/*
* Transform uses of %TYPE in a statement.
*/
static Node *
transformTypeRefs(ParseState *pstate, Node *stmt)
{
switch (nodeTag(stmt))
{
case T_ProcedureStmt:
{
ProcedureStmt *ps = (ProcedureStmt *) stmt;
transformTypeRefsList(pstate, ps->argTypes);
transformTypeRef(pstate, (TypeName *) ps->returnType);
transformTypeRefsList(pstate, ps->withClause);
}
break;
case T_CommentStmt:
{
CommentStmt *cs = (CommentStmt *) stmt;
transformTypeRefsList(pstate, cs->objlist);
}
break;
case T_RemoveFuncStmt:
{
RemoveFuncStmt *rs = (RemoveFuncStmt *) stmt;
transformTypeRefsList(pstate, rs->args);
}
break;
case T_DefineStmt:
{
DefineStmt *ds = (DefineStmt *) stmt;
List *ele;
foreach(ele, ds->definition)
{
DefElem *de = (DefElem *) lfirst(ele);
if (de->arg != NULL
&& IsA(de->arg, TypeName))
transformTypeRef(pstate, (TypeName *) de->arg);
}
}
break;
default:
elog(ERROR, "Unsupported type %d in transformTypeRefs",
nodeTag(stmt));
break;
}
return stmt;
}
/*
* Transform uses of %TYPE in a list.
*/
static void
transformTypeRefsList(ParseState *pstate, List *l)
{
List *ele;
foreach(ele, l)
{
Node *elem = lfirst(ele);
if (elem && IsA(elem, TypeName))
transformTypeRef(pstate, (TypeName *) elem);
}
}
/*
* Transform a TypeName to not use %TYPE.
*/
static void
transformTypeRef(ParseState *pstate, TypeName *tn)
{
ColumnRef *cref;
Node *n;
Var *v;
char *tyn;
if (tn->attrname == NULL)
return;
/* XXX this needs work; can't type name be qualified? */
cref = makeNode(ColumnRef);
cref->fields = makeList2(makeString(tn->name), makeString(tn->attrname));
cref->indirection = NIL;
n = transformExpr(pstate, (Node *) cref);
if (!IsA(n, Var))
elog(ERROR, "unsupported expression in %%TYPE");
v = (Var *) n;
tyn = typeidTypeName(v->vartype);
elog(NOTICE, "%s.%s%%TYPE converted to %s", tn->name, tn->attrname, tyn);
tn->name = tyn;
tn->typmod = v->vartypmod;
tn->attrname = NULL;
}
/* exported so planner can check again after rewriting, query pullup, etc */
void
CheckSelectForUpdate(Query *qry)
......@@ -3059,15 +2946,7 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
ColumnDef *col = lfirst(cols);
if (strcmp(col->colname, colname) == 0)
{
char *buff = TypeNameToInternalName(col->typename);
result = typenameTypeId(buff);
if (!OidIsValid(result))
elog(ERROR, "Unable to lookup type %s",
col->typename->name);
return result;
}
return typenameTypeId(col->typename);
}
/* Perhaps it's a system column name */
sysatt = SystemAttributeByName(colname, cxt->hasoids);
......@@ -3092,7 +2971,6 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
if (strcmp(name, colname) == 0)
{
result = rel->rd_att->attrs[count]->atttypid;
heap_close(rel, NoLock);
return result;
}
......@@ -3111,7 +2989,6 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
if (HeapTupleIsValid(atttuple))
{
result = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
ReleaseSysCache(atttuple);
return result;
}
......@@ -3233,7 +3110,7 @@ static void
transformColumnType(ParseState *pstate, ColumnDef *column)
{
TypeName *typename = column->typename;
Type ctype = typenameType(typename->name);
Type ctype = typenameType(typename);
/*
* Is this the name of a complex type? If so, implement it as a set.
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.111 2002/03/21 16:01:03 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.112 2002/03/29 19:06:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1103,7 +1103,7 @@ parser_typecast_constant(Value *expr, TypeName *typename)
bool string_palloced = false;
bool isNull = false;
tp = typenameType(TypeNameToInternalName(typename));
tp = typenameType(typename);
switch (nodeTag(expr))
{
......@@ -1161,7 +1161,7 @@ parser_typecast_expression(ParseState *pstate,
Oid inputType = exprType(expr);
Oid targetType;
targetType = typenameTypeId(TypeNameToInternalName(typename));
targetType = typenameTypeId(typename);
if (inputType == InvalidOid)
return expr; /* do nothing if NULL input */
......@@ -1185,27 +1185,3 @@ parser_typecast_expression(ParseState *pstate,
return expr;
}
/*
* Given a TypeName node as returned by the grammar, generate the internal
* name of the corresponding type. Note this does NOT check if the type
* exists or not.
*/
char *
TypeNameToInternalName(TypeName *typename)
{
Assert(typename->attrname == NULL);
if (typename->arrayBounds != NIL)
{
/*
* By convention, the name of an array type is the name of its
* element type with "_" prepended.
*/
char *arrayname = palloc(strlen(typename->name) + 2);
sprintf(arrayname, "_%s", typename->name);
return arrayname;
}
else
return typename->name;
}
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.120 2002/03/22 02:56:34 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.121 2002/03/29 19:06:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -20,6 +20,7 @@
#include "catalog/indexing.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "nodes/makefuncs.h"
#include "parser/parse_agg.h"
......@@ -969,9 +970,14 @@ func_get_detail(char *funcname,
{
Oid targetType;
targetType = GetSysCacheOid(TYPENAME,
/* XXX WRONG: need to search searchpath for name; but little
* point in fixing before we revise this code for qualified
* funcnames too.
*/
targetType = GetSysCacheOid(TYPENAMENSP,
PointerGetDatum(funcname),
0, 0, 0);
ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
0, 0);
if (OidIsValid(targetType) &&
!ISCOMPLEX(targetType))
{
......@@ -1222,13 +1228,11 @@ find_inheritors(Oid relid, Oid **supervec)
{
/* return the type id, rather than the relation id */
Relation rd;
Oid trelid;
relid = lfirsti(elt);
rd = heap_open(relid, NoLock);
trelid = typenameTypeId(RelationGetRelationName(rd));
*relidvec++ = rd->rd_rel->reltype;
heap_close(rd, NoLock);
*relidvec++ = trelid;
}
}
else
......@@ -1473,7 +1477,9 @@ ParseComplexProjection(ParseState *pstate,
* argument types
*/
void
func_error(char *caller, char *funcname, int nargs, Oid *argtypes, char *msg)
func_error(const char *caller, const char *funcname,
int nargs, const Oid *argtypes,
const char *msg)
{
char p[(NAMEDATALEN + 2) * FUNC_MAX_ARGS],
*ptr;
......@@ -1488,9 +1494,9 @@ func_error(char *caller, char *funcname, int nargs, Oid *argtypes, char *msg)
*ptr++ = ',';
*ptr++ = ' ';
}
if (argtypes[i] != 0)
if (OidIsValid(argtypes[i]))
{
strcpy(ptr, typeidTypeName(argtypes[i]));
strncpy(ptr, typeidTypeName(argtypes[i]), NAMEDATALEN);
*(ptr + NAMEDATALEN) = '\0';
}
else
......
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.46 2002/03/21 23:27:23 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.47 2002/03/29 19:06:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -30,11 +30,12 @@
/*
* RemoveRewriteRule
*
* Delete a rule given its rulename.
* Delete a rule given its (possibly qualified) rulename.
*/
void
RemoveRewriteRule(char *ruleName)
RemoveRewriteRule(List *names)
{
char *ruleName;
Relation RewriteRelation;
Relation event_relation;
HeapTuple tuple;
......@@ -43,6 +44,13 @@ RemoveRewriteRule(char *ruleName)
bool hasMoreRules;
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.
*/
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment