Code review for DOMAIN patch.

This commit is contained in:
Tom Lane 2002-03-20 19:45:13 +00:00
parent 251282d4b7
commit 337b22cb47
37 changed files with 869 additions and 850 deletions

View File

@ -1,6 +1,6 @@
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.34 2002/03/19 02:18:10 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.35 2002/03/20 19:43:24 tgl Exp $
-->
<chapter id="catalogs">
@ -2274,7 +2274,8 @@
This catalog stores information about datatypes. Scalar types
(<quote>base types</>) are created with <command>CREATE TYPE</command>.
A complex type is also created for each table in the database, to
represent the row structure of the table.
represent the row structure of the table. It is also possible to create
derived types with <command>CREATE DOMAIN</command>.
</para>
<table>
@ -2345,11 +2346,10 @@
<entry></entry>
<entry>
<structfield>typtype</structfield> is <literal>b</literal> for
a base type and <literal>c</literal> for a complex type (i.e.,
a table's row type). If <structfield>typtype</structfield> is
<literal>c</literal>, <structfield>typrelid</structfield> is
the OID of the type's entry in
<structname>pg_class</structname>.
a base type, <literal>c</literal> for a complex type (i.e.,
a table's row type), or <literal>d</literal> for a derived type (i.e.,
a domain). See also <structfield>typrelid</structfield>
and <structfield>typbasetype</structfield>.
</entry>
</row>
@ -2382,6 +2382,7 @@
the <structfield>pg_class</structfield> entry that defines the
corresponding table. A table could theoretically be used as a
composite data type, but this is not fully functional.
Zero for non-complex types.
</entry>
</row>
@ -2511,38 +2512,53 @@
</row>
<row>
<entry>typbasetype</entry>
<entry><type>oid</type></entry>
<entry>typnotnull</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry><para>
<structfield>typbasetype</structfield> is the type that this one is based
on. Normally references the domains parent type, and is 0 otherwise.
<structfield>typnotnull</structfield> represents a NOT NULL
constraint on a type. Presently used for domains only.
</para></entry>
</row>
<row>
<entry>typnotnull</entry>
<entry><type>boolean</type></entry>
<entry></entry>
<entry><para>
<structfield>typnotnull</structfield> represents a NOT NULL
constraint on a type. Used for domains only.
</para></entry>
</row>
<row>
<entry>typbasetype</entry>
<entry><type>oid</type></entry>
<entry>pg_type.oid</entry>
<entry><para>
If this is a derived type (see <structfield>typtype</structfield>),
then <structfield>typbasetype</structfield> identifies
the type that this one is based on. Zero if not a derived type.
</para></entry>
</row>
<row>
<entry>typmod</entry>
<entry><type>integer</type></entry>
<entry>typtypmod</entry>
<entry><type>int4</type></entry>
<entry></entry>
<entry><para>
<structfield>typmod</structfield> records type-specific data
<structfield>typtypmod</structfield> records type-specific data
supplied at table creation time (for example, the maximum
length of a <type>varchar</type> column). It is passed to
type-specific input and output functions as the third
argument. The value will generally be -1 for types that do not
need typmod. This data is copied to
<structfield>pg_attribute.atttypmod</structfield> on creation
of a table using a domain as it's field type.
need typmod. This value is copied to
<structfield>pg_attribute.atttypmod</structfield> when
creating a column of a domain type.
</para></entry>
</row>
<row>
<entry>typndims</entry>
<entry><type>int4</type></entry>
<entry></entry>
<entry><para>
<structfield>typndims</structfield> is the number of array dimensions
for a domain that is an array. (The array element type is
typbasetype.) Zero for non-domains and non-array domains.
This value is copied to
<structfield>pg_attribute.attndims</structfield> when
creating a column of a domain type.
</para></entry>
</row>
@ -2551,9 +2567,9 @@
<entry><type>text</type></entry>
<entry></entry>
<entry><para>
<structfield>typdefaultbin</structfield> is NULL for types without a
default value. If it's not NULL, it contains the internal string
representation of the default expression node.
If <structfield>typdefaultbin</> is not NULL, it is the nodeToString
representation of a default expression for the type. Currently this is
only used for domains.
</para></entry>
</row>
@ -2562,9 +2578,14 @@
<entry><type>text</type></entry>
<entry></entry>
<entry><para>
<structfield>typdefault</structfield> is NULL for types without a
default value. If it's not NULL, it contains the external string
representation of the type's default value.
<structfield>typdefault</> is NULL if the type has no associated
default value. If <structfield>typdefaultbin</> is not NULL,
<structfield>typdefault</> must contain a human-readable version of the
default expression represented by <structfield>typdefaultbin</>. If
<structfield>typdefaultbin</> is NULL and <structfield>typdefault</> is
not, then <structfield>typdefault</> is the external representation of
the type's default value, which may be fed to the type's input
converter to produce a constant.
</para></entry>
</row>
</tbody>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_domain.sgml,v 1.3 2002/03/19 02:18:13 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_domain.sgml,v 1.4 2002/03/20 19:43:28 tgl Exp $
PostgreSQL documentation
-->
@ -23,13 +23,14 @@ PostgreSQL documentation
<date>2002-02-24</date>
</refsynopsisdivinfo>
<synopsis>
CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceable class="parameter">data_type</replaceable> [ DEFAULT <replaceable>default_expr</> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [, ... ] ]
CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> [AS] <replaceable class="parameter">data_type</replaceable>
[ DEFAULT <replaceable>default_expr</> ]
[ <replaceable class="PARAMETER">constraint</replaceable> [, ... ] ]
where <replaceable class="PARAMETER">constraint</replaceable> is:
[ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
{ NOT NULL | NULL <!-- | UNIQUE | PRIMARY KEY |
CHECK (<replaceable class="PARAMETER">expression</replaceable>) |
REFERENCES <replaceable class="PARAMETER">reftable</replaceable> [ ( <replaceable class="PARAMETER">refcolumn</replaceable> ) ] [ MATCH FULL | MATCH PARTIAL ]
[ ON DELETE <replaceable class="parameter">action</replaceable> ] [ ON UPDATE <replaceable class="parameter">action</replaceable> ] --> }
<!-- [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -->
{ NOT NULL | NULL }
</synopsis>
<refsect2 id="R2-SQL-CREATEDOMAIN-1">
@ -67,23 +68,26 @@ CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceab
<replaceable>default_expr</replaceable></literal></term>
<listitem>
<para>
The <literal>DEFAULT</> clause assigns a default data value for
the column whose column definition it appears within. The value
is any variable-free expression (subselects and cross-references
to other columns in the current table are not allowed). The
The <literal>DEFAULT</> clause specifies a default value for
columns of the domain data type. The value
is any variable-free expression (but subselects are not allowed).
The
data type of the default expression must match the data type of the
domain.
</para>
<para>
The default expression will be used in any insert operation that
does not specify a value for the domain. If there is no default
does not specify a value for the column. If there is no default
for a domain, then the default is NULL.
</para>
<note>
<para>
The default of a column will be tested before that of the domain.
If a default value is specified for a particular column, it
overrides any default associated with the domain. In turn,
the domain default overrides any default value associated with
the underlying data type.
</para>
</note>
</listitem>
@ -93,7 +97,7 @@ CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceab
<term><literal>CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable></literal></term>
<listitem>
<para>
An optional name for a domain. If not specified,
An optional name for a constraint. If not specified,
the system generates a name.
</para>
</listitem>
@ -103,7 +107,7 @@ CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceab
<term><literal>NOT NULL</></term>
<listitem>
<para>
The column is not allowed to contain NULL values. This is
Values of this domain are not allowed to be NULL. This is
equivalent to the column constraint <literal>CHECK (<replaceable
class="PARAMETER">column</replaceable> NOT NULL)</literal>.
</para>
@ -114,7 +118,7 @@ CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceab
<term><literal>NULL</></term>
<listitem>
<para>
The column is allowed to contain NULL values. This is the default.
Values of this domain are allowed to be NULL. This is the default.
</para>
<para>
@ -175,7 +179,7 @@ CREATE DOMAIN
Domains are useful for abstracting common fields between tables into
a single location for maintenance. An email address column may be used
in several tables, all with the same properties. Define a domain and
use that rather than setting up each tables constraints individually.
use that rather than setting up each table's constraints individually.
</para>
</refsect1>
@ -195,9 +199,9 @@ CREATE TABLE countrylist (id INT4, country country_code);
<title>Compatibility</title>
<para>
This <command>CREATE DOMAIN</command> command is a
<productname>PostgreSQL</productname> extension. CHECK and FOREIGN KEY
constraints are currently unsupported.
SQL99 defines CREATE DOMAIN, but says that the only allowed constraint
type is CHECK constraints. CHECK constraints for domains are not yet
supported by <productname>PostgreSQL</productname>.
</para>
</refsect1>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_domain.sgml,v 1.3 2002/03/19 02:18:13 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_domain.sgml,v 1.4 2002/03/20 19:43:28 tgl Exp $
PostgreSQL documentation
-->
@ -23,7 +23,7 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP DOMAIN <replaceable class="PARAMETER">domainname</replaceable> [, ...]
DROP DOMAIN <replaceable class="PARAMETER">domainname</replaceable> [, ...] [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPDOMAIN-1">
@ -43,6 +43,25 @@ DROP DOMAIN <replaceable class="PARAMETER">domainname</replaceable> [, ...]
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>CASCADE</></term>
<listitem>
<para>
Automatically drop objects that depend on the domain. This
behavior is not currently supported.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>RESTRICT</></term>
<listitem>
<para>
Do not drop dependent objects. This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
@ -117,7 +136,7 @@ ERROR: RemoveDomain: type '<replaceable class="parameter">domainname</replaceab
To remove the <type>box</type> domain:
<programlisting>
DROP DOMAIN box RESTRICT;
DROP DOMAIN box;
</programlisting>
</para>
</refsect1>
@ -134,9 +153,8 @@ DROP DOMAIN box RESTRICT;
<synopsis>
DROP DOMAIN <replaceable>name</replaceable> { CASCADE | RESTRICT }
</synopsis>
<productname>PostgreSQL</productname> enforces the existance of
RESTRICT or CASCADE but ignores their enforcement against the
system tables.
<productname>PostgreSQL</productname> accepts only the RESTRICT
option, and currently does not check for existence of dependent objects.
</para>
</refsect1>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.64 2002/03/19 02:32:19 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.65 2002/03/20 19:43:30 tgl Exp $
PostgreSQL documentation
-->
@ -419,21 +419,10 @@ testdb=>
<term><literal>\dD</literal> [ <replaceable class="parameter">pattern</replaceable> ]</term>
<listitem>
<para>
Lists all database domains.
Lists all available domains (derived types).
If <replaceable class="parameter">pattern</replaceable>
(a regular expression) is specified, only matching domains are shown.
</para>
<para>
Descriptions for objects can be generated with the <command>COMMENT ON</command>
<acronym>SQL</acronym> command.
</para>
<note>
<para>
<productname>PostgreSQL</productname> stores the object descriptions in the
pg_description system table.
</para>
</note>
</listitem>
</varlistentry>

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.188 2002/03/19 02:58:19 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.189 2002/03/20 19:43:34 tgl Exp $
*
*
* INTERFACE ROUTINES
@ -705,7 +705,7 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
true, /* passed by value */
'i', /* default alignment - same as for OID */
'p', /* Not TOASTable */
-1, /* Type mod length */
-1, /* typmod */
0, /* array dimensions for typBaseType */
false); /* Type NOT NULL */
}
@ -1589,10 +1589,7 @@ AddRelationRawConstraints(Relation rel,
RangeTblEntry *rte;
int numchecks;
List *listptr;
/* Probably shouldn't be null by default */
Node *expr = NULL;
Node *expr;
/*
* Get info about existing constraints.
@ -1624,17 +1621,11 @@ AddRelationRawConstraints(Relation rel,
foreach(listptr, rawColDefaults)
{
RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr);
Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
expr = cookDefault(pstate, colDef->raw_default
, atp->atttypid, atp->atttypmod
, NameStr(atp->attname));
/*
* OK, store it.
*/
expr = cookDefault(pstate, colDef->raw_default,
atp->atttypid, atp->atttypmod,
NameStr(atp->attname));
StoreAttrDefault(rel, colDef->attnum, nodeToString(expr));
}
@ -1646,7 +1637,6 @@ AddRelationRawConstraints(Relation rel,
{
Constraint *cdef = (Constraint *) lfirst(listptr);
char *ccname;
Node *expr;
if (cdef->contype != CONSTR_CHECK || cdef->raw_expr == NULL)
continue;
@ -1851,17 +1841,21 @@ SetRelationNumChecks(Relation rel, int numchecks)
* Take a raw default and convert it to a cooked format ready for
* storage.
*
* Parse state, attypid, attypmod and attname are required for
* CoerceTargetExpr() and more importantly transformExpr().
* Parse state should be set up to recognize any vars that might appear
* in the expression. (Even though we plan to reject vars, it's more
* user-friendly to give the correct error message than "unknown var".)
*
* If atttypid is not InvalidOid, check that the expression is coercible
* to the specified type. atttypmod is needed in this case, and attname
* is used in the error message if any.
*/
Node *
cookDefault(ParseState *pstate,
Node *raw_default,
Oid atttypid,
int32 atttypmod,
char *attname) {
Oid type_id;
char *attname)
{
Node *expr;
Assert(raw_default != NULL);
@ -1896,22 +1890,20 @@ cookDefault(ParseState *pstate,
* will actually do the coercion, to ensure we don't accept an
* unusable default expression.
*/
type_id = exprType(expr);
if (type_id != InvalidOid && atttypid != InvalidOid) {
if (type_id != atttypid) {
if (OidIsValid(atttypid))
{
Oid type_id = exprType(expr);
/* Try coercing to the base type of the domain if available */
if (type_id != atttypid)
{
if (CoerceTargetExpr(pstate, expr, type_id,
getBaseType(atttypid),
atttypmod) == NULL) {
atttypid, atttypmod) == NULL)
elog(ERROR, "Column \"%s\" is of type %s"
" but default expression is of type %s"
"\n\tYou will need to rewrite or cast the expression",
" but default expression is of type %s"
"\n\tYou will need to rewrite or cast the expression",
attname,
format_type_be(atttypid),
format_type_be(type_id));
}
}
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.40 2001/10/25 05:49:23 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.41 2002/03/20 19:43:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -135,14 +135,13 @@ AggregateCreate(char *aggName,
/*
* If the transfn is strict and the initval is NULL, make sure input
* type and transtype are the same (or at least binary- compatible),
* type and transtype are the same (or at least binary-compatible),
* so that it's OK to use the first input value as the initial
* transValue.
*/
if (proc->proisstrict && agginitval == NULL)
{
if (basetype != transtype &&
!IS_BINARY_COMPATIBLE(basetype, transtype))
if (!IsBinaryCompatible(basetype, transtype))
elog(ERROR, "must not omit initval when transfn is strict and transtype is not compatible with input type");
}
ReleaseSysCache(tup);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.65 2002/03/06 06:09:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.66 2002/03/20 19:43:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -423,7 +423,7 @@ checkretval(Oid rettype, List *queryTreeList)
format_type_be(rettype));
restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
if (restype != rettype && !IS_BINARY_COMPATIBLE(restype, rettype))
if (!IsBinaryCompatible(restype, rettype))
elog(ERROR, "return type mismatch in function: declared to return %s, returns %s",
format_type_be(rettype), format_type_be(restype));
@ -440,7 +440,7 @@ checkretval(Oid rettype, List *queryTreeList)
if (tlistlen == 1)
{
restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
if (restype == rettype || IS_BINARY_COMPATIBLE(restype, rettype))
if (IsBinaryCompatible(restype, rettype))
return;
}
@ -470,7 +470,7 @@ checkretval(Oid rettype, List *queryTreeList)
continue;
tletype = exprType(tle->expr);
atttype = reln->rd_att->attrs[i]->atttypid;
if (tletype != atttype && !IS_BINARY_COMPATIBLE(tletype, atttype))
if (!IsBinaryCompatible(tletype, atttype))
elog(ERROR, "function declared to return %s returns %s instead of %s at column %d",
format_type_be(rettype),
format_type_be(tletype),

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.68 2002/03/19 02:18:14 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.69 2002/03/20 19:43:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -179,13 +179,11 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
values[i++] = CharGetDatum('i'); /* 15 */
values[i++] = CharGetDatum('p'); /* 16 */
values[i++] = BoolGetDatum(false); /* 17 */
values[i++] = Int32GetDatum(-1); /* 18 */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 19 */
values[i++] = ObjectIdGetDatum(InvalidOid); /* 18 */
values[i++] = Int32GetDatum(-1); /* 19 */
values[i++] = Int32GetDatum(0); /* 20 */
values[i++] = DirectFunctionCall1(textin,
CStringGetDatum(typeName)); /* 21 */
values[i++] = DirectFunctionCall1(textin,
CStringGetDatum(typeName)); /* 22 */
nulls[i++] = 'n'; /* 21 */
nulls[i++] = 'n'; /* 22 */
/*
* create a new type tuple with FormHeapTuple
@ -288,7 +286,7 @@ TypeCreate(char *typeName,
char storage,
int32 typeMod,
int32 typNDims, /* Array dimensions for baseTypeName */
bool typeNotNull) /* binary default representation (cooked) */
bool typeNotNull)
{
int i,
j;
@ -452,21 +450,10 @@ TypeCreate(char *typeName,
*/
values[i++] = CharGetDatum(storage); /* 16 */
/*
* set the typenotnull value
*/
values[i++] = BoolGetDatum(typeNotNull); /* 17 */
/*
* set the typemod value
*/
values[i++] = Int32GetDatum(typeMod); /* 18 */
values[i++] = ObjectIdGetDatum(baseObjectId); /* 19 */
/*
* Dimension number for an array base type
*/
/* 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 */
/*
@ -475,17 +462,17 @@ TypeCreate(char *typeName,
*/
if (defaultTypeBin)
values[i] = DirectFunctionCall1(textin,
CStringGetDatum(defaultTypeBin));
CStringGetDatum(defaultTypeBin));
else
nulls[i] = 'n';
i++; /* 21 */
i++; /* 21 */
/*
* initialize the default value for this type.
*/
if (defaultTypeValue)
values[i] = DirectFunctionCall1(textin,
CStringGetDatum(defaultTypeValue));
CStringGetDatum(defaultTypeValue));
else
nulls[i] = 'n';
i++; /* 22 */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.87 2002/03/19 02:58:19 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.88 2002/03/20 19:43:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -42,6 +42,7 @@ static int findAttrByName(const char *attributeName, List *schema);
static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
static List *MergeDomainAttributes(List *schema);
/* ----------------------------------------------------------------
* DefineRelation
* Creates a new relation.
@ -71,9 +72,9 @@ DefineRelation(CreateStmt *stmt, char relkind)
StrNCpy(relname, stmt->relname, NAMEDATALEN);
/*
* Inherit domain attributes into the known columns before table inheritance
* applies it's changes otherwise we risk adding double constraints
* to a domain thats inherited.
* Merge domain attributes into the known columns before processing table
* inheritance. Otherwise we risk adding double constraints to a
* domain-type column that's inherited.
*/
schema = MergeDomainAttributes(schema);
@ -273,11 +274,8 @@ TruncateRelation(const char *relname)
/*
* MergeDomainAttributes
* Returns a new table schema with the constraints, types, and other
* attributes of the domain resolved for fields using the domain as
* their type.
*
* Defaults are pulled out by the table attribute as required, similar to
* how all types defaults are processed.
* attributes of domains resolved for fields using a domain as
* their type.
*/
static List *
MergeDomainAttributes(List *schema)
@ -295,34 +293,25 @@ 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);
typeTup = (Form_pg_type) GETSTRUCT(tuple);
if (typeTup->typtype == 'd') {
/*
* This is a domain, lets force the properties of the domain on to
* the new column.
*/
/* Enforce the typmod value */
coldef->typename->typmod = typeTup->typmod;
/* Enforce type NOT NULL || column definition NOT NULL -> NOT NULL */
coldef->is_not_null |= typeTup->typnotnull;
/* Enforce the element type in the event the domain is an array
*
* BUG: How do we fill out arrayBounds and attrname from typelem and typNDimms?
*/
if (typeTup->typtype == 'd')
{
/* Force the column to have the correct typmod. */
coldef->typename->typmod = typeTup->typtypmod;
/* XXX more to do here? */
}
/* Enforce type NOT NULL || column definition NOT NULL -> NOT NULL */
/* Currently only used for domains, but could be valid for all */
coldef->is_not_null |= typeTup->typnotnull;
ReleaseSysCache(tuple);
}

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.70 2002/03/19 02:18:15 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.71 2002/03/20 19:43:44 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@ -483,38 +483,29 @@ DefineAggregate(char *aggName, List *parameters)
void
DefineDomain(CreateDomainStmt *stmt)
{
int16 internalLength = -1; /* int2 */
int16 externalLength = -1; /* int2 */
char *inputName = NULL;
char *outputName = NULL;
char *sendName = NULL;
char *receiveName = NULL;
/*
* Domains store the external representation in defaultValue
* and the interal Node representation in defaultValueBin
*/
char *defaultValue = NULL;
char *defaultValueBin = NULL;
bool byValue = false;
char delimiter = DEFAULT_TYPDELIM;
char alignment = 'i'; /* default alignment */
char storage = 'p'; /* default TOAST storage method */
int16 internalLength;
int16 externalLength;
char *inputName;
char *outputName;
char *sendName;
char *receiveName;
bool byValue;
char delimiter;
char alignment;
char storage;
char typtype;
Datum datum;
bool isnull;
char *defaultValue = NULL;
char *defaultValueBin = NULL;
bool typNotNull = false;
Oid basetypelem;
char *elemName = NULL;
int32 typNDims = 0; /* No array dimensions by default */
bool isnull;
Relation pg_type_rel;
TupleDesc pg_type_dsc;
HeapTuple typeTup;
char *typeName = stmt->typename->name;
List *listptr;
List *schema = stmt->constraints;
List *listptr;
/*
* Domainnames, unlike typenames don't need to account for the '_'
@ -524,25 +515,13 @@ DefineDomain(CreateDomainStmt *stmt)
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
);
typeTup = SearchSysCache(TYPENAME,
PointerGetDatum(stmt->domainname),
0, 0, 0);
if (HeapTupleIsValid(typeTup))
{
elog(ERROR, "CREATE DOMAIN: domain or type %s already exists",
elog(ERROR, "CREATE DOMAIN: domain or type %s already exists",
stmt->domainname);
}
/*
* Get the information about old types
*/
pg_type_rel = heap_openr(TypeRelationName, RowExclusiveLock);
pg_type_dsc = RelationGetDescr(pg_type_rel);
/*
* When the type is an array for some reason we don't actually receive
@ -555,22 +534,12 @@ DefineDomain(CreateDomainStmt *stmt)
typNDims = length(stmt->typename->arrayBounds);
}
typeTup = SearchSysCache( TYPENAME
, PointerGetDatum(typeName)
, 0, 0, 0
);
typeTup = SearchSysCache(TYPENAME,
PointerGetDatum(typeName),
0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
elog(ERROR, "CREATE DOMAIN: type %s does not exist",
stmt->typename->name);
}
/* Check that this is a basetype */
typtype = DatumGetChar(heap_getattr(typeTup, Anum_pg_type_typtype, pg_type_dsc, &isnull));
Assert(!isnull);
/*
* What we really don't want is domains of domains. This could cause all sorts
@ -578,9 +547,10 @@ DefineDomain(CreateDomainStmt *stmt)
*
* With testing, we may determine complex types should be allowed
*/
if (typtype != 'b') {
elog(ERROR, "DefineDomain: %s is not a basetype", stmt->typename->name);
}
typtype = ((Form_pg_type) GETSTRUCT(typeTup))->typtype;
if (typtype != 'b')
elog(ERROR, "DefineDomain: %s is not a basetype",
stmt->typename->name);
/* passed by value */
byValue = ((Form_pg_type) GETSTRUCT(typeTup))->typbyval;
@ -588,6 +558,9 @@ DefineDomain(CreateDomainStmt *stmt)
/* Required Alignment */
alignment = ((Form_pg_type) GETSTRUCT(typeTup))->typalign;
/* TOAST Strategy */
storage = ((Form_pg_type) GETSTRUCT(typeTup))->typstorage;
/* Storage Length */
internalLength = ((Form_pg_type) GETSTRUCT(typeTup))->typlen;
@ -597,70 +570,66 @@ 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 = heap_getattr(typeTup, Anum_pg_type_typinput, pg_type_dsc, &isnull);
datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typinput, &isnull);
Assert(!isnull);
inputName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
/* Output Function Name */
datum = heap_getattr(typeTup, Anum_pg_type_typoutput, pg_type_dsc, &isnull);
datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typoutput, &isnull);
Assert(!isnull);
outputName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
/* ReceiveName */
datum = heap_getattr(typeTup, Anum_pg_type_typreceive, pg_type_dsc, &isnull);
datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typreceive, &isnull);
Assert(!isnull);
receiveName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
/* SendName */
datum = heap_getattr(typeTup, Anum_pg_type_typsend, pg_type_dsc, &isnull);
datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typsend, &isnull);
Assert(!isnull);
sendName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
/* TOAST Strategy */
storage = ((Form_pg_type) GETSTRUCT(typeTup))->typstorage;
Assert(!isnull);
/* Inherited default value */
datum = heap_getattr(typeTup, Anum_pg_type_typdefault, pg_type_dsc, &isnull);
if (!isnull) {
defaultValue = DatumGetCString(DirectFunctionCall1(textout, datum));
}
datum = SysCacheGetAttr(TYPENAME, typeTup,
Anum_pg_type_typdefault, &isnull);
if (!isnull)
defaultValue = DatumGetCString(DirectFunctionCall1(textout, datum));
/* Inherited default binary value */
datum = heap_getattr(typeTup, Anum_pg_type_typdefaultbin, pg_type_dsc, &isnull);
if (!isnull) {
defaultValueBin = DatumGetCString(DirectFunctionCall1(textout, datum));
}
datum = SysCacheGetAttr(TYPENAME, typeTup,
Anum_pg_type_typdefaultbin, &isnull);
if (!isnull)
defaultValueBin = DatumGetCString(DirectFunctionCall1(textout, datum));
/*
* Pull out the typelem name of the parent OID.
*
* This is what enables us to make a domain of an array
*/
datum = heap_getattr(typeTup, Anum_pg_type_typelem, pg_type_dsc, &isnull);
Assert(!isnull);
if (DatumGetObjectId(datum) != InvalidOid) {
basetypelem = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
if (basetypelem != InvalidOid)
{
HeapTuple tup;
tup = SearchSysCache( TYPEOID
, datum
, 0, 0, 0
);
elemName = NameStr(((Form_pg_type) GETSTRUCT(tup))->typname);
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(basetypelem),
0, 0, 0);
elemName = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(tup))->typname));
ReleaseSysCache(tup);
}
/*
* Run through constraints manually avoids the additional
* Run through constraints manually to avoid the additional
* processing conducted by DefineRelation() and friends.
*
* Besides, we don't want any constraints to be cooked. We'll
@ -668,20 +637,13 @@ DefineDomain(CreateDomainStmt *stmt)
*/
foreach(listptr, schema)
{
Constraint *colDef = lfirst(listptr);
bool nullDefined = false;
Node *expr;
Constraint *colDef = lfirst(listptr);
/* Used for the statement transformation */
ParseState *pstate;
/*
* Create a dummy ParseState and insert the target relation as its
* sole rangetable entry. We need a ParseState for transformExpr.
*/
pstate = make_parsestate(NULL);
switch(colDef->contype) {
switch (colDef->contype)
{
/*
* The inherited default value may be overridden by the user
* with the DEFAULT <expr> statement.
@ -690,27 +652,26 @@ DefineDomain(CreateDomainStmt *stmt)
* don't want to cook or fiddle too much.
*/
case CONSTR_DEFAULT:
/* Create a dummy ParseState for transformExpr */
pstate = make_parsestate(NULL);
/*
* Cook the colDef->raw_expr into an expression to ensure
* that it can be done. We store the text version of the
* raw value.
*
* Cook the colDef->raw_expr into an expression.
* Note: Name is strictly for error message
*/
expr = cookDefault(pstate, colDef->raw_expr
, typeTup->t_data->t_oid
, stmt->typename->typmod
, stmt->typename->name);
/* Binary default required */
expr = cookDefault(pstate, colDef->raw_expr,
typeTup->t_data->t_oid,
stmt->typename->typmod,
stmt->typename->name);
/*
* 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,
InvalidOid),
false);
defaultValueBin = nodeToString(expr);
break;
/*
@ -723,7 +684,6 @@ DefineDomain(CreateDomainStmt *stmt)
typNotNull = true;
nullDefined = true;
}
break;
case CONSTR_NULL:
@ -733,31 +693,31 @@ DefineDomain(CreateDomainStmt *stmt)
typNotNull = false;
nullDefined = true;
}
break;
case CONSTR_UNIQUE:
elog(ERROR, "CREATE DOMAIN / UNIQUE indecies not supported");
elog(ERROR, "CREATE DOMAIN / UNIQUE indexes not supported");
break;
case CONSTR_PRIMARY:
elog(ERROR, "CREATE DOMAIN / PRIMARY KEY indecies not supported");
elog(ERROR, "CREATE DOMAIN / PRIMARY KEY indexes not supported");
break;
case CONSTR_CHECK:
elog(ERROR, "defineDomain: CHECK Constraints not supported");
elog(ERROR, "DefineDomain: CHECK Constraints not supported");
break;
case CONSTR_ATTR_DEFERRABLE:
case CONSTR_ATTR_NOT_DEFERRABLE:
case CONSTR_ATTR_DEFERRED:
case CONSTR_ATTR_IMMEDIATE:
elog(ERROR, "defineDomain: DEFERRABLE, NON DEFERRABLE, DEFERRED and IMMEDIATE not supported");
elog(ERROR, "DefineDomain: DEFERRABLE, NON DEFERRABLE, DEFERRED and IMMEDIATE not supported");
break;
default:
elog(ERROR, "DefineDomain: unrecognized constraint node type");
break;
}
}
/*
@ -776,8 +736,8 @@ DefineDomain(CreateDomainStmt *stmt)
sendName, /* send procedure */
elemName, /* element type name */
typeName, /* base type name */
defaultValue, /* default type value */
defaultValueBin, /* default type value */
defaultValue, /* default type value (text) */
defaultValueBin, /* default type value (binary) */
byValue, /* passed by value */
alignment, /* required alignment */
storage, /* TOAST strategy */
@ -789,10 +749,8 @@ DefineDomain(CreateDomainStmt *stmt)
* Now we can clean up.
*/
ReleaseSysCache(typeTup);
heap_close(pg_type_rel, NoLock);
}
/*
* DefineType
* Registers a new type.
@ -808,8 +766,6 @@ DefineType(char *typeName, List *parameters)
char *sendName = NULL;
char *receiveName = NULL;
char *defaultValue = NULL;
char *defaultValueBin = NULL;
Node *defaultRaw = (Node *) NULL;
bool byValue = false;
char delimiter = DEFAULT_TYPDELIM;
char *shadow_type;
@ -851,7 +807,7 @@ DefineType(char *typeName, List *parameters)
else if (strcasecmp(defel->defname, "element") == 0)
elemName = defGetString(defel);
else if (strcasecmp(defel->defname, "default") == 0)
defaultRaw = defel->arg;
defaultValue = defGetString(defel);
else if (strcasecmp(defel->defname, "passedbyvalue") == 0)
byValue = true;
else if (strcasecmp(defel->defname, "alignment") == 0)
@ -911,32 +867,6 @@ DefineType(char *typeName, List *parameters)
if (outputName == NULL)
elog(ERROR, "Define: \"output\" unspecified");
if (defaultRaw) {
Node *expr;
ParseState *pstate;
/*
* Create a dummy ParseState and insert the target relation as its
* sole rangetable entry. We need a ParseState for transformExpr.
*/
pstate = make_parsestate(NULL);
expr = cookDefault(pstate, defaultRaw,
InvalidOid,
-1,
typeName);
/* Binary default required */
defaultValue = deparse_expression(expr,
deparse_context_for(typeName,
InvalidOid),
false);
defaultValueBin = nodeToString(expr);
}
/*
* now have TypeCreate do all the real work.
*/
@ -952,9 +882,9 @@ DefineType(char *typeName, List *parameters)
receiveName, /* receive procedure */
sendName, /* send procedure */
elemName, /* element type name */
NULL, /* base type name (Non-zero for domains) */
NULL, /* base type name (only for domains) */
defaultValue, /* default type value */
defaultValueBin, /* default type value (Binary form) */
NULL, /* no binary form available */
byValue, /* passed by value */
alignment, /* required alignment */
storage, /* TOAST strategy */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.63 2002/03/06 06:09:33 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.64 2002/03/20 19:43:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -314,8 +314,7 @@ FuncIndexArgs(IndexInfo *indexInfo,
for (i = 0; i < nargs; i++)
{
if (argTypes[i] != true_typeids[i] &&
!IS_BINARY_COMPATIBLE(argTypes[i], true_typeids[i]))
if (!IsBinaryCompatible(argTypes[i], true_typeids[i]))
func_error("DefineIndex", funcIndex->name, nargs, argTypes,
"Index function must be binary-compatible with table datatype");
}
@ -418,8 +417,7 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype;
ReleaseSysCache(tuple);
if (attrType != opInputType &&
!IS_BINARY_COMPATIBLE(attrType, opInputType))
if (!IsBinaryCompatible(attrType, opInputType))
elog(ERROR, "operator class \"%s\" does not accept data type %s",
attribute->class, format_type_be(attrType));
@ -470,7 +468,7 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId)
nexact++;
exactOid = tuple->t_data->t_oid;
}
else if (IS_BINARY_COMPATIBLE(opclass->opcintype, attrType))
else if (IsBinaryCompatible(opclass->opcintype, attrType))
{
ncompatible++;
compatibleOid = tuple->t_data->t_oid;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.69 2002/03/19 02:18:16 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.70 2002/03/20 19:43:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -282,23 +282,18 @@ RemoveType(char *typeName) /* type name to be removed */
* use it.
*/
void
RemoveDomain(char *domainName, int behavior) /* domain name to be removed */
RemoveDomain(char *domainName, int behavior)
{
Relation relation;
HeapTuple tup;
TupleDesc description;
char typtype;
bool isnull;
/* Domains are stored as types. Check for permissions on the type */
if (!pg_ownercheck(GetUserId(), domainName, TYPENAME))
elog(ERROR, "RemoveDomain: type '%s': permission denied",
domainName);
relation = heap_openr(TypeRelationName, RowExclusiveLock);
description = RelationGetDescr(relation);
tup = SearchSysCache(TYPENAME,
PointerGetDatum(domainName),
@ -306,14 +301,11 @@ RemoveDomain(char *domainName, int behavior) /* domain name to be removed */
if (!HeapTupleIsValid(tup))
elog(ERROR, "RemoveType: type '%s' does not exist", domainName);
/* Check that this is actually a domain */
typtype = DatumGetChar(heap_getattr(tup, Anum_pg_type_typtype, description, &isnull));
Assert(!isnull);
typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype;
if (typtype != 'd') {
if (typtype != 'd')
elog(ERROR, "%s is not a domain", domainName);
}
/* CASCADE unsupported */
if (behavior == CASCADE) {

View File

@ -46,7 +46,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.79 2002/03/02 21:39:25 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.80 2002/03/20 19:43:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -896,8 +896,7 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
*/
Oid inputType = exprType(aggref->target);
if (inputType != aggform->aggtranstype &&
!IS_BINARY_COMPATIBLE(inputType, aggform->aggtranstype))
if (!IsBinaryCompatible(inputType, aggform->aggtranstype))
elog(ERROR, "Aggregate %s needs to have compatible input type and transition type",
aggname);
}

View File

@ -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.170 2002/03/19 02:18:16 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.171 2002/03/20 19:43:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -2026,6 +2026,7 @@ _copyDropStmt(DropStmt *from)
Node_Copy(from, newnode, names);
newnode->removeType = from->removeType;
newnode->behavior = from->behavior;
return newnode;
}
@ -2238,7 +2239,6 @@ _copyCreateDomainStmt(CreateDomainStmt *from)
if (from->domainname)
newnode->domainname = pstrdup(from->domainname);
Node_Copy(from, newnode, typename);
Node_Copy(from, newnode, constraints);

View File

@ -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.118 2002/03/19 02:18:16 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.119 2002/03/20 19:44:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -878,6 +878,8 @@ _equalDropStmt(DropStmt *a, DropStmt *b)
return false;
if (a->removeType != b->removeType)
return false;
if (a->behavior != b->behavior)
return false;
return true;
}

View File

@ -8,16 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.26 2001/03/22 03:59:32 momjian Exp $
*
* NOTES
* Creator functions in POSTGRES 4.2 are generated automatically. Most of
* them are rarely used. Now we don't generate them any more. If you want
* one, you have to write it yourself.
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
* Andrew Yu Oct 20, 1994 file creation
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.27 2002/03/20 19:44:04 tgl Exp $
*/
#include "postgres.h"
@ -184,3 +175,19 @@ makeAttr(char *relname, char *attname)
return a;
}
/*
* makeRelabelType -
* creates a RelabelType node
*/
RelabelType *
makeRelabelType(Node *arg, Oid rtype, int32 rtypmod)
{
RelabelType *r = makeNode(RelabelType);
r->arg = arg;
r->resulttype = rtype;
r->resulttypmod = rtypmod;
return r;
}

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.113 2002/03/02 21:39:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.114 2002/03/20 19:44:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -900,9 +900,9 @@ indexable_operator(Expr *clause, Oid opclass, bool indexkey_on_left)
*/
if (ltype == indexkeytype && rtype == indexkeytype)
return InvalidOid; /* no chance for a different operator */
if (ltype != indexkeytype && !IS_BINARY_COMPATIBLE(ltype, indexkeytype))
if (!IsBinaryCompatible(ltype, indexkeytype))
return InvalidOid;
if (rtype != indexkeytype && !IS_BINARY_COMPATIBLE(rtype, indexkeytype))
if (!IsBinaryCompatible(rtype, indexkeytype))
return InvalidOid;
/*

View File

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.49 2002/03/19 02:18:17 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.50 2002/03/20 19:44:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -355,9 +355,9 @@ build_column_default(Relation rel, int attrno)
Form_pg_attribute att_tup = rd_att->attrs[attrno - 1];
Oid atttype = att_tup->atttypid;
int32 atttypmod = att_tup->atttypmod;
int16 typlen;
bool typbyval;
Node *expr;
int16 typlen = att_tup->attlen;
bool typbyval = att_tup->attbyval;
Node *expr = NULL;
/*
* Scan to see if relation has a default for this column.
@ -371,110 +371,86 @@ build_column_default(Relation rel, int attrno)
{
if (attrno == defval[ndef].adnum)
{
Oid type_id;
/*
* Found it, convert string representation to node tree.
*/
expr = stringToNode(defval[ndef].adbin);
/*
* Make sure the value is coerced to the target column
* type (might not be right type yet if it's not a
* constant!) This should match the parser's processing of
* non-defaulted expressions --- see
* updateTargetListEntry().
*/
type_id = exprType(expr);
if (type_id != atttype)
{
expr = CoerceTargetExpr(NULL, expr, type_id,
getBaseType(atttype), atttypmod);
/*
* This really shouldn't fail; should have checked the
* default's type when it was created ...
*/
if (expr == NULL)
elog(ERROR, "Column \"%s\" is of type %s"
" but default expression is of type %s"
"\n\tYou will need to rewrite or cast the expression",
NameStr(att_tup->attname),
format_type_be(atttype),
format_type_be(type_id));
}
/*
* If the column is a fixed-length type, it may need a
* length coercion as well as a type coercion.
*/
expr = coerce_type_typmod(NULL, expr,
atttype, atttypmod);
return expr;
break;
}
}
}
/*
* No per-column default, so look for a default for the type itself.
* If there isn't one, we generate a NULL constant of the correct
* type.
*/
if (att_tup->attisset)
if (expr == NULL)
{
/*
* Set attributes are represented as OIDs no matter what the set
* element type is, and the element type's default is irrelevant
* too.
* No per-column default, so look for a default for the type itself.
*/
typlen = sizeof(Oid);
typbyval = true;
if (att_tup->attisset)
{
/*
* Set attributes are represented as OIDs no matter what the set
* element type is, and the element type's default is irrelevant
* too.
*/
typlen = sizeof(Oid);
typbyval = true;
}
else
{
expr = get_typdefault(atttype);
}
}
if (expr == NULL)
{
/*
* No default anywhere, so generate a NULL constant.
*/
expr = (Node *) makeConst(atttype,
typlen,
(Datum) 0,
true,
true, /* isnull */
typbyval,
false, /* not a set */
false, /* not a set */
false);
}
else
{
#ifdef _DROP_COLUMN_HACK__
if (COLUMN_IS_DROPPED(att_tup))
Oid exprtype;
/*
* Make sure the value is coerced to the target column
* type (might not be right type yet if it's not a
* constant!) This should match the parser's processing of
* non-defaulted expressions --- see
* updateTargetListEntry().
*/
exprtype = exprType(expr);
if (exprtype != atttype)
{
expr = CoerceTargetExpr(NULL, expr, exprtype,
atttype, atttypmod);
expr = (Node *) makeConst(atttype,
typlen,
(Datum) 0,
true,
typbyval,
false, /* not a set */
false);
/*
* This really shouldn't fail; should have checked the
* default's type when it was created ...
*/
if (expr == NULL)
elog(ERROR, "Column \"%s\" is of type %s"
" but default expression is of type %s"
"\n\tYou will need to rewrite or cast the expression",
NameStr(att_tup->attname),
format_type_be(atttype),
format_type_be(exprtype));
}
else
#endif /* _DROP_COLUMN_HACK__ */
expr = get_typdefault(atttype, atttypmod);
if (expr == NULL) {
expr = (Node *) makeConst(atttype,
typlen,
(Datum) 0,
true,
typbyval,
false, /* not a set */
false);
}
get_typlenbyval(atttype, &typlen, &typbyval);
/*
* If the column is a fixed-length type, it may need a
* length coercion as well as a type coercion.
*/
expr = coerce_type_typmod(NULL, expr, atttype, atttypmod);
}
/*
* If the column is a fixed-length type, it may need a length coercion
* as well as a type coercion, as well as direction to the final type.
*/
expr = coerce_type_typmod(NULL, expr,
atttype, atttypmod);
return expr;
}

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.293 2002/03/19 12:52:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.294 2002/03/20 19:44:21 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -135,8 +135,7 @@ static void doNegateFloat(Value *v);
ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,
CopyStmt, CreateAsStmt, CreateDomainStmt, CreateGroupStmt, CreatePLangStmt,
CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
CreateUserStmt, CreatedbStmt, CursorStmt,
DefineStmt, DeleteStmt,
CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
@ -151,7 +150,7 @@ static void doNegateFloat(Value *v);
simple_select
%type <node> alter_column_default
%type <ival> drop_behavior
%type <ival> drop_behavior, opt_drop_behavior
%type <list> createdb_opt_list, createdb_opt_item
%type <boolean> opt_equal
@ -1181,6 +1180,10 @@ drop_behavior: CASCADE { $$ = CASCADE; }
| RESTRICT { $$ = RESTRICT; }
;
opt_drop_behavior: CASCADE { $$ = CASCADE; }
| RESTRICT { $$ = RESTRICT; }
| /* EMPTY */ { $$ = RESTRICT; /* default */ }
;
/*****************************************************************************
@ -2030,22 +2033,13 @@ def_list: def_elem { $$ = makeList1($1); }
| def_list ',' def_elem { $$ = lappend($1, $3); }
;
def_elem: DEFAULT '=' b_expr
{
$$ = makeNode(DefElem);
$$->defname = "default";
if (exprIsNullConstant($3))
$$->arg = (Node *)NULL;
else
$$->arg = $3;
}
| ColId '=' def_arg
def_elem: ColLabel '=' def_arg
{
$$ = makeNode(DefElem);
$$->defname = $1;
$$->arg = (Node *)$3;
}
| ColId
| ColLabel
{
$$ = makeNode(DefElem);
$$->defname = $1;
@ -2069,19 +2063,11 @@ def_arg: func_return { $$ = (Node *)$1; }
*
*****************************************************************************/
DropStmt: DROP drop_type name_list
DropStmt: DROP drop_type name_list opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
n->removeType = $2;
n->names = $3;
n->behavior = RESTRICT; /* Restricted by default */
$$ = (Node *)n;
}
| DROP DOMAIN_P name_list drop_behavior
{
DropStmt *n = makeNode(DropStmt);
n->removeType = DROP_DOMAIN_P;
n->names = $3;
n->behavior = $4;
$$ = (Node *)n;
}
@ -2092,7 +2078,8 @@ drop_type: TABLE { $$ = DROP_TABLE; }
| VIEW { $$ = DROP_VIEW; }
| INDEX { $$ = DROP_INDEX; }
| RULE { $$ = DROP_RULE; }
| TYPE_P { $$ = DROP_TYPE_P; }
| TYPE_P { $$ = DROP_TYPE; }
| DOMAIN_P { $$ = DROP_DOMAIN; }
;
/*****************************************************************************
@ -3194,22 +3181,6 @@ createdb_opt_item: LOCATION opt_equal Sconst
}
;
/*****************************************************************************
*
* DROP DATABASE
*
*
*****************************************************************************/
DropdbStmt: DROP DATABASE database_name
{
DropdbStmt *n = makeNode(DropdbStmt);
n->dbname = $3;
$$ = (Node *)n;
}
;
/*
* Though the equals sign doesn't match other WITH options, pg_dump uses
* equals for backward compability, and it doesn't seem worth remove it.
@ -3221,8 +3192,22 @@ opt_equal: '=' { $$ = TRUE; }
/*****************************************************************************
*
* ALTER DATABASE
* DROP DATABASE
*
*****************************************************************************/
DropdbStmt: DROP DATABASE database_name
{
DropdbStmt *n = makeNode(DropdbStmt);
n->dbname = $3;
$$ = (Node *)n;
}
;
/*****************************************************************************
*
* ALTER DATABASE
*
*****************************************************************************/

