Support type modifiers for user-defined types, and pull most knowledge

about typmod representation for standard types out into type-specific
typmod I/O functions.  Teodor Sigaev, with some editorialization by
Tom Lane.
This commit is contained in:
Tom Lane 2006-12-30 21:21:56 +00:00
parent 24b1f14eae
commit 5725b9d9af
47 changed files with 1628 additions and 685 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.139 2006/12/23 00:43:08 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.140 2006/12/30 21:21:52 tgl Exp $ -->
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
--> -->
@ -4393,6 +4393,20 @@
<entry>Output conversion function (binary format), or 0 if none</entry> <entry>Output conversion function (binary format), or 0 if none</entry>
</row> </row>
<row>
<entry><structfield>typmodin</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry>Type modifier input function, or 0 if type does not support modifiers</entry>
</row>
<row>
<entry><structfield>typmodout</structfield></entry>
<entry><type>regproc</type></entry>
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
<entry>Type modifier output function, or 0 to use the standard format</entry>
</row>
<row> <row>
<entry><structfield>typanalyze</structfield></entry> <entry><structfield>typanalyze</structfield></entry>
<entry><type>regproc</type></entry> <entry><type>regproc</type></entry>

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/keywords.sgml,v 2.18 2006/10/08 20:51:52 petere Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/keywords.sgml,v 2.19 2006/12/30 21:21:52 tgl Exp $ -->
<appendix id="sql-keywords-appendix"> <appendix id="sql-keywords-appendix">
<title><acronym>SQL</acronym> Key Words</title> <title><acronym>SQL</acronym> Key Words</title>
@ -45,16 +45,17 @@
In <xref linkend="keywords-table"> in the column for In <xref linkend="keywords-table"> in the column for
<productname>PostgreSQL</productname> we classify as <productname>PostgreSQL</productname> we classify as
<quote>non-reserved</quote> those key words that are explicitly <quote>non-reserved</quote> those key words that are explicitly
known to the parser but are allowed in most or all contexts where an known to the parser but are allowed as column or table names.
identifier is expected. Some key words that are otherwise Some key words that are otherwise
non-reserved cannot be used as function or data type names and are non-reserved cannot be used as function or data type names and are
marked accordingly. (Most of these words represent built-in marked accordingly. (Most of these words represent built-in
functions or data types with special syntax. The function or type functions or data types with special syntax. The function or type
is still available but it cannot be redefined by the user.) Labeled is still available but it cannot be redefined by the user.) Labeled
<quote>reserved</quote> are those tokens that are only allowed as <quote>reserved</quote> are those tokens that are not allowed as
<quote>AS</quote> column label names (and perhaps in very few other column or table names. Some reserved key words are
contexts). Some reserved key words are allowable as names for allowable as names for functions or data types; this is also shown in the
functions; this is also shown in the table. table. If not so marked, a reserved key word is only allowed as an
<quote>AS</quote> column label name.
</para> </para>
<para> <para>
@ -326,7 +327,7 @@
</row> </row>
<row> <row>
<entry><token>AUTHORIZATION</token></entry> <entry><token>AUTHORIZATION</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -368,7 +369,7 @@
</row> </row>
<row> <row>
<entry><token>BETWEEN</token></entry> <entry><token>BETWEEN</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>non-reserved</entry> <entry>non-reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -382,7 +383,7 @@
</row> </row>
<row> <row>
<entry><token>BINARY</token></entry> <entry><token>BINARY</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry></entry> <entry></entry>
@ -956,7 +957,7 @@
</row> </row>
<row> <row>
<entry><token>CROSS</token></entry> <entry><token>CROSS</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -1642,7 +1643,7 @@
</row> </row>
<row> <row>
<entry><token>FREEZE</token></entry> <entry><token>FREEZE</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
@ -1656,7 +1657,7 @@
</row> </row>
<row> <row>
<entry><token>FULL</token></entry> <entry><token>FULL</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -1831,7 +1832,7 @@
</row> </row>
<row> <row>
<entry><token>ILIKE</token></entry> <entry><token>ILIKE</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
@ -1943,7 +1944,7 @@
</row> </row>
<row> <row>
<entry><token>INNER</token></entry> <entry><token>INNER</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -2048,14 +2049,14 @@
</row> </row>
<row> <row>
<entry><token>IS</token></entry> <entry><token>IS</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
</row> </row>
<row> <row>
<entry><token>ISNULL</token></entry> <entry><token>ISNULL</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
@ -2076,7 +2077,7 @@
</row> </row>
<row> <row>
<entry><token>JOIN</token></entry> <entry><token>JOIN</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -2160,7 +2161,7 @@
</row> </row>
<row> <row>
<entry><token>LEFT</token></entry> <entry><token>LEFT</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -2188,7 +2189,7 @@
</row> </row>
<row> <row>
<entry><token>LIKE</token></entry> <entry><token>LIKE</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -2475,7 +2476,7 @@
</row> </row>
<row> <row>
<entry><token>NATURAL</token></entry> <entry><token>NATURAL</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -2608,7 +2609,7 @@
</row> </row>
<row> <row>
<entry><token>NOTNULL</token></entry> <entry><token>NOTNULL</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
@ -2811,7 +2812,7 @@
</row> </row>
<row> <row>
<entry><token>OUTER</token></entry> <entry><token>OUTER</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -2832,7 +2833,7 @@
</row> </row>
<row> <row>
<entry><token>OVERLAPS</token></entry> <entry><token>OVERLAPS</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>non-reserved</entry> <entry>non-reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -3385,7 +3386,7 @@
</row> </row>
<row> <row>
<entry><token>RIGHT</token></entry> <entry><token>RIGHT</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>reserved</entry> <entry>reserved</entry>
@ -3658,7 +3659,7 @@
</row> </row>
<row> <row>
<entry><token>SIMILAR</token></entry> <entry><token>SIMILAR</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry>reserved</entry> <entry>reserved</entry>
<entry>non-reserved</entry> <entry>non-reserved</entry>
<entry></entry> <entry></entry>
@ -4414,7 +4415,7 @@
</row> </row>
<row> <row>
<entry><token>VERBOSE</token></entry> <entry><token>VERBOSE</token></entry>
<entry>reserved (can be function)</entry> <entry>reserved (can be function or type)</entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>

View File

