Implement types regprocedure, regoper, regoperator, regclass, regtype

per pghackers discussion.  Add some more typsanity tests, and clean
up some problems exposed thereby (broken or missing array types for
some built-in types).  Also, clean up loose ends from unknownin/out
patch.
This commit is contained in:
Tom Lane 2002-04-25 02:56:56 +00:00
parent 4eac3919dd
commit 52200befd0
28 changed files with 1638 additions and 229 deletions

View File

@ -1,10 +1,10 @@
findoidjoins
This program scans a database, and prints oid fields (also regproc fields)
and the tables they join to. CAUTION: it is ver-r-r-y slow on a large
database, or even a not-so-large one. We don't really recommend running
it on anything but an empty database, such as template1.
This program scans a database, and prints oid fields (also regproc, regclass
and regtype fields) and the tables they join to. CAUTION: it is ver-r-r-y
slow on a large database, or even a not-so-large one. We don't really
recommend running it on anything but an empty database, such as template1.
Uses pgeasy library.

View File

@ -39,7 +39,9 @@ main(int argc, char **argv)
WHERE a.attnum > 0 AND \
relkind = 'r' AND \
(typname = 'oid' OR \
typname = 'regproc') AND \
typname = 'regproc' OR \
typname = 'regclass' OR \
typname = 'regtype') AND \
a.attrelid = c.oid AND \
a.atttypid = t.oid \
ORDER BY 2, a.attnum ; \
@ -77,7 +79,7 @@ main(int argc, char **argv)
DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*)::int4 \
FROM \"%s\" t1, \"%s\" t2 \
WHERE RegprocToOid(t1.\"%s\") = t2.oid ",
WHERE t1.\"%s\"::oid = t2.oid ",
relname, relname2, attname);
doquery(query);

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/bki.sgml,v 1.10 2002/03/22 19:20:02 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/bki.sgml,v 1.11 2002/04/25 02:56:55 tgl Exp $
-->
<chapter id="bki">
@ -122,7 +122,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/bki.sgml,v 1.10 2002/03/22 19:20:02 petere
storage. The following types are allowed: <type>bool</type>,
<type>bytea</type>, <type>char</type> (1 byte),
<type>name</type>, <type>int2</type>, <type>int2vector</type>,
<type>int4</type>, <type>regproc</type>, <type>text</type>,
<type>int4</type>, <type>regproc</type>, <type>regclass</type>,
<type>regtype</type>, <type>text</type>,
<type>oid</type>, <type>tid</type>, <type>xid</type>,
<type>cid</type>, <type>oidvector</type>, <type>smgr</type>,
<type>_int4</type> (array), <type>_aclitem</type> (array).

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.89 2002/04/21 18:58:00 thomas Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.90 2002/04/25 02:56:55 tgl Exp $
-->
<chapter id="datatype">
@ -172,12 +172,6 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.89 2002/04/21 18:58:00 th
<entry>exact numeric with selectable precision</entry>
</row>
<row>
<entry><type>oid</type></entry>
<entry></entry>
<entry>object identifier</entry>
</row>
<row>
<entry><type>path</type></entry>
<entry></entry>
@ -2894,6 +2888,165 @@ SELECT SUBSTRING(b FROM 1 FOR 2) FROM test;
</sect1>
<sect1 id="datatype-oid">
<title>Object Identifier Types</title>
<indexterm zone="datatype-oid">
<primary>object identifier</primary>
<secondary>data type</secondary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>oid</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regproc</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regprocedure</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regoper</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regoperator</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regclass</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regtype</primary>
</indexterm>
<para>
Object identifiers (OIDs) are used internally by
<productname>PostgreSQL</productname> as primary keys for various system
tables. Also, an OID system column is added to user-created tables
(unless <literal>WITHOUT OIDS</> is specified at table creation time).
Type <type>oid</> represents an object identifier. There are also
several aliases for <type>oid</>: <type>regproc</>, <type>regprocedure</>,
<type>regoper</>, <type>regoperator</>, <type>regclass</>,
and <type>regtype</>.
</para>
<para>
The <type>oid</> type is currently implemented as an unsigned four-byte
integer.
Therefore, it is not large enough to provide database-wide uniqueness
in large databases, or even in large individual tables. So, using a
user-created table's OID column as a primary key is discouraged.
OIDs are best used only for references to system tables.
</para>
<para>
The <type>oid</> type itself has few operations beyond comparison
(which is implemented as unsigned comparison). It can be cast to
integer, however, and then manipulated using the standard integer
operators. (Beware of possible signed-versus-unsigned confusion
if you do this.)
</para>
<para>
The <type>oid</> alias types have no operations of their own except
for specialized input and output routines. These routines are able
to accept and display symbolic names for system objects, rather than
the raw numeric value that type <type>oid</> would use. The alias
types allow simplified lookup of OID values for objects: for example,
one may write <literal>'mytable'::regclass</> to get the OID of table
<literal>mytable</>, rather than <literal>SELECT oid FROM pg_class WHERE
relname = 'mytable'</>. (In reality, a much more complicated SELECT would
be needed to deal with selecting the right OID when there are multiple
tables named <literal>mytable</> in different schemas.)
</para>
<para>
<table tocentry="1">
<title>Object Identifier Types</title>
<tgroup cols="4">
<thead>
<row>
<entry>Type name</entry>
<entry>References</entry>
<entry>Description</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry><type>oid</></entry>
<entry>any</entry>
<entry>Numeric object identifier</entry>
<entry>564182</entry>
</row>
<row>
<entry><type>regproc</></entry>
<entry>pg_proc</entry>
<entry>Function name</entry>
<entry>sum</entry>
</row>
<row>
<entry><type>regprocedure</></entry>
<entry>pg_proc</entry>
<entry>Function with argument types</entry>
<entry>sum(int4)</entry>
</row>
<row>
<entry><type>regoper</></entry>
<entry>pg_operator</entry>
<entry>Operator name</entry>
<entry>+</entry>
</row>
<row>
<entry><type>regoperator</></entry>
<entry>pg_operator</entry>
<entry>Operator with argument types</entry>
<entry>*(integer,integer) -(NONE,integer)</entry>
</row>
<row>
<entry><type>regclass</></entry>
<entry>pg_class</entry>
<entry>Relation name</entry>
<entry>pg_type</entry>
</row>
<row>
<entry><type>regtype</></entry>
<entry>pg_type</entry>
<entry>Type name</entry>
<entry>integer</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
All of the alias types accept schema-qualified names, and will
display schema-qualified names on output if the object would not
be found in the current search path without being qualified.
The <type>regproc</> and <type>regoper</> alias types will only
accept input names that are unique (not overloaded), so they are
of limited use; for most uses <type>regprocedure</> or
<type>regoperator</> is more appropriate. For <type>regoperator</>,
unary operators are identified by writing NONE for the unused
operand.
</para>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.125 2002/03/26 19:15:16 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.126 2002/04/25 02:56:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -109,12 +109,14 @@ static struct typinfo Procid[] = {
{"int2vector", INT2VECTOROID, 0, INDEX_MAX_KEYS * 2, F_INT2VECTORIN, F_INT2VECTOROUT},
{"int4", INT4OID, 0, 4, F_INT4IN, F_INT4OUT},
{"regproc", REGPROCOID, 0, 4, F_REGPROCIN, F_REGPROCOUT},
{"regclass", REGCLASSOID, 0, 4, F_REGCLASSIN, F_REGCLASSOUT},
{"regtype", REGTYPEOID, 0, 4, F_REGTYPEIN, F_REGTYPEOUT},
{"text", TEXTOID, 0, -1, F_TEXTIN, F_TEXTOUT},
{"oid", OIDOID, 0, 4, F_OIDIN, F_OIDOUT},
{"tid", TIDOID, 0, 6, F_TIDIN, F_TIDOUT},
{"xid", XIDOID, 0, 4, F_XIDIN, F_XIDOUT},
{"cid", CIDOID, 0, 4, F_CIDIN, F_CIDOUT},
{"oidvector", 30, 0, INDEX_MAX_KEYS * 4, F_OIDVECTORIN, F_OIDVECTOROUT},
{"oidvector", OIDVECTOROID, 0, INDEX_MAX_KEYS * 4, F_OIDVECTORIN, F_OIDVECTOROUT},
{"smgr", 210, 0, 2, F_SMGRIN, F_SMGROUT},
{"_int4", 1007, INT4OID, -1, F_ARRAY_IN, F_ARRAY_OUT},
{"_aclitem", 1034, 1033, -1, F_ARRAY_IN, F_ARRAY_OUT}
@ -600,7 +602,7 @@ DefineAttr(char *name, char *type, int attnum)
attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen;
attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;;
attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;
attrtypes[attnum]->attalign = Ap->am_typ.typalign;
}
else
@ -610,28 +612,37 @@ DefineAttr(char *name, char *type, int attnum)
elog(DEBUG3, "column %s %s", NameStr(attrtypes[attnum]->attname), type);
attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
attlen = attrtypes[attnum]->attlen = Procid[typeoid].len;
attrtypes[attnum]->attstorage = 'p';
/*
* Cheat like mad to fill in these items from the length only.
* This only has to work for types used in the system catalogs...
* This only has to work for types that appear in Procid[].
*/
switch (attlen)
{
case 1:
attrtypes[attnum]->attbyval = true;
attrtypes[attnum]->attstorage = 'p';
attrtypes[attnum]->attalign = 'c';
break;
case 2:
attrtypes[attnum]->attbyval = true;
attrtypes[attnum]->attstorage = 'p';
attrtypes[attnum]->attalign = 's';
break;
case 4:
attrtypes[attnum]->attbyval = true;
attrtypes[attnum]->attstorage = 'p';
attrtypes[attnum]->attalign = 'i';
break;
case -1:
attrtypes[attnum]->attbyval = false;
attrtypes[attnum]->attstorage = 'x';
attrtypes[attnum]->attalign = 'i';
break;
default:
/* TID and fixed-length arrays, such as oidvector */
attrtypes[attnum]->attbyval = false;
attrtypes[attnum]->attstorage = 'p';
attrtypes[attnum]->attalign = 'i';
break;
}
@ -803,6 +814,13 @@ cleanup()
/* ----------------
* gettype
*
* NB: this is really ugly; it will return an integer index into Procid[],
* and not an OID at all, until the first reference to a type not known in
* Procid[]. At that point it will read and cache pg_type in the Typ array,
* and subsequently return a real OID (and set the global pointer Ap to
* point at the found row in Typ). So caller must check whether Typ is
* still NULL to determine what the return value is!
* ----------------
*/
static Oid
@ -827,7 +845,7 @@ gettype(char *type)
}
else
{
for (i = 0; i <= n_types; i++)
for (i = 0; i < n_types; i++)
{
if (strncmp(type, Procid[i].name, NAMEDATALEN) == 0)
return i;

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.11 2002/04/17 20:57:56 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.12 2002/04/25 02:56:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -365,9 +365,12 @@ OpclassnameGetOpcid(Oid amid, const char *opcname)
* Given a possibly-qualified function name and argument count,
* retrieve a list of the possible matches.
*
* If nargs is -1, we return all functions matching the given name,
* regardless of argument count.
*
* We search a single namespace if the function name is qualified, else
* all namespaces in the search path. The return list will never contain
* multiple entries with identical argument types --- in the multiple-
* multiple entries with identical argument lists --- in the multiple-
* namespace case, we arrange for entries in earlier namespaces to mask
* identical entries in later namespaces.
*/
@ -423,11 +426,16 @@ FuncnameGetCandidates(List *names, int nargs)
namespaceId = InvalidOid;
}
/* Search syscache by name and nargs only */
catlist = SearchSysCacheList(PROCNAMENSP, 2,
CStringGetDatum(funcname),
Int16GetDatum(nargs),
0, 0);
/* Search syscache by name and (optionally) nargs only */
if (nargs >= 0)
catlist = SearchSysCacheList(PROCNAMENSP, 2,
CStringGetDatum(funcname),
Int16GetDatum(nargs),
0, 0);
else
catlist = SearchSysCacheList(PROCNAMENSP, 1,
CStringGetDatum(funcname),
0, 0, 0);
for (i = 0; i < catlist->n_members; i++)
{
@ -436,6 +444,8 @@ FuncnameGetCandidates(List *names, int nargs)
int pathpos = 0;
FuncCandidateList newResult;
nargs = procform->pronargs;
if (OidIsValid(namespaceId))
{
/* Consider only procs in specified namespace */
@ -478,7 +488,8 @@ FuncnameGetCandidates(List *names, int nargs)
if (catlist->ordered)
{
if (memcmp(procform->proargtypes, resultList->args,
if (nargs == resultList->nargs &&
memcmp(procform->proargtypes, resultList->args,
nargs * sizeof(Oid)) == 0)
prevResult = resultList;
else
@ -490,7 +501,8 @@ FuncnameGetCandidates(List *names, int nargs)
prevResult;
prevResult = prevResult->next)
{
if (memcmp(procform->proargtypes, prevResult->args,
if (nargs == prevResult->nargs &&
memcmp(procform->proargtypes, prevResult->args,
nargs * sizeof(Oid)) == 0)
break;
}
@ -517,6 +529,7 @@ FuncnameGetCandidates(List *names, int nargs)
+ nargs * sizeof(Oid));
newResult->pathpos = pathpos;
newResult->oid = proctup->t_data->t_oid;
newResult->nargs = nargs;
memcpy(newResult->args, procform->proargtypes, nargs * sizeof(Oid));
newResult->next = resultList;
@ -533,14 +546,17 @@ FuncnameGetCandidates(List *names, int nargs)
* Given a possibly-qualified operator name and operator kind,
* retrieve a list of the possible matches.
*
* If oprkind is '\0', we return all operators matching the given name,
* regardless of arguments.
*
* We search a single namespace if the operator name is qualified, else
* all namespaces in the search path. The return list will never contain
* multiple entries with identical argument types --- in the multiple-
* multiple entries with identical argument lists --- in the multiple-
* namespace case, we arrange for entries in earlier namespaces to mask
* identical entries in later namespaces.
*
* The returned items always have two args[] entries --- one or the other
* will be InvalidOid for a prefix or postfix oprkind.
* will be InvalidOid for a prefix or postfix oprkind. nargs is 2, too.
*/
FuncCandidateList
OpernameGetCandidates(List *names, char oprkind)
@ -606,8 +622,8 @@ OpernameGetCandidates(List *names, char oprkind)
int pathpos = 0;
FuncCandidateList newResult;
/* Ignore operators of wrong kind */
if (operform->oprkind != oprkind)
/* Ignore operators of wrong kind, if specific kind requested */
if (oprkind && operform->oprkind != oprkind)
continue;
if (OidIsValid(namespaceId))
@ -690,6 +706,7 @@ OpernameGetCandidates(List *names, char oprkind)
palloc(sizeof(struct _FuncCandidateList) + sizeof(Oid));
newResult->pathpos = pathpos;
newResult->oid = opertup->t_data->t_oid;
newResult->nargs = 2;
newResult->args[0] = operform->oprleft;
newResult->args[1] = operform->oprright;
newResult->next = resultList;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.66 2002/04/16 23:08:10 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.67 2002/04/25 02:56:55 tgl Exp $
*
* NOTES
* these routines moved here from commands/define.c and somewhat cleaned up.
@ -138,7 +138,7 @@ OperatorGet(const char *operatorName,
ObjectIdGetDatum(operatorNamespace));
if (HeapTupleIsValid(tup))
{
regproc oprcode = ((Form_pg_operator) GETSTRUCT(tup))->oprcode;
RegProcedure oprcode = ((Form_pg_operator) GETSTRUCT(tup))->oprcode;
operatorObjectId = tup->t_data->t_oid;
*defined = RegProcedureIsValid(oprcode);
@ -168,7 +168,7 @@ OperatorLookup(List *operatorName,
bool *defined)
{
Oid operatorObjectId;
regproc oprcode;
RegProcedure oprcode;
operatorObjectId = LookupOperName(operatorName, leftObjectId,
rightObjectId);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.70 2002/04/11 20:00:00 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.71 2002/04/25 02:56:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -81,8 +81,7 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
if (!con->constisnull)
{
/* We know the source constant is really of type 'text' */
char *val = DatumGetCString(DirectFunctionCall1(textout,
char *val = DatumGetCString(DirectFunctionCall1(unknownout,
con->constvalue));
newcon->constvalue = stringTypeDatum(targetType, val, atttypmod);
@ -477,6 +476,11 @@ TypeCategory(Oid inType)
case (OIDOID):
case (REGPROCOID):
case (REGPROCEDUREOID):
case (REGOPEROID):
case (REGOPERATOROID):
case (REGCLASSOID):
case (REGTYPEOID):
case (INT2OID):
case (INT4OID):
case (INT8OID):
@ -540,38 +544,72 @@ TypeCategory(Oid inType)
* to allow for better type extensibility.
*/
#define TypeIsTextGroup(t) \
((t) == TEXTOID || \
(t) == BPCHAROID || \
(t) == VARCHAROID)
/* Notice OidGroup is a subset of Int4GroupA */
#define TypeIsOidGroup(t) \
((t) == OIDOID || \
(t) == REGPROCOID || \
(t) == REGPROCEDUREOID || \
(t) == REGOPEROID || \
(t) == REGOPERATOROID || \
(t) == REGCLASSOID || \
(t) == REGTYPEOID)
/*
* This macro describes hard-coded knowledge of binary compatibility
* for built-in types.
* INT4 is binary-compatible with many types, but we don't want to allow
* implicit coercion directly between, say, OID and AbsTime. So we subdivide
* the categories.
*/
#define IS_BINARY_COMPATIBLE(a,b) \
(((a) == BPCHAROID && (b) == TEXTOID) \
|| ((a) == BPCHAROID && (b) == VARCHAROID) \
|| ((a) == VARCHAROID && (b) == TEXTOID) \
|| ((a) == VARCHAROID && (b) == BPCHAROID) \
|| ((a) == TEXTOID && (b) == BPCHAROID) \
|| ((a) == TEXTOID && (b) == VARCHAROID) \
|| ((a) == OIDOID && (b) == INT4OID) \
|| ((a) == OIDOID && (b) == REGPROCOID) \
|| ((a) == INT4OID && (b) == OIDOID) \
|| ((a) == INT4OID && (b) == REGPROCOID) \
|| ((a) == REGPROCOID && (b) == OIDOID) \
|| ((a) == REGPROCOID && (b) == INT4OID) \
|| ((a) == ABSTIMEOID && (b) == INT4OID) \
|| ((a) == INT4OID && (b) == ABSTIMEOID) \
|| ((a) == RELTIMEOID && (b) == INT4OID) \
|| ((a) == INT4OID && (b) == RELTIMEOID) \
|| ((a) == INETOID && (b) == CIDROID) \
|| ((a) == CIDROID && (b) == INETOID) \
|| ((a) == BITOID && (b) == VARBITOID) \
|| ((a) == VARBITOID && (b) == BITOID))
#define TypeIsInt4GroupA(t) \
((t) == INT4OID || \
TypeIsOidGroup(t))
#define TypeIsInt4GroupB(t) \
((t) == INT4OID || \
(t) == ABSTIMEOID)
#define TypeIsInt4GroupC(t) \
((t) == INT4OID || \
(t) == RELTIMEOID)
#define TypeIsInetGroup(t) \
((t) == INETOID || \
(t) == CIDROID)
#define TypeIsBitGroup(t) \
((t) == BITOID || \
(t) == VARBITOID)
static bool
DirectlyBinaryCompatible(Oid type1, Oid type2)
{
if (type1 == type2)
return true;
if (TypeIsTextGroup(type1) && TypeIsTextGroup(type2))
return true;
if (TypeIsInt4GroupA(type1) && TypeIsInt4GroupA(type2))
return true;
if (TypeIsInt4GroupB(type1) && TypeIsInt4GroupB(type2))
return true;
if (TypeIsInt4GroupC(type1) && TypeIsInt4GroupC(type2))
return true;
if (TypeIsInetGroup(type1) && TypeIsInetGroup(type2))
return true;
if (TypeIsBitGroup(type1) && TypeIsBitGroup(type2))
return true;
return false;
}
bool
IsBinaryCompatible(Oid type1, Oid type2)
{
if (type1 == type2)
return true;
if (IS_BINARY_COMPATIBLE(type1, type2))
if (DirectlyBinaryCompatible(type1, type2))
return true;
/*
* Perhaps the types are domains; if so, look at their base types
@ -580,9 +618,7 @@ IsBinaryCompatible(Oid type1, Oid type2)
type1 = getBaseType(type1);
if (OidIsValid(type2))
type2 = getBaseType(type2);
if (type1 == type2)
return true;
if (IS_BINARY_COMPATIBLE(type1, type2))
if (DirectlyBinaryCompatible(type1, type2))
return true;
return false;
}
@ -627,7 +663,7 @@ PreferredType(CATEGORY category, Oid type)
break;
case (NUMERIC_TYPE):
if (type == OIDOID)
if (TypeIsOidGroup(type))
result = OIDOID;
else if (type == NUMERICOID)
result = NUMERICOID;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.62 2002/04/16 23:08:11 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.63 2002/04/25 02:56:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -424,7 +424,8 @@ make_const(Value *value)
break;
case T_String:
val = DirectFunctionCall1(textin, CStringGetDatum(strVal(value)));
val = DirectFunctionCall1(unknownin,
CStringGetDatum(strVal(value)));
typeid = UNKNOWNOID; /* will be coerced later */
typelen = -1; /* variable len */

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.98 2002/04/19 23:13:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.99 2002/04/25 02:56:55 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@ -123,7 +123,7 @@ static void get_delete_query_def(Query *query, deparse_context *context);
static void get_utility_query_def(Query *query, deparse_context *context);
static void get_basic_select_query(Query *query, deparse_context *context);
static void get_setop_query(Node *setOp, Query *query,
deparse_context *context, bool toplevel);
deparse_context *context);
static void get_rule_sortgroupclause(SortClause *srt, List *tlist,
bool force_colno,
deparse_context *context);
@ -142,7 +142,6 @@ static void get_from_clause_item(Node *jtnode, Query *query,
static void get_opclass_name(Oid opclass, Oid actual_datatype,
StringInfo buf);
static bool tleIsArrayAssign(TargetEntry *tle);
static char *quote_identifier(char *ident);
static char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
#define only_marker(rte) ((rte)->inh ? "" : "ONLY ")
@ -1109,7 +1108,7 @@ get_select_query_def(Query *query, deparse_context *context)
*/
if (query->setOperations)
{
get_setop_query(query->setOperations, query, context, true);
get_setop_query(query->setOperations, query, context);
/* ORDER BY clauses must be simple in this case */
force_colno = true;
}
@ -1266,8 +1265,7 @@ get_basic_select_query(Query *query, deparse_context *context)
}
static void
get_setop_query(Node *setOp, Query *query, deparse_context *context,
bool toplevel)
get_setop_query(Node *setOp, Query *query, deparse_context *context)
{
StringInfo buf = context->buf;
@ -1284,33 +1282,29 @@ get_setop_query(Node *setOp, Query *query, deparse_context *context,
{
SetOperationStmt *op = (SetOperationStmt *) setOp;
/*
* Must suppress parens at top level of a setop tree because of
* grammar limitations...
*/
if (!toplevel)
appendStringInfo(buf, "(");
get_setop_query(op->larg, query, context, false);
appendStringInfo(buf, "((");
get_setop_query(op->larg, query, context);
switch (op->op)
{
case SETOP_UNION:
appendStringInfo(buf, " UNION ");
appendStringInfo(buf, ") UNION ");
break;
case SETOP_INTERSECT:
appendStringInfo(buf, " INTERSECT ");
appendStringInfo(buf, ") INTERSECT ");
break;
case SETOP_EXCEPT:
appendStringInfo(buf, " EXCEPT ");
appendStringInfo(buf, ") EXCEPT ");
break;
default:
elog(ERROR, "get_setop_query: unexpected set op %d",
(int) op->op);
}
if (op->all)
appendStringInfo(buf, "ALL ");
get_setop_query(op->rarg, query, context, false);
if (!toplevel)
appendStringInfo(buf, ")");
appendStringInfo(buf, "ALL (");
else
appendStringInfo(buf, "(");
get_setop_query(op->rarg, query, context);
appendStringInfo(buf, "))");
}
else
{
@ -2585,8 +2579,8 @@ tleIsArrayAssign(TargetEntry *tle)
* space-wasteful but well worth it for notational simplicity.
* ----------
*/
static char *
quote_identifier(char *ident)
const char *
quote_identifier(const char *ident)
{
/*
* Can avoid quoting if ident starts with a lowercase letter and
@ -2603,7 +2597,7 @@ quote_identifier(char *ident)
safe = (ident[0] >= 'a' && ident[0] <= 'z');
if (safe)
{
char *ptr;
const char *ptr;
for (ptr = ident + 1; *ptr; ptr++)
{
@ -2628,7 +2622,7 @@ quote_identifier(char *ident)
* Note: ScanKeywordLookup() does case-insensitive comparison, but
* that's fine, since we already know we have all-lower-case.
*/
if (ScanKeywordLookup(ident) != NULL)
if (ScanKeywordLookup((char *) ident) != NULL)
safe = false;
}
@ -2640,6 +2634,26 @@ quote_identifier(char *ident)
return result;
}
/* ----------
* quote_qualified_identifier - Quote a possibly-qualified identifier
*
* Return a name of the form namespace.ident, or just ident if namespace
* is NULL, quoting each component if necessary. The result is palloc'd.
* ----------
*/
char *
quote_qualified_identifier(const char *namespace,
const char *ident)
{
StringInfoData buf;
initStringInfo(&buf);
if (namespace)
appendStringInfo(&buf, "%s.", quote_identifier(namespace));
appendStringInfo(&buf, "%s", quote_identifier(ident));
return buf.data;
}
/* ----------
* get_relid_attribute_name
* Get an attribute name by its relations Oid and its attnum

View File

@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.109 2002/04/21 19:48:13 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.110 2002/04/25 02:56:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1991,6 +1991,11 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
case NUMERICOID:
case OIDOID:
case REGPROCOID:
case REGPROCEDUREOID:
case REGOPEROID:
case REGOPERATOROID:
case REGCLASSOID:
case REGTYPEOID:
*scaledvalue = convert_numeric_to_scalar(value, valuetypid);
*scaledlobound = convert_numeric_to_scalar(lobound, boundstypid);
*scaledhibound = convert_numeric_to_scalar(hibound, boundstypid);
@ -2088,6 +2093,11 @@ convert_numeric_to_scalar(Datum value, Oid typid)
value));
case OIDOID:
case REGPROCOID:
case REGPROCEDUREOID:
case REGOPEROID:
case REGOPERATOROID:
case REGCLASSOID:
case REGTYPEOID:
/* we can treat OIDs as integers... */
return (double) DatumGetObjectId(value);
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.84 2002/04/24 02:12:53 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.85 2002/04/25 02:56:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -21,6 +21,13 @@
#include "utils/builtins.h"
#include "utils/pg_locale.h"
typedef struct varlena unknown;
#define DatumGetUnknownP(X) ((unknown *) PG_DETOAST_DATUM(X))
#define PG_GETARG_UNKNOWN_P(n) DatumGetUnknownP(PG_GETARG_DATUM(n))
#define PG_RETURN_UNKNOWN_P(x) PG_RETURN_POINTER(x)
static int text_cmp(text *arg1, text *arg2);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.94 2002/04/06 06:59:22 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.95 2002/04/25 02:56:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -136,8 +136,13 @@ GetCCHashFunc(Oid keytype)
return hashint4;
case TEXTOID:
return hashvarlena;
case REGPROCOID:
case OIDOID:
case REGPROCOID:
case REGPROCEDUREOID:
case REGOPEROID:
case REGOPERATOROID:
case REGCLASSOID:
case REGTYPEOID:
return hashoid;
case OIDVECTOROID:
return hashoidvector;

View File

@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.52 2002/04/24 06:17:04 petere Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.53 2002/04/25 02:56:56 tgl Exp $
*/
#include "postgres_fe.h"
#include "describe.h"
@ -361,7 +361,7 @@ objectDescription(const char *object)
/* Operator descriptions (must get comment via associated function) */
"UNION ALL\n"
" SELECT RegprocToOid(o.oprcode) as oid,\n"
" SELECT CAST(o.oprcode AS oid) as oid,\n"
" (SELECT oid FROM pg_class WHERE relname = 'pg_proc') as tableoid,\n"
" CAST(o.oprname AS text) as name, CAST('%s' AS text) as object\n"
" FROM pg_operator o\n"

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: c.h,v 1.118 2002/04/24 02:12:53 momjian Exp $
* $Id: c.h,v 1.119 2002/04/25 02:56:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -361,9 +361,12 @@ typedef double float8;
/* typedef Oid is in postgres_ext.h */
/* unfortunately, both regproc and RegProcedure are used */
/*
* regproc is the type name used in the include/catalog headers, but
* RegProcedure is the preferred name in C code.
*/
typedef Oid regproc;
typedef Oid RegProcedure;
typedef regproc RegProcedure;
typedef uint32 TransactionId;
@ -404,7 +407,6 @@ struct varlena
*/
typedef struct varlena bytea;
typedef struct varlena text;
typedef struct varlena unknown;
typedef struct varlena BpChar; /* blank-padded char, ie SQL char(n) */
typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.125 2002/04/24 05:23:14 momjian Exp $
* $Id: catversion.h,v 1.126 2002/04/25 02:56:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200204241
#define CATALOG_VERSION_NO 200204242
#endif

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: namespace.h,v 1.9 2002/04/17 20:57:56 tgl Exp $
* $Id: namespace.h,v 1.10 2002/04/25 02:56:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -22,13 +22,13 @@
* found by namespace lookup. Each function/operator is identified
* by OID and by argument types; the list must be pruned by type
* resolution rules that are embodied in the parser, not here.
* The number of arguments is assumed to be known a priori.
*/
typedef struct _FuncCandidateList
{
struct _FuncCandidateList *next;
int pathpos; /* for internal use of namespace lookup */
Oid oid; /* the function or operator's OID */
int nargs; /* number of arg types returned */
Oid args[1]; /* arg types --- VARIABLE LENGTH ARRAY */
} *FuncCandidateList; /* VARIABLE LENGTH STRUCT */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_namespace.h,v 1.5 2002/04/21 00:26:43 tgl Exp $
* $Id: pg_namespace.h,v 1.6 2002/04/25 02:56:56 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -72,9 +72,9 @@ DESCR("System catalog namespace");
DATA(insert OID = 99 ( "pg_toast" PGUID "{=}" ));
DESCR("Reserved namespace for TOAST tables");
#define PG_TOAST_NAMESPACE 99
DATA(insert OID = 2071 ( "public" PGUID "{=UC}" ));
DATA(insert OID = 2200 ( "public" PGUID "{=UC}" ));
DESCR("Standard public namespace");
#define PG_PUBLIC_NAMESPACE 2071
#define PG_PUBLIC_NAMESPACE 2200
/*

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_operator.h,v 1.103 2002/04/21 19:48:23 thomas Exp $
* $Id: pg_operator.h,v 1.104 2002/04/25 02:56:56 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -847,6 +847,33 @@ DATA(insert OID = 2066 ( "+" PGNSP PGUID 0 b t f 1114 1186 1114 0 0 0 0 0
DATA(insert OID = 2067 ( "-" PGNSP PGUID 0 b t f 1114 1114 1186 0 0 0 0 0 0 timestamp_mi - - ));
DATA(insert OID = 2068 ( "-" PGNSP PGUID 0 b t f 1114 1186 1114 0 0 0 0 0 0 timestamp_mi_span - - ));
/* array equality operators */
DATA(insert OID = 2222 ( "=" PGNSP PGUID 0 b t f 2207 2207 16 2222 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2223 ( "=" PGNSP PGUID 0 b t f 2208 2208 16 2223 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2224 ( "=" PGNSP PGUID 0 b t f 2209 2209 16 2224 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2225 ( "=" PGNSP PGUID 0 b t f 2210 2210 16 2225 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2226 ( "=" PGNSP PGUID 0 b t f 2211 2211 16 2226 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2227 ( "=" PGNSP PGUID 0 b t f 629 629 16 2227 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2228 ( "=" PGNSP PGUID 0 b t f 651 651 16 2228 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2229 ( "=" PGNSP PGUID 0 b t f 719 719 16 2229 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2230 ( "=" PGNSP PGUID 0 b t f 791 791 16 2230 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2231 ( "=" PGNSP PGUID 0 b t f 1014 1014 16 2231 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2232 ( "=" PGNSP PGUID 0 b t f 1015 1015 16 2232 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2233 ( "=" PGNSP PGUID 0 b t f 1016 1016 16 2233 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2234 ( "=" PGNSP PGUID 0 b t f 1040 1040 16 2234 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2235 ( "=" PGNSP PGUID 0 b t f 1041 1041 16 2235 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2236 ( "=" PGNSP PGUID 0 b t f 1115 1115 16 2236 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2237 ( "=" PGNSP PGUID 0 b t f 1182 1182 16 2237 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2238 ( "=" PGNSP PGUID 0 b t f 1183 1183 16 2238 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2239 ( "=" PGNSP PGUID 0 b t f 1185 1185 16 2239 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2240 ( "=" PGNSP PGUID 0 b t f 1187 1187 16 2240 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2241 ( "=" PGNSP PGUID 0 b t f 1231 1231 16 2241 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2242 ( "=" PGNSP PGUID 0 b t f 1270 1270 16 2242 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2243 ( "=" PGNSP PGUID 0 b t f 1561 1561 16 2243 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2244 ( "=" PGNSP PGUID 0 b t f 1563 1563 16 2244 0 0 0 0 0 array_eq eqsel eqjoinsel ));
DATA(insert OID = 2245 ( "=" PGNSP PGUID 0 b t f 2201 2201 16 2245 0 0 0 0 0 array_eq eqsel eqjoinsel ));
/*
* function prototypes

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.232 2002/04/24 05:22:20 momjian Exp $
* $Id: pg_proc.h,v 1.233 2002/04/25 02:56:56 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@ -1216,8 +1216,6 @@ DESCR("closest point to line on box");
DATA(insert OID = 964 ( lo_unlink PGNSP PGUID 12 f t f t f v 1 23 "26" 100 0 0 100 lo_unlink - _null_ ));
DESCR("large object unlink(delete)");
DATA(insert OID = 972 ( regproctooid PGNSP PGUID 12 f t f t f i 1 26 "24" 100 0 0 100 regproctooid - _null_ ));
DESCR("get oid for regproc");
DATA(insert OID = 973 ( path_inter PGNSP PGUID 12 f t f t f i 2 16 "602 602" 100 0 0 100 path_inter - _null_ ));
DESCR("paths intersect?");
@ -2930,6 +2928,28 @@ DATA(insert OID = 2158 ( stddev PGNSP PGUID 12 t t f f f i 1 701 "701" 100 0
DATA(insert OID = 2159 ( stddev PGNSP PGUID 12 t t f f f i 1 1700 "1700" 100 0 0 100 aggregate_dummy - _null_ ));
DATA(insert OID = 2212 ( regprocedurein PGNSP PGUID 12 f t f t f s 1 2202 "0" 100 0 0 100 regprocedurein - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2213 ( regprocedureout PGNSP PGUID 12 f t f t f s 1 23 "0" 100 0 0 100 regprocedureout - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2214 ( regoperin PGNSP PGUID 12 f t f t f s 1 2203 "0" 100 0 0 100 regoperin - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2215 ( regoperout PGNSP PGUID 12 f t f t f s 1 23 "0" 100 0 0 100 regoperout - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2216 ( regoperatorin PGNSP PGUID 12 f t f t f s 1 2204 "0" 100 0 0 100 regoperatorin - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2217 ( regoperatorout PGNSP PGUID 12 f t f t f s 1 23 "0" 100 0 0 100 regoperatorout - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2218 ( regclassin PGNSP PGUID 12 f t f t f s 1 2205 "0" 100 0 0 100 regclassin - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2219 ( regclassout PGNSP PGUID 12 f t f t f s 1 23 "0" 100 0 0 100 regclassout - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2220 ( regtypein PGNSP PGUID 12 f t f t f s 1 2206 "0" 100 0 0 100 regtypein - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2221 ( regtypeout PGNSP PGUID 12 f t f t f s 1 23 "0" 100 0 0 100 regtypeout - _null_ ));
DESCR("(internal)");
/*
* Symbolic values for provolatile column: these indicate whether the result
* of a function is dependent *only* on the values of its explicit arguments,

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_type.h,v 1.121 2002/04/24 02:12:53 momjian Exp $
* $Id: pg_type.h,v 1.122 2002/04/25 02:56:56 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -274,7 +274,7 @@ DATA(insert OID = 23 ( int4 PGNSP PGUID 4 10 t b t \054 0 0 int4in int4ou
DESCR("-2 billion to 2 billion integer, 4-byte storage");
#define INT4OID 23
DATA(insert OID = 24 ( regproc PGNSP PGUID 4 16 t b t \054 0 0 regprocin regprocout regprocin regprocout i p f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 24 ( regproc PGNSP PGUID 4 -1 t b t \054 0 0 regprocin regprocout regprocin regprocout i p f 0 -1 0 _null_ _null_ ));
DESCR("registered procedure");
#define REGPROCOID 24
@ -444,7 +444,7 @@ DESCR("hh:mm:ss, ANSI SQL time");
DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 47 f b t \054 0 0 timestamp_in timestamp_out timestamp_in timestamp_out d p f 0 -1 0 _null_ _null_ ));
DESCR("date and time");
#define TIMESTAMPOID 1114
DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 -1 f b t \054 0 1114 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1182 ( _date PGNSP PGUID -1 -1 f b t \054 0 1082 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1183 ( _time PGNSP PGUID -1 -1 f b t \054 0 1083 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 47 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_in timestamptz_out d p f 0 -1 0 _null_ _null_ ));
@ -484,8 +484,34 @@ DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 -1 f b t \054 0 0 textin
DESCR("reference cursor (portal name)");
#define REFCURSOROID 1790
/* OIDS 2000 - 2099 */
DATA(insert OID = 2019 ( _refcursor PGNSP PGUID -1 -1 f b t \054 0 1790 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
/* OIDS 2200 - 2299 */
DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 -1 f b t \054 0 1790 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 -1 t b t \054 0 0 regprocedurein regprocedureout regprocedurein regprocedureout i p f 0 -1 0 _null_ _null_ ));
DESCR("registered procedure (with args)");
#define REGPROCEDUREOID 2202
DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 -1 t b t \054 0 0 regoperin regoperout regoperin regoperout i p f 0 -1 0 _null_ _null_ ));
DESCR("registered operator");
#define REGOPEROID 2203
DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 -1 t b t \054 0 0 regoperatorin regoperatorout regoperatorin regoperatorout i p f 0 -1 0 _null_ _null_ ));
DESCR("registered operator (with args)");
#define REGOPERATOROID 2204
DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 -1 t b t \054 0 0 regclassin regclassout regclassin regclassout i p f 0 -1 0 _null_ _null_ ));
DESCR("registered class");
#define REGCLASSOID 2205
DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 -1 t b t \054 0 0 regtypein regtypeout regtypein regtypeout i p f 0 -1 0 _null_ _null_ ));
DESCR("registered type");
#define REGTYPEOID 2206
DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 -1 f b t \054 0 2202 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 -1 f b t \054 0 2203 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 -1 f b t \054 0 2204 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 -1 f b t \054 0 2205 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 -1 f b t \054 0 2206 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
/*

View File

@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: fmgr.h,v 1.20 2002/04/24 02:12:53 momjian Exp $
* $Id: fmgr.h,v 1.21 2002/04/25 02:56:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -185,7 +185,6 @@ extern struct varlena *pg_detoast_datum_slice(struct varlena * datum,
/* DatumGetFoo macros for varlena types will typically look like this: */
#define DatumGetByteaP(X) ((bytea *) PG_DETOAST_DATUM(X))
#define DatumGetTextP(X) ((text *) PG_DETOAST_DATUM(X))
#define DatumGetUnknownP(X) ((unknown *) PG_DETOAST_DATUM(X))
#define DatumGetBpCharP(X) ((BpChar *) PG_DETOAST_DATUM(X))
#define DatumGetVarCharP(X) ((VarChar *) PG_DETOAST_DATUM(X))
/* And we also offer variants that return an OK-to-write copy */
@ -201,7 +200,6 @@ extern struct varlena *pg_detoast_datum_slice(struct varlena * datum,
/* GETARG macros for varlena types will typically look like this: */
#define PG_GETARG_BYTEA_P(n) DatumGetByteaP(PG_GETARG_DATUM(n))
#define PG_GETARG_TEXT_P(n) DatumGetTextP(PG_GETARG_DATUM(n))
#define PG_GETARG_UNKNOWN_P(n) DatumGetUnknownP(PG_GETARG_DATUM(n))
#define PG_GETARG_BPCHAR_P(n) DatumGetBpCharP(PG_GETARG_DATUM(n))
#define PG_GETARG_VARCHAR_P(n) DatumGetVarCharP(PG_GETARG_DATUM(n))
/* And we also offer variants that return an OK-to-write copy */
@ -241,7 +239,6 @@ extern struct varlena *pg_detoast_datum_slice(struct varlena * datum,
/* RETURN macros for other pass-by-ref types will typically look like this: */
#define PG_RETURN_BYTEA_P(x) PG_RETURN_POINTER(x)
#define PG_RETURN_TEXT_P(x) PG_RETURN_POINTER(x)
#define PG_RETURN_UNKNOWN_P(x) PG_RETURN_POINTER(x)
#define PG_RETURN_BPCHAR_P(x) PG_RETURN_POINTER(x)
#define PG_RETURN_VARCHAR_P(x) PG_RETURN_POINTER(x)

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: builtins.h,v 1.178 2002/04/24 02:12:53 momjian Exp $
* $Id: builtins.h,v 1.179 2002/04/25 02:56:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -329,10 +329,16 @@ extern Datum texticregexne(PG_FUNCTION_ARGS);
/* regproc.c */
extern Datum regprocin(PG_FUNCTION_ARGS);
extern Datum regprocout(PG_FUNCTION_ARGS);
extern Datum regproctooid(PG_FUNCTION_ARGS);
/* define macro to replace mixed-case function call - tgl 97/04/27 */
#define RegprocToOid(rp) ((Oid) (rp))
extern Datum regprocedurein(PG_FUNCTION_ARGS);
extern Datum regprocedureout(PG_FUNCTION_ARGS);
extern Datum regoperin(PG_FUNCTION_ARGS);
extern Datum regoperout(PG_FUNCTION_ARGS);
extern Datum regoperatorin(PG_FUNCTION_ARGS);
extern Datum regoperatorout(PG_FUNCTION_ARGS);
extern Datum regclassin(PG_FUNCTION_ARGS);
extern Datum regclassout(PG_FUNCTION_ARGS);
extern Datum regtypein(PG_FUNCTION_ARGS);
extern Datum regtypeout(PG_FUNCTION_ARGS);
/* ruleutils.c */
extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);
@ -349,6 +355,9 @@ extern List *deparse_context_for_plan(int outer_varno, Node *outercontext,
extern Node *deparse_context_for_relation(const char *aliasname, Oid relid);
extern Node *deparse_context_for_subplan(const char *name, List *tlist,
List *rtable);
extern const char *quote_identifier(const char *ident);
extern char *quote_qualified_identifier(const char *namespace,
const char *ident);
/* tid.c */
extern void setLastTid(const ItemPointer tid);

View File

@ -14,11 +14,6 @@
--
-- NB: run this test earlier than the create_operator test, because
-- that test creates some bogus operators...
--
-- NOTE hardwired assumptions about standard types:
-- type bool has OID 16
-- type float8 has OID 701
--
-- **************** pg_proc ****************
-- Look for illegal values in pg_proc fields.
-- NOTE: currently there are a few pg_proc entries that have prorettype = 0.
@ -26,7 +21,7 @@
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9)
p1.pronargs < 0 OR p1.pronargs > 16)
AND p1.proname !~ '^pl[^_]+_call_handler$'
AND p1.proname !~ '^RI_FKey_'
AND p1.proname !~ 'costestimate$'
@ -196,7 +191,7 @@ WHERE p1.proimplicit AND
t.typname = p1.proname) OR
NOT ((p1.pronargs = 1 AND p1.proargtypes[0] != prorettype) OR
(p1.pronargs = 2 AND p1.proargtypes[0] = prorettype AND
p1.proargtypes[1] = 23)));
p1.proargtypes[1] = 'int4'::regtype)));
oid | proname
-----+---------
(0 rows)
@ -263,8 +258,8 @@ WHERE p1.oprnegate = p2.oid AND
(p1.oprkind != p2.oprkind OR
p1.oprleft != p2.oprleft OR
p1.oprright != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oid != p2.oprnegate OR
p1.oid = p2.oid);
oid | oprcode | oid | oprcode
@ -282,8 +277,8 @@ WHERE p1.oprlsortop = p2.oid AND
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprleft != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oprrsortop = 0);
oid | oprcode | oid | oprcode
-----+---------+-----+---------
@ -296,8 +291,8 @@ WHERE p1.oprrsortop = p2.oid AND
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprright != p2.oprleft OR
p1.oprright != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oprlsortop = 0);
oid | oprcode | oid | oprcode
-----+---------+-----+---------
@ -363,8 +358,8 @@ WHERE p1.oprlsortop != p1.oprrsortop AND
SELECT p1.oid, p1.oprname
FROM pg_operator AS p1
WHERE p1.oprcanhash AND NOT
(p1.oprkind = 'b' AND p1.oprresult = 16 AND p1.oprleft = p1.oprright AND
p1.oprname = '=' AND p1.oprcom = p1.oid);
(p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND
p1.oprleft = p1.oprright AND p1.oprname = '=' AND p1.oprcom = p1.oid);
oid | oprname
------+---------
353 | =
@ -448,11 +443,11 @@ WHERE p1.oprcode = p2.oid AND
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprrest = p2.oid AND
(p1.oprresult != 16 OR
p2.prorettype != 701 OR p2.proretset OR
(p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 4 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 23);
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 'int4'::regtype);
oid | oprname | oid | proname
-----+---------+-----+---------
(0 rows)
@ -464,10 +459,10 @@ WHERE p1.oprrest = p2.oid AND
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprjoin = p2.oid AND
(p1.oprkind != 'b' OR p1.oprresult != 16 OR
p2.prorettype != 701 OR p2.proretset OR
(p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 3 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
p2.proargtypes[2] != 0);
oid | oprname | oid | proname
-----+---------+-----+---------
@ -611,7 +606,8 @@ WHERE p2.opcamid = p1.oid AND
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
FROM pg_amop AS p1, pg_operator AS p2
WHERE p1.amopopr = p2.oid AND
(p2.oprkind != 'b' OR p2.oprresult != 16 OR p2.oprleft != p2.oprright);
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
p2.oprleft != p2.oprright);
amopclaid | amopopr | oid | oprname
-----------+---------+-----+---------
(0 rows)

View File

@ -19,7 +19,9 @@ WHERE (p1.typlen <= 0 AND p1.typlen != -1) OR
(p1.typtype != 'b' AND p1.typtype != 'c') OR
NOT p1.typisdefined OR
(p1.typalign != 'c' AND p1.typalign != 's' AND
p1.typalign != 'i' AND p1.typalign != 'd');
p1.typalign != 'i' AND p1.typalign != 'd') OR
(p1.typstorage != 'p' AND p1.typstorage != 'x' AND
p1.typstorage != 'e' AND p1.typstorage != 'm');
oid | typname
-----+---------
(0 rows)
@ -35,6 +37,15 @@ WHERE p1.typbyval AND
-----+---------
(0 rows)
-- Look for "toastable" types that aren't varlena.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typstorage != 'p' AND
(p1.typbyval OR p1.typlen != -1);
oid | typname
-----+---------
(0 rows)
-- Look for complex types that do not have a typrelid entry,
-- or basic types that do.
SELECT p1.oid, p1.typname
@ -45,6 +56,31 @@ WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
-----+---------
(0 rows)
-- Look for basic types that don't have an array type.
-- NOTE: as of 7.3, this check finds SET, smgr, and unknown.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typtype != 'c' AND p1.typname NOT LIKE '\\_%' AND NOT EXISTS
(SELECT 1 FROM pg_type as p2
WHERE p2.typname = ('_' || p1.typname)::name AND
p2.typelem = p1.oid);
oid | typname
-----+---------
32 | SET
210 | smgr
705 | unknown
(3 rows)
-- Look for array types that don't have an equality operator.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typtype != 'c' AND p1.typname LIKE '\\_%' AND NOT EXISTS
(SELECT 1 FROM pg_operator
WHERE oprname = '=' AND oprleft = p1.oid AND oprright = p1.oid);
oid | typname
-----+---------
(0 rows)
-- Conversion routines must be provided except in 'c' entries.
SELECT p1.oid, p1.typname
FROM pg_type as p1
@ -63,7 +99,7 @@ SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typtype = 'b' AND
(p2.pronargs != 1 OR p2.proretset) AND
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 23);
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
@ -89,7 +125,7 @@ SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype = 'b' AND
(p2.pronargs != 1 OR p2.proretset) AND
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 23);
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
@ -154,12 +190,15 @@ WHERE p1.relnatts != (SELECT count(*) FROM pg_attribute AS p2
(0 rows)
-- Cross-check against pg_type entry
-- NOTE: we allow attstorage to be 'plain' even when typstorage is not;
-- this is mainly for toast tables.
SELECT p1.attrelid, p1.attname, p2.oid, p2.typname
FROM pg_attribute AS p1, pg_type AS p2
WHERE p1.atttypid = p2.oid AND
(p1.attlen != p2.typlen OR
p1.attalign != p2.typalign OR
p1.attbyval != p2.typbyval);
p1.attbyval != p2.typbyval OR
(p1.attstorage != p2.typstorage AND p1.attstorage != 'p'));
attrelid | attname | oid | typname
----------+---------+-----+---------
(0 rows)

View File

@ -14,11 +14,6 @@
--
-- NB: run this test earlier than the create_operator test, because
-- that test creates some bogus operators...
--
-- NOTE hardwired assumptions about standard types:
-- type bool has OID 16
-- type float8 has OID 701
--
-- **************** pg_proc ****************
@ -29,7 +24,7 @@
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9)
p1.pronargs < 0 OR p1.pronargs > 16)
AND p1.proname !~ '^pl[^_]+_call_handler$'
AND p1.proname !~ '^RI_FKey_'
AND p1.proname !~ 'costestimate$'
@ -158,7 +153,7 @@ WHERE p1.proimplicit AND
t.typname = p1.proname) OR
NOT ((p1.pronargs = 1 AND p1.proargtypes[0] != prorettype) OR
(p1.pronargs = 2 AND p1.proargtypes[0] = prorettype AND
p1.proargtypes[1] = 23)));
p1.proargtypes[1] = 'int4'::regtype)));
-- **************** pg_operator ****************
@ -216,8 +211,8 @@ WHERE p1.oprnegate = p2.oid AND
(p1.oprkind != p2.oprkind OR
p1.oprleft != p2.oprleft OR
p1.oprright != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oid != p2.oprnegate OR
p1.oid = p2.oid);
@ -233,8 +228,8 @@ WHERE p1.oprlsortop = p2.oid AND
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprleft != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oprrsortop = 0);
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
@ -244,8 +239,8 @@ WHERE p1.oprrsortop = p2.oid AND
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprright != p2.oprleft OR
p1.oprright != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oprlsortop = 0);
-- A mergejoinable = operator must have a commutator (usually itself)
@ -300,8 +295,8 @@ WHERE p1.oprlsortop != p1.oprrsortop AND
SELECT p1.oid, p1.oprname
FROM pg_operator AS p1
WHERE p1.oprcanhash AND NOT
(p1.oprkind = 'b' AND p1.oprresult = 16 AND p1.oprleft = p1.oprright AND
p1.oprname = '=' AND p1.oprcom = p1.oid);
(p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND
p1.oprleft = p1.oprright AND p1.oprname = '=' AND p1.oprcom = p1.oid);
-- In 6.5 we accepted hashable array equality operators when the array element
-- type is hashable. However, what we actually need to make hashjoin work on
@ -372,11 +367,11 @@ WHERE p1.oprcode = p2.oid AND
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprrest = p2.oid AND
(p1.oprresult != 16 OR
p2.prorettype != 701 OR p2.proretset OR
(p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 4 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 23);
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 'int4'::regtype);
-- If oprjoin is set, the operator must be a binary boolean op,
-- and it must link to a proc with the right signature
@ -386,10 +381,10 @@ WHERE p1.oprrest = p2.oid AND
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprjoin = p2.oid AND
(p1.oprkind != 'b' OR p1.oprresult != 16 OR
p2.prorettype != 701 OR p2.proretset OR
(p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 3 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
p2.proargtypes[2] != 0);
-- **************** pg_aggregate ****************
@ -507,7 +502,8 @@ WHERE p2.opcamid = p1.oid AND
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
FROM pg_amop AS p1, pg_operator AS p2
WHERE p1.amopopr = p2.oid AND
(p2.oprkind != 'b' OR p2.oprresult != 16 OR p2.oprleft != p2.oprright);
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
p2.oprleft != p2.oprright);
-- Check that all operators linked to by opclass entries have selectivity
-- estimators. This is not absolutely required, but it seems a reasonable

View File

@ -22,7 +22,9 @@ WHERE (p1.typlen <= 0 AND p1.typlen != -1) OR
(p1.typtype != 'b' AND p1.typtype != 'c') OR
NOT p1.typisdefined OR
(p1.typalign != 'c' AND p1.typalign != 's' AND
p1.typalign != 'i' AND p1.typalign != 'd');
p1.typalign != 'i' AND p1.typalign != 'd') OR
(p1.typstorage != 'p' AND p1.typstorage != 'x' AND
p1.typstorage != 'e' AND p1.typstorage != 'm');
-- Look for "pass by value" types that can't be passed by value.
@ -33,6 +35,13 @@ WHERE p1.typbyval AND
(p1.typlen != 2 OR p1.typalign != 's') AND
(p1.typlen != 4 OR p1.typalign != 'i');
-- Look for "toastable" types that aren't varlena.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typstorage != 'p' AND
(p1.typbyval OR p1.typlen != -1);
-- Look for complex types that do not have a typrelid entry,
-- or basic types that do.
@ -41,6 +50,24 @@ FROM pg_type as p1
WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
(p1.typtype != 'c' AND p1.typrelid != 0);
-- Look for basic types that don't have an array type.
-- NOTE: as of 7.3, this check finds SET, smgr, and unknown.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typtype != 'c' AND p1.typname NOT LIKE '\\_%' AND NOT EXISTS
(SELECT 1 FROM pg_type as p2
WHERE p2.typname = ('_' || p1.typname)::name AND
p2.typelem = p1.oid);
-- Look for array types that don't have an equality operator.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typtype != 'c' AND p1.typname LIKE '\\_%' AND NOT EXISTS
(SELECT 1 FROM pg_operator
WHERE oprname = '=' AND oprleft = p1.oid AND oprright = p1.oid);
-- Conversion routines must be provided except in 'c' entries.
SELECT p1.oid, p1.typname
@ -58,7 +85,7 @@ SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typtype = 'b' AND
(p2.pronargs != 1 OR p2.proretset) AND
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 23);
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
-- Check for bogus typoutput routines
-- The first OR subclause detects bogus non-array cases,
@ -80,7 +107,7 @@ SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype = 'b' AND
(p2.pronargs != 1 OR p2.proretset) AND
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 23);
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
-- Check for bogus typsend routines
-- The first OR subclause detects bogus non-array cases,
@ -132,10 +159,13 @@ WHERE p1.relnatts != (SELECT count(*) FROM pg_attribute AS p2
WHERE p2.attrelid = p1.oid AND p2.attnum > 0);
-- Cross-check against pg_type entry
-- NOTE: we allow attstorage to be 'plain' even when typstorage is not;
-- this is mainly for toast tables.
SELECT p1.attrelid, p1.attname, p2.oid, p2.typname
FROM pg_attribute AS p1, pg_type AS p2
WHERE p1.atttypid = p2.oid AND
(p1.attlen != p2.typlen OR
p1.attalign != p2.typalign OR
p1.attbyval != p2.typbyval);
p1.attbyval != p2.typbyval OR
(p1.attstorage != p2.typstorage AND p1.attstorage != 'p'));