View File

@ -8,25 +8,31 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.67 2002/03/19 02:18:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.68 2002/03/20 19:44:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/pg_proc.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
Oid DemoteType(Oid inType);
Oid PromoteTypeToNext(Oid inType);
static Oid PreferredType(CATEGORY category, Oid type);
static Node *build_func_call(Oid funcid, Oid rettype, List *args);
static Oid find_coercion_function(Oid targetTypeId, Oid inputTypeId,
Oid secondArgType);
/* coerce_type()
@ -87,32 +93,28 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
result = (Node *) newcon;
}
else if (IS_BINARY_COMPATIBLE(inputTypeId, targetTypeId))
else if (IsBinaryCompatible(inputTypeId, targetTypeId))
{
/*
* We don't really need to do a conversion, but we do need to
* attach a RelabelType node so that the expression will be seen
* to have the intended type when inspected by higher-level code.
*/
RelabelType *relabel = makeNode(RelabelType);
relabel->arg = node;
relabel->resulttype = targetTypeId;
/*
*
* XXX could we label result with exprTypmod(node) instead of
* default -1 typmod, to save a possible length-coercion later?
* Would work if both types have same interpretation of typmod,
* which is likely but not certain.
*/
relabel->resulttypmod = -1;
result = (Node *) relabel;
result = (Node *) makeRelabelType(node, targetTypeId, -1);
}
else if (typeInheritsFrom(inputTypeId, targetTypeId))
{
/* Input class type is a subclass of target, so nothing to do */
result = node;
/*
* Input class type is a subclass of target, so nothing to do
* --- except relabel the type. This is binary compatibility
* for complex types.
*/
result = (Node *) makeRelabelType(node, targetTypeId, -1);
}
else
{
@ -121,21 +123,24 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
* (caller should have determined that there is one), and generate
* an expression tree representing run-time application of the
* conversion function.
*
* For domains, we use the coercion function for the base type.
*/
FuncCall *n = makeNode(FuncCall);
Oid baseTypeId = getBaseType(targetTypeId);
Oid funcId;
n->funcname = typeidTypeName(targetTypeId);
n->args = makeList1(node);
n->agg_star = false;
n->agg_distinct = false;
funcId = find_coercion_function(baseTypeId,
getBaseType(inputTypeId),
InvalidOid);
if (!OidIsValid(funcId))
elog(ERROR, "coerce_type: no conversion function from %s to %s",
format_type_be(inputTypeId), format_type_be(targetTypeId));
result = transformExpr(pstate, (Node *) n, EXPR_COLUMN_FIRST);
result = build_func_call(funcId, baseTypeId, makeList1(node));
/* safety check that we got the right thing */
if (exprType(result) != targetTypeId)
elog(ERROR, "coerce_type: conversion function %s produced %s",
typeidTypeName(targetTypeId),
typeidTypeName(exprType(result)));
/* if domain, relabel with domain type ID */
if (targetTypeId != baseTypeId)
result = (Node *) makeRelabelType(result, targetTypeId, -1);
/*
* If the input is a constant, apply the type conversion function
@ -152,7 +157,8 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
* nodes that mustn't be collapsed. (It'd be a lot cleaner to
* make a separate node type for that purpose...)
*/
if (IsA(node, Const) &&!((Const *) node)->constisnull)
if (IsA(node, Const) &&
!((Const *) node)->constisnull)
result = eval_const_expressions(result);
}
@ -169,23 +175,18 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
*
* Notes:
* This uses the same mechanism as the CAST() SQL construct in gram.y.
* We should also check the function return type on candidate conversion
* routines just to be safe but we do not do that yet...
* - thomas 1998-03-31
*/
bool
can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
{
int i;
HeapTuple ftup;
Form_pg_proc pform;
Oid oid_array[FUNC_MAX_ARGS];
/* run through argument list... */
for (i = 0; i < nargs; i++)
{
Oid inputTypeId = input_typeids[i];
Oid targetTypeId = func_typeids[i];
Oid funcId;
/* no problem if same type */
if (inputTypeId == targetTypeId)
@ -195,7 +196,7 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
* one of the known-good transparent conversions? then drop
* through...
*/
if (IS_BINARY_COMPATIBLE(inputTypeId, targetTypeId))
if (IsBinaryCompatible(inputTypeId, targetTypeId))
continue;
/* don't know what to do for the output type? then quit... */
@ -232,25 +233,14 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
* Else, try for explicit conversion using functions: look for a
* single-argument function named with the target type name and
* accepting the source type.
*
* If either type is a domain, use its base type instead.
*/
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
oid_array[0] = inputTypeId;
ftup = SearchSysCache(PROCNAME,
PointerGetDatum(typeidTypeName(targetTypeId)),
Int32GetDatum(1),
PointerGetDatum(oid_array),
0);
if (!HeapTupleIsValid(ftup))
funcId = find_coercion_function(getBaseType(targetTypeId),
getBaseType(inputTypeId),
InvalidOid);
if (!OidIsValid(funcId))
return false;
/* Make sure the function's result type is as expected, too */
pform = (Form_pg_proc) GETSTRUCT(ftup);
if (pform->prorettype != targetTypeId)
{
ReleaseSysCache(ftup);
return false;
}
ReleaseSysCache(ftup);
}
return true;
@ -277,8 +267,8 @@ Node *
coerce_type_typmod(ParseState *pstate, Node *node,
Oid targetTypeId, int32 atttypmod)
{
char *funcname;
Oid oid_array[FUNC_MAX_ARGS];
Oid baseTypeId;
Oid funcId;
/*
* A negative typmod is assumed to mean that no coercion is wanted.
@ -286,30 +276,28 @@ coerce_type_typmod(ParseState *pstate, Node *node,
if (atttypmod < 0 || atttypmod == exprTypmod(node))
return node;
funcname = typeidTypeName(targetTypeId);
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
oid_array[0] = targetTypeId;
oid_array[1] = INT4OID;
/* If given type is a domain, use base type instead */
baseTypeId = getBaseType(targetTypeId);
/* attempt to find with arguments exactly as specified... */
if (SearchSysCacheExists(PROCNAME,
PointerGetDatum(funcname),
Int32GetDatum(2),
PointerGetDatum(oid_array),
0))
funcId = find_coercion_function(baseTypeId, baseTypeId, INT4OID);
if (OidIsValid(funcId))
{
A_Const *cons = makeNode(A_Const);
FuncCall *func = makeNode(FuncCall);
Const *cons;
cons->val.type = T_Integer;
cons->val.val.ival = atttypmod;
cons = makeConst(INT4OID,
sizeof(int32),
Int32GetDatum(atttypmod),
false,
true,
false,
false);
func->funcname = funcname;
func->args = makeList2(node, cons);
func->agg_star = false;
func->agg_distinct = false;
node = build_func_call(funcId, baseTypeId, makeList2(node, cons));
node = transformExpr(pstate, (Node *) func, EXPR_COLUMN_FIRST);
/* relabel if it's domain case */
if (targetTypeId != baseTypeId)
node = (Node *) makeRelabelType(node, targetTypeId, atttypmod);
}
return node;
@ -532,6 +520,64 @@ TypeCategory(Oid inType)
} /* TypeCategory() */
/* IsBinaryCompatible()
* Check if two types are binary-compatible.
*
* This notion allows us to cheat and directly exchange values without
* going through the trouble of calling a conversion function.
*
* XXX This should be moved to system catalog lookups
* to allow for better type extensibility.
*/
/*
* This macro describes hard-coded knowledge of binary compatibility
* for built-in types.
*/
#define IS_BINARY_COMPATIBLE(a,b) \
(((a) == BPCHAROID && (b) == TEXTOID) \
|| ((a) == BPCHAROID && (b) == VARCHAROID) \
|| ((a) == VARCHAROID && (b) == TEXTOID) \
|| ((a) == VARCHAROID && (b) == BPCHAROID) \
|| ((a) == TEXTOID && (b) == BPCHAROID) \
|| ((a) == TEXTOID && (b) == VARCHAROID) \
|| ((a) == OIDOID && (b) == INT4OID) \
|| ((a) == OIDOID && (b) == REGPROCOID) \
|| ((a) == INT4OID && (b) == OIDOID) \
|| ((a) == INT4OID && (b) == REGPROCOID) \
|| ((a) == REGPROCOID && (b) == OIDOID) \
|| ((a) == REGPROCOID && (b) == INT4OID) \
|| ((a) == ABSTIMEOID && (b) == INT4OID) \
|| ((a) == INT4OID && (b) == ABSTIMEOID) \
|| ((a) == RELTIMEOID && (b) == INT4OID) \
|| ((a) == INT4OID && (b) == RELTIMEOID) \
|| ((a) == INETOID && (b) == CIDROID) \
|| ((a) == CIDROID && (b) == INETOID) \
|| ((a) == BITOID && (b) == VARBITOID) \
|| ((a) == VARBITOID && (b) == BITOID))
bool
IsBinaryCompatible(Oid type1, Oid type2)
{
if (type1 == type2)
return true;
if (IS_BINARY_COMPATIBLE(type1, type2))
return true;
/*
* Perhaps the types are domains; if so, look at their base types
*/
if (OidIsValid(type1))
type1 = getBaseType(type1);
if (OidIsValid(type2))
type2 = getBaseType(type2);
if (type1 == type2)
return true;
if (IS_BINARY_COMPATIBLE(type1, type2))
return true;
return false;
}
/* IsPreferredType()
* Check if this type is a preferred type.
* XXX This should be moved to system catalog lookups
@ -606,31 +652,81 @@ PreferredType(CATEGORY category, Oid type)
return result;
} /* PreferredType() */
/*
* find_coercion_function
* Look for a coercion function between two types.
*
* A coercion function must be named after (the internal name of) its
* result type, and must accept exactly the specified input type.
*
* This routine is also used to look for length-coercion functions, which
* are similar but accept a second argument. secondArgType is the type
* of the second argument (normally INT4OID), or InvalidOid if we are
* looking for a regular coercion function.
*
* If a function is found, return its pg_proc OID; else return InvalidOid.
*/
static Oid
find_coercion_function(Oid targetTypeId, Oid inputTypeId, Oid secondArgType)
{
char *funcname;
Oid oid_array[FUNC_MAX_ARGS];
int nargs;
HeapTuple ftup;
Form_pg_proc pform;
Oid funcid;
funcname = typeidTypeName(targetTypeId);
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
oid_array[0] = inputTypeId;
if (OidIsValid(secondArgType))
{
oid_array[1] = secondArgType;
nargs = 2;
}
else
nargs = 1;
ftup = SearchSysCache(PROCNAME,
PointerGetDatum(funcname),
Int32GetDatum(nargs),
PointerGetDatum(oid_array),
0);
if (!HeapTupleIsValid(ftup))
return InvalidOid;
/* Make sure the function's result type is as expected, too */
pform = (Form_pg_proc) GETSTRUCT(ftup);
if (pform->prorettype != targetTypeId)
{
ReleaseSysCache(ftup);
return InvalidOid;
}
funcid = ftup->t_data->t_oid;
ReleaseSysCache(ftup);
return funcid;
}
/*
* If the targetTypeId is a domain, we really want to coerce
* the tuple to the domain type -- not the domain itself
* Build an expression tree representing a function call.
*
* The argument expressions must have been transformed already.
*/
Oid
getBaseType(Oid inType)
static Node *
build_func_call(Oid funcid, Oid rettype, List *args)
{
HeapTuple tup;
Form_pg_type typTup;
Func *funcnode;
Expr *expr;
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(inType),
0, 0, 0);
funcnode = makeNode(Func);
funcnode->funcid = funcid;
funcnode->functype = rettype;
funcnode->func_fcache = NULL;
typTup = ((Form_pg_type) GETSTRUCT(tup));
expr = makeNode(Expr);
expr->typeOid = rettype;
expr->opType = FUNC_EXPR;
expr->oper = (Node *) funcnode;
expr->args = args;
/*
* Assume that typbasetype exists and is a base type, where inType
* was a domain
*/
if (typTup->typtype == 'd')
inType = typTup->typbasetype;
ReleaseSysCache(tup);
return inType;
return (Node *) expr;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.109 2002/03/19 02:18:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.110 2002/03/20 19:44:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1027,8 +1027,7 @@ parser_typecast_expression(ParseState *pstate,
if (inputType != targetType)
{
expr = CoerceTargetExpr(pstate, expr, inputType,
getBaseType(targetType),
typename->typmod);
targetType, typename->typmod);
if (expr == NULL)
elog(ERROR, "Cannot cast type '%s' to '%s'",
format_type_be(inputType),
@ -1040,7 +1039,7 @@ parser_typecast_expression(ParseState *pstate,
* as well as a type coercion.
*/
expr = coerce_type_typmod(pstate, expr,
getBaseType(targetType), typename->typmod);
targetType, typename->typmod);
return expr;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.117 2002/03/12 00:51:55 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.118 2002/03/20 19:44:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -575,8 +575,7 @@ agg_select_candidate(Oid typeid, CandidateList candidates)
{
current_typeid = current_candidate->args[0];
if (current_typeid == typeid
|| IS_BINARY_COMPATIBLE(current_typeid, typeid))
if (IsBinaryCompatible(current_typeid, typeid))
{
last_candidate = current_candidate;
ncandidates++;
@ -815,9 +814,7 @@ func_select_candidate(int nargs,
{
if (input_typeids[i] != UNKNOWNOID)
{
if (current_typeids[i] == input_typeids[i] ||
IS_BINARY_COMPATIBLE(current_typeids[i],
input_typeids[i]))
if (IsBinaryCompatible(current_typeids[i], input_typeids[i]))
nmatch++;
}
}
@ -1115,8 +1112,7 @@ func_get_detail(char *funcname,
Node *arg1 = lfirst(fargs);
if ((sourceType == UNKNOWNOID && IsA(arg1, Const)) ||
sourceType == targetType ||
IS_BINARY_COMPATIBLE(sourceType, targetType))
IsBinaryCompatible(sourceType, targetType))
{
/* Yup, it's a type coercion */
*funcid = InvalidOid;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.52 2002/02/19 20:11:15 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.53 2002/03/20 19:44:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -354,9 +354,7 @@ oper_select_candidate(int nargs,
{
if (input_typeids[i] != UNKNOWNOID)
{
if (current_typeids[i] == input_typeids[i] ||
IS_BINARY_COMPATIBLE(current_typeids[i],
input_typeids[i]))
if (IsBinaryCompatible(current_typeids[i], input_typeids[i]))
nmatch++;
}
}
@ -736,10 +734,8 @@ compatible_oper(char *op, Oid arg1, Oid arg2, bool noError)
/* but is it good enough? */
opform = (Form_pg_operator) GETSTRUCT(optup);
if ((opform->oprleft == arg1 ||
IS_BINARY_COMPATIBLE(opform->oprleft, arg1)) &&
(opform->oprright == arg2 ||
IS_BINARY_COMPATIBLE(opform->oprright, arg2)))
if (IsBinaryCompatible(opform->oprleft, arg1) &&
IsBinaryCompatible(opform->oprright, arg2))
return optup;
/* nope... */

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.134 2002/03/19 02:58:19 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.135 2002/03/20 19:44:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -276,12 +276,12 @@ ProcessUtility(Node *parsetree,
}
break;
case DROP_TYPE_P:
case DROP_TYPE:
/* RemoveType does its own permissions checks */
RemoveType(relname);
break;
case DROP_DOMAIN_P:
case DROP_DOMAIN:
/* RemoveDomain does its own permissions checks */
RemoveDomain(relname, stmt->behavior);
break;

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.27 2002/03/19 02:18:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.28 2002/03/20 19:44:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -123,10 +123,10 @@ format_type_internal(Oid type_oid, int32 typemod,
HeapTuple tuple;
Oid array_base_type;
int16 typlen;
char typtype;
bool is_array;
char *name;
char *buf;
char typtype;
if (type_oid == InvalidOid && allow_invalid)
return pstrdup("-");
@ -143,34 +143,16 @@ format_type_internal(Oid type_oid, int32 typemod,
type_oid);
}
/*
* Check if it's an array (and not a domain --- we don't want to show
* the substructure of a domain type). Fixed-length array types such
* as "name" shouldn't get deconstructed either.
*/
array_base_type = ((Form_pg_type) GETSTRUCT(tuple))->typelem;
typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen;
typtype = ((Form_pg_type) GETSTRUCT(tuple))->typtype;
/*
* Domains look alot like arrays, so lets process them first, and return
* back to avoid the array and 'standard' formatting procedures that are
* use for base types.
*/
if (typtype == 'd') {
name = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname);
/*
* Double-quote the name if it's not a standard identifier.
* Note this is *necessary* for ruleutils.c's use.
*/
if (strspn(name, "abcdefghijklmnopqrstuvwxyz0123456789_") != strlen(name)
|| isdigit((unsigned char) name[0]))
buf = psnprintf(strlen(name) + 3, "\"%s\"", name);
else
buf = pstrdup(name);
ReleaseSysCache(tuple);
return buf;
}
if (array_base_type != InvalidOid && typlen < 0)
if (array_base_type != InvalidOid && typlen < 0 && typtype != 'd')
{
/* Switch our attention to the array element type */
ReleaseSysCache(tuple);

View File

@ -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.63 2002/03/19 02:18:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.64 2002/03/20 19:44:42 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
@ -23,7 +23,7 @@
#include "catalog/pg_shadow.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "parser/parse_coerce.h"
#include "nodes/makefuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
@ -818,19 +818,19 @@ get_typstorage(Oid typid)
/*
* get_typdefault
*
* Given a type OID, return the type's default value, if any.
* Returns FALSE if there is no default (effectively, default is NULL).
* The result points to palloc'd storage for pass-by-reference types.
*
* The result is a palloc'd expression node tree, or NULL if there
* is no defined default for the datatype.
*
* NB: caller should be prepared to coerce result to correct datatype;
* the returned expression tree might produce something of the wrong type.
*/
Node *
get_typdefault(Oid typid, int32 atttypmod)
get_typdefault(Oid typid)
{
HeapTuple typeTuple;
Form_pg_type type;
Oid typinput;
Oid typbasetype;
char typtype;
Datum datum;
bool isNull;
Node *expr;
@ -838,50 +838,104 @@ get_typdefault(Oid typid, int32 atttypmod)
typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "get_typdefault: failed to lookup type %u", typid);
type = (Form_pg_type) GETSTRUCT(typeTuple);
typinput = type->typinput;
typbasetype = type->typbasetype;
typtype = type->typtype;
/*
* typdefaultbin is potentially null, so don't try to access it as a
* struct field. Must do it the hard way with SysCacheGetAttr.
* typdefault and typdefaultbin are potentially null, so don't try to
* access 'em as struct fields. Must do it the hard way with
* SysCacheGetAttr.
*/
datum = SysCacheGetAttr(TYPEOID,
typeTuple,
Anum_pg_type_typdefaultbin,
&isNull);
ReleaseSysCache(typeTuple);
if (isNull)
return (Node *) NULL;
if (!isNull)
{
/* We have an expression default */
expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout,
datum)));
}
else
{
/* Perhaps we have a plain literal default */
datum = SysCacheGetAttr(TYPEOID,
typeTuple,
Anum_pg_type_typdefault,
&isNull);
/* Convert Datum to a Node */
expr = stringToNode(DatumGetCString(
DirectFunctionCall1(textout, datum)));
if (!isNull)
{
char *strDefaultVal;
/*
* Ensure we goto the basetype before the domain type.
*
* Prevents scenarios like the below from failing:
* CREATE DOMAIN dom text DEFAULT random();
*
*/
if (typbasetype != InvalidOid) {
expr = coerce_type(NULL, expr, typid,
typbasetype, atttypmod);
/* Convert text datum to C string */
strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
datum));
/* Convert C string to a value of the given type */
datum = OidFunctionCall3(type->typinput,
CStringGetDatum(strDefaultVal),
ObjectIdGetDatum(type->typelem),
Int32GetDatum(-1));
/* Build a Const node containing the value */
expr = (Node *) makeConst(typid,
type->typlen,
datum,
false,
type->typbyval,
false, /* not a set */
false);
pfree(strDefaultVal);
}
else
{
/* No default */
expr = NULL;
}
}
ReleaseSysCache(typeTuple);
return expr;
}
/*
* getBaseType
* If the given type is a domain, return its base type;
* otherwise return the type's own OID.
*/
Oid
getBaseType(Oid typid)
{
/*
* We loop to find the bottom base type in a stack of domains.
*/
for (;;)
{
HeapTuple tup;
Form_pg_type typTup;
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid),
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "getBaseType: failed to lookup type %u", typid);
typTup = (Form_pg_type) GETSTRUCT(tup);
if (typTup->typtype != 'd')
{
/* Not a domain, so done */
ReleaseSysCache(tup);
break;
}
typid = typTup->typbasetype;
ReleaseSysCache(tup);
}
return typid;
}
/*
* get_typavgwidth
*

View File

@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.46 2002/03/19 02:32:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.47 2002/03/20 19:44:45 tgl Exp $
*/
#include "postgres_fe.h"
#include "describe.h"
@ -1053,7 +1053,7 @@ listDomains(const char *name)
snprintf(buf, sizeof(buf),
"SELECT t.typname as \"%s\",\n"
" format_type( t.typbasetype, t.typmod) as \"%s\",\n"
" format_type( t.typbasetype, t.typtypmod) as \"%s\",\n"
" CASE WHEN t.typnotnull AND t.typdefault IS NOT NULL THEN 'not null default '||t.typdefault\n"
" WHEN t.typnotnull AND t.typdefault IS NULL THEN 'not null'\n"
" WHEN NOT t.typnotnull AND t.typdefault IS NOT NULL THEN 'default '||t.typdefault\n"

View File

@ -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.106 2002/03/12 00:51:59 tgl Exp $
* $Id: catversion.h,v 1.107 2002/03/20 19:44:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200203111
#define CATALOG_VERSION_NO 200203191
#endif

View File

@ -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.45 2002/03/19 02:58:19 momjian Exp $
* $Id: heap.h,v 1.46 2002/03/20 19:44:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -47,11 +47,11 @@ extern void AddRelationRawConstraints(Relation rel,
List *rawColDefaults,
List *rawConstraints);
extern Node *cookDefault(ParseState *pstate
, Node *raw_default
, Oid atttypid
, int32 atttypmod
, char *attname);
extern Node *cookDefault(ParseState *pstate,
Node *raw_default,
Oid atttypid,
int32 atttypmod,
char *attname);
extern int RemoveCheckConstraint(Relation rel, const char *constrName, bool inh);

View File

@ -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.84 2002/03/19 02:18:22 momjian Exp $
* $Id: pg_attribute.h,v 1.85 2002/03/20 19:44:55 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -241,8 +241,8 @@ typedef FormData_pg_attribute *Form_pg_attribute;
{ 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, {"typmod"}, 23, 0, 4, 18, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typbasetype"}, 26, 0, 4, 19, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"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 }
@ -265,8 +265,8 @@ 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 typmod 23 0 4 18 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typbasetype 26 0 4 19 0 -1 -1 t p f i f f));
DATA(insert ( 1247 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));