@ -1,5 +1,5 @@
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.65 2006/12/23 01:28:09 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.66 2006/12/30 21:21:52 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -28,6 +28,8 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
OUTPUT = <replaceable class="parameter">output_function</replaceable> OUTPUT = <replaceable class="parameter">output_function</replaceable>
[ , RECEIVE = <replaceable class="parameter">receive_function</replaceable> ] [ , RECEIVE = <replaceable class="parameter">receive_function</replaceable> ]
[ , SEND = <replaceable class="parameter">send_function</replaceable> ] [ , SEND = <replaceable class="parameter">send_function</replaceable> ]
[ , TYPMOD_IN = <replaceable class="parameter">type_modifier_input_function</replaceable> ]
[ , TYPMOD_OUT = <replaceable class="parameter">type_modifier_output_function</replaceable> ]
[ , ANALYZE = <replaceable class="parameter">analyze_function</replaceable> ] [ , ANALYZE = <replaceable class="parameter">analyze_function</replaceable> ]
[ , INTERNALLENGTH = { <replaceable class="parameter">internallength</replaceable> | VARIABLE } ] [ , INTERNALLENGTH = { <replaceable class="parameter">internallength</replaceable> | VARIABLE } ]
[ , PASSEDBYVALUE ] [ , PASSEDBYVALUE ]
@ -83,12 +85,14 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
(scalar type). The parameters may appear in any order, not only that (scalar type). The parameters may appear in any order, not only that
illustrated above, and most are optional. You must register illustrated above, and most are optional. You must register
two or more functions (using <command>CREATE FUNCTION</command>) before two or more functions (using <command>CREATE FUNCTION</command>) before
defining the type. The support functions defining the type. The support functions
<replaceable class="parameter">input_function</replaceable> and <replaceable class="parameter">input_function</replaceable> and
<replaceable class="parameter">output_function</replaceable> <replaceable class="parameter">output_function</replaceable>
are required, while the functions are required, while the functions
<replaceable class="parameter">receive_function</replaceable>, <replaceable class="parameter">receive_function</replaceable>,
<replaceable class="parameter">send_function</replaceable> and <replaceable class="parameter">send_function</replaceable>,
<replaceable class="parameter">type_modifier_input_function</replaceable>,
<replaceable class="parameter">type_modifier_output_function</replaceable> and
<replaceable class="parameter">analyze_function</replaceable> <replaceable class="parameter">analyze_function</replaceable>
are optional. Generally these functions have to be coded in C are optional. Generally these functions have to be coded in C
or another low-level language. or another low-level language.
@ -169,6 +173,34 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
used normally. used normally.
</para> </para>
<para>
The optional
<replaceable class="parameter">type_modifier_input_function</replaceable>
and <replaceable class="parameter">type_modifier_output_function</replaceable>
are needed if the type supports modifiers, that is optional constraints
attached to a type declaration, such as <literal>char(5)</> or
<literal>numeric(30,2)</>. <productname>PostgreSQL</productname> allows
user-defined types to take one or more integer constants as modifiers;
however, this information must be capable of being packed into a single
non-negative integer value for storage in the system catalogs. The
<replaceable class="parameter">type_modifier_input_function</replaceable>
is passed the declared modifier(s) in the form of an <type>integer</>
array. It must check the values for validity (throwing an error if they
are wrong), and if they are correct, return a single non-negative
<type>integer</> value that will be stored as the column <quote>typmod</>.
Type modifiers will be rejected if the type does not have a
<replaceable class="parameter">type_modifier_input_function</replaceable>.
The <replaceable class="parameter">type_modifier_output_function</replaceable>
converts the internal integer typmod value back to the correct form for
user display. It must return a <type>cstring</> value that is the exact
string to append to the type name; for example <type>numeric</>'s
function might return <literal>(30,2)</>.
It is allowed to omit the
<replaceable class="parameter">type_modifier_output_function</replaceable>,
in which case the default display format is just the stored typmod value
enclosed in parentheses.
</para>
<para> <para>
The optional <replaceable class="parameter">analyze_function</replaceable> The optional <replaceable class="parameter">analyze_function</replaceable>
performs type-specific statistics collection for columns of the data type. performs type-specific statistics collection for columns of the data type.
@ -265,7 +297,7 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
<title>Array Types</title> <title>Array Types</title>
<para> <para>
Whenever a user-defined base data type is created, Whenever a user-defined base data type is created,
<productname>PostgreSQL</productname> automatically creates an <productname>PostgreSQL</productname> automatically creates an
associated array type, whose name consists of the base type's associated array type, whose name consists of the base type's
name prepended with an underscore. The parser understands this name prepended with an underscore. The parser understands this
@ -298,7 +330,7 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
</para> </para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1> <refsect1>
<title>Parameters</title> <title>Parameters</title>
@ -371,6 +403,26 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">type_modifier_input_function</replaceable></term>
<listitem>
<para>
The name of a function that converts numeric modifier(s) for the type
into internal form.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">type_modifier_output_function</replaceable></term>
<listitem>
<para>
The name of a function that converts the internal form of the type's
modifier(s) to external textual form.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">analyze_function</replaceable></term> <term><replaceable class="parameter">analyze_function</replaceable></term>
<listitem> <listitem>
@ -499,7 +551,7 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
</para> </para>
</refsect1> </refsect1>
<refsect1> <refsect1>
<title>Examples</title> <title>Examples</title>

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.118 2006/07/14 14:52:16 momjian Exp $ * $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.119 2006/12/30 21:21:52 tgl Exp $
* *
* NOTES * NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be * some of the executor utility code such as "ExecTypeFromTL" should be
@ -508,6 +508,7 @@ BuildDescForRelation(List *schema)
AttrDefault *attrdef = NULL; AttrDefault *attrdef = NULL;
TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr)); TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
char *attname; char *attname;
Oid atttypid;
int32 atttypmod; int32 atttypmod;
int attdim; int attdim;
int ndef = 0; int ndef = 0;
@ -533,7 +534,8 @@ BuildDescForRelation(List *schema)
attnum++; attnum++;
attname = entry->colname; attname = entry->colname;
atttypmod = entry->typename->typmod; atttypid = typenameTypeId(NULL, entry->typename);
atttypmod = typenameTypeMod(NULL, entry->typename, atttypid);
attdim = list_length(entry->typename->arrayBounds); attdim = list_length(entry->typename->arrayBounds);
if (entry->typename->setof) if (entry->typename->setof)
@ -543,8 +545,7 @@ BuildDescForRelation(List *schema)
attname))); attname)));
TupleDescInitEntry(desc, attnum, attname, TupleDescInitEntry(desc, attnum, attname,
typenameTypeId(NULL, entry->typename), atttypid, atttypmod, attdim);
atttypmod, attdim);
/* Fill in additional stuff not handled by TupleDescInitEntry */ /* Fill in additional stuff not handled by TupleDescInitEntry */
if (entry->is_not_null) if (entry->is_not_null)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.314 2006/11/05 22:42:08 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.315 2006/12/30 21:21:52 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -724,6 +724,8 @@ AddNewRelationType(const char *typeName,
F_RECORD_OUT, /* output procedure */ F_RECORD_OUT, /* output procedure */
F_RECORD_RECV, /* receive procedure */ F_RECORD_RECV, /* receive procedure */
F_RECORD_SEND, /* send procedure */ F_RECORD_SEND, /* send procedure */
InvalidOid, /* typmodin procedure - none */
InvalidOid, /* typmodout procedure - none */
InvalidOid, /* analyze procedure - default */ InvalidOid, /* analyze procedure - default */
InvalidOid, /* array element type - irrelevant */ InvalidOid, /* array element type - irrelevant */
InvalidOid, /* domain base type - irrelevant */ InvalidOid, /* domain base type - irrelevant */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.108 2006/10/04 00:29:50 momjian Exp $ * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.109 2006/12/30 21:21:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -94,6 +94,8 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
values[i++] = ObjectIdGetDatum(F_SHELL_OUT); /* typoutput */ values[i++] = ObjectIdGetDatum(F_SHELL_OUT); /* typoutput */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typsend */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typsend */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typmodin */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typmodout */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typanalyze */ values[i++] = ObjectIdGetDatum(InvalidOid); /* typanalyze */
values[i++] = CharGetDatum('i'); /* typalign */ values[i++] = CharGetDatum('i'); /* typalign */
values[i++] = CharGetDatum('p'); /* typstorage */ values[i++] = CharGetDatum('p'); /* typstorage */
@ -132,6 +134,8 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
InvalidOid, InvalidOid,
InvalidOid, InvalidOid,
InvalidOid, InvalidOid,
InvalidOid,
InvalidOid,
NULL, NULL,
false); false);
@ -164,6 +168,8 @@ TypeCreate(const char *typeName,
Oid outputProcedure, Oid outputProcedure,
Oid receiveProcedure, Oid receiveProcedure,
Oid sendProcedure, Oid sendProcedure,
Oid typmodinProcedure,
Oid typmodoutProcedure,
Oid analyzeProcedure, Oid analyzeProcedure,
Oid elementType, Oid elementType,
Oid baseType, Oid baseType,
@ -243,6 +249,8 @@ TypeCreate(const char *typeName,
values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */ values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */
values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */ values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */
values[i++] = ObjectIdGetDatum(sendProcedure); /* typsend */ values[i++] = ObjectIdGetDatum(sendProcedure); /* typsend */
values[i++] = ObjectIdGetDatum(typmodinProcedure); /* typmodin */
values[i++] = ObjectIdGetDatum(typmodoutProcedure); /* typmodout */
values[i++] = ObjectIdGetDatum(analyzeProcedure); /* typanalyze */ values[i++] = ObjectIdGetDatum(analyzeProcedure); /* typanalyze */
values[i++] = CharGetDatum(alignment); /* typalign */ values[i++] = CharGetDatum(alignment); /* typalign */
values[i++] = CharGetDatum(storage); /* typstorage */ values[i++] = CharGetDatum(storage); /* typstorage */
@ -341,6 +349,8 @@ TypeCreate(const char *typeName,
outputProcedure, outputProcedure,
receiveProcedure, receiveProcedure,
sendProcedure, sendProcedure,
typmodinProcedure,
typmodoutProcedure,
analyzeProcedure, analyzeProcedure,
elementType, elementType,
baseType, baseType,
@ -374,6 +384,8 @@ GenerateTypeDependencies(Oid typeNamespace,
Oid outputProcedure, Oid outputProcedure,
Oid receiveProcedure, Oid receiveProcedure,
Oid sendProcedure, Oid sendProcedure,
Oid typmodinProcedure,
Oid typmodoutProcedure,
Oid analyzeProcedure, Oid analyzeProcedure,
Oid elementType, Oid elementType,
Oid baseType, Oid baseType,
@ -436,6 +448,22 @@ GenerateTypeDependencies(Oid typeNamespace,
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
} }
if (OidIsValid(typmodinProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = typmodinProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(typmodoutProcedure))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = typmodoutProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(analyzeProcedure)) if (OidIsValid(analyzeProcedure))
{ {
referenced.classId = ProcedureRelationId; referenced.classId = ProcedureRelationId;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.207 2006/12/23 00:43:09 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.208 2006/12/30 21:21:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -889,6 +889,9 @@ MergeAttributes(List *schema, List *supers, bool istemp,
exist_attno = findAttrByName(attributeName, inhSchema); exist_attno = findAttrByName(attributeName, inhSchema);
if (exist_attno > 0) if (exist_attno > 0)
{ {
Oid defTypeId;
int32 deftypmod;
/* /*
* Yes, try to merge the two column definitions. They must * Yes, try to merge the two column definitions. They must
* have the same type and typmod. * have the same type and typmod.
@ -897,8 +900,10 @@ MergeAttributes(List *schema, List *supers, bool istemp,
(errmsg("merging multiple inherited definitions of column \"%s\"", (errmsg("merging multiple inherited definitions of column \"%s\"",
attributeName))); attributeName)));
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1); def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
if (typenameTypeId(NULL, def->typename) != attribute->atttypid || defTypeId = typenameTypeId(NULL, def->typename);
def->typename->typmod != attribute->atttypmod) deftypmod = typenameTypeMod(NULL, def->typename, defTypeId);
if (defTypeId != attribute->atttypid ||
deftypmod != attribute->atttypmod)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("inherited column \"%s\" has a type conflict", errmsg("inherited column \"%s\" has a type conflict",
@ -1029,6 +1034,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
if (exist_attno > 0) if (exist_attno > 0)
{ {
ColumnDef *def; ColumnDef *def;
Oid defTypeId, newTypeId;
int32 deftypmod, newtypmod;
/* /*
* Yes, try to merge the two column definitions. They must * Yes, try to merge the two column definitions. They must
@ -1038,8 +1045,11 @@ MergeAttributes(List *schema, List *supers, bool istemp,
(errmsg("merging column \"%s\" with inherited definition", (errmsg("merging column \"%s\" with inherited definition",
attributeName))); attributeName)));
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1); def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
if (typenameTypeId(NULL, def->typename) != typenameTypeId(NULL, newdef->typename) || defTypeId = typenameTypeId(NULL, def->typename);
def->typename->typmod != newdef->typename->typmod) deftypmod = typenameTypeMod(NULL, def->typename, defTypeId);
newTypeId = typenameTypeId(NULL, newdef->typename);
newtypmod = typenameTypeMod(NULL, newdef->typename, newTypeId);
if (defTypeId != newTypeId || deftypmod != newtypmod)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("column \"%s\" has a type conflict", errmsg("column \"%s\" has a type conflict",
@ -3092,6 +3102,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
maxatts; maxatts;
HeapTuple typeTuple; HeapTuple typeTuple;
Oid typeOid; Oid typeOid;
int32 typmod;
Form_pg_type tform; Form_pg_type tform;
Expr *defval; Expr *defval;
@ -3110,10 +3121,14 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
if (HeapTupleIsValid(tuple)) if (HeapTupleIsValid(tuple))
{ {
Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple); Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
Oid ctypeId;
int32 ctypmod;
/* Okay if child matches by type */ /* Okay if child matches by type */
if (typenameTypeId(NULL, colDef->typename) != childatt->atttypid || ctypeId = typenameTypeId(NULL, colDef->typename);
colDef->typename->typmod != childatt->atttypmod) ctypmod = typenameTypeMod(NULL, colDef->typename, ctypeId);
if (ctypeId != childatt->atttypid ||
ctypmod != childatt->atttypmod)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("child table \"%s\" has different type for column \"%s\"", errmsg("child table \"%s\" has different type for column \"%s\"",
@ -3169,6 +3184,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
typeTuple = typenameType(NULL, colDef->typename); typeTuple = typenameType(NULL, colDef->typename);
tform = (Form_pg_type) GETSTRUCT(typeTuple); tform = (Form_pg_type) GETSTRUCT(typeTuple);
typeOid = HeapTupleGetOid(typeTuple); typeOid = HeapTupleGetOid(typeTuple);
typmod = typenameTypeMod(NULL, colDef->typename, typeOid);
/* make sure datatype is legal for a column */ /* make sure datatype is legal for a column */
CheckAttributeType(colDef->colname, typeOid); CheckAttributeType(colDef->colname, typeOid);
@ -3186,7 +3202,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
attribute->attstattarget = -1; attribute->attstattarget = -1;
attribute->attlen = tform->typlen; attribute->attlen = tform->typlen;
attribute->attcacheoff = -1; attribute->attcacheoff = -1;
attribute->atttypmod = colDef->typename->typmod; attribute->atttypmod = typmod;
attribute->attnum = i; attribute->attnum = i;
attribute->attbyval = tform->typbyval; attribute->attbyval = tform->typbyval;
attribute->attndims = list_length(colDef->typename->arrayBounds); attribute->attndims = list_length(colDef->typename->arrayBounds);
@ -3278,7 +3294,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
(Node *) defval, (Node *) defval,
basetype, basetype,
typeOid, typeOid,
colDef->typename->typmod, typmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST);
if (defval == NULL) /* should not happen */ if (defval == NULL) /* should not happen */
@ -4877,6 +4893,7 @@ ATPrepAlterColumnType(List **wqueue,
Form_pg_attribute attTup; Form_pg_attribute attTup;
AttrNumber attnum; AttrNumber attnum;
Oid targettype; Oid targettype;
int32 targettypmod;
Node *transform; Node *transform;
NewColumnValue *newval; NewColumnValue *newval;
ParseState *pstate = make_parsestate(NULL); ParseState *pstate = make_parsestate(NULL);
@ -4907,6 +4924,7 @@ ATPrepAlterColumnType(List **wqueue,
/* Look up the target type */ /* Look up the target type */
targettype = typenameTypeId(NULL, typename); targettype = typenameTypeId(NULL, typename);
targettypmod = typenameTypeMod(NULL, typename, targettype);
/* make sure datatype is legal for a column */ /* make sure datatype is legal for a column */
CheckAttributeType(colName, targettype); CheckAttributeType(colName, targettype);
@ -4958,7 +4976,7 @@ ATPrepAlterColumnType(List **wqueue,
transform = coerce_to_target_type(pstate, transform = coerce_to_target_type(pstate,
transform, exprType(transform), transform, exprType(transform),
targettype, typename->typmod, targettype, targettypmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST);
if (transform == NULL) if (transform == NULL)
@ -5004,6 +5022,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
HeapTuple typeTuple; HeapTuple typeTuple;
Form_pg_type tform; Form_pg_type tform;
Oid targettype; Oid targettype;
int32 targettypmod;
Node *defaultexpr; Node *defaultexpr;
Relation attrelation; Relation attrelation;
Relation depRel; Relation depRel;
@ -5035,6 +5054,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
typeTuple = typenameType(NULL, typename); typeTuple = typenameType(NULL, typename);
tform = (Form_pg_type) GETSTRUCT(typeTuple); tform = (Form_pg_type) GETSTRUCT(typeTuple);
targettype = HeapTupleGetOid(typeTuple); targettype = HeapTupleGetOid(typeTuple);
targettypmod = typenameTypeMod(NULL, typename, targettype);
/* /*
* If there is a default expression for the column, get it and ensure we * If there is a default expression for the column, get it and ensure we
@ -5055,7 +5075,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
defaultexpr = strip_implicit_coercions(defaultexpr); defaultexpr = strip_implicit_coercions(defaultexpr);
defaultexpr = coerce_to_target_type(NULL, /* no UNKNOWN params */ defaultexpr = coerce_to_target_type(NULL, /* no UNKNOWN params */
defaultexpr, exprType(defaultexpr), defaultexpr, exprType(defaultexpr),
targettype, typename->typmod, targettype, targettypmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST);
if (defaultexpr == NULL) if (defaultexpr == NULL)
@ -5272,7 +5292,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
* copy of the syscache entry, so okay to scribble on.) * copy of the syscache entry, so okay to scribble on.)
*/ */
attTup->atttypid = targettype; attTup->atttypid = targettype;
attTup->atttypmod = typename->typmod; attTup->atttypmod = targettypmod;
attTup->attndims = list_length(typename->arrayBounds); attTup->attndims = list_length(typename->arrayBounds);
attTup->attlen = tform->typlen; attTup->attlen = tform->typlen;
attTup->attbyval = tform->typbyval; attTup->attbyval = tform->typbyval;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.97 2006/10/04 00:29:51 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.98 2006/12/30 21:21:53 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
@ -75,6 +75,8 @@ static Oid findTypeInputFunction(List *procname, Oid typeOid);
static Oid findTypeOutputFunction(List *procname, Oid typeOid); static Oid findTypeOutputFunction(List *procname, Oid typeOid);
static Oid findTypeReceiveFunction(List *procname, Oid typeOid); static Oid findTypeReceiveFunction(List *procname, Oid typeOid);
static Oid findTypeSendFunction(List *procname, Oid typeOid); static Oid findTypeSendFunction(List *procname, Oid typeOid);
static Oid findTypeTypmodinFunction(List *procname);
static Oid findTypeTypmodoutFunction(List *procname);
static Oid findTypeAnalyzeFunction(List *procname, Oid typeOid); static Oid findTypeAnalyzeFunction(List *procname, Oid typeOid);
static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode); static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode);
static void checkDomainOwner(HeapTuple tup, TypeName *typename); static void checkDomainOwner(HeapTuple tup, TypeName *typename);
@ -100,6 +102,8 @@ DefineType(List *names, List *parameters)
List *outputName = NIL; List *outputName = NIL;
List *receiveName = NIL; List *receiveName = NIL;
List *sendName = NIL; List *sendName = NIL;
List *typmodinName = NIL;
List *typmodoutName = NIL;
List *analyzeName = NIL; List *analyzeName = NIL;
char *defaultValue = NULL; char *defaultValue = NULL;
bool byValue = false; bool byValue = false;
@ -110,6 +114,8 @@ DefineType(List *names, List *parameters)
Oid outputOid; Oid outputOid;
Oid receiveOid = InvalidOid; Oid receiveOid = InvalidOid;
Oid sendOid = InvalidOid; Oid sendOid = InvalidOid;
Oid typmodinOid = InvalidOid;
Oid typmodoutOid = InvalidOid;
Oid analyzeOid = InvalidOid; Oid analyzeOid = InvalidOid;
char *shadow_type; char *shadow_type;
ListCell *pl; ListCell *pl;
@ -182,6 +188,10 @@ DefineType(List *names, List *parameters)
receiveName = defGetQualifiedName(defel); receiveName = defGetQualifiedName(defel);
else if (pg_strcasecmp(defel->defname, "send") == 0) else if (pg_strcasecmp(defel->defname, "send") == 0)
sendName = defGetQualifiedName(defel); sendName = defGetQualifiedName(defel);
else if (pg_strcasecmp(defel->defname, "typmod_in") == 0)
typmodinName = defGetQualifiedName(defel);
else if (pg_strcasecmp(defel->defname, "typmod_out") == 0)
typmodoutName = defGetQualifiedName(defel);
else if (pg_strcasecmp(defel->defname, "analyze") == 0 || else if (pg_strcasecmp(defel->defname, "analyze") == 0 ||
pg_strcasecmp(defel->defname, "analyse") == 0) pg_strcasecmp(defel->defname, "analyse") == 0)
analyzeName = defGetQualifiedName(defel); analyzeName = defGetQualifiedName(defel);
@ -268,6 +278,11 @@ DefineType(List *names, List *parameters)
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION), (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("type output function must be specified"))); errmsg("type output function must be specified")));
if (typmodinName == NIL && typmodoutName != NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("type modifier output function is useless without a type modifier input function")));
/* /*
* Convert I/O proc names to OIDs * Convert I/O proc names to OIDs
*/ */
@ -335,6 +350,14 @@ DefineType(List *names, List *parameters)
NameListToString(sendName)))); NameListToString(sendName))));
} }
/*
* Convert typmodin/out function proc names to OIDs.
*/
if (typmodinName)
typmodinOid = findTypeTypmodinFunction(typmodinName);
if (typmodoutName)
typmodoutOid = findTypeTypmodoutFunction(typmodoutName);
/* /*
* Convert analysis function proc name to an OID. If no analysis function * Convert analysis function proc name to an OID. If no analysis function
* is specified, we'll use zero to select the built-in default algorithm. * is specified, we'll use zero to select the built-in default algorithm.
@ -362,6 +385,12 @@ DefineType(List *names, List *parameters)
if (sendOid && !pg_proc_ownercheck(sendOid, GetUserId())) if (sendOid && !pg_proc_ownercheck(sendOid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
NameListToString(sendName)); NameListToString(sendName));
if (typmodinOid && !pg_proc_ownercheck(typmodinOid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
NameListToString(typmodinName));
if (typmodoutOid && !pg_proc_ownercheck(typmodoutOid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
NameListToString(typmodoutName));
if (analyzeOid && !pg_proc_ownercheck(analyzeOid, GetUserId())) if (analyzeOid && !pg_proc_ownercheck(analyzeOid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
NameListToString(analyzeName)); NameListToString(analyzeName));
@ -381,6 +410,8 @@ DefineType(List *names, List *parameters)
outputOid, /* output procedure */ outputOid, /* output procedure */
receiveOid, /* receive procedure */ receiveOid, /* receive procedure */
sendOid, /* send procedure */ sendOid, /* send procedure */
typmodinOid, /* typmodin procedure */
typmodoutOid,/* typmodout procedure */
analyzeOid, /* analyze procedure */ analyzeOid, /* analyze procedure */
elemType, /* element type ID */ elemType, /* element type ID */
InvalidOid, /* base type ID (only for domains) */ InvalidOid, /* base type ID (only for domains) */
@ -413,6 +444,8 @@ DefineType(List *names, List *parameters)
F_ARRAY_OUT, /* output procedure */ F_ARRAY_OUT, /* output procedure */
F_ARRAY_RECV, /* receive procedure */ F_ARRAY_RECV, /* receive procedure */
F_ARRAY_SEND, /* send procedure */ F_ARRAY_SEND, /* send procedure */
typmodinOid, /* typmodin procedure */
typmodoutOid, /* typmodout procedure */
InvalidOid, /* analyze procedure - default */ InvalidOid, /* analyze procedure - default */
typoid, /* element type ID */ typoid, /* element type ID */
InvalidOid, /* base type ID */ InvalidOid, /* base type ID */
@ -552,6 +585,7 @@ DefineDomain(CreateDomainStmt *stmt)
Oid basetypeoid; Oid basetypeoid;
Oid domainoid; Oid domainoid;
Form_pg_type baseType; Form_pg_type baseType;
int32 basetypeMod;
/* Convert list of names to a name and namespace */ /* Convert list of names to a name and namespace */
domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname, domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname,
@ -581,9 +615,9 @@ DefineDomain(CreateDomainStmt *stmt)
* Look up the base type. * Look up the base type.
*/ */
typeTup = typenameType(NULL, stmt->typename); typeTup = typenameType(NULL, stmt->typename);
baseType = (Form_pg_type) GETSTRUCT(typeTup); baseType = (Form_pg_type) GETSTRUCT(typeTup);
basetypeoid = HeapTupleGetOid(typeTup); basetypeoid = HeapTupleGetOid(typeTup);
basetypeMod = typenameTypeMod(NULL, stmt->typename, basetypeoid);
/* /*
* Base type must be a plain base type or another domain. Domains over * Base type must be a plain base type or another domain. Domains over
@ -621,6 +655,8 @@ DefineDomain(CreateDomainStmt *stmt)
receiveProcedure = F_DOMAIN_RECV; receiveProcedure = F_DOMAIN_RECV;
sendProcedure = baseType->typsend; sendProcedure = baseType->typsend;
/* Domains never accept typmods, so no typmodin/typmodout needed */
/* Analysis function */ /* Analysis function */
analyzeProcedure = baseType->typanalyze; analyzeProcedure = baseType->typanalyze;
@ -681,7 +717,7 @@ DefineDomain(CreateDomainStmt *stmt)
*/ */
defaultExpr = cookDefault(pstate, constr->raw_expr, defaultExpr = cookDefault(pstate, constr->raw_expr,
basetypeoid, basetypeoid,
stmt->typename->typmod, basetypeMod,
domainName); domainName);
/* /*
@ -768,6 +804,8 @@ DefineDomain(CreateDomainStmt *stmt)
outputProcedure, /* output procedure */ outputProcedure, /* output procedure */
receiveProcedure, /* receive procedure */ receiveProcedure, /* receive procedure */
sendProcedure, /* send procedure */ sendProcedure, /* send procedure */
InvalidOid, /* typmodin procedure - none */
InvalidOid, /* typmodout procedure - none */
analyzeProcedure, /* analyze procedure */ analyzeProcedure, /* analyze procedure */
typelem, /* element type ID */ typelem, /* element type ID */
basetypeoid, /* base type ID */ basetypeoid, /* base type ID */
@ -776,7 +814,7 @@ DefineDomain(CreateDomainStmt *stmt)
byValue, /* passed by value */ byValue, /* passed by value */
alignment, /* required alignment */ alignment, /* required alignment */
storage, /* TOAST strategy */ storage, /* TOAST strategy */
stmt->typename->typmod, /* typeMod value */ basetypeMod, /* typeMod value */
typNDims, /* Array dimensions for base type */ typNDims, /* Array dimensions for base type */
typNotNull); /* Type NOT NULL */ typNotNull); /* Type NOT NULL */
@ -793,7 +831,7 @@ DefineDomain(CreateDomainStmt *stmt)
{ {
case CONSTR_CHECK: case CONSTR_CHECK:
domainAddConstraint(domainoid, domainNamespace, domainAddConstraint(domainoid, domainNamespace,
basetypeoid, stmt->typename->typmod, basetypeoid, basetypeMod,
constr, domainName); constr, domainName);
break; break;
@ -1067,6 +1105,60 @@ findTypeSendFunction(List *procname, Oid typeOid)
return InvalidOid; /* keep compiler quiet */ return InvalidOid; /* keep compiler quiet */
} }
static Oid
findTypeTypmodinFunction(List *procname)
{
Oid argList[1];
Oid procOid;
/*
* typmodin functions always take one int4[] argument and return int4.
*/
argList[0] = INT4ARRAYOID;
procOid = LookupFuncName(procname, 1, argList, true);
if (!OidIsValid(procOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function %s does not exist",
func_signature_string(procname, 1, argList))));
if (get_func_rettype(procOid) != INT4OID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("typmod_in function %s must return type \"integer\"",
NameListToString(procname))));
return procOid;
}
static Oid
findTypeTypmodoutFunction(List *procname)
{
Oid argList[1];
Oid procOid;
/*
* typmodout functions always take one int4 argument and return cstring.
*/
argList[0] = INT4OID;
procOid = LookupFuncName(procname, 1, argList, true);
if (!OidIsValid(procOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function %s does not exist",
func_signature_string(procname, 1, argList))));
if (get_func_rettype(procOid) != CSTRINGOID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("typmod_out function %s must return type \"cstring\"",
NameListToString(procname))));
return procOid;
}
static Oid static Oid
findTypeAnalyzeFunction(List *procname, Oid typeOid) findTypeAnalyzeFunction(List *procname, Oid typeOid)
{ {
@ -1244,6 +1336,8 @@ AlterDomainDefault(List *names, Node *defaultRaw)
typTup->typoutput, typTup->typoutput,
typTup->typreceive, typTup->typreceive,
typTup->typsend, typTup->typsend,
typTup->typmodin,
typTup->typmodout,
typTup->typanalyze, typTup->typanalyze,
typTup->typelem, typTup->typelem,
typTup->typbasetype, typTup->typbasetype,

View File

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.357 2006/12/24 00:29:18 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.358 2006/12/30 21:21:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1584,7 +1584,8 @@ _copyTypeName(TypeName *from)
COPY_SCALAR_FIELD(timezone); COPY_SCALAR_FIELD(timezone);
COPY_SCALAR_FIELD(setof); COPY_SCALAR_FIELD(setof);
COPY_SCALAR_FIELD(pct_type); COPY_SCALAR_FIELD(pct_type);
COPY_SCALAR_FIELD(typmod); COPY_NODE_FIELD(typmods);
COPY_SCALAR_FIELD(typemod);
COPY_NODE_FIELD(arrayBounds); COPY_NODE_FIELD(arrayBounds);
COPY_SCALAR_FIELD(location); COPY_SCALAR_FIELD(location);

View File

@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.291 2006/12/24 00:29:18 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.292 2006/12/30 21:21:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1614,7 +1614,8 @@ _equalTypeName(TypeName *a, TypeName *b)
COMPARE_SCALAR_FIELD(timezone); COMPARE_SCALAR_FIELD(timezone);
COMPARE_SCALAR_FIELD(setof); COMPARE_SCALAR_FIELD(setof);
COMPARE_SCALAR_FIELD(pct_type); COMPARE_SCALAR_FIELD(pct_type);
COMPARE_SCALAR_FIELD(typmod); COMPARE_NODE_FIELD(typmods);
COMPARE_SCALAR_FIELD(typemod);
COMPARE_NODE_FIELD(arrayBounds); COMPARE_NODE_FIELD(arrayBounds);
COMPARE_SCALAR_FIELD(location); COMPARE_SCALAR_FIELD(location);

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.52 2006/10/04 00:29:53 momjian Exp $ * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.53 2006/12/30 21:21:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -262,12 +262,7 @@ makeRangeVar(char *schemaname, char *relname)
TypeName * TypeName *
makeTypeName(char *typnam) makeTypeName(char *typnam)
{ {
TypeName *n = makeNode(TypeName); return makeTypeNameFromNameList(list_make1(makeString(typnam)));
n->names = list_make1(makeString(typnam));
n->typmod = -1;
n->location = -1;
return n;
} }
/* /*
@ -282,14 +277,15 @@ makeTypeNameFromNameList(List *names)
TypeName *n = makeNode(TypeName); TypeName *n = makeNode(TypeName);
n->names = names; n->names = names;
n->typmod = -1; n->typmods = NIL;
n->typemod = -1;
n->location = -1; n->location = -1;
return n; return n;
} }
/* /*
* makeTypeNameFromOid - * makeTypeNameFromOid -
* build a TypeName node to represent a type already known by OID. * build a TypeName node to represent a type already known by OID/typmod.
*/ */
TypeName * TypeName *
makeTypeNameFromOid(Oid typeid, int32 typmod) makeTypeNameFromOid(Oid typeid, int32 typmod)
@ -297,7 +293,7 @@ makeTypeNameFromOid(Oid typeid, int32 typmod)
TypeName *n = makeNode(TypeName); TypeName *n = makeNode(TypeName);
n->typeid = typeid; n->typeid = typeid;
n->typmod = typmod; n->typemod = typmod;
n->location = -1; n->location = -1;
return n; return n;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.289 2006/12/24 00:29:18 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.290 2006/12/30 21:21:53 tgl Exp $
* *
* NOTES * NOTES
* Every node type that can appear in stored rules' parsetrees *must* * Every node type that can appear in stored rules' parsetrees *must*
@ -1476,7 +1476,8 @@ _outTypeName(StringInfo str, TypeName *node)
WRITE_BOOL_FIELD(timezone); WRITE_BOOL_FIELD(timezone);
WRITE_BOOL_FIELD(setof); WRITE_BOOL_FIELD(setof);
WRITE_BOOL_FIELD(pct_type); WRITE_BOOL_FIELD(pct_type);
WRITE_INT_FIELD(typmod); WRITE_NODE_FIELD(typmods);
WRITE_INT_FIELD(typemod);
WRITE_NODE_FIELD(arrayBounds); WRITE_NODE_FIELD(arrayBounds);
WRITE_INT_FIELD(location); WRITE_INT_FIELD(location);
} }

View File

