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:
parent
4eac3919dd
commit
52200befd0
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
9
src/backend/utils/cache/catcache.c
vendored
9
src/backend/utils/cache/catcache.c
vendored
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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) */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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_ ));
|
||||
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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'));
|
||||
|
Loading…
x
Reference in New Issue
Block a user