View File

@ -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.117 2002/03/19 02:18:23 momjian Exp $
* $Id: pg_type.h,v 1.118 2002/03/20 19:44:57 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -151,36 +151,41 @@ CATALOG(pg_type) BOOTSTRAP
bool typnotnull;
/*
* typmod records type-specific data supplied at domain creation
* time (for example, the max length of a varchar field). It is
* passed to type-specific input and output functions as the third
* argument. The value will generally be -1 for types that do not need
* typmod. This value is copied to pg_attribute.atttypmod.
*/
int4 typmod;
/*
* Domains use typbasetype to determine the base (or complex)type that
* the domain is based off. It must be non-zero if the type is a
* domain.
* Domains use typbasetype to show the base (or complex) type that
* the domain is based on. Zero if the type is not a domain.
*/
Oid typbasetype;
/*
* typndims is the declared number of dimensions, if an array typbasetype,
* otherwise zero.
* typtypmod records type-specific data supplied at domain creation
* time (for example, the max length of a varchar field). It is
* passed to type-specific input and output functions as the third
* argument. The value will generally be -1 for types that do not need
* typmod. This value is copied to pg_attribute.atttypmod when
* creating a column of a domain type.
*/
int4 typtypmod;
/*
* typndims is the declared number of dimensions for a domain type that
* is an array (with element type typbasetype). Otherwise zero.
*/
int4 typndims;
/*
* typdefaultbin is the binary representation of typdefault
* If typdefaultbin is not NULL, it is the nodeToString representation
* of a default expression for the type. Currently this is only used
* for domains.
*/
text typdefaultbin; /* VARIABLE LENGTH FIELD */
/*
* typdefault is NULL if the type has no associated default value. If
* it's not NULL, it contains the external representation of the
* type's default value
* typdefaultbin is not NULL, typdefault must contain a human-readable
* version of the default expression represented by typdefaultbin.
* If typdefaultbin is NULL and typdefault is not, then typdefault is
* the external representation of the type's default value, which may
* be fed to the type's input converter to produce a constant.
*/
text typdefault; /* VARIABLE LENGTH FIELD */
@ -215,8 +220,8 @@ typedef FormData_pg_type *Form_pg_type;
#define Anum_pg_type_typalign 15
#define Anum_pg_type_typstorage 16
#define Anum_pg_type_typnotnull 17
#define Anum_pg_type_typmod 18
#define Anum_pg_type_typbasetype 19
#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
@ -235,82 +240,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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 0 _null_ _null_ ));
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_ ));
/* 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 -1 0 0 _null_ _null_ ));
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_ ));
DESCR("storage manager");
/* OIDS 300 - 399 */
@ -320,167 +325,167 @@ 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
/* 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 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 -1 0 0 _null_ _null_ ));
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_ ));
/*
* 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 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 -1 0 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 -1 0 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 -1 0 0 _null_ _null_ ));
DATA(insert OID = 1042 ( bpchar PGUID -1 -1 f b t \054 0 0 bpcharin bpcharout bpcharin bpcharout i x f -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 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 -1 0 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 -1 0 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
/* 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 -1 0 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
/* 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
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_ ));
/* 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 -1 0 0 _null_ _null_ ));
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_ ));
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 -1 0 0 _null_ _null_ ));
DATA(insert OID = 1790 ( refcursor PGUID -1 -1 f b t \054 0 0 textin textout textin textout i x f 0 -1 0 _null_ _null_ ));
DESCR("reference cursor (portal name)");
#define REFCURSOROID 1790

View File

@ -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.30 2001/11/05 17:46:34 momjian Exp $
* $Id: makefuncs.h,v 1.31 2002/03/20 19:45:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -46,4 +46,6 @@ extern Const *makeNullConst(Oid consttype);
extern Attr *makeAttr(char *relname, char *attname);
extern RelabelType *makeRelabelType(Node *arg, Oid rtype, int32 rtypmod);
#endif /* MAKEFUNC_H */