@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.570 2006/12/24 00:29:18 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.571 2006/12/30 21:21:53 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -206,7 +206,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
%type <str> relation_name copy_file_name %type <str> relation_name copy_file_name
database_name access_method_clause access_method attr_name database_name access_method_clause access_method attr_name
index_name name function_name file_name index_name name file_name
%type <list> func_name handler_name qual_Op qual_all_Op subquery_Op %type <list> func_name handler_name qual_Op qual_all_Op subquery_Op
opt_class opt_validator opt_class opt_validator
@ -242,7 +242,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
group_clause TriggerFuncArgs select_limit group_clause TriggerFuncArgs select_limit
opt_select_limit opclass_item_list opt_select_limit opclass_item_list
transaction_mode_list_or_empty transaction_mode_list_or_empty
TableFuncElementList TableFuncElementList opt_type_modifiers
prep_type_clause prep_type_list prep_type_clause prep_type_list
execute_param_clause using_clause returning_clause execute_param_clause using_clause returning_clause
@ -319,20 +319,19 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
%type <str> character %type <str> character
%type <str> extract_arg %type <str> extract_arg
%type <str> opt_charset %type <str> opt_charset
%type <ival> opt_numeric opt_decimal
%type <boolean> opt_varying opt_timezone %type <boolean> opt_varying opt_timezone
%type <ival> Iconst SignedIconst %type <ival> Iconst SignedIconst
%type <str> Sconst comment_text %type <str> Sconst comment_text
%type <str> RoleId opt_granted_by opt_boolean ColId_or_Sconst %type <str> RoleId opt_granted_by opt_boolean ColId_or_Sconst
%type <list> var_list var_list_or_default %type <list> var_list var_list_or_default
%type <str> ColId ColLabel var_name type_name param_name %type <str> ColId ColLabel var_name type_function_name param_name
%type <node> var_value zone_value %type <node> var_value zone_value
%type <keyword> unreserved_keyword func_name_keyword %type <keyword> unreserved_keyword type_func_name_keyword
%type <keyword> col_name_keyword reserved_keyword %type <keyword> col_name_keyword reserved_keyword
%type <node> TableConstraint TableLikeClause %type <node> TableConstraint TableLikeClause
%type <list> TableLikeOptionList %type <list> TableLikeOptionList
%type <ival> TableLikeOption %type <ival> TableLikeOption
%type <list> ColQualList %type <list> ColQualList
@ -1180,35 +1179,20 @@ zone_value:
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE"))); errmsg("time zone interval must be HOUR or HOUR TO MINUTE")));
n->typename->typmod = INTERVAL_TYPMOD(INTERVAL_FULL_PRECISION, $3); n->typename->typmods = list_make1(makeIntConst($3));
} }
$$ = (Node *)n; $$ = (Node *)n;
} }
| ConstInterval '(' Iconst ')' Sconst opt_interval | ConstInterval '(' Iconst ')' Sconst opt_interval
{ {
A_Const *n = (A_Const *) makeStringConst($5, $1); A_Const *n = (A_Const *) makeStringConst($5, $1);
if ($3 < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("INTERVAL(%d) precision must not be negative",
$3)));
if ($3 > MAX_INTERVAL_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",
$3, MAX_INTERVAL_PRECISION)));
$3 = MAX_INTERVAL_PRECISION;
}
if (($6 != INTERVAL_FULL_RANGE) if (($6 != INTERVAL_FULL_RANGE)
&& (($6 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)) && (($6 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE"))); errmsg("time zone interval must be HOUR or HOUR TO MINUTE")));
n->typename->typmods = list_make2(makeIntConst($6),
n->typename->typmod = INTERVAL_TYPMOD($3, $6); makeIntConst($3));
$$ = (Node *)n; $$ = (Node *)n;
} }
| NumericOnly { $$ = makeAConst($1); } | NumericOnly { $$ = makeAConst($1); }
@ -2823,7 +2807,7 @@ DefineStmt:
n->definition = $4; n->definition = $4;
$$ = (Node *)n; $$ = (Node *)n;
} }
| CREATE TYPE_P any_name | CREATE TYPE_P any_name
{ {
/* Shell type (identified by lack of definition) */ /* Shell type (identified by lack of definition) */
DefineStmt *n = makeNode(DefineStmt); DefineStmt *n = makeNode(DefineStmt);
@ -2889,7 +2873,6 @@ def_elem: ColLabel '=' def_arg
/* Note: any simple identifier will be returned as a type name! */ /* Note: any simple identifier will be returned as a type name! */
def_arg: func_type { $$ = (Node *)$1; } def_arg: func_type { $$ = (Node *)$1; }
| func_name_keyword { $$ = (Node *)makeString(pstrdup($1)); }
| reserved_keyword { $$ = (Node *)makeString(pstrdup($1)); } | reserved_keyword { $$ = (Node *)makeString(pstrdup($1)); }
| qual_all_Op { $$ = (Node *)$1; } | qual_all_Op { $$ = (Node *)$1; }
| NumericOnly { $$ = (Node *)$1; } | NumericOnly { $$ = (Node *)$1; }
@ -3047,7 +3030,7 @@ ReassignOwnedStmt:
* *
* QUERY: * QUERY:
* *
* DROP itemtype [ IF EXISTS ] itemname [, itemname ...] * DROP itemtype [ IF EXISTS ] itemname [, itemname ...]
* [ RESTRICT | CASCADE ] * [ RESTRICT | CASCADE ]
* *
*****************************************************************************/ *****************************************************************************/
@ -3872,7 +3855,7 @@ arg_class: IN_P { $$ = FUNC_PARAM_IN; }
/* /*
* Ideally param_name should be ColId, but that causes too many conflicts. * Ideally param_name should be ColId, but that causes too many conflicts.
*/ */
param_name: function_name param_name: type_function_name
; ;
func_return: func_return:
@ -3888,23 +3871,20 @@ func_return:
/* /*
* We would like to make the %TYPE productions here be ColId attrs etc, * We would like to make the %TYPE productions here be ColId attrs etc,
* but that causes reduce/reduce conflicts. type_name is next best choice. * but that causes reduce/reduce conflicts. type_function_name
* is next best choice.
*/ */
func_type: Typename { $$ = $1; } func_type: Typename { $$ = $1; }
| type_name attrs '%' TYPE_P | type_function_name attrs '%' TYPE_P
{ {
$$ = makeNode(TypeName); $$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
$$->names = lcons(makeString($1), $2);
$$->pct_type = true; $$->pct_type = true;
$$->typmod = -1;
$$->location = @1; $$->location = @1;
} }
| SETOF type_name attrs '%' TYPE_P | SETOF type_function_name attrs '%' TYPE_P
{ {
$$ = makeNode(TypeName); $$ = makeTypeNameFromNameList(lcons(makeString($2), $3));
$$->names = lcons(makeString($2), $3);
$$->pct_type = true; $$->pct_type = true;
$$->typmod = -1;
$$->setof = TRUE; $$->setof = TRUE;
$$->location = @2; $$->location = @2;
} }
@ -5552,7 +5532,7 @@ multiple_set_clause:
res_col->val = res_val; res_col->val = res_val;
} }
$$ = $2; $$ = $2;
} }
; ;
@ -6363,14 +6343,6 @@ opt_array_bounds:
{ $$ = NIL; } { $$ = NIL; }
; ;
/*
* XXX ideally, the production for a qualified typename should be ColId attrs
* (there's no obvious reason why the first name should need to be restricted)
* and should be an alternative of GenericType (so that it can be used to
* specify a type for a literal in AExprConst). However doing either causes
* reduce/reduce conflicts that I haven't been able to find a workaround
* for. FIXME later.
*/
SimpleTypename: SimpleTypename:
GenericType { $$ = $1; } GenericType { $$ = $1; }
| Numeric { $$ = $1; } | Numeric { $$ = $1; }
@ -6381,32 +6353,13 @@ SimpleTypename:
{ {
$$ = $1; $$ = $1;
if ($2 != INTERVAL_FULL_RANGE) if ($2 != INTERVAL_FULL_RANGE)
$$->typmod = INTERVAL_TYPMOD(INTERVAL_FULL_PRECISION, $2); $$->typmods = list_make1(makeIntConst($2));
} }
| ConstInterval '(' Iconst ')' opt_interval | ConstInterval '(' Iconst ')' opt_interval
{ {
$$ = $1; $$ = $1;
if ($3 < 0) $$->typmods = list_make2(makeIntConst($5),
ereport(ERROR, makeIntConst($3));
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("INTERVAL(%d) precision must not be negative",
$3)));
if ($3 > MAX_INTERVAL_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",
$3, MAX_INTERVAL_PRECISION)));
$3 = MAX_INTERVAL_PRECISION;
}
$$->typmod = INTERVAL_TYPMOD($3, $5);
}
| type_name attrs
{
$$ = makeNode(TypeName);
$$->names = lcons(makeString($1), $2);
$$->typmod = -1;
$$->location = @1;
} }
; ;
@ -6417,80 +6370,112 @@ SimpleTypename:
* where there is an obvious better choice to make. * where there is an obvious better choice to make.
* Note that ConstInterval is not included here since it must * Note that ConstInterval is not included here since it must
* be pushed up higher in the rules to accomodate the postfix * be pushed up higher in the rules to accomodate the postfix
* options (e.g. INTERVAL '1' YEAR). * options (e.g. INTERVAL '1' YEAR). Likewise, we have to handle
* the generic-type-name case in AExprConst to avoid premature
* reduce/reduce conflicts against function names.
*/ */
ConstTypename: ConstTypename:
GenericType { $$ = $1; } Numeric { $$ = $1; }
| Numeric { $$ = $1; }
| ConstBit { $$ = $1; } | ConstBit { $$ = $1; }
| ConstCharacter { $$ = $1; } | ConstCharacter { $$ = $1; }
| ConstDatetime { $$ = $1; } | ConstDatetime { $$ = $1; }
; ;
/*
* GenericType covers all type names that don't have special syntax mandated
* by the standard, including qualified names. We also allow type modifiers.
* To avoid parsing conflicts against function invocations, the modifiers
* have to be shown as expr_list here, but parse analysis will only accept
* integer constants for them.
*/
GenericType: GenericType:
type_name type_function_name opt_type_modifiers
{ {
$$ = makeTypeName($1); $$ = makeTypeName($1);
$$->typmods = $2;
$$->location = @1;
}
| type_function_name attrs opt_type_modifiers
{
$$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
$$->typmods = $3;
$$->location = @1; $$->location = @1;
} }
; ;
/* SQL92 numeric data types opt_type_modifiers: '(' expr_list ')' { $$ = $2; }
* Check FLOAT() precision limits assuming IEEE floating types. | /* EMPTY */ { $$ = NIL; }
* - thomas 1997-09-18 ;
* Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
/*
* SQL92 numeric data types
*/ */
Numeric: INT_P Numeric: INT_P
{ {
$$ = SystemTypeName("int4"); $$ = SystemTypeName("int4");
$$->location = @1;
} }
| INTEGER | INTEGER
{ {
$$ = SystemTypeName("int4"); $$ = SystemTypeName("int4");
$$->location = @1;
} }
| SMALLINT | SMALLINT
{ {
$$ = SystemTypeName("int2"); $$ = SystemTypeName("int2");
$$->location = @1;
} }
| BIGINT | BIGINT
{ {
$$ = SystemTypeName("int8"); $$ = SystemTypeName("int8");
$$->location = @1;
} }
| REAL | REAL
{ {
$$ = SystemTypeName("float4"); $$ = SystemTypeName("float4");
$$->location = @1;
} }
| FLOAT_P opt_float | FLOAT_P opt_float
{ {
$$ = $2; $$ = $2;
$$->location = @1;
} }
| DOUBLE_P PRECISION | DOUBLE_P PRECISION
{ {
$$ = SystemTypeName("float8"); $$ = SystemTypeName("float8");
$$->location = @1;
} }
| DECIMAL_P opt_decimal | DECIMAL_P opt_type_modifiers
{ {
$$ = SystemTypeName("numeric"); $$ = SystemTypeName("numeric");
$$->typmod = $2; $$->typmods = $2;
$$->location = @1;
} }
| DEC opt_decimal | DEC opt_type_modifiers
{ {
$$ = SystemTypeName("numeric"); $$ = SystemTypeName("numeric");
$$->typmod = $2; $$->typmods = $2;
$$->location = @1;
} }
| NUMERIC opt_numeric | NUMERIC opt_type_modifiers
{ {
$$ = SystemTypeName("numeric"); $$ = SystemTypeName("numeric");
$$->typmod = $2; $$->typmods = $2;
$$->location = @1;
} }
| BOOLEAN_P | BOOLEAN_P
{ {
$$ = SystemTypeName("bool"); $$ = SystemTypeName("bool");
$$->location = @1;
} }
; ;
opt_float: '(' Iconst ')' opt_float: '(' Iconst ')'
{ {
/*
* Check FLOAT() precision limits assuming IEEE floating
* types - thomas 1997-09-18
*/
if ($2 < 1) if ($2 < 1)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@ -6510,73 +6495,6 @@ opt_float: '(' Iconst ')'
} }
; ;
opt_numeric:
'(' Iconst ',' Iconst ')'
{
if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("NUMERIC precision %d must be between 1 and %d",
$2, NUMERIC_MAX_PRECISION)));
if ($4 < 0 || $4 > $2)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("NUMERIC scale %d must be between 0 and precision %d",
$4, $2)));
$$ = (($2 << 16) | $4) + VARHDRSZ;
}
| '(' Iconst ')'
{
if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("NUMERIC precision %d must be between 1 and %d",
$2, NUMERIC_MAX_PRECISION)));
$$ = ($2 << 16) + VARHDRSZ;
}
| /*EMPTY*/
{
/* Insert "-1" meaning "no limit" */
$$ = -1;
}
;
opt_decimal:
'(' Iconst ',' Iconst ')'
{
if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("DECIMAL precision %d must be between 1 and %d",
$2, NUMERIC_MAX_PRECISION)));
if ($4 < 0 || $4 > $2)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("DECIMAL scale %d must be between 0 and precision %d",
$4, $2)));
$$ = (($2 << 16) | $4) + VARHDRSZ;
}
| '(' Iconst ')'
{
if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("DECIMAL precision %d must be between 1 and %d",
$2, NUMERIC_MAX_PRECISION)));
$$ = ($2 << 16) + VARHDRSZ;
}
| /*EMPTY*/
{
/* Insert "-1" meaning "no limit" */
$$ = -1;
}
;
/* /*
* SQL92 bit-field data types * SQL92 bit-field data types
* The following implements BIT() and BIT VARYING(). * The following implements BIT() and BIT VARYING().
@ -6600,28 +6518,19 @@ ConstBit: BitWithLength
| BitWithoutLength | BitWithoutLength
{ {
$$ = $1; $$ = $1;
$$->typmod = -1; $$->typmods = NIL;
} }
; ;
BitWithLength: BitWithLength:
BIT opt_varying '(' Iconst ')' BIT opt_varying '(' expr_list ')'
{ {
char *typname; char *typname;
typname = $2 ? "varbit" : "bit"; typname = $2 ? "varbit" : "bit";
$$ = SystemTypeName(typname); $$ = SystemTypeName(typname);
if ($4 < 1) $$->typmods = $4;
ereport(ERROR, $$->location = @1;
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("length for type %s must be at least 1",
typname)));
else if ($4 > (MaxAttrSize * BITS_PER_BYTE))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("length for type %s cannot exceed %d",
typname, MaxAttrSize * BITS_PER_BYTE)));
$$->typmod = $4;
} }
; ;
@ -6632,13 +6541,13 @@ BitWithoutLength:
if ($2) if ($2)
{ {
$$ = SystemTypeName("varbit"); $$ = SystemTypeName("varbit");
$$->typmod = -1;
} }
else else
{ {
$$ = SystemTypeName("bit"); $$ = SystemTypeName("bit");
$$->typmod = 1; $$->typmods = list_make1(makeIntConst(1));
} }
$$->location = @1;
} }
; ;
@ -6670,7 +6579,7 @@ ConstCharacter: CharacterWithLength
* was not specified. * was not specified.
*/ */
$$ = $1; $$ = $1;
$$->typmod = -1; $$->typmods = NIL;
} }
; ;
@ -6688,24 +6597,8 @@ CharacterWithLength: character '(' Iconst ')' opt_charset
} }
$$ = SystemTypeName($1); $$ = SystemTypeName($1);
$$->typmods = list_make1(makeIntConst($3));
if ($3 < 1) $$->location = @1;
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("length for type %s must be at least 1",
$1)));
else if ($3 > MaxAttrSize)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("length for type %s cannot exceed %d",
$1, MaxAttrSize)));
/* we actually implement these like a varlen, so
* the first 4 bytes is the length. (the difference
* between these and "text" is that we blank-pad and
* truncate where necessary)
*/
$$->typmod = VARHDRSZ + $3;
} }
; ;
@ -6726,9 +6619,9 @@ CharacterWithoutLength: character opt_charset
/* char defaults to char(1), varchar to no limit */ /* char defaults to char(1), varchar to no limit */
if (strcmp($1, "bpchar") == 0) if (strcmp($1, "bpchar") == 0)
$$->typmod = VARHDRSZ + 1; $$->typmods = list_make1(makeIntConst(1));
else
$$->typmod = -1; $$->location = @1;
} }
; ;
@ -6756,6 +6649,9 @@ opt_charset:
| /*EMPTY*/ { $$ = NULL; } | /*EMPTY*/ { $$ = NULL; }
; ;
/*
* SQL92 date/time types
*/
ConstDatetime: ConstDatetime:
TIMESTAMP '(' Iconst ')' opt_timezone TIMESTAMP '(' Iconst ')' opt_timezone
{ {
@ -6767,21 +6663,8 @@ ConstDatetime:
* - thomas 2001-09-06 * - thomas 2001-09-06
*/ */
$$->timezone = $5; $$->timezone = $5;
if ($3 < 0) $$->typmods = list_make1(makeIntConst($3));
ereport(ERROR, $$->location = @1;
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIMESTAMP(%d)%s precision must not be negative",
$3, ($5 ? " WITH TIME ZONE": ""))));
if ($3 > MAX_TIMESTAMP_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
$3, ($5 ? " WITH TIME ZONE": ""),
MAX_TIMESTAMP_PRECISION)));
$3 = MAX_TIMESTAMP_PRECISION;
}
$$->typmod = $3;
} }
| TIMESTAMP opt_timezone | TIMESTAMP opt_timezone
{ {
@ -6793,6 +6676,7 @@ ConstDatetime:
* - thomas 2001-09-06 * - thomas 2001-09-06
*/ */
$$->timezone = $2; $$->timezone = $2;
$$->location = @1;
} }
| TIME '(' Iconst ')' opt_timezone | TIME '(' Iconst ')' opt_timezone
{ {
@ -6800,21 +6684,8 @@ ConstDatetime:
$$ = SystemTypeName("timetz"); $$ = SystemTypeName("timetz");
else else
$$ = SystemTypeName("time"); $$ = SystemTypeName("time");
if ($3 < 0) $$->typmods = list_make1(makeIntConst($3));
ereport(ERROR, $$->location = @1;
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIME(%d)%s precision must not be negative",
$3, ($5 ? " WITH TIME ZONE": ""))));
if ($3 > MAX_TIME_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIME(%d)%s precision reduced to maximum allowed, %d",
$3, ($5 ? " WITH TIME ZONE": ""),
MAX_TIME_PRECISION)));
$3 = MAX_TIME_PRECISION;
}
$$->typmod = $3;
} }
| TIME opt_timezone | TIME opt_timezone
{ {
@ -6822,11 +6693,16 @@ ConstDatetime:
$$ = SystemTypeName("timetz"); $$ = SystemTypeName("timetz");
else else
$$ = SystemTypeName("time"); $$ = SystemTypeName("time");
$$->location = @1;
} }
; ;
ConstInterval: ConstInterval:
INTERVAL { $$ = SystemTypeName("interval"); } INTERVAL
{
$$ = SystemTypeName("interval");
$$->location = @1;
}
; ;
opt_timezone: opt_timezone:
@ -7520,20 +7396,7 @@ func_expr: func_name '(' ')'
s->val.val.str = "now"; s->val.val.str = "now";
s->typename = SystemTypeName("text"); s->typename = SystemTypeName("text");
d = SystemTypeName("timetz"); d = SystemTypeName("timetz");
if ($3 < 0) d->typmods = list_make1(makeIntConst($3));
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("CURRENT_TIME(%d) precision must not be negative",
$3)));
if ($3 > MAX_TIME_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("CURRENT_TIME(%d) precision reduced to maximum allowed, %d",
$3, MAX_TIME_PRECISION)));
$3 = MAX_TIME_PRECISION;
}
d->typmod = $3;
$$ = (Node *)makeTypeCast((Node *)s, d); $$ = (Node *)makeTypeCast((Node *)s, d);
} }
@ -7565,20 +7428,7 @@ func_expr: func_name '(' ')'
s->typename = SystemTypeName("text"); s->typename = SystemTypeName("text");
d = SystemTypeName("timestamptz"); d = SystemTypeName("timestamptz");
if ($3 < 0) d->typmods = list_make1(makeIntConst($3));
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("CURRENT_TIMESTAMP(%d) precision must not be negative",
$3)));
if ($3 > MAX_TIMESTAMP_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("CURRENT_TIMESTAMP(%d) precision reduced to maximum allowed, %d",
$3, MAX_TIMESTAMP_PRECISION)));
$3 = MAX_TIMESTAMP_PRECISION;
}
d->typmod = $3;
$$ = (Node *)makeTypeCast((Node *)s, d); $$ = (Node *)makeTypeCast((Node *)s, d);
} }
@ -7612,20 +7462,7 @@ func_expr: func_name '(' ')'
s->val.val.str = "now"; s->val.val.str = "now";
s->typename = SystemTypeName("text"); s->typename = SystemTypeName("text");
d = SystemTypeName("time"); d = SystemTypeName("time");
if ($3 < 0) d->typmods = list_make1(makeIntConst($3));
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("LOCALTIME(%d) precision must not be negative",
$3)));
if ($3 > MAX_TIME_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("LOCALTIME(%d) precision reduced to maximum allowed, %d",
$3, MAX_TIME_PRECISION)));
$3 = MAX_TIME_PRECISION;
}
d->typmod = $3;
$$ = (Node *)makeTypeCast((Node *)s, d); $$ = (Node *)makeTypeCast((Node *)s, d);
} }
@ -7660,20 +7497,7 @@ func_expr: func_name '(' ')'
s->typename = SystemTypeName("text"); s->typename = SystemTypeName("text");
d = SystemTypeName("timestamp"); d = SystemTypeName("timestamp");
if ($3 < 0) d->typmods = list_make1(makeIntConst($3));
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("LOCALTIMESTAMP(%d) precision must not be negative",
$3)));
if ($3 > MAX_TIMESTAMP_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("LOCALTIMESTAMP(%d) precision reduced to maximum allowed, %d",
$3, MAX_TIMESTAMP_PRECISION)));
$3 = MAX_TIMESTAMP_PRECISION;
}
d->typmod = $3;
$$ = (Node *)makeTypeCast((Node *)s, d); $$ = (Node *)makeTypeCast((Node *)s, d);
} }
@ -7880,7 +7704,7 @@ func_expr: func_name '(' ')'
$$ = (Node *)v; $$ = (Node *)v;
} }
| XMLCONCAT '(' expr_list ')' | XMLCONCAT '(' expr_list ')'
{ {
$$ = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, $3); $$ = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, $3);
} }
| XMLELEMENT '(' NAME_P ColLabel ')' | XMLELEMENT '(' NAME_P ColLabel ')'
@ -7985,7 +7809,7 @@ xml_attribute_el: a_expr AS ColLabel
$$ = makeNode(ResTarget); $$ = makeNode(ResTarget);
$$->name = NULL; $$->name = NULL;
$$->indirection = NULL; $$->indirection = NULL;
$$->val = (Node *) $1; $$->val = (Node *) $1;
$$->location = @1; $$->location = @1;
} }
; ;
@ -8486,12 +8310,12 @@ file_name: Sconst { $$ = $1; };
/* /*
* The production for a qualified func_name has to exactly match the * The production for a qualified func_name has to exactly match the
* production for a qualified columnref, because we cannot tell which we * production for a qualified columnref, because we cannot tell which we
* are parsing until we see what comes after it ('(' for a func_name, * are parsing until we see what comes after it ('(' or Sconst for a func_name,
* anything else for a columnref). Therefore we allow 'indirection' which * anything else for a columnref). Therefore we allow 'indirection' which
* may contain subscripts, and reject that case in the C code. (If we * may contain subscripts, and reject that case in the C code. (If we
* ever implement SQL99-like methods, such syntax may actually become legal!) * ever implement SQL99-like methods, such syntax may actually become legal!)
*/ */
func_name: function_name func_name: type_function_name
{ $$ = list_make1(makeString($1)); } { $$ = list_make1(makeString($1)); }
| relation_name indirection | relation_name indirection
{ $$ = check_func_name(lcons(makeString($1), $2)); } { $$ = check_func_name(lcons(makeString($1), $2)); }
@ -8541,6 +8365,27 @@ AexprConst: Iconst
n->val.val.str = $1; n->val.val.str = $1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| func_name Sconst
{
/* generic type 'literal' syntax */
A_Const *n = makeNode(A_Const);
n->typename = makeTypeNameFromNameList($1);
n->typename->location = @1;
n->val.type = T_String;
n->val.val.str = $2;
$$ = (Node *)n;
}
| func_name '(' expr_list ')' Sconst
{
/* generic syntax with a type modifier */
A_Const *n = makeNode(A_Const);
n->typename = makeTypeNameFromNameList($1);
n->typename->typmods = $3;
n->typename->location = @1;
n->val.type = T_String;
n->val.val.str = $5;
$$ = (Node *)n;
}
| ConstTypename Sconst | ConstTypename Sconst
{ {
A_Const *n = makeNode(A_Const); A_Const *n = makeNode(A_Const);
@ -8557,7 +8402,7 @@ AexprConst: Iconst
n->val.val.str = $2; n->val.val.str = $2;
/* precision is not specified, but fields may be... */ /* precision is not specified, but fields may be... */
if ($3 != INTERVAL_FULL_RANGE) if ($3 != INTERVAL_FULL_RANGE)
n->typename->typmod = INTERVAL_TYPMOD(INTERVAL_FULL_PRECISION, $3); n->typename->typmods = list_make1(makeIntConst($3));
$$ = (Node *)n; $$ = (Node *)n;
} }
| ConstInterval '(' Iconst ')' Sconst opt_interval | ConstInterval '(' Iconst ')' Sconst opt_interval
@ -8566,21 +8411,8 @@ AexprConst: Iconst
n->typename = $1; n->typename = $1;
n->val.type = T_String; n->val.type = T_String;
n->val.val.str = $5; n->val.val.str = $5;
/* precision specified, and fields may be... */ n->typename->typmods = list_make2(makeIntConst($6),
if ($3 < 0) makeIntConst($3));
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("INTERVAL(%d) precision must not be negative",
$3)));
if ($3 > MAX_INTERVAL_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",
$3, MAX_INTERVAL_PRECISION)));
$3 = MAX_INTERVAL_PRECISION;
}
n->typename->typmod = INTERVAL_TYPMOD($3, $6);
$$ = (Node *)n; $$ = (Node *)n;
} }
| TRUE_P | TRUE_P
@ -8625,18 +8457,11 @@ ColId: IDENT { $$ = $1; }
| col_name_keyword { $$ = pstrdup($1); } | col_name_keyword { $$ = pstrdup($1); }
; ;
/* Type identifier --- names that can be type names. /* Type/function identifier --- names that can be type or function names.
*/ */
type_name: IDENT { $$ = $1; } type_function_name: IDENT { $$ = $1; }
| unreserved_keyword { $$ = pstrdup($1); } | unreserved_keyword { $$ = pstrdup($1); }
; | type_func_name_keyword { $$ = pstrdup($1); }
/* Function identifier --- names that can be function names.
*/
function_name:
IDENT { $$ = $1; }
| unreserved_keyword { $$ = pstrdup($1); }
| func_name_keyword { $$ = pstrdup($1); }
; ;
/* Column label --- allowed labels in "AS" clauses. /* Column label --- allowed labels in "AS" clauses.
@ -8645,7 +8470,7 @@ function_name:
ColLabel: IDENT { $$ = $1; } ColLabel: IDENT { $$ = $1; }
| unreserved_keyword { $$ = pstrdup($1); } | unreserved_keyword { $$ = pstrdup($1); }
| col_name_keyword { $$ = pstrdup($1); } | col_name_keyword { $$ = pstrdup($1); }
| func_name_keyword { $$ = pstrdup($1); } | type_func_name_keyword { $$ = pstrdup($1); }
| reserved_keyword { $$ = pstrdup($1); } | reserved_keyword { $$ = pstrdup($1); }
; ;
@ -8940,7 +8765,7 @@ col_name_keyword:
| XMLSERIALIZE | XMLSERIALIZE
; ;
/* Function identifier --- keywords that can be function names. /* Type/function identifier --- keywords that can be type or function names.
* *
* Most of these are keywords that are used as operators in expressions; * Most of these are keywords that are used as operators in expressions;
* in general such keywords can't be column names because they would be * in general such keywords can't be column names because they would be
@ -8950,7 +8775,7 @@ col_name_keyword:
* productions in a_expr to support the goofy SQL9x argument syntax. * productions in a_expr to support the goofy SQL9x argument syntax.
* - thomas 2000-11-28 * - thomas 2000-11-28
*/ */
func_name_keyword: type_func_name_keyword:
AUTHORIZATION AUTHORIZATION
| BETWEEN | BETWEEN
| BINARY | BINARY
@ -9383,12 +9208,8 @@ SystemFuncName(char *name)
TypeName * TypeName *
SystemTypeName(char *name) SystemTypeName(char *name)
{ {
TypeName *n = makeNode(TypeName); return makeTypeNameFromNameList(list_make2(makeString("pg_catalog"),
makeString(name)));
n->names = list_make2(makeString("pg_catalog"), makeString(name));
n->typmod = -1;
n->location = -1;
return n;
} }
/* parser_init() /* parser_init()

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.202 2006/12/24 00:29:19 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.203 2006/12/30 21:21:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1810,29 +1810,6 @@ exprTypmod(Node *expr)
{ {
case T_Var: case T_Var:
return ((Var *) expr)->vartypmod; return ((Var *) expr)->vartypmod;
case T_Const:
{
/* Be smart about string constants... */
Const *con = (Const *) expr;
switch (con->consttype)
{
case BPCHAROID:
if (!con->constisnull)
{
int32 len = VARSIZE(DatumGetPointer(con->constvalue)) - VARHDRSZ;
/* if multi-byte, take len and find # characters */
if (pg_database_encoding_max_length() > 1)
len = pg_mbstrlen_with_len(VARDATA(DatumGetPointer(con->constvalue)), len);
return len + VARHDRSZ;
}
break;
default:
break;
}
}
break;
case T_Param: case T_Param:
return ((Param *) expr)->paramtypmod; return ((Param *) expr)->paramtypmod;
case T_FuncExpr: case T_FuncExpr:
@ -2024,14 +2001,16 @@ typecast_expression(ParseState *pstate, Node *expr, TypeName *typename)
{ {
Oid inputType = exprType(expr); Oid inputType = exprType(expr);
Oid targetType; Oid targetType;
int32 targetTypmod;
targetType = typenameTypeId(pstate, typename); targetType = typenameTypeId(pstate, typename);
targetTypmod = typenameTypeMod(pstate, typename, targetType);
if (inputType == InvalidOid) if (inputType == InvalidOid)
return expr; /* do nothing if NULL input */ return expr; /* do nothing if NULL input */
expr = coerce_to_target_type(pstate, expr, inputType, expr = coerce_to_target_type(pstate, expr, inputType,
targetType, typename->typmod, targetType, targetTypmod,
COERCION_EXPLICIT, COERCION_EXPLICIT,
COERCE_EXPLICIT_CAST); COERCE_EXPLICIT_CAST);
if (expr == NULL) if (expr == NULL)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.125 2006/10/04 00:29:56 momjian Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.126 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -901,9 +901,9 @@ addRangeTableEntryForFunction(ParseState *pstate,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION), (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("column \"%s\" cannot be declared SETOF", errmsg("column \"%s\" cannot be declared SETOF",
attrname))); attrname)));
eref->colnames = lappend(eref->colnames, makeString(attrname));
attrtype = typenameTypeId(pstate, n->typename); attrtype = typenameTypeId(pstate, n->typename);
attrtypmod = n->typename->typmod; attrtypmod = typenameTypeMod(pstate, n->typename, attrtype);
eref->colnames = lappend(eref->colnames, makeString(attrname));
rte->funccoltypes = lappend_oid(rte->funccoltypes, attrtype); rte->funccoltypes = lappend_oid(rte->funccoltypes, attrtype);
rte->funccoltypmods = lappend_int(rte->funccoltypmods, attrtypmod); rte->funccoltypmods = lappend_int(rte->funccoltypmods, attrtypmod);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.85 2006/10/04 00:29:56 momjian Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.86 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -20,6 +20,7 @@
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "parser/parser.h" #include "parser/parser.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
@ -245,9 +246,81 @@ typenameTypeId(ParseState *pstate, const TypeName *typename)
errmsg("type \"%s\" is only a shell", errmsg("type \"%s\" is only a shell",
TypeNameToString(typename)), TypeNameToString(typename)),
parser_errposition(pstate, typename->location))); parser_errposition(pstate, typename->location)));
return typoid; return typoid;
} }
/*
* typenameTypeMod - given a TypeName, return the internal typmod value
*
* This will throw an error if the TypeName includes type modifiers that are
* illegal for the data type.
*
* The actual type OID represented by the TypeName must already have been
* determined (usually by typenameTypeId()), and is passed as typeId.
*
* pstate is only used for error location info, and may be NULL.
*/
int32
typenameTypeMod(ParseState *pstate, const TypeName *typename,
Oid typeId)
{
int32 result;
Oid typmodin;
Datum *datums;
int n;
ListCell *l;
ArrayType *arrtypmod;
Assert(OidIsValid(typeId));
/* Return prespecified typmod if no typmod expressions */
if (typename->typmods == NIL)
return typename->typemod;
/* Else, type had better accept typmods */
typmodin = get_typmodin(typeId);
if (typmodin == InvalidOid)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("type modifier is not allowed for type \"%s\"",
TypeNameToString(typename)),
parser_errposition(pstate, typename->location)));
/*
* Convert the list of (raw grammar output) expressions to an integer
* array. Currently, we only allow simple integer constants, though
* possibly this could be extended.
*/
datums = (Datum *) palloc(list_length(typename->typmods) * sizeof(Datum));
n = 0;
foreach(l, typename->typmods)
{
A_Const *ac = (A_Const *) lfirst(l);
if (!IsA(ac, A_Const) ||
!IsA(&ac->val, Integer))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("type modifiers must be integer constants"),
parser_errposition(pstate, typename->location)));
datums[n++] = Int32GetDatum(ac->val.val.ival);
}
/* hardwired knowledge about int4's representation details here */
arrtypmod = construct_array(datums, n, INT4OID,
sizeof(int4), true, 'i');
result = DatumGetInt32(OidFunctionCall1(typmodin,
PointerGetDatum(arrtypmod)));
pfree(datums);
pfree(arrtypmod);
return result;
}
/* /*
* typenameType - given a TypeName, return a Type structure * typenameType - given a TypeName, return a Type structure
* *
@ -490,7 +563,7 @@ parseTypeString(const char *str, Oid *type_id, int32 *typmod)
goto fail; goto fail;
*type_id = typenameTypeId(NULL, typename); *type_id = typenameTypeId(NULL, typename);
*typmod = typename->typmod; *typmod = typenameTypeMod(NULL, typename, *type_id);
pfree(buf.data); pfree(buf.data);

View File

@ -8,13 +8,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayutils.c,v 1.21 2006/03/05 15:58:41 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/arrayutils.c,v 1.22 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "catalog/pg_type.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/memutils.h" #include "utils/memutils.h"
@ -188,3 +189,30 @@ mda_next_tuple(int n, int *curr, const int *span)
return -1; return -1;
} }
/*
* ArrayGetTypmods: verify that argument is a 1-D integer array,
* return its length and a pointer to the first contained integer.
*/
int32 *
ArrayGetTypmods(ArrayType *arr, int *n)
{
if (ARR_ELEMTYPE(arr) != INT4OID)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
errmsg("typmod array must be type integer[]")));
if (ARR_NDIM(arr) != 1)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("typmod array must be one-dimensional")));
if (ARR_HASNULL(arr))
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("typmod array must not contain nulls")));
*n = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
return (int32 *) ARR_DATA_PTR(arr);
}

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.125 2006/07/14 14:52:23 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.126 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -24,6 +24,7 @@
#include "libpq/pqformat.h" #include "libpq/pqformat.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/scansup.h" #include "parser/scansup.h"
#include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/date.h" #include "utils/date.h"
#include "utils/nabstime.h" #include "utils/nabstime.h"
@ -43,6 +44,60 @@ static int tm2time(struct pg_tm * tm, fsec_t fsec, TimeADT *result);
static int tm2timetz(struct pg_tm * tm, fsec_t fsec, int tz, TimeTzADT *result); static int tm2timetz(struct pg_tm * tm, fsec_t fsec, int tz, TimeTzADT *result);
static void AdjustTimeForTypmod(TimeADT *time, int32 typmod); static void AdjustTimeForTypmod(TimeADT *time, int32 typmod);
/* common code for timetypmodin and timetztypmodin */
static int32
anytime_typmodin(bool istz, ArrayType *ta)
{
int32 typmod;
int32 *tl;
int n;
tl = ArrayGetTypmods(ta, &n);
/*
* we're not too tense about good error message here because grammar
* shouldn't allow wrong number of modifiers for TIME
*/
if (n != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid type modifier")));
if (*tl < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIME(%d)%s precision must not be negative",
*tl, (istz ? " WITH TIME ZONE" : ""))));
if (*tl > MAX_TIME_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIME(%d)%s precision reduced to maximum allowed, %d",
*tl, (istz ? " WITH TIME ZONE" : "" ),
MAX_TIME_PRECISION)));
typmod = MAX_TIME_PRECISION;
} else
typmod = *tl;
return typmod;
}
/* common code for timetypmodout and timetztypmodout */
static char *
anytime_typmodout(bool istz, int32 typmod)
{
char *res = (char *) palloc(64);
const char *tz = istz ? " with time zone" : " without time zone";
if (typmod >= 0)
snprintf(res, 64, "(%d)%s", (int) typmod, tz);
else
snprintf(res, 64, "%s", tz);
return res;
}
/***************************************************************************** /*****************************************************************************
* Date ADT * Date ADT
*****************************************************************************/ *****************************************************************************/
@ -1029,6 +1084,22 @@ time_send(PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
} }
Datum
timetypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anytime_typmodin(false, ta));
}
Datum
timetypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anytime_typmodout(false, typmod));
}
/* time_scale() /* time_scale()
* Adjust time type for specified scale factor. * Adjust time type for specified scale factor.
@ -1830,6 +1901,22 @@ timetz_send(PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
} }
Datum
timetztypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anytime_typmodin(true, ta));
}
Datum
timetztypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anytime_typmodout(true, typmod));
}
/* timetz2tm() /* timetz2tm()
* Convert TIME WITH TIME ZONE data type to POSIX time structure. * Convert TIME WITH TIME ZONE data type to POSIX time structure.

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/format_type.c,v 1.44 2006/07/14 14:52:24 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/format_type.c,v 1.45 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -20,7 +20,6 @@
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/datetime.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/numeric.h" #include "utils/numeric.h"
#include "utils/syscache.h" #include "utils/syscache.h"
@ -31,6 +30,7 @@
static char *format_type_internal(Oid type_oid, int32 typemod, static char *format_type_internal(Oid type_oid, int32 typemod,
bool typemod_given, bool allow_invalid); bool typemod_given, bool allow_invalid);
static char *printTypmod(const char *typname, int32 typmod, Oid typmodout);
static char * static char *
psnprintf(size_t len, const char *fmt,...) psnprintf(size_t len, const char *fmt,...)
/* This lets gcc check the format string for consistency. */ /* This lets gcc check the format string for consistency. */
@ -186,8 +186,7 @@ format_type_internal(Oid type_oid, int32 typemod,
{ {
case BITOID: case BITOID:
if (with_typemod) if (with_typemod)
buf = psnprintf(5 + MAX_INT32_LEN + 1, "bit(%d)", buf = printTypmod("bit", typemod, typeform->typmodout);
(int) typemod);
else if (typemod_given) else if (typemod_given)
{ {
/* /*
@ -206,8 +205,7 @@ format_type_internal(Oid type_oid, int32 typemod,
case BPCHAROID: case BPCHAROID:
if (with_typemod) if (with_typemod)
buf = psnprintf(11 + MAX_INT32_LEN + 1, "character(%d)", buf = printTypmod("character", typemod, typeform->typmodout);
(int) (typemod - VARHDRSZ));
else if (typemod_given) else if (typemod_given)
{ {
/* /*
@ -242,136 +240,56 @@ format_type_internal(Oid type_oid, int32 typemod,
case NUMERICOID: case NUMERICOID:
if (with_typemod) if (with_typemod)
buf = psnprintf(10 + 2 * MAX_INT32_LEN + 1, "numeric(%d,%d)", buf = printTypmod("numeric", typemod, typeform->typmodout);
((typemod - VARHDRSZ) >> 16) & 0xffff,
(typemod - VARHDRSZ) & 0xffff);
else else
buf = pstrdup("numeric"); buf = pstrdup("numeric");
break; break;
case INTERVALOID: case INTERVALOID:
if (with_typemod) if (with_typemod)
{ buf = printTypmod("interval", typemod, typeform->typmodout);
int fields = INTERVAL_RANGE(typemod);
int precision = INTERVAL_PRECISION(typemod);
const char *fieldstr;
switch (fields)
{
case INTERVAL_MASK(YEAR):
fieldstr = " year";
break;
case INTERVAL_MASK(MONTH):
fieldstr = " month";
break;
case INTERVAL_MASK(DAY):
fieldstr = " day";
break;
case INTERVAL_MASK(HOUR):
fieldstr = " hour";
break;
case INTERVAL_MASK(MINUTE):
fieldstr = " minute";
break;
case INTERVAL_MASK(SECOND):
fieldstr = " second";
break;
case INTERVAL_MASK(YEAR)
| INTERVAL_MASK(MONTH):
fieldstr = " year to month";
break;
case INTERVAL_MASK(DAY)
| INTERVAL_MASK(HOUR):
fieldstr = " day to hour";
break;
case INTERVAL_MASK(DAY)
| INTERVAL_MASK(HOUR)
| INTERVAL_MASK(MINUTE):
fieldstr = " day to minute";
break;
case INTERVAL_MASK(DAY)
| INTERVAL_MASK(HOUR)
| INTERVAL_MASK(MINUTE)
| INTERVAL_MASK(SECOND):
fieldstr = " day to second";
break;
case INTERVAL_MASK(HOUR)
| INTERVAL_MASK(MINUTE):
fieldstr = " hour to minute";
break;
case INTERVAL_MASK(HOUR)
| INTERVAL_MASK(MINUTE)
| INTERVAL_MASK(SECOND):
fieldstr = " hour to second";
break;
case INTERVAL_MASK(MINUTE)
| INTERVAL_MASK(SECOND):
fieldstr = " minute to second";
break;
case INTERVAL_FULL_RANGE:
fieldstr = "";
break;
default:
elog(ERROR, "invalid INTERVAL typmod: 0x%x", typemod);
fieldstr = "";
break;
}
if (precision != INTERVAL_FULL_PRECISION)
buf = psnprintf(100, "interval(%d)%s",
precision, fieldstr);
else
buf = psnprintf(100, "interval%s",
fieldstr);
}
else else
buf = pstrdup("interval"); buf = pstrdup("interval");
break; break;
case TIMEOID: case TIMEOID:
if (with_typemod) if (with_typemod)
buf = psnprintf(50, "time(%d) without time zone", buf = printTypmod("time", typemod, typeform->typmodout);
typemod);
else else
buf = pstrdup("time without time zone"); buf = pstrdup("time without time zone");
break; break;
case TIMETZOID: case TIMETZOID:
if (with_typemod) if (with_typemod)
buf = psnprintf(50, "time(%d) with time zone", buf = printTypmod("time", typemod, typeform->typmodout);
typemod);
else else
buf = pstrdup("time with time zone"); buf = pstrdup("time with time zone");
break; break;
case TIMESTAMPOID: case TIMESTAMPOID:
if (with_typemod) if (with_typemod)
buf = psnprintf(50, "timestamp(%d) without time zone", buf = printTypmod("timestamp", typemod, typeform->typmodout);
typemod);
else else
buf = pstrdup("timestamp without time zone"); buf = pstrdup("timestamp without time zone");
break; break;
case TIMESTAMPTZOID: case TIMESTAMPTZOID:
if (with_typemod) if (with_typemod)
buf = psnprintf(50, "timestamp(%d) with time zone", buf = printTypmod("timestamp", typemod, typeform->typmodout);
typemod);
else else
buf = pstrdup("timestamp with time zone"); buf = pstrdup("timestamp with time zone");
break; break;
case VARBITOID: case VARBITOID:
if (with_typemod) if (with_typemod)
buf = psnprintf(13 + MAX_INT32_LEN + 1, "bit varying(%d)", buf = printTypmod("bit varying", typemod, typeform->typmodout);
(int) typemod);
else else
buf = pstrdup("bit varying"); buf = pstrdup("bit varying");
break; break;
case VARCHAROID: case VARCHAROID:
if (with_typemod) if (with_typemod)
buf = psnprintf(19 + MAX_INT32_LEN + 1, buf = printTypmod("character varying", typemod, typeform->typmodout);
"character varying(%d)",
(int) (typemod - VARHDRSZ));
else else
buf = pstrdup("character varying"); buf = pstrdup("character varying");
break; break;
@ -396,6 +314,9 @@ format_type_internal(Oid type_oid, int32 typemod,
typname = NameStr(typeform->typname); typname = NameStr(typeform->typname);
buf = quote_qualified_identifier(nspname, typname); buf = quote_qualified_identifier(nspname, typname);
if (with_typemod)
buf = printTypmod(buf, typemod, typeform->typmodout);
} }
if (is_array) if (is_array)
@ -407,6 +328,38 @@ format_type_internal(Oid type_oid, int32 typemod,
} }
/*
* Add typmod decoration to the basic type name
*/
static char *
printTypmod(const char *typname, int32 typmod, Oid typmodout)
{
char *res;
/* Shouldn't be called if typmod is -1 */
Assert(typmod >= 0);
if (typmodout == InvalidOid)
{
/* Default behavior: just print the integer typmod with parens */
res = psnprintf(strlen(typname) + MAX_INT32_LEN + 3, "%s(%d)",
typname, (int) typmod);
}
else
{
/* Use the type-specific typmodout procedure */
char *tmstr;
tmstr = DatumGetCString(OidFunctionCall1(typmodout,
Int32GetDatum(typmod)));
res = psnprintf(strlen(typname) + strlen(tmstr) + 1, "%s%s",
typname, tmstr);
}
return res;
}
/* /*
* type_maximum_size --- determine maximum width of a variable-width column * type_maximum_size --- determine maximum width of a variable-width column
* *
@ -417,7 +370,9 @@ format_type_internal(Oid type_oid, int32 typemod,
* *
* This may appear unrelated to format_type(), but in fact the two routines * This may appear unrelated to format_type(), but in fact the two routines
* share knowledge of the encoding of typmod for different types, so it's * share knowledge of the encoding of typmod for different types, so it's
* convenient to keep them together. * convenient to keep them together. (XXX now that most of this knowledge
* has been pushed out of format_type into the typmodout functions, it's
* interesting to wonder if it's worth trying to factor this code too...)
*/ */
int32 int32
type_maximum_size(Oid type_oid, int32 typemod) type_maximum_size(Oid type_oid, int32 typemod)

View File

@ -14,7 +14,7 @@
* Copyright (c) 1998-2006, PostgreSQL Global Development Group * Copyright (c) 1998-2006, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.96 2006/10/04 00:29:59 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.97 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -470,7 +470,7 @@ numeric_send(PG_FUNCTION_ARGS)
* scale of the attribute have to be applied on the value. * scale of the attribute have to be applied on the value.
*/ */
Datum Datum
numeric (PG_FUNCTION_ARGS) numeric(PG_FUNCTION_ARGS)
{ {
Numeric num = PG_GETARG_NUMERIC(0); Numeric num = PG_GETARG_NUMERIC(0);
int32 typmod = PG_GETARG_INT32(1); int32 typmod = PG_GETARG_INT32(1);
@ -537,6 +537,67 @@ numeric (PG_FUNCTION_ARGS)
PG_RETURN_NUMERIC(new); PG_RETURN_NUMERIC(new);
} }
Datum
numerictypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
int32 *tl;
int n;
int32 typmod;
tl = ArrayGetTypmods(ta, &n);
if (n == 2)
{
if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("NUMERIC precision %d must be between 1 and %d",
tl[0], NUMERIC_MAX_PRECISION)));
if (tl[1] < 0 || tl[1] > tl[0])
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("NUMERIC scale %d must be between 0 and precision %d",
tl[1], tl[0])));
typmod = ((tl[0] << 16) | tl[1]) + VARHDRSZ;
}
else if (n == 1)
{
if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("NUMERIC precision %d must be between 1 and %d",
tl[0], NUMERIC_MAX_PRECISION)));
/* scale defaults to zero */
typmod = (tl[0] << 16) + VARHDRSZ;
}
else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid NUMERIC type modifier")));
typmod = 0; /* keep compiler quiet */
}
PG_RETURN_INT32(typmod);
}
Datum
numerictypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
char *res = (char *) palloc(64);
if (typmod >= 0)
snprintf(res, 64, "(%d,%d)",
((typmod - VARHDRSZ) >> 16) & 0xffff,
(typmod - VARHDRSZ) & 0xffff);
else
*res = '\0';
PG_RETURN_CSTRING(res);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
* *

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.169 2006/11/11 01:14:19 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.170 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -56,6 +56,60 @@ static void AdjustIntervalForTypmod(Interval *interval, int32 typmod);
static TimestampTz timestamp2timestamptz(Timestamp timestamp); static TimestampTz timestamp2timestamptz(Timestamp timestamp);
/* common code for timestamptypmodin and timestamptztypmodin */
static int32
anytimestamp_typmodin(bool istz, ArrayType *ta)
{
int32 typmod;
int32 *tl;
int n;
tl = ArrayGetTypmods(ta, &n);
/*
* we're not too tense about good error message here because grammar
* shouldn't allow wrong number of modifiers for TIMESTAMP
*/
if (n != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid type modifier")));
if (*tl < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIMESTAMP(%d)%s precision must not be negative",
*tl, (istz ? " WITH TIME ZONE" : ""))));
if (*tl > MAX_TIMESTAMP_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
*tl, (istz ? " WITH TIME ZONE" : ""),
MAX_TIMESTAMP_PRECISION)));
typmod = MAX_TIMESTAMP_PRECISION;
} else
typmod = *tl;
return typmod;
}
/* common code for timestamptypmodout and timestamptztypmodout */
static char *
anytimestamp_typmodout(bool istz, int32 typmod)
{
char *res = (char *) palloc(64);
const char *tz = istz ? " with time zone" : " without time zone";
if (typmod >= 0)
snprintf(res, 64, "(%d)%s", (int) typmod, tz);
else
snprintf(res, 64, "%s", tz);
return res;
}
/***************************************************************************** /*****************************************************************************
* USER I/O ROUTINES * * USER I/O ROUTINES *
*****************************************************************************/ *****************************************************************************/
@ -215,6 +269,22 @@ timestamp_send(PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
} }
Datum
timestamptypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anytimestamp_typmodin(false, ta));
}
Datum
timestamptypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anytimestamp_typmodout(false, typmod));
}
/* timestamp_scale() /* timestamp_scale()
* Adjust time type for specified scale factor. * Adjust time type for specified scale factor.
@ -461,6 +531,22 @@ timestamptz_send(PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
} }
Datum
timestamptztypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anytimestamp_typmodin(true, ta));
}
Datum
timestamptztypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anytimestamp_typmodout(true, typmod));
}
/* timestamptz_scale() /* timestamptz_scale()
* Adjust time type for specified scale factor. * Adjust time type for specified scale factor.
@ -625,6 +711,162 @@ interval_send(PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
} }
Datum
intervaltypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
int32 *tl;
int n;
int32 typmod;
tl = ArrayGetTypmods(ta, &n);
/*
* tl[0] - opt_interval
* tl[1] - Iconst (optional)
*
* Note we must validate tl[0] even though it's normally guaranteed
* correct by the grammar --- consider SELECT 'foo'::"interval"(1000).
*/
if (n > 0)
{
switch (tl[0])
{
case INTERVAL_MASK(YEAR):
case INTERVAL_MASK(MONTH):
case INTERVAL_MASK(DAY):
case INTERVAL_MASK(HOUR):
case INTERVAL_MASK(MINUTE):
case INTERVAL_MASK(SECOND):
case INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH):
case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR):
case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
case INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
case INTERVAL_FULL_RANGE:
/* all OK */
break;
default:
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid INTERVAL type modifier")));
}
}
if (n == 1)
{
if (tl[0] != INTERVAL_FULL_RANGE)
typmod = INTERVAL_TYPMOD(INTERVAL_FULL_PRECISION, tl[0]);
else
typmod = -1;
}
else if (n == 2)
{
if (tl[1] < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("INTERVAL(%d) precision must not be negative",
tl[1])));
if (tl[1] > MAX_INTERVAL_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",
tl[1], MAX_INTERVAL_PRECISION)));
typmod = INTERVAL_TYPMOD(MAX_INTERVAL_PRECISION, tl[0]);
}
else
typmod = INTERVAL_TYPMOD(tl[1], tl[0]);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid INTERVAL type modifier")));
typmod = 0; /* keep compiler quiet */
}
PG_RETURN_INT32(typmod);
}
Datum
intervaltypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
char *res = (char *) palloc(64);
int fields;
int precision;
const char *fieldstr;
if (typmod < 0)
{
*res = '\0';
PG_RETURN_CSTRING(res);
}
fields = INTERVAL_RANGE(typmod);
precision = INTERVAL_PRECISION(typmod);
switch (fields)
{
case INTERVAL_MASK(YEAR):
fieldstr = " year";
break;
case INTERVAL_MASK(MONTH):
fieldstr = " month";
break;
case INTERVAL_MASK(DAY):
fieldstr = " day";
break;
case INTERVAL_MASK(HOUR):
fieldstr = " hour";
break;
case INTERVAL_MASK(MINUTE):
fieldstr = " minute";
break;
case INTERVAL_MASK(SECOND):
fieldstr = " second";
break;
case INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH):
fieldstr = " year to month";
break;
case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR):
fieldstr = " day to hour";
break;
case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
fieldstr = " day to minute";
break;
case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
fieldstr = " day to second";
break;
case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
fieldstr = " hour to minute";
break;
case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
fieldstr = " hour to second";
break;
case INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
fieldstr = " minute to second";
break;
case INTERVAL_FULL_RANGE:
fieldstr = "";
break;
default:
elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
fieldstr = "";
break;
}
if (precision != INTERVAL_FULL_PRECISION)
snprintf(res, 64, "(%d)%s", precision, fieldstr);
else
snprintf(res, 64, "%s", fieldstr);
PG_RETURN_CSTRING(res);
}
/* interval_scale() /* interval_scale()
* Adjust interval type for specified fields. * Adjust interval type for specified fields.

View File

@ -9,19 +9,71 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.50 2006/07/14 14:52:24 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.51 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "access/htup.h"
#include "libpq/pqformat.h" #include "libpq/pqformat.h"
#include "utils/array.h"
#include "utils/varbit.h" #include "utils/varbit.h"
#define HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A')) #define HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
/* common code for bittypmodin and varbittypmodin */
static int32
anybit_typmodin(ArrayType *ta, const char *typename)
{
int32 typmod;
int32 *tl;
int n;
tl = ArrayGetTypmods(ta, &n);
/*
* we're not too tense about good error message here because grammar
* shouldn't allow wrong number of modifiers for BIT
*/
if (n != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid type modifier")));
if (*tl < 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("length for type %s must be at least 1",
typename)));
if (*tl > (MaxAttrSize * BITS_PER_BYTE))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("length for type %s cannot exceed %d",
typename, MaxAttrSize * BITS_PER_BYTE)));
typmod = *tl;
return typmod;
}
/* common code for bittypmodout and varbittypmodout */
static char *
anybit_typmodout(int32 typmod)
{
char *res = (char *) palloc(64);
if (typmod >= 0)
snprintf(res, 64, "(%d)", typmod);
else
*res = '\0';
return res;
}
/*---------- /*----------
* attypmod -- contains the length of the bit string in bits, or for * attypmod -- contains the length of the bit string in bits, or for
* varying bits the maximum length. * varying bits the maximum length.
@ -325,6 +377,23 @@ bit(PG_FUNCTION_ARGS)
PG_RETURN_VARBIT_P(result); PG_RETURN_VARBIT_P(result);
} }
Datum
bittypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anybit_typmodin(ta, "bit"));
}
Datum
bittypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anybit_typmodout(typmod));
}
/* /*
* varbit_in - * varbit_in -
* converts a string to the internal representation of a bitstring. * converts a string to the internal representation of a bitstring.
@ -603,6 +672,22 @@ varbit(PG_FUNCTION_ARGS)
PG_RETURN_VARBIT_P(result); PG_RETURN_VARBIT_P(result);
} }
Datum
varbittypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anybit_typmodin(ta, "varbit"));
}
Datum
varbittypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anybit_typmodout(typmod));
}
/* /*
* Comparison operators * Comparison operators

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.119 2006/10/04 00:30:00 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.120 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -17,10 +17,65 @@
#include "access/hash.h" #include "access/hash.h"
#include "libpq/pqformat.h" #include "libpq/pqformat.h"
#include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "mb/pg_wchar.h" #include "mb/pg_wchar.h"
/* common code for bpchartypmodin and varchartypmodin */
static int32
anychar_typmodin(ArrayType *ta, const char *typename)
{
int32 typmod;
int32 *tl;
int n;
tl = ArrayGetTypmods(ta, &n);
/*
* we're not too tense about good error message here because grammar
* shouldn't allow wrong number of modifiers for CHAR
*/
if (n != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid type modifier")));
if (*tl < 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("length for type %s must be at least 1", typename)));
if (*tl > MaxAttrSize)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("length for type %s cannot exceed %d",
typename, MaxAttrSize)));
/*
* For largely historical reasons, the typmod is VARHDRSZ plus the
* number of characters; there is enough client-side code that knows
* about that that we'd better not change it.
*/
typmod = VARHDRSZ + *tl;
return typmod;
}
/* common code for bpchartypmodout and varchartypmodout */
static char *
anychar_typmodout(int32 typmod)
{
char *res = (char *) palloc(64);
if (typmod > VARHDRSZ)
snprintf(res, 64, "(%d)", (int) (typmod - VARHDRSZ));
else
*res = '\0';
return res;
}
/* /*
* CHAR() and VARCHAR() types are part of the ANSI SQL standard. CHAR() * CHAR() and VARCHAR() types are part of the ANSI SQL standard. CHAR()
* is for blank-padded string whose length is specified in CREATE TABLE. * is for blank-padded string whose length is specified in CREATE TABLE.
@ -359,6 +414,22 @@ name_bpchar(PG_FUNCTION_ARGS)
PG_RETURN_BPCHAR_P(result); PG_RETURN_BPCHAR_P(result);
} }
Datum
bpchartypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anychar_typmodin(ta, "char"));
}
Datum
bpchartypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anychar_typmodout(typmod));
}
/***************************************************************************** /*****************************************************************************
* varchar - varchar(n) * varchar - varchar(n)
@ -536,6 +607,22 @@ varchar(PG_FUNCTION_ARGS)
PG_RETURN_VARCHAR_P(result); PG_RETURN_VARCHAR_P(result);
} }
Datum
varchartypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anychar_typmodin(ta, "varchar"));
}
Datum
varchartypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anychar_typmodout(typmod));
}
/***************************************************************************** /*****************************************************************************
* Exported functions * Exported functions

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.139 2006/12/23 00:43:11 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.140 2006/12/30 21:21:54 tgl Exp $
* *
* NOTES * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
@ -2016,6 +2016,60 @@ getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
ReleaseSysCache(typeTuple); ReleaseSysCache(typeTuple);
} }
/*
* get_typmodin
*
* Given the type OID, return the type's typmodin procedure, if any.
*/
Oid
get_typmodin(Oid typid)
{
HeapTuple tp;
tp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid),
0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
Oid result;
result = typtup->typmodin;
ReleaseSysCache(tp);
return result;
}
else
return InvalidOid;
}
#ifdef NOT_USED
/*
* get_typmodout
*
* Given the type OID, return the type's typmodout procedure, if any.
*/
Oid
get_typmodout(Oid typid)
{
HeapTuple tp;
tp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid),
0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
Oid result;
result = typtup->typmodout;
ReleaseSysCache(tp);
return result;
}
else
return InvalidOid;
}
#endif /* NOT_USED */
/* ---------- STATISTICS CACHE ---------- */ /* ---------- STATISTICS CACHE ---------- */

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.363 2006/12/23 00:52:40 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.364 2006/12/30 21:21:54 tgl Exp $
* *
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
@ -45,6 +45,7 @@
#include "parser/gramparse.h" #include "parser/gramparse.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_relation.h" #include "parser/parse_relation.h"
#include "parser/parse_type.h"
#include "parser/scansup.h" #include "parser/scansup.h"
#include "pgstat.h" #include "pgstat.h"
#include "postmaster/autovacuum.h" #include "postmaster/autovacuum.h"
@ -4523,14 +4524,17 @@ flatten_set_variable_args(const char *name, List *args)
* to interval and back to normalize the value and account * to interval and back to normalize the value and account
* for any typmod. * for any typmod.
*/ */
int32 typmod;
Datum interval; Datum interval;
char *intervalout; char *intervalout;
typmod = typenameTypeMod(NULL, arg->typename, INTERVALOID);
interval = interval =
DirectFunctionCall3(interval_in, DirectFunctionCall3(interval_in,
CStringGetDatum(val), CStringGetDatum(val),
ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(InvalidOid),
Int32GetDatum(arg->typename->typmod)); Int32GetDatum(typmod));
intervalout = intervalout =
DatumGetCString(DirectFunctionCall1(interval_out, DatumGetCString(DirectFunctionCall1(interval_out,

View File

@ -12,7 +12,7 @@
* by PostgreSQL * by PostgreSQL
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.454 2006/12/23 00:43:12 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.455 2006/12/30 21:21:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -5007,11 +5007,15 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
char *typoutput; char *typoutput;
char *typreceive; char *typreceive;
char *typsend; char *typsend;
char *typmodin;
char *typmodout;
char *typanalyze; char *typanalyze;
Oid typinputoid; Oid typinputoid;
Oid typoutputoid; Oid typoutputoid;
Oid typreceiveoid; Oid typreceiveoid;
Oid typsendoid; Oid typsendoid;
Oid typmodinoid;
Oid typmodoutoid;
Oid typanalyzeoid; Oid typanalyzeoid;
char *typdelim; char *typdelim;
char *typbyval; char *typbyval;
@ -5024,15 +5028,35 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
selectSourceSchema(tinfo->dobj.namespace->dobj.name); selectSourceSchema(tinfo->dobj.namespace->dobj.name);
/* Fetch type-specific details */ /* Fetch type-specific details */
if (fout->remoteVersion >= 80000) if (fout->remoteVersion >= 80300)
{ {
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, typreceive, typsend, " "typinput, typoutput, typreceive, typsend, "
"typmodin, typmodout, typanalyze, "
"typinput::pg_catalog.oid as typinputoid, "
"typoutput::pg_catalog.oid as typoutputoid, "
"typreceive::pg_catalog.oid as typreceiveoid, "
"typsend::pg_catalog.oid as typsendoid, "
"typmodin::pg_catalog.oid as typmodinoid, "
"typmodout::pg_catalog.oid as typmodoutoid, "
"typanalyze::pg_catalog.oid as typanalyzeoid, "
"typdelim, typbyval, typalign, typstorage, "
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
"FROM pg_catalog.pg_type "
"WHERE oid = '%u'::pg_catalog.oid",
tinfo->dobj.catId.oid);
}
else if (fout->remoteVersion >= 80000)
{
appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, typreceive, typsend, "
"'-' as typmodin, '-' as typmodout, "
"typanalyze, " "typanalyze, "
"typinput::pg_catalog.oid as typinputoid, " "typinput::pg_catalog.oid as typinputoid, "
"typoutput::pg_catalog.oid as typoutputoid, " "typoutput::pg_catalog.oid as typoutputoid, "
"typreceive::pg_catalog.oid as typreceiveoid, " "typreceive::pg_catalog.oid as typreceiveoid, "
"typsend::pg_catalog.oid as typsendoid, " "typsend::pg_catalog.oid as typsendoid, "
"0 as typmodinoid, 0 as typmodoutoid, "
"typanalyze::pg_catalog.oid as typanalyzeoid, " "typanalyze::pg_catalog.oid as typanalyzeoid, "
"typdelim, typbyval, typalign, typstorage, " "typdelim, typbyval, typalign, typstorage, "
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault " "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
@ -5044,11 +5068,13 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
{ {
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, typreceive, typsend, " "typinput, typoutput, typreceive, typsend, "
"'-' as typmodin, '-' as typmodout, "
"'-' as typanalyze, " "'-' as typanalyze, "
"typinput::pg_catalog.oid as typinputoid, " "typinput::pg_catalog.oid as typinputoid, "
"typoutput::pg_catalog.oid as typoutputoid, " "typoutput::pg_catalog.oid as typoutputoid, "
"typreceive::pg_catalog.oid as typreceiveoid, " "typreceive::pg_catalog.oid as typreceiveoid, "
"typsend::pg_catalog.oid as typsendoid, " "typsend::pg_catalog.oid as typsendoid, "
"0 as typmodinoid, 0 as typmodoutoid, "
"0 as typanalyzeoid, " "0 as typanalyzeoid, "
"typdelim, typbyval, typalign, typstorage, " "typdelim, typbyval, typalign, typstorage, "
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault " "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
@ -5061,10 +5087,12 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, " "typinput, typoutput, "
"'-' as typreceive, '-' as typsend, " "'-' as typreceive, '-' as typsend, "
"'-' as typmodin, '-' as typmodout, "
"'-' as typanalyze, " "'-' as typanalyze, "
"typinput::pg_catalog.oid as typinputoid, " "typinput::pg_catalog.oid as typinputoid, "
"typoutput::pg_catalog.oid as typoutputoid, " "typoutput::pg_catalog.oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, " "0 as typreceiveoid, 0 as typsendoid, "
"0 as typmodinoid, 0 as typmodoutoid, "
"0 as typanalyzeoid, " "0 as typanalyzeoid, "
"typdelim, typbyval, typalign, typstorage, " "typdelim, typbyval, typalign, typstorage, "
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault " "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
@ -5081,10 +5109,12 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, " "typinput, typoutput, "
"'-' as typreceive, '-' as typsend, " "'-' as typreceive, '-' as typsend, "
"'-' as typmodin, '-' as typmodout, "
"'-' as typanalyze, " "'-' as typanalyze, "
"typinput::oid as typinputoid, " "typinput::oid as typinputoid, "
"typoutput::oid as typoutputoid, " "typoutput::oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, " "0 as typreceiveoid, 0 as typsendoid, "
"0 as typmodinoid, 0 as typmodoutoid, "
"0 as typanalyzeoid, " "0 as typanalyzeoid, "
"typdelim, typbyval, typalign, typstorage, " "typdelim, typbyval, typalign, typstorage, "
"NULL as typdefaultbin, typdefault " "NULL as typdefaultbin, typdefault "
@ -5101,10 +5131,12 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, " "typinput, typoutput, "
"'-' as typreceive, '-' as typsend, " "'-' as typreceive, '-' as typsend, "
"'-' as typmodin, '-' as typmodout, "
"'-' as typanalyze, " "'-' as typanalyze, "
"typinput::oid as typinputoid, " "typinput::oid as typinputoid, "
"typoutput::oid as typoutputoid, " "typoutput::oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, " "0 as typreceiveoid, 0 as typsendoid, "
"0 as typmodinoid, 0 as typmodoutoid, "
"0 as typanalyzeoid, " "0 as typanalyzeoid, "
"typdelim, typbyval, typalign, typstorage, " "typdelim, typbyval, typalign, typstorage, "
"NULL as typdefaultbin, NULL as typdefault " "NULL as typdefaultbin, NULL as typdefault "
@ -5117,10 +5149,12 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
appendPQExpBuffer(query, "SELECT typlen, " appendPQExpBuffer(query, "SELECT typlen, "
"typinput, typoutput, " "typinput, typoutput, "
"'-' as typreceive, '-' as typsend, " "'-' as typreceive, '-' as typsend, "
"'-' as typmodin, '-' as typmodout, "
"'-' as typanalyze, " "'-' as typanalyze, "
"typinput::oid as typinputoid, " "typinput::oid as typinputoid, "
"typoutput::oid as typoutputoid, " "typoutput::oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, " "0 as typreceiveoid, 0 as typsendoid, "
"0 as typmodinoid, 0 as typmodoutoid, "
"0 as typanalyzeoid, " "0 as typanalyzeoid, "
"typdelim, typbyval, typalign, " "typdelim, typbyval, typalign, "
"'p'::char as typstorage, " "'p'::char as typstorage, "
@ -5147,11 +5181,15 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput")); typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive")); typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend")); typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze")); typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
typinputoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typinputoid"))); typinputoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typinputoid")));
typoutputoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typoutputoid"))); typoutputoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typoutputoid")));
typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid"))); typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid"))); typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid"))); typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim")); typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval")); typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
@ -5193,6 +5231,10 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive); appendPQExpBuffer(q, ",\n RECEIVE = %s", typreceive);
if (OidIsValid(typsendoid)) if (OidIsValid(typsendoid))
appendPQExpBuffer(q, ",\n SEND = %s", typsend); appendPQExpBuffer(q, ",\n SEND = %s", typsend);
if (OidIsValid(typmodinoid))
appendPQExpBuffer(q, ",\n TYPMOD_IN = %s", typmodin);
if (OidIsValid(typmodoutoid))
appendPQExpBuffer(q, ",\n TYPMOD_OUT = %s", typmodout);
if (OidIsValid(typanalyzeoid)) if (OidIsValid(typanalyzeoid))
appendPQExpBuffer(q, ",\n ANALYZE = %s", typanalyze); appendPQExpBuffer(q, ",\n ANALYZE = %s", typanalyze);
} }
@ -5202,7 +5244,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
/* cannot combine these because fmtId uses static result area */ /* cannot combine these because fmtId uses static result area */
appendPQExpBuffer(q, ",\n INPUT = %s", fmtId(typinput)); appendPQExpBuffer(q, ",\n INPUT = %s", fmtId(typinput));
appendPQExpBuffer(q, ",\n OUTPUT = %s", fmtId(typoutput)); appendPQExpBuffer(q, ",\n OUTPUT = %s", fmtId(typoutput));
/* no chance that receive/send/analyze need be printed */ /* receive/send/typmodin/typmodout/analyze need not be printed */
} }
if (typdefault != NULL) if (typdefault != NULL)

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.367 2006/12/28 14:28:36 petere Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.368 2006/12/30 21:21:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200612281 #define CATALOG_VERSION_NO 200612291
#endif #endif

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.126 2006/11/05 22:42:10 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.127 2006/12/30 21:21:55 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -236,15 +236,17 @@ typedef FormData_pg_attribute *Form_pg_attribute;
{ 1247, {"typoutput"}, 24, -1, 4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typoutput"}, 24, -1, 4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typreceive"}, 24, -1, 4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typreceive"}, 24, -1, 4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typsend"}, 24, -1, 4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typsend"}, 24, -1, 4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typanalyze"}, 24, -1, 4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typmodin"}, 24, -1, 4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typalign"}, 18, -1, 1, 16, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ { 1247, {"typmodout"}, 24, -1, 4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typstorage"}, 18, -1, 1, 17, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ { 1247, {"typanalyze"}, 24, -1, 4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typnotnull"}, 16, -1, 1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ { 1247, {"typalign"}, 18, -1, 1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1247, {"typbasetype"}, 26, -1, 4, 19, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typstorage"}, 18, -1, 1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1247, {"typtypmod"}, 23, -1, 4, 20, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typnotnull"}, 16, -1, 1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1247, {"typndims"}, 23, -1, 4, 21, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typbasetype"}, 26, -1, 4, 21, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typdefaultbin"}, 25, -1, -1, 22, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \ { 1247, {"typtypmod"}, 23, -1, 4, 22, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typdefault"}, 25, -1, -1, 23, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 } { 1247, {"typndims"}, 23, -1, 4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typdefaultbin"}, 25, -1, -1, 24, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1247, {"typdefault"}, 25, -1, -1, 25, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0)); DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0));
DATA(insert ( 1247 typnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
@ -260,15 +262,17 @@ DATA(insert ( 1247 typinput 24 -1 4 11 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typoutput 24 -1 4 12 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typoutput 24 -1 4 12 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typreceive 24 -1 4 13 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typreceive 24 -1 4 13 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typsend 24 -1 4 14 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typsend 24 -1 4 14 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typanalyze 24 -1 4 15 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typmodin 24 -1 4 15 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typalign 18 -1 1 16 0 -1 -1 t p c t f f t 0)); DATA(insert ( 1247 typmodout 24 -1 4 16 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typstorage 18 -1 1 17 0 -1 -1 t p c t f f t 0)); DATA(insert ( 1247 typanalyze 24 -1 4 17 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typnotnull 16 -1 1 18 0 -1 -1 t p c t f f t 0)); DATA(insert ( 1247 typalign 18 -1 1 18 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1247 typbasetype 26 -1 4 19 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typstorage 18 -1 1 19 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1247 typtypmod 23 -1 4 20 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typnotnull 16 -1 1 20 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1247 typndims 23 -1 4 21 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typbasetype 26 -1 4 21 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typdefaultbin 25 -1 -1 22 0 -1 -1 f x i f f f t 0)); DATA(insert ( 1247 typtypmod 23 -1 4 22 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typdefault 25 -1 -1 23 0 -1 -1 f x i f f f t 0)); DATA(insert ( 1247 typndims 23 -1 4 23 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typdefaultbin 25 -1 -1 24 0 -1 -1 f x i f f f t 0));
DATA(insert ( 1247 typdefault 25 -1 -1 25 0 -1 -1 f x i f f f t 0));
DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p s t f f t 0)); DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p s t f f t 0));
DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p i t f f t 0));

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.97 2006/11/05 22:42:10 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.98 2006/12/30 21:21:55 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -132,7 +132,7 @@ typedef FormData_pg_class *Form_pg_class;
*/ */
/* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */ /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */
DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 23 0 0 0 0 0 t f f f 3 _null_ _null_ )); DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 25 0 0 0 0 0 t f f f 3 _null_ _null_ ));
DESCR(""); DESCR("");
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f 3 _null_ _null_ )); DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f 3 _null_ _null_ ));
DESCR(""); DESCR("");

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.433 2006/12/28 14:28:36 petere Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.434 2006/12/30 21:21:55 tgl Exp $
* *
* NOTES * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * The script catalog/genbki.sh reads this file and generates .bki
@ -1335,10 +1335,18 @@ DATA(insert OID = 1044 ( bpcharin PGNSP PGUID 12 f f t f i 3 1042 "2275 26
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1045 ( bpcharout PGNSP PGUID 12 f f t f i 1 2275 "1042" _null_ _null_ _null_ bpcharout - _null_ )); DATA(insert OID = 1045 ( bpcharout PGNSP PGUID 12 f f t f i 1 2275 "1042" _null_ _null_ _null_ bpcharout - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2913 ( bpchartypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ bpchartypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2914 ( bpchartypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ bpchartypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1046 ( varcharin PGNSP PGUID 12 f f t f i 3 1043 "2275 26 23" _null_ _null_ _null_ varcharin - _null_ )); DATA(insert OID = 1046 ( varcharin PGNSP PGUID 12 f f t f i 3 1043 "2275 26 23" _null_ _null_ _null_ varcharin - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1047 ( varcharout PGNSP PGUID 12 f f t f i 1 2275 "1043" _null_ _null_ _null_ varcharout - _null_ )); DATA(insert OID = 1047 ( varcharout PGNSP PGUID 12 f f t f i 1 2275 "1043" _null_ _null_ _null_ varcharout - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2915 ( varchartypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ varchartypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2916 ( varchartypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ varchartypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1048 ( bpchareq PGNSP PGUID 12 f f t f i 2 16 "1042 1042" _null_ _null_ _null_ bpchareq - _null_ )); DATA(insert OID = 1048 ( bpchareq PGNSP PGUID 12 f f t f i 2 16 "1042 1042" _null_ _null_ _null_ bpchareq - _null_ ));
DESCR("equal"); DESCR("equal");
DATA(insert OID = 1049 ( bpcharlt PGNSP PGUID 12 f f t f i 2 16 "1042 1042" _null_ _null_ _null_ bpcharlt - _null_ )); DATA(insert OID = 1049 ( bpcharlt PGNSP PGUID 12 f f t f i 2 16 "1042 1042" _null_ _null_ _null_ bpcharlt - _null_ ));
@ -1408,6 +1416,10 @@ DATA(insert OID = 1143 ( time_in PGNSP PGUID 12 f f t f s 3 1083 "2275 26 2
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1144 ( time_out PGNSP PGUID 12 f f t f i 1 2275 "1083" _null_ _null_ _null_ time_out - _null_ )); DATA(insert OID = 1144 ( time_out PGNSP PGUID 12 f f t f i 1 2275 "1083" _null_ _null_ _null_ time_out - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2909 ( timetypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ timetypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2910 ( timetypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ timetypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1145 ( time_eq PGNSP PGUID 12 f f t f i 2 16 "1083 1083" _null_ _null_ _null_ time_eq - _null_ )); DATA(insert OID = 1145 ( time_eq PGNSP PGUID 12 f f t f i 2 16 "1083 1083" _null_ _null_ _null_ time_eq - _null_ ));
DESCR("equal"); DESCR("equal");
@ -1424,6 +1436,10 @@ DATA(insert OID = 1150 ( timestamptz_in PGNSP PGUID 12 f f t f s 3 1184 "2275
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1151 ( timestamptz_out PGNSP PGUID 12 f f t f s 1 2275 "1184" _null_ _null_ _null_ timestamptz_out - _null_ )); DATA(insert OID = 1151 ( timestamptz_out PGNSP PGUID 12 f f t f s 1 2275 "1184" _null_ _null_ _null_ timestamptz_out - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2907 ( timestamptztypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ timestamptztypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2908 ( timestamptztypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ timestamptztypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1152 ( timestamptz_eq PGNSP PGUID 12 f f t f i 2 16 "1184 1184" _null_ _null_ _null_ timestamp_eq - _null_ )); DATA(insert OID = 1152 ( timestamptz_eq PGNSP PGUID 12 f f t f i 2 16 "1184 1184" _null_ _null_ _null_ timestamp_eq - _null_ ));
DESCR("equal"); DESCR("equal");
DATA(insert OID = 1153 ( timestamptz_ne PGNSP PGUID 12 f f t f i 2 16 "1184 1184" _null_ _null_ _null_ timestamp_ne - _null_ )); DATA(insert OID = 1153 ( timestamptz_ne PGNSP PGUID 12 f f t f i 2 16 "1184 1184" _null_ _null_ _null_ timestamp_ne - _null_ ));
@ -1445,6 +1461,10 @@ DATA(insert OID = 1160 ( interval_in PGNSP PGUID 12 f f t f s 3 1186 "2275 2
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1161 ( interval_out PGNSP PGUID 12 f f t f i 1 2275 "1186" _null_ _null_ _null_ interval_out - _null_ )); DATA(insert OID = 1161 ( interval_out PGNSP PGUID 12 f f t f i 1 2275 "1186" _null_ _null_ _null_ interval_out - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2903 ( intervaltypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ intervaltypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2904 ( intervaltypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ intervaltypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1162 ( interval_eq PGNSP PGUID 12 f f t f i 2 16 "1186 1186" _null_ _null_ _null_ interval_eq - _null_ )); DATA(insert OID = 1162 ( interval_eq PGNSP PGUID 12 f f t f i 2 16 "1186 1186" _null_ _null_ _null_ interval_eq - _null_ ));
DESCR("equal"); DESCR("equal");
DATA(insert OID = 1163 ( interval_ne PGNSP PGUID 12 f f t f i 2 16 "1186 1186" _null_ _null_ _null_ interval_ne - _null_ )); DATA(insert OID = 1163 ( interval_ne PGNSP PGUID 12 f f t f i 2 16 "1186 1186" _null_ _null_ _null_ interval_ne - _null_ ));
@ -1668,6 +1688,10 @@ DATA(insert OID = 1312 ( timestamp_in PGNSP PGUID 12 f f t f s 3 1114 "2275 2
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1313 ( timestamp_out PGNSP PGUID 12 f f t f s 1 2275 "1114" _null_ _null_ _null_ timestamp_out - _null_ )); DATA(insert OID = 1313 ( timestamp_out PGNSP PGUID 12 f f t f s 1 2275 "1114" _null_ _null_ _null_ timestamp_out - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2905 ( timestamptypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ timestamptypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2906 ( timestamptypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ timestamptypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1314 ( timestamptz_cmp PGNSP PGUID 12 f f t f i 2 23 "1184 1184" _null_ _null_ _null_ timestamp_cmp - _null_ )); DATA(insert OID = 1314 ( timestamptz_cmp PGNSP PGUID 12 f f t f i 2 23 "1184 1184" _null_ _null_ _null_ timestamp_cmp - _null_ ));
DESCR("less-equal-greater"); DESCR("less-equal-greater");
DATA(insert OID = 1315 ( interval_cmp PGNSP PGUID 12 f f t f i 2 23 "1186 1186" _null_ _null_ _null_ interval_cmp - _null_ )); DATA(insert OID = 1315 ( interval_cmp PGNSP PGUID 12 f f t f i 2 23 "1186 1186" _null_ _null_ _null_ interval_cmp - _null_ ));
@ -1721,6 +1745,10 @@ DATA(insert OID = 1350 ( timetz_in PGNSP PGUID 12 f f t f s 3 1266 "2275 26
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1351 ( timetz_out PGNSP PGUID 12 f f t f i 1 2275 "1266" _null_ _null_ _null_ timetz_out - _null_ )); DATA(insert OID = 1351 ( timetz_out PGNSP PGUID 12 f f t f i 1 2275 "1266" _null_ _null_ _null_ timetz_out - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2911 ( timetztypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ timetztypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2912 ( timetztypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ timetztypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1352 ( timetz_eq PGNSP PGUID 12 f f t f i 2 16 "1266 1266" _null_ _null_ _null_ timetz_eq - _null_ )); DATA(insert OID = 1352 ( timetz_eq PGNSP PGUID 12 f f t f i 2 16 "1266 1266" _null_ _null_ _null_ timetz_eq - _null_ ));
DESCR("equal"); DESCR("equal");
DATA(insert OID = 1353 ( timetz_ne PGNSP PGUID 12 f f t f i 2 16 "1266 1266" _null_ _null_ _null_ timetz_ne - _null_ )); DATA(insert OID = 1353 ( timetz_ne PGNSP PGUID 12 f f t f i 2 16 "1266 1266" _null_ _null_ _null_ timetz_ne - _null_ ));
@ -2053,6 +2081,10 @@ DATA(insert OID = 1564 ( bit_in PGNSP PGUID 12 f f t f i 3 1560 "2275 26 23"
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1565 ( bit_out PGNSP PGUID 12 f f t f i 1 2275 "1560" _null_ _null_ _null_ bit_out - _null_ )); DATA(insert OID = 1565 ( bit_out PGNSP PGUID 12 f f t f i 1 2275 "1560" _null_ _null_ _null_ bit_out - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2919 ( bittypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ bittypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2920 ( bittypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ bittypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1569 ( like PGNSP PGUID 12 f f t f i 2 16 "25 25" _null_ _null_ _null_ textlike - _null_ )); DATA(insert OID = 1569 ( like PGNSP PGUID 12 f f t f i 2 16 "25 25" _null_ _null_ _null_ textlike - _null_ ));
DESCR("matches LIKE expression"); DESCR("matches LIKE expression");
@ -2078,6 +2110,10 @@ DATA(insert OID = 1579 ( varbit_in PGNSP PGUID 12 f f t f i 3 1562 "2275 26 2
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1580 ( varbit_out PGNSP PGUID 12 f f t f i 1 2275 "1562" _null_ _null_ _null_ varbit_out - _null_ )); DATA(insert OID = 1580 ( varbit_out PGNSP PGUID 12 f f t f i 1 2275 "1562" _null_ _null_ _null_ varbit_out - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2902 ( varbittypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ varbittypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2921 ( varbittypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ varbittypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1581 ( biteq PGNSP PGUID 12 f f t f i 2 16 "1560 1560" _null_ _null_ _null_ biteq - _null_ )); DATA(insert OID = 1581 ( biteq PGNSP PGUID 12 f f t f i 2 16 "1560 1560" _null_ _null_ _null_ biteq - _null_ ));
DESCR("equal"); DESCR("equal");
@ -2498,6 +2534,10 @@ DATA(insert OID = 1701 ( numeric_in PGNSP PGUID 12 f f t f i 3 1700 "2275 26
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 1702 ( numeric_out PGNSP PGUID 12 f f t f i 1 2275 "1700" _null_ _null_ _null_ numeric_out - _null_ )); DATA(insert OID = 1702 ( numeric_out PGNSP PGUID 12 f f t f i 1 2275 "1700" _null_ _null_ _null_ numeric_out - _null_ ));
DESCR("I/O"); DESCR("I/O");
DATA(insert OID = 2917 ( numerictypmodin PGNSP PGUID 12 f f t f i 1 23 "1007" _null_ _null_ _null_ numerictypmodin - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2918 ( numerictypmodout PGNSP PGUID 12 f f t f i 1 2275 "23" _null_ _null_ _null_ numerictypmodout - _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 1703 ( numeric PGNSP PGUID 12 f f t f i 2 1700 "1700 23" _null_ _null_ _null_ numeric - _null_ )); DATA(insert OID = 1703 ( numeric PGNSP PGUID 12 f f t f i 2 1700 "1700 23" _null_ _null_ _null_ numeric - _null_ ));
DESCR("adjust numeric to typmod precision/scale"); DESCR("adjust numeric to typmod precision/scale");
DATA(insert OID = 1704 ( numeric_abs PGNSP PGUID 12 f f t f i 1 1700 "1700" _null_ _null_ _null_ numeric_abs - _null_ )); DATA(insert OID = 1704 ( numeric_abs PGNSP PGUID 12 f f t f i 1 1700 "1700" _null_ _null_ _null_ numeric_abs - _null_ ));

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.175 2006/12/28 14:28:36 petere Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.176 2006/12/30 21:21:55 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -104,6 +104,12 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP
regproc typreceive; /* binary format (optional) */ regproc typreceive; /* binary format (optional) */
regproc typsend; regproc typsend;
/*
* I/O functions for optional type modifiers.
*/
regproc typmodin;
regproc typmodout;
/* /*
* Custom ANALYZE procedure for the datatype (0 selects the default). * Custom ANALYZE procedure for the datatype (0 selects the default).
*/ */
@ -205,7 +211,7 @@ typedef FormData_pg_type *Form_pg_type;
* compiler constants for pg_type * compiler constants for pg_type
* ---------------- * ----------------
*/ */
#define Natts_pg_type 23 #define Natts_pg_type 25
#define Anum_pg_type_typname 1 #define Anum_pg_type_typname 1
#define Anum_pg_type_typnamespace 2 #define Anum_pg_type_typnamespace 2
#define Anum_pg_type_typowner 3 #define Anum_pg_type_typowner 3
@ -220,15 +226,17 @@ typedef FormData_pg_type *Form_pg_type;
#define Anum_pg_type_typoutput 12 #define Anum_pg_type_typoutput 12
#define Anum_pg_type_typreceive 13 #define Anum_pg_type_typreceive 13
#define Anum_pg_type_typsend 14 #define Anum_pg_type_typsend 14
#define Anum_pg_type_typanalyze 15 #define Anum_pg_type_typmodin 15
#define Anum_pg_type_typalign 16 #define Anum_pg_type_typmodout 16
#define Anum_pg_type_typstorage 17 #define Anum_pg_type_typanalyze 17
#define Anum_pg_type_typnotnull 18 #define Anum_pg_type_typalign 18
#define Anum_pg_type_typbasetype 19 #define Anum_pg_type_typstorage 19
#define Anum_pg_type_typtypmod 20 #define Anum_pg_type_typnotnull 20
#define Anum_pg_type_typndims 21 #define Anum_pg_type_typbasetype 21
#define Anum_pg_type_typdefaultbin 22 #define Anum_pg_type_typtypmod 22
#define Anum_pg_type_typdefault 23 #define Anum_pg_type_typndims 23
#define Anum_pg_type_typdefaultbin 24
#define Anum_pg_type_typdefault 25
/* ---------------- /* ----------------
@ -244,86 +252,86 @@ typedef FormData_pg_type *Form_pg_type;
*/ */
/* OIDS 1 - 99 */ /* OIDS 1 - 99 */
DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b t \054 0 0 boolin boolout boolrecv boolsend - c p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b t \054 0 0 boolin boolout boolrecv boolsend - - - c p f 0 -1 0 _null_ _null_ ));
DESCR("boolean, 'true'/'false'"); DESCR("boolean, 'true'/'false'");
#define BOOLOID 16 #define BOOLOID 16
DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b t \054 0 0 byteain byteaout bytearecv byteasend - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b t \054 0 0 byteain byteaout bytearecv byteasend - - - i x f 0 -1 0 _null_ _null_ ));
DESCR("variable-length string, binary values escaped"); DESCR("variable-length string, binary values escaped");
#define BYTEAOID 17 #define BYTEAOID 17
DATA(insert OID = 18 ( char PGNSP PGUID 1 t b t \054 0 0 charin charout charrecv charsend - c p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 18 ( char PGNSP PGUID 1 t b t \054 0 0 charin charout charrecv charsend - - - c p f 0 -1 0 _null_ _null_ ));
DESCR("single character"); DESCR("single character");
#define CHAROID 18 #define CHAROID 18
DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 namein nameout namerecv namesend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 namein nameout namerecv namesend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("63-character type for storing system identifiers"); DESCR("63-character type for storing system identifiers");
#define NAMEOID 19 #define NAMEOID 19
DATA(insert OID = 20 ( int8 PGNSP PGUID 8 f b t \054 0 0 int8in int8out int8recv int8send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 20 ( int8 PGNSP PGUID 8 f b t \054 0 0 int8in int8out int8recv int8send - - - d p f 0 -1 0 _null_ _null_ ));
DESCR("~18 digit integer, 8-byte storage"); DESCR("~18 digit integer, 8-byte storage");
#define INT8OID 20 #define INT8OID 20
DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b t \054 0 0 int2in int2out int2recv int2send - s p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b t \054 0 0 int2in int2out int2recv int2send - - - s p f 0 -1 0 _null_ _null_ ));
DESCR("-32 thousand to 32 thousand, 2-byte storage"); DESCR("-32 thousand to 32 thousand, 2-byte storage");
#define INT2OID 21 #define INT2OID 21
DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b t \054 0 21 int2vectorin int2vectorout int2vectorrecv int2vectorsend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b t \054 0 21 int2vectorin int2vectorout int2vectorrecv int2vectorsend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("array of int2, used in system tables"); DESCR("array of int2, used in system tables");
#define INT2VECTOROID 22 #define INT2VECTOROID 22
DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 int4in int4out int4recv int4send - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 int4in int4out int4recv int4send - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("-2 billion to 2 billion integer, 4-byte storage"); DESCR("-2 billion to 2 billion integer, 4-byte storage");
#define INT4OID 23 #define INT4OID 23
DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b t \054 0 0 regprocin regprocout regprocrecv regprocsend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b t \054 0 0 regprocin regprocout regprocrecv regprocsend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("registered procedure"); DESCR("registered procedure");
#define REGPROCOID 24 #define REGPROCOID 24
DATA(insert OID = 25 ( text PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 25 ( text PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ ));
DESCR("variable-length string, no limit specified"); DESCR("variable-length string, no limit specified");
#define TEXTOID 25 #define TEXTOID 25
DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b t \054 0 0 oidin oidout oidrecv oidsend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b t \054 0 0 oidin oidout oidrecv oidsend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("object identifier(oid), maximum 4 billion"); DESCR("object identifier(oid), maximum 4 billion");
#define OIDOID 26 #define OIDOID 26
DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b t \054 0 0 tidin tidout tidrecv tidsend - s p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b t \054 0 0 tidin tidout tidrecv tidsend - - - s p f 0 -1 0 _null_ _null_ ));
DESCR("(Block, offset), physical location of tuple"); DESCR("(Block, offset), physical location of tuple");
#define TIDOID 27 #define TIDOID 27
DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b t \054 0 0 xidin xidout xidrecv xidsend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b t \054 0 0 xidin xidout xidrecv xidsend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("transaction id"); DESCR("transaction id");
#define XIDOID 28 #define XIDOID 28
DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b t \054 0 0 cidin cidout cidrecv cidsend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b t \054 0 0 cidin cidout cidrecv cidsend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("command identifier type, sequence in transaction id"); DESCR("command identifier type, sequence in transaction id");
#define CIDOID 29 #define CIDOID 29
DATA(insert OID = 30 ( oidvector PGNSP PGUID -1 f b t \054 0 26 oidvectorin oidvectorout oidvectorrecv oidvectorsend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 30 ( oidvector PGNSP PGUID -1 f b t \054 0 26 oidvectorin oidvectorout oidvectorrecv oidvectorsend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("array of oids, used in system tables"); DESCR("array of oids, used in system tables");
#define OIDVECTOROID 30 #define OIDVECTOROID 30
/* hand-built rowtype entries for bootstrapped catalogs: */ /* hand-built rowtype entries for bootstrapped catalogs: */
DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c t \054 1247 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c t \054 1247 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
#define PG_TYPE_RELTYPE_OID 71 #define PG_TYPE_RELTYPE_OID 71
DATA(insert OID = 75 ( pg_attribute PGNSP PGUID -1 f c t \054 1249 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 75 ( pg_attribute PGNSP PGUID -1 f c t \054 1249 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
#define PG_ATTRIBUTE_RELTYPE_OID 75 #define PG_ATTRIBUTE_RELTYPE_OID 75
DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c t \054 1255 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c t \054 1255 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
#define PG_PROC_RELTYPE_OID 81 #define PG_PROC_RELTYPE_OID 81
DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c t \054 1259 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c t \054 1259 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
#define PG_CLASS_RELTYPE_OID 83 #define PG_CLASS_RELTYPE_OID 83
/* OIDS 100 - 199 */ /* OIDS 100 - 199 */
DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b t \054 0 0 xml_in xml_out xml_recv xml_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b t \054 0 0 xml_in xml_out xml_recv xml_send - - - i x f 0 -1 0 _null_ _null_ ));
DESCR("XML content"); DESCR("XML content");
#define XMLOID 142 #define XMLOID 142
DATA(insert OID = 143 ( _xml PGNSP PGUID -1 f b t \054 0 142 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 143 ( _xml PGNSP PGUID -1 f b t \054 0 142 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
/* OIDS 200 - 299 */ /* OIDS 200 - 299 */
DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b t \054 0 0 smgrin smgrout - - - s p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b t \054 0 0 smgrin smgrout - - - - - s p f 0 -1 0 _null_ _null_ ));
DESCR("storage manager"); DESCR("storage manager");
/* OIDS 300 - 399 */ /* OIDS 300 - 399 */
@ -333,194 +341,194 @@ DESCR("storage manager");
/* OIDS 500 - 599 */ /* OIDS 500 - 599 */
/* OIDS 600 - 699 */ /* OIDS 600 - 699 */
DATA(insert OID = 600 ( point PGNSP PGUID 16 f b t \054 0 701 point_in point_out point_recv point_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 600 ( point PGNSP PGUID 16 f b t \054 0 701 point_in point_out point_recv point_send - - - d p f 0 -1 0 _null_ _null_ ));
DESCR("geometric point '(x, y)'"); DESCR("geometric point '(x, y)'");
#define POINTOID 600 #define POINTOID 600
DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b t \054 0 600 lseg_in lseg_out lseg_recv lseg_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b t \054 0 600 lseg_in lseg_out lseg_recv lseg_send - - - d p f 0 -1 0 _null_ _null_ ));
DESCR("geometric line segment '(pt1,pt2)'"); DESCR("geometric line segment '(pt1,pt2)'");
#define LSEGOID 601 #define LSEGOID 601
DATA(insert OID = 602 ( path PGNSP PGUID -1 f b t \054 0 0 path_in path_out path_recv path_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 602 ( path PGNSP PGUID -1 f b t \054 0 0 path_in path_out path_recv path_send - - - d x f 0 -1 0 _null_ _null_ ));
DESCR("geometric path '(pt1,...)'"); DESCR("geometric path '(pt1,...)'");
#define PATHOID 602 #define PATHOID 602
DATA(insert OID = 603 ( box PGNSP PGUID 32 f b t \073 0 600 box_in box_out box_recv box_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 603 ( box PGNSP PGUID 32 f b t \073 0 600 box_in box_out box_recv box_send - - - d p f 0 -1 0 _null_ _null_ ));
DESCR("geometric box '(lower left,upper right)'"); DESCR("geometric box '(lower left,upper right)'");
#define BOXOID 603 #define BOXOID 603
DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b t \054 0 0 poly_in poly_out poly_recv poly_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b t \054 0 0 poly_in poly_out poly_recv poly_send - - - d x f 0 -1 0 _null_ _null_ ));
DESCR("geometric polygon '(pt1,...)'"); DESCR("geometric polygon '(pt1,...)'");
#define POLYGONOID 604 #define POLYGONOID 604
DATA(insert OID = 628 ( line PGNSP PGUID 32 f b t \054 0 701 line_in line_out line_recv line_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 628 ( line PGNSP PGUID 32 f b t \054 0 701 line_in line_out line_recv line_send - - - d p f 0 -1 0 _null_ _null_ ));
DESCR("geometric line (not implemented)'"); DESCR("geometric line (not implemented)'");
#define LINEOID 628 #define LINEOID 628
DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b t \054 0 628 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b t \054 0 628 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DESCR(""); DESCR("");
/* OIDS 700 - 799 */ /* OIDS 700 - 799 */
DATA(insert OID = 700 ( float4 PGNSP PGUID 4 f b t \054 0 0 float4in float4out float4recv float4send - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 700 ( float4 PGNSP PGUID 4 f b t \054 0 0 float4in float4out float4recv float4send - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("single-precision floating point number, 4-byte storage"); DESCR("single-precision floating point number, 4-byte storage");
#define FLOAT4OID 700 #define FLOAT4OID 700
DATA(insert OID = 701 ( float8 PGNSP PGUID 8 f b t \054 0 0 float8in float8out float8recv float8send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 701 ( float8 PGNSP PGUID 8 f b t \054 0 0 float8in float8out float8recv float8send - - - d p f 0 -1 0 _null_ _null_ ));
DESCR("double-precision floating point number, 8-byte storage"); DESCR("double-precision floating point number, 8-byte storage");
#define FLOAT8OID 701 #define FLOAT8OID 701
DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b t \054 0 0 abstimein abstimeout abstimerecv abstimesend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b t \054 0 0 abstimein abstimeout abstimerecv abstimesend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("absolute, limited-range date and time (Unix system time)"); DESCR("absolute, limited-range date and time (Unix system time)");
#define ABSTIMEOID 702 #define ABSTIMEOID 702
DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b t \054 0 0 reltimein reltimeout reltimerecv reltimesend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b t \054 0 0 reltimein reltimeout reltimerecv reltimesend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("relative, limited-range time interval (Unix delta time)"); DESCR("relative, limited-range time interval (Unix delta time)");
#define RELTIMEOID 703 #define RELTIMEOID 703
DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b t \054 0 0 tintervalin tintervalout tintervalrecv tintervalsend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b t \054 0 0 tintervalin tintervalout tintervalrecv tintervalsend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("(abstime,abstime), time interval"); DESCR("(abstime,abstime), time interval");
#define TINTERVALOID 704 #define TINTERVALOID 704
DATA(insert OID = 705 ( unknown PGNSP PGUID -2 f b t \054 0 0 unknownin unknownout unknownrecv unknownsend - c p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 705 ( unknown PGNSP PGUID -2 f b t \054 0 0 unknownin unknownout unknownrecv unknownsend - - - c p f 0 -1 0 _null_ _null_ ));
DESCR(""); DESCR("");
#define UNKNOWNOID 705 #define UNKNOWNOID 705
DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b t \054 0 0 circle_in circle_out circle_recv circle_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b t \054 0 0 circle_in circle_out circle_recv circle_send - - - d p f 0 -1 0 _null_ _null_ ));
DESCR("geometric circle '(center,radius)'"); DESCR("geometric circle '(center,radius)'");
#define CIRCLEOID 718 #define CIRCLEOID 718
DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b t \054 0 718 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b t \054 0 718 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 790 ( money PGNSP PGUID 4 f b t \054 0 0 cash_in cash_out cash_recv cash_send - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 790 ( money PGNSP PGUID 4 f b t \054 0 0 cash_in cash_out cash_recv cash_send - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("monetary amounts, $d,ddd.cc"); DESCR("monetary amounts, $d,ddd.cc");
#define CASHOID 790 #define CASHOID 790
DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b t \054 0 790 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b t \054 0 790 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
/* OIDS 800 - 899 */ /* OIDS 800 - 899 */
DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b t \054 0 0 macaddr_in macaddr_out macaddr_recv macaddr_send - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b t \054 0 0 macaddr_in macaddr_out macaddr_recv macaddr_send - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("XX:XX:XX:XX:XX:XX, MAC address"); DESCR("XX:XX:XX:XX:XX:XX, MAC address");
#define MACADDROID 829 #define MACADDROID 829
DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b t \054 0 0 inet_in inet_out inet_recv inet_send - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b t \054 0 0 inet_in inet_out inet_recv inet_send - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("IP address/netmask, host address, netmask optional"); DESCR("IP address/netmask, host address, netmask optional");
#define INETOID 869 #define INETOID 869
DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b t \054 0 0 cidr_in cidr_out cidr_recv cidr_send - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b t \054 0 0 cidr_in cidr_out cidr_recv cidr_send - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("network IP address/netmask, network address"); DESCR("network IP address/netmask, network address");
#define CIDROID 650 #define CIDROID 650
/* OIDS 900 - 999 */ /* OIDS 900 - 999 */
/* OIDS 1000 - 1099 */ /* OIDS 1000 - 1099 */
DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b t \054 0 16 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b t \054 0 16 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b t \054 0 17 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b t \054 0 17 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b t \054 0 18 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b t \054 0 18 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b t \054 0 19 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b t \054 0 19 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b t \054 0 21 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b t \054 0 21 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b t \054 0 22 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b t \054 0 22 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b t \054 0 23 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b t \054 0 23 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
#define INT4ARRAYOID 1007 #define INT4ARRAYOID 1007
DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b t \054 0 24 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b t \054 0 24 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b t \054 0 25 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b t \054 0 25 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b t \054 0 26 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b t \054 0 26 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b t \054 0 27 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b t \054 0 27 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b t \054 0 28 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b t \054 0 28 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b t \054 0 29 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b t \054 0 29 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b t \054 0 30 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b t \054 0 30 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b t \054 0 1042 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b t \054 0 1042 array_in array_out array_recv array_send bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b t \054 0 1043 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b t \054 0 1043 array_in array_out array_recv array_send varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b t \054 0 20 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b t \054 0 20 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b t \054 0 600 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b t \054 0 600 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b t \054 0 601 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b t \054 0 601 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b t \054 0 602 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b t \054 0 602 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b t \073 0 603 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b t \073 0 603 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 f b t \054 0 700 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 f b t \054 0 700 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
#define FLOAT4ARRAYOID 1021 #define FLOAT4ARRAYOID 1021
DATA(insert OID = 1022 ( _float8 PGNSP PGUID -1 f b t \054 0 701 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1022 ( _float8 PGNSP PGUID -1 f b t \054 0 701 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b t \054 0 702 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b t \054 0 702 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 f b t \054 0 703 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 f b t \054 0 703 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b t \054 0 704 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b t \054 0 704 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b t \054 0 604 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b t \054 0 604 array_in array_out array_recv array_send - - - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1033 ( aclitem PGNSP PGUID 12 f b t \054 0 0 aclitemin aclitemout - - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1033 ( aclitem PGNSP PGUID 12 f b t \054 0 0 aclitemin aclitemout - - - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("access control list"); DESCR("access control list");
#define ACLITEMOID 1033 #define ACLITEMOID 1033
DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b t \054 0 1033 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b t \054 0 1033 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b t \054 0 829 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b t \054 0 829 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b t \054 0 869 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b t \054 0 869 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b t \054 0 650 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b t \054 0 650 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b t \054 0 0 bpcharin bpcharout bpcharrecv bpcharsend - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b t \054 0 0 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodin bpchartypmodout - i x f 0 -1 0 _null_ _null_ ));
DESCR("char(length), blank-padded string, fixed storage length"); DESCR("char(length), blank-padded string, fixed storage length");
#define BPCHAROID 1042 #define BPCHAROID 1042
DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b t \054 0 0 varcharin varcharout varcharrecv varcharsend - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b t \054 0 0 varcharin varcharout varcharrecv varcharsend varchartypmodin varchartypmodout - i x f 0 -1 0 _null_ _null_ ));
DESCR("varchar(length), non-blank-padded string, variable storage length"); DESCR("varchar(length), non-blank-padded string, variable storage length");
#define VARCHAROID 1043 #define VARCHAROID 1043
DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b t \054 0 0 date_in date_out date_recv date_send - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b t \054 0 0 date_in date_out date_recv date_send - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("ANSI SQL date"); DESCR("ANSI SQL date");
#define DATEOID 1082 #define DATEOID 1082
DATA(insert OID = 1083 ( time PGNSP PGUID 8 f b t \054 0 0 time_in time_out time_recv time_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1083 ( time PGNSP PGUID 8 f b t \054 0 0 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 _null_ _null_ ));
DESCR("hh:mm:ss, ANSI SQL time"); DESCR("hh:mm:ss, ANSI SQL time");
#define TIMEOID 1083 #define TIMEOID 1083
/* OIDS 1100 - 1199 */ /* OIDS 1100 - 1199 */
DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 f b t \054 0 0 timestamp_in timestamp_out timestamp_recv timestamp_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 f b t \054 0 0 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 _null_ _null_ ));
DESCR("date and time"); DESCR("date and time");
#define TIMESTAMPOID 1114 #define TIMESTAMPOID 1114
DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b t \054 0 1114 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b t \054 0 1114 array_in array_out array_recv array_send timestamptypmodin timestamptypmodout - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1182 ( _date PGNSP PGUID -1 f b t \054 0 1082 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1182 ( _date PGNSP PGUID -1 f b t \054 0 1082 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1183 ( _time PGNSP PGUID -1 f b t \054 0 1083 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1183 ( _time PGNSP PGUID -1 f b t \054 0 1083 array_in array_out array_recv array_send timetypmodin timetypmodout - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 _null_ _null_ ));
DESCR("date and time with time zone"); DESCR("date and time with time zone");
#define TIMESTAMPTZOID 1184 #define TIMESTAMPTZOID 1184
DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b t \054 0 1184 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b t \054 0 1184 array_in array_out array_recv array_send timestamptztypmodin timestamptztypmodout - d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1186 ( interval PGNSP PGUID 16 f b t \054 0 0 interval_in interval_out interval_recv interval_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1186 ( interval PGNSP PGUID 16 f b t \054 0 0 interval_in interval_out interval_recv interval_send intervaltypmodin intervaltypmodout - d p f 0 -1 0 _null_ _null_ ));
DESCR("@ <number> <units>, time interval"); DESCR("@ <number> <units>, time interval");
#define INTERVALOID 1186 #define INTERVALOID 1186
DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b t \054 0 1186 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b t \054 0 1186 array_in array_out array_recv array_send intervaltypmodin intervaltypmodout - d x f 0 -1 0 _null_ _null_ ));
/* OIDS 1200 - 1299 */ /* OIDS 1200 - 1299 */
DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b t \054 0 1700 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b t \054 0 1700 array_in array_out array_recv array_send numerictypmodin numerictypmodout - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 f b t \054 0 0 timetz_in timetz_out timetz_recv timetz_send - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 f b t \054 0 0 timetz_in timetz_out timetz_recv timetz_send timetztypmodin timetztypmodout - d p f 0 -1 0 _null_ _null_ ));
DESCR("hh:mm:ss, ANSI SQL time"); DESCR("hh:mm:ss, ANSI SQL time");
#define TIMETZOID 1266 #define TIMETZOID 1266
DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b t \054 0 1266 array_in array_out array_recv array_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b t \054 0 1266 array_in array_out array_recv array_send timetztypmodin timetztypmodout - d x f 0 -1 0 _null_ _null_ ));
/* OIDS 1500 - 1599 */ /* OIDS 1500 - 1599 */
DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b t \054 0 0 bit_in bit_out bit_recv bit_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b t \054 0 0 bit_in bit_out bit_recv bit_send bittypmodin bittypmodout - i x f 0 -1 0 _null_ _null_ ));
DESCR("fixed-length bit string"); DESCR("fixed-length bit string");
#define BITOID 1560 #define BITOID 1560
DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b t \054 0 1560 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b t \054 0 1560 array_in array_out array_recv array_send bittypmodin bittypmodout - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 f b t \054 0 0 varbit_in varbit_out varbit_recv varbit_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 f b t \054 0 0 varbit_in varbit_out varbit_recv varbit_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ ));
DESCR("variable-length bit string"); DESCR("variable-length bit string");
#define VARBITOID 1562 #define VARBITOID 1562
DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b t \054 0 1562 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b t \054 0 1562 array_in array_out array_recv array_send varbittypmodin varbittypmodout - i x f 0 -1 0 _null_ _null_ ));
/* OIDS 1600 - 1699 */ /* OIDS 1600 - 1699 */
/* OIDS 1700 - 1799 */ /* OIDS 1700 - 1799 */
DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b t \054 0 0 numeric_in numeric_out numeric_recv numeric_send - i m f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b t \054 0 0 numeric_in numeric_out numeric_recv numeric_send numerictypmodin numerictypmodout - i m f 0 -1 0 _null_ _null_ ));
DESCR("numeric(precision, decimal), arbitrary precision number"); DESCR("numeric(precision, decimal), arbitrary precision number");
#define NUMERICOID 1700 #define NUMERICOID 1700
DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend - - - i x f 0 -1 0 _null_ _null_ ));
DESCR("reference cursor (portal name)"); DESCR("reference cursor (portal name)");
#define REFCURSOROID 1790 #define REFCURSOROID 1790
/* OIDS 2200 - 2299 */ /* OIDS 2200 - 2299 */
DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b t \054 0 1790 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b t \054 0 1790 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b t \054 0 0 regprocedurein regprocedureout regprocedurerecv regproceduresend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b t \054 0 0 regprocedurein regprocedureout regprocedurerecv regproceduresend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("registered procedure (with args)"); DESCR("registered procedure (with args)");
#define REGPROCEDUREOID 2202 #define REGPROCEDUREOID 2202
DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b t \054 0 0 regoperin regoperout regoperrecv regopersend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b t \054 0 0 regoperin regoperout regoperrecv regopersend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("registered operator"); DESCR("registered operator");
#define REGOPEROID 2203 #define REGOPEROID 2203
DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b t \054 0 0 regoperatorin regoperatorout regoperatorrecv regoperatorsend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b t \054 0 0 regoperatorin regoperatorout regoperatorrecv regoperatorsend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("registered operator (with args)"); DESCR("registered operator (with args)");
#define REGOPERATOROID 2204 #define REGOPERATOROID 2204
DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b t \054 0 0 regclassin regclassout regclassrecv regclasssend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b t \054 0 0 regclassin regclassout regclassrecv regclasssend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("registered class"); DESCR("registered class");
#define REGCLASSOID 2205 #define REGCLASSOID 2205
DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b t \054 0 0 regtypein regtypeout regtyperecv regtypesend - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b t \054 0 0 regtypein regtypeout regtyperecv regtypesend - - - i p f 0 -1 0 _null_ _null_ ));
DESCR("registered type"); DESCR("registered type");
#define REGTYPEOID 2206 #define REGTYPEOID 2206
DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b t \054 0 2202 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b t \054 0 2202 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b t \054 0 2203 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b t \054 0 2203 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b t \054 0 2204 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b t \054 0 2204 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b t \054 0 2205 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b t \054 0 2205 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b t \054 0 2206 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b t \054 0 2206 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
#define REGTYPEARRAYOID 2211 #define REGTYPEARRAYOID 2211
/* /*
@ -532,25 +540,25 @@ DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b t \054 0 2206 array_in a
* argument and result types (if supported by the function's implementation * argument and result types (if supported by the function's implementation
* language). * language).
*/ */
DATA(insert OID = 2249 ( record PGNSP PGUID -1 f p t \054 0 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2249 ( record PGNSP PGUID -1 f p t \054 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 _null_ _null_ ));
#define RECORDOID 2249 #define RECORDOID 2249
DATA(insert OID = 2275 ( cstring PGNSP PGUID -2 f p t \054 0 0 cstring_in cstring_out cstring_recv cstring_send - c p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2275 ( cstring PGNSP PGUID -2 f p t \054 0 0 cstring_in cstring_out cstring_recv cstring_send - - - c p f 0 -1 0 _null_ _null_ ));
#define CSTRINGOID 2275 #define CSTRINGOID 2275
DATA(insert OID = 2276 ( any PGNSP PGUID 4 t p t \054 0 0 any_in any_out - - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2276 ( any PGNSP PGUID 4 t p t \054 0 0 any_in any_out - - - - - i p f 0 -1 0 _null_ _null_ ));
#define ANYOID 2276 #define ANYOID 2276
DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p t \054 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send - d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p t \054 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send - - - d x f 0 -1 0 _null_ _null_ ));
#define ANYARRAYOID 2277 #define ANYARRAYOID 2277
DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p t \054 0 0 void_in void_out - - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p t \054 0 0 void_in void_out - - - - - i p f 0 -1 0 _null_ _null_ ));
#define VOIDOID 2278 #define VOIDOID 2278
DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p t \054 0 0 trigger_in trigger_out - - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p t \054 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 _null_ _null_ ));
#define TRIGGEROID 2279 #define TRIGGEROID 2279
DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p t \054 0 0 language_handler_in language_handler_out - - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p t \054 0 0 language_handler_in language_handler_out - - - - - i p f 0 -1 0 _null_ _null_ ));
#define LANGUAGE_HANDLEROID 2280 #define LANGUAGE_HANDLEROID 2280
DATA(insert OID = 2281 ( internal PGNSP PGUID 4 t p t \054 0 0 internal_in internal_out - - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2281 ( internal PGNSP PGUID 4 t p t \054 0 0 internal_in internal_out - - - - - i p f 0 -1 0 _null_ _null_ ));
#define INTERNALOID 2281 #define INTERNALOID 2281
DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p t \054 0 0 opaque_in opaque_out - - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p t \054 0 0 opaque_in opaque_out - - - - - i p f 0 -1 0 _null_ _null_ ));
#define OPAQUEOID 2282 #define OPAQUEOID 2282
DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p t \054 0 0 anyelement_in anyelement_out - - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p t \054 0 0 anyelement_in anyelement_out - - - - - i p f 0 -1 0 _null_ _null_ ));
#define ANYELEMENTOID 2283 #define ANYELEMENTOID 2283
/* /*
@ -569,6 +577,8 @@ extern Oid TypeCreate(const char *typeName,
Oid outputProcedure, Oid outputProcedure,
Oid receiveProcedure, Oid receiveProcedure,
Oid sendProcedure, Oid sendProcedure,
Oid typmodinProcedure,
Oid typmodoutProcedure,
Oid analyzeProcedure, Oid analyzeProcedure,
Oid elementType, Oid elementType,
Oid baseType, Oid baseType,
@ -590,6 +600,8 @@ extern void GenerateTypeDependencies(Oid typeNamespace,
Oid outputProcedure, Oid outputProcedure,
Oid receiveProcedure, Oid receiveProcedure,
Oid sendProcedure, Oid sendProcedure,
Oid typmodinProcedure,
Oid typmodoutProcedure,
Oid analyzeProcedure, Oid analyzeProcedure,
Oid elementType, Oid elementType,
Oid baseType, Oid baseType,

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.335 2006/12/23 00:43:12 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.336 2006/12/30 21:21:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -167,6 +167,8 @@ typedef struct Query
* For TypeName structures generated internally, it is often easier to * For TypeName structures generated internally, it is often easier to
* specify the type by OID than by name. If "names" is NIL then the * specify the type by OID than by name. If "names" is NIL then the
* actual type OID is given by typeid, otherwise typeid is unused. * actual type OID is given by typeid, otherwise typeid is unused.
* Similarly, if "typmods" is NIL then the actual typmod is expected to
* be prespecified in typemod, otherwise typemod is unused.
* *
* If pct_type is TRUE, then names is actually a field name and we look up * If pct_type is TRUE, then names is actually a field name and we look up
* the type of that field. Otherwise (the normal case), names is a type * the type of that field. Otherwise (the normal case), names is a type
@ -180,7 +182,8 @@ typedef struct TypeName
bool timezone; /* timezone specified? */ bool timezone; /* timezone specified? */
bool setof; /* is a set? */ bool setof; /* is a set? */
bool pct_type; /* %TYPE specified? */ bool pct_type; /* %TYPE specified? */
int32 typmod; /* type modifier */ List *typmods; /* type modifier expression(s) */
int32 typemod; /* prespecified type modifier */
List *arrayBounds; /* array bounds */ List *arrayBounds; /* array bounds */
int location; /* token location, or -1 if unknown */ int location; /* token location, or -1 if unknown */
} TypeName; } TypeName;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/parser/parse_type.h,v 1.33 2006/09/25 15:17:34 tgl Exp $ * $PostgreSQL: pgsql/src/include/parser/parse_type.h,v 1.34 2006/12/30 21:21:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -24,6 +24,8 @@ extern Oid LookupTypeName(ParseState *pstate, const TypeName *typename);
extern char *TypeNameToString(const TypeName *typename); extern char *TypeNameToString(const TypeName *typename);
extern char *TypeNameListToString(List *typenames); extern char *TypeNameListToString(List *typenames);
extern Oid typenameTypeId(ParseState *pstate, const TypeName *typename); extern Oid typenameTypeId(ParseState *pstate, const TypeName *typename);
extern int32 typenameTypeMod(ParseState *pstate, const TypeName *typename,
Oid typeId);
extern Type typenameType(ParseState *pstate, const TypeName *typename); extern Type typenameType(ParseState *pstate, const TypeName *typename);
extern Type typeidType(Oid id); extern Type typeidType(Oid id);

View File

@ -49,7 +49,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.60 2006/11/08 19:24:38 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/array.h,v 1.61 2006/12/30 21:21:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -255,6 +255,7 @@ extern void mda_get_range(int n, int *span, const int *st, const int *endp);
extern void mda_get_prod(int n, const int *range, int *prod); extern void mda_get_prod(int n, const int *range, int *prod);
extern void mda_get_offset_values(int n, int *dist, const int *prod, const int *span); extern void mda_get_offset_values(int n, int *dist, const int *prod, const int *span);
extern int mda_next_tuple(int n, int *curr, const int *span); extern int mda_next_tuple(int n, int *curr, const int *span);
extern int32 *ArrayGetTypmods(ArrayType *arr, int *n);
/* /*
* prototypes for functions defined in array_userfuncs.c * prototypes for functions defined in array_userfuncs.c

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.282 2006/09/18 22:40:40 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.283 2006/12/30 21:21:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -565,6 +565,8 @@ extern Datum bpcharin(PG_FUNCTION_ARGS);
extern Datum bpcharout(PG_FUNCTION_ARGS); extern Datum bpcharout(PG_FUNCTION_ARGS);
extern Datum bpcharrecv(PG_FUNCTION_ARGS); extern Datum bpcharrecv(PG_FUNCTION_ARGS);
extern Datum bpcharsend(PG_FUNCTION_ARGS); extern Datum bpcharsend(PG_FUNCTION_ARGS);
extern Datum bpchartypmodin(PG_FUNCTION_ARGS);
extern Datum bpchartypmodout(PG_FUNCTION_ARGS);
extern Datum bpchar(PG_FUNCTION_ARGS); extern Datum bpchar(PG_FUNCTION_ARGS);
extern Datum char_bpchar(PG_FUNCTION_ARGS); extern Datum char_bpchar(PG_FUNCTION_ARGS);
extern Datum name_bpchar(PG_FUNCTION_ARGS); extern Datum name_bpchar(PG_FUNCTION_ARGS);
@ -586,6 +588,8 @@ extern Datum varcharin(PG_FUNCTION_ARGS);
extern Datum varcharout(PG_FUNCTION_ARGS); extern Datum varcharout(PG_FUNCTION_ARGS);
extern Datum varcharrecv(PG_FUNCTION_ARGS); extern Datum varcharrecv(PG_FUNCTION_ARGS);
extern Datum varcharsend(PG_FUNCTION_ARGS); extern Datum varcharsend(PG_FUNCTION_ARGS);
extern Datum varchartypmodin(PG_FUNCTION_ARGS);
extern Datum varchartypmodout(PG_FUNCTION_ARGS);
extern Datum varchar(PG_FUNCTION_ARGS); extern Datum varchar(PG_FUNCTION_ARGS);
/* varlena.c */ /* varlena.c */
@ -789,7 +793,9 @@ extern Datum numeric_in(PG_FUNCTION_ARGS);
extern Datum numeric_out(PG_FUNCTION_ARGS); extern Datum numeric_out(PG_FUNCTION_ARGS);
extern Datum numeric_recv(PG_FUNCTION_ARGS); extern Datum numeric_recv(PG_FUNCTION_ARGS);
extern Datum numeric_send(PG_FUNCTION_ARGS); extern Datum numeric_send(PG_FUNCTION_ARGS);
extern Datum numeric (PG_FUNCTION_ARGS); extern Datum numerictypmodin(PG_FUNCTION_ARGS);
extern Datum numerictypmodout(PG_FUNCTION_ARGS);
extern Datum numeric(PG_FUNCTION_ARGS);
extern Datum numeric_abs(PG_FUNCTION_ARGS); extern Datum numeric_abs(PG_FUNCTION_ARGS);
extern Datum numeric_uminus(PG_FUNCTION_ARGS); extern Datum numeric_uminus(PG_FUNCTION_ARGS);
extern Datum numeric_uplus(PG_FUNCTION_ARGS); extern Datum numeric_uplus(PG_FUNCTION_ARGS);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/date.h,v 1.34 2006/07/13 16:49:20 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/date.h,v 1.35 2006/12/30 21:21:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -140,6 +140,8 @@ extern Datum time_in(PG_FUNCTION_ARGS);
extern Datum time_out(PG_FUNCTION_ARGS); extern Datum time_out(PG_FUNCTION_ARGS);
extern Datum time_recv(PG_FUNCTION_ARGS); extern Datum time_recv(PG_FUNCTION_ARGS);
extern Datum time_send(PG_FUNCTION_ARGS); extern Datum time_send(PG_FUNCTION_ARGS);
extern Datum timetypmodin(PG_FUNCTION_ARGS);
extern Datum timetypmodout(PG_FUNCTION_ARGS);
extern Datum time_scale(PG_FUNCTION_ARGS); extern Datum time_scale(PG_FUNCTION_ARGS);
extern Datum time_eq(PG_FUNCTION_ARGS); extern Datum time_eq(PG_FUNCTION_ARGS);
extern Datum time_ne(PG_FUNCTION_ARGS); extern Datum time_ne(PG_FUNCTION_ARGS);
@ -166,6 +168,8 @@ extern Datum timetz_in(PG_FUNCTION_ARGS);
extern Datum timetz_out(PG_FUNCTION_ARGS); extern Datum timetz_out(PG_FUNCTION_ARGS);
extern Datum timetz_recv(PG_FUNCTION_ARGS); extern Datum timetz_recv(PG_FUNCTION_ARGS);
extern Datum timetz_send(PG_FUNCTION_ARGS); extern Datum timetz_send(PG_FUNCTION_ARGS);
extern Datum timetztypmodin(PG_FUNCTION_ARGS);
extern Datum timetztypmodout(PG_FUNCTION_ARGS);
extern Datum timetz_scale(PG_FUNCTION_ARGS); extern Datum timetz_scale(PG_FUNCTION_ARGS);
extern Datum timetz_eq(PG_FUNCTION_ARGS); extern Datum timetz_eq(PG_FUNCTION_ARGS);
extern Datum timetz_ne(PG_FUNCTION_ARGS); extern Datum timetz_ne(PG_FUNCTION_ARGS);

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.108 2006/12/23 00:43:13 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.109 2006/12/30 21:21:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -100,6 +100,7 @@ extern void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam);
extern void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena); extern void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena);
extern void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam); extern void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam);
extern void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena); extern void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena);
extern Oid get_typmodin(Oid typid);
extern Oid getBaseType(Oid typid); extern Oid getBaseType(Oid typid);
extern Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod); extern Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod);
extern int32 get_typavgwidth(Oid typid, int32 typmod); extern int32 get_typavgwidth(Oid typid, int32 typmod);

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.64 2006/10/04 00:30:11 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.65 2006/12/30 21:21:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -200,6 +200,8 @@ extern Datum timestamp_in(PG_FUNCTION_ARGS);
extern Datum timestamp_out(PG_FUNCTION_ARGS); extern Datum timestamp_out(PG_FUNCTION_ARGS);
extern Datum timestamp_recv(PG_FUNCTION_ARGS); extern Datum timestamp_recv(PG_FUNCTION_ARGS);
extern Datum timestamp_send(PG_FUNCTION_ARGS); extern Datum timestamp_send(PG_FUNCTION_ARGS);
extern Datum timestamptypmodin(PG_FUNCTION_ARGS);
extern Datum timestamptypmodout(PG_FUNCTION_ARGS);
extern Datum timestamp_scale(PG_FUNCTION_ARGS); extern Datum timestamp_scale(PG_FUNCTION_ARGS);
extern Datum timestamp_eq(PG_FUNCTION_ARGS); extern Datum timestamp_eq(PG_FUNCTION_ARGS);
extern Datum timestamp_ne(PG_FUNCTION_ARGS); extern Datum timestamp_ne(PG_FUNCTION_ARGS);
@ -232,6 +234,8 @@ extern Datum interval_in(PG_FUNCTION_ARGS);
extern Datum interval_out(PG_FUNCTION_ARGS); extern Datum interval_out(PG_FUNCTION_ARGS);
extern Datum interval_recv(PG_FUNCTION_ARGS); extern Datum interval_recv(PG_FUNCTION_ARGS);
extern Datum interval_send(PG_FUNCTION_ARGS); extern Datum interval_send(PG_FUNCTION_ARGS);
extern Datum intervaltypmodin(PG_FUNCTION_ARGS);
extern Datum intervaltypmodout(PG_FUNCTION_ARGS);
extern Datum interval_scale(PG_FUNCTION_ARGS); extern Datum interval_scale(PG_FUNCTION_ARGS);
extern Datum interval_eq(PG_FUNCTION_ARGS); extern Datum interval_eq(PG_FUNCTION_ARGS);
extern Datum interval_ne(PG_FUNCTION_ARGS); extern Datum interval_ne(PG_FUNCTION_ARGS);
@ -264,6 +268,8 @@ extern Datum timestamptz_in(PG_FUNCTION_ARGS);
extern Datum timestamptz_out(PG_FUNCTION_ARGS); extern Datum timestamptz_out(PG_FUNCTION_ARGS);
extern Datum timestamptz_recv(PG_FUNCTION_ARGS); extern Datum timestamptz_recv(PG_FUNCTION_ARGS);
extern Datum timestamptz_send(PG_FUNCTION_ARGS); extern Datum timestamptz_send(PG_FUNCTION_ARGS);
extern Datum timestamptztypmodin(PG_FUNCTION_ARGS);
extern Datum timestamptztypmodout(PG_FUNCTION_ARGS);
extern Datum timestamptz_scale(PG_FUNCTION_ARGS); extern Datum timestamptz_scale(PG_FUNCTION_ARGS);
extern Datum timestamptz_timestamp(PG_FUNCTION_ARGS); extern Datum timestamptz_timestamp(PG_FUNCTION_ARGS);
extern Datum timestamptz_zone(PG_FUNCTION_ARGS); extern Datum timestamptz_zone(PG_FUNCTION_ARGS);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/varbit.h,v 1.23 2006/03/05 15:59:08 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/varbit.h,v 1.24 2006/12/30 21:21:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -64,10 +64,14 @@ extern Datum bit_in(PG_FUNCTION_ARGS);
extern Datum bit_out(PG_FUNCTION_ARGS); extern Datum bit_out(PG_FUNCTION_ARGS);
extern Datum bit_recv(PG_FUNCTION_ARGS); extern Datum bit_recv(PG_FUNCTION_ARGS);
extern Datum bit_send(PG_FUNCTION_ARGS); extern Datum bit_send(PG_FUNCTION_ARGS);
extern Datum bittypmodin(PG_FUNCTION_ARGS);
extern Datum bittypmodout(PG_FUNCTION_ARGS);
extern Datum varbit_in(PG_FUNCTION_ARGS); extern Datum varbit_in(PG_FUNCTION_ARGS);
extern Datum varbit_out(PG_FUNCTION_ARGS); extern Datum varbit_out(PG_FUNCTION_ARGS);
extern Datum varbit_recv(PG_FUNCTION_ARGS); extern Datum varbit_recv(PG_FUNCTION_ARGS);
extern Datum varbit_send(PG_FUNCTION_ARGS); extern Datum varbit_send(PG_FUNCTION_ARGS);
extern Datum varbittypmodin(PG_FUNCTION_ARGS);
extern Datum varbittypmodout(PG_FUNCTION_ARGS);
extern Datum bit(PG_FUNCTION_ARGS); extern Datum bit(PG_FUNCTION_ARGS);
extern Datum varbit(PG_FUNCTION_ARGS); extern Datum varbit(PG_FUNCTION_ARGS);
extern Datum biteq(PG_FUNCTION_ARGS); extern Datum biteq(PG_FUNCTION_ARGS);

View File

@ -10,6 +10,8 @@ CREATE TYPE widget (
internallength = 24, internallength = 24,
input = widget_in, input = widget_in,
output = widget_out, output = widget_out,
typmod_in = numerictypmodin,
typmod_out = numerictypmodout,
alignment = double alignment = double
); );
CREATE TYPE city_budget ( CREATE TYPE city_budget (
@ -99,3 +101,15 @@ ERROR: type "text_w_default" already exists
DROP TYPE default_test_row CASCADE; DROP TYPE default_test_row CASCADE;
NOTICE: drop cascades to function get_default_test() NOTICE: drop cascades to function get_default_test()
DROP TABLE default_test; DROP TABLE default_test;
-- Check usage of typmod with a user-defined type
-- (we have borrowed numeric's typmod functions)
CREATE TEMP TABLE mytab (foo widget(42,13,7)); -- should fail
ERROR: invalid NUMERIC type modifier
CREATE TEMP TABLE mytab (foo widget(42,13));
SELECT format_type(atttypid,atttypmod) FROM pg_attribute
WHERE attrelid = 'mytab'::regclass AND attnum > 0;
format_type
---------------
widget(42,13)
(1 row)

View File

@ -840,8 +840,12 @@ SELECT time '03:30' + interval '1 month 04:01' AS "07:31:00";
SELECT CAST(time with time zone '01:02-08' AS interval) AS "+00:01"; SELECT CAST(time with time zone '01:02-08' AS interval) AS "+00:01";
ERROR: cannot cast type time with time zone to interval ERROR: cannot cast type time with time zone to interval
LINE 1: SELECT CAST(time with time zone '01:02-08' AS interval) AS "...
^
SELECT CAST(interval '02:03' AS time with time zone) AS "02:03:00-08"; SELECT CAST(interval '02:03' AS time with time zone) AS "02:03:00-08";
ERROR: cannot cast type interval to time with time zone ERROR: cannot cast type interval to time with time zone
LINE 1: SELECT CAST(interval '02:03' AS time with time zone) AS "02:...
^
SELECT time with time zone '01:30-08' - interval '02:01' AS "23:29:00-08"; SELECT time with time zone '01:30-08' - interval '02:01' AS "23:29:00-08";
23:29:00-08 23:29:00-08
------------- -------------

View File

@ -753,6 +753,22 @@ WHERE typsend != 0 AND
------+--------- ------+---------
(0 rows) (0 rows)
SELECT ctid, typmodin
FROM pg_catalog.pg_type fk
WHERE typmodin != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typmodin);
ctid | typmodin
------+----------
(0 rows)
SELECT ctid, typmodout
FROM pg_catalog.pg_type fk
WHERE typmodout != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typmodout);
ctid | typmodout
------+-----------
(0 rows)
SELECT ctid, typbasetype SELECT ctid, typbasetype
FROM pg_catalog.pg_type fk FROM pg_catalog.pg_type fk
WHERE typbasetype != 0 AND WHERE typbasetype != 0 AND

View File

@ -212,6 +212,48 @@ WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Check for bogus typmodin routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typmodin = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND
p2.proargtypes[0] = 'int4[]'::regtype AND
p2.prorettype = 'int4'::regtype AND NOT p2.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- Check for bogus typmodout routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typmodout = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND
p2.proargtypes[0] = 'int4'::regtype AND
p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- Array types should have same typmodin/out as their element types
SELECT p1.oid, p1.typname, p2.oid, p2.typname
FROM pg_type AS p1, pg_type AS p2
WHERE p1.typelem = p2.oid AND NOT
(p1.typmodin = p2.typmodin AND p1.typmodout = p2.typmodout);
oid | typname | oid | typname
-----+---------+-----+---------
(0 rows)
-- Check for bogus typanalyze routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typanalyze = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND
p2.proargtypes[0] = 'internal'::regtype AND
p2.prorettype = 'bool'::regtype AND NOT p2.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- **************** pg_class **************** -- **************** pg_class ****************
-- Look for illegal values in pg_class fields -- Look for illegal values in pg_class fields
SELECT p1.oid, p1.relname SELECT p1.oid, p1.relname

View File

@ -11,6 +11,8 @@ CREATE TYPE widget (
internallength = 24, internallength = 24,
input = widget_in, input = widget_in,
output = widget_out, output = widget_out,
typmod_in = numerictypmodin,
typmod_out = numerictypmodout,
alignment = double alignment = double
); );
@ -98,3 +100,12 @@ CREATE TYPE text_w_default; -- should fail
DROP TYPE default_test_row CASCADE; DROP TYPE default_test_row CASCADE;
DROP TABLE default_test; DROP TABLE default_test;
-- Check usage of typmod with a user-defined type
-- (we have borrowed numeric's typmod functions)
CREATE TEMP TABLE mytab (foo widget(42,13,7)); -- should fail
CREATE TEMP TABLE mytab (foo widget(42,13));
SELECT format_type(atttypid,atttypmod) FROM pg_attribute
WHERE attrelid = 'mytab'::regclass AND attnum > 0;

View File

@ -377,6 +377,14 @@ SELECT ctid, typsend
FROM pg_catalog.pg_type fk FROM pg_catalog.pg_type fk
WHERE typsend != 0 AND WHERE typsend != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typsend); NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typsend);
SELECT ctid, typmodin
FROM pg_catalog.pg_type fk
WHERE typmodin != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typmodin);
SELECT ctid, typmodout
FROM pg_catalog.pg_type fk
WHERE typmodout != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.typmodout);
SELECT ctid, typbasetype SELECT ctid, typbasetype
FROM pg_catalog.pg_type fk FROM pg_catalog.pg_type fk
WHERE typbasetype != 0 AND WHERE typbasetype != 0 AND

View File

@ -163,6 +163,40 @@ FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p2.prorettype = 'bytea'::regtype AND NOT p2.proretset); (p2.prorettype = 'bytea'::regtype AND NOT p2.proretset);
-- Check for bogus typmodin routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typmodin = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND
p2.proargtypes[0] = 'int4[]'::regtype AND
p2.prorettype = 'int4'::regtype AND NOT p2.proretset);
-- Check for bogus typmodout routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typmodout = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND
p2.proargtypes[0] = 'int4'::regtype AND
p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
-- Array types should have same typmodin/out as their element types
SELECT p1.oid, p1.typname, p2.oid, p2.typname
FROM pg_type AS p1, pg_type AS p2
WHERE p1.typelem = p2.oid AND NOT
(p1.typmodin = p2.typmodin AND p1.typmodout = p2.typmodout);
-- Check for bogus typanalyze routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typanalyze = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND
p2.proargtypes[0] = 'internal'::regtype AND
p2.prorettype = 'bool'::regtype AND NOT p2.proretset);
-- **************** pg_class **************** -- **************** pg_class ****************
-- Look for illegal values in pg_class fields -- Look for illegal values in pg_class fields

View File

@ -130,6 +130,8 @@ Join pg_catalog.pg_type.typinput => pg_catalog.pg_proc.oid
Join pg_catalog.pg_type.typoutput => pg_catalog.pg_proc.oid Join pg_catalog.pg_type.typoutput => pg_catalog.pg_proc.oid
Join pg_catalog.pg_type.typreceive => pg_catalog.pg_proc.oid Join pg_catalog.pg_type.typreceive => pg_catalog.pg_proc.oid
Join pg_catalog.pg_type.typsend => pg_catalog.pg_proc.oid Join pg_catalog.pg_type.typsend => pg_catalog.pg_proc.oid
Join pg_catalog.pg_type.typmodin => pg_catalog.pg_proc.oid
Join pg_catalog.pg_type.typmodout => pg_catalog.pg_proc.oid
Join pg_catalog.pg_type.typbasetype => pg_catalog.pg_type.oid Join pg_catalog.pg_type.typbasetype => pg_catalog.pg_type.oid
--------------------------------------------------------------------------- ---------------------------------------------------------------------------