<!--
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">
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>
<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>
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>
</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>
<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>
<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>
<!--
-$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
-->
<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">
<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>
<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>
<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>
<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>
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>
<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>
<!--
-$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
-->
<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">
</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>
To remove the <type>box</type> domain:
<programlisting>
-DROP DOMAIN box RESTRICT;
+DROP DOMAIN box;
</programlisting>
</para>
</refsect1>
<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>
<!--
-$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
-->
<term><literal>\dD</literal> [ <replaceable class="parameter">pattern</replaceable> ]</term>
<listitem>
<para>
- Lists all database domains.
- </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.
+ Lists all available domains (derived types).
+ If <replaceable class="parameter">pattern</replaceable>
+ (a regular expression) is specified, only matching domains are shown.
</para>
- </note>
-
</listitem>
</varlistentry>
*
*
* 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
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 */
}
RangeTblEntry *rte;
int numchecks;
List *listptr;
-
- /* Probably shouldn't be null by default */
- Node *expr = NULL;
-
+ Node *expr;
/*
* Get info about existing constraints.
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));
}
{
Constraint *cdef = (Constraint *) lfirst(listptr);
char *ccname;
- Node *expr;
if (cdef->contype != CONSTR_CHECK || cdef->raw_expr == NULL)
continue;
* 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);
* 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));
- }
}
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* 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);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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));
if (tlistlen == 1)
{
restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
- if (restype == rettype || IS_BINARY_COMPATIBLE(restype, rettype))
+ if (IsBinaryCompatible(restype, rettype))
return;
}
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),
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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
char storage,
int32 typeMod,
int32 typNDims, /* Array dimensions for baseTypeName */
- bool typeNotNull) /* binary default representation (cooked) */
+ bool typeNotNull)
{
int i,
j;
*/
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 */
/*
*/
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 */
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
static List *MergeDomainAttributes(List *schema);
+
/* ----------------------------------------------------------------
* DefineRelation
* Creates a new relation.
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);
/*
* 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)
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;
+ if (typeTup->typtype == 'd')
+ {
+ /* Force the column to have the correct typmod. */
+ coldef->typename->typmod = typeTup->typtypmod;
+ /* XXX more to do here? */
+ }
- /* 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?
- */
+ /* 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);
}
*
*
* 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
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 '_'
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
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
*
* 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;
/* 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;
/* 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
*/
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.
* 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;
/*
typNotNull = true;
nullDefined = true;
}
-
break;
case CONSTR_NULL:
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;
+ }
}
/*
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 */
* Now we can clean up.
*/
ReleaseSysCache(typeTup);
- heap_close(pg_type_rel, NoLock);
}
-
/*
* DefineType
* Registers a new type.
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;
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)
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.
*/
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 */
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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");
}
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));
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;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* 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),
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) {
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
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);
}
* 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 $
*
*-------------------------------------------------------------------------
*/
Node_Copy(from, newnode, names);
newnode->removeType = from->removeType;
+ newnode->behavior = from->behavior;
return newnode;
}
if (from->domainname)
newnode->domainname = pstrdup(from->domainname);
-
Node_Copy(from, newnode, typename);
Node_Copy(from, newnode, constraints);
* 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 $
*
*-------------------------------------------------------------------------
*/
return false;
if (a->removeType != b->removeType)
return false;
+ if (a->behavior != b->behavior)
+ return false;
return true;
}
*
*
* 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"
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;
+}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
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;
/*
* 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 $
*
*-------------------------------------------------------------------------
*/
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.
{
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);
- }
- 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);
+ /*
+ * 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));
}
- 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, as well as direction to the final type.
- */
- 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.
+ */
+ expr = coerce_type_typmod(NULL, expr, atttype, atttypmod);
+ }
return expr;
}
*
*
* 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
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,
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
| RESTRICT { $$ = RESTRICT; }
;
+opt_drop_behavior: CASCADE { $$ = CASCADE; }
+ | RESTRICT { $$ = RESTRICT; }
+ | /* EMPTY */ { $$ = RESTRICT; /* default */ }
+ ;
/*****************************************************************************
| 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;
*
*****************************************************************************/
-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;
}
| VIEW { $$ = DROP_VIEW; }
| INDEX { $$ = DROP_INDEX; }
| RULE { $$ = DROP_RULE; }
- | TYPE_P { $$ = DROP_TYPE_P; }
+ | TYPE_P { $$ = DROP_TYPE; }
+ | DOMAIN_P { $$ = DROP_DOMAIN; }
;
/*****************************************************************************
}
;
+/*
+ * 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.
+ */
+opt_equal: '=' { $$ = TRUE; }
+ | /*EMPTY*/ { $$ = FALSE; }
+ ;
+
/*****************************************************************************
*
* DROP DATABASE
*
- *
*****************************************************************************/
DropdbStmt: DROP DATABASE database_name
}
;
-/*
- * 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.
- */
-opt_equal: '=' { $$ = TRUE; }
- | /*EMPTY*/ { $$ = FALSE; }
- ;
-
/*****************************************************************************
*
* ALTER DATABASE
*
- *
*****************************************************************************/
AlterDatabaseSetStmt: ALTER DATABASE database_name VariableSetStmt
*
*
* 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()
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
{
* (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
* 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);
}
*
* 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)
* 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... */
* 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))
- 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);
+ funcId = find_coercion_function(getBaseType(targetTypeId),
+ getBaseType(inputTypeId),
+ InvalidOid);
+ if (!OidIsValid(funcId))
return false;
- }
- ReleaseSysCache(ftup);
}
return true;
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.
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;
-
- /* attempt to find with arguments exactly as specified... */
- if (SearchSysCacheExists(PROCNAME,
- PointerGetDatum(funcname),
- Int32GetDatum(2),
- PointerGetDatum(oid_array),
- 0))
+ /* If given type is a domain, use base type instead */
+ baseTypeId = getBaseType(targetTypeId);
+
+ 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;
} /* 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
return result;
} /* PreferredType() */
-
/*
- * If the targetTypeId is a domain, we really want to coerce
- * the tuple to the domain type -- not the domain itself
+ * 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.
*/
-Oid
-getBaseType(Oid inType)
+static Oid
+find_coercion_function(Oid targetTypeId, Oid inputTypeId, Oid secondArgType)
{
- HeapTuple tup;
- Form_pg_type typTup;
+ char *funcname;
+ Oid oid_array[FUNC_MAX_ARGS];
+ int nargs;
+ HeapTuple ftup;
+ Form_pg_proc pform;
+ Oid funcid;
- tup = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(inType),
- 0, 0, 0);
+ 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;
+}
- typTup = ((Form_pg_type) GETSTRUCT(tup));
+/*
+ * Build an expression tree representing a function call.
+ *
+ * The argument expressions must have been transformed already.
+ */
+static Node *
+build_func_call(Oid funcid, Oid rettype, List *args)
+{
+ Func *funcnode;
+ Expr *expr;
- /*
- * Assume that typbasetype exists and is a base type, where inType
- * was a domain
- */
- if (typTup->typtype == 'd')
- inType = typTup->typbasetype;
+ funcnode = makeNode(Func);
+ funcnode->funcid = funcid;
+ funcnode->functype = rettype;
+ funcnode->func_fcache = NULL;
- ReleaseSysCache(tup);
+ expr = makeNode(Expr);
+ expr->typeOid = rettype;
+ expr->opType = FUNC_EXPR;
+ expr->oper = (Node *) funcnode;
+ expr->args = args;
- return inType;
+ return (Node *) expr;
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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),
* as well as a type coercion.
*/
expr = coerce_type_typmod(pstate, expr,
- getBaseType(targetType), typename->typmod);
+ targetType, typename->typmod);
return expr;
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{
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++;
{
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++;
}
}
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;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{
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++;
}
}
/* 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... */
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
}
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;
* 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 $
*
*-------------------------------------------------------------------------
*/
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("-");
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);
* 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.
#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"
/*
* 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;
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;
+
+ /* 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)
+{
/*
- * Ensure we goto the basetype before the domain type.
- *
- * Prevents scenarios like the below from failing:
- * CREATE DOMAIN dom text DEFAULT random();
- *
+ * We loop to find the bottom base type in a stack of domains.
*/
- if (typbasetype != InvalidOid) {
- expr = coerce_type(NULL, expr, typid,
- typbasetype, atttypmod);
- }
+ 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 expr;
+ return typid;
}
/*
*
* 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"
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"
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200203111
+#define CATALOG_VERSION_NO 200203191
#endif
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
* 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
{ 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 }
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));
* 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
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.
+ * Domains use typbasetype to show the base (or complex) type that
+ * the domain is based on. Zero if the type is not a domain.
*/
- int4 typmod;
+ Oid typbasetype;
/*
- * 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.
+ * 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.
*/
- Oid typbasetype;
+ int4 typtypmod;
/*
- * typndims is the declared number of dimensions, if an array typbasetype,
- * otherwise zero.
+ * 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 */
#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
*/
/* 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 */
/* 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
* 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 $
*
*-------------------------------------------------------------------------
*/
extern Attr *makeAttr(char *relname, char *attname);
+extern RelabelType *makeRelabelType(Node *arg, Oid rtype, int32 rtypmod);
+
#endif /* MAKEFUNC_H */
* 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 $
*
*-------------------------------------------------------------------------
*/
} 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
****************************************************************************/
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
* ----------------------
#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
{
* 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 $
*
*-------------------------------------------------------------------------
*/
} 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);
extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
Oid targetTypeId,
const char *context);
-extern Oid getBaseType(Oid inType);
#endif /* PARSE_COERCE_H */
* 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 $
*
*-------------------------------------------------------------------------
*/
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,
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);
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];
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;
create domain basetypetest domaindroptest;
+drop domain domaindroptest cascade;
drop domain domaindroptest;
-drop domain domaindroptest restrict;
-- TEST Domains.
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
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;