View File

@ -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.161 2002/03/19 02:18:24 momjian Exp $
* $Id: parsenodes.h,v 1.162 2002/03/20 19:45:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -407,23 +407,6 @@ typedef struct DefElem
} DefElem;
/****************************************************************************
* Nodes for a Domain Creation tree
****************************************************************************/
/* ----------------------
* CreateDomain Statement
* ----------------------
* Down here as it required TypeName to be defined first.
*/
typedef struct CreateDomainStmt
{
NodeTag type;
char *domainname; /* name of domain to create */
TypeName *typename; /* the typecast */
List *constraints; /* constraints (list of Constraint nodes) */
} CreateDomainStmt;
/****************************************************************************
* Nodes for a Query tree
****************************************************************************/
@ -1056,11 +1039,23 @@ typedef struct VersionStmt
typedef struct DefineStmt
{
NodeTag type;
int defType; /* OPERATOR|P_TYPE|AGGREGATE */
int defType; /* OPERATOR|TYPE_P|AGGREGATE */
char *defname;
List *definition; /* a list of DefElem */
} DefineStmt;
/* ----------------------
* Create Domain Statement
* ----------------------
*/
typedef struct CreateDomainStmt
{
NodeTag type;
char *domainname; /* name of domain to create */
TypeName *typename; /* the base type */
List *constraints; /* constraints (list of Constraint nodes) */
} CreateDomainStmt;
/* ----------------------
* Drop Table|Sequence|View|Index|Rule|Type Statement
* ----------------------
@ -1071,8 +1066,8 @@ typedef struct DefineStmt
#define DROP_VIEW 3
#define DROP_INDEX 4
#define DROP_RULE 5
#define DROP_TYPE_P 6
#define DROP_DOMAIN_P 7
#define DROP_TYPE 6
#define DROP_DOMAIN 7
typedef struct DropStmt
{

View File

@ -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_coerce.h,v 1.40 2002/03/19 02:18:24 momjian Exp $
* $Id: parse_coerce.h,v 1.41 2002/03/20 19:45:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -34,38 +34,7 @@ typedef enum CATEGORY
} CATEGORY;
/* IS_BINARY_COMPATIBLE()
* Check for types with the same underlying binary representation.
* This allows us to cheat and directly exchange values without
* going through the trouble of calling a conversion function.
*
* Remove equivalencing of FLOAT8 and TIMESTAMP. They really are not
* close enough in behavior, with the TIMESTAMP reserved values
* and special formatting. - thomas 1999-01-24
*/
#define IS_BINARY_COMPATIBLE(a,b) \
(((a) == BPCHAROID && (b) == TEXTOID) \
|| ((a) == BPCHAROID && (b) == VARCHAROID) \
|| ((a) == VARCHAROID && (b) == TEXTOID) \
|| ((a) == VARCHAROID && (b) == BPCHAROID) \
|| ((a) == TEXTOID && (b) == BPCHAROID) \
|| ((a) == TEXTOID && (b) == VARCHAROID) \
|| ((a) == OIDOID && (b) == INT4OID) \
|| ((a) == OIDOID && (b) == REGPROCOID) \
|| ((a) == INT4OID && (b) == OIDOID) \
|| ((a) == INT4OID && (b) == REGPROCOID) \
|| ((a) == REGPROCOID && (b) == OIDOID) \
|| ((a) == REGPROCOID && (b) == INT4OID) \
|| ((a) == ABSTIMEOID && (b) == INT4OID) \
|| ((a) == INT4OID && (b) == ABSTIMEOID) \
|| ((a) == RELTIMEOID && (b) == INT4OID) \
|| ((a) == INT4OID && (b) == RELTIMEOID) \
|| ((a) == INETOID && (b) == CIDROID) \
|| ((a) == CIDROID && (b) == INETOID) \
|| ((a) == BITOID && (b) == VARBITOID) \
|| ((a) == VARBITOID && (b) == BITOID))
extern bool IsBinaryCompatible(Oid type1, Oid type2);
extern bool IsPreferredType(CATEGORY category, Oid type);
extern CATEGORY TypeCategory(Oid type);
@ -81,6 +50,5 @@ extern Oid select_common_type(List *typeids, const char *context);
extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
Oid targetTypeId,
const char *context);
extern Oid getBaseType(Oid inType);
#endif /* PARSE_COERCE_H */

View File

@ -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.43 2002/03/19 02:18:24 momjian Exp $
* $Id: lsyscache.h,v 1.44 2002/03/20 19:45:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -44,7 +44,8 @@ extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid);
extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
extern char get_typstorage(Oid typid);
extern Node *get_typdefault(Oid typid, int32 atttypmod);
extern Node *get_typdefault(Oid typid);
extern Oid getBaseType(Oid typid);
extern int32 get_typavgwidth(Oid typid, int32 typmod);
extern int32 get_attavgwidth(Oid relid, AttrNumber attnum);
extern bool get_attstatsslot(HeapTuple statstuple,

View File

@ -3,9 +3,9 @@ create domain domaindroptest int4;
comment on domain domaindroptest is 'About to drop this..';
create domain basetypetest domaindroptest;
ERROR: DefineDomain: domaindroptest is not a basetype
drop domain domaindroptest cascade;
ERROR: DROP DOMAIN does not support the CASCADE keyword
drop domain domaindroptest;
ERROR: parser: parse error at or near ";"
drop domain domaindroptest restrict;
-- TEST Domains.
create domain domainvarchar varchar(5);
create domain domainnumeric numeric(8,2);
@ -29,11 +29,21 @@ select * from basictest;
88 | haha | short | 123.12
(2 rows)
-- check that domains inherit operations from base types
-- XXX shouldn't have to quote the constant here
select testtext || testvarchar as concat, testnumeric + '42' as sum
from basictest;
concat | sum
-----------+--------
hahashort | 165.12
hahashort | 165.12
(2 rows)
drop table basictest;
drop domain domainvarchar restrict;
drop domain domainnumeric restrict;
drop domain domainint4 restrict;
drop domain domaintext restrict;
drop domain domaintext;
-- Array Test
create domain domainint4arr int4[1];
create domain domaintextarr text[2][3];
@ -46,6 +56,26 @@ INSERT INTO domarrtest values ('{{2,2}{2,2}}', '{{"a","b"}}');
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}{"e"}}');
INSERT INTO domarrtest values ('{2,2}', '{{"a"}{"c"}}');
INSERT INTO domarrtest values (NULL, '{{"a","b"}{"c","d","e"}}');
select * from domarrtest;
testint4arr | testtextarr
---------------+---------------------
{2,2} | {{a,c},{"",d}}
{{2,2},{0,2}} | {{a,b}}
{2,2} | {{a},{c},{e}}
{2,2} | {{c},{""}}
| {{a,c,""},{"",d,e}}
(5 rows)
select testint4arr[1], testtextarr[2:2] from domarrtest;
testint4arr | testtextarr
-------------+-------------
2 | {{"",d}}
|
2 | {{c}}
2 | {{""}}
| {{"",d,e}}
(5 rows)
drop table domarrtest;
drop domain domainint4arr restrict;
drop domain domaintextarr restrict;

View File

@ -6,8 +6,8 @@ comment on domain domaindroptest is 'About to drop this..';
create domain basetypetest domaindroptest;
drop domain domaindroptest cascade;
drop domain domaindroptest;
drop domain domaindroptest restrict;
-- TEST Domains.
@ -31,11 +31,16 @@ INSERT INTO basictest values ('88', 'haha', 'short text', '123.12'); -- Bad varc
INSERT INTO basictest values ('88', 'haha', 'short', '123.1212'); -- Truncate numeric
select * from basictest;
-- check that domains inherit operations from base types
-- XXX shouldn't have to quote the constant here
select testtext || testvarchar as concat, testnumeric + '42' as sum
from basictest;
drop table basictest;
drop domain domainvarchar restrict;
drop domain domainnumeric restrict;
drop domain domainint4 restrict;
drop domain domaintext restrict;
drop domain domaintext;
-- Array Test
@ -51,6 +56,8 @@ INSERT INTO domarrtest values ('{{2,2}{2,2}}', '{{"a","b"}}');
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}{"e"}}');
INSERT INTO domarrtest values ('{2,2}', '{{"a"}{"c"}}');
INSERT INTO domarrtest values (NULL, '{{"a","b"}{"c","d","e"}}');
select * from domarrtest;
select testint4arr[1], testtextarr[2:2] from domarrtest;
drop table domarrtest;
drop domain domainint4arr restrict;