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:
parent
7c1ff35410
commit
d5e99ab4d6
|
@ -1,6 +1,6 @@
|
|||
<!--
|
||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.38 2002/03/26 19:15:10 tgl Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.39 2002/03/29 19:05:57 tgl Exp $
|
||||
-->
|
||||
|
||||
<chapter id="catalogs">
|
||||
|
@ -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);
|
||||
|
||||
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);
|
||||
|
||||
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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.63 2001/10/25 05:49:23 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.64 2002/03/29 19:06:01 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* these routines moved here from commands/define.c and somewhat cleaned up.
|
||||
|
@ -30,34 +30,28 @@
|
|||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
static Oid OperatorGetWithOpenRelation(Relation pg_operator_desc,
|
||||
const char *operatorName,
|
||||
Oid leftObjectId,
|
||||
Oid rightObjectId,
|
||||
bool *defined);
|
||||
static Oid OperatorGet(const char *operatorName,
|
||||
Oid leftObjectId,
|
||||
Oid rightObjectId,
|
||||
bool *defined);
|
||||
|
||||
static Oid OperatorGet(char *operatorName,
|
||||
char *leftTypeName,
|
||||
char *rightTypeName,
|
||||
bool *defined);
|
||||
static Oid OperatorShellMake(const char *operatorName,
|
||||
Oid leftTypeId,
|
||||
Oid rightTypeId);
|
||||
|
||||
static Oid OperatorShellMake(char *operatorName,
|
||||
char *leftTypeName,
|
||||
char *rightTypeName);
|
||||
|
||||
static void OperatorDef(char *operatorName,
|
||||
char *leftTypeName,
|
||||
char *rightTypeName,
|
||||
char *procedureName,
|
||||
static void OperatorDef(const char *operatorName,
|
||||
Oid leftTypeId,
|
||||
Oid rightTypeId,
|
||||
const char *procedureName,
|
||||
uint16 precedence,
|
||||
bool isLeftAssociative,
|
||||
char *commutatorName,
|
||||
char *negatorName,
|
||||
char *restrictionName,
|
||||
char *oinName,
|
||||
const char *commutatorName,
|
||||
const char *negatorName,
|
||||
const char *restrictionName,
|
||||
const char *joinName,
|
||||
bool canHash,
|
||||
char *leftSortName,
|
||||
char *rightSortName);
|
||||
const char *leftSortName,
|
||||
const char *rightSortName);
|
||||
|
||||
static void OperatorUpd(Oid baseId, Oid commId, Oid negId);
|
||||
|
||||
|
@ -120,29 +114,37 @@ validOperatorName(const char *name)
|
|||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* OperatorGetWithOpenRelation
|
||||
* OperatorGet
|
||||
*
|
||||
* performs a scan on pg_operator for an operator tuple
|
||||
* with given name and left/right type oids.
|
||||
* finds the operator associated with the specified name
|
||||
* and left and right type IDs.
|
||||
*
|
||||
* pg_operator_desc -- reldesc for pg_operator
|
||||
* operatorName -- name of operator to fetch
|
||||
* leftObjectId -- left data type oid of operator to fetch
|
||||
* rightObjectId -- right data type oid of operator to fetch
|
||||
* defined -- set TRUE if defined (not a shell)
|
||||
* operatorName -- name of operator to fetch
|
||||
* leftObjectId -- left data type oid of operator to fetch
|
||||
* rightObjectId -- right data type oid of operator to fetch
|
||||
* defined -- set TRUE if defined (not a shell)
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static Oid
|
||||
OperatorGetWithOpenRelation(Relation pg_operator_desc,
|
||||
const char *operatorName,
|
||||
Oid leftObjectId,
|
||||
Oid rightObjectId,
|
||||
bool *defined)
|
||||
OperatorGet(const char *operatorName,
|
||||
Oid leftObjectId,
|
||||
Oid rightObjectId,
|
||||
bool *defined)
|
||||
{
|
||||
Relation pg_operator_desc;
|
||||
HeapScanDesc pg_operator_scan;
|
||||
Oid operatorObjectId;
|
||||
HeapTuple tup;
|
||||
ScanKeyData opKey[3];
|
||||
Oid operatorObjectId;
|
||||
|
||||
if (!(OidIsValid(leftObjectId) || OidIsValid(rightObjectId)))
|
||||
elog(ERROR, "operator %s must have at least one operand type",
|
||||
operatorName);
|
||||
|
||||
/*
|
||||
* open the pg_operator relation
|
||||
*/
|
||||
pg_operator_desc = heap_openr(OperatorRelationName, AccessShareLock);
|
||||
|
||||
/*
|
||||
* form scan key
|
||||
|
@ -192,99 +194,22 @@ OperatorGetWithOpenRelation(Relation pg_operator_desc,
|
|||
* close the scan and return the oid.
|
||||
*/
|
||||
heap_endscan(pg_operator_scan);
|
||||
|
||||
return operatorObjectId;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* OperatorGet
|
||||
*
|
||||
* finds the operator associated with the specified name
|
||||
* and left and right type names.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static Oid
|
||||
OperatorGet(char *operatorName,
|
||||
char *leftTypeName,
|
||||
char *rightTypeName,
|
||||
bool *defined)
|
||||
{
|
||||
Relation pg_operator_desc;
|
||||
Oid operatorObjectId;
|
||||
Oid leftObjectId = InvalidOid;
|
||||
Oid rightObjectId = InvalidOid;
|
||||
bool leftDefined = false;
|
||||
bool rightDefined = false;
|
||||
|
||||
/*
|
||||
* look up the operator data types.
|
||||
*
|
||||
* Note: types must be defined before operators
|
||||
*/
|
||||
if (leftTypeName)
|
||||
{
|
||||
leftObjectId = TypeGet(leftTypeName, &leftDefined);
|
||||
|
||||
if (!OidIsValid(leftObjectId) || !leftDefined)
|
||||
elog(ERROR, "left type \"%s\" of operator %s does not exist",
|
||||
leftTypeName, operatorName);
|
||||
}
|
||||
|
||||
if (rightTypeName)
|
||||
{
|
||||
rightObjectId = TypeGet(rightTypeName, &rightDefined);
|
||||
|
||||
if (!OidIsValid(rightObjectId) || !rightDefined)
|
||||
elog(ERROR, "right type \"%s\" of operator %s does not exist",
|
||||
rightTypeName, operatorName);
|
||||
}
|
||||
|
||||
if (!((OidIsValid(leftObjectId) && leftDefined) ||
|
||||
(OidIsValid(rightObjectId) && rightDefined)))
|
||||
elog(ERROR, "operator %s must have at least one operand type", operatorName);
|
||||
|
||||
/*
|
||||
* open the pg_operator relation
|
||||
*/
|
||||
pg_operator_desc = heap_openr(OperatorRelationName, AccessShareLock);
|
||||
|
||||
/*
|
||||
* get the oid for the operator with the appropriate name and
|
||||
* left/right types.
|
||||
*/
|
||||
operatorObjectId = OperatorGetWithOpenRelation(pg_operator_desc,
|
||||
operatorName,
|
||||
leftObjectId,
|
||||
rightObjectId,
|
||||
defined);
|
||||
|
||||
/*
|
||||
* close the relation and return the operator oid.
|
||||
*/
|
||||
heap_close(pg_operator_desc, AccessShareLock);
|
||||
|
||||
return operatorObjectId;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* OperatorShellMake
|
||||
*
|
||||
* Specify operator name and left and right type names,
|
||||
* fill an operator struct with this info and NULL's,
|
||||
* call heap_insert and return the Oid to the caller.
|
||||
* ----------------------------------------------------------------
|
||||
/*
|
||||
* OperatorShellMake
|
||||
* Make a "shell" entry for a not-yet-existing operator.
|
||||
*/
|
||||
static Oid
|
||||
OperatorShellMake(char *operatorName,
|
||||
char *leftTypeName,
|
||||
char *rightTypeName)
|
||||
OperatorShellMake(const char *operatorName,
|
||||
Oid leftTypeId,
|
||||
Oid rightTypeId)
|
||||
{
|
||||
Relation pg_operator_desc;
|
||||
Oid operatorObjectId;
|
||||
Oid leftObjectId = InvalidOid;
|
||||
Oid rightObjectId = InvalidOid;
|
||||
bool leftDefined = false;
|
||||
bool rightDefined = false;
|
||||
int i;
|
||||
HeapTuple tup;
|
||||
Datum values[Natts_pg_operator];
|
||||
|
@ -298,19 +223,6 @@ OperatorShellMake(char *operatorName,
|
|||
if (!validOperatorName(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
|
||||
*/
|
||||
|
@ -337,8 +249,8 @@ OperatorShellMake(char *operatorName,
|
|||
values[i++] = CharGetDatum('b'); /* assume it's binary */
|
||||
values[i++] = BoolGetDatum(false);
|
||||
values[i++] = BoolGetDatum(false);
|
||||
values[i++] = ObjectIdGetDatum(leftObjectId); /* <-- left oid */
|
||||
values[i++] = ObjectIdGetDatum(rightObjectId); /* <-- right oid */
|
||||
values[i++] = ObjectIdGetDatum(leftTypeId);
|
||||
values[i++] = ObjectIdGetDatum(rightTypeId);
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid);
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid);
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid);
|
||||
|
@ -444,8 +356,8 @@ OperatorShellMake(char *operatorName,
|
|||
* --------------------------------
|
||||
* "X" indicates an optional argument (i.e. one that can be NULL)
|
||||
* operatorName; -- operator name
|
||||
* leftTypeName; -- X left type name
|
||||
* rightTypeName; -- X right type name
|
||||
* leftTypeId; -- X left type id
|
||||
* rightTypeId; -- X right type id
|
||||
* procedureName; -- procedure name for operator code
|
||||
* precedence; -- operator precedence
|
||||
* isLeftAssociative; -- operator is left associative?
|
||||
|
@ -458,22 +370,20 @@ OperatorShellMake(char *operatorName,
|
|||
* rightSortName; -- X right sort operator (for merge join)
|
||||
*/
|
||||
static void
|
||||
OperatorDef(char *operatorName,
|
||||
char *leftTypeName,
|
||||
char *rightTypeName,
|
||||
char *procedureName,
|
||||
OperatorDef(const char *operatorName,
|
||||
Oid leftTypeId,
|
||||
Oid rightTypeId,
|
||||
const char *procedureName,
|
||||
uint16 precedence,
|
||||
bool isLeftAssociative,
|
||||
char *commutatorName,
|
||||
char *negatorName,
|
||||
char *restrictionName,
|
||||
char *joinName,
|
||||
const char *commutatorName,
|
||||
const char *negatorName,
|
||||
const char *restrictionName,
|
||||
const char *joinName,
|
||||
bool canHash,
|
||||
char *leftSortName,
|
||||
char *rightSortName)
|
||||
const char *leftSortName,
|
||||
const char *rightSortName)
|
||||
{
|
||||
int i,
|
||||
j;
|
||||
Relation pg_operator_desc;
|
||||
HeapScanDesc pg_operator_scan;
|
||||
HeapTuple tup;
|
||||
|
@ -482,23 +392,30 @@ OperatorDef(char *operatorName,
|
|||
Datum values[Natts_pg_operator];
|
||||
Oid operatorObjectId;
|
||||
bool operatorAlreadyDefined;
|
||||
Oid leftTypeId = InvalidOid;
|
||||
Oid rightTypeId = InvalidOid;
|
||||
Oid commutatorId = InvalidOid;
|
||||
Oid negatorId = InvalidOid;
|
||||
bool leftDefined = false;
|
||||
bool rightDefined = false;
|
||||
bool selfCommutator = false;
|
||||
char *name[4];
|
||||
const char *name[4];
|
||||
Oid typeId[FUNC_MAX_ARGS];
|
||||
int nargs;
|
||||
NameData oname;
|
||||
TupleDesc tupDesc;
|
||||
ScanKeyData opKey[3];
|
||||
int i,
|
||||
j;
|
||||
|
||||
/*
|
||||
* validate operator name
|
||||
*/
|
||||
if (!validOperatorName(operatorName))
|
||||
elog(ERROR, "\"%s\" is not a valid operator name", operatorName);
|
||||
|
||||
if (!(OidIsValid(leftTypeId) || OidIsValid(rightTypeId)))
|
||||
elog(ERROR, "operator must have at least one operand type");
|
||||
|
||||
operatorObjectId = OperatorGet(operatorName,
|
||||
leftTypeName,
|
||||
rightTypeName,
|
||||
leftTypeId,
|
||||
rightTypeId,
|
||||
&operatorAlreadyDefined);
|
||||
|
||||
if (operatorAlreadyDefined)
|
||||
|
@ -510,39 +427,6 @@ OperatorDef(char *operatorName,
|
|||
* filling in a previously-created shell.
|
||||
*/
|
||||
|
||||
/*
|
||||
* validate operator name
|
||||
*/
|
||||
if (!validOperatorName(operatorName))
|
||||
elog(ERROR, "\"%s\" is not a valid operator name", operatorName);
|
||||
|
||||
/*
|
||||
* look up the operator data types.
|
||||
*
|
||||
* Note: types must be defined before operators
|
||||
*/
|
||||
if (leftTypeName)
|
||||
{
|
||||
leftTypeId = TypeGet(leftTypeName, &leftDefined);
|
||||
|
||||
if (!OidIsValid(leftTypeId) || !leftDefined)
|
||||
elog(ERROR, "left type \"%s\" does not exist",
|
||||
leftTypeName);
|
||||
}
|
||||
|
||||
if (rightTypeName)
|
||||
{
|
||||
rightTypeId = TypeGet(rightTypeName, &rightDefined);
|
||||
|
||||
if (!OidIsValid(rightTypeId) || !rightDefined)
|
||||
elog(ERROR, "right type \"%s\" does not exist",
|
||||
rightTypeName);
|
||||
}
|
||||
|
||||
if (!((OidIsValid(leftTypeId) && leftDefined) ||
|
||||
(OidIsValid(rightTypeId) && rightDefined)))
|
||||
elog(ERROR, "operator must have at least one operand type");
|
||||
|
||||
for (i = 0; i < Natts_pg_operator; ++i)
|
||||
{
|
||||
values[i] = (Datum) NULL;
|
||||
|
@ -556,12 +440,12 @@ OperatorDef(char *operatorName,
|
|||
* created so we don't have to worry about deleting them later.
|
||||
*/
|
||||
MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||
if (!leftTypeName)
|
||||
if (!OidIsValid(leftTypeId))
|
||||
{
|
||||
typeId[0] = rightTypeId;
|
||||
nargs = 1;
|
||||
}
|
||||
else if (!rightTypeName)
|
||||
else if (!OidIsValid(rightTypeId))
|
||||
{
|
||||
typeId[0] = leftTypeId;
|
||||
nargs = 1;
|
||||
|
@ -645,7 +529,7 @@ OperatorDef(char *operatorName,
|
|||
values[i++] = NameGetDatum(&oname);
|
||||
values[i++] = Int32GetDatum(GetUserId());
|
||||
values[i++] = UInt16GetDatum(precedence);
|
||||
values[i++] = CharGetDatum(leftTypeName ? (rightTypeName ? 'b' : 'r') : 'l');
|
||||
values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l');
|
||||
values[i++] = BoolGetDatum(isLeftAssociative);
|
||||
values[i++] = BoolGetDatum(canHash);
|
||||
values[i++] = ObjectIdGetDatum(leftTypeId);
|
||||
|
@ -667,8 +551,6 @@ OperatorDef(char *operatorName,
|
|||
{
|
||||
if (name[j])
|
||||
{
|
||||
char *otherLeftTypeName = NULL;
|
||||
char *otherRightTypeName = NULL;
|
||||
Oid otherLeftTypeId = InvalidOid;
|
||||
Oid otherRightTypeId = InvalidOid;
|
||||
Oid other_oid = InvalidOid;
|
||||
|
@ -677,46 +559,37 @@ OperatorDef(char *operatorName,
|
|||
switch (j)
|
||||
{
|
||||
case 0: /* commutator has reversed arg types */
|
||||
otherLeftTypeName = rightTypeName;
|
||||
otherRightTypeName = leftTypeName;
|
||||
otherLeftTypeId = rightTypeId;
|
||||
otherRightTypeId = leftTypeId;
|
||||
other_oid = OperatorGet(name[j],
|
||||
otherLeftTypeName,
|
||||
otherRightTypeName,
|
||||
otherLeftTypeId,
|
||||
otherRightTypeId,
|
||||
&otherDefined);
|
||||
commutatorId = other_oid;
|
||||
break;
|
||||
case 1: /* negator has same arg types */
|
||||
otherLeftTypeName = leftTypeName;
|
||||
otherRightTypeName = rightTypeName;
|
||||
otherLeftTypeId = leftTypeId;
|
||||
otherRightTypeId = rightTypeId;
|
||||
other_oid = OperatorGet(name[j],
|
||||
otherLeftTypeName,
|
||||
otherRightTypeName,
|
||||
otherLeftTypeId,
|
||||
otherRightTypeId,
|
||||
&otherDefined);
|
||||
negatorId = other_oid;
|
||||
break;
|
||||
case 2: /* left sort op takes left-side data type */
|
||||
otherLeftTypeName = leftTypeName;
|
||||
otherRightTypeName = leftTypeName;
|
||||
otherLeftTypeId = leftTypeId;
|
||||
otherRightTypeId = leftTypeId;
|
||||
other_oid = OperatorGet(name[j],
|
||||
otherLeftTypeName,
|
||||
otherRightTypeName,
|
||||
otherLeftTypeId,
|
||||
otherRightTypeId,
|
||||
&otherDefined);
|
||||
break;
|
||||
case 3: /* right sort op takes right-side data
|
||||
* type */
|
||||
otherLeftTypeName = rightTypeName;
|
||||
otherRightTypeName = rightTypeName;
|
||||
case 3: /* right sort op takes right-side data type */
|
||||
otherLeftTypeId = rightTypeId;
|
||||
otherRightTypeId = rightTypeId;
|
||||
other_oid = OperatorGet(name[j],
|
||||
otherLeftTypeName,
|
||||
otherRightTypeName,
|
||||
otherLeftTypeId,
|
||||
otherRightTypeId,
|
||||
&otherDefined);
|
||||
break;
|
||||
}
|
||||
|
@ -732,8 +605,8 @@ OperatorDef(char *operatorName,
|
|||
{
|
||||
/* not in catalogs, different from operator */
|
||||
other_oid = OperatorShellMake(name[j],
|
||||
otherLeftTypeName,
|
||||
otherRightTypeName);
|
||||
otherLeftTypeId,
|
||||
otherRightTypeId);
|
||||
if (!OidIsValid(other_oid))
|
||||
elog(ERROR,
|
||||
"OperatorDef: can't create operator shell \"%s\"",
|
||||
|
@ -1023,10 +896,10 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
|
|||
*
|
||||
* This is now just an interface procedure for OperatorDef ...
|
||||
*
|
||||
* "X" indicates an optional argument (i.e. one that can be NULL)
|
||||
* "X" indicates an optional argument (i.e. one that can be NULL or 0)
|
||||
* operatorName; -- operator name
|
||||
* leftTypeName; -- X left type name
|
||||
* rightTypeName; -- X right type name
|
||||
* leftTypeId; -- X left type ID
|
||||
* rightTypeId; -- X right type ID
|
||||
* procedureName; -- procedure for operator
|
||||
* precedence; -- operator precedence
|
||||
* isLeftAssociative; -- operator is left associative
|
||||
|
@ -1039,24 +912,24 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
|
|||
* rightSortName; -- X right sort operator (for merge join)
|
||||
*/
|
||||
void
|
||||
OperatorCreate(char *operatorName,
|
||||
char *leftTypeName,
|
||||
char *rightTypeName,
|
||||
char *procedureName,
|
||||
OperatorCreate(const char *operatorName,
|
||||
Oid leftTypeId,
|
||||
Oid rightTypeId,
|
||||
const char *procedureName,
|
||||
uint16 precedence,
|
||||
bool isLeftAssociative,
|
||||
char *commutatorName,
|
||||
char *negatorName,
|
||||
char *restrictionName,
|
||||
char *joinName,
|
||||
const char *commutatorName,
|
||||
const char *negatorName,
|
||||
const char *restrictionName,
|
||||
const char *joinName,
|
||||
bool canHash,
|
||||
char *leftSortName,
|
||||
char *rightSortName)
|
||||
const char *leftSortName,
|
||||
const char *rightSortName)
|
||||
{
|
||||
if (!leftTypeName && !rightTypeName)
|
||||
if (!OidIsValid(leftTypeId) && !OidIsValid(rightTypeId))
|
||||
elog(ERROR, "at least one of leftarg or rightarg must be specified");
|
||||
|
||||
if (!(leftTypeName && rightTypeName))
|
||||
if (!(OidIsValid(leftTypeId) && OidIsValid(rightTypeId)))
|
||||
{
|
||||
/* If it's not a binary op, these things mustn't be set: */
|
||||
if (commutatorName)
|
||||
|
@ -1075,8 +948,8 @@ OperatorCreate(char *operatorName,
|
|||
* already exist.
|
||||
*/
|
||||
OperatorDef(operatorName,
|
||||
leftTypeName,
|
||||
rightTypeName,
|
||||
leftTypeId,
|
||||
rightTypeId,
|
||||
procedureName,
|
||||
precedence,
|
||||
isLeftAssociative,
|
||||
|
|
|
@ -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);
|
||||
char *typnam = TypeNameToString(t);
|
||||
|
||||
if (!OidIsValid(toid))
|
||||
elog(ERROR, "argument type %s does not exist",
|
||||
typnam);
|
||||
if (!defined)
|
||||
elog(WARNING, "argument type %s is only a shell",
|
||||
typnam);
|
||||
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.");
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.69 2002/03/20 19:43:38 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.70 2002/03/29 19:06:02 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -19,134 +19,42 @@
|
|||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "miscadmin.h"
|
||||
#include "parser/parse_func.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
static Oid TypeShellMakeWithOpenRelation(Relation pg_type_desc,
|
||||
char *typeName);
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* TypeGetWithOpenRelation
|
||||
* TypeShellMake
|
||||
*
|
||||
* preforms a scan on pg_type for a type tuple with the
|
||||
* given type name.
|
||||
* ----------------------------------------------------------------
|
||||
* pg_type_desc -- reldesc for pg_type
|
||||
* typeName -- name of type to be fetched
|
||||
* defined -- has the type been defined?
|
||||
*/
|
||||
static Oid
|
||||
TypeGetWithOpenRelation(Relation pg_type_desc,
|
||||
char *typeName,
|
||||
bool *defined)
|
||||
{
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tup;
|
||||
Oid typoid;
|
||||
ScanKeyData typeKey[1];
|
||||
|
||||
/*
|
||||
* initialize the scan key and begin a scan of pg_type
|
||||
*/
|
||||
ScanKeyEntryInitialize(&typeKey[0],
|
||||
0,
|
||||
Anum_pg_type_typname,
|
||||
F_NAMEEQ,
|
||||
PointerGetDatum(typeName));
|
||||
|
||||
scan = heap_beginscan(pg_type_desc,
|
||||
0,
|
||||
SnapshotSelf, /* cache? */
|
||||
1,
|
||||
typeKey);
|
||||
|
||||
/*
|
||||
* get the type tuple, if it exists.
|
||||
*/
|
||||
tup = heap_getnext(scan, 0);
|
||||
|
||||
/*
|
||||
* if no type tuple exists for the given type name, then end the scan
|
||||
* and return appropriate information.
|
||||
*/
|
||||
if (!HeapTupleIsValid(tup))
|
||||
{
|
||||
heap_endscan(scan);
|
||||
*defined = false;
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
/*
|
||||
* here, the type tuple does exist so we pull information from the
|
||||
* typisdefined field of the tuple and return the tuple's oid, which
|
||||
* is the oid of the type.
|
||||
*/
|
||||
*defined = (bool) ((Form_pg_type) GETSTRUCT(tup))->typisdefined;
|
||||
typoid = tup->t_data->t_oid;
|
||||
|
||||
heap_endscan(scan);
|
||||
|
||||
return typoid;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* TypeGet
|
||||
* 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.
|
||||
*
|
||||
* Finds the ObjectId of a type, even if uncommitted; "defined"
|
||||
* is only set if the type has actually been defined, i.e., if
|
||||
* the type tuple is not a shell.
|
||||
*
|
||||
* Note: the meat of this function is now in the function
|
||||
* TypeGetWithOpenRelation(). -cim 6/15/90
|
||||
*
|
||||
* Also called from util/remove.c
|
||||
* This is used so that a tuple exists in the catalogs.
|
||||
* The invalid fields should be fixed up sometime after
|
||||
* this routine is called, and then the "typeisdefined"
|
||||
* field is set to true. -cim 6/15/90
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
Oid
|
||||
TypeGet(char *typeName, /* name of type to be fetched */
|
||||
bool *defined) /* has the type been defined? */
|
||||
TypeShellMake(const char *typeName, Oid typeNamespace)
|
||||
{
|
||||
Relation pg_type_desc;
|
||||
Oid typeoid;
|
||||
|
||||
/*
|
||||
* open the pg_type relation
|
||||
*/
|
||||
pg_type_desc = heap_openr(TypeRelationName, AccessShareLock);
|
||||
|
||||
/*
|
||||
* scan the type relation for the information we want
|
||||
*/
|
||||
typeoid = TypeGetWithOpenRelation(pg_type_desc,
|
||||
typeName,
|
||||
defined);
|
||||
|
||||
/*
|
||||
* close the type relation and return the type oid.
|
||||
*/
|
||||
heap_close(pg_type_desc, AccessShareLock);
|
||||
|
||||
return typeoid;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* TypeShellMakeWithOpenRelation
|
||||
*
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static Oid
|
||||
TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
|
||||
{
|
||||
TupleDesc tupDesc;
|
||||
int i;
|
||||
HeapTuple tup;
|
||||
Datum values[Natts_pg_type];
|
||||
char nulls[Natts_pg_type];
|
||||
Oid typoid;
|
||||
NameData name;
|
||||
TupleDesc tupDesc;
|
||||
|
||||
Assert(PointerIsValid(typeName));
|
||||
|
||||
/*
|
||||
* open pg_type
|
||||
*/
|
||||
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
|
||||
tupDesc = pg_type_desc->rd_att;
|
||||
|
||||
/*
|
||||
* initialize our *nulls and *values arrays
|
||||
|
@ -162,34 +70,33 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
|
|||
*/
|
||||
i = 0;
|
||||
namestrcpy(&name, typeName);
|
||||
values[i++] = NameGetDatum(&name); /* 1 */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* 2 */
|
||||
values[i++] = Int16GetDatum(0); /* 3 */
|
||||
values[i++] = Int16GetDatum(0); /* 4 */
|
||||
values[i++] = BoolGetDatum(false); /* 5 */
|
||||
values[i++] = CharGetDatum(0); /* 6 */
|
||||
values[i++] = BoolGetDatum(false); /* 7 */
|
||||
values[i++] = CharGetDatum(0); /* 8 */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* 9 */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* 10 */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* 11 */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* 12 */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* 13 */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* 14 */
|
||||
values[i++] = CharGetDatum('i'); /* 15 */
|
||||
values[i++] = CharGetDatum('p'); /* 16 */
|
||||
values[i++] = BoolGetDatum(false); /* 17 */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* 18 */
|
||||
values[i++] = Int32GetDatum(-1); /* 19 */
|
||||
values[i++] = Int32GetDatum(0); /* 20 */
|
||||
nulls[i++] = 'n'; /* 21 */
|
||||
nulls[i++] = 'n'; /* 22 */
|
||||
values[i++] = NameGetDatum(&name); /* typname */
|
||||
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* typowner */
|
||||
values[i++] = Int16GetDatum(0); /* typlen */
|
||||
values[i++] = Int16GetDatum(0); /* typprtlen */
|
||||
values[i++] = BoolGetDatum(false); /* typbyval */
|
||||
values[i++] = CharGetDatum(0); /* typtype */
|
||||
values[i++] = BoolGetDatum(false); /* typisdefined */
|
||||
values[i++] = CharGetDatum(0); /* typdelim */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* typrelid */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* typelem */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* typinput */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* typoutput */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* typsend */
|
||||
values[i++] = CharGetDatum('i'); /* typalign */
|
||||
values[i++] = CharGetDatum('p'); /* typstorage */
|
||||
values[i++] = BoolGetDatum(false); /* typnotnull */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* typbasetype */
|
||||
values[i++] = Int32GetDatum(-1); /* typtypmod */
|
||||
values[i++] = Int32GetDatum(0); /* typndims */
|
||||
nulls[i++] = 'n'; /* typdefaultbin */
|
||||
nulls[i++] = 'n'; /* typdefault */
|
||||
|
||||
/*
|
||||
* create a new type tuple with FormHeapTuple
|
||||
* create a new type tuple
|
||||
*/
|
||||
tupDesc = pg_type_desc->rd_att;
|
||||
|
||||
tup = heap_formtuple(tupDesc, values, nulls);
|
||||
|
||||
/*
|
||||
|
@ -208,47 +115,9 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
|
|||
}
|
||||
|
||||
/*
|
||||
* free the tuple and return the type-oid
|
||||
* clean up and return the type-oid
|
||||
*/
|
||||
heap_freetuple(tup);
|
||||
|
||||
return typoid;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* TypeShellMake
|
||||
*
|
||||
* This procedure inserts a "shell" tuple into the type
|
||||
* relation. The type tuple inserted has invalid values
|
||||
* and in particular, the "typisdefined" field is false.
|
||||
*
|
||||
* This is used so that a tuple exists in the catalogs.
|
||||
* The invalid fields should be fixed up sometime after
|
||||
* this routine is called, and then the "typeisdefined"
|
||||
* field is set to true. -cim 6/15/90
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
Oid
|
||||
TypeShellMake(char *typeName)
|
||||
{
|
||||
Relation pg_type_desc;
|
||||
Oid typoid;
|
||||
|
||||
Assert(PointerIsValid(typeName));
|
||||
|
||||
/*
|
||||
* open pg_type
|
||||
*/
|
||||
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
* insert the shell tuple
|
||||
*/
|
||||
typoid = TypeShellMakeWithOpenRelation(pg_type_desc, typeName);
|
||||
|
||||
/*
|
||||
* close pg_type and return the tuple's oid.
|
||||
*/
|
||||
heap_close(pg_type_desc, RowExclusiveLock);
|
||||
|
||||
return typoid;
|
||||
|
@ -266,77 +135,38 @@ TypeShellMake(char *typeName)
|
|||
* ----------------------------------------------------------------
|
||||
*/
|
||||
Oid
|
||||
TypeCreate(char *typeName,
|
||||
TypeCreate(const char *typeName,
|
||||
Oid typeNamespace,
|
||||
Oid assignedTypeOid,
|
||||
Oid relationOid, /* only for 'c'atalog typeTypes */
|
||||
int16 internalSize,
|
||||
int16 externalSize,
|
||||
char typeType,
|
||||
char typDelim,
|
||||
char *inputProcedure,
|
||||
char *outputProcedure,
|
||||
char *receiveProcedure,
|
||||
char *sendProcedure,
|
||||
char *elementTypeName,
|
||||
char *baseTypeName,
|
||||
char *defaultTypeValue, /* human readable rep */
|
||||
char *defaultTypeBin, /* cooked rep */
|
||||
Oid inputProcedure,
|
||||
Oid outputProcedure,
|
||||
Oid receiveProcedure,
|
||||
Oid sendProcedure,
|
||||
Oid elementType,
|
||||
Oid baseType,
|
||||
const char *defaultTypeValue, /* human readable rep */
|
||||
const char *defaultTypeBin, /* cooked rep */
|
||||
bool passedByValue,
|
||||
char alignment,
|
||||
char storage,
|
||||
int32 typeMod,
|
||||
int32 typNDims, /* Array dimensions for baseTypeName */
|
||||
int32 typNDims, /* Array dimensions for baseType */
|
||||
bool typeNotNull)
|
||||
{
|
||||
int i,
|
||||
j;
|
||||
Relation pg_type_desc;
|
||||
HeapScanDesc pg_type_scan;
|
||||
Oid typeObjectId;
|
||||
Oid elementObjectId = InvalidOid;
|
||||
Oid baseObjectId = InvalidOid;
|
||||
HeapTuple tup;
|
||||
char nulls[Natts_pg_type];
|
||||
char replaces[Natts_pg_type];
|
||||
Datum values[Natts_pg_type];
|
||||
char *procname;
|
||||
char *procs[4];
|
||||
bool defined;
|
||||
NameData name;
|
||||
TupleDesc tupDesc;
|
||||
Oid argList[FUNC_MAX_ARGS];
|
||||
ScanKeyData typeKey[1];
|
||||
|
||||
/*
|
||||
* check that the type is not already defined. It might exist as a
|
||||
* shell type, however (but only if assignedTypeOid is not given).
|
||||
*/
|
||||
typeObjectId = TypeGet(typeName, &defined);
|
||||
if (OidIsValid(typeObjectId) &&
|
||||
(defined || assignedTypeOid != InvalidOid))
|
||||
elog(ERROR, "type named %s already exists", typeName);
|
||||
|
||||
/*
|
||||
* if this type has an associated elementType, then we check that it
|
||||
* is defined.
|
||||
*/
|
||||
if (elementTypeName)
|
||||
{
|
||||
elementObjectId = TypeGet(elementTypeName, &defined);
|
||||
if (!defined)
|
||||
elog(ERROR, "type %s does not exist", elementTypeName);
|
||||
}
|
||||
|
||||
/*
|
||||
* if this type has an associated baseType, then we check that it
|
||||
* is defined.
|
||||
*/
|
||||
if (baseTypeName)
|
||||
{
|
||||
baseObjectId = TypeGet(baseTypeName, &defined);
|
||||
if (!defined)
|
||||
elog(ERROR, "type %s does not exist", baseTypeName);
|
||||
}
|
||||
int i;
|
||||
|
||||
/*
|
||||
* validate size specifications: either positive (fixed-length) or -1
|
||||
|
@ -353,7 +183,7 @@ TypeCreate(char *typeName,
|
|||
elog(ERROR, "TypeCreate: fixed size types must have storage PLAIN");
|
||||
|
||||
/*
|
||||
* initialize arrays needed by FormHeapTuple
|
||||
* initialize arrays needed for heap_formtuple or heap_modifytuple
|
||||
*/
|
||||
for (i = 0; i < Natts_pg_type; ++i)
|
||||
{
|
||||
|
@ -367,94 +197,27 @@ TypeCreate(char *typeName,
|
|||
*/
|
||||
i = 0;
|
||||
namestrcpy(&name, typeName);
|
||||
values[i++] = NameGetDatum(&name); /* 1 */
|
||||
values[i++] = Int32GetDatum(GetUserId()); /* 2 */
|
||||
values[i++] = Int16GetDatum(internalSize); /* 3 */
|
||||
values[i++] = Int16GetDatum(externalSize); /* 4 */
|
||||
values[i++] = BoolGetDatum(passedByValue); /* 5 */
|
||||
values[i++] = CharGetDatum(typeType); /* 6 */
|
||||
values[i++] = BoolGetDatum(true); /* 7 */
|
||||
values[i++] = CharGetDatum(typDelim); /* 8 */
|
||||
values[i++] = ObjectIdGetDatum(typeType == 'c' ? relationOid : InvalidOid); /* 9 */
|
||||
values[i++] = ObjectIdGetDatum(elementObjectId); /* 10 */
|
||||
|
||||
procs[0] = inputProcedure;
|
||||
procs[1] = outputProcedure;
|
||||
procs[2] = (receiveProcedure) ? receiveProcedure : inputProcedure;
|
||||
procs[3] = (sendProcedure) ? sendProcedure : outputProcedure;
|
||||
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
Oid procOid;
|
||||
|
||||
procname = procs[j];
|
||||
|
||||
/*
|
||||
* First look for a 1-argument func with all argtypes 0. This is
|
||||
* valid for all four kinds of procedure.
|
||||
*/
|
||||
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||
|
||||
procOid = GetSysCacheOid(PROCNAME,
|
||||
PointerGetDatum(procname),
|
||||
Int32GetDatum(1),
|
||||
PointerGetDatum(argList),
|
||||
0);
|
||||
|
||||
if (!OidIsValid(procOid))
|
||||
{
|
||||
/*
|
||||
* For array types, the input procedures may take 3 args (data
|
||||
* value, element OID, atttypmod); the pg_proc argtype
|
||||
* signature is 0,OIDOID,INT4OID. The output procedures may
|
||||
* take 2 args (data value, element OID).
|
||||
*/
|
||||
if (OidIsValid(elementObjectId) || OidIsValid(baseObjectId))
|
||||
{
|
||||
int nargs;
|
||||
|
||||
if (j % 2)
|
||||
{
|
||||
/* output proc */
|
||||
nargs = 2;
|
||||
argList[1] = OIDOID;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* input proc */
|
||||
nargs = 3;
|
||||
argList[1] = OIDOID;
|
||||
argList[2] = INT4OID;
|
||||
}
|
||||
procOid = GetSysCacheOid(PROCNAME,
|
||||
PointerGetDatum(procname),
|
||||
Int32GetDatum(nargs),
|
||||
PointerGetDatum(argList),
|
||||
0);
|
||||
}
|
||||
|
||||
if (!OidIsValid(procOid))
|
||||
func_error("TypeCreate", procname, 1, argList, NULL);
|
||||
}
|
||||
|
||||
values[i++] = ObjectIdGetDatum(procOid); /* 11 - 14 */
|
||||
}
|
||||
|
||||
/*
|
||||
* set default alignment
|
||||
*/
|
||||
values[i++] = CharGetDatum(alignment); /* 15 */
|
||||
|
||||
/*
|
||||
* set default storage for TOAST
|
||||
*/
|
||||
values[i++] = CharGetDatum(storage); /* 16 */
|
||||
|
||||
/* set typnotnull, typbasetype, typtypmod, typndims */
|
||||
values[i++] = BoolGetDatum(typeNotNull); /* 17 */
|
||||
values[i++] = ObjectIdGetDatum(baseObjectId); /* 18 */
|
||||
values[i++] = Int32GetDatum(typeMod); /* 19 */
|
||||
values[i++] = Int32GetDatum(typNDims); /* 20 */
|
||||
values[i++] = NameGetDatum(&name); /* typname */
|
||||
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
|
||||
values[i++] = Int32GetDatum(GetUserId()); /* typowner */
|
||||
values[i++] = Int16GetDatum(internalSize); /* typlen */
|
||||
values[i++] = Int16GetDatum(externalSize); /* typprtlen */
|
||||
values[i++] = BoolGetDatum(passedByValue); /* typbyval */
|
||||
values[i++] = CharGetDatum(typeType); /* typtype */
|
||||
values[i++] = BoolGetDatum(true); /* typisdefined */
|
||||
values[i++] = CharGetDatum(typDelim); /* typdelim */
|
||||
values[i++] = ObjectIdGetDatum(typeType == 'c' ? relationOid : InvalidOid); /* typrelid */
|
||||
values[i++] = ObjectIdGetDatum(elementType); /* typelem */
|
||||
values[i++] = ObjectIdGetDatum(inputProcedure); /* typinput */
|
||||
values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */
|
||||
values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */
|
||||
values[i++] = ObjectIdGetDatum(sendProcedure); /* typsend */
|
||||
values[i++] = CharGetDatum(alignment); /* typalign */
|
||||
values[i++] = CharGetDatum(storage); /* typstorage */
|
||||
values[i++] = BoolGetDatum(typeNotNull); /* typnotnull */
|
||||
values[i++] = ObjectIdGetDatum(baseType); /* typbasetype */
|
||||
values[i++] = Int32GetDatum(typeMod); /* typtypmod */
|
||||
values[i++] = Int32GetDatum(typNDims); /* typndims */
|
||||
|
||||
/*
|
||||
* initialize the default binary value for this type. Check for
|
||||
|
@ -465,7 +228,7 @@ TypeCreate(char *typeName,
|
|||
CStringGetDatum(defaultTypeBin));
|
||||
else
|
||||
nulls[i] = 'n';
|
||||
i++; /* 21 */
|
||||
i++; /* typdefaultbin */
|
||||
|
||||
/*
|
||||
* initialize the default value for this type.
|
||||
|
@ -475,36 +238,33 @@ TypeCreate(char *typeName,
|
|||
CStringGetDatum(defaultTypeValue));
|
||||
else
|
||||
nulls[i] = 'n';
|
||||
i++; /* 22 */
|
||||
i++; /* typdefault */
|
||||
|
||||
/*
|
||||
* open pg_type and begin a scan for the type name.
|
||||
* open pg_type and prepare to insert or update a row.
|
||||
*
|
||||
* NOTE: updating will not work correctly in bootstrap mode; but we don't
|
||||
* expect to be overwriting any shell types in bootstrap mode.
|
||||
*/
|
||||
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
|
||||
|
||||
ScanKeyEntryInitialize(&typeKey[0],
|
||||
0,
|
||||
Anum_pg_type_typname,
|
||||
F_NAMEEQ,
|
||||
PointerGetDatum(typeName));
|
||||
|
||||
pg_type_scan = heap_beginscan(pg_type_desc,
|
||||
0,
|
||||
SnapshotSelf, /* cache? */
|
||||
1,
|
||||
typeKey);
|
||||
|
||||
/*
|
||||
* define the type either by adding a tuple to the type relation, or
|
||||
* by updating the fields of the "shell" tuple already there.
|
||||
*/
|
||||
tup = heap_getnext(pg_type_scan, 0);
|
||||
tup = SearchSysCacheCopy(TYPENAMENSP,
|
||||
CStringGetDatum(typeName),
|
||||
ObjectIdGetDatum(typeNamespace),
|
||||
0, 0);
|
||||
if (HeapTupleIsValid(tup))
|
||||
{
|
||||
/* should not happen given prior test? */
|
||||
if (assignedTypeOid != InvalidOid)
|
||||
/*
|
||||
* check that the type is not already defined. It may exist as a
|
||||
* shell type, however (but only if assignedTypeOid is not given).
|
||||
*/
|
||||
if (((Form_pg_type) GETSTRUCT(tup))->typisdefined ||
|
||||
assignedTypeOid != InvalidOid)
|
||||
elog(ERROR, "type %s already exists", typeName);
|
||||
|
||||
/*
|
||||
* Okay to update existing "shell" type tuple
|
||||
*/
|
||||
tup = heap_modifytuple(tup,
|
||||
pg_type_desc,
|
||||
values,
|
||||
|
@ -531,11 +291,7 @@ TypeCreate(char *typeName,
|
|||
typeObjectId = tup->t_data->t_oid;
|
||||
}
|
||||
|
||||
/*
|
||||
* finish up
|
||||
*/
|
||||
heap_endscan(pg_type_scan);
|
||||
|
||||
/* Update indices (not necessary if bootstrapping) */
|
||||
if (RelationGetForm(pg_type_desc)->relhasindex)
|
||||
{
|
||||
Relation idescs[Num_pg_type_indices];
|
||||
|
@ -545,19 +301,25 @@ TypeCreate(char *typeName,
|
|||
CatalogCloseIndices(Num_pg_type_indices, idescs);
|
||||
}
|
||||
|
||||
/*
|
||||
* finish up
|
||||
*/
|
||||
heap_close(pg_type_desc, RowExclusiveLock);
|
||||
|
||||
return typeObjectId;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* TypeRename
|
||||
*
|
||||
/*
|
||||
* TypeRename
|
||||
* This renames a type
|
||||
* ----------------------------------------------------------------
|
||||
*
|
||||
* Note: any associated array type is *not* renamed; caller must make
|
||||
* another call to handle that case. Currently this is only used for
|
||||
* renaming types associated with tables, for which there are no arrays.
|
||||
*/
|
||||
void
|
||||
TypeRename(const char *oldTypeName, const char *newTypeName)
|
||||
TypeRename(const char *oldTypeName, Oid typeNamespace,
|
||||
const char *newTypeName)
|
||||
{
|
||||
Relation pg_type_desc;
|
||||
Relation idescs[Num_pg_type_indices];
|
||||
|
@ -565,15 +327,17 @@ TypeRename(const char *oldTypeName, const char *newTypeName)
|
|||
|
||||
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
|
||||
|
||||
tuple = SearchSysCacheCopy(TYPENAME,
|
||||
PointerGetDatum(oldTypeName),
|
||||
0, 0, 0);
|
||||
tuple = SearchSysCacheCopy(TYPENAMENSP,
|
||||
CStringGetDatum(oldTypeName),
|
||||
ObjectIdGetDatum(typeNamespace),
|
||||
0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "type %s does not exist", oldTypeName);
|
||||
|
||||
if (SearchSysCacheExists(TYPENAME,
|
||||
PointerGetDatum(newTypeName),
|
||||
0, 0, 0))
|
||||
if (SearchSysCacheExists(TYPENAMENSP,
|
||||
CStringGetDatum(newTypeName),
|
||||
ObjectIdGetDatum(typeNamespace),
|
||||
0, 0))
|
||||
elog(ERROR, "type named %s already exists", newTypeName);
|
||||
|
||||
namestrcpy(&(((Form_pg_type) GETSTRUCT(tuple))->typname), newTypeName);
|
||||
|
@ -596,7 +360,7 @@ TypeRename(const char *oldTypeName, const char *newTypeName)
|
|||
* the caller is responsible for pfreeing the result
|
||||
*/
|
||||
char *
|
||||
makeArrayTypeName(char *typeName)
|
||||
makeArrayTypeName(const char *typeName)
|
||||
{
|
||||
char *arr;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.166 2002/03/26 19:15:36 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.167 2002/03/29 19:06:03 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The PerformAddAttribute() code, like most of the relation
|
||||
|
@ -42,11 +42,12 @@
|
|||
#include "optimizer/clauses.h"
|
||||
#include "optimizer/planmain.h"
|
||||
#include "optimizer/prep.h"
|
||||
#include "parser/analyze.h"
|
||||
#include "parser/parse.h"
|
||||
#include "parser/parse_expr.h"
|
||||
#include "parser/parse_oper.h"
|
||||
#include "parser/parse_relation.h"
|
||||
#include "parser/analyze.h"
|
||||
#include "parser/parse_type.h"
|
||||
#include "tcop/utility.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/builtins.h"
|
||||
|
@ -58,9 +59,9 @@
|
|||
|
||||
static void drop_default(Oid relid, int16 attnum);
|
||||
static bool needs_toast_table(Relation rel);
|
||||
static void AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId);
|
||||
static void CheckTupleType(Form_pg_class tuple_class);
|
||||
|
||||
|
||||
/* --------------------------------
|
||||
* PortalCleanup
|
||||
* --------------------------------
|
||||
|
@ -309,13 +310,13 @@ PerformPortalClose(char *name, CommandDest dest)
|
|||
* ----------------
|
||||
*/
|
||||
void
|
||||
AlterTableAddColumn(const char *relationName,
|
||||
AlterTableAddColumn(Oid myrelid,
|
||||
bool inherits,
|
||||
ColumnDef *colDef)
|
||||
{
|
||||
Relation rel,
|
||||
pgclass,
|
||||
attrdesc;
|
||||
Oid myrelid;
|
||||
HeapTuple reltup;
|
||||
HeapTuple newreltup;
|
||||
HeapTuple attributeTuple;
|
||||
|
@ -326,19 +327,17 @@ AlterTableAddColumn(const char *relationName,
|
|||
maxatts;
|
||||
HeapTuple typeTuple;
|
||||
Form_pg_type tform;
|
||||
char *typename;
|
||||
int attndims;
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
rel = heap_open(myrelid, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
/*
|
||||
* permissions checking. this would normally be done in utility.c,
|
||||
|
@ -346,13 +345,13 @@ AlterTableAddColumn(const char *relationName,
|
|||
*
|
||||
* normally, only the owner of a class can change its schema.
|
||||
*/
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
if (!allowSystemTableMods
|
||||
&& IsSystemRelationName(RelationGetRelationName(rel)))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
/*
|
||||
* Recurse to add the column to child classes, if requested.
|
||||
|
@ -377,17 +376,11 @@ AlterTableAddColumn(const char *relationName,
|
|||
foreach(child, children)
|
||||
{
|
||||
Oid childrelid = lfirsti(child);
|
||||
char *childrelname;
|
||||
|
||||
if (childrelid == myrelid)
|
||||
continue;
|
||||
rel = heap_open(childrelid, AccessExclusiveLock);
|
||||
childrelname = pstrdup(RelationGetRelationName(rel));
|
||||
heap_close(rel, AccessExclusiveLock);
|
||||
|
||||
AlterTableAddColumn(childrelname, false, colDef);
|
||||
|
||||
pfree(childrelname);
|
||||
AlterTableAddColumn(childrelid, false, colDef);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -412,23 +405,21 @@ AlterTableAddColumn(const char *relationName,
|
|||
elog(ERROR, "Adding NOT NULL columns is not implemented."
|
||||
"\n\tAdd the column, then use ALTER TABLE ADD CONSTRAINT.");
|
||||
|
||||
|
||||
rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||
pgclass = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||
|
||||
reltup = SearchSysCache(RELOID,
|
||||
ObjectIdGetDatum(myrelid),
|
||||
0, 0, 0);
|
||||
|
||||
if (!HeapTupleIsValid(reltup))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (SearchSysCacheExists(ATTNAME,
|
||||
ObjectIdGetDatum(myrelid),
|
||||
PointerGetDatum(colDef->colname),
|
||||
0, 0))
|
||||
elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"",
|
||||
colDef->colname, relationName);
|
||||
colDef->colname, RelationGetRelationName(rel));
|
||||
|
||||
minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
|
||||
maxatts = minattnum + 1;
|
||||
|
@ -440,21 +431,11 @@ AlterTableAddColumn(const char *relationName,
|
|||
attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock);
|
||||
|
||||
if (colDef->typename->arrayBounds)
|
||||
{
|
||||
attndims = length(colDef->typename->arrayBounds);
|
||||
typename = makeArrayTypeName(colDef->typename->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
attndims = 0;
|
||||
typename = colDef->typename->name;
|
||||
}
|
||||
|
||||
typeTuple = SearchSysCache(TYPENAME,
|
||||
PointerGetDatum(typename),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(typeTuple))
|
||||
elog(ERROR, "ALTER TABLE: type \"%s\" does not exist", typename);
|
||||
typeTuple = typenameType(colDef->typename);
|
||||
tform = (Form_pg_type) GETSTRUCT(typeTuple);
|
||||
|
||||
attributeTuple = heap_addheader(Natts_pg_attribute,
|
||||
|
@ -494,7 +475,7 @@ AlterTableAddColumn(const char *relationName,
|
|||
CatalogCloseIndices(Num_pg_attr_indices, idescs);
|
||||
}
|
||||
|
||||
heap_close(attrdesc, NoLock);
|
||||
heap_close(attrdesc, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
* Update number of attributes in pg_class tuple
|
||||
|
@ -502,22 +483,24 @@ AlterTableAddColumn(const char *relationName,
|
|||
newreltup = heap_copytuple(reltup);
|
||||
|
||||
((Form_pg_class) GETSTRUCT(newreltup))->relnatts = maxatts;
|
||||
simple_heap_update(rel, &newreltup->t_self, newreltup);
|
||||
simple_heap_update(pgclass, &newreltup->t_self, newreltup);
|
||||
|
||||
/* keep catalog indices current */
|
||||
if (RelationGetForm(rel)->relhasindex)
|
||||
if (RelationGetForm(pgclass)->relhasindex)
|
||||
{
|
||||
Relation ridescs[Num_pg_class_indices];
|
||||
|
||||
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
|
||||
CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, newreltup);
|
||||
CatalogIndexInsert(ridescs, Num_pg_class_indices, pgclass, newreltup);
|
||||
CatalogCloseIndices(Num_pg_class_indices, ridescs);
|
||||
}
|
||||
|
||||
heap_freetuple(newreltup);
|
||||
ReleaseSysCache(reltup);
|
||||
|
||||
heap_close(rel, NoLock);
|
||||
heap_close(pgclass, NoLock);
|
||||
|
||||
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||
|
||||
/*
|
||||
* Make our catalog updates visible for subsequent steps.
|
||||
|
@ -549,29 +532,28 @@ AlterTableAddColumn(const char *relationName,
|
|||
* ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
|
||||
*/
|
||||
void
|
||||
AlterTableAlterColumnDefault(const char *relationName,
|
||||
AlterTableAlterColumnDefault(Oid myrelid,
|
||||
bool inh, const char *colName,
|
||||
Node *newDefault)
|
||||
{
|
||||
Relation rel;
|
||||
HeapTuple tuple;
|
||||
int16 attnum;
|
||||
Oid myrelid;
|
||||
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
rel = heap_open(myrelid, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
if (!allowSystemTableMods
|
||||
&& IsSystemRelationName(RelationGetRelationName(rel)))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
heap_close(rel, NoLock);
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: \"%s\" permission denied",
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
/*
|
||||
* Propagate to children if desired
|
||||
|
@ -595,18 +577,13 @@ AlterTableAlterColumnDefault(const char *relationName,
|
|||
|
||||
if (childrelid == myrelid)
|
||||
continue;
|
||||
rel = heap_open(childrelid, AccessExclusiveLock);
|
||||
AlterTableAlterColumnDefault(RelationGetRelationName(rel),
|
||||
AlterTableAlterColumnDefault(childrelid,
|
||||
false, colName, newDefault);
|
||||
heap_close(rel, AccessExclusiveLock);
|
||||
}
|
||||
}
|
||||
|
||||
/* -= now do the thing on this relation =- */
|
||||
|
||||
/* reopen the business */
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
|
||||
/*
|
||||
* get the number of the attribute
|
||||
*/
|
||||
|
@ -616,7 +593,7 @@ AlterTableAlterColumnDefault(const char *relationName,
|
|||
0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
|
||||
relationName, colName);
|
||||
RelationGetRelationName(rel), colName);
|
||||
|
||||
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
|
||||
ReleaseSysCache(tuple);
|
||||
|
@ -718,43 +695,42 @@ drop_default(Oid relid, int16 attnum)
|
|||
* ALTER TABLE ALTER COLUMN SET STATISTICS / STORAGE
|
||||
*/
|
||||
void
|
||||
AlterTableAlterColumnFlags(const char *relationName,
|
||||
AlterTableAlterColumnFlags(Oid myrelid,
|
||||
bool inh, const char *colName,
|
||||
Node *flagValue, const char *flagType)
|
||||
{
|
||||
Relation rel;
|
||||
Oid myrelid;
|
||||
int newtarget = 1;
|
||||
char newstorage = 'x';
|
||||
char *storagemode;
|
||||
Relation attrelation;
|
||||
HeapTuple tuple;
|
||||
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
rel = heap_open(myrelid, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
/* we allow statistics case for system tables */
|
||||
if (*flagType == 'M' &&
|
||||
!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
/*
|
||||
* we allow statistics case for system tables
|
||||
*/
|
||||
if (*flagType != 'S' &&
|
||||
!allowSystemTableMods
|
||||
&& IsSystemRelationName(RelationGetRelationName(rel)))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
heap_close(rel, NoLock); /* close rel, but keep lock! */
|
||||
|
||||
elog(ERROR, "ALTER TABLE: \"%s\" permission denied",
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
/*
|
||||
* Check the supplied parameters before anything else
|
||||
*/
|
||||
if (*flagType == 'S') /*
|
||||
* STATISTICS
|
||||
*/
|
||||
if (*flagType == 'S')
|
||||
{
|
||||
/* STATISTICS */
|
||||
Assert(IsA(flagValue, Integer));
|
||||
newtarget = intVal(flagValue);
|
||||
|
||||
|
@ -766,10 +742,9 @@ AlterTableAlterColumnFlags(const char *relationName,
|
|||
else if (newtarget > 1000)
|
||||
newtarget = 1000;
|
||||
}
|
||||
else if (*flagType == 'M') /*
|
||||
* STORAGE
|
||||
*/
|
||||
else if (*flagType == 'M')
|
||||
{
|
||||
/* STORAGE */
|
||||
Assert(IsA(flagValue, Value));
|
||||
|
||||
storagemode = strVal(flagValue);
|
||||
|
@ -813,10 +788,8 @@ AlterTableAlterColumnFlags(const char *relationName,
|
|||
|
||||
if (childrelid == myrelid)
|
||||
continue;
|
||||
rel = heap_open(childrelid, AccessExclusiveLock);
|
||||
AlterTableAlterColumnFlags(RelationGetRelationName(rel),
|
||||
false, colName, flagValue, flagType);
|
||||
heap_close(rel, AccessExclusiveLock);
|
||||
AlterTableAlterColumnFlags(childrelid,
|
||||
false, colName, flagValue, flagType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -830,7 +803,7 @@ AlterTableAlterColumnFlags(const char *relationName,
|
|||
0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
|
||||
relationName, colName);
|
||||
RelationGetRelationName(rel), colName);
|
||||
|
||||
if (((Form_pg_attribute) GETSTRUCT(tuple))->attnum < 0)
|
||||
elog(ERROR, "ALTER TABLE: cannot change system attribute \"%s\"",
|
||||
|
@ -864,6 +837,7 @@ AlterTableAlterColumnFlags(const char *relationName,
|
|||
|
||||
heap_freetuple(tuple);
|
||||
heap_close(attrelation, NoLock);
|
||||
heap_close(rel, NoLock); /* close rel, but keep lock! */
|
||||
}
|
||||
|
||||
|
||||
|
@ -1006,14 +980,13 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
|
|||
* ALTER TABLE DROP COLUMN
|
||||
*/
|
||||
void
|
||||
AlterTableDropColumn(const char *relationName,
|
||||
AlterTableDropColumn(Oid myrelid,
|
||||
bool inh, const char *colName,
|
||||
int behavior)
|
||||
{
|
||||
#ifdef _DROP_COLUMN_HACK__
|
||||
Relation rel,
|
||||
attrdesc;
|
||||
Oid myrelid;
|
||||
HeapTuple reltup;
|
||||
HeapTupleData classtuple;
|
||||
Buffer buffer;
|
||||
|
@ -1031,12 +1004,16 @@ AlterTableDropColumn(const char *relationName,
|
|||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
rel = heap_open(myrelid, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (!allowSystemTableMods
|
||||
&& IsSystemRelationName(RelationGetRelationName(rel))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
/*
|
||||
* permissions checking. this would normally be done in utility.c,
|
||||
|
@ -1044,9 +1021,6 @@ AlterTableDropColumn(const char *relationName,
|
|||
*
|
||||
* normally, only the owner of a class can change its schema.
|
||||
*/
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
|
@ -1066,8 +1040,17 @@ AlterTableDropColumn(const char *relationName,
|
|||
ObjectIdGetDatum(myrelid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(reltup))
|
||||
{
|
||||
Relation myrel;
|
||||
char *myrelname;
|
||||
|
||||
myrel = heap_open(myrelid, AccessExclusiveLock);
|
||||
myrelname = pstrdup(RelationGetRelationName(myrel));
|
||||
heap_close(myrel, AccessExclusiveLock);
|
||||
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
|
||||
relationName);
|
||||
myrelname);
|
||||
}
|
||||
classtuple.t_self = reltup->t_self;
|
||||
ReleaseSysCache(reltup);
|
||||
|
||||
|
@ -1092,8 +1075,17 @@ AlterTableDropColumn(const char *relationName,
|
|||
PointerGetDatum(colName),
|
||||
0, 0);
|
||||
if (!HeapTupleIsValid(tup))
|
||||
{
|
||||
Relation myrel;
|
||||
char *myrelname;
|
||||
|
||||
myrel = heap_open(myrelid, AccessExclusiveLock);
|
||||
myrelname = pstrdup(RelationGetRelationName(myrel));
|
||||
heap_close(myrel, AccessExclusiveLock);
|
||||
|
||||
elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"",
|
||||
colName, relationName);
|
||||
colName, myrelname);
|
||||
}
|
||||
|
||||
attribute = (Form_pg_attribute) GETSTRUCT(tup);
|
||||
attnum = attribute->attnum;
|
||||
|
@ -1164,29 +1156,30 @@ AlterTableDropColumn(const char *relationName,
|
|||
* ALTER TABLE ADD CONSTRAINT
|
||||
*/
|
||||
void
|
||||
AlterTableAddConstraint(char *relationName,
|
||||
AlterTableAddConstraint(Oid myrelid,
|
||||
bool inh, List *newConstraints)
|
||||
{
|
||||
Relation rel;
|
||||
Oid myrelid;
|
||||
List *listptr;
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
rel = heap_open(myrelid, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
if (!allowSystemTableMods
|
||||
&& IsSystemRelationName(RelationGetRelationName(rel)))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (inh)
|
||||
{
|
||||
|
@ -1204,16 +1197,10 @@ AlterTableAddConstraint(char *relationName,
|
|||
foreach(child, children)
|
||||
{
|
||||
Oid childrelid = lfirsti(child);
|
||||
char *childrelname;
|
||||
Relation childrel;
|
||||
|
||||
if (childrelid == myrelid)
|
||||
continue;
|
||||
childrel = heap_open(childrelid, AccessExclusiveLock);
|
||||
childrelname = pstrdup(RelationGetRelationName(childrel));
|
||||
heap_close(childrel, AccessExclusiveLock);
|
||||
AlterTableAddConstraint(childrelname, false, newConstraints);
|
||||
pfree(childrelname);
|
||||
AlterTableAddConstraint(childrelid, false, newConstraints);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1262,7 +1249,7 @@ AlterTableAddConstraint(char *relationName,
|
|||
pstate = make_parsestate(NULL);
|
||||
rte = addRangeTableEntryForRelation(pstate,
|
||||
myrelid,
|
||||
makeAlias(relationName, NIL),
|
||||
makeAlias(RelationGetRelationName(rel), NIL),
|
||||
false,
|
||||
true);
|
||||
addRTEtoQuery(pstate, rte, true, true);
|
||||
|
@ -1286,7 +1273,7 @@ AlterTableAddConstraint(char *relationName,
|
|||
*/
|
||||
if (length(pstate->p_rtable) != 1)
|
||||
elog(ERROR, "Only relation '%s' can be referenced in CHECK",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
/*
|
||||
* Might as well try to reduce any
|
||||
|
@ -1358,7 +1345,7 @@ AlterTableAddConstraint(char *relationName,
|
|||
int count;
|
||||
|
||||
if (is_temp_rel_name(fkconstraint->pktable->relname) &&
|
||||
!is_temp_rel_name(relationName))
|
||||
!is_temp_rel_name(RelationGetRelationName(rel)))
|
||||
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint.");
|
||||
|
||||
/*
|
||||
|
@ -1408,7 +1395,7 @@ AlterTableAddConstraint(char *relationName,
|
|||
trig.tgargs[0] = fkconstraint->constr_name;
|
||||
else
|
||||
trig.tgargs[0] = "<unknown>";
|
||||
trig.tgargs[1] = (char *) relationName;
|
||||
trig.tgargs[1] = pstrdup(RelationGetRelationName(rel));
|
||||
trig.tgargs[2] = fkconstraint->pktable->relname;
|
||||
trig.tgargs[3] = fkconstraint->match_type;
|
||||
count = 4;
|
||||
|
@ -1483,12 +1470,11 @@ AlterTableAddConstraint(char *relationName,
|
|||
* Christopher Kings-Lynne
|
||||
*/
|
||||
void
|
||||
AlterTableDropConstraint(const char *relationName,
|
||||
AlterTableDropConstraint(Oid myrelid,
|
||||
bool inh, const char *constrName,
|
||||
int behavior)
|
||||
{
|
||||
Relation rel;
|
||||
Oid myrelid;
|
||||
int deleted;
|
||||
|
||||
/*
|
||||
|
@ -1502,19 +1488,21 @@ AlterTableDropConstraint(const char *relationName,
|
|||
* Acquire an exclusive lock on the target relation for the duration
|
||||
* of the operation.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
rel = heap_open(myrelid, AccessExclusiveLock);
|
||||
|
||||
/* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
if (!allowSystemTableMods
|
||||
&& IsSystemRelationName(RelationGetRelationName(rel)))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
/*
|
||||
* Since all we have is the name of the constraint, we have to look
|
||||
|
@ -1554,30 +1542,7 @@ AlterTableDropConstraint(const char *relationName,
|
|||
* ALTER TABLE OWNER
|
||||
*/
|
||||
void
|
||||
AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName)
|
||||
{
|
||||
Relation rel;
|
||||
Oid myrelid;
|
||||
int32 newOwnerSysId;
|
||||
|
||||
/* check that we are the superuser */
|
||||
if (!superuser())
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
/* lookup the OID of the target relation */
|
||||
rel = relation_openrv(tgtrel, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||
|
||||
/* lookup the sysid of the new owner */
|
||||
newOwnerSysId = get_usesysid(newOwnerName);
|
||||
|
||||
/* do all the actual work */
|
||||
AlterTableOwnerId(myrelid, newOwnerSysId);
|
||||
}
|
||||
|
||||
static void
|
||||
AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId)
|
||||
AlterTableOwner(Oid relationOid, int32 newOwnerSysId)
|
||||
{
|
||||
Relation target_rel;
|
||||
Relation class_rel;
|
||||
|
@ -1629,7 +1594,7 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId)
|
|||
/* For each index, recursively change its ownership */
|
||||
foreach(i, index_oid_list)
|
||||
{
|
||||
AlterTableOwnerId(lfirsti(i), newOwnerSysId);
|
||||
AlterTableOwner(lfirsti(i), newOwnerSysId);
|
||||
}
|
||||
|
||||
freeList(index_oid_list);
|
||||
|
@ -1640,7 +1605,7 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId)
|
|||
/* If it has a toast table, recurse to change its ownership */
|
||||
if (tuple_class->reltoastrelid != InvalidOid)
|
||||
{
|
||||
AlterTableOwnerId(tuple_class->reltoastrelid, newOwnerSysId);
|
||||
AlterTableOwner(tuple_class->reltoastrelid, newOwnerSysId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
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);
|
||||
|
||||
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 */
|
||||
|
@ -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);
|
||||
leftoid = typenameTypeId(typenode1);
|
||||
|
||||
/* Attempt to fetch the right type oid, if specified */
|
||||
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 */
|
||||
|
||||
if (righttype != NULL)
|
||||
{
|
||||
rightoid = TypeGet(righttype, &defined);
|
||||
if (!OidIsValid(rightoid))
|
||||
elog(ERROR, "right type '%s' does not exist", righttype);
|
||||
}
|
||||
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 */
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.71 2002/03/20 19:43:44 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.72 2002/03/29 19:06:06 tgl Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
|
@ -41,6 +41,7 @@
|
|||
#include "access/heapam.h"
|
||||
#include "catalog/catname.h"
|
||||
#include "catalog/heap.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_aggregate.h"
|
||||
#include "catalog/pg_language.h"
|
||||
#include "catalog/pg_operator.h"
|
||||
|
@ -50,13 +51,19 @@
|
|||
#include "fmgr.h"
|
||||
#include "miscadmin.h"
|
||||
#include "optimizer/cost.h"
|
||||
#include "parser/parse_expr.h"
|
||||
#include "parser/parse_func.h"
|
||||
#include "parser/parse_type.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
static Oid findTypeIOFunction(const char *procname, bool isOutput);
|
||||
static char *defGetString(DefElem *def);
|
||||
static double defGetNumeric(DefElem *def);
|
||||
static TypeName *defGetTypeName(DefElem *def);
|
||||
static int defGetTypeLength(DefElem *def);
|
||||
|
||||
#define DEFAULT_TYPDELIM ','
|
||||
|
@ -77,16 +84,59 @@ case_translate_language_name(const char *input, char *output)
|
|||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
compute_return_type(TypeName *returnType,
|
||||
char **prorettype_p, bool *returnsSet_p)
|
||||
{
|
||||
/*
|
||||
* Examine the "returns" clause returnType of the CREATE FUNCTION statement
|
||||
* and return information about it as *prorettype_p and *returnsSet.
|
||||
*
|
||||
* This is more complex than the average typename lookup because we want to
|
||||
* allow a shell type to be used, or even created if the specified return type
|
||||
* doesn't exist yet. (Without this, there's no way to define the I/O procs
|
||||
* for a new type.) But SQL function creation won't cope, so error out if
|
||||
* the target language is SQL.
|
||||
*/
|
||||
*prorettype_p = TypeNameToInternalName(returnType);
|
||||
static void
|
||||
compute_return_type(TypeName *returnType, Oid languageOid,
|
||||
Oid *prorettype_p, bool *returnsSet_p)
|
||||
{
|
||||
Oid rettype;
|
||||
|
||||
rettype = LookupTypeName(returnType);
|
||||
|
||||
if (OidIsValid(rettype))
|
||||
{
|
||||
if (!get_typisdefined(rettype))
|
||||
{
|
||||
if (languageOid == SQLlanguageId)
|
||||
elog(ERROR, "SQL functions cannot return shell types");
|
||||
else
|
||||
elog(WARNING, "Return type \"%s\" is only a shell",
|
||||
TypeNameToString(returnType));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *typnam = TypeNameToString(returnType);
|
||||
|
||||
if (strcmp(typnam, "opaque") == 0)
|
||||
rettype = InvalidOid;
|
||||
else
|
||||
{
|
||||
Oid namespaceId;
|
||||
char *typname;
|
||||
|
||||
if (languageOid == SQLlanguageId)
|
||||
elog(ERROR, "Type \"%s\" does not exist", typnam);
|
||||
elog(WARNING, "ProcedureCreate: type %s is not yet defined",
|
||||
typnam);
|
||||
namespaceId = QualifiedNameGetCreationNamespace(returnType->names,
|
||||
&typname);
|
||||
rettype = TypeShellMake(typname, namespaceId);
|
||||
if (!OidIsValid(rettype))
|
||||
elog(ERROR, "could not create type %s", typnam);
|
||||
}
|
||||
}
|
||||
|
||||
*prorettype_p = rettype;
|
||||
*returnsSet_p = returnType->setof;
|
||||
}
|
||||
|
||||
|
@ -211,34 +261,31 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
|
|||
void
|
||||
CreateFunction(ProcedureStmt *stmt)
|
||||
{
|
||||
/* pathname of executable file that executes this function, if any */
|
||||
char *probin_str;
|
||||
/* SQL that executes this function, if any */
|
||||
char *prosrc_str;
|
||||
/* Type of return value (or member of set of values) from function */
|
||||
char *prorettype;
|
||||
/* name of language of function, with case adjusted */
|
||||
char languageName[NAMEDATALEN];
|
||||
/* The function returns a set of values, as opposed to a singleton. */
|
||||
Oid prorettype;
|
||||
bool returnsSet;
|
||||
/*
|
||||
* The following are optional user-supplied attributes of the
|
||||
* function.
|
||||
*/
|
||||
char languageName[NAMEDATALEN];
|
||||
Oid languageOid;
|
||||
char *funcname;
|
||||
Oid namespaceId;
|
||||
int32 byte_pct,
|
||||
perbyte_cpu,
|
||||
percall_cpu,
|
||||
outin_ratio;
|
||||
bool canCache,
|
||||
isStrict;
|
||||
|
||||
HeapTuple languageTuple;
|
||||
Form_pg_language languageStruct;
|
||||
Oid languageOid;
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname,
|
||||
&funcname);
|
||||
|
||||
/* Convert language name to canonical case */
|
||||
case_translate_language_name(stmt->language, languageName);
|
||||
|
||||
/* Look up the language and validate permissions */
|
||||
languageTuple = SearchSysCache(LANGNAME,
|
||||
PointerGetDatum(languageName),
|
||||
0, 0, 0);
|
||||
|
@ -259,21 +306,22 @@ CreateFunction(ProcedureStmt *stmt)
|
|||
* Convert remaining parameters of CREATE to form wanted by
|
||||
* ProcedureCreate.
|
||||
*/
|
||||
Assert(IsA(stmt->returnType, TypeName));
|
||||
compute_return_type((TypeName *) stmt->returnType,
|
||||
compute_return_type(stmt->returnType, languageOid,
|
||||
&prorettype, &returnsSet);
|
||||
|
||||
compute_full_attributes(stmt->withClause,
|
||||
&byte_pct, &perbyte_cpu, &percall_cpu,
|
||||
&outin_ratio, &canCache, &isStrict);
|
||||
|
||||
interpret_AS_clause(languageOid, languageName, stmt->as, &prosrc_str, &probin_str);
|
||||
interpret_AS_clause(languageOid, languageName, stmt->as,
|
||||
&prosrc_str, &probin_str);
|
||||
|
||||
/*
|
||||
* And now that we have all the parameters, and know we're permitted
|
||||
* to do so, go ahead and create the function.
|
||||
*/
|
||||
ProcedureCreate(stmt->funcname,
|
||||
ProcedureCreate(funcname,
|
||||
namespaceId,
|
||||
stmt->replace,
|
||||
returnsSet,
|
||||
prorettype,
|
||||
|
@ -292,27 +340,28 @@ CreateFunction(ProcedureStmt *stmt)
|
|||
|
||||
|
||||
|
||||
/* --------------------------------
|
||||
/*
|
||||
* DefineOperator
|
||||
*
|
||||
* this function extracts all the information from the
|
||||
* parameter list generated by the parser and then has
|
||||
* OperatorCreate() do all the actual work.
|
||||
*
|
||||
* 'parameters' is a list of DefElem
|
||||
* --------------------------------
|
||||
*/
|
||||
void
|
||||
DefineOperator(char *oprName,
|
||||
List *parameters)
|
||||
DefineOperator(List *names, List *parameters)
|
||||
{
|
||||
char *oprName;
|
||||
Oid oprNamespace;
|
||||
uint16 precedence = 0; /* operator precedence */
|
||||
bool canHash = false; /* operator hashes */
|
||||
bool isLeftAssociative = true; /* operator is left
|
||||
* associative */
|
||||
char *functionName = NULL; /* function for operator */
|
||||
char *typeName1 = NULL; /* first type name */
|
||||
char *typeName2 = NULL; /* second type name */
|
||||
TypeName *typeName1 = NULL; /* first type name */
|
||||
TypeName *typeName2 = NULL; /* second type name */
|
||||
Oid typeId1 = InvalidOid; /* types converted to OID */
|
||||
Oid typeId2 = InvalidOid;
|
||||
char *commutatorName = NULL; /* optional commutator operator
|
||||
* name */
|
||||
char *negatorName = NULL; /* optional negator operator name */
|
||||
|
@ -323,6 +372,9 @@ DefineOperator(char *oprName,
|
|||
char *sortName2 = NULL; /* optional second sort operator */
|
||||
List *pl;
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
|
||||
|
||||
/*
|
||||
* loop over the definition list and extract the information we need.
|
||||
*/
|
||||
|
@ -332,16 +384,14 @@ DefineOperator(char *oprName,
|
|||
|
||||
if (strcasecmp(defel->defname, "leftarg") == 0)
|
||||
{
|
||||
typeName1 = defGetString(defel);
|
||||
if (IsA(defel->arg, TypeName) &&
|
||||
((TypeName *) defel->arg)->setof)
|
||||
typeName1 = defGetTypeName(defel);
|
||||
if (typeName1->setof)
|
||||
elog(ERROR, "setof type not implemented for leftarg");
|
||||
}
|
||||
else if (strcasecmp(defel->defname, "rightarg") == 0)
|
||||
{
|
||||
typeName2 = defGetString(defel);
|
||||
if (IsA(defel->arg, TypeName) &&
|
||||
((TypeName *) defel->arg)->setof)
|
||||
typeName2 = defGetTypeName(defel);
|
||||
if (typeName2->setof)
|
||||
elog(ERROR, "setof type not implemented for rightarg");
|
||||
}
|
||||
else if (strcasecmp(defel->defname, "procedure") == 0)
|
||||
|
@ -367,15 +417,7 @@ DefineOperator(char *oprName,
|
|||
else if (strcasecmp(defel->defname, "hashes") == 0)
|
||||
canHash = TRUE;
|
||||
else if (strcasecmp(defel->defname, "sort1") == 0)
|
||||
{
|
||||
/* ----------------
|
||||
* XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... )
|
||||
* XXX is undocumented in the reference manual source as of
|
||||
* 89/8/22.
|
||||
* ----------------
|
||||
*/
|
||||
sortName1 = defGetString(defel);
|
||||
}
|
||||
else if (strcasecmp(defel->defname, "sort2") == 0)
|
||||
sortName2 = defGetString(defel);
|
||||
else
|
||||
|
@ -391,12 +433,18 @@ DefineOperator(char *oprName,
|
|||
if (functionName == NULL)
|
||||
elog(ERROR, "Define: \"procedure\" unspecified");
|
||||
|
||||
/* Transform type names to type OIDs */
|
||||
if (typeName1)
|
||||
typeId1 = typenameTypeId(typeName1);
|
||||
if (typeName2)
|
||||
typeId2 = typenameTypeId(typeName2);
|
||||
|
||||
/*
|
||||
* now have OperatorCreate do all the work..
|
||||
*/
|
||||
OperatorCreate(oprName, /* operator name */
|
||||
typeName1, /* first type name */
|
||||
typeName2, /* second type name */
|
||||
typeId1, /* left type id */
|
||||
typeId2, /* right type id */
|
||||
functionName, /* function for operator */
|
||||
precedence, /* operator precedence */
|
||||
isLeftAssociative, /* operator is left associative */
|
||||
|
@ -412,20 +460,26 @@ DefineOperator(char *oprName,
|
|||
|
||||
}
|
||||
|
||||
/* -------------------
|
||||
/*
|
||||
* DefineAggregate
|
||||
* ------------------
|
||||
*/
|
||||
void
|
||||
DefineAggregate(char *aggName, List *parameters)
|
||||
DefineAggregate(List *names, List *parameters)
|
||||
{
|
||||
char *aggName;
|
||||
Oid aggNamespace;
|
||||
char *transfuncName = NULL;
|
||||
char *finalfuncName = NULL;
|
||||
char *baseType = NULL;
|
||||
char *transType = NULL;
|
||||
TypeName *baseType = NULL;
|
||||
TypeName *transType = NULL;
|
||||
char *initval = NULL;
|
||||
Oid baseTypeId;
|
||||
Oid transTypeId;
|
||||
List *pl;
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
aggNamespace = QualifiedNameGetCreationNamespace(names, &aggName);
|
||||
|
||||
foreach(pl, parameters)
|
||||
{
|
||||
DefElem *defel = (DefElem *) lfirst(pl);
|
||||
|
@ -441,11 +495,11 @@ DefineAggregate(char *aggName, List *parameters)
|
|||
else if (strcasecmp(defel->defname, "finalfunc") == 0)
|
||||
finalfuncName = defGetString(defel);
|
||||
else if (strcasecmp(defel->defname, "basetype") == 0)
|
||||
baseType = defGetString(defel);
|
||||
baseType = defGetTypeName(defel);
|
||||
else if (strcasecmp(defel->defname, "stype") == 0)
|
||||
transType = defGetString(defel);
|
||||
transType = defGetTypeName(defel);
|
||||
else if (strcasecmp(defel->defname, "stype1") == 0)
|
||||
transType = defGetString(defel);
|
||||
transType = defGetTypeName(defel);
|
||||
else if (strcasecmp(defel->defname, "initcond") == 0)
|
||||
initval = defGetString(defel);
|
||||
else if (strcasecmp(defel->defname, "initcond1") == 0)
|
||||
|
@ -465,14 +519,40 @@ DefineAggregate(char *aggName, List *parameters)
|
|||
if (transfuncName == NULL)
|
||||
elog(ERROR, "Define: \"sfunc\" unspecified");
|
||||
|
||||
/*
|
||||
* Handle the aggregate's base type (input data type). This can be
|
||||
* specified as 'ANY' for a data-independent transition function, such
|
||||
* as COUNT(*).
|
||||
*/
|
||||
baseTypeId = LookupTypeName(baseType);
|
||||
if (OidIsValid(baseTypeId))
|
||||
{
|
||||
/* no need to allow aggregates on as-yet-undefined types */
|
||||
if (!get_typisdefined(baseTypeId))
|
||||
elog(ERROR, "Type \"%s\" is only a shell",
|
||||
TypeNameToString(baseType));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *typnam = TypeNameToString(baseType);
|
||||
|
||||
if (strcasecmp(typnam, "ANY") != 0)
|
||||
elog(ERROR, "Type \"%s\" does not exist", typnam);
|
||||
baseTypeId = InvalidOid;
|
||||
}
|
||||
|
||||
/* handle transtype --- no special cases here */
|
||||
transTypeId = typenameTypeId(transType);
|
||||
|
||||
/*
|
||||
* Most of the argument-checking is done inside of AggregateCreate
|
||||
*/
|
||||
AggregateCreate(aggName, /* aggregate name */
|
||||
aggNamespace, /* namespace */
|
||||
transfuncName, /* step function name */
|
||||
finalfuncName, /* final function name */
|
||||
baseType, /* type of data being aggregated */
|
||||
transType, /* transition data type */
|
||||
baseTypeId, /* type of data being aggregated */
|
||||
transTypeId, /* transition data type */
|
||||
initval); /* initial condition */
|
||||
}
|
||||
|
||||
|
@ -483,12 +563,14 @@ DefineAggregate(char *aggName, List *parameters)
|
|||
void
|
||||
DefineDomain(CreateDomainStmt *stmt)
|
||||
{
|
||||
char *domainName;
|
||||
Oid domainNamespace;
|
||||
int16 internalLength;
|
||||
int16 externalLength;
|
||||
char *inputName;
|
||||
char *outputName;
|
||||
char *sendName;
|
||||
char *receiveName;
|
||||
Oid inputProcedure;
|
||||
Oid outputProcedure;
|
||||
Oid receiveProcedure;
|
||||
Oid sendProcedure;
|
||||
bool byValue;
|
||||
char delimiter;
|
||||
char alignment;
|
||||
|
@ -500,46 +582,27 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||
char *defaultValueBin = NULL;
|
||||
bool typNotNull = false;
|
||||
Oid basetypelem;
|
||||
char *elemName = NULL;
|
||||
int32 typNDims = 0; /* No array dimensions by default */
|
||||
int32 typNDims = length(stmt->typename->arrayBounds);
|
||||
HeapTuple typeTup;
|
||||
char *typeName = stmt->typename->name;
|
||||
List *schema = stmt->constraints;
|
||||
List *listptr;
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname,
|
||||
&domainName);
|
||||
|
||||
/*
|
||||
* Domainnames, unlike typenames don't need to account for the '_'
|
||||
* prefix. So they can be one character longer.
|
||||
*/
|
||||
if (strlen(stmt->domainname) > (NAMEDATALEN - 1))
|
||||
if (strlen(domainName) > (NAMEDATALEN - 1))
|
||||
elog(ERROR, "CREATE DOMAIN: domain names must be %d characters or less",
|
||||
NAMEDATALEN - 1);
|
||||
|
||||
/* Test for existing Domain (or type) of that name */
|
||||
typeTup = SearchSysCache(TYPENAME,
|
||||
PointerGetDatum(stmt->domainname),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(typeTup))
|
||||
elog(ERROR, "CREATE DOMAIN: domain or type %s already exists",
|
||||
stmt->domainname);
|
||||
|
||||
/*
|
||||
* When the type is an array for some reason we don't actually receive
|
||||
* the name here. We receive the base types name. Lets set Dims while
|
||||
* were at it.
|
||||
* Look up the base type.
|
||||
*/
|
||||
if (stmt->typename->arrayBounds > 0) {
|
||||
typeName = makeArrayTypeName(stmt->typename->name);
|
||||
|
||||
typNDims = length(stmt->typename->arrayBounds);
|
||||
}
|
||||
|
||||
typeTup = SearchSysCache(TYPENAME,
|
||||
PointerGetDatum(typeName),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(typeTup))
|
||||
elog(ERROR, "CREATE DOMAIN: type %s does not exist",
|
||||
stmt->typename->name);
|
||||
typeTup = typenameType(stmt->typename);
|
||||
|
||||
/*
|
||||
* What we really don't want is domains of domains. This could cause all sorts
|
||||
|
@ -550,7 +613,7 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||
typtype = ((Form_pg_type) GETSTRUCT(typeTup))->typtype;
|
||||
if (typtype != 'b')
|
||||
elog(ERROR, "DefineDomain: %s is not a basetype",
|
||||
stmt->typename->name);
|
||||
TypeNameToString(stmt->typename));
|
||||
|
||||
/* passed by value */
|
||||
byValue = ((Form_pg_type) GETSTRUCT(typeTup))->typbyval;
|
||||
|
@ -570,43 +633,20 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||
/* Array element Delimiter */
|
||||
delimiter = ((Form_pg_type) GETSTRUCT(typeTup))->typdelim;
|
||||
|
||||
/*
|
||||
* XXX this is pretty bogus: should be passing function OIDs to
|
||||
* TypeCreate, not names which aren't unique.
|
||||
*/
|
||||
|
||||
/* Input Function Name */
|
||||
datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typinput, &isnull);
|
||||
Assert(!isnull);
|
||||
|
||||
inputName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
|
||||
|
||||
/* Output Function Name */
|
||||
datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typoutput, &isnull);
|
||||
Assert(!isnull);
|
||||
|
||||
outputName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
|
||||
|
||||
/* ReceiveName */
|
||||
datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typreceive, &isnull);
|
||||
Assert(!isnull);
|
||||
|
||||
receiveName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
|
||||
|
||||
/* SendName */
|
||||
datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typsend, &isnull);
|
||||
Assert(!isnull);
|
||||
|
||||
sendName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
|
||||
/* I/O Functions */
|
||||
inputProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typinput;
|
||||
outputProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typoutput;
|
||||
receiveProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typreceive;
|
||||
sendProcedure = ((Form_pg_type) GETSTRUCT(typeTup))->typsend;
|
||||
|
||||
/* Inherited default value */
|
||||
datum = SysCacheGetAttr(TYPENAME, typeTup,
|
||||
datum = SysCacheGetAttr(TYPEOID, typeTup,
|
||||
Anum_pg_type_typdefault, &isnull);
|
||||
if (!isnull)
|
||||
defaultValue = DatumGetCString(DirectFunctionCall1(textout, datum));
|
||||
|
||||
/* Inherited default binary value */
|
||||
datum = SysCacheGetAttr(TYPENAME, typeTup,
|
||||
datum = SysCacheGetAttr(TYPEOID, typeTup,
|
||||
Anum_pg_type_typdefaultbin, &isnull);
|
||||
if (!isnull)
|
||||
defaultValueBin = DatumGetCString(DirectFunctionCall1(textout, datum));
|
||||
|
@ -617,16 +657,6 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||
* This is what enables us to make a domain of an array
|
||||
*/
|
||||
basetypelem = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
|
||||
if (basetypelem != InvalidOid)
|
||||
{
|
||||
HeapTuple tup;
|
||||
|
||||
tup = SearchSysCache(TYPEOID,
|
||||
ObjectIdGetDatum(basetypelem),
|
||||
0, 0, 0);
|
||||
elemName = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(tup))->typname));
|
||||
ReleaseSysCache(tup);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run through constraints manually to avoid the additional
|
||||
|
@ -661,14 +691,14 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||
expr = cookDefault(pstate, colDef->raw_expr,
|
||||
typeTup->t_data->t_oid,
|
||||
stmt->typename->typmod,
|
||||
stmt->typename->name);
|
||||
domainName);
|
||||
/*
|
||||
* Expression must be stored as a nodeToString result,
|
||||
* but we also require a valid textual representation
|
||||
* (mainly to make life easier for pg_dump).
|
||||
*/
|
||||
defaultValue = deparse_expression(expr,
|
||||
deparse_context_for(stmt->domainname,
|
||||
deparse_context_for(domainName,
|
||||
InvalidOid),
|
||||
false);
|
||||
defaultValueBin = nodeToString(expr);
|
||||
|
@ -723,19 +753,20 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||
/*
|
||||
* Have TypeCreate do all the real work.
|
||||
*/
|
||||
TypeCreate(stmt->domainname, /* type name */
|
||||
TypeCreate(domainName, /* type name */
|
||||
domainNamespace, /* namespace */
|
||||
InvalidOid, /* preassigned type oid (not done here) */
|
||||
InvalidOid, /* relation oid (n/a here) */
|
||||
internalLength, /* internal size */
|
||||
externalLength, /* external size */
|
||||
'd', /* type-type (domain type) */
|
||||
delimiter, /* array element delimiter */
|
||||
inputName, /* input procedure */
|
||||
outputName, /* output procedure */
|
||||
receiveName, /* receive procedure */
|
||||
sendName, /* send procedure */
|
||||
elemName, /* element type name */
|
||||
typeName, /* base type name */
|
||||
inputProcedure, /* input procedure */
|
||||
outputProcedure, /* output procedure */
|
||||
receiveProcedure, /* receive procedure */
|
||||
sendProcedure, /* send procedure */
|
||||
basetypelem, /* element type ID */
|
||||
typeTup->t_data->t_oid, /* base type ID */
|
||||
defaultValue, /* default type value (text) */
|
||||
defaultValueBin, /* default type value (binary) */
|
||||
byValue, /* passed by value */
|
||||
|
@ -743,7 +774,7 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||
storage, /* TOAST strategy */
|
||||
stmt->typename->typmod, /* typeMod value */
|
||||
typNDims, /* Array dimensions for base type */
|
||||
typNotNull); /* Type NOT NULL */
|
||||
typNotNull); /* Type NOT NULL */
|
||||
|
||||
/*
|
||||
* Now we can clean up.
|
||||
|
@ -756,11 +787,13 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||
* Registers a new type.
|
||||
*/
|
||||
void
|
||||
DefineType(char *typeName, List *parameters)
|
||||
DefineType(List *names, List *parameters)
|
||||
{
|
||||
char *typeName;
|
||||
Oid typeNamespace;
|
||||
int16 internalLength = -1; /* int2 */
|
||||
int16 externalLength = -1; /* int2 */
|
||||
char *elemName = NULL;
|
||||
Oid elemType = InvalidOid;
|
||||
char *inputName = NULL;
|
||||
char *outputName = NULL;
|
||||
char *sendName = NULL;
|
||||
|
@ -768,10 +801,18 @@ DefineType(char *typeName, List *parameters)
|
|||
char *defaultValue = NULL;
|
||||
bool byValue = false;
|
||||
char delimiter = DEFAULT_TYPDELIM;
|
||||
char *shadow_type;
|
||||
List *pl;
|
||||
char alignment = 'i'; /* default alignment */
|
||||
char storage = 'p'; /* default TOAST storage method */
|
||||
Oid inputOid;
|
||||
Oid outputOid;
|
||||
Oid sendOid;
|
||||
Oid receiveOid;
|
||||
char *shadow_type;
|
||||
List *pl;
|
||||
Oid typoid;
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
typeNamespace = QualifiedNameGetCreationNamespace(names, &typeName);
|
||||
|
||||
/*
|
||||
* Type names must be one character shorter than other names, allowing
|
||||
|
@ -796,16 +837,16 @@ DefineType(char *typeName, List *parameters)
|
|||
outputName = defGetString(defel);
|
||||
else if (strcasecmp(defel->defname, "send") == 0)
|
||||
sendName = defGetString(defel);
|
||||
else if (strcasecmp(defel->defname, "receive") == 0)
|
||||
receiveName = defGetString(defel);
|
||||
else if (strcasecmp(defel->defname, "delimiter") == 0)
|
||||
{
|
||||
char *p = defGetString(defel);
|
||||
|
||||
delimiter = p[0];
|
||||
}
|
||||
else if (strcasecmp(defel->defname, "receive") == 0)
|
||||
receiveName = defGetString(defel);
|
||||
else if (strcasecmp(defel->defname, "element") == 0)
|
||||
elemName = defGetString(defel);
|
||||
elemType = typenameTypeId(defGetTypeName(defel));
|
||||
else if (strcasecmp(defel->defname, "default") == 0)
|
||||
defaultValue = defGetString(defel);
|
||||
else if (strcasecmp(defel->defname, "passedbyvalue") == 0)
|
||||
|
@ -867,30 +908,44 @@ DefineType(char *typeName, List *parameters)
|
|||
if (outputName == NULL)
|
||||
elog(ERROR, "Define: \"output\" unspecified");
|
||||
|
||||
/* Convert I/O proc names to OIDs */
|
||||
inputOid = findTypeIOFunction(inputName, false);
|
||||
outputOid = findTypeIOFunction(outputName, true);
|
||||
if (sendName)
|
||||
sendOid = findTypeIOFunction(sendName, true);
|
||||
else
|
||||
sendOid = outputOid;
|
||||
if (receiveName)
|
||||
receiveOid = findTypeIOFunction(receiveName, false);
|
||||
else
|
||||
receiveOid = inputOid;
|
||||
|
||||
/*
|
||||
* now have TypeCreate do all the real work.
|
||||
*/
|
||||
TypeCreate(typeName, /* type name */
|
||||
InvalidOid, /* preassigned type oid (not done here) */
|
||||
InvalidOid, /* relation oid (n/a here) */
|
||||
internalLength, /* internal size */
|
||||
externalLength, /* external size */
|
||||
'b', /* type-type (base type) */
|
||||
delimiter, /* array element delimiter */
|
||||
inputName, /* input procedure */
|
||||
outputName, /* output procedure */
|
||||
receiveName, /* receive procedure */
|
||||
sendName, /* send procedure */
|
||||
elemName, /* element type name */
|
||||
NULL, /* base type name (only for domains) */
|
||||
defaultValue, /* default type value */
|
||||
NULL, /* no binary form available */
|
||||
byValue, /* passed by value */
|
||||
alignment, /* required alignment */
|
||||
storage, /* TOAST strategy */
|
||||
-1, /* typMod (Domains only) */
|
||||
0, /* Array Dimensions of typbasetype */
|
||||
'f'); /* Type NOT NULL */
|
||||
typoid =
|
||||
TypeCreate(typeName, /* type name */
|
||||
typeNamespace, /* namespace */
|
||||
InvalidOid, /* preassigned type oid (not done here) */
|
||||
InvalidOid, /* relation oid (n/a here) */
|
||||
internalLength, /* internal size */
|
||||
externalLength, /* external size */
|
||||
'b', /* type-type (base type) */
|
||||
delimiter, /* array element delimiter */
|
||||
inputOid, /* input procedure */
|
||||
outputOid, /* output procedure */
|
||||
receiveOid, /* receive procedure */
|
||||
sendOid, /* send procedure */
|
||||
elemType, /* element type ID */
|
||||
InvalidOid, /* base type ID (only for domains) */
|
||||
defaultValue, /* default type value */
|
||||
NULL, /* no binary form available */
|
||||
byValue, /* passed by value */
|
||||
alignment, /* required alignment */
|
||||
storage, /* TOAST strategy */
|
||||
-1, /* typMod (Domains only) */
|
||||
0, /* Array Dimensions of typbasetype */
|
||||
false); /* Type NOT NULL */
|
||||
|
||||
/*
|
||||
* When we create a base type (as opposed to a complex type) we need
|
||||
|
@ -902,18 +957,19 @@ DefineType(char *typeName, List *parameters)
|
|||
alignment = (alignment == 'd') ? 'd' : 'i';
|
||||
|
||||
TypeCreate(shadow_type, /* type name */
|
||||
typeNamespace, /* namespace */
|
||||
InvalidOid, /* preassigned type oid (not done here) */
|
||||
InvalidOid, /* relation oid (n/a here) */
|
||||
-1, /* internal size */
|
||||
-1, /* external size */
|
||||
'b', /* type-type (base type) */
|
||||
DEFAULT_TYPDELIM, /* array element delimiter */
|
||||
"array_in", /* input procedure */
|
||||
"array_out", /* output procedure */
|
||||
"array_in", /* receive procedure */
|
||||
"array_out", /* send procedure */
|
||||
typeName, /* element type name */
|
||||
NULL, /* base type name */
|
||||
F_ARRAY_IN, /* input procedure */
|
||||
F_ARRAY_OUT, /* output procedure */
|
||||
F_ARRAY_IN, /* receive procedure */
|
||||
F_ARRAY_OUT, /* send procedure */
|
||||
typoid, /* element type ID */
|
||||
InvalidOid, /* base type ID */
|
||||
NULL, /* never a default type value */
|
||||
NULL, /* binary default isn't sent either */
|
||||
false, /* never passed by value */
|
||||
|
@ -921,11 +977,65 @@ DefineType(char *typeName, List *parameters)
|
|||
'x', /* ARRAY is always toastable */
|
||||
-1, /* typMod (Domains only) */
|
||||
0, /* Array dimensions of typbasetype */
|
||||
'f'); /* Type NOT NULL */
|
||||
false); /* Type NOT NULL */
|
||||
|
||||
pfree(shadow_type);
|
||||
}
|
||||
|
||||
static Oid
|
||||
findTypeIOFunction(const char *procname, bool isOutput)
|
||||
{
|
||||
Oid argList[FUNC_MAX_ARGS];
|
||||
int nargs;
|
||||
Oid procOid;
|
||||
|
||||
/*
|
||||
* First look for a 1-argument func with all argtypes 0. This is
|
||||
* valid for all kinds of procedure.
|
||||
*/
|
||||
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||
|
||||
procOid = GetSysCacheOid(PROCNAME,
|
||||
PointerGetDatum(procname),
|
||||
Int32GetDatum(1),
|
||||
PointerGetDatum(argList),
|
||||
0);
|
||||
|
||||
if (!OidIsValid(procOid))
|
||||
{
|
||||
/*
|
||||
* Alternatively, input procedures may take 3 args (data
|
||||
* value, element OID, atttypmod); the pg_proc argtype
|
||||
* signature is 0,OIDOID,INT4OID. Output procedures may
|
||||
* take 2 args (data value, element OID).
|
||||
*/
|
||||
if (isOutput)
|
||||
{
|
||||
/* output proc */
|
||||
nargs = 2;
|
||||
argList[1] = OIDOID;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* input proc */
|
||||
nargs = 3;
|
||||
argList[1] = OIDOID;
|
||||
argList[2] = INT4OID;
|
||||
}
|
||||
procOid = GetSysCacheOid(PROCNAME,
|
||||
PointerGetDatum(procname),
|
||||
Int32GetDatum(nargs),
|
||||
PointerGetDatum(argList),
|
||||
0);
|
||||
|
||||
if (!OidIsValid(procOid))
|
||||
func_error("TypeCreate", procname, 1, argList, NULL);
|
||||
}
|
||||
|
||||
return procOid;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
defGetString(DefElem *def)
|
||||
{
|
||||
|
@ -951,7 +1061,7 @@ defGetString(DefElem *def)
|
|||
case T_String:
|
||||
return strVal(def->arg);
|
||||
case T_TypeName:
|
||||
return TypeNameToInternalName((TypeName *) def->arg);
|
||||
return TypeNameToString((TypeName *) def->arg);
|
||||
default:
|
||||
elog(ERROR, "Define: cannot interpret argument of \"%s\"",
|
||||
def->defname);
|
||||
|
@ -978,6 +1088,32 @@ defGetNumeric(DefElem *def)
|
|||
return 0; /* keep compiler quiet */
|
||||
}
|
||||
|
||||
static TypeName *
|
||||
defGetTypeName(DefElem *def)
|
||||
{
|
||||
if (def->arg == NULL)
|
||||
elog(ERROR, "Define: \"%s\" requires a parameter",
|
||||
def->defname);
|
||||
switch (nodeTag(def->arg))
|
||||
{
|
||||
case T_TypeName:
|
||||
return (TypeName *) def->arg;
|
||||
case T_String:
|
||||
{
|
||||
/* Allow quoted typename for backwards compatibility */
|
||||
TypeName *n = makeNode(TypeName);
|
||||
|
||||
n->names = makeList1(def->arg);
|
||||
n->typmod = -1;
|
||||
return n;
|
||||
}
|
||||
default:
|
||||
elog(ERROR, "Define: argument of \"%s\" must be a type name",
|
||||
def->defname);
|
||||
}
|
||||
return NULL; /* keep compiler quiet */
|
||||
}
|
||||
|
||||
static int
|
||||
defGetTypeLength(DefElem *def)
|
||||
{
|
||||
|
@ -998,7 +1134,7 @@ defGetTypeLength(DefElem *def)
|
|||
break;
|
||||
case T_TypeName:
|
||||
/* cope if grammar chooses to believe "variable" is a typename */
|
||||
if (strcasecmp(TypeNameToInternalName((TypeName *) def->arg),
|
||||
if (strcasecmp(TypeNameToString((TypeName *) def->arg),
|
||||
"variable") == 0)
|
||||
return -1; /* variable length */
|
||||
break;
|
||||
|
|
|
@ -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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
@ -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)
|
||||
if (length(column->typename->names) == 1)
|
||||
{
|
||||
is_serial = true;
|
||||
column->typename->name = pstrdup("int4");
|
||||
}
|
||||
else if (strcmp(column->typename->name, "bigserial") == 0 ||
|
||||
strcmp(column->typename->name, "serial8") == 0)
|
||||
{
|
||||
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.
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.296 2002/03/22 02:56:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.297 2002/03/29 19:06:10 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
|
@ -53,6 +53,7 @@
|
|||
#include "access/htup.h"
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "nodes/params.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "parser/gramparse.h"
|
||||
|
@ -122,8 +123,6 @@ static void doNegateFloat(Value *v);
|
|||
ResTarget *target;
|
||||
PrivTarget *privtarget;
|
||||
|
||||
DefineStmt *dstmt;
|
||||
RuleStmt *rstmt;
|
||||
InsertStmt *istmt;
|
||||
}
|
||||
|
||||
|
@ -175,7 +174,8 @@ static void doNegateFloat(Value *v);
|
|||
|
||||
%type <str> relation_name, copy_file_name, copy_delimiter, copy_null,
|
||||
database_name, access_method_clause, access_method, attr_name,
|
||||
class, index_name, name, func_name, file_name
|
||||
class, index_name, name, function_name, file_name,
|
||||
func_name, handler_name
|
||||
|
||||
%type <range> qualified_name, OptConstrFromTable
|
||||
|
||||
|
@ -200,8 +200,8 @@ static void doNegateFloat(Value *v);
|
|||
opt_column_list, columnList, opt_name_list,
|
||||
sort_clause, sortby_list, index_params, index_list, name_list,
|
||||
from_clause, from_list, opt_array_bounds, qualified_name_list,
|
||||
expr_list, attrs, opt_attrs, target_list, update_target_list,
|
||||
insert_column_list,
|
||||
any_name, any_name_list, expr_list, dotted_name, attrs,
|
||||
target_list, update_target_list, insert_column_list,
|
||||
def_list, opt_indirection, group_clause, TriggerFuncArgs,
|
||||
select_limit, opt_select_limit
|
||||
|
||||
|
@ -411,10 +411,10 @@ static void doNegateFloat(Value *v);
|
|||
/* Unary Operators */
|
||||
%left AT ZONE /* sets precedence for AT TIME ZONE */
|
||||
%right UMINUS
|
||||
%left '.'
|
||||
%left '[' ']'
|
||||
%left '(' ')'
|
||||
%left TYPECAST
|
||||
%left '.'
|
||||
%%
|
||||
|
||||
/*
|
||||
|
@ -1812,7 +1812,7 @@ IntegerOnly: Iconst
|
|||
*****************************************************************************/
|
||||
|
||||
CreatePLangStmt: CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
|
||||
HANDLER func_name opt_lancompiler
|
||||
HANDLER handler_name opt_lancompiler
|
||||
{
|
||||
CreatePLangStmt *n = makeNode(CreatePLangStmt);
|
||||
n->plname = $5;
|
||||
|
@ -1827,6 +1827,16 @@ opt_trusted: TRUSTED { $$ = TRUE; }
|
|||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
;
|
||||
|
||||
/* This ought to be just func_name, but that causes reduce/reduce conflicts
|
||||
* (CREATE LANGUAGE is the only place where func_name isn't followed by '(').
|
||||
* Work around by using name and dotted_name separately.
|
||||
*/
|
||||
handler_name: name
|
||||
{ $$ = $1; }
|
||||
| dotted_name
|
||||
{ $$ = strVal(lfirst($1)); /* XXX changing soon */ }
|
||||
;
|
||||
|
||||
opt_lancompiler: LANCOMPILER Sconst { $$ = $2; }
|
||||
| /*EMPTY*/ { $$ = ""; }
|
||||
;
|
||||
|
@ -1853,7 +1863,7 @@ opt_procedural: PROCEDURAL { $$ = TRUE; }
|
|||
|
||||
CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
|
||||
qualified_name TriggerForSpec EXECUTE PROCEDURE
|
||||
name '(' TriggerFuncArgs ')'
|
||||
func_name '(' TriggerFuncArgs ')'
|
||||
{
|
||||
CreateTrigStmt *n = makeNode(CreateTrigStmt);
|
||||
n->trigname = $3;
|
||||
|
@ -1877,7 +1887,8 @@ CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
|
|||
| CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
|
||||
qualified_name OptConstrFromTable
|
||||
ConstraintAttributeSpec
|
||||
FOR EACH ROW EXECUTE PROCEDURE name '(' TriggerFuncArgs ')'
|
||||
FOR EACH ROW EXECUTE PROCEDURE
|
||||
func_name '(' TriggerFuncArgs ')'
|
||||
{
|
||||
CreateTrigStmt *n = makeNode(CreateTrigStmt);
|
||||
n->trigname = $4;
|
||||
|
@ -2043,7 +2054,7 @@ DefineStmt: CREATE AGGREGATE func_name definition
|
|||
{
|
||||
DefineStmt *n = makeNode(DefineStmt);
|
||||
n->defType = AGGREGATE;
|
||||
n->defname = $3;
|
||||
n->defnames = makeList1(makeString($3)); /* XXX */
|
||||
n->definition = $4;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
|
@ -2051,15 +2062,15 @@ DefineStmt: CREATE AGGREGATE func_name definition
|
|||
{
|
||||
DefineStmt *n = makeNode(DefineStmt);
|
||||
n->defType = OPERATOR;
|
||||
n->defname = $3;
|
||||
n->defnames = makeList1(makeString($3)); /* XXX */
|
||||
n->definition = $4;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| CREATE TYPE_P name definition
|
||||
| CREATE TYPE_P any_name definition
|
||||
{
|
||||
DefineStmt *n = makeNode(DefineStmt);
|
||||
n->defType = TYPE_P;
|
||||
n->defname = $3;
|
||||
n->defnames = $3;
|
||||
n->definition = $4;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
|
@ -2102,10 +2113,7 @@ def_arg: func_return { $$ = (Node *)$1; }
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* DropStmt needs to use qualified_name_list as many of the objects
|
||||
* are relations or other schema objects (names can be schema-qualified) */
|
||||
|
||||
DropStmt: DROP drop_type qualified_name_list opt_drop_behavior
|
||||
DropStmt: DROP drop_type any_name_list opt_drop_behavior
|
||||
{
|
||||
DropStmt *n = makeNode(DropStmt);
|
||||
n->removeType = $2;
|
||||
|
@ -2124,6 +2132,18 @@ drop_type: TABLE { $$ = DROP_TABLE; }
|
|||
| DOMAIN_P { $$ = DROP_DOMAIN; }
|
||||
;
|
||||
|
||||
any_name_list: any_name
|
||||
{ $$ = makeList1($1); }
|
||||
| any_name_list ',' any_name
|
||||
{ $$ = lappend($1, $3); }
|
||||
;
|
||||
|
||||
any_name: ColId
|
||||
{ $$ = makeList1(makeString($1)); }
|
||||
| dotted_name
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* QUERY:
|
||||
|
@ -2192,7 +2212,7 @@ CommentStmt: COMMENT ON comment_type name IS comment_text
|
|||
n->comment = $10;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| COMMENT ON AGGREGATE name '(' aggr_argtype ')' IS comment_text
|
||||
| COMMENT ON AGGREGATE func_name '(' aggr_argtype ')' IS comment_text
|
||||
{
|
||||
CommentStmt *n = makeNode(CommentStmt);
|
||||
n->objtype = AGGREGATE;
|
||||
|
@ -2203,18 +2223,6 @@ CommentStmt: COMMENT ON comment_type name IS comment_text
|
|||
n->comment = $9;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| COMMENT ON AGGREGATE name aggr_argtype IS comment_text
|
||||
{
|
||||
/* Obsolete syntax, but must support for awhile */
|
||||
CommentStmt *n = makeNode(CommentStmt);
|
||||
n->objtype = AGGREGATE;
|
||||
n->objschema = NULL;
|
||||
n->objname = $4;
|
||||
n->objproperty = NULL;
|
||||
n->objlist = makeList1($5);
|
||||
n->comment = $7;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| COMMENT ON FUNCTION func_name func_args IS comment_text
|
||||
{
|
||||
CommentStmt *n = makeNode(CommentStmt);
|
||||
|
@ -2691,9 +2699,9 @@ ProcedureStmt: CREATE opt_or_replace FUNCTION func_name func_args
|
|||
{
|
||||
ProcedureStmt *n = makeNode(ProcedureStmt);
|
||||
n->replace = $2;
|
||||
n->funcname = $4;
|
||||
n->funcname = makeList1(makeString($4)); /* XXX */
|
||||
n->argTypes = $5;
|
||||
n->returnType = (Node *) $7;
|
||||
n->returnType = $7;
|
||||
n->withClause = $12;
|
||||
n->as = $9;
|
||||
n->language = $11;
|
||||
|
@ -2765,19 +2773,19 @@ func_return: func_type
|
|||
;
|
||||
|
||||
/*
|
||||
* We would like to make the second production here be ColId '.' ColId etc,
|
||||
* We would like to make the second production here be ColId attrs etc,
|
||||
* but that causes reduce/reduce conflicts. type_name is next best choice.
|
||||
*/
|
||||
func_type: Typename
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| type_name '.' ColId '%' TYPE_P
|
||||
| type_name attrs '%' TYPE_P
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = $1;
|
||||
$$->names = lcons(makeString($1), $2);
|
||||
$$->pct_type = true;
|
||||
$$->typmod = -1;
|
||||
$$->attrname = $3;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -2804,15 +2812,7 @@ RemoveAggrStmt: DROP AGGREGATE func_name '(' aggr_argtype ')'
|
|||
{
|
||||
RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
|
||||
n->aggname = $3;
|
||||
n->aggtype = (Node *) $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| DROP AGGREGATE func_name aggr_argtype
|
||||
{
|
||||
/* Obsolete syntax, but must support for awhile */
|
||||
RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
|
||||
n->aggname = $3;
|
||||
n->aggtype = (Node *) $4;
|
||||
n->aggtype = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
@ -3293,7 +3293,7 @@ DropdbStmt: DROP DATABASE database_name
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
CreateDomainStmt: CREATE DOMAIN_P name opt_as Typename ColQualList opt_collate
|
||||
CreateDomainStmt: CREATE DOMAIN_P any_name opt_as Typename ColQualList opt_collate
|
||||
{
|
||||
CreateDomainStmt *n = makeNode(CreateDomainStmt);
|
||||
n->domainname = $3;
|
||||
|
@ -4237,6 +4237,14 @@ opt_array_bounds: opt_array_bounds '[' ']'
|
|||
{ $$ = NIL; }
|
||||
;
|
||||
|
||||
/*
|
||||
* XXX ideally, the production for a qualified typename should be ColId attrs
|
||||
* (there's no obvious reason why the first name should need to be restricted)
|
||||
* and should be an alternative of GenericType (so that it can be used to
|
||||
* specify a type for a literal in AExprConst). However doing either causes
|
||||
* reduce/reduce conflicts that I haven't been able to find a workaround
|
||||
* for. FIXME later.
|
||||
*/
|
||||
SimpleTypename: ConstTypename
|
||||
| ConstInterval opt_interval
|
||||
{
|
||||
|
@ -4249,6 +4257,12 @@ SimpleTypename: ConstTypename
|
|||
$$ = $1;
|
||||
$$->typmod = ((($5 & 0x7FFF) << 16) | $3);
|
||||
}
|
||||
| type_name attrs
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->names = lcons(makeString($1), $2);
|
||||
$$->typmod = -1;
|
||||
}
|
||||
;
|
||||
|
||||
ConstTypename: GenericType
|
||||
|
@ -4260,9 +4274,7 @@ ConstTypename: GenericType
|
|||
|
||||
GenericType: type_name
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = xlateSqlType($1);
|
||||
$$->typmod = -1;
|
||||
$$ = makeTypeName(xlateSqlType($1));
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -4273,32 +4285,25 @@ GenericType: type_name
|
|||
*/
|
||||
Numeric: FLOAT opt_float
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = $2; /* already xlated */
|
||||
$$->typmod = -1;
|
||||
$$ = makeTypeName($2); /* already xlated */
|
||||
}
|
||||
| DOUBLE PRECISION
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = xlateSqlType("float8");
|
||||
$$->typmod = -1;
|
||||
$$ = makeTypeName(xlateSqlType("float8"));
|
||||
}
|
||||
| DECIMAL opt_decimal
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = xlateSqlType("decimal");
|
||||
$$ = makeTypeName(xlateSqlType("decimal"));
|
||||
$$->typmod = $2;
|
||||
}
|
||||
| DEC opt_decimal
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = xlateSqlType("decimal");
|
||||
$$ = makeTypeName(xlateSqlType("decimal"));
|
||||
$$->typmod = $2;
|
||||
}
|
||||
| NUMERIC opt_numeric
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = xlateSqlType("numeric");
|
||||
$$ = makeTypeName(xlateSqlType("numeric"));
|
||||
$$->typmod = $2;
|
||||
}
|
||||
;
|
||||
|
@ -4379,8 +4384,7 @@ opt_decimal: '(' Iconst ',' Iconst ')'
|
|||
*/
|
||||
Bit: bit '(' Iconst ')'
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = $1;
|
||||
$$ = makeTypeName($1);
|
||||
if ($3 < 1)
|
||||
elog(ERROR,"length for type '%s' must be at least 1",
|
||||
$1);
|
||||
|
@ -4391,8 +4395,7 @@ Bit: bit '(' Iconst ')'
|
|||
}
|
||||
| bit
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = $1;
|
||||
$$ = makeTypeName($1);
|
||||
/* bit defaults to bit(1), varbit to no limit */
|
||||
if (strcmp($1, "bit") == 0)
|
||||
$$->typmod = 1;
|
||||
|
@ -4418,8 +4421,19 @@ bit: BIT opt_varying
|
|||
*/
|
||||
Character: character '(' Iconst ')' opt_charset
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = $1;
|
||||
if (($5 != NULL) && (strcmp($5, "sql_text") != 0))
|
||||
{
|
||||
char *type;
|
||||
|
||||
type = palloc(strlen($1) + 1 + strlen($5) + 1);
|
||||
strcpy(type, $1);
|
||||
strcat(type, "_");
|
||||
strcat(type, $5);
|
||||
$1 = xlateSqlType(type);
|
||||
}
|
||||
|
||||
$$ = makeTypeName($1);
|
||||
|
||||
if ($3 < 1)
|
||||
elog(ERROR,"length for type '%s' must be at least 1",
|
||||
$1);
|
||||
|
@ -4433,36 +4447,27 @@ Character: character '(' Iconst ')' opt_charset
|
|||
* truncate where necessary)
|
||||
*/
|
||||
$$->typmod = VARHDRSZ + $3;
|
||||
|
||||
if (($5 != NULL) && (strcmp($5, "sql_text") != 0)) {
|
||||
char *type;
|
||||
|
||||
type = palloc(strlen($$->name) + 1 + strlen($5) + 1);
|
||||
strcpy(type, $$->name);
|
||||
strcat(type, "_");
|
||||
strcat(type, $5);
|
||||
$$->name = xlateSqlType(type);
|
||||
};
|
||||
}
|
||||
| character opt_charset
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = $1;
|
||||
if (($2 != NULL) && (strcmp($2, "sql_text") != 0))
|
||||
{
|
||||
char *type;
|
||||
|
||||
type = palloc(strlen($1) + 1 + strlen($2) + 1);
|
||||
strcpy(type, $1);
|
||||
strcat(type, "_");
|
||||
strcat(type, $2);
|
||||
$1 = xlateSqlType(type);
|
||||
}
|
||||
|
||||
$$ = makeTypeName($1);
|
||||
|
||||
/* char defaults to char(1), varchar to no limit */
|
||||
if (strcmp($1, "bpchar") == 0)
|
||||
$$->typmod = VARHDRSZ + 1;
|
||||
else
|
||||
$$->typmod = -1;
|
||||
|
||||
if (($2 != NULL) && (strcmp($2, "sql_text") != 0)) {
|
||||
char *type;
|
||||
|
||||
type = palloc(strlen($$->name) + 1 + strlen($2) + 1);
|
||||
strcpy(type, $$->name);
|
||||
strcat(type, "_");
|
||||
strcat(type, $2);
|
||||
$$->name = xlateSqlType(type);
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -4488,11 +4493,10 @@ opt_collate: COLLATE ColId { $$ = $2; }
|
|||
|
||||
ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
if ($5)
|
||||
$$->name = xlateSqlType("timestamptz");
|
||||
$$ = makeTypeName(xlateSqlType("timestamptz"));
|
||||
else
|
||||
$$->name = xlateSqlType("timestamp");
|
||||
$$ = makeTypeName(xlateSqlType("timestamp"));
|
||||
/* XXX the timezone field seems to be unused
|
||||
* - thomas 2001-09-06
|
||||
*/
|
||||
|
@ -4504,11 +4508,10 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
|
|||
}
|
||||
| TIMESTAMP opt_timezone_x
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
if ($2)
|
||||
$$->name = xlateSqlType("timestamptz");
|
||||
$$ = makeTypeName(xlateSqlType("timestamptz"));
|
||||
else
|
||||
$$->name = xlateSqlType("timestamp");
|
||||
$$ = makeTypeName(xlateSqlType("timestamp"));
|
||||
/* XXX the timezone field seems to be unused
|
||||
* - thomas 2001-09-06
|
||||
*/
|
||||
|
@ -4524,11 +4527,10 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
|
|||
}
|
||||
| TIME '(' Iconst ')' opt_timezone
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
if ($5)
|
||||
$$->name = xlateSqlType("timetz");
|
||||
$$ = makeTypeName(xlateSqlType("timetz"));
|
||||
else
|
||||
$$->name = xlateSqlType("time");
|
||||
$$ = makeTypeName(xlateSqlType("time"));
|
||||
if (($3 < 0) || ($3 > 13))
|
||||
elog(ERROR,"TIME(%d)%s precision must be between %d and %d",
|
||||
$3, ($5 ? " WITH TIME ZONE": ""), 0, 13);
|
||||
|
@ -4536,11 +4538,10 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
|
|||
}
|
||||
| TIME opt_timezone
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
if ($2)
|
||||
$$->name = xlateSqlType("timetz");
|
||||
$$ = makeTypeName(xlateSqlType("timetz"));
|
||||
else
|
||||
$$->name = xlateSqlType("time");
|
||||
$$ = makeTypeName(xlateSqlType("time"));
|
||||
/* SQL99 specified a default precision of zero.
|
||||
* See comments for timestamp above on why we will
|
||||
* leave this unspecified for now. - thomas 2001-12-07
|
||||
|
@ -4551,9 +4552,7 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x
|
|||
|
||||
ConstInterval: INTERVAL
|
||||
{
|
||||
$$ = makeNode(TypeName);
|
||||
$$->name = xlateSqlType("interval");
|
||||
$$->typmod = -1;
|
||||
$$ = makeTypeName(xlateSqlType("interval"));
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -5161,7 +5160,7 @@ c_expr: columnref
|
|||
| CURRENT_DATE opt_empty_parentheses
|
||||
{
|
||||
/*
|
||||
* Translate as "date('now'::text)".
|
||||
* Translate as "'now'::text::date".
|
||||
*
|
||||
* We cannot use "'now'::date" because coerce_type() will
|
||||
* immediately reduce that to a constant representing
|
||||
|
@ -5174,43 +5173,30 @@ c_expr: columnref
|
|||
* of type-input conversion functions...
|
||||
*/
|
||||
A_Const *s = makeNode(A_Const);
|
||||
TypeName *t = makeNode(TypeName);
|
||||
TypeName *d = makeNode(TypeName);
|
||||
TypeName *d;
|
||||
|
||||
s->val.type = T_String;
|
||||
s->val.val.str = "now";
|
||||
s->typename = t;
|
||||
s->typename = makeTypeName(xlateSqlType("text"));
|
||||
|
||||
t->name = xlateSqlType("text");
|
||||
t->setof = FALSE;
|
||||
t->typmod = -1;
|
||||
|
||||
d->name = xlateSqlType("date");
|
||||
d->setof = FALSE;
|
||||
d->typmod = -1;
|
||||
d = makeTypeName(xlateSqlType("date"));
|
||||
|
||||
$$ = (Node *)makeTypeCast((Node *)s, d);
|
||||
}
|
||||
| CURRENT_TIME opt_empty_parentheses
|
||||
{
|
||||
/*
|
||||
* Translate as "timetz('now'::text)".
|
||||
* Translate as "'now'::text::timetz".
|
||||
* See comments for CURRENT_DATE.
|
||||
*/
|
||||
A_Const *s = makeNode(A_Const);
|
||||
TypeName *t = makeNode(TypeName);
|
||||
TypeName *d = makeNode(TypeName);
|
||||
TypeName *d;
|
||||
|
||||
s->val.type = T_String;
|
||||
s->val.val.str = "now";
|
||||
s->typename = t;
|
||||
s->typename = makeTypeName(xlateSqlType("text"));
|
||||
|
||||
t->name = xlateSqlType("text");
|
||||
t->setof = FALSE;
|
||||
t->typmod = -1;
|
||||
|
||||
d->name = xlateSqlType("timetz");
|
||||
d->setof = FALSE;
|
||||
d = makeTypeName(xlateSqlType("timetz"));
|
||||
/* SQL99 mandates a default precision of zero for TIME
|
||||
* fields in schemas. However, for CURRENT_TIME
|
||||
* let's preserve the microsecond precision we
|
||||
|
@ -5223,23 +5209,17 @@ c_expr: columnref
|
|||
| CURRENT_TIME '(' Iconst ')'
|
||||
{
|
||||
/*
|
||||
* Translate as "timetz('now'::text)".
|
||||
* Translate as "'now'::text::timetz(n)".
|
||||
* See comments for CURRENT_DATE.
|
||||
*/
|
||||
A_Const *s = makeNode(A_Const);
|
||||
TypeName *t = makeNode(TypeName);
|
||||
TypeName *d = makeNode(TypeName);
|
||||
TypeName *d;
|
||||
|
||||
s->val.type = T_String;
|
||||
s->val.val.str = "now";
|
||||
s->typename = t;
|
||||
s->typename = makeTypeName(xlateSqlType("text"));
|
||||
|
||||
t->name = xlateSqlType("text");
|
||||
t->setof = FALSE;
|
||||
t->typmod = -1;
|
||||
|
||||
d->name = xlateSqlType("timetz");
|
||||
d->setof = FALSE;
|
||||
d = makeTypeName(xlateSqlType("timetz"));
|
||||
if (($3 < 0) || ($3 > 13))
|
||||
elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d",
|
||||
$3, 0, 13);
|
||||
|
@ -5250,23 +5230,17 @@ c_expr: columnref
|
|||
| CURRENT_TIMESTAMP opt_empty_parentheses
|
||||
{
|
||||
/*
|
||||
* Translate as "timestamptz('now'::text)".
|
||||
* Translate as "'now'::text::timestamptz".
|
||||
* See comments for CURRENT_DATE.
|
||||
*/
|
||||
A_Const *s = makeNode(A_Const);
|
||||
TypeName *t = makeNode(TypeName);
|
||||
TypeName *d = makeNode(TypeName);
|
||||
TypeName *d;
|
||||
|
||||
s->val.type = T_String;
|
||||
s->val.val.str = "now";
|
||||
s->typename = t;
|
||||
s->typename = makeTypeName(xlateSqlType("text"));
|
||||
|
||||
t->name = xlateSqlType("text");
|
||||
t->setof = FALSE;
|
||||
t->typmod = -1;
|
||||
|
||||
d->name = xlateSqlType("timestamptz");
|
||||
d->setof = FALSE;
|
||||
d = makeTypeName(xlateSqlType("timestamptz"));
|
||||
/* SQL99 mandates a default precision of 6 for timestamp.
|
||||
* Also, that is about as precise as we will get since
|
||||
* we are using a microsecond time interface.
|
||||
|
@ -5279,23 +5253,17 @@ c_expr: columnref
|
|||
| CURRENT_TIMESTAMP '(' Iconst ')'
|
||||
{
|
||||
/*
|
||||
* Translate as "timestamptz('now'::text)".
|
||||
* Translate as "'now'::text::timestamptz(n)".
|
||||
* See comments for CURRENT_DATE.
|
||||
*/
|
||||
A_Const *s = makeNode(A_Const);
|
||||
TypeName *t = makeNode(TypeName);
|
||||
TypeName *d = makeNode(TypeName);
|
||||
TypeName *d;
|
||||
|
||||
s->val.type = T_String;
|
||||
s->val.val.str = "now";
|
||||
s->typename = t;
|
||||
s->typename = makeTypeName(xlateSqlType("text"));
|
||||
|
||||
t->name = xlateSqlType("text");
|
||||
t->setof = FALSE;
|
||||
t->typmod = -1;
|
||||
|
||||
d->name = xlateSqlType("timestamptz");
|
||||
d->setof = FALSE;
|
||||
d = makeTypeName(xlateSqlType("timestamptz"));
|
||||
if (($3 < 0) || ($3 > 13))
|
||||
elog(ERROR,"CURRENT_TIMESTAMP(%d) precision must be between %d and %d",
|
||||
$3, 0, 13);
|
||||
|
@ -5645,24 +5613,24 @@ columnref: relation_name opt_indirection
|
|||
$$->fields = makeList1(makeString($1));
|
||||
$$->indirection = $2;
|
||||
}
|
||||
| relation_name attrs opt_indirection
|
||||
| dotted_name opt_indirection
|
||||
{
|
||||
$$ = makeNode(ColumnRef);
|
||||
$$->fields = lcons(makeString($1), $2);
|
||||
$$->indirection = $3;
|
||||
$$->fields = $1;
|
||||
$$->indirection = $2;
|
||||
}
|
||||
;
|
||||
|
||||
attrs: opt_attrs '.' attr_name
|
||||
{ $$ = lappend($1, makeString($3)); }
|
||||
| opt_attrs '.' '*'
|
||||
{ $$ = lappend($1, makeString("*")); }
|
||||
dotted_name: relation_name attrs
|
||||
{ $$ = lcons(makeString($1), $2); }
|
||||
;
|
||||
|
||||
opt_attrs: /*EMPTY*/
|
||||
{ $$ = NIL; }
|
||||
| opt_attrs '.' attr_name
|
||||
{ $$ = lappend($1, makeString($3)); }
|
||||
attrs: '.' attr_name
|
||||
{ $$ = makeList1(makeString($2)); }
|
||||
| '.' '*'
|
||||
{ $$ = makeList1(makeString("*")); }
|
||||
| '.' attr_name attrs
|
||||
{ $$ = lcons(makeString($2), $3); }
|
||||
;
|
||||
|
||||
opt_empty_parentheses: '(' ')' { $$ = TRUE; }
|
||||
|
@ -5742,11 +5710,11 @@ relation_name: SpecialRuleRelation
|
|||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
qualified_name_list: qualified_name
|
||||
{ $$ = makeList1($1); }
|
||||
{ $$ = makeList1($1); }
|
||||
| qualified_name_list ',' qualified_name
|
||||
{ $$ = lappend($1, $3); }
|
||||
{ $$ = lappend($1, $3); }
|
||||
;
|
||||
|
||||
qualified_name: ColId
|
||||
|
@ -5787,6 +5755,21 @@ class: ColId { $$ = $1; };
|
|||
index_name: ColId { $$ = $1; };
|
||||
file_name: Sconst { $$ = $1; };
|
||||
|
||||
/* func_name will soon return a List ... but not yet */
|
||||
/*
|
||||
func_name: function_name
|
||||
{ $$ = makeList1(makeString($1)); }
|
||||
| dotted_name
|
||||
{ $$ = $1; }
|
||||
;
|
||||
*/
|
||||
func_name: function_name
|
||||
{ $$ = $1; }
|
||||
| dotted_name
|
||||
{ $$ = strVal(lfirst($1)); }
|
||||
;
|
||||
|
||||
|
||||
/* Constants
|
||||
* Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
|
||||
*/
|
||||
|
@ -5867,9 +5850,7 @@ AexprConst: Iconst
|
|||
A_Const *n = makeNode(A_Const);
|
||||
n->val.type = T_String;
|
||||
n->val.val.str = "t";
|
||||
n->typename = makeNode(TypeName);
|
||||
n->typename->name = xlateSqlType("bool");
|
||||
n->typename->typmod = -1;
|
||||
n->typename = makeTypeName(xlateSqlType("bool"));
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| FALSE_P
|
||||
|
@ -5877,9 +5858,7 @@ AexprConst: Iconst
|
|||
A_Const *n = makeNode(A_Const);
|
||||
n->val.type = T_String;
|
||||
n->val.val.str = "f";
|
||||
n->typename = makeNode(TypeName);
|
||||
n->typename->name = xlateSqlType("bool");
|
||||
n->typename->typmod = -1;
|
||||
n->typename = makeTypeName(xlateSqlType("bool"));
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| NULL_P
|
||||
|
@ -5920,7 +5899,7 @@ type_name: IDENT { $$ = $1; }
|
|||
|
||||
/* Function identifier --- names that can be function names.
|
||||
*/
|
||||
func_name: IDENT { $$ = xlateSqlFunc($1); }
|
||||
function_name: IDENT { $$ = xlateSqlFunc($1); }
|
||||
| unreserved_keyword { $$ = xlateSqlFunc($1); }
|
||||
| func_name_keyword { $$ = xlateSqlFunc($1); }
|
||||
;
|
||||
|
@ -6304,6 +6283,7 @@ static Node *
|
|||
makeStringConst(char *str, TypeName *typename)
|
||||
{
|
||||
A_Const *n = makeNode(A_Const);
|
||||
|
||||
n->val.type = T_String;
|
||||
n->val.val.str = str;
|
||||
n->typename = typename;
|
||||
|
@ -6315,12 +6295,10 @@ static Node *
|
|||
makeFloatConst(char *str)
|
||||
{
|
||||
A_Const *n = makeNode(A_Const);
|
||||
TypeName *t = makeNode(TypeName);
|
||||
|
||||
n->val.type = T_Float;
|
||||
n->val.val.str = str;
|
||||
t->name = xlateSqlType("float");
|
||||
t->typmod = -1;
|
||||
n->typename = t;
|
||||
n->typename = makeTypeName(xlateSqlType("float"));
|
||||
|
||||
return (Node *)n;
|
||||
}
|
||||
|
@ -6435,7 +6413,6 @@ makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg)
|
|||
return (Node *) n;
|
||||
}
|
||||
|
||||
|
||||
/* xlateSqlFunc()
|
||||
* Convert alternate function names to internal Postgres functions.
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.79 2002/03/22 02:56:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.80 2002/03/29 19:06:12 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -525,8 +525,15 @@ FigureColnameInternal(Node *node, char **name)
|
|||
case T_A_Const:
|
||||
if (((A_Const *) node)->typename != NULL)
|
||||
{
|
||||
*name = ((A_Const *) node)->typename->name;
|
||||
return 1;
|
||||
List *names = ((A_Const *) node)->typename->names;
|
||||
|
||||
if (names != NIL)
|
||||
{
|
||||
while (lnext(names) != NIL)
|
||||
names = lnext(names);
|
||||
*name = strVal(lfirst(names));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case T_TypeCast:
|
||||
|
@ -536,8 +543,15 @@ FigureColnameInternal(Node *node, char **name)
|
|||
{
|
||||
if (((TypeCast *) node)->typename != NULL)
|
||||
{
|
||||
*name = ((TypeCast *) node)->typename->name;
|
||||
return 1;
|
||||
List *names = ((TypeCast *) node)->typename->names;
|
||||
|
||||
if (names != NIL)
|
||||
{
|
||||
while (lnext(names) != NIL)
|
||||
names = lnext(names);
|
||||
*name = strVal(lfirst(names));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -8,20 +8,250 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.37 2001/10/25 05:49:40 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.38 2002/03/29 19:06:12 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "parser/parser.h"
|
||||
#include "parser/parse_expr.h"
|
||||
#include "parser/parse_type.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
/*
|
||||
* LookupTypeName
|
||||
* Given a TypeName object, get the OID of the referenced type.
|
||||
* Returns InvalidOid if no such type can be found.
|
||||
*
|
||||
* NB: even if the returned OID is not InvalidOid, the type might be
|
||||
* just a shell. Caller should check typisdefined before using the type.
|
||||
*/
|
||||
Oid
|
||||
LookupTypeName(const TypeName *typename)
|
||||
{
|
||||
Oid restype;
|
||||
|
||||
/* Easy if it's an internally generated TypeName */
|
||||
if (typename->names == NIL)
|
||||
return typename->typeid;
|
||||
|
||||
if (typename->pct_type)
|
||||
{
|
||||
/* Handle %TYPE reference to type of an existing field */
|
||||
RangeVar *rel = makeRangeVar(NULL, NULL);
|
||||
char *field = NULL;
|
||||
Oid relid;
|
||||
AttrNumber attnum;
|
||||
|
||||
/* deconstruct the name list */
|
||||
switch (length(typename->names))
|
||||
{
|
||||
case 1:
|
||||
elog(ERROR, "Improper %%TYPE reference (too few dotted names)");
|
||||
break;
|
||||
case 2:
|
||||
rel->relname = strVal(lfirst(typename->names));
|
||||
field = strVal(lsecond(typename->names));
|
||||
break;
|
||||
case 3:
|
||||
rel->schemaname = strVal(lfirst(typename->names));
|
||||
rel->relname = strVal(lsecond(typename->names));
|
||||
field = strVal(lfirst(lnext(lnext(typename->names))));
|
||||
break;
|
||||
case 4:
|
||||
rel->catalogname = strVal(lfirst(typename->names));
|
||||
rel->schemaname = strVal(lsecond(typename->names));
|
||||
rel->relname = strVal(lfirst(lnext(lnext(typename->names))));
|
||||
field = strVal(lfirst(lnext(lnext(lnext(typename->names)))));
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "Improper %%TYPE reference (too many dotted names)");
|
||||
break;
|
||||
}
|
||||
|
||||
/* look up the field */
|
||||
relid = RangeVarGetRelid(rel, false);
|
||||
attnum = get_attnum(relid, field);
|
||||
if (attnum == InvalidAttrNumber)
|
||||
elog(ERROR, "'%s' is not an attribute of class '%s'",
|
||||
field, rel->relname);
|
||||
restype = get_atttype(relid, attnum);
|
||||
|
||||
/* this construct should never have an array indicator */
|
||||
Assert(typename->arrayBounds == NIL);
|
||||
|
||||
/* emit nuisance warning */
|
||||
elog(NOTICE, "%s converted to %s",
|
||||
TypeNameToString(typename), typeidTypeName(restype));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normal reference to a type name */
|
||||
char *catalogname;
|
||||
char *schemaname = NULL;
|
||||
char *typname = NULL;
|
||||
|
||||
/* deconstruct the name list */
|
||||
switch (length(typename->names))
|
||||
{
|
||||
case 1:
|
||||
typname = strVal(lfirst(typename->names));
|
||||
break;
|
||||
case 2:
|
||||
schemaname = strVal(lfirst(typename->names));
|
||||
typname = strVal(lsecond(typename->names));
|
||||
break;
|
||||
case 3:
|
||||
catalogname = strVal(lfirst(typename->names));
|
||||
schemaname = strVal(lsecond(typename->names));
|
||||
typname = strVal(lfirst(lnext(lnext(typename->names))));
|
||||
/*
|
||||
* We check the catalog name and then ignore it.
|
||||
*/
|
||||
if (strcmp(catalogname, DatabaseName) != 0)
|
||||
elog(ERROR, "Cross-database references are not implemented");
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "Improper type name (too many dotted names)");
|
||||
break;
|
||||
}
|
||||
|
||||
/* If an array reference, look up the array type instead */
|
||||
if (typename->arrayBounds != NIL)
|
||||
typname = makeArrayTypeName(typname);
|
||||
|
||||
if (schemaname)
|
||||
{
|
||||
Oid namespaceId;
|
||||
|
||||
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
||||
CStringGetDatum(schemaname),
|
||||
0, 0, 0);
|
||||
if (!OidIsValid(namespaceId))
|
||||
elog(ERROR, "Namespace \"%s\" does not exist",
|
||||
schemaname);
|
||||
restype = GetSysCacheOid(TYPENAMENSP,
|
||||
PointerGetDatum(typname),
|
||||
ObjectIdGetDatum(namespaceId),
|
||||
0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* XXX wrong, should use namespace search */
|
||||
restype = GetSysCacheOid(TYPENAMENSP,
|
||||
PointerGetDatum(typname),
|
||||
ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
|
||||
0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return restype;
|
||||
}
|
||||
|
||||
/*
|
||||
* TypeNameToString
|
||||
* Produce a string representing the name of a TypeName.
|
||||
*
|
||||
* NB: this must work on TypeNames that do not describe any actual type;
|
||||
* it is mostly used for reporting lookup errors.
|
||||
*/
|
||||
char *
|
||||
TypeNameToString(const TypeName *typename)
|
||||
{
|
||||
StringInfoData string;
|
||||
|
||||
initStringInfo(&string);
|
||||
|
||||
if (typename->names != NIL)
|
||||
{
|
||||
/* Emit possibly-qualified name as-is */
|
||||
List *l;
|
||||
|
||||
foreach(l, typename->names)
|
||||
{
|
||||
if (l != typename->names)
|
||||
appendStringInfoChar(&string, '.');
|
||||
appendStringInfo(&string, "%s", strVal(lfirst(l)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Look up internally-specified type */
|
||||
appendStringInfo(&string, "%s", typeidTypeName(typename->typeid));
|
||||
}
|
||||
|
||||
/*
|
||||
* Add decoration as needed, but only for fields considered by
|
||||
* LookupTypeName
|
||||
*/
|
||||
if (typename->pct_type)
|
||||
appendStringInfo(&string, "%%TYPE");
|
||||
|
||||
if (typename->arrayBounds != NIL)
|
||||
appendStringInfo(&string, "[]");
|
||||
|
||||
return string.data;
|
||||
}
|
||||
|
||||
/*
|
||||
* typenameTypeId - given a TypeName, return the type's OID
|
||||
*
|
||||
* This is equivalent to LookupTypeName, except that this will report
|
||||
* a suitable error message if the type cannot be found or is not defined.
|
||||
*/
|
||||
Oid
|
||||
typenameTypeId(const TypeName *typename)
|
||||
{
|
||||
Oid typoid;
|
||||
|
||||
typoid = LookupTypeName(typename);
|
||||
if (!OidIsValid(typoid))
|
||||
elog(ERROR, "Type \"%s\" does not exist",
|
||||
TypeNameToString(typename));
|
||||
if (!get_typisdefined(typoid))
|
||||
elog(ERROR, "Type \"%s\" is only a shell",
|
||||
TypeNameToString(typename));
|
||||
return typoid;
|
||||
}
|
||||
|
||||
/*
|
||||
* typenameType - given a TypeName, return a Type structure
|
||||
*
|
||||
* This is equivalent to typenameTypeId + syscache fetch of Type tuple.
|
||||
* NB: caller must ReleaseSysCache the type tuple when done with it.
|
||||
*/
|
||||
Type
|
||||
typenameType(const TypeName *typename)
|
||||
{
|
||||
Oid typoid;
|
||||
HeapTuple tup;
|
||||
|
||||
typoid = LookupTypeName(typename);
|
||||
if (!OidIsValid(typoid))
|
||||
elog(ERROR, "Type \"%s\" does not exist",
|
||||
TypeNameToString(typename));
|
||||
tup = SearchSysCache(TYPEOID,
|
||||
ObjectIdGetDatum(typoid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tup))
|
||||
elog(ERROR, "Type \"%s\" does not exist",
|
||||
TypeNameToString(typename));
|
||||
if (! ((Form_pg_type) GETSTRUCT(tup))->typisdefined)
|
||||
elog(ERROR, "Type \"%s\" is only a shell",
|
||||
TypeNameToString(typename));
|
||||
return (Type) tup;
|
||||
}
|
||||
|
||||
/* check to see if a type id is valid,
|
||||
* returns true if it is. By using this call before calling
|
||||
* typeidType or typeidTypeName, more meaningful error messages
|
||||
|
@ -51,24 +281,6 @@ typeidType(Oid id)
|
|||
return (Type) tup;
|
||||
}
|
||||
|
||||
/* return a Type structure, given type name */
|
||||
/* NB: caller must ReleaseSysCache the type tuple when done with it */
|
||||
Type
|
||||
typenameType(char *s)
|
||||
{
|
||||
HeapTuple tup;
|
||||
|
||||
if (s == NULL)
|
||||
elog(ERROR, "typenameType: Null typename");
|
||||
|
||||
tup = SearchSysCache(TYPENAME,
|
||||
PointerGetDatum(s),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tup))
|
||||
elog(ERROR, "Unable to locate type name '%s' in catalog", s);
|
||||
return (Type) tup;
|
||||
}
|
||||
|
||||
/* given type (as type struct), return the type OID */
|
||||
Oid
|
||||
typeTypeId(Type tp)
|
||||
|
@ -207,6 +419,7 @@ typeidOutfunc(Oid type_id)
|
|||
#endif
|
||||
|
||||
/* return a type name, given a typeid */
|
||||
/* nb: type name is NOT unique; use this only for error messages */
|
||||
char *
|
||||
typeidTypeName(Oid id)
|
||||
{
|
||||
|
@ -251,18 +464,6 @@ typeidTypeRelid(Oid type_id)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* given a type name, return the type's typeid */
|
||||
Oid
|
||||
typenameTypeId(char *s)
|
||||
{
|
||||
Type typ = typenameType(s);
|
||||
Oid result;
|
||||
|
||||
result = typ->t_data->t_oid;
|
||||
ReleaseSysCache(typ);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a string that is supposed to be a SQL-compatible type declaration,
|
||||
* such as "int4" or "integer" or "character varying(32)", parse
|
||||
|
@ -327,7 +528,7 @@ parseTypeString(const char *str, Oid *type_id, int32 *typmod)
|
|||
!IsA(typename, TypeName))
|
||||
elog(ERROR, "Invalid type name '%s'", str);
|
||||
|
||||
*type_id = typenameTypeId(TypeNameToInternalName(typename));
|
||||
*type_id = typenameTypeId(typename);
|
||||
*typmod = typename->typmod;
|
||||
|
||||
pfree(buf);
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.140 2002/03/26 19:16:03 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.141 2002/03/29 19:06:13 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -38,13 +38,16 @@
|
|||
#include "commands/variable.h"
|
||||
#include "commands/view.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "parser/parse.h"
|
||||
#include "parser/parse_clause.h"
|
||||
#include "parser/parse_expr.h"
|
||||
#include "parser/parse_type.h"
|
||||
#include "rewrite/rewriteDefine.h"
|
||||
#include "rewrite/rewriteRemove.h"
|
||||
#include "tcop/utility.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "utils/temprel.h"
|
||||
#include "access/xlog.h"
|
||||
|
@ -280,45 +283,48 @@ ProcessUtility(Node *parsetree,
|
|||
|
||||
foreach(arg, stmt->objects)
|
||||
{
|
||||
RangeVar *rel = (RangeVar *) lfirst(arg);
|
||||
|
||||
relname = rel->relname;
|
||||
List *names = (List *) lfirst(arg);
|
||||
RangeVar *rel;
|
||||
|
||||
switch (stmt->removeType)
|
||||
{
|
||||
case DROP_TABLE:
|
||||
rel = makeRangeVarFromNameList(names);
|
||||
CheckDropPermissions(rel, RELKIND_RELATION);
|
||||
RemoveRelation(relname);
|
||||
RemoveRelation(rel);
|
||||
break;
|
||||
|
||||
case DROP_SEQUENCE:
|
||||
rel = makeRangeVarFromNameList(names);
|
||||
CheckDropPermissions(rel, RELKIND_SEQUENCE);
|
||||
RemoveRelation(relname);
|
||||
RemoveRelation(rel);
|
||||
break;
|
||||
|
||||
case DROP_VIEW:
|
||||
rel = makeRangeVarFromNameList(names);
|
||||
CheckDropPermissions(rel, RELKIND_VIEW);
|
||||
RemoveView(relname);
|
||||
RemoveView(rel);
|
||||
break;
|
||||
|
||||
case DROP_INDEX:
|
||||
rel = makeRangeVarFromNameList(names);
|
||||
CheckDropPermissions(rel, RELKIND_INDEX);
|
||||
RemoveIndex(rel);
|
||||
break;
|
||||
|
||||
case DROP_RULE:
|
||||
/* RemoveRewriteRule checks permissions */
|
||||
RemoveRewriteRule(relname);
|
||||
RemoveRewriteRule(names);
|
||||
break;
|
||||
|
||||
case DROP_TYPE:
|
||||
/* RemoveType does its own permissions checks */
|
||||
RemoveType(relname);
|
||||
RemoveType(names);
|
||||
break;
|
||||
|
||||
case DROP_DOMAIN:
|
||||
/* RemoveDomain does its own permissions checks */
|
||||
RemoveDomain(relname, stmt->behavior);
|
||||
RemoveDomain(names, stmt->behavior);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -334,16 +340,15 @@ ProcessUtility(Node *parsetree,
|
|||
|
||||
case T_TruncateStmt:
|
||||
{
|
||||
relname = ((TruncateStmt *) parsetree)->relation->relname;
|
||||
TruncateRelation(relname);
|
||||
TruncateStmt *stmt = (TruncateStmt *) parsetree;
|
||||
|
||||
TruncateRelation(stmt->relation);
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CommentStmt:
|
||||
{
|
||||
CommentStmt *stmt;
|
||||
|
||||
stmt = ((CommentStmt *) parsetree);
|
||||
CommentStmt *stmt = (CommentStmt *) parsetree;
|
||||
|
||||
CommentObject(stmt->objtype, stmt->objschema, stmt->objname,
|
||||
stmt->objproperty, stmt->objlist, stmt->comment);
|
||||
|
@ -357,7 +362,7 @@ ProcessUtility(Node *parsetree,
|
|||
if (stmt->direction != FROM)
|
||||
SetQuerySnapshot();
|
||||
|
||||
DoCopy(stmt->relation->relname,
|
||||
DoCopy(stmt->relation,
|
||||
stmt->binary,
|
||||
stmt->oids,
|
||||
(bool) (stmt->direction == FROM),
|
||||
|
@ -408,7 +413,7 @@ ProcessUtility(Node *parsetree,
|
|||
/*
|
||||
* rename attribute
|
||||
*/
|
||||
renameatt(relname, /* relname */
|
||||
renameatt(RangeVarGetRelid(stmt->relation, false), /* relation */
|
||||
stmt->column, /* old att name */
|
||||
stmt->newname, /* new att name */
|
||||
interpretInhOption(stmt->relation->inhOpt)); /* recursive? */
|
||||
|
@ -429,38 +434,63 @@ ProcessUtility(Node *parsetree,
|
|||
switch (stmt->subtype)
|
||||
{
|
||||
case 'A': /* ADD COLUMN */
|
||||
AlterTableAddColumn(stmt->relation->relname,
|
||||
interpretInhOption((stmt->relation)->inhOpt),
|
||||
/*
|
||||
* Recursively add column to table and,
|
||||
* if requested, to descendants
|
||||
*/
|
||||
AlterTableAddColumn(RangeVarGetRelid(stmt->relation, false),
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
(ColumnDef *) stmt->def);
|
||||
break;
|
||||
case 'T': /* ALTER COLUMN DEFAULT */
|
||||
AlterTableAlterColumnDefault(stmt->relation->relname,
|
||||
interpretInhOption((stmt->relation)->inhOpt),
|
||||
/*
|
||||
* Recursively alter column default for table and,
|
||||
* if requested, for descendants
|
||||
*/
|
||||
AlterTableAlterColumnDefault(RangeVarGetRelid(stmt->relation, false),
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
stmt->name,
|
||||
stmt->def);
|
||||
break;
|
||||
case 'S': /* ALTER COLUMN STATISTICS */
|
||||
case 'M': /* ALTER COLUMN STORAGE */
|
||||
AlterTableAlterColumnFlags(stmt->relation->relname,
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
stmt->name,
|
||||
stmt->def,
|
||||
&(stmt->subtype));
|
||||
/*
|
||||
* Recursively alter column statistics for table and,
|
||||
* if requested, for descendants
|
||||
*/
|
||||
AlterTableAlterColumnFlags(RangeVarGetRelid(stmt->relation, false),
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
stmt->name,
|
||||
stmt->def,
|
||||
&(stmt->subtype));
|
||||
break;
|
||||
case 'D': /* DROP COLUMN */
|
||||
AlterTableDropColumn(stmt->relation->relname,
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
/*
|
||||
* XXX We don't actually recurse yet, but what we should do would be:
|
||||
* Recursively drop column from table and,
|
||||
* if requested, from descendants
|
||||
*/
|
||||
AlterTableDropColumn(RangeVarGetRelid(stmt->relation, false),
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
stmt->name,
|
||||
stmt->behavior);
|
||||
break;
|
||||
case 'C': /* ADD CONSTRAINT */
|
||||
AlterTableAddConstraint(stmt->relation->relname,
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
/*
|
||||
* Recursively add constraint to table and,
|
||||
* if requested, to descendants
|
||||
*/
|
||||
AlterTableAddConstraint(RangeVarGetRelid(stmt->relation, false),
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
(List *) stmt->def);
|
||||
break;
|
||||
case 'X': /* DROP CONSTRAINT */
|
||||
AlterTableDropConstraint(stmt->relation->relname,
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
/*
|
||||
* Recursively drop constraint from table and,
|
||||
* if requested, from descendants
|
||||
*/
|
||||
AlterTableDropConstraint(RangeVarGetRelid(stmt->relation, false),
|
||||
interpretInhOption(stmt->relation->inhOpt),
|
||||
stmt->name,
|
||||
stmt->behavior);
|
||||
break;
|
||||
|
@ -469,8 +499,12 @@ ProcessUtility(Node *parsetree,
|
|||
false);
|
||||
break;
|
||||
case 'U': /* ALTER OWNER */
|
||||
AlterTableOwner(stmt->relation,
|
||||
stmt->name);
|
||||
/* check that we are the superuser */
|
||||
if (!superuser())
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
/* get_usesysid raises an error if no such user */
|
||||
AlterTableOwner(RangeVarGetRelid(stmt->relation, false),
|
||||
get_usesysid(stmt->name));
|
||||
break;
|
||||
default: /* oops */
|
||||
elog(ERROR, "T_AlterTableStmt: unknown subtype");
|
||||
|
@ -500,15 +534,13 @@ ProcessUtility(Node *parsetree,
|
|||
switch (stmt->defType)
|
||||
{
|
||||
case OPERATOR:
|
||||
DefineOperator(stmt->defname, /* operator name */
|
||||
stmt->definition); /* rest */
|
||||
DefineOperator(stmt->defnames, stmt->definition);
|
||||
break;
|
||||
case TYPE_P:
|
||||
DefineType(stmt->defname, stmt->definition);
|
||||
DefineType(stmt->defnames, stmt->definition);
|
||||
break;
|
||||
case AGGREGATE:
|
||||
DefineAggregate(stmt->defname, /* aggregate name */
|
||||
stmt->definition); /* rest */
|
||||
DefineAggregate(stmt->defnames, stmt->definition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +550,7 @@ ProcessUtility(Node *parsetree,
|
|||
{
|
||||
ViewStmt *stmt = (ViewStmt *) parsetree;
|
||||
|
||||
DefineView(stmt->view->relname, stmt->query); /* retrieve parsetree */
|
||||
DefineView(stmt->view, stmt->query);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -554,12 +586,8 @@ ProcessUtility(Node *parsetree,
|
|||
case T_RemoveAggrStmt:
|
||||
{
|
||||
RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
|
||||
char *typename = (char *) NULL;
|
||||
|
||||
if (stmt->aggtype != NULL)
|
||||
typename = TypeNameToInternalName((TypeName *) stmt->aggtype);
|
||||
|
||||
RemoveAggregate(stmt->aggname, typename);
|
||||
RemoveAggregate(stmt->aggname, stmt->aggtype);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -576,15 +604,8 @@ ProcessUtility(Node *parsetree,
|
|||
RemoveOperStmt *stmt = (RemoveOperStmt *) parsetree;
|
||||
TypeName *typenode1 = (TypeName *) lfirst(stmt->args);
|
||||
TypeName *typenode2 = (TypeName *) lsecond(stmt->args);
|
||||
char *typename1 = (char *) NULL;
|
||||
char *typename2 = (char *) NULL;
|
||||
|
||||
if (typenode1 != NULL)
|
||||
typename1 = TypeNameToInternalName(typenode1);
|
||||
if (typenode2 != NULL)
|
||||
typename2 = TypeNameToInternalName(typenode2);
|
||||
|
||||
RemoveOperator(stmt->opname, typename1, typename2);
|
||||
RemoveOperator(stmt->opname, typenode1, typenode2);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.40 2002/02/18 23:11:23 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.41 2002/03/29 19:06:14 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -21,6 +21,7 @@
|
|||
#include "catalog/catname.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_language.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "executor/executor.h"
|
||||
#include "utils/fcache.h"
|
||||
|
@ -36,7 +37,7 @@
|
|||
* in pg_proc.
|
||||
*/
|
||||
Oid
|
||||
SetDefine(char *querystr, char *typename)
|
||||
SetDefine(char *querystr, Oid elemType)
|
||||
{
|
||||
Oid setoid;
|
||||
char *procname = GENERICSETNAME;
|
||||
|
@ -52,9 +53,10 @@ SetDefine(char *querystr, char *typename)
|
|||
char repl[Natts_pg_proc];
|
||||
|
||||
setoid = ProcedureCreate(procname, /* changed below, after oid known */
|
||||
PG_CATALOG_NAMESPACE, /* XXX wrong */
|
||||
false, /* don't replace */
|
||||
true, /* returnsSet */
|
||||
typename, /* returnTypeName */
|
||||
elemType, /* returnType */
|
||||
SQLlanguageId, /* language */
|
||||
querystr, /* sourceCode */
|
||||
fileName, /* fileName */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.66 2002/03/26 19:16:09 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.67 2002/03/29 19:06:15 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Eventually, the index information should go through here, too.
|
||||
|
@ -738,6 +738,33 @@ get_rel_type_id(Oid relid)
|
|||
|
||||
/* ---------- TYPE CACHE ---------- */
|
||||
|
||||
/*
|
||||
* get_typisdefined
|
||||
*
|
||||
* Given the type OID, determine whether the type is defined
|
||||
* (if not, it's only a shell).
|
||||
*/
|
||||
bool
|
||||
get_typisdefined(Oid typid)
|
||||
{
|
||||
HeapTuple tp;
|
||||
|
||||
tp = SearchSysCache(TYPEOID,
|
||||
ObjectIdGetDatum(typid),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(tp))
|
||||
{
|
||||
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
|
||||
bool result;
|
||||
|
||||
result = typtup->typisdefined;
|
||||
ReleaseSysCache(tp);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_typlen
|
||||
*
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.70 2002/03/26 19:16:14 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.71 2002/03/29 19:06:15 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* These routines allow the parser/planner/executor to perform
|
||||
|
@ -384,13 +384,13 @@ static const struct cachedesc cacheinfo[] = {
|
|||
0,
|
||||
0
|
||||
}},
|
||||
{TypeRelationName, /* TYPENAME */
|
||||
TypeNameIndex,
|
||||
{TypeRelationName, /* TYPENAMENSP */
|
||||
TypeNameNspIndex,
|
||||
Anum_pg_type_typrelid,
|
||||
1,
|
||||
2,
|
||||
{
|
||||
Anum_pg_type_typname,
|
||||
0,
|
||||
Anum_pg_type_typnamespace,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
|
@ -515,7 +515,7 @@ SearchSysCache(int cacheId,
|
|||
* when sought. This is a kluge ... temp table substitution should be
|
||||
* happening at a higher level ...
|
||||
*/
|
||||
if (cacheId == RELNAMENSP || cacheId == TYPENAME)
|
||||
if (cacheId == RELNAMENSP || cacheId == TYPENAMENSP)
|
||||
{
|
||||
char *nontemp_relname;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.35 2001/03/22 03:59:58 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.36 2002/03/29 19:06:16 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -227,13 +227,7 @@ remove_all_temp_relations(void)
|
|||
continue; /* ignore it if deleted already */
|
||||
|
||||
if (temp_rel->relkind != RELKIND_INDEX)
|
||||
{
|
||||
char relname[NAMEDATALEN];
|
||||
|
||||
/* safe from deallocation */
|
||||
strcpy(relname, NameStr(temp_rel->user_relname));
|
||||
heap_drop_with_catalog(relname, allowSystemTableMods);
|
||||
}
|
||||
heap_drop_with_catalog(temp_rel->relid, allowSystemTableMods);
|
||||
else
|
||||
index_drop(temp_rel->relid);
|
||||
/* advance cmd counter to make catalog changes visible */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: tupdesc.h,v 1.33 2001/11/05 17:46:31 momjian Exp $
|
||||
* $Id: tupdesc.h,v 1.34 2002/03/29 19:06:16 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -65,7 +65,7 @@ extern void FreeTupleDesc(TupleDesc tupdesc);
|
|||
|
||||
extern bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2);
|
||||
|
||||
extern bool TupleDescInitEntry(TupleDesc desc,
|
||||
extern void TupleDescInitEntry(TupleDesc desc,
|
||||
AttrNumber attributeNumber,
|
||||
char *attributeName,
|
||||
Oid oidtypeid,
|
||||
|
@ -73,6 +73,6 @@ extern bool TupleDescInitEntry(TupleDesc desc,
|
|||
int attdim,
|
||||
bool attisset);
|
||||
|
||||
extern TupleDesc BuildDescForRelation(List *schema, char *relname);
|
||||
extern TupleDesc BuildDescForRelation(List *schema);
|
||||
|
||||
#endif /* TUPDESC_H */
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: catversion.h,v 1.111 2002/03/26 19:16:22 tgl Exp $
|
||||
* $Id: catversion.h,v 1.112 2002/03/29 19:06:17 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -53,6 +53,6 @@
|
|||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 200203251
|
||||
#define CATALOG_VERSION_NO 200203261
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: heap.h,v 1.47 2002/03/26 19:16:23 tgl Exp $
|
||||
* $Id: heap.h,v 1.48 2002/03/29 19:06:17 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -39,10 +39,9 @@ extern Oid heap_create_with_catalog(char *relname, Oid relnamespace,
|
|||
char relkind, bool relhasoids, bool istemp,
|
||||
bool allow_system_table_mods);
|
||||
|
||||
extern void heap_drop_with_catalog(const char *relname,
|
||||
bool allow_system_table_mods);
|
||||
extern void heap_drop_with_catalog(Oid rid, bool allow_system_table_mods);
|
||||
|
||||
extern void heap_truncate(const char *relname);
|
||||
extern void heap_truncate(Oid rid);
|
||||
|
||||
extern void AddRelationRawConstraints(Relation rel,
|
||||
List *rawColDefaults,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: indexing.h,v 1.59 2002/03/26 19:16:26 tgl Exp $
|
||||
* $Id: indexing.h,v 1.60 2002/03/29 19:06:17 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -89,7 +89,7 @@
|
|||
#define TriggerConstrRelidIndex "pg_trigger_tgconstrrelid_index"
|
||||
#define TriggerRelidIndex "pg_trigger_tgrelid_index"
|
||||
#define TriggerOidIndex "pg_trigger_oid_index"
|
||||
#define TypeNameIndex "pg_type_typname_index"
|
||||
#define TypeNameNspIndex "pg_type_typname_nsp_index"
|
||||
#define TypeOidIndex "pg_type_oid_index"
|
||||
|
||||
/* Arrays of names of indices for each system catalog */
|
||||
|
@ -189,7 +189,7 @@ DECLARE_INDEX(pg_trigger_tgconstrrelid_index on pg_trigger using btree(tgconstrr
|
|||
DECLARE_INDEX(pg_trigger_tgrelid_index on pg_trigger using btree(tgrelid oid_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_trigger_oid_index on pg_trigger using btree(oid oid_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_type_oid_index on pg_type using btree(oid oid_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_type_typname_index on pg_type using btree(typname name_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index on pg_type using btree(typname name_ops, typnamespace oid_ops));
|
||||
|
||||
/* last step of initialization script: build the indices declared above */
|
||||
BUILD_INDICES
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: namespace.h,v 1.1 2002/03/26 19:16:28 tgl Exp $
|
||||
* $Id: namespace.h,v 1.2 2002/03/29 19:06:18 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -23,4 +23,8 @@ extern Oid RangeVarGetCreationNamespace(const RangeVar *newRelation);
|
|||
|
||||
extern Oid RelnameGetRelid(const char *relname);
|
||||
|
||||
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
|
||||
|
||||
extern RangeVar *makeRangeVarFromNameList(List *names);
|
||||
|
||||
#endif /* NAMESPACE_H */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_aggregate.h,v 1.35 2001/11/05 17:46:32 momjian Exp $
|
||||
* $Id: pg_aggregate.h,v 1.36 2002/03/29 19:06:18 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
|
@ -155,12 +155,13 @@ DATA(insert OID = 0 ( stddev PGUID numeric_accum numeric_stddev 1700 1231 1700
|
|||
/*
|
||||
* prototypes for functions in pg_aggregate.c
|
||||
*/
|
||||
extern void AggregateCreate(char *aggName,
|
||||
char *aggtransfnName,
|
||||
char *aggfinalfnName,
|
||||
char *aggbasetypeName,
|
||||
char *aggtranstypeName,
|
||||
char *agginitval);
|
||||
extern void AggregateCreate(const char *aggName,
|
||||
Oid aggNamespace,
|
||||
char *aggtransfnName,
|
||||
char *aggfinalfnName,
|
||||
Oid aggBaseType,
|
||||
Oid aggTransType,
|
||||
const char *agginitval);
|
||||
|
||||
extern Datum AggNameGetInitVal(char *aggName, Oid basetype,
|
||||
bool *isNull);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_attribute.h,v 1.86 2002/03/26 19:16:29 tgl Exp $
|
||||
* $Id: pg_attribute.h,v 1.87 2002/03/29 19:06:18 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
|
@ -225,51 +225,53 @@ typedef FormData_pg_attribute *Form_pg_attribute;
|
|||
*/
|
||||
#define Schema_pg_type \
|
||||
{ 1247, {"typname"}, 19, DEFAULT_ATTSTATTARGET, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typowner"}, 23, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typlen"}, 21, 0, 2, 3, 0, -1, -1, true, 'p', false, 's', false, false }, \
|
||||
{ 1247, {"typprtlen"}, 21, 0, 2, 4, 0, -1, -1, true, 'p', false, 's', false, false }, \
|
||||
{ 1247, {"typbyval"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typtype"}, 18, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typisdefined"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typdelim"}, 18, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typrelid"}, 26, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typelem"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typinput"}, 24, 0, 4, 11, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typoutput"}, 24, 0, 4, 12, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typreceive"}, 24, 0, 4, 13, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typsend"}, 24, 0, 4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typalign"}, 18, 0, 1, 15, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typstorage"}, 18, 0, 1, 16, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typnotnull"}, 16, 0, 1, 17, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typbasetype"}, 26, 0, 4, 18, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typtypmod"}, 23, 0, 4, 19, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typndims"}, 23, 0, 4, 20, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typdefaultbin"}, 25, 0, -1, 21, 0, -1, -1, false, 'x', false, 'i', false, false }, \
|
||||
{ 1247, {"typdefault"}, 25, 0, -1, 22, 0, -1, -1, false, 'x', false, 'i', false, false }
|
||||
{ 1247, {"typnamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typlen"}, 21, 0, 2, 4, 0, -1, -1, true, 'p', false, 's', false, false }, \
|
||||
{ 1247, {"typprtlen"}, 21, 0, 2, 5, 0, -1, -1, true, 'p', false, 's', false, false }, \
|
||||
{ 1247, {"typbyval"}, 16, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typtype"}, 18, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typisdefined"}, 16, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typdelim"}, 18, 0, 1, 9, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typrelid"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typelem"}, 26, 0, 4, 11, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typinput"}, 24, 0, 4, 12, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typoutput"}, 24, 0, 4, 13, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typreceive"}, 24, 0, 4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typsend"}, 24, 0, 4, 15, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typalign"}, 18, 0, 1, 16, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typstorage"}, 18, 0, 1, 17, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typnotnull"}, 16, 0, 1, 18, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||
{ 1247, {"typbasetype"}, 26, 0, 4, 19, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typtypmod"}, 23, 0, 4, 20, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typndims"}, 23, 0, 4, 21, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||
{ 1247, {"typdefaultbin"}, 25, 0, -1, 22, 0, -1, -1, false, 'x', false, 'i', false, false }, \
|
||||
{ 1247, {"typdefault"}, 25, 0, -1, 23, 0, -1, -1, false, 'x', false, 'i', false, false }
|
||||
|
||||
|
||||
DATA(insert ( 1247 typname 19 DEFAULT_ATTSTATTARGET NAMEDATALEN 1 0 -1 -1 f p f i f f));
|
||||
DATA(insert ( 1247 typowner 23 0 4 2 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typlen 21 0 2 3 0 -1 -1 t p f s f f));
|
||||
DATA(insert ( 1247 typprtlen 21 0 2 4 0 -1 -1 t p f s f f));
|
||||
DATA(insert ( 1247 typbyval 16 0 1 5 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typtype 18 0 1 6 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typisdefined 16 0 1 7 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typdelim 18 0 1 8 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typrelid 26 0 4 9 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typelem 26 0 4 10 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typinput 24 0 4 11 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typoutput 24 0 4 12 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typreceive 24 0 4 13 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typsend 24 0 4 14 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typalign 18 0 1 15 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typstorage 18 0 1 16 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typnotnull 16 0 1 17 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typbasetype 26 0 4 18 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typtypmod 23 0 4 19 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typndims 23 0 4 20 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typdefaultbin 25 0 -1 21 0 -1 -1 f x f i f f));
|
||||
DATA(insert ( 1247 typdefault 25 0 -1 22 0 -1 -1 f x f i f f));
|
||||
DATA(insert ( 1247 typnamespace 26 0 4 2 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typowner 23 0 4 3 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typlen 21 0 2 4 0 -1 -1 t p f s f f));
|
||||
DATA(insert ( 1247 typprtlen 21 0 2 5 0 -1 -1 t p f s f f));
|
||||
DATA(insert ( 1247 typbyval 16 0 1 6 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typtype 18 0 1 7 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typisdefined 16 0 1 8 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typdelim 18 0 1 9 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typrelid 26 0 4 10 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typelem 26 0 4 11 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typinput 24 0 4 12 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typoutput 24 0 4 13 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typreceive 24 0 4 14 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typsend 24 0 4 15 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typalign 18 0 1 16 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typstorage 18 0 1 17 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typnotnull 16 0 1 18 0 -1 -1 t p f c f f));
|
||||
DATA(insert ( 1247 typbasetype 26 0 4 19 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typtypmod 23 0 4 20 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typndims 23 0 4 21 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 typdefaultbin 25 0 -1 22 0 -1 -1 f x f i f f));
|
||||
DATA(insert ( 1247 typdefault 25 0 -1 23 0 -1 -1 f x f i f f));
|
||||
DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
|
||||
DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p f i f f));
|
||||
DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_class.h,v 1.63 2002/03/26 19:16:35 tgl Exp $
|
||||
* $Id: pg_class.h,v 1.64 2002/03/29 19:06:18 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
|
@ -134,7 +134,7 @@ typedef FormData_pg_class *Form_pg_class;
|
|||
* ----------------
|
||||
*/
|
||||
|
||||
DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 f f r 22 0 0 0 0 0 t f f f _null_ ));
|
||||
DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 f f r 23 0 0 0 0 0 t f f f _null_ ));
|
||||
DESCR("");
|
||||
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ ));
|
||||
DESCR("");
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_operator.h,v 1.99 2001/11/05 17:46:32 momjian Exp $
|
||||
* $Id: pg_operator.h,v 1.100 2002/03/29 19:06:19 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
|
@ -843,18 +843,18 @@ DATA(insert OID = 2068 ( "-" PGUID 0 b t f 1114 1186 1114 0 0 0 0 timesta
|
|||
/*
|
||||
* function prototypes
|
||||
*/
|
||||
extern void OperatorCreate(char *operatorName,
|
||||
char *leftTypeName,
|
||||
char *rightTypeName,
|
||||
char *procedureName,
|
||||
extern void OperatorCreate(const char *operatorName,
|
||||
Oid leftTypeId,
|
||||
Oid rightTypeId,
|
||||
const char *procedureName,
|
||||
uint16 precedence,
|
||||
bool isLeftAssociative,
|
||||
char *commutatorName,
|
||||
char *negatorName,
|
||||
char *restrictionName,
|
||||
char *joinName,
|
||||
const char *commutatorName,
|
||||
const char *negatorName,
|
||||
const char *restrictionName,
|
||||
const char *joinName,
|
||||
bool canHash,
|
||||
char *leftSortName,
|
||||
char *rightSortName);
|
||||
const char *leftSortName,
|
||||
const char *rightSortName);
|
||||
|
||||
#endif /* PG_OPERATOR_H */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_proc.h,v 1.223 2002/02/18 23:11:36 petere Exp $
|
||||
* $Id: pg_proc.h,v 1.224 2002/03/29 19:06:19 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The script catalog/genbki.sh reads this file and generates .bki
|
||||
|
@ -2873,12 +2873,13 @@ DESCR("time zone");
|
|||
|
||||
|
||||
/*
|
||||
* prototypes for functions pg_proc.c
|
||||
* prototypes for functions in pg_proc.c
|
||||
*/
|
||||
extern Oid ProcedureCreate(char *procedureName,
|
||||
Oid procNamespace,
|
||||
bool replace,
|
||||
bool returnsSet,
|
||||
char *returnTypeName,
|
||||
Oid returnType,
|
||||
Oid languageObjectId,
|
||||
char *prosrc,
|
||||
char *probin,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_type.h,v 1.118 2002/03/20 19:44:57 tgl Exp $
|
||||
* $Id: pg_type.h,v 1.119 2002/03/29 19:06:20 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
|
@ -38,8 +38,9 @@
|
|||
*/
|
||||
CATALOG(pg_type) BOOTSTRAP
|
||||
{
|
||||
NameData typname;
|
||||
int4 typowner;
|
||||
NameData typname; /* type name */
|
||||
Oid typnamespace; /* OID of namespace containing this type */
|
||||
int4 typowner; /* type owner */
|
||||
|
||||
/*
|
||||
* For a fixed-size type, typlen is the number of bytes we use to
|
||||
|
@ -202,29 +203,30 @@ typedef FormData_pg_type *Form_pg_type;
|
|||
* compiler constants for pg_type
|
||||
* ----------------
|
||||
*/
|
||||
#define Natts_pg_type 22
|
||||
#define Natts_pg_type 23
|
||||
#define Anum_pg_type_typname 1
|
||||
#define Anum_pg_type_typowner 2
|
||||
#define Anum_pg_type_typlen 3
|
||||
#define Anum_pg_type_typprtlen 4
|
||||
#define Anum_pg_type_typbyval 5
|
||||
#define Anum_pg_type_typtype 6
|
||||
#define Anum_pg_type_typisdefined 7
|
||||
#define Anum_pg_type_typdelim 8
|
||||
#define Anum_pg_type_typrelid 9
|
||||
#define Anum_pg_type_typelem 10
|
||||
#define Anum_pg_type_typinput 11
|
||||
#define Anum_pg_type_typoutput 12
|
||||
#define Anum_pg_type_typreceive 13
|
||||
#define Anum_pg_type_typsend 14
|
||||
#define Anum_pg_type_typalign 15
|
||||
#define Anum_pg_type_typstorage 16
|
||||
#define Anum_pg_type_typnotnull 17
|
||||
#define Anum_pg_type_typbasetype 18
|
||||
#define Anum_pg_type_typtypmod 19
|
||||
#define Anum_pg_type_typndims 20
|
||||
#define Anum_pg_type_typdefaultbin 21
|
||||
#define Anum_pg_type_typdefault 22
|
||||
#define Anum_pg_type_typnamespace 2
|
||||
#define Anum_pg_type_typowner 3
|
||||
#define Anum_pg_type_typlen 4
|
||||
#define Anum_pg_type_typprtlen 5
|
||||
#define Anum_pg_type_typbyval 6
|
||||
#define Anum_pg_type_typtype 7
|
||||
#define Anum_pg_type_typisdefined 8
|
||||
#define Anum_pg_type_typdelim 9
|
||||
#define Anum_pg_type_typrelid 10
|
||||
#define Anum_pg_type_typelem 11
|
||||
#define Anum_pg_type_typinput 12
|
||||
#define Anum_pg_type_typoutput 13
|
||||
#define Anum_pg_type_typreceive 14
|
||||
#define Anum_pg_type_typsend 15
|
||||
#define Anum_pg_type_typalign 16
|
||||
#define Anum_pg_type_typstorage 17
|
||||
#define Anum_pg_type_typnotnull 18
|
||||
#define Anum_pg_type_typbasetype 19
|
||||
#define Anum_pg_type_typtypmod 20
|
||||
#define Anum_pg_type_typndims 21
|
||||
#define Anum_pg_type_typdefaultbin 22
|
||||
#define Anum_pg_type_typdefault 23
|
||||
|
||||
|
||||
/* ----------------
|
||||
|
@ -240,82 +242,82 @@ typedef FormData_pg_type *Form_pg_type;
|
|||
*/
|
||||
|
||||
/* OIDS 1 - 99 */
|
||||
DATA(insert OID = 16 ( bool PGUID 1 1 t b t \054 0 0 boolin boolout boolin boolout c p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 16 ( bool PGNSP PGUID 1 1 t b t \054 0 0 boolin boolout boolin boolout c p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("boolean, 'true'/'false'");
|
||||
#define BOOLOID 16
|
||||
|
||||
DATA(insert OID = 17 ( bytea PGUID -1 -1 f b t \054 0 0 byteain byteaout byteain byteaout i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 17 ( bytea PGNSP PGUID -1 -1 f b t \054 0 0 byteain byteaout byteain byteaout i x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("variable-length string, binary values escaped");
|
||||
#define BYTEAOID 17
|
||||
|
||||
DATA(insert OID = 18 ( char PGUID 1 1 t b t \054 0 0 charin charout charin charout c p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 18 ( char PGNSP PGUID 1 1 t b t \054 0 0 charin charout charin charout c p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("single character");
|
||||
#define CHAROID 18
|
||||
|
||||
DATA(insert OID = 19 ( name PGUID NAMEDATALEN NAMEDATALEN f b t \054 0 18 namein nameout namein nameout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN NAMEDATALEN f b t \054 0 18 namein nameout namein nameout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("31-character type for storing system identifiers");
|
||||
#define NAMEOID 19
|
||||
|
||||
DATA(insert OID = 20 ( int8 PGUID 8 20 f b t \054 0 0 int8in int8out int8in int8out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 20 ( int8 PGNSP PGUID 8 20 f b t \054 0 0 int8in int8out int8in int8out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("~18 digit integer, 8-byte storage");
|
||||
#define INT8OID 20
|
||||
|
||||
DATA(insert OID = 21 ( int2 PGUID 2 5 t b t \054 0 0 int2in int2out int2in int2out s p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 21 ( int2 PGNSP PGUID 2 5 t b t \054 0 0 int2in int2out int2in int2out s p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("-32 thousand to 32 thousand, 2-byte storage");
|
||||
#define INT2OID 21
|
||||
|
||||
DATA(insert OID = 22 ( int2vector PGUID INDEX_MAX_KEYS*2 -1 f b t \054 0 21 int2vectorin int2vectorout int2vectorin int2vectorout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 22 ( int2vector PGNSP PGUID INDEX_MAX_KEYS*2 -1 f b t \054 0 21 int2vectorin int2vectorout int2vectorin int2vectorout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables");
|
||||
#define INT2VECTOROID 22
|
||||
|
||||
DATA(insert OID = 23 ( int4 PGUID 4 10 t b t \054 0 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 23 ( int4 PGNSP PGUID 4 10 t b t \054 0 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("-2 billion to 2 billion integer, 4-byte storage");
|
||||
#define INT4OID 23
|
||||
|
||||
DATA(insert OID = 24 ( regproc PGUID 4 16 t b t \054 0 0 regprocin regprocout regprocin regprocout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 24 ( regproc PGNSP PGUID 4 16 t b t \054 0 0 regprocin regprocout regprocin regprocout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("registered procedure");
|
||||
#define REGPROCOID 24
|
||||
|
||||
DATA(insert OID = 25 ( text PGUID -1 -1 f b t \054 0 0 textin textout textin textout i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 25 ( text PGNSP PGUID -1 -1 f b t \054 0 0 textin textout textin textout i x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("variable-length string, no limit specified");
|
||||
#define TEXTOID 25
|
||||
|
||||
DATA(insert OID = 26 ( oid PGUID 4 10 t b t \054 0 0 oidin oidout oidin oidout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 26 ( oid PGNSP PGUID 4 10 t b t \054 0 0 oidin oidout oidin oidout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("object identifier(oid), maximum 4 billion");
|
||||
#define OIDOID 26
|
||||
|
||||
DATA(insert OID = 27 ( tid PGUID 6 19 f b t \054 0 0 tidin tidout tidin tidout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 27 ( tid PGNSP PGUID 6 19 f b t \054 0 0 tidin tidout tidin tidout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("(Block, offset), physical location of tuple");
|
||||
#define TIDOID 27
|
||||
|
||||
DATA(insert OID = 28 ( xid PGUID 4 12 t b t \054 0 0 xidin xidout xidin xidout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 28 ( xid PGNSP PGUID 4 12 t b t \054 0 0 xidin xidout xidin xidout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("transaction id");
|
||||
#define XIDOID 28
|
||||
|
||||
DATA(insert OID = 29 ( cid PGUID 4 10 t b t \054 0 0 cidin cidout cidin cidout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 29 ( cid PGNSP PGUID 4 10 t b t \054 0 0 cidin cidout cidin cidout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("command identifier type, sequence in transaction id");
|
||||
#define CIDOID 29
|
||||
|
||||
DATA(insert OID = 30 ( oidvector PGUID INDEX_MAX_KEYS*4 -1 f b t \054 0 26 oidvectorin oidvectorout oidvectorin oidvectorout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 30 ( oidvector PGNSP PGUID INDEX_MAX_KEYS*4 -1 f b t \054 0 26 oidvectorin oidvectorout oidvectorin oidvectorout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
|
||||
#define OIDVECTOROID 30
|
||||
|
||||
DATA(insert OID = 32 ( SET PGUID -1 -1 f b t \054 0 0 textin textout textin textout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 32 ( SET PGNSP PGUID -1 -1 f b t \054 0 0 textin textout textin textout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("set of tuples");
|
||||
|
||||
DATA(insert OID = 71 ( pg_type PGUID 4 4 t c t \054 1247 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 75 ( pg_attribute PGUID 4 4 t c t \054 1249 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 81 ( pg_proc PGUID 4 4 t c t \054 1255 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 83 ( pg_class PGUID 4 4 t c t \054 1259 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 86 ( pg_shadow PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 87 ( pg_group PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 88 ( pg_database PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 71 ( pg_type PGNSP PGUID 4 4 t c t \054 1247 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 75 ( pg_attribute PGNSP PGUID 4 4 t c t \054 1249 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 81 ( pg_proc PGNSP PGUID 4 4 t c t \054 1255 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 83 ( pg_class PGNSP PGUID 4 4 t c t \054 1259 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 86 ( pg_shadow PGNSP PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 87 ( pg_group PGNSP PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 88 ( pg_database PGNSP PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
|
||||
|
||||
/* OIDS 100 - 199 */
|
||||
|
||||
/* OIDS 200 - 299 */
|
||||
|
||||
DATA(insert OID = 210 ( smgr PGUID 2 12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 210 ( smgr PGNSP PGUID 2 12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("storage manager");
|
||||
|
||||
/* OIDS 300 - 399 */
|
||||
|
@ -325,192 +327,194 @@ DESCR("storage manager");
|
|||
/* OIDS 500 - 599 */
|
||||
|
||||
/* OIDS 600 - 699 */
|
||||
DATA(insert OID = 600 ( point PGUID 16 24 f b t \054 0 701 point_in point_out point_in point_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 600 ( point PGNSP PGUID 16 24 f b t \054 0 701 point_in point_out point_in point_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("geometric point '(x, y)'");
|
||||
#define POINTOID 600
|
||||
DATA(insert OID = 601 ( lseg PGUID 32 48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 601 ( lseg PGNSP PGUID 32 48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("geometric line segment '(pt1,pt2)'");
|
||||
#define LSEGOID 601
|
||||
DATA(insert OID = 602 ( path PGUID -1 -1 f b t \054 0 0 path_in path_out path_in path_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 602 ( path PGNSP PGUID -1 -1 f b t \054 0 0 path_in path_out path_in path_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("geometric path '(pt1,...)'");
|
||||
#define PATHOID 602
|
||||
DATA(insert OID = 603 ( box PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 603 ( box PGNSP PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("geometric box '(lower left,upper right)'");
|
||||
#define BOXOID 603
|
||||
DATA(insert OID = 604 ( polygon PGUID -1 -1 f b t \054 0 0 poly_in poly_out poly_in poly_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 604 ( polygon PGNSP PGUID -1 -1 f b t \054 0 0 poly_in poly_out poly_in poly_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("geometric polygon '(pt1,...)'");
|
||||
#define POLYGONOID 604
|
||||
|
||||
DATA(insert OID = 628 ( line PGUID 32 48 f b t \054 0 701 line_in line_out line_in line_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 628 ( line PGNSP PGUID 32 48 f b t \054 0 701 line_in line_out line_in line_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("geometric line '(pt1,pt2)'");
|
||||
#define LINEOID 628
|
||||
DATA(insert OID = 629 ( _line PGUID -1 -1 f b t \054 0 628 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 629 ( _line PGNSP PGUID -1 -1 f b t \054 0 628 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("");
|
||||
|
||||
/* OIDS 700 - 799 */
|
||||
|
||||
DATA(insert OID = 700 ( float4 PGUID 4 12 f b t \054 0 0 float4in float4out float4in float4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 700 ( float4 PGNSP PGUID 4 12 f b t \054 0 0 float4in float4out float4in float4out i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("single-precision floating point number, 4-byte storage");
|
||||
#define FLOAT4OID 700
|
||||
DATA(insert OID = 701 ( float8 PGUID 8 24 f b t \054 0 0 float8in float8out float8in float8out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 701 ( float8 PGNSP PGUID 8 24 f b t \054 0 0 float8in float8out float8in float8out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("double-precision floating point number, 8-byte storage");
|
||||
#define FLOAT8OID 701
|
||||
DATA(insert OID = 702 ( abstime PGUID 4 20 t b t \054 0 0 nabstimein nabstimeout nabstimein nabstimeout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 702 ( abstime PGNSP PGUID 4 20 t b t \054 0 0 nabstimein nabstimeout nabstimein nabstimeout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("absolute, limited-range date and time (Unix system time)");
|
||||
#define ABSTIMEOID 702
|
||||
DATA(insert OID = 703 ( reltime PGUID 4 20 t b t \054 0 0 reltimein reltimeout reltimein reltimeout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 703 ( reltime PGNSP PGUID 4 20 t b t \054 0 0 reltimein reltimeout reltimein reltimeout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("relative, limited-range time interval (Unix delta time)");
|
||||
#define RELTIMEOID 703
|
||||
DATA(insert OID = 704 ( tinterval PGUID 12 47 f b t \054 0 0 tintervalin tintervalout tintervalin tintervalout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 47 f b t \054 0 0 tintervalin tintervalout tintervalin tintervalout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("(abstime,abstime), time interval");
|
||||
#define TINTERVALOID 704
|
||||
DATA(insert OID = 705 ( unknown PGUID -1 -1 f b t \054 0 0 textin textout textin textout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 705 ( unknown PGNSP PGUID -1 -1 f b t \054 0 0 textin textout textin textout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("");
|
||||
#define UNKNOWNOID 705
|
||||
|
||||
DATA(insert OID = 718 ( circle PGUID 24 47 f b t \054 0 0 circle_in circle_out circle_in circle_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 718 ( circle PGNSP PGUID 24 47 f b t \054 0 0 circle_in circle_out circle_in circle_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("geometric circle '(center,radius)'");
|
||||
#define CIRCLEOID 718
|
||||
DATA(insert OID = 719 ( _circle PGUID -1 -1 f b t \054 0 718 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 790 ( money PGUID 4 24 f b t \054 0 0 cash_in cash_out cash_in cash_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 719 ( _circle PGNSP PGUID -1 -1 f b t \054 0 718 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 790 ( money PGNSP PGUID 4 24 f b t \054 0 0 cash_in cash_out cash_in cash_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("$d,ddd.cc, money");
|
||||
#define CASHOID 790
|
||||
DATA(insert OID = 791 ( _money PGUID -1 -1 f b t \054 0 790 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 791 ( _money PGNSP PGUID -1 -1 f b t \054 0 790 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
|
||||
/* OIDS 800 - 899 */
|
||||
DATA(insert OID = 829 ( macaddr PGUID 6 -1 f b t \054 0 0 macaddr_in macaddr_out macaddr_in macaddr_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 -1 f b t \054 0 0 macaddr_in macaddr_out macaddr_in macaddr_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("XX:XX:XX:XX:XX:XX, MAC address");
|
||||
#define MACADDROID 829
|
||||
DATA(insert OID = 869 ( inet PGUID -1 -1 f b t \054 0 0 inet_in inet_out inet_in inet_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 869 ( inet PGNSP PGUID -1 -1 f b t \054 0 0 inet_in inet_out inet_in inet_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("IP address/netmask, host address, netmask optional");
|
||||
#define INETOID 869
|
||||
DATA(insert OID = 650 ( cidr PGUID -1 -1 f b t \054 0 0 cidr_in cidr_out cidr_in cidr_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 650 ( cidr PGNSP PGUID -1 -1 f b t \054 0 0 cidr_in cidr_out cidr_in cidr_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("network IP address/netmask, network address");
|
||||
#define CIDROID 650
|
||||
|
||||
/* OIDS 900 - 999 */
|
||||
|
||||
/* OIDS 1000 - 1099 */
|
||||
DATA(insert OID = 1000 ( _bool PGUID -1 -1 f b t \054 0 16 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1001 ( _bytea PGUID -1 -1 f b t \054 0 17 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1002 ( _char PGUID -1 -1 f b t \054 0 18 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1003 ( _name PGUID -1 -1 f b t \054 0 19 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1005 ( _int2 PGUID -1 -1 f b t \054 0 21 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1006 ( _int2vector PGUID -1 -1 f b t \054 0 22 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1007 ( _int4 PGUID -1 -1 f b t \054 0 23 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1008 ( _regproc PGUID -1 -1 f b t \054 0 24 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1009 ( _text PGUID -1 -1 f b t \054 0 25 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1028 ( _oid PGUID -1 -1 f b t \054 0 26 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1010 ( _tid PGUID -1 -1 f b t \054 0 27 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1011 ( _xid PGUID -1 -1 f b t \054 0 28 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1012 ( _cid PGUID -1 -1 f b t \054 0 29 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1013 ( _oidvector PGUID -1 -1 f b t \054 0 30 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1014 ( _bpchar PGUID -1 -1 f b t \054 0 1042 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1015 ( _varchar PGUID -1 -1 f b t \054 0 1043 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1016 ( _int8 PGUID -1 -1 f b t \054 0 20 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1017 ( _point PGUID -1 -1 f b t \054 0 600 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1018 ( _lseg PGUID -1 -1 f b t \054 0 601 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1019 ( _path PGUID -1 -1 f b t \054 0 602 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1020 ( _box PGUID -1 -1 f b t \073 0 603 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1021 ( _float4 PGUID -1 -1 f b t \054 0 700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1022 ( _float8 PGUID -1 -1 f b t \054 0 701 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1023 ( _abstime PGUID -1 -1 f b t \054 0 702 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1024 ( _reltime PGUID -1 -1 f b t \054 0 703 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1025 ( _tinterval PGUID -1 -1 f b t \054 0 704 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1027 ( _polygon PGUID -1 -1 f b t \054 0 604 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 -1 f b t \054 0 16 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 -1 f b t \054 0 17 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1002 ( _char PGNSP PGUID -1 -1 f b t \054 0 18 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1003 ( _name PGNSP PGUID -1 -1 f b t \054 0 19 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 -1 f b t \054 0 21 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 -1 f b t \054 0 22 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 -1 f b t \054 0 23 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 -1 f b t \054 0 24 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1009 ( _text PGNSP PGUID -1 -1 f b t \054 0 25 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 -1 f b t \054 0 26 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 -1 f b t \054 0 27 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 -1 f b t \054 0 28 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 -1 f b t \054 0 29 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 -1 f b t \054 0 30 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 -1 f b t \054 0 1042 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 -1 f b t \054 0 1043 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 -1 f b t \054 0 20 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1017 ( _point PGNSP PGUID -1 -1 f b t \054 0 600 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 -1 f b t \054 0 601 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1019 ( _path PGNSP PGUID -1 -1 f b t \054 0 602 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1020 ( _box PGNSP PGUID -1 -1 f b t \073 0 603 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 -1 f b t \054 0 700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1022 ( _float8 PGNSP PGUID -1 -1 f b t \054 0 701 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 -1 f b t \054 0 702 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 -1 f b t \054 0 703 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 -1 f b t \054 0 704 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 -1 f b t \054 0 604 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
/*
|
||||
* Note: the size of aclitem needs to match sizeof(AclItem) in acl.h.
|
||||
* Thanks to some padding, this will be 8 on all platforms.
|
||||
* We also have an Assert to make sure.
|
||||
*/
|
||||
#define ACLITEMSIZE 8
|
||||
DATA(insert OID = 1033 ( aclitem PGUID 8 -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1033 ( aclitem PGNSP PGUID 8 -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("access control list");
|
||||
DATA(insert OID = 1034 ( _aclitem PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1040 ( _macaddr PGUID -1 -1 f b t \054 0 829 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1041 ( _inet PGUID -1 -1 f b t \054 0 869 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 651 ( _cidr PGUID -1 -1 f b t \054 0 650 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1042 ( bpchar PGUID -1 -1 f b t \054 0 0 bpcharin bpcharout bpcharin bpcharout i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 -1 f b t \054 0 829 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 -1 f b t \054 0 869 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 -1 f b t \054 0 650 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 -1 f b t \054 0 0 bpcharin bpcharout bpcharin bpcharout i x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("char(length), blank-padded string, fixed storage length");
|
||||
#define BPCHAROID 1042
|
||||
DATA(insert OID = 1043 ( varchar PGUID -1 -1 f b t \054 0 0 varcharin varcharout varcharin varcharout i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 -1 f b t \054 0 0 varcharin varcharout varcharin varcharout i x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("varchar(length), non-blank-padded string, variable storage length");
|
||||
#define VARCHAROID 1043
|
||||
|
||||
DATA(insert OID = 1082 ( date PGUID 4 10 t b t \054 0 0 date_in date_out date_in date_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1082 ( date PGNSP PGUID 4 10 t b t \054 0 0 date_in date_out date_in date_out i p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("ANSI SQL date");
|
||||
#define DATEOID 1082
|
||||
DATA(insert OID = 1083 ( time PGUID 8 16 f b t \054 0 0 time_in time_out time_in time_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1083 ( time PGNSP PGUID 8 16 f b t \054 0 0 time_in time_out time_in time_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("hh:mm:ss, ANSI SQL time");
|
||||
#define TIMEOID 1083
|
||||
|
||||
/* OIDS 1100 - 1199 */
|
||||
DATA(insert OID = 1114 ( timestamp PGUID 8 47 f b t \054 0 0 timestamp_in timestamp_out timestamp_in timestamp_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 47 f b t \054 0 0 timestamp_in timestamp_out timestamp_in timestamp_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("date and time");
|
||||
#define TIMESTAMPOID 1114
|
||||
DATA(insert OID = 1115 ( _timestamp PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1182 ( _date PGUID -1 -1 f b t \054 0 1082 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1183 ( _time PGUID -1 -1 f b t \054 0 1083 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1184 ( timestamptz PGUID 8 47 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_in timestamptz_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1182 ( _date PGNSP PGUID -1 -1 f b t \054 0 1082 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1183 ( _time PGNSP PGUID -1 -1 f b t \054 0 1083 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 47 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_in timestamptz_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("date and time with time zone");
|
||||
#define TIMESTAMPTZOID 1184
|
||||
DATA(insert OID = 1185 ( _timestamptz PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1186 ( interval PGUID 12 47 f b t \054 0 0 interval_in interval_out interval_in interval_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1186 ( interval PGNSP PGUID 12 47 f b t \054 0 0 interval_in interval_out interval_in interval_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("@ <number> <units>, time interval");
|
||||
#define INTERVALOID 1186
|
||||
DATA(insert OID = 1187 ( _interval PGUID -1 -1 f b t \054 0 1186 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 -1 f b t \054 0 1186 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
|
||||
/* OIDS 1200 - 1299 */
|
||||
DATA(insert OID = 1231 ( _numeric PGUID -1 -1 f b t \054 0 1700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1266 ( timetz PGUID 12 22 f b t \054 0 0 timetz_in timetz_out timetz_in timetz_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 -1 f b t \054 0 1700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 22 f b t \054 0 0 timetz_in timetz_out timetz_in timetz_out d p f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("hh:mm:ss, ANSI SQL time");
|
||||
#define TIMETZOID 1266
|
||||
DATA(insert OID = 1270 ( _timetz PGUID -1 -1 f b t \054 0 1266 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 -1 f b t \054 0 1266 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
|
||||
|
||||
/* OIDS 1500 - 1599 */
|
||||
DATA(insert OID = 1560 ( bit PGUID -1 -1 f b t \054 0 0 bit_in bit_out bit_in bit_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1560 ( bit PGNSP PGUID -1 -1 f b t \054 0 0 bit_in bit_out bit_in bit_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("fixed-length bit string");
|
||||
#define BITOID 1560
|
||||
DATA(insert OID = 1561 ( _bit PGUID -1 -1 f b t \054 0 1560 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1562 ( varbit PGUID -1 -1 f b t \054 0 0 varbit_in varbit_out varbit_in varbit_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 -1 f b t \054 0 1560 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 -1 f b t \054 0 0 varbit_in varbit_out varbit_in varbit_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("variable-length bit string");
|
||||
#define VARBITOID 1562
|
||||
DATA(insert OID = 1563 ( _varbit PGUID -1 -1 f b t \054 0 1562 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 -1 f b t \054 0 1562 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
|
||||
/* OIDS 1600 - 1699 */
|
||||
|
||||
/* OIDS 1700 - 1799 */
|
||||
DATA(insert OID = 1700 ( numeric PGUID -1 -1 f b t \054 0 0 numeric_in numeric_out numeric_in numeric_out i m f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 -1 f b t \054 0 0 numeric_in numeric_out numeric_in numeric_out i m f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("numeric(precision, decimal), arbitrary precision number");
|
||||
#define NUMERICOID 1700
|
||||
|
||||
/* OID 1790 */
|
||||
DATA(insert OID = 1790 ( refcursor PGUID -1 -1 f b t \054 0 0 textin textout textin textout i x f 0 -1 0 _null_ _null_ ));
|
||||
DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 -1 f b t \054 0 0 textin textout textin textout i x f 0 -1 0 _null_ _null_ ));
|
||||
DESCR("reference cursor (portal name)");
|
||||
#define REFCURSOROID 1790
|
||||
|
||||
/* OIDS 2000 - 2099 */
|
||||
DATA(insert OID = 2019 ( _refcursor PGNSP PGUID -1 -1 f b t \054 0 1790 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
|
||||
|
||||
|
||||
/*
|
||||
* prototypes for functions in pg_type.c
|
||||
*/
|
||||
extern Oid TypeGet(char *typeName, bool *defined);
|
||||
extern Oid TypeShellMake(char *typeName);
|
||||
extern Oid TypeShellMake(const char *typeName, Oid typeNamespace);
|
||||
|
||||
extern Oid TypeCreate(char *typeName,
|
||||
extern Oid TypeCreate(const char *typeName,
|
||||
Oid typeNamespace,
|
||||
Oid assignedTypeOid,
|
||||
Oid relationOid,
|
||||
int16 internalSize,
|
||||
int16 externalSize,
|
||||
char typeType,
|
||||
char typDelim,
|
||||
char *inputProcedure,
|
||||
char *outputProcedure,
|
||||
char *receiveProcedure,
|
||||
char *sendProcedure,
|
||||
char *elementTypeName,
|
||||
char *baseTypeName,
|
||||
char *defaultTypeValue,
|
||||
char *defaultTypeBin,
|
||||
Oid inputProcedure,
|
||||
Oid outputProcedure,
|
||||
Oid receiveProcedure,
|
||||
Oid sendProcedure,
|
||||
Oid elementType,
|
||||
Oid baseType,
|
||||
const char *defaultTypeValue,
|
||||
const char *defaultTypeBin,
|
||||
bool passedByValue,
|
||||
char alignment,
|
||||
char storage,
|
||||
|
@ -519,7 +523,8 @@ extern Oid TypeCreate(char *typeName,
|
|||
bool typeNotNull);
|
||||
|
||||
|
||||
extern void TypeRename(const char *oldTypeName, const char *newTypeName);
|
||||
extern char *makeArrayTypeName(char *typeName);
|
||||
extern void TypeRename(const char *oldTypeName, Oid typeNamespace,
|
||||
const char *newTypeName);
|
||||
extern char *makeArrayTypeName(const char *typeName);
|
||||
|
||||
#endif /* PG_TYPE_H */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: command.h,v 1.35 2002/03/26 19:16:40 tgl Exp $
|
||||
* $Id: command.h,v 1.36 2002/03/29 19:06:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -40,31 +40,27 @@ extern void PortalCleanup(Portal portal);
|
|||
/*
|
||||
* ALTER TABLE variants
|
||||
*/
|
||||
extern void AlterTableAddColumn(const char *relationName,
|
||||
bool inh, ColumnDef *colDef);
|
||||
extern void AlterTableAddColumn(Oid myrelid, bool inherits, ColumnDef *colDef);
|
||||
|
||||
extern void AlterTableAlterColumnDefault(const char *relationName,
|
||||
bool inh, const char *colName,
|
||||
Node *newDefault);
|
||||
extern void AlterTableAlterColumnDefault(Oid myrelid, bool inh,
|
||||
const char *colName, Node *newDefault);
|
||||
|
||||
extern void AlterTableAlterColumnFlags(const char *relationName,
|
||||
bool inh, const char *colName,
|
||||
Node *flagValue, const char *flagType);
|
||||
extern void AlterTableAlterColumnFlags(Oid myrelid,
|
||||
bool inh, const char *colName,
|
||||
Node *flagValue, const char *flagType);
|
||||
|
||||
extern void AlterTableDropColumn(const char *relationName,
|
||||
bool inh, const char *colName,
|
||||
int behavior);
|
||||
extern void AlterTableDropColumn(Oid myrelid, bool inh,
|
||||
const char *colName, int behavior);
|
||||
|
||||
extern void AlterTableAddConstraint(char *relationName,
|
||||
bool inh, List *newConstraints);
|
||||
extern void AlterTableAddConstraint(Oid myrelid,
|
||||
bool inh, List *newConstraints);
|
||||
|
||||
extern void AlterTableDropConstraint(const char *relationName,
|
||||
bool inh, const char *constrName,
|
||||
int behavior);
|
||||
extern void AlterTableDropConstraint(Oid myrelid,
|
||||
bool inh, const char *constrName, int behavior);
|
||||
|
||||
extern void AlterTableCreateToastTable(Oid relOid, bool silent);
|
||||
|
||||
extern void AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName);
|
||||
extern void AlterTableOwner(Oid relationOid, int32 newOwnerSysId);
|
||||
|
||||
/*
|
||||
* LOCK
|
||||
|
|
|
@ -7,16 +7,19 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: copy.h,v 1.16 2001/11/05 17:46:33 momjian Exp $
|
||||
* $Id: copy.h,v 1.17 2002/03/29 19:06:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef COPY_H
|
||||
#define COPY_H
|
||||
|
||||
#include "nodes/primnodes.h"
|
||||
|
||||
extern int copy_lineno;
|
||||
|
||||
void DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
|
||||
char *filename, char *delim, char *null_print);
|
||||
void DoCopy(const RangeVar *relation, bool binary, bool oids,
|
||||
bool from, bool pipe,
|
||||
char *filename, char *delim, char *null_print);
|
||||
|
||||
#endif /* COPY_H */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: creatinh.h,v 1.19 2002/03/22 02:56:36 tgl Exp $
|
||||
* $Id: creatinh.h,v 1.20 2002/03/29 19:06:22 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -17,7 +17,7 @@
|
|||
#include "nodes/parsenodes.h"
|
||||
|
||||
extern Oid DefineRelation(CreateStmt *stmt, char relkind);
|
||||
extern void RemoveRelation(const char *name);
|
||||
extern void TruncateRelation(const char *name);
|
||||
extern void RemoveRelation(const RangeVar *relation);
|
||||
extern void TruncateRelation(const RangeVar *relation);
|
||||
|
||||
#endif /* CREATINH_H */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: defrem.h,v 1.32 2002/03/26 19:16:47 tgl Exp $
|
||||
* $Id: defrem.h,v 1.33 2002/03/29 19:06:22 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -36,19 +36,19 @@ extern void ReindexDatabase(const char *databaseName, bool force, bool all);
|
|||
* prototypes in define.c
|
||||
*/
|
||||
extern void CreateFunction(ProcedureStmt *stmt);
|
||||
extern void DefineOperator(char *name, List *parameters);
|
||||
extern void DefineAggregate(char *name, List *parameters);
|
||||
extern void DefineType(char *name, List *parameters);
|
||||
extern void DefineOperator(List *names, List *parameters);
|
||||
extern void DefineAggregate(List *names, List *parameters);
|
||||
extern void DefineType(List *names, List *parameters);
|
||||
extern void DefineDomain(CreateDomainStmt *stmt);
|
||||
|
||||
/*
|
||||
* prototypes in remove.c
|
||||
*/
|
||||
extern void RemoveDomain(char *domainName, int behavior);
|
||||
extern void RemoveDomain(List *names, int behavior);
|
||||
extern void RemoveFunction(char *functionName, List *argTypes);
|
||||
extern void RemoveOperator(char *operatorName,
|
||||
char *typeName1, char *typeName2);
|
||||
extern void RemoveType(char *typeName);
|
||||
extern void RemoveAggregate(char *aggName, char *aggType);
|
||||
TypeName *typeName1, TypeName *typeName2);
|
||||
extern void RemoveType(List *names);
|
||||
extern void RemoveAggregate(char *aggName, TypeName *aggType);
|
||||
|
||||
#endif /* DEFREM_H */
|
||||
|
|
|
@ -7,17 +7,17 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: rename.h,v 1.14 2002/03/26 19:16:49 tgl Exp $
|
||||
* $Id: rename.h,v 1.15 2002/03/29 19:06:22 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef RENAME_H
|
||||
#define RENAME_H
|
||||
|
||||
extern void renameatt(char *relname,
|
||||
extern void renameatt(Oid relid,
|
||||
char *oldattname,
|
||||
char *newattname,
|
||||
int recurse);
|
||||
bool recurse);
|
||||
|
||||
extern void renamerel(const RangeVar *relation,
|
||||
const char *newrelname);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: view.h,v 1.13 2001/11/05 17:46:33 momjian Exp $
|
||||
* $Id: view.h,v 1.14 2002/03/29 19:06:22 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "nodes/parsenodes.h"
|
||||
|
||||
extern void DefineView(char *view_name, Query *view_parse);
|
||||
extern void RemoveView(char *view_name);
|
||||
extern void DefineView(const RangeVar *view, Query *view_parse);
|
||||
extern void RemoveView(const RangeVar *view);
|
||||
|
||||
#endif /* VIEW_H */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: makefuncs.h,v 1.33 2002/03/22 02:56:36 tgl Exp $
|
||||
* $Id: makefuncs.h,v 1.34 2002/03/29 19:06:23 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -50,4 +50,6 @@ extern RelabelType *makeRelabelType(Node *arg, Oid rtype, int32 rtypmod);
|
|||
|
||||
extern RangeVar *makeRangeVar(char *schemaname, char *relname);
|
||||
|
||||
extern TypeName *makeTypeName(char *typnam);
|
||||
|
||||
#endif /* MAKEFUNC_H */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parsenodes.h,v 1.165 2002/03/26 19:16:53 tgl Exp $
|
||||
* $Id: parsenodes.h,v 1.166 2002/03/29 19:06:23 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -104,16 +104,25 @@ typedef struct Query
|
|||
|
||||
/*
|
||||
* TypeName - specifies a type in definitions
|
||||
*
|
||||
* For TypeName structures generated internally, it is often easier to
|
||||
* specify the type by OID than by name. If "names" is NIL then the
|
||||
* actual type OID is given by typeid, otherwise typeid is unused.
|
||||
*
|
||||
* If pct_type is TRUE, then names is actually a field name and we look up
|
||||
* the type of that field. Otherwise (the normal case), names is a type
|
||||
* name possibly qualified with schema and database name.
|
||||
*/
|
||||
typedef struct TypeName
|
||||
{
|
||||
NodeTag type;
|
||||
char *name; /* name of the type */
|
||||
List *names; /* qualified name (list of Value strings) */
|
||||
Oid typeid; /* type identified by OID */
|
||||
bool timezone; /* timezone specified? */
|
||||
bool setof; /* is a set? */
|
||||
bool pct_type; /* %TYPE specified? */
|
||||
int32 typmod; /* type modifier */
|
||||
List *arrayBounds; /* array bounds */
|
||||
char *attrname; /* field name when using %TYPE */
|
||||
} TypeName;
|
||||
|
||||
/*
|
||||
|
@ -1023,7 +1032,7 @@ typedef struct DefineStmt
|
|||
{
|
||||
NodeTag type;
|
||||
int defType; /* OPERATOR|TYPE_P|AGGREGATE */
|
||||
char *defname;
|
||||
List *defnames; /* qualified name (list of Value strings) */
|
||||
List *definition; /* a list of DefElem */
|
||||
} DefineStmt;
|
||||
|
||||
|
@ -1034,9 +1043,9 @@ typedef struct DefineStmt
|
|||
typedef struct CreateDomainStmt
|
||||
{
|
||||
NodeTag type;
|
||||
char *domainname; /* name of domain to create */
|
||||
TypeName *typename; /* the base type */
|
||||
List *constraints; /* constraints (list of Constraint nodes) */
|
||||
List *domainname; /* qualified name (list of Value strings) */
|
||||
TypeName *typename; /* the base type */
|
||||
List *constraints; /* constraints (list of Constraint nodes) */
|
||||
} CreateDomainStmt;
|
||||
|
||||
/* ----------------------
|
||||
|
@ -1055,7 +1064,7 @@ typedef struct CreateDomainStmt
|
|||
typedef struct DropStmt
|
||||
{
|
||||
NodeTag type;
|
||||
List *objects;
|
||||
List *objects; /* list of sublists of names (as Values) */
|
||||
int removeType;
|
||||
int behavior; /* CASCADE or RESTRICT drop behavior */
|
||||
} DropStmt;
|
||||
|
@ -1135,9 +1144,9 @@ typedef struct ProcedureStmt
|
|||
{
|
||||
NodeTag type;
|
||||
bool replace; /* T => replace if already exists */
|
||||
char *funcname; /* name of function to create */
|
||||
List *funcname; /* name of function to create */
|
||||
List *argTypes; /* list of argument types (TypeName nodes) */
|
||||
Node *returnType; /* the return type (a TypeName node) */
|
||||
TypeName *returnType; /* the return type */
|
||||
List *withClause; /* a list of DefElem */
|
||||
List *as; /* definition of function body */
|
||||
char *language; /* C, SQL, etc */
|
||||
|
@ -1151,7 +1160,7 @@ typedef struct RemoveAggrStmt
|
|||
{
|
||||
NodeTag type;
|
||||
char *aggname; /* aggregate to drop */
|
||||
Node *aggtype; /* TypeName for input datatype, or NULL */
|
||||
TypeName *aggtype; /* TypeName for input datatype, or NULL */
|
||||
} RemoveAggrStmt;
|
||||
|
||||
/* ----------------------
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parse_expr.h,v 1.26 2002/03/21 16:01:59 tgl Exp $
|
||||
* $Id: parse_expr.h,v 1.27 2002/03/29 19:06:24 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -26,6 +26,5 @@ extern Oid exprType(Node *expr);
|
|||
extern int32 exprTypmod(Node *expr);
|
||||
extern bool exprIsLengthCoercion(Node *expr, int32 *coercedTypmod);
|
||||
extern void parse_expr_init(void);
|
||||
extern char *TypeNameToInternalName(TypeName *typename);
|
||||
|
||||
#endif /* PARSE_EXPR_H */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parse_func.h,v 1.36 2002/03/21 16:02:01 tgl Exp $
|
||||
* $Id: parse_func.h,v 1.37 2002/03/29 19:06:24 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -58,7 +58,8 @@ extern FuncDetailCode func_get_detail(char *funcname, List *fargs,
|
|||
|
||||
extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId);
|
||||
|
||||
extern void func_error(char *caller, char *funcname,
|
||||
int nargs, Oid *argtypes, char *msg);
|
||||
extern void func_error(const char *caller, const char *funcname,
|
||||
int nargs, const Oid *argtypes,
|
||||
const char *msg);
|
||||
|
||||
#endif /* PARSE_FUNC_H */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parse_type.h,v 1.20 2001/11/05 17:46:35 momjian Exp $
|
||||
* $Id: parse_type.h,v 1.21 2002/03/29 19:06:25 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -15,12 +15,18 @@
|
|||
#define PARSE_TYPE_H
|
||||
|
||||
#include "access/htup.h"
|
||||
#include "parser/parse_node.h"
|
||||
|
||||
|
||||
typedef HeapTuple Type;
|
||||
|
||||
extern Oid LookupTypeName(const TypeName *typename);
|
||||
extern char *TypeNameToString(const TypeName *typename);
|
||||
extern Oid typenameTypeId(const TypeName *typename);
|
||||
extern Type typenameType(const TypeName *typename);
|
||||
|
||||
extern bool typeidIsValid(Oid id);
|
||||
extern Type typeidType(Oid id);
|
||||
extern Type typenameType(char *s);
|
||||
|
||||
extern Oid typeTypeId(Type tp);
|
||||
extern int16 typeLen(Type t);
|
||||
|
@ -32,7 +38,6 @@ extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod);
|
|||
|
||||
extern char *typeidTypeName(Oid id);
|
||||
extern Oid typeidTypeRelid(Oid type_id);
|
||||
extern Oid typenameTypeId(char *s);
|
||||
|
||||
extern void parseTypeString(const char *str, Oid *type_id, int32 *typmod);
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: rewriteRemove.h,v 1.11 2002/03/21 23:27:24 tgl Exp $
|
||||
* $Id: rewriteRemove.h,v 1.12 2002/03/29 19:06:26 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef REWRITEREMOVE_H
|
||||
#define REWRITEREMOVE_H
|
||||
|
||||
extern void RemoveRewriteRule(char *ruleName);
|
||||
extern void RemoveRewriteRule(List *names);
|
||||
extern void RelationRemoveRules(Oid relid);
|
||||
|
||||
#endif /* REWRITEREMOVE_H */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: lsyscache.h,v 1.46 2002/03/26 19:16:57 tgl Exp $
|
||||
* $Id: lsyscache.h,v 1.47 2002/03/29 19:06:26 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -42,6 +42,7 @@ extern bool func_iscachable(Oid funcid);
|
|||
extern Oid get_relname_relid(const char *relname, Oid relnamespace);
|
||||
extern char *get_rel_name(Oid relid);
|
||||
extern Oid get_rel_type_id(Oid relid);
|
||||
extern bool get_typisdefined(Oid typid);
|
||||
extern int16 get_typlen(Oid typid);
|
||||
extern bool get_typbyval(Oid typid);
|
||||
extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: sets.h,v 1.12 2001/11/05 17:46:36 momjian Exp $
|
||||
* $Id: sets.h,v 1.13 2002/03/29 19:06:26 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -20,7 +20,7 @@
|
|||
/* Temporary name of a set function, before SetDefine changes it. */
|
||||
#define GENERICSETNAME "ZYX#Set#ZYX"
|
||||
|
||||
extern Oid SetDefine(char *querystr, char *typename);
|
||||
extern Oid SetDefine(char *querystr, Oid elemType);
|
||||
|
||||
extern Datum seteval(PG_FUNCTION_ARGS);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: syscache.h,v 1.40 2002/03/26 19:16:59 tgl Exp $
|
||||
* $Id: syscache.h,v 1.41 2002/03/29 19:06:26 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -57,7 +57,7 @@
|
|||
#define SHADOWNAME 26
|
||||
#define SHADOWSYSID 27
|
||||
#define STATRELATT 28
|
||||
#define TYPENAME 29
|
||||
#define TYPENAMENSP 29
|
||||
#define TYPEOID 30
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* procedural language
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.39 2002/03/26 19:17:02 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.40 2002/03/29 19:06:27 tgl Exp $
|
||||
*
|
||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||
*
|
||||
|
@ -47,14 +47,15 @@
|
|||
#include "access/heapam.h"
|
||||
#include "catalog/catname.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "catalog/pg_class.h"
|
||||
#include "catalog/pg_attribute.h"
|
||||
#include "catalog/pg_attrdef.h"
|
||||
#include "catalog/pg_class.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "executor/spi.h"
|
||||
#include "fmgr.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "parser/gramparse.h"
|
||||
#include "parser/parse_type.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
|
@ -851,10 +852,8 @@ plpgsql_parse_wordtype(char *word)
|
|||
{
|
||||
PLpgSQL_nsitem *nse;
|
||||
char *cp;
|
||||
HeapTuple typeTup;
|
||||
Form_pg_type typeStruct;
|
||||
char *typeXlated;
|
||||
bool old_nsstate;
|
||||
Oid typeOid;
|
||||
|
||||
/*
|
||||
* We do our lookups case insensitive
|
||||
|
@ -887,39 +886,46 @@ plpgsql_parse_wordtype(char *word)
|
|||
/*
|
||||
* Word wasn't found on the namestack. Try to find a data type with
|
||||
* that name, but ignore pg_type entries that are in fact class types.
|
||||
*
|
||||
* XXX this should be improved to handle qualified-type-name references.
|
||||
*/
|
||||
typeXlated = xlateSqlType(cp);
|
||||
typeTup = SearchSysCache(TYPENAME,
|
||||
PointerGetDatum(typeXlated),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(typeTup))
|
||||
typeOid = LookupTypeName(makeTypeName(xlateSqlType(cp)));
|
||||
if (OidIsValid(typeOid))
|
||||
{
|
||||
PLpgSQL_type *typ;
|
||||
HeapTuple typeTup;
|
||||
|
||||
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
|
||||
|
||||
if (typeStruct->typrelid != InvalidOid)
|
||||
typeTup = SearchSysCache(TYPEOID,
|
||||
ObjectIdGetDatum(typeOid),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(typeTup))
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.16 2002/03/06 18:50:32 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.17 2002/03/29 19:06:27 tgl Exp $
|
||||
*
|
||||
*********************************************************************
|
||||
*/
|
||||
|
@ -49,16 +49,16 @@
|
|||
|
||||
/* postgreSQL stuff
|
||||
*/
|
||||
#include "executor/spi.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "utils/elog.h"
|
||||
#include "fmgr.h"
|
||||
#include "access/heapam.h"
|
||||
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "executor/spi.h"
|
||||
#include "fmgr.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "parser/parse_type.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
#include <Python.h>
|
||||
#include "plpython.h"
|
||||
|
@ -2086,16 +2086,8 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
|
|||
RAISE_EXC(1);
|
||||
}
|
||||
sptr = PyString_AsString(optr);
|
||||
typeTup = SearchSysCache(TYPENAME, PointerGetDatum(sptr),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(typeTup))
|
||||
{
|
||||
PLy_exception_set(PLy_exc_spi_error,
|
||||
"Cache lookup for type `%s' failed.",
|
||||
sptr);
|
||||
RAISE_EXC(1);
|
||||
}
|
||||
|
||||
/* XXX should extend this to allow qualified type names */
|
||||
typeTup = typenameType(makeTypeName(sptr));
|
||||
Py_DECREF(optr);
|
||||
optr = NULL; /* this is important */
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.52 2002/03/06 18:50:33 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.53 2002/03/29 19:06:28 tgl Exp $
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
|
@ -47,17 +47,18 @@
|
|||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "executor/spi.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "fmgr.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_proc.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 \
|
||||
&& TCL_MINOR_VERSION > 0
|
||||
|
@ -1750,11 +1751,8 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
|
|||
************************************************************/
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
typeTup = SearchSysCache(TYPENAME,
|
||||
PointerGetDatum(args[i]),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(typeTup))
|
||||
elog(ERROR, "pltcl: Cache lookup of type %s failed", args[i]);
|
||||
/* XXX should extend this to allow qualified type names */
|
||||
typeTup = typenameType(makeTypeName(args[i]));
|
||||
qdesc->argtypes[i] = typeTup->t_data->t_oid;
|
||||
perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput,
|
||||
&(qdesc->arginfuncs[i]));
|
||||
|
|
|
@ -137,7 +137,7 @@ drop aggregate 314159 (int);
|
|||
ERROR: parser: parse error at or near "314159"
|
||||
-- bad aggregate type
|
||||
drop aggregate newcnt (nonesuch);
|
||||
ERROR: RemoveAggregate: type 'nonesuch' does not exist
|
||||
ERROR: Type "nonesuch" does not exist
|
||||
-- no such aggregate
|
||||
drop aggregate nonesuch (int4);
|
||||
ERROR: RemoveAggregate: aggregate 'nonesuch' for type integer does not exist
|
||||
|
@ -167,7 +167,7 @@ drop type 314159;
|
|||
ERROR: parser: parse error at or near "314159"
|
||||
-- no such type
|
||||
drop type nonesuch;
|
||||
ERROR: RemoveType: type 'nonesuch' does not exist
|
||||
ERROR: Type "nonesuch" does not exist
|
||||
--
|
||||
-- DROP OPERATOR
|
||||
|
||||
|
@ -203,10 +203,10 @@ drop operator = ( , int4);
|
|||
ERROR: parser: parse error at or near ","
|
||||
-- no such type1
|
||||
drop operator = (nonesuch, int4);
|
||||
ERROR: RemoveOperator: type 'nonesuch' does not exist
|
||||
ERROR: Type "nonesuch" does not exist
|
||||
-- no such type2
|
||||
drop operator = (int4, nonesuch);
|
||||
ERROR: RemoveOperator: type 'nonesuch' does not exist
|
||||
ERROR: Type "nonesuch" does not exist
|
||||
-- no such type2
|
||||
drop operator = (int4, );
|
||||
ERROR: parser: parse error at or near ")"
|
||||
|
|
|
@ -13,8 +13,8 @@ CREATE FUNCTION hobbies_by_name(hobbies_r.name%TYPE)
|
|||
RETURNS hobbies_r.person%TYPE
|
||||
AS 'select person from hobbies_r where name = $1'
|
||||
LANGUAGE 'sql';
|
||||
NOTICE: hobbies_r.name%TYPE converted to text
|
||||
NOTICE: hobbies_r.person%TYPE converted to text
|
||||
NOTICE: hobbies_r.name%TYPE converted to text
|
||||
CREATE FUNCTION equipment(hobbies_r)
|
||||
RETURNS setof equipment_r
|
||||
AS 'select * from equipment_r where hobby = $1.name'
|
||||
|
|
Loading…
Reference in New Issue