Convert oidvector and int2vector into variable-length arrays. This
change saves a great deal of space in pg_proc and its primary index, and it eliminates the former requirement that INDEX_MAX_KEYS and FUNC_MAX_ARGS have the same value. INDEX_MAX_KEYS is still embedded in the on-disk representation (because it affects index tuple header size), but FUNC_MAX_ARGS is not. I believe it would now be possible to increase FUNC_MAX_ARGS at little cost, but haven't experimented yet. There are still a lot of vestigial references to FUNC_MAX_ARGS, which I will clean up in a separate pass. However, getting rid of it altogether would require changing the FunctionCallInfoData struct, and I'm not sure I want to buy into that.
This commit is contained in:
parent
119191609c
commit
70c9763d48
@ -74,13 +74,13 @@ static HTAB *createConnHash(void);
|
|||||||
static void createNewConnection(const char *name, remoteConn * con);
|
static void createNewConnection(const char *name, remoteConn * con);
|
||||||
static void deleteConnection(const char *name);
|
static void deleteConnection(const char *name);
|
||||||
static char **get_pkey_attnames(Oid relid, int16 *numatts);
|
static char **get_pkey_attnames(Oid relid, int16 *numatts);
|
||||||
static char *get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals);
|
static char *get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals);
|
||||||
static char *get_sql_delete(Oid relid, int16 *pkattnums, int16 pknumatts, char **tgt_pkattvals);
|
static char *get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pkattvals);
|
||||||
static char *get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals);
|
static char *get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals);
|
||||||
static char *quote_literal_cstr(char *rawstr);
|
static char *quote_literal_cstr(char *rawstr);
|
||||||
static char *quote_ident_cstr(char *rawstr);
|
static char *quote_ident_cstr(char *rawstr);
|
||||||
static int16 get_attnum_pk_pos(int16 *pkattnums, int16 pknumatts, int16 key);
|
static int16 get_attnum_pk_pos(int2vector *pkattnums, int16 pknumatts, int16 key);
|
||||||
static HeapTuple get_tuple_of_interest(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals);
|
static HeapTuple get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pkattvals);
|
||||||
static Oid get_relid_from_relname(text *relname_text);
|
static Oid get_relid_from_relname(text *relname_text);
|
||||||
static char *generate_relation_name(Oid relid);
|
static char *generate_relation_name(Oid relid);
|
||||||
|
|
||||||
@ -1094,7 +1094,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
Oid relid;
|
Oid relid;
|
||||||
text *relname_text;
|
text *relname_text;
|
||||||
int16 *pkattnums;
|
int2vector *pkattnums;
|
||||||
int pknumatts_tmp;
|
int pknumatts_tmp;
|
||||||
int16 pknumatts = 0;
|
int16 pknumatts = 0;
|
||||||
char **src_pkattvals;
|
char **src_pkattvals;
|
||||||
@ -1126,7 +1126,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
|||||||
errmsg("relation \"%s\" does not exist",
|
errmsg("relation \"%s\" does not exist",
|
||||||
GET_STR(relname_text))));
|
GET_STR(relname_text))));
|
||||||
|
|
||||||
pkattnums = (int16 *) PG_GETARG_POINTER(1);
|
pkattnums = (int2vector *) PG_GETARG_POINTER(1);
|
||||||
pknumatts_tmp = PG_GETARG_INT32(2);
|
pknumatts_tmp = PG_GETARG_INT32(2);
|
||||||
if (pknumatts_tmp <= SHRT_MAX)
|
if (pknumatts_tmp <= SHRT_MAX)
|
||||||
pknumatts = pknumatts_tmp;
|
pknumatts = pknumatts_tmp;
|
||||||
@ -1246,7 +1246,7 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
Oid relid;
|
Oid relid;
|
||||||
text *relname_text;
|
text *relname_text;
|
||||||
int16 *pkattnums;
|
int2vector *pkattnums;
|
||||||
int pknumatts_tmp;
|
int pknumatts_tmp;
|
||||||
int16 pknumatts = 0;
|
int16 pknumatts = 0;
|
||||||
char **tgt_pkattvals;
|
char **tgt_pkattvals;
|
||||||
@ -1273,7 +1273,7 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
|
|||||||
errmsg("relation \"%s\" does not exist",
|
errmsg("relation \"%s\" does not exist",
|
||||||
GET_STR(relname_text))));
|
GET_STR(relname_text))));
|
||||||
|
|
||||||
pkattnums = (int16 *) PG_GETARG_POINTER(1);
|
pkattnums = (int2vector *) PG_GETARG_POINTER(1);
|
||||||
pknumatts_tmp = PG_GETARG_INT32(2);
|
pknumatts_tmp = PG_GETARG_INT32(2);
|
||||||
if (pknumatts_tmp <= SHRT_MAX)
|
if (pknumatts_tmp <= SHRT_MAX)
|
||||||
pknumatts = pknumatts_tmp;
|
pknumatts = pknumatts_tmp;
|
||||||
@ -1363,7 +1363,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
Oid relid;
|
Oid relid;
|
||||||
text *relname_text;
|
text *relname_text;
|
||||||
int16 *pkattnums;
|
int2vector *pkattnums;
|
||||||
int pknumatts_tmp;
|
int pknumatts_tmp;
|
||||||
int16 pknumatts = 0;
|
int16 pknumatts = 0;
|
||||||
char **src_pkattvals;
|
char **src_pkattvals;
|
||||||
@ -1395,7 +1395,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
|||||||
errmsg("relation \"%s\" does not exist",
|
errmsg("relation \"%s\" does not exist",
|
||||||
GET_STR(relname_text))));
|
GET_STR(relname_text))));
|
||||||
|
|
||||||
pkattnums = (int16 *) PG_GETARG_POINTER(1);
|
pkattnums = (int2vector *) PG_GETARG_POINTER(1);
|
||||||
pknumatts_tmp = PG_GETARG_INT32(2);
|
pknumatts_tmp = PG_GETARG_INT32(2);
|
||||||
if (pknumatts_tmp <= SHRT_MAX)
|
if (pknumatts_tmp <= SHRT_MAX)
|
||||||
pknumatts = pknumatts_tmp;
|
pknumatts = pknumatts_tmp;
|
||||||
@ -1552,16 +1552,13 @@ get_pkey_attnames(Oid relid, int16 *numatts)
|
|||||||
/* we're only interested if it is the primary key */
|
/* we're only interested if it is the primary key */
|
||||||
if (index->indisprimary == TRUE)
|
if (index->indisprimary == TRUE)
|
||||||
{
|
{
|
||||||
i = 0;
|
*numatts = index->indnatts;
|
||||||
while (index->indkey[i++] != 0)
|
|
||||||
(*numatts)++;
|
|
||||||
|
|
||||||
if (*numatts > 0)
|
if (*numatts > 0)
|
||||||
{
|
{
|
||||||
result = (char **) palloc(*numatts * sizeof(char *));
|
result = (char **) palloc(*numatts * sizeof(char *));
|
||||||
|
|
||||||
for (i = 0; i < *numatts; i++)
|
for (i = 0; i < *numatts; i++)
|
||||||
result[i] = SPI_fname(tupdesc, index->indkey[i]);
|
result[i] = SPI_fname(tupdesc, index->indkey.values[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1574,7 +1571,7 @@ get_pkey_attnames(Oid relid, int16 *numatts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals)
|
get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
char *relname;
|
char *relname;
|
||||||
@ -1664,7 +1661,7 @@ get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
get_sql_delete(Oid relid, int16 *pkattnums, int16 pknumatts, char **tgt_pkattvals)
|
get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pkattvals)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
char *relname;
|
char *relname;
|
||||||
@ -1688,7 +1685,7 @@ get_sql_delete(Oid relid, int16 *pkattnums, int16 pknumatts, char **tgt_pkattval
|
|||||||
appendStringInfo(str, "DELETE FROM %s WHERE ", relname);
|
appendStringInfo(str, "DELETE FROM %s WHERE ", relname);
|
||||||
for (i = 0; i < pknumatts; i++)
|
for (i = 0; i < pknumatts; i++)
|
||||||
{
|
{
|
||||||
int16 pkattnum = pkattnums[i];
|
int16 pkattnum = pkattnums->values[i];
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
appendStringInfo(str, " AND ");
|
appendStringInfo(str, " AND ");
|
||||||
@ -1720,7 +1717,7 @@ get_sql_delete(Oid relid, int16 *pkattnums, int16 pknumatts, char **tgt_pkattval
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals)
|
get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
char *relname;
|
char *relname;
|
||||||
@ -1788,7 +1785,7 @@ get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
|
|||||||
|
|
||||||
for (i = 0; i < pknumatts; i++)
|
for (i = 0; i < pknumatts; i++)
|
||||||
{
|
{
|
||||||
int16 pkattnum = pkattnums[i];
|
int16 pkattnum = pkattnums->values[i];
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
appendStringInfo(str, " AND ");
|
appendStringInfo(str, " AND ");
|
||||||
@ -1855,7 +1852,7 @@ quote_ident_cstr(char *rawstr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int16
|
static int16
|
||||||
get_attnum_pk_pos(int16 *pkattnums, int16 pknumatts, int16 key)
|
get_attnum_pk_pos(int2vector *pkattnums, int16 pknumatts, int16 key)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -1863,14 +1860,14 @@ get_attnum_pk_pos(int16 *pkattnums, int16 pknumatts, int16 key)
|
|||||||
* Not likely a long list anyway, so just scan for the value
|
* Not likely a long list anyway, so just scan for the value
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < pknumatts; i++)
|
for (i = 0; i < pknumatts; i++)
|
||||||
if (key == pkattnums[i])
|
if (key == pkattnums->values[i])
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HeapTuple
|
static HeapTuple
|
||||||
get_tuple_of_interest(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals)
|
get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pkattvals)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
char *relname;
|
char *relname;
|
||||||
@ -1907,7 +1904,7 @@ get_tuple_of_interest(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_p
|
|||||||
|
|
||||||
for (i = 0; i < pknumatts; i++)
|
for (i = 0; i < pknumatts; i++)
|
||||||
{
|
{
|
||||||
int16 pkattnum = pkattnums[i];
|
int16 pkattnum = pkattnums->values[i];
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
appendStringInfo(str, " AND ");
|
appendStringInfo(str, " AND ");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* pending.c
|
* pending.c
|
||||||
* $Id: pending.c,v 1.20 2004/09/10 04:31:06 neilc Exp $
|
* $Id: pending.c,v 1.21 2005/03/29 00:16:48 tgl Exp $
|
||||||
* $PostgreSQL: pgsql/contrib/dbmirror/pending.c,v 1.20 2004/09/10 04:31:06 neilc Exp $
|
* $PostgreSQL: pgsql/contrib/dbmirror/pending.c,v 1.21 2005/03/29 00:16:48 tgl Exp $
|
||||||
*
|
*
|
||||||
* This file contains a trigger for Postgresql-7.x to record changes to tables
|
* This file contains a trigger for Postgresql-7.x to record changes to tables
|
||||||
* to a pending table for mirroring.
|
* to a pending table for mirroring.
|
||||||
@ -349,8 +349,8 @@ getPrimaryKey(Oid tblOid)
|
|||||||
resDatum = SPI_getbinval(resTuple, SPI_tuptable->tupdesc, 1, &isNull);
|
resDatum = SPI_getbinval(resTuple, SPI_tuptable->tupdesc, 1, &isNull);
|
||||||
|
|
||||||
tpResultKey = (int2vector *) DatumGetPointer(resDatum);
|
tpResultKey = (int2vector *) DatumGetPointer(resDatum);
|
||||||
resultKey = SPI_palloc(sizeof(int2vector));
|
resultKey = SPI_palloc(VARSIZE(tpResultKey));
|
||||||
memcpy(resultKey, tpResultKey, sizeof(int2vector));
|
memcpy(resultKey, tpResultKey, VARSIZE(tpResultKey));
|
||||||
|
|
||||||
return resultKey;
|
return resultKey;
|
||||||
}
|
}
|
||||||
@ -438,11 +438,8 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc, Oid tableOid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tpPKeys != NULL)
|
if (tpPKeys != NULL)
|
||||||
{
|
|
||||||
debug_msg("dbmirror:packageData have primary keys");
|
debug_msg("dbmirror:packageData have primary keys");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
cpDataBlock = SPI_palloc(BUFFER_SIZE);
|
cpDataBlock = SPI_palloc(BUFFER_SIZE);
|
||||||
iDataBlockSize = BUFFER_SIZE;
|
iDataBlockSize = BUFFER_SIZE;
|
||||||
iUsedDataBlock = 0; /* To account for the null */
|
iUsedDataBlock = 0; /* To account for the null */
|
||||||
@ -462,11 +459,10 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc, Oid tableOid,
|
|||||||
/* Determine if this is a primary key or not. */
|
/* Determine if this is a primary key or not. */
|
||||||
iIsPrimaryKey = 0;
|
iIsPrimaryKey = 0;
|
||||||
for (iPrimaryKeyIndex = 0;
|
for (iPrimaryKeyIndex = 0;
|
||||||
(*tpPKeys)[iPrimaryKeyIndex] != 0;
|
iPrimaryKeyIndex < tpPKeys->dim1;
|
||||||
iPrimaryKeyIndex++)
|
iPrimaryKeyIndex++)
|
||||||
{
|
{
|
||||||
if ((*tpPKeys)[iPrimaryKeyIndex]
|
if (tpPKeys->values[iPrimaryKeyIndex] == iColumnCounter)
|
||||||
== iColumnCounter)
|
|
||||||
{
|
{
|
||||||
iIsPrimaryKey = 1;
|
iIsPrimaryKey = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.97 2005/03/27 23:52:51 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.98 2005/03/29 00:16:49 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="catalogs">
|
<chapter id="catalogs">
|
||||||
@ -2007,32 +2007,6 @@
|
|||||||
<entry>The OID of the <structname>pg_class</> entry for the table this index is for</entry>
|
<entry>The OID of the <structname>pg_class</> entry for the table this index is for</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry><structfield>indkey</structfield></entry>
|
|
||||||
<entry><type>int2vector</type></entry>
|
|
||||||
<entry><literal><link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.attnum</literal></entry>
|
|
||||||
<entry>
|
|
||||||
This is an array of <structfield>indnatts</structfield> (up to
|
|
||||||
<symbol>INDEX_MAX_KEYS</symbol>) values that indicate which
|
|
||||||
table columns this index indexes. For example a value of
|
|
||||||
<literal>1 3</literal> would mean that the first and the third table
|
|
||||||
columns make up the index key. A zero in this array indicates that the
|
|
||||||
corresponding index attribute is an expression over the table columns,
|
|
||||||
rather than a simple column reference.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry><structfield>indclass</structfield></entry>
|
|
||||||
<entry><type>oidvector</type></entry>
|
|
||||||
<entry><literal><link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.oid</literal></entry>
|
|
||||||
<entry>
|
|
||||||
For each column in the index key this contains the OID of
|
|
||||||
the operator class to use. See
|
|
||||||
<structname>pg_opclass</structname> for details.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><structfield>indnatts</structfield></entry>
|
<entry><structfield>indnatts</structfield></entry>
|
||||||
<entry><type>int2</type></entry>
|
<entry><type>int2</type></entry>
|
||||||
@ -2063,6 +2037,31 @@
|
|||||||
<entry>If true, the table was last clustered on this index.</entry>
|
<entry>If true, the table was last clustered on this index.</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><structfield>indkey</structfield></entry>
|
||||||
|
<entry><type>int2vector</type></entry>
|
||||||
|
<entry><literal><link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.attnum</literal></entry>
|
||||||
|
<entry>
|
||||||
|
This is an array of <structfield>indnatts</structfield> values that
|
||||||
|
indicate which table columns this index indexes. For example a value
|
||||||
|
of <literal>1 3</literal> would mean that the first and the third table
|
||||||
|
columns make up the index key. A zero in this array indicates that the
|
||||||
|
corresponding index attribute is an expression over the table columns,
|
||||||
|
rather than a simple column reference.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><structfield>indclass</structfield></entry>
|
||||||
|
<entry><type>oidvector</type></entry>
|
||||||
|
<entry><literal><link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.oid</literal></entry>
|
||||||
|
<entry>
|
||||||
|
For each column in the index key this contains the OID of
|
||||||
|
the operator class to use. See
|
||||||
|
<structname>pg_opclass</structname> for details.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><structfield>indexprs</structfield></entry>
|
<entry><structfield>indexprs</structfield></entry>
|
||||||
<entry><type>text</type></entry>
|
<entry><type>text</type></entry>
|
||||||
@ -3637,7 +3636,7 @@
|
|||||||
(<structfield>typlen</structfield> = -1),
|
(<structfield>typlen</structfield> = -1),
|
||||||
but some fixed-length (<structfield>typlen</structfield> > 0) types
|
but some fixed-length (<structfield>typlen</structfield> > 0) types
|
||||||
also have nonzero <structfield>typelem</structfield>, for example
|
also have nonzero <structfield>typelem</structfield>, for example
|
||||||
<type>name</type> and <type>oidvector</type>.
|
<type>name</type> and <type>point</type>.
|
||||||
If a fixed-length type has a <structfield>typelem</structfield> then
|
If a fixed-length type has a <structfield>typelem</structfield> then
|
||||||
its internal representation must be some number of values of the
|
its internal representation must be some number of values of the
|
||||||
<structfield>typelem</structfield> data type with no other data.
|
<structfield>typelem</structfield> data type with no other data.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.41 2005/01/22 22:56:36 momjian Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.42 2005/03/29 00:16:49 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="triggers">
|
<chapter id="triggers">
|
||||||
@ -453,7 +453,8 @@ typedef struct Trigger
|
|||||||
bool tgdeferrable;
|
bool tgdeferrable;
|
||||||
bool tginitdeferred;
|
bool tginitdeferred;
|
||||||
int16 tgnargs;
|
int16 tgnargs;
|
||||||
int16 tgattr[FUNC_MAX_ARGS];
|
int16 tgnattr;
|
||||||
|
int16 *tgattr;
|
||||||
char **tgargs;
|
char **tgargs;
|
||||||
} Trigger;
|
} Trigger;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/hash/hashfunc.c,v 1.42 2004/12/31 21:59:13 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/access/hash/hashfunc.c,v 1.43 2005/03/29 00:16:50 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* These functions are stored in pg_amproc. For each operator class
|
* These functions are stored in pg_amproc. For each operator class
|
||||||
@ -107,17 +107,17 @@ hashfloat8(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
hashoidvector(PG_FUNCTION_ARGS)
|
hashoidvector(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *key = (Oid *) PG_GETARG_POINTER(0);
|
oidvector *key = (oidvector *) PG_GETARG_POINTER(0);
|
||||||
|
|
||||||
return hash_any((unsigned char *) key, INDEX_MAX_KEYS * sizeof(Oid));
|
return hash_any((unsigned char *) key->values, key->dim1 * sizeof(Oid));
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
hashint2vector(PG_FUNCTION_ARGS)
|
hashint2vector(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int16 *key = (int16 *) PG_GETARG_POINTER(0);
|
int2vector *key = (int2vector *) PG_GETARG_POINTER(0);
|
||||||
|
|
||||||
return hash_any((unsigned char *) key, INDEX_MAX_KEYS * sizeof(int16));
|
return hash_any((unsigned char *) key->values, key->dim1 * sizeof(int2));
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.45 2005/03/27 23:52:59 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.46 2005/03/29 00:16:51 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* many of the old access method routines have been turned into
|
* many of the old access method routines have been turned into
|
||||||
@ -219,7 +219,7 @@ systable_beginscan(Relation heapRelation,
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < nkeys; i++)
|
for (i = 0; i < nkeys; i++)
|
||||||
{
|
{
|
||||||
Assert(key[i].sk_attno == irel->rd_index->indkey[i]);
|
Assert(key[i].sk_attno == irel->rd_index->indkey.values[i]);
|
||||||
key[i].sk_attno = i + 1;
|
key[i].sk_attno = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.50 2004/12/31 21:59:22 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.51 2005/03/29 00:16:52 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -198,15 +198,19 @@ btoidcmp(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
btoidvectorcmp(PG_FUNCTION_ARGS)
|
btoidvectorcmp(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *a = (Oid *) PG_GETARG_POINTER(0);
|
oidvector *a = (oidvector *) PG_GETARG_POINTER(0);
|
||||||
Oid *b = (Oid *) PG_GETARG_POINTER(1);
|
oidvector *b = (oidvector *) PG_GETARG_POINTER(1);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
/* We arbitrarily choose to sort first by vector length */
|
||||||
|
if (a->dim1 != b->dim1)
|
||||||
|
PG_RETURN_INT32(a->dim1 - b->dim1);
|
||||||
|
|
||||||
|
for (i = 0; i < a->dim1; i++)
|
||||||
{
|
{
|
||||||
if (a[i] != b[i])
|
if (a->values[i] != b->values[i])
|
||||||
{
|
{
|
||||||
if (a[i] > b[i])
|
if (a->values[i] > b->values[i])
|
||||||
PG_RETURN_INT32(1);
|
PG_RETURN_INT32(1);
|
||||||
else
|
else
|
||||||
PG_RETURN_INT32(-1);
|
PG_RETURN_INT32(-1);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.90 2004/12/31 21:59:22 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.91 2005/03/29 00:16:52 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -684,7 +684,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
{
|
{
|
||||||
RegProcedure cmp_proc;
|
RegProcedure cmp_proc;
|
||||||
|
|
||||||
cmp_proc = get_opclass_proc(rel->rd_index->indclass[i],
|
cmp_proc = get_opclass_proc(rel->rd_indclass->values[i],
|
||||||
cur->sk_subtype,
|
cur->sk_subtype,
|
||||||
BTORDER_PROC);
|
BTORDER_PROC);
|
||||||
ScanKeyEntryInitialize(scankeys + i,
|
ScanKeyEntryInitialize(scankeys + i,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/rtree/rtscan.c,v 1.57 2005/01/18 23:25:48 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/access/rtree/rtscan.c,v 1.58 2005/03/29 00:16:53 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -135,7 +135,7 @@ rtrescan(PG_FUNCTION_ARGS)
|
|||||||
Oid int_oper;
|
Oid int_oper;
|
||||||
RegProcedure int_proc;
|
RegProcedure int_proc;
|
||||||
|
|
||||||
opclass = s->indexRelation->rd_index->indclass[attno - 1];
|
opclass = s->indexRelation->rd_indclass->values[attno - 1];
|
||||||
int_strategy = RTMapToInternalOperator(s->keyData[i].sk_strategy);
|
int_strategy = RTMapToInternalOperator(s->keyData[i].sk_strategy);
|
||||||
int_oper = get_opclass_member(opclass,
|
int_oper = get_opclass_member(opclass,
|
||||||
s->keyData[i].sk_subtype,
|
s->keyData[i].sk_subtype,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.199 2005/02/20 02:21:31 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.200 2005/03/29 00:16:54 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -139,9 +139,9 @@ static const struct typinfo TypInfo[] = {
|
|||||||
F_XIDIN, F_XIDOUT},
|
F_XIDIN, F_XIDOUT},
|
||||||
{"cid", CIDOID, 0, 4, true, 'i', 'p',
|
{"cid", CIDOID, 0, 4, true, 'i', 'p',
|
||||||
F_CIDIN, F_CIDOUT},
|
F_CIDIN, F_CIDOUT},
|
||||||
{"int2vector", INT2VECTOROID, INT2OID, INDEX_MAX_KEYS * 2, false, 's', 'p',
|
{"int2vector", INT2VECTOROID, INT2OID, -1, false, 'i', 'p',
|
||||||
F_INT2VECTORIN, F_INT2VECTOROUT},
|
F_INT2VECTORIN, F_INT2VECTOROUT},
|
||||||
{"oidvector", OIDVECTOROID, OIDOID, INDEX_MAX_KEYS * 4, false, 'i', 'p',
|
{"oidvector", OIDVECTOROID, OIDOID, -1, false, 'i', 'p',
|
||||||
F_OIDVECTORIN, F_OIDVECTOROUT},
|
F_OIDVECTORIN, F_OIDVECTOROUT},
|
||||||
{"_int4", INT4ARRAYOID, INT4OID, -1, false, 'i', 'x',
|
{"_int4", INT4ARRAYOID, INT4OID, -1, false, 'i', 'x',
|
||||||
F_ARRAY_IN, F_ARRAY_OUT},
|
F_ARRAY_IN, F_ARRAY_OUT},
|
||||||
@ -667,7 +667,6 @@ closerel(char *name)
|
|||||||
void
|
void
|
||||||
DefineAttr(char *name, char *type, int attnum)
|
DefineAttr(char *name, char *type, int attnum)
|
||||||
{
|
{
|
||||||
int attlen;
|
|
||||||
Oid typeoid;
|
Oid typeoid;
|
||||||
|
|
||||||
if (boot_reldesc != NULL)
|
if (boot_reldesc != NULL)
|
||||||
@ -689,7 +688,7 @@ DefineAttr(char *name, char *type, int attnum)
|
|||||||
if (Typ != NULL)
|
if (Typ != NULL)
|
||||||
{
|
{
|
||||||
attrtypes[attnum]->atttypid = Ap->am_oid;
|
attrtypes[attnum]->atttypid = Ap->am_oid;
|
||||||
attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen;
|
attrtypes[attnum]->attlen = Ap->am_typ.typlen;
|
||||||
attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
|
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;
|
attrtypes[attnum]->attalign = Ap->am_typ.typalign;
|
||||||
@ -702,12 +701,13 @@ DefineAttr(char *name, char *type, int attnum)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
attrtypes[attnum]->atttypid = TypInfo[typeoid].oid;
|
attrtypes[attnum]->atttypid = TypInfo[typeoid].oid;
|
||||||
attlen = attrtypes[attnum]->attlen = TypInfo[typeoid].len;
|
attrtypes[attnum]->attlen = TypInfo[typeoid].len;
|
||||||
attrtypes[attnum]->attbyval = TypInfo[typeoid].byval;
|
attrtypes[attnum]->attbyval = TypInfo[typeoid].byval;
|
||||||
attrtypes[attnum]->attstorage = TypInfo[typeoid].storage;
|
attrtypes[attnum]->attstorage = TypInfo[typeoid].storage;
|
||||||
attrtypes[attnum]->attalign = TypInfo[typeoid].align;
|
attrtypes[attnum]->attalign = TypInfo[typeoid].align;
|
||||||
/* if an array type, assume 1-dimensional attribute */
|
/* if an array type, assume 1-dimensional attribute */
|
||||||
if (TypInfo[typeoid].elem != InvalidOid && attlen < 0)
|
if (TypInfo[typeoid].elem != InvalidOid &&
|
||||||
|
attrtypes[attnum]->attlen < 0)
|
||||||
attrtypes[attnum]->attndims = 1;
|
attrtypes[attnum]->attndims = 1;
|
||||||
else
|
else
|
||||||
attrtypes[attnum]->attndims = 0;
|
attrtypes[attnum]->attndims = 0;
|
||||||
@ -722,14 +722,22 @@ DefineAttr(char *name, char *type, int attnum)
|
|||||||
* Mark as "not null" if type is fixed-width and prior columns are
|
* Mark as "not null" if type is fixed-width and prior columns are
|
||||||
* too. This corresponds to case where column can be accessed directly
|
* too. This corresponds to case where column can be accessed directly
|
||||||
* via C struct declaration.
|
* via C struct declaration.
|
||||||
|
*
|
||||||
|
* oidvector and int2vector are also treated as not-nullable, even
|
||||||
|
* though they are no longer fixed-width.
|
||||||
*/
|
*/
|
||||||
if (attlen > 0)
|
#define MARKNOTNULL(att) \
|
||||||
|
((att)->attlen > 0 || \
|
||||||
|
(att)->atttypid == OIDVECTOROID || \
|
||||||
|
(att)->atttypid == INT2VECTOROID)
|
||||||
|
|
||||||
|
if (MARKNOTNULL(attrtypes[attnum]))
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < attnum; i++)
|
for (i = 0; i < attnum; i++)
|
||||||
{
|
{
|
||||||
if (attrtypes[i]->attlen <= 0)
|
if (!MARKNOTNULL(attrtypes[i]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == attnum)
|
if (i == attnum)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.32 2004/01/04 05:57:21 tgl Exp $
|
# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.33 2005/03/29 00:16:55 tgl Exp $
|
||||||
#
|
#
|
||||||
# NOTES
|
# NOTES
|
||||||
# non-essential whitespace is removed from the generated file.
|
# non-essential whitespace is removed from the generated file.
|
||||||
@ -113,15 +113,6 @@ for dir in $INCLUDE_DIRS; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Get INDEX_MAX_KEYS from pg_config_manual.h
|
|
||||||
# (who needs consistency?)
|
|
||||||
for dir in $INCLUDE_DIRS; do
|
|
||||||
if [ -f "$dir/pg_config_manual.h" ]; then
|
|
||||||
INDEXMAXKEYS=`grep '^#define[ ]*INDEX_MAX_KEYS' $dir/pg_config_manual.h | $AWK '{ print $3 }'`
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h
|
# Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h
|
||||||
for dir in $INCLUDE_DIRS; do
|
for dir in $INCLUDE_DIRS; do
|
||||||
if [ -f "$dir/catalog/pg_namespace.h" ]; then
|
if [ -f "$dir/catalog/pg_namespace.h" ]; then
|
||||||
@ -139,14 +130,6 @@ for dir in $INCLUDE_DIRS; do
|
|||||||
done
|
done
|
||||||
export BKIOBJECTID
|
export BKIOBJECTID
|
||||||
|
|
||||||
# NOTE: we assume here that FUNC_MAX_ARGS has the same value as
|
|
||||||
# INDEX_MAX_KEYS, and don't read it separately from
|
|
||||||
# pg_config_manual.h. This is OK because both of them must be equal
|
|
||||||
# to the length of oidvector.
|
|
||||||
|
|
||||||
INDEXMAXKEYS2=`expr $INDEXMAXKEYS '*' 2` || exit
|
|
||||||
INDEXMAXKEYS4=`expr $INDEXMAXKEYS '*' 4` || exit
|
|
||||||
|
|
||||||
touch ${OUTPUT_PREFIX}.description.$$
|
touch ${OUTPUT_PREFIX}.description.$$
|
||||||
|
|
||||||
# ----------------
|
# ----------------
|
||||||
@ -181,12 +164,6 @@ sed -e "s/;[ ]*$//g" \
|
|||||||
-e "s/PGUID/1/g" \
|
-e "s/PGUID/1/g" \
|
||||||
-e "s/NAMEDATALEN/$NAMEDATALEN/g" \
|
-e "s/NAMEDATALEN/$NAMEDATALEN/g" \
|
||||||
-e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
|
-e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
|
||||||
-e "s/INDEX_MAX_KEYS\*2/$INDEXMAXKEYS2/g" \
|
|
||||||
-e "s/INDEX_MAX_KEYS\*4/$INDEXMAXKEYS4/g" \
|
|
||||||
-e "s/INDEX_MAX_KEYS/$INDEXMAXKEYS/g" \
|
|
||||||
-e "s/FUNC_MAX_ARGS\*2/$INDEXMAXKEYS2/g" \
|
|
||||||
-e "s/FUNC_MAX_ARGS\*4/$INDEXMAXKEYS4/g" \
|
|
||||||
-e "s/FUNC_MAX_ARGS/$INDEXMAXKEYS/g" \
|
|
||||||
| $AWK '
|
| $AWK '
|
||||||
# ----------------
|
# ----------------
|
||||||
# now use awk to process remaining .h file..
|
# now use awk to process remaining .h file..
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.249 2005/03/21 01:24:01 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.250 2005/03/29 00:16:55 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -347,8 +347,8 @@ UpdateIndexRelation(Oid indexoid,
|
|||||||
Oid *classOids,
|
Oid *classOids,
|
||||||
bool primary)
|
bool primary)
|
||||||
{
|
{
|
||||||
int16 indkey[INDEX_MAX_KEYS];
|
int2vector *indkey;
|
||||||
Oid indclass[INDEX_MAX_KEYS];
|
oidvector *indclass;
|
||||||
Datum exprsDatum;
|
Datum exprsDatum;
|
||||||
Datum predDatum;
|
Datum predDatum;
|
||||||
Datum values[Natts_pg_index];
|
Datum values[Natts_pg_index];
|
||||||
@ -358,15 +358,13 @@ UpdateIndexRelation(Oid indexoid,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the index key and opclass info into zero-filled vectors
|
* Copy the index key and opclass info into arrays (should we make the
|
||||||
|
* caller pass them like this to start with?)
|
||||||
*/
|
*/
|
||||||
MemSet(indkey, 0, sizeof(indkey));
|
indkey = buildint2vector(NULL, indexInfo->ii_NumIndexAttrs);
|
||||||
MemSet(indclass, 0, sizeof(indclass));
|
indclass = buildoidvector(classOids, indexInfo->ii_NumIndexAttrs);
|
||||||
for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
|
for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
|
||||||
{
|
indkey->values[i] = indexInfo->ii_KeyAttrNumbers[i];
|
||||||
indkey[i] = indexInfo->ii_KeyAttrNumbers[i];
|
|
||||||
indclass[i] = classOids[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert the index expressions (if any) to a text datum
|
* Convert the index expressions (if any) to a text datum
|
||||||
@ -411,12 +409,12 @@ UpdateIndexRelation(Oid indexoid,
|
|||||||
|
|
||||||
values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
|
values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
|
||||||
values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
|
values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
|
||||||
values[Anum_pg_index_indkey - 1] = PointerGetDatum(indkey);
|
|
||||||
values[Anum_pg_index_indclass - 1] = PointerGetDatum(indclass);
|
|
||||||
values[Anum_pg_index_indnatts - 1] = Int16GetDatum(indexInfo->ii_NumIndexAttrs);
|
values[Anum_pg_index_indnatts - 1] = Int16GetDatum(indexInfo->ii_NumIndexAttrs);
|
||||||
values[Anum_pg_index_indisunique - 1] = BoolGetDatum(indexInfo->ii_Unique);
|
values[Anum_pg_index_indisunique - 1] = BoolGetDatum(indexInfo->ii_Unique);
|
||||||
values[Anum_pg_index_indisprimary - 1] = BoolGetDatum(primary);
|
values[Anum_pg_index_indisprimary - 1] = BoolGetDatum(primary);
|
||||||
values[Anum_pg_index_indisclustered - 1] = BoolGetDatum(false);
|
values[Anum_pg_index_indisclustered - 1] = BoolGetDatum(false);
|
||||||
|
values[Anum_pg_index_indkey - 1] = PointerGetDatum(indkey);
|
||||||
|
values[Anum_pg_index_indclass - 1] = PointerGetDatum(indclass);
|
||||||
values[Anum_pg_index_indexprs - 1] = exprsDatum;
|
values[Anum_pg_index_indexprs - 1] = exprsDatum;
|
||||||
if (exprsDatum == (Datum) 0)
|
if (exprsDatum == (Datum) 0)
|
||||||
nulls[Anum_pg_index_indexprs - 1] = 'n';
|
nulls[Anum_pg_index_indexprs - 1] = 'n';
|
||||||
@ -871,7 +869,7 @@ BuildIndexInfo(Relation index)
|
|||||||
numKeys, RelationGetRelid(index));
|
numKeys, RelationGetRelid(index));
|
||||||
ii->ii_NumIndexAttrs = numKeys;
|
ii->ii_NumIndexAttrs = numKeys;
|
||||||
for (i = 0; i < numKeys; i++)
|
for (i = 0; i < numKeys; i++)
|
||||||
ii->ii_KeyAttrNumbers[i] = indexStruct->indkey[i];
|
ii->ii_KeyAttrNumbers[i] = indexStruct->indkey.values[i];
|
||||||
|
|
||||||
/* fetch any expressions needed for expressional indexes */
|
/* fetch any expressions needed for expressional indexes */
|
||||||
ii->ii_Expressions = RelationGetIndexExpressions(index);
|
ii->ii_Expressions = RelationGetIndexExpressions(index);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.26 2005/01/01 20:44:14 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.27 2005/03/29 00:16:56 tgl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -30,13 +30,22 @@ SET search_path TO information_schema, public;
|
|||||||
* A few supporting functions first ...
|
* A few supporting functions first ...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This returns the integers from 1 to INDEX_MAX_KEYS/FUNC_MAX_ARGS */
|
/* Expand an oidvector or smallint[] into a set with integers 1..N */
|
||||||
CREATE FUNCTION _pg_keypositions() RETURNS SETOF integer
|
CREATE TYPE _pg_expandoidvector_type AS (o oid, n int);
|
||||||
LANGUAGE sql
|
|
||||||
IMMUTABLE
|
CREATE FUNCTION _pg_expandoidvector(oidvector)
|
||||||
AS 'select g.s
|
RETURNS SETOF _pg_expandoidvector_type
|
||||||
from generate_series(1,current_setting(''max_index_keys'')::int,1)
|
LANGUAGE sql STRICT IMMUTABLE
|
||||||
as g(s)';
|
AS 'select $1[s], s+1
|
||||||
|
from generate_series(0,array_upper($1,1),1) as g(s)';
|
||||||
|
|
||||||
|
CREATE TYPE _pg_expandsmallint_type AS (i smallint, n int);
|
||||||
|
|
||||||
|
CREATE FUNCTION _pg_expandsmallint(smallint[])
|
||||||
|
RETURNS SETOF _pg_expandsmallint_type
|
||||||
|
LANGUAGE sql STRICT IMMUTABLE
|
||||||
|
AS 'select $1[s], s
|
||||||
|
from generate_series(1,array_upper($1,1),1) as g(s)';
|
||||||
|
|
||||||
CREATE FUNCTION _pg_keyissubset(smallint[], smallint[]) RETURNS boolean
|
CREATE FUNCTION _pg_keyissubset(smallint[], smallint[]) RETURNS boolean
|
||||||
LANGUAGE sql
|
LANGUAGE sql
|
||||||
@ -501,12 +510,12 @@ CREATE VIEW constraint_column_usage AS
|
|||||||
/* unique/primary key/foreign key constraints */
|
/* unique/primary key/foreign key constraints */
|
||||||
SELECT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname
|
SELECT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname
|
||||||
FROM pg_namespace nr, pg_class r, pg_attribute a, pg_namespace nc,
|
FROM pg_namespace nr, pg_class r, pg_attribute a, pg_namespace nc,
|
||||||
pg_constraint c, _pg_keypositions() AS pos(n)
|
pg_constraint c
|
||||||
WHERE nr.oid = r.relnamespace
|
WHERE nr.oid = r.relnamespace
|
||||||
AND r.oid = a.attrelid
|
AND r.oid = a.attrelid
|
||||||
AND nc.oid = c.connamespace
|
AND nc.oid = c.connamespace
|
||||||
AND (CASE WHEN c.contype = 'f' THEN r.oid = c.confrelid AND c.confkey[pos.n] = a.attnum
|
AND (CASE WHEN c.contype = 'f' THEN r.oid = c.confrelid AND a.attnum = ANY (c.confkey)
|
||||||
ELSE r.oid = c.conrelid AND c.conkey[pos.n] = a.attnum END)
|
ELSE r.oid = c.conrelid AND a.attnum = ANY (c.conkey) END)
|
||||||
AND NOT a.attisdropped
|
AND NOT a.attisdropped
|
||||||
AND c.contype IN ('p', 'u', 'f')
|
AND c.contype IN ('p', 'u', 'f')
|
||||||
AND r.relkind = 'r'
|
AND r.relkind = 'r'
|
||||||
@ -707,26 +716,30 @@ GRANT SELECT ON enabled_roles TO PUBLIC;
|
|||||||
|
|
||||||
CREATE VIEW key_column_usage AS
|
CREATE VIEW key_column_usage AS
|
||||||
SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
|
SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
|
||||||
CAST(nc.nspname AS sql_identifier) AS constraint_schema,
|
CAST(nc_nspname AS sql_identifier) AS constraint_schema,
|
||||||
CAST(c.conname AS sql_identifier) AS constraint_name,
|
CAST(conname AS sql_identifier) AS constraint_name,
|
||||||
CAST(current_database() AS sql_identifier) AS table_catalog,
|
CAST(current_database() AS sql_identifier) AS table_catalog,
|
||||||
CAST(nr.nspname AS sql_identifier) AS table_schema,
|
CAST(nr_nspname AS sql_identifier) AS table_schema,
|
||||||
CAST(r.relname AS sql_identifier) AS table_name,
|
CAST(relname AS sql_identifier) AS table_name,
|
||||||
CAST(a.attname AS sql_identifier) AS column_name,
|
CAST(a.attname AS sql_identifier) AS column_name,
|
||||||
CAST(pos.n AS cardinal_number) AS ordinal_position
|
CAST((ss.x).n AS cardinal_number) AS ordinal_position
|
||||||
|
|
||||||
FROM pg_namespace nr, pg_class r, pg_attribute a, pg_namespace nc,
|
FROM pg_attribute a,
|
||||||
pg_constraint c, pg_user u, _pg_keypositions() AS pos(n)
|
(SELECT r.oid, nc.nspname AS nc_nspname, c.conname,
|
||||||
WHERE nr.oid = r.relnamespace
|
nr.nspname AS nr_nspname, r.relname,
|
||||||
AND r.oid = a.attrelid
|
_pg_expandsmallint(c.conkey) AS x
|
||||||
AND r.oid = c.conrelid
|
FROM pg_namespace nr, pg_class r, pg_namespace nc,
|
||||||
AND nc.oid = c.connamespace
|
pg_constraint c, pg_user u
|
||||||
AND c.conkey[pos.n] = a.attnum
|
WHERE nr.oid = r.relnamespace
|
||||||
AND NOT a.attisdropped
|
AND r.oid = c.conrelid
|
||||||
AND c.contype IN ('p', 'u', 'f')
|
AND nc.oid = c.connamespace
|
||||||
AND r.relkind = 'r'
|
AND c.contype IN ('p', 'u', 'f')
|
||||||
AND r.relowner = u.usesysid
|
AND r.relkind = 'r'
|
||||||
AND u.usename = current_user;
|
AND r.relowner = u.usesysid
|
||||||
|
AND u.usename = current_user) AS ss
|
||||||
|
WHERE ss.oid = a.attrelid
|
||||||
|
AND a.attnum = (ss.x).i
|
||||||
|
AND NOT a.attisdropped;
|
||||||
|
|
||||||
GRANT SELECT ON key_column_usage TO PUBLIC;
|
GRANT SELECT ON key_column_usage TO PUBLIC;
|
||||||
|
|
||||||
@ -738,13 +751,13 @@ GRANT SELECT ON key_column_usage TO PUBLIC;
|
|||||||
|
|
||||||
CREATE VIEW parameters AS
|
CREATE VIEW parameters AS
|
||||||
SELECT CAST(current_database() AS sql_identifier) AS specific_catalog,
|
SELECT CAST(current_database() AS sql_identifier) AS specific_catalog,
|
||||||
CAST(n.nspname AS sql_identifier) AS specific_schema,
|
CAST(n_nspname AS sql_identifier) AS specific_schema,
|
||||||
CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name,
|
CAST(proname || '_' || CAST(p_oid AS text) AS sql_identifier) AS specific_name,
|
||||||
CAST(pos.n AS cardinal_number) AS ordinal_position,
|
CAST((ss.x).n AS cardinal_number) AS ordinal_position,
|
||||||
CAST('IN' AS character_data) AS parameter_mode,
|
CAST('IN' AS character_data) AS parameter_mode,
|
||||||
CAST('NO' AS character_data) AS is_result,
|
CAST('NO' AS character_data) AS is_result,
|
||||||
CAST('NO' AS character_data) AS as_locator,
|
CAST('NO' AS character_data) AS as_locator,
|
||||||
CAST(NULLIF(p.proargnames[pos.n], '') AS sql_identifier) AS parameter_name,
|
CAST(NULLIF(proargnames[(ss.x).n], '') AS sql_identifier) AS parameter_name,
|
||||||
CAST(
|
CAST(
|
||||||
CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
|
CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
|
||||||
WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null)
|
WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null)
|
||||||
@ -771,15 +784,17 @@ CREATE VIEW parameters AS
|
|||||||
CAST(null AS sql_identifier) AS scope_schema,
|
CAST(null AS sql_identifier) AS scope_schema,
|
||||||
CAST(null AS sql_identifier) AS scope_name,
|
CAST(null AS sql_identifier) AS scope_name,
|
||||||
CAST(null AS cardinal_number) AS maximum_cardinality,
|
CAST(null AS cardinal_number) AS maximum_cardinality,
|
||||||
CAST(pos.n AS sql_identifier) AS dtd_identifier
|
CAST((ss.x).n AS sql_identifier) AS dtd_identifier
|
||||||
|
|
||||||
FROM pg_namespace n, pg_proc p, pg_type t, pg_namespace nt, pg_user u,
|
FROM pg_type t, pg_namespace nt,
|
||||||
_pg_keypositions() AS pos(n)
|
(SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid,
|
||||||
|
p.proargnames, _pg_expandoidvector(p.proargtypes) AS x
|
||||||
WHERE n.oid = p.pronamespace AND p.pronargs >= pos.n
|
FROM pg_namespace n, pg_proc p, pg_user u
|
||||||
AND p.proargtypes[pos.n-1] = t.oid AND t.typnamespace = nt.oid
|
WHERE n.oid = p.pronamespace
|
||||||
AND p.proowner = u.usesysid
|
AND p.proowner = u.usesysid
|
||||||
AND (u.usename = current_user OR has_function_privilege(p.oid, 'EXECUTE'));
|
AND (u.usename = current_user OR
|
||||||
|
has_function_privilege(p.oid, 'EXECUTE'))) AS ss
|
||||||
|
WHERE t.oid = (ss.x).o AND t.typnamespace = nt.oid;
|
||||||
|
|
||||||
GRANT SELECT ON parameters TO PUBLIC;
|
GRANT SELECT ON parameters TO PUBLIC;
|
||||||
|
|
||||||
@ -1702,10 +1717,11 @@ CREATE VIEW element_types AS
|
|||||||
UNION ALL
|
UNION ALL
|
||||||
|
|
||||||
/* parameters */
|
/* parameters */
|
||||||
SELECT p.pronamespace, CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier),
|
SELECT pronamespace, CAST(proname || '_' || CAST(oid AS text) AS sql_identifier),
|
||||||
'ROUTINE'::text, pos.n, p.proargtypes[pos.n-1]
|
'ROUTINE'::text, (ss.x).n, (ss.x).o
|
||||||
FROM pg_proc p, _pg_keypositions() AS pos(n)
|
FROM (SELECT p.pronamespace, p.proname, p.oid,
|
||||||
WHERE p.pronargs >= pos.n
|
_pg_expandoidvector(p.proargtypes) AS x
|
||||||
|
FROM pg_proc p) AS ss
|
||||||
|
|
||||||
UNION ALL
|
UNION ALL
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.73 2004/12/31 21:59:38 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.74 2005/03/29 00:16:56 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -471,25 +471,22 @@ FuncnameGetCandidates(List *names, int nargs)
|
|||||||
recomputeNamespacePath();
|
recomputeNamespacePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search syscache by name and (optionally) nargs only */
|
/* Search syscache by name only */
|
||||||
if (nargs >= 0)
|
catlist = SearchSysCacheList(PROCNAMEARGSNSP, 1,
|
||||||
catlist = SearchSysCacheList(PROCNAMENSP, 2,
|
CStringGetDatum(funcname),
|
||||||
CStringGetDatum(funcname),
|
0, 0, 0);
|
||||||
Int16GetDatum(nargs),
|
|
||||||
0, 0);
|
|
||||||
else
|
|
||||||
catlist = SearchSysCacheList(PROCNAMENSP, 1,
|
|
||||||
CStringGetDatum(funcname),
|
|
||||||
0, 0, 0);
|
|
||||||
|
|
||||||
for (i = 0; i < catlist->n_members; i++)
|
for (i = 0; i < catlist->n_members; i++)
|
||||||
{
|
{
|
||||||
HeapTuple proctup = &catlist->members[i]->tuple;
|
HeapTuple proctup = &catlist->members[i]->tuple;
|
||||||
Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
|
Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
|
||||||
|
int pronargs = procform->pronargs;
|
||||||
int pathpos = 0;
|
int pathpos = 0;
|
||||||
FuncCandidateList newResult;
|
FuncCandidateList newResult;
|
||||||
|
|
||||||
nargs = procform->pronargs;
|
/* Ignore if it doesn't match requested argument count */
|
||||||
|
if (nargs >= 0 && pronargs != nargs)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (OidIsValid(namespaceId))
|
if (OidIsValid(namespaceId))
|
||||||
{
|
{
|
||||||
@ -529,9 +526,10 @@ FuncnameGetCandidates(List *names, int nargs)
|
|||||||
|
|
||||||
if (catlist->ordered)
|
if (catlist->ordered)
|
||||||
{
|
{
|
||||||
if (nargs == resultList->nargs &&
|
if (pronargs == resultList->nargs &&
|
||||||
memcmp(procform->proargtypes, resultList->args,
|
memcmp(procform->proargtypes.values,
|
||||||
nargs * sizeof(Oid)) == 0)
|
resultList->args,
|
||||||
|
pronargs * sizeof(Oid)) == 0)
|
||||||
prevResult = resultList;
|
prevResult = resultList;
|
||||||
else
|
else
|
||||||
prevResult = NULL;
|
prevResult = NULL;
|
||||||
@ -542,9 +540,10 @@ FuncnameGetCandidates(List *names, int nargs)
|
|||||||
prevResult;
|
prevResult;
|
||||||
prevResult = prevResult->next)
|
prevResult = prevResult->next)
|
||||||
{
|
{
|
||||||
if (nargs == prevResult->nargs &&
|
if (pronargs == prevResult->nargs &&
|
||||||
memcmp(procform->proargtypes, prevResult->args,
|
memcmp(procform->proargtypes.values,
|
||||||
nargs * sizeof(Oid)) == 0)
|
prevResult->args,
|
||||||
|
pronargs * sizeof(Oid)) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -567,11 +566,12 @@ FuncnameGetCandidates(List *names, int nargs)
|
|||||||
*/
|
*/
|
||||||
newResult = (FuncCandidateList)
|
newResult = (FuncCandidateList)
|
||||||
palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
|
palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
|
||||||
+ nargs * sizeof(Oid));
|
+ pronargs * sizeof(Oid));
|
||||||
newResult->pathpos = pathpos;
|
newResult->pathpos = pathpos;
|
||||||
newResult->oid = HeapTupleGetOid(proctup);
|
newResult->oid = HeapTupleGetOid(proctup);
|
||||||
newResult->nargs = nargs;
|
newResult->nargs = pronargs;
|
||||||
memcpy(newResult->args, procform->proargtypes, nargs * sizeof(Oid));
|
memcpy(newResult->args, procform->proargtypes.values,
|
||||||
|
pronargs * sizeof(Oid));
|
||||||
|
|
||||||
newResult->next = resultList;
|
newResult->next = resultList;
|
||||||
resultList = newResult;
|
resultList = newResult;
|
||||||
@ -632,7 +632,7 @@ FunctionIsVisible(Oid funcid)
|
|||||||
|
|
||||||
for (; clist; clist = clist->next)
|
for (; clist; clist = clist->next)
|
||||||
{
|
{
|
||||||
if (memcmp(clist->args, procform->proargtypes,
|
if (memcmp(clist->args, procform->proargtypes.values,
|
||||||
nargs * sizeof(Oid)) == 0)
|
nargs * sizeof(Oid)) == 0)
|
||||||
{
|
{
|
||||||
/* Found the expected entry; is it the right proc? */
|
/* Found the expected entry; is it the right proc? */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.123 2005/01/27 23:23:51 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.124 2005/03/29 00:16:56 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -78,7 +78,7 @@ ProcedureCreate(const char *procedureName,
|
|||||||
char nulls[Natts_pg_proc];
|
char nulls[Natts_pg_proc];
|
||||||
Datum values[Natts_pg_proc];
|
Datum values[Natts_pg_proc];
|
||||||
char replaces[Natts_pg_proc];
|
char replaces[Natts_pg_proc];
|
||||||
Oid typev[FUNC_MAX_ARGS];
|
oidvector *proargtypes;
|
||||||
Datum namesarray;
|
Datum namesarray;
|
||||||
Oid relid;
|
Oid relid;
|
||||||
NameData procname;
|
NameData procname;
|
||||||
@ -125,10 +125,9 @@ ProcedureCreate(const char *procedureName,
|
|||||||
errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type.")));
|
errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure we have a zero-padded param type array */
|
/* Convert param types to oidvector */
|
||||||
MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
/* (Probably we should make caller pass it this way to start with) */
|
||||||
if (parameterCount > 0)
|
proargtypes = buildoidvector(parameterTypes, parameterCount);
|
||||||
memcpy(typev, parameterTypes, parameterCount * sizeof(Oid));
|
|
||||||
|
|
||||||
/* Process param names, if given */
|
/* Process param names, if given */
|
||||||
namesarray = create_parameternames_array(parameterCount, parameterNames);
|
namesarray = create_parameternames_array(parameterCount, parameterNames);
|
||||||
@ -137,13 +136,13 @@ ProcedureCreate(const char *procedureName,
|
|||||||
* don't allow functions of complex types that have the same name as
|
* don't allow functions of complex types that have the same name as
|
||||||
* existing attributes of the type
|
* existing attributes of the type
|
||||||
*/
|
*/
|
||||||
if (parameterCount == 1 && OidIsValid(typev[0]) &&
|
if (parameterCount == 1 && OidIsValid(parameterTypes[0]) &&
|
||||||
(relid = typeidTypeRelid(typev[0])) != InvalidOid &&
|
(relid = typeidTypeRelid(parameterTypes[0])) != InvalidOid &&
|
||||||
get_attnum(relid, procedureName) != InvalidAttrNumber)
|
get_attnum(relid, procedureName) != InvalidAttrNumber)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_DUPLICATE_COLUMN),
|
(errcode(ERRCODE_DUPLICATE_COLUMN),
|
||||||
errmsg("\"%s\" is already an attribute of type %s",
|
errmsg("\"%s\" is already an attribute of type %s",
|
||||||
procedureName, format_type_be(typev[0]))));
|
procedureName, format_type_be(parameterTypes[0]))));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All seems OK; prepare the data to be inserted into pg_proc.
|
* All seems OK; prepare the data to be inserted into pg_proc.
|
||||||
@ -162,15 +161,15 @@ ProcedureCreate(const char *procedureName,
|
|||||||
values[i++] = ObjectIdGetDatum(procNamespace); /* pronamespace */
|
values[i++] = ObjectIdGetDatum(procNamespace); /* pronamespace */
|
||||||
values[i++] = Int32GetDatum(GetUserId()); /* proowner */
|
values[i++] = Int32GetDatum(GetUserId()); /* proowner */
|
||||||
values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */
|
values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */
|
||||||
values[i++] = BoolGetDatum(isAgg); /* proisagg */
|
values[i++] = BoolGetDatum(isAgg); /* proisagg */
|
||||||
values[i++] = BoolGetDatum(security_definer); /* prosecdef */
|
values[i++] = BoolGetDatum(security_definer); /* prosecdef */
|
||||||
values[i++] = BoolGetDatum(isStrict); /* proisstrict */
|
values[i++] = BoolGetDatum(isStrict); /* proisstrict */
|
||||||
values[i++] = BoolGetDatum(returnsSet); /* proretset */
|
values[i++] = BoolGetDatum(returnsSet); /* proretset */
|
||||||
values[i++] = CharGetDatum(volatility); /* provolatile */
|
values[i++] = CharGetDatum(volatility); /* provolatile */
|
||||||
values[i++] = UInt16GetDatum(parameterCount); /* pronargs */
|
values[i++] = UInt16GetDatum(parameterCount); /* pronargs */
|
||||||
values[i++] = ObjectIdGetDatum(returnType); /* prorettype */
|
values[i++] = ObjectIdGetDatum(returnType); /* prorettype */
|
||||||
values[i++] = PointerGetDatum(typev); /* proargtypes */
|
values[i++] = PointerGetDatum(proargtypes); /* proargtypes */
|
||||||
values[i++] = namesarray; /* proargnames */
|
values[i++] = namesarray; /* proargnames */
|
||||||
if (namesarray == PointerGetDatum(NULL))
|
if (namesarray == PointerGetDatum(NULL))
|
||||||
nulls[Anum_pg_proc_proargnames - 1] = 'n';
|
nulls[Anum_pg_proc_proargnames - 1] = 'n';
|
||||||
values[i++] = DirectFunctionCall1(textin, /* prosrc */
|
values[i++] = DirectFunctionCall1(textin, /* prosrc */
|
||||||
@ -183,11 +182,11 @@ ProcedureCreate(const char *procedureName,
|
|||||||
tupDesc = RelationGetDescr(rel);
|
tupDesc = RelationGetDescr(rel);
|
||||||
|
|
||||||
/* Check for pre-existing definition */
|
/* Check for pre-existing definition */
|
||||||
oldtup = SearchSysCache(PROCNAMENSP,
|
oldtup = SearchSysCache(PROCNAMEARGSNSP,
|
||||||
PointerGetDatum(procedureName),
|
PointerGetDatum(procedureName),
|
||||||
UInt16GetDatum(parameterCount),
|
PointerGetDatum(proargtypes),
|
||||||
PointerGetDatum(typev),
|
ObjectIdGetDatum(procNamespace),
|
||||||
ObjectIdGetDatum(procNamespace));
|
0);
|
||||||
|
|
||||||
if (HeapTupleIsValid(oldtup))
|
if (HeapTupleIsValid(oldtup))
|
||||||
{
|
{
|
||||||
@ -290,7 +289,7 @@ ProcedureCreate(const char *procedureName,
|
|||||||
for (i = 0; i < parameterCount; i++)
|
for (i = 0; i < parameterCount; i++)
|
||||||
{
|
{
|
||||||
referenced.classId = RelOid_pg_type;
|
referenced.classId = RelOid_pg_type;
|
||||||
referenced.objectId = typev[i];
|
referenced.objectId = parameterTypes[i];
|
||||||
referenced.objectSubId = 0;
|
referenced.objectSubId = 0;
|
||||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
}
|
}
|
||||||
@ -492,16 +491,16 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
|
|||||||
haspolyarg = false;
|
haspolyarg = false;
|
||||||
for (i = 0; i < proc->pronargs; i++)
|
for (i = 0; i < proc->pronargs; i++)
|
||||||
{
|
{
|
||||||
if (get_typtype(proc->proargtypes[i]) == 'p')
|
if (get_typtype(proc->proargtypes.values[i]) == 'p')
|
||||||
{
|
{
|
||||||
if (proc->proargtypes[i] == ANYARRAYOID ||
|
if (proc->proargtypes.values[i] == ANYARRAYOID ||
|
||||||
proc->proargtypes[i] == ANYELEMENTOID)
|
proc->proargtypes.values[i] == ANYELEMENTOID)
|
||||||
haspolyarg = true;
|
haspolyarg = true;
|
||||||
else
|
else
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("SQL functions cannot have arguments of type %s",
|
errmsg("SQL functions cannot have arguments of type %s",
|
||||||
format_type_be(proc->proargtypes[i]))));
|
format_type_be(proc->proargtypes.values[i]))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +533,7 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
|
|||||||
if (!haspolyarg)
|
if (!haspolyarg)
|
||||||
{
|
{
|
||||||
querytree_list = pg_parse_and_rewrite(prosrc,
|
querytree_list = pg_parse_and_rewrite(prosrc,
|
||||||
proc->proargtypes,
|
proc->proargtypes.values,
|
||||||
proc->pronargs);
|
proc->pronargs);
|
||||||
(void) check_sql_fn_retval(proc->prorettype, functyptype,
|
(void) check_sql_fn_retval(proc->prorettype, functyptype,
|
||||||
querytree_list, NULL);
|
querytree_list, NULL);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.22 2004/12/31 21:59:41 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.23 2005/03/29 00:16:57 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
@ -246,11 +246,11 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname)
|
|||||||
namespaceOid = procForm->pronamespace;
|
namespaceOid = procForm->pronamespace;
|
||||||
|
|
||||||
/* make sure the new name doesn't exist */
|
/* make sure the new name doesn't exist */
|
||||||
if (SearchSysCacheExists(PROCNAMENSP,
|
if (SearchSysCacheExists(PROCNAMEARGSNSP,
|
||||||
CStringGetDatum(newname),
|
CStringGetDatum(newname),
|
||||||
Int16GetDatum(procForm->pronargs),
|
PointerGetDatum(&procForm->proargtypes),
|
||||||
PointerGetDatum(procForm->proargtypes),
|
ObjectIdGetDatum(namespaceOid),
|
||||||
ObjectIdGetDatum(namespaceOid)))
|
0))
|
||||||
{
|
{
|
||||||
if (basetypeOid == ANYOID)
|
if (basetypeOid == ANYOID)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -264,7 +264,7 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname)
|
|||||||
errmsg("function %s already exists in schema \"%s\"",
|
errmsg("function %s already exists in schema \"%s\"",
|
||||||
funcname_signature_string(newname,
|
funcname_signature_string(newname,
|
||||||
procForm->pronargs,
|
procForm->pronargs,
|
||||||
procForm->proargtypes),
|
procForm->proargtypes.values),
|
||||||
get_namespace_name(namespaceOid))));
|
get_namespace_name(namespaceOid))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.133 2005/03/20 22:00:52 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.134 2005/03/29 00:16:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -347,7 +347,7 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid)
|
|||||||
* at the first column; multicolumn-capable AMs are *required* to
|
* at the first column; multicolumn-capable AMs are *required* to
|
||||||
* index nulls in columns after the first.
|
* index nulls in columns after the first.
|
||||||
*/
|
*/
|
||||||
colno = OldIndex->rd_index->indkey[0];
|
colno = OldIndex->rd_index->indkey.values[0];
|
||||||
if (colno > 0)
|
if (colno > 0)
|
||||||
{
|
{
|
||||||
/* ordinary user attribute */
|
/* ordinary user attribute */
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.56 2005/03/14 00:19:36 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.57 2005/03/29 00:16:57 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* These routines take the parse tree and pick out the
|
* These routines take the parse tree and pick out the
|
||||||
@ -716,18 +716,18 @@ RenameFunction(List *name, List *argtypes, const char *newname)
|
|||||||
namespaceOid = procForm->pronamespace;
|
namespaceOid = procForm->pronamespace;
|
||||||
|
|
||||||
/* make sure the new name doesn't exist */
|
/* make sure the new name doesn't exist */
|
||||||
if (SearchSysCacheExists(PROCNAMENSP,
|
if (SearchSysCacheExists(PROCNAMEARGSNSP,
|
||||||
CStringGetDatum(newname),
|
CStringGetDatum(newname),
|
||||||
Int16GetDatum(procForm->pronargs),
|
PointerGetDatum(&procForm->proargtypes),
|
||||||
PointerGetDatum(procForm->proargtypes),
|
ObjectIdGetDatum(namespaceOid),
|
||||||
ObjectIdGetDatum(namespaceOid)))
|
0))
|
||||||
{
|
{
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_DUPLICATE_FUNCTION),
|
(errcode(ERRCODE_DUPLICATE_FUNCTION),
|
||||||
errmsg("function %s already exists in schema \"%s\"",
|
errmsg("function %s already exists in schema \"%s\"",
|
||||||
funcname_signature_string(newname,
|
funcname_signature_string(newname,
|
||||||
procForm->pronargs,
|
procForm->pronargs,
|
||||||
procForm->proargtypes),
|
procForm->proargtypes.values),
|
||||||
get_namespace_name(namespaceOid))));
|
get_namespace_name(namespaceOid))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -962,11 +962,11 @@ SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType)
|
|||||||
procForm = (Form_pg_proc) GETSTRUCT(tup);
|
procForm = (Form_pg_proc) GETSTRUCT(tup);
|
||||||
|
|
||||||
if (argIndex < 0 || argIndex >= procForm->pronargs ||
|
if (argIndex < 0 || argIndex >= procForm->pronargs ||
|
||||||
procForm->proargtypes[argIndex] != OPAQUEOID)
|
procForm->proargtypes.values[argIndex] != OPAQUEOID)
|
||||||
elog(ERROR, "function %u doesn't take OPAQUE", funcOid);
|
elog(ERROR, "function %u doesn't take OPAQUE", funcOid);
|
||||||
|
|
||||||
/* okay to overwrite copied tuple */
|
/* okay to overwrite copied tuple */
|
||||||
procForm->proargtypes[argIndex] = newArgType;
|
procForm->proargtypes.values[argIndex] = newArgType;
|
||||||
|
|
||||||
/* update the catalog and its indexes */
|
/* update the catalog and its indexes */
|
||||||
simple_heap_update(pg_proc_rel, &tup->t_self, tup);
|
simple_heap_update(pg_proc_rel, &tup->t_self, tup);
|
||||||
@ -1064,15 +1064,15 @@ CreateCast(CreateCastStmt *stmt)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
errmsg("cast function must take one to three arguments")));
|
errmsg("cast function must take one to three arguments")));
|
||||||
if (procstruct->proargtypes[0] != sourcetypeid)
|
if (procstruct->proargtypes.values[0] != sourcetypeid)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
errmsg("argument of cast function must match source data type")));
|
errmsg("argument of cast function must match source data type")));
|
||||||
if (nargs > 1 && procstruct->proargtypes[1] != INT4OID)
|
if (nargs > 1 && procstruct->proargtypes.values[1] != INT4OID)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
errmsg("second argument of cast function must be type integer")));
|
errmsg("second argument of cast function must be type integer")));
|
||||||
if (nargs > 2 && procstruct->proargtypes[2] != BOOLOID)
|
if (nargs > 2 && procstruct->proargtypes.values[2] != BOOLOID)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
errmsg("third argument of cast function must be type boolean")));
|
errmsg("third argument of cast function must be type boolean")));
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.29 2004/12/31 21:59:41 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.30 2005/03/29 00:16:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -486,7 +486,7 @@ assignProcSubtype(Oid amoid, Oid typeoid, Oid procOid)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
errmsg("btree procedures must return integer")));
|
errmsg("btree procedures must return integer")));
|
||||||
if (procform->proargtypes[0] != typeoid)
|
if (procform->proargtypes.values[0] != typeoid)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
errmsg("btree procedures must have index type as first input")));
|
errmsg("btree procedures must have index type as first input")));
|
||||||
@ -495,10 +495,10 @@ assignProcSubtype(Oid amoid, Oid typeoid, Oid procOid)
|
|||||||
* The subtype is "default" (0) if second input type matches the
|
* The subtype is "default" (0) if second input type matches the
|
||||||
* operator class, otherwise it is the second input type.
|
* operator class, otherwise it is the second input type.
|
||||||
*/
|
*/
|
||||||
if (procform->proargtypes[1] == typeoid)
|
if (procform->proargtypes.values[1] == typeoid)
|
||||||
subtype = InvalidOid;
|
subtype = InvalidOid;
|
||||||
else
|
else
|
||||||
subtype = procform->proargtypes[1];
|
subtype = procform->proargtypes.values[1];
|
||||||
ReleaseSysCache(proctup);
|
ReleaseSysCache(proctup);
|
||||||
return subtype;
|
return subtype;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.151 2005/03/25 18:04:34 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.152 2005/03/29 00:16:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1419,7 +1419,7 @@ renameatt(Oid myrelid,
|
|||||||
|
|
||||||
for (i = 0; i < indexform->indnatts; i++)
|
for (i = 0; i < indexform->indnatts; i++)
|
||||||
{
|
{
|
||||||
if (attnum != indexform->indkey[i])
|
if (attnum != indexform->indkey.values[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1676,9 +1676,10 @@ update_ri_trigger_args(Oid relid,
|
|||||||
* line; so does trigger.c ...
|
* line; so does trigger.c ...
|
||||||
*/
|
*/
|
||||||
tgnargs = pg_trigger->tgnargs;
|
tgnargs = pg_trigger->tgnargs;
|
||||||
val = (bytea *) fastgetattr(tuple,
|
val = (bytea *)
|
||||||
Anum_pg_trigger_tgargs,
|
DatumGetPointer(fastgetattr(tuple,
|
||||||
tgrel->rd_att, &isnull);
|
Anum_pg_trigger_tgargs,
|
||||||
|
tgrel->rd_att, &isnull));
|
||||||
if (isnull || tgnargs < RI_FIRST_ATTNAME_ARGNO ||
|
if (isnull || tgnargs < RI_FIRST_ATTNAME_ARGNO ||
|
||||||
tgnargs > RI_MAX_ARGUMENTS)
|
tgnargs > RI_MAX_ARGUMENTS)
|
||||||
{
|
{
|
||||||
@ -3202,7 +3203,7 @@ ATExecDropNotNull(Relation rel, const char *colName)
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < indexStruct->indnatts; i++)
|
for (i = 0; i < indexStruct->indnatts; i++)
|
||||||
{
|
{
|
||||||
if (indexStruct->indkey[i] == attnum)
|
if (indexStruct->indkey.values[i] == attnum)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||||
errmsg("column \"%s\" is in a primary key",
|
errmsg("column \"%s\" is in a primary key",
|
||||||
@ -4096,6 +4097,9 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
|
|||||||
ListCell *indexoidscan;
|
ListCell *indexoidscan;
|
||||||
HeapTuple indexTuple = NULL;
|
HeapTuple indexTuple = NULL;
|
||||||
Form_pg_index indexStruct = NULL;
|
Form_pg_index indexStruct = NULL;
|
||||||
|
Datum indclassDatum;
|
||||||
|
bool isnull;
|
||||||
|
oidvector *indclass;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4135,6 +4139,12 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
|
|||||||
errmsg("there is no primary key for referenced table \"%s\"",
|
errmsg("there is no primary key for referenced table \"%s\"",
|
||||||
RelationGetRelationName(pkrel))));
|
RelationGetRelationName(pkrel))));
|
||||||
|
|
||||||
|
/* Must get indclass the hard way */
|
||||||
|
indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
|
||||||
|
Anum_pg_index_indclass, &isnull);
|
||||||
|
Assert(!isnull);
|
||||||
|
indclass = (oidvector *) DatumGetPointer(indclassDatum);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now build the list of PK attributes from the indkey definition (we
|
* Now build the list of PK attributes from the indkey definition (we
|
||||||
* assume a primary key cannot have expressional elements)
|
* assume a primary key cannot have expressional elements)
|
||||||
@ -4142,11 +4152,11 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
|
|||||||
*attnamelist = NIL;
|
*attnamelist = NIL;
|
||||||
for (i = 0; i < indexStruct->indnatts; i++)
|
for (i = 0; i < indexStruct->indnatts; i++)
|
||||||
{
|
{
|
||||||
int pkattno = indexStruct->indkey[i];
|
int pkattno = indexStruct->indkey.values[i];
|
||||||
|
|
||||||
attnums[i] = pkattno;
|
attnums[i] = pkattno;
|
||||||
atttypids[i] = attnumTypeId(pkrel, pkattno);
|
atttypids[i] = attnumTypeId(pkrel, pkattno);
|
||||||
opclasses[i] = indexStruct->indclass[i];
|
opclasses[i] = indclass->values[i];
|
||||||
*attnamelist = lappend(*attnamelist,
|
*attnamelist = lappend(*attnamelist,
|
||||||
makeString(pstrdup(NameStr(*attnumAttName(pkrel, pkattno)))));
|
makeString(pstrdup(NameStr(*attnumAttName(pkrel, pkattno)))));
|
||||||
}
|
}
|
||||||
@ -4205,6 +4215,16 @@ transformFkeyCheckAttrs(Relation pkrel,
|
|||||||
heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
|
heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
|
||||||
heap_attisnull(indexTuple, Anum_pg_index_indexprs))
|
heap_attisnull(indexTuple, Anum_pg_index_indexprs))
|
||||||
{
|
{
|
||||||
|
/* Must get indclass the hard way */
|
||||||
|
Datum indclassDatum;
|
||||||
|
bool isnull;
|
||||||
|
oidvector *indclass;
|
||||||
|
|
||||||
|
indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
|
||||||
|
Anum_pg_index_indclass, &isnull);
|
||||||
|
Assert(!isnull);
|
||||||
|
indclass = (oidvector *) DatumGetPointer(indclassDatum);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The given attnum list may match the index columns in any
|
* The given attnum list may match the index columns in any
|
||||||
* order. Check that each list is a subset of the other.
|
* order. Check that each list is a subset of the other.
|
||||||
@ -4214,7 +4234,7 @@ transformFkeyCheckAttrs(Relation pkrel,
|
|||||||
found = false;
|
found = false;
|
||||||
for (j = 0; j < numattrs; j++)
|
for (j = 0; j < numattrs; j++)
|
||||||
{
|
{
|
||||||
if (attnums[i] == indexStruct->indkey[j])
|
if (attnums[i] == indexStruct->indkey.values[j])
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@ -4230,9 +4250,9 @@ transformFkeyCheckAttrs(Relation pkrel,
|
|||||||
found = false;
|
found = false;
|
||||||
for (j = 0; j < numattrs; j++)
|
for (j = 0; j < numattrs; j++)
|
||||||
{
|
{
|
||||||
if (attnums[j] == indexStruct->indkey[i])
|
if (attnums[j] == indexStruct->indkey.values[i])
|
||||||
{
|
{
|
||||||
opclasses[j] = indexStruct->indclass[i];
|
opclasses[j] = indclass->values[i];
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.181 2005/03/25 21:57:58 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.182 2005/03/29 00:16:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -67,7 +67,7 @@ Oid
|
|||||||
CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
|
CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
|
||||||
{
|
{
|
||||||
int16 tgtype;
|
int16 tgtype;
|
||||||
int16 tgattr[FUNC_MAX_ARGS];
|
int2vector *tgattr;
|
||||||
Datum values[Natts_pg_trigger];
|
Datum values[Natts_pg_trigger];
|
||||||
char nulls[Natts_pg_trigger];
|
char nulls[Natts_pg_trigger];
|
||||||
Relation rel;
|
Relation rel;
|
||||||
@ -77,7 +77,7 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
|
|||||||
ScanKeyData key;
|
ScanKeyData key;
|
||||||
Relation pgrel;
|
Relation pgrel;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Oid fargtypes[FUNC_MAX_ARGS];
|
Oid fargtypes[1]; /* dummy */
|
||||||
Oid funcoid;
|
Oid funcoid;
|
||||||
Oid funcrettype;
|
Oid funcrettype;
|
||||||
Oid trigoid;
|
Oid trigoid;
|
||||||
@ -275,7 +275,6 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
|
|||||||
/*
|
/*
|
||||||
* Find and validate the trigger function.
|
* Find and validate the trigger function.
|
||||||
*/
|
*/
|
||||||
MemSet(fargtypes, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
|
||||||
funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
|
funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
|
||||||
funcrettype = get_func_rettype(funcoid);
|
funcrettype = get_func_rettype(funcoid);
|
||||||
if (funcrettype != TRIGGEROID)
|
if (funcrettype != TRIGGEROID)
|
||||||
@ -359,7 +358,8 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
|
|||||||
values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
|
values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
|
||||||
CStringGetDatum(""));
|
CStringGetDatum(""));
|
||||||
}
|
}
|
||||||
MemSet(tgattr, 0, FUNC_MAX_ARGS * sizeof(int16));
|
/* tgattr is currently always a zero-length array */
|
||||||
|
tgattr = buildint2vector(NULL, 0);
|
||||||
values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
|
values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
|
||||||
|
|
||||||
tuple = heap_formtuple(tgrel->rd_att, values, nulls);
|
tuple = heap_formtuple(tgrel->rd_att, values, nulls);
|
||||||
@ -774,8 +774,16 @@ RelationBuildTriggers(Relation relation)
|
|||||||
build->tgdeferrable = pg_trigger->tgdeferrable;
|
build->tgdeferrable = pg_trigger->tgdeferrable;
|
||||||
build->tginitdeferred = pg_trigger->tginitdeferred;
|
build->tginitdeferred = pg_trigger->tginitdeferred;
|
||||||
build->tgnargs = pg_trigger->tgnargs;
|
build->tgnargs = pg_trigger->tgnargs;
|
||||||
memcpy(build->tgattr, &(pg_trigger->tgattr),
|
/* tgattr is first var-width field, so OK to access directly */
|
||||||
FUNC_MAX_ARGS * sizeof(int16));
|
build->tgnattr = pg_trigger->tgattr.dim1;
|
||||||
|
if (build->tgnattr > 0)
|
||||||
|
{
|
||||||
|
build->tgattr = (int2 *) palloc(build->tgnattr * sizeof(int2));
|
||||||
|
memcpy(build->tgattr, &(pg_trigger->tgattr.values),
|
||||||
|
build->tgnattr * sizeof(int2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
build->tgattr = NULL;
|
||||||
if (build->tgnargs > 0)
|
if (build->tgnargs > 0)
|
||||||
{
|
{
|
||||||
bytea *val;
|
bytea *val;
|
||||||
@ -783,9 +791,10 @@ RelationBuildTriggers(Relation relation)
|
|||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
val = (bytea *) fastgetattr(htup,
|
val = (bytea *)
|
||||||
Anum_pg_trigger_tgargs,
|
DatumGetPointer(fastgetattr(htup,
|
||||||
tgrel->rd_att, &isnull);
|
Anum_pg_trigger_tgargs,
|
||||||
|
tgrel->rd_att, &isnull));
|
||||||
if (isnull)
|
if (isnull)
|
||||||
elog(ERROR, "tgargs is null in trigger for relation \"%s\"",
|
elog(ERROR, "tgargs is null in trigger for relation \"%s\"",
|
||||||
RelationGetRelationName(relation));
|
RelationGetRelationName(relation));
|
||||||
@ -928,6 +937,15 @@ CopyTriggerDesc(TriggerDesc *trigdesc)
|
|||||||
for (i = 0; i < trigdesc->numtriggers; i++)
|
for (i = 0; i < trigdesc->numtriggers; i++)
|
||||||
{
|
{
|
||||||
trigger->tgname = pstrdup(trigger->tgname);
|
trigger->tgname = pstrdup(trigger->tgname);
|
||||||
|
if (trigger->tgnattr > 0)
|
||||||
|
{
|
||||||
|
int2 *newattr;
|
||||||
|
|
||||||
|
newattr = (int2 *) palloc(trigger->tgnattr * sizeof(int2));
|
||||||
|
memcpy(newattr, trigger->tgattr,
|
||||||
|
trigger->tgnattr * sizeof(int2));
|
||||||
|
trigger->tgattr = newattr;
|
||||||
|
}
|
||||||
if (trigger->tgnargs > 0)
|
if (trigger->tgnargs > 0)
|
||||||
{
|
{
|
||||||
char **newargs;
|
char **newargs;
|
||||||
@ -1031,6 +1049,8 @@ FreeTriggerDesc(TriggerDesc *trigdesc)
|
|||||||
for (i = 0; i < trigdesc->numtriggers; i++)
|
for (i = 0; i < trigdesc->numtriggers; i++)
|
||||||
{
|
{
|
||||||
pfree(trigger->tgname);
|
pfree(trigger->tgname);
|
||||||
|
if (trigger->tgnattr > 0)
|
||||||
|
pfree(trigger->tgattr);
|
||||||
if (trigger->tgnargs > 0)
|
if (trigger->tgnargs > 0)
|
||||||
{
|
{
|
||||||
while (--(trigger->tgnargs) >= 0)
|
while (--(trigger->tgnargs) >= 0)
|
||||||
@ -1092,8 +1112,11 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
|
|||||||
return false;
|
return false;
|
||||||
if (trig1->tgnargs != trig2->tgnargs)
|
if (trig1->tgnargs != trig2->tgnargs)
|
||||||
return false;
|
return false;
|
||||||
if (memcmp(trig1->tgattr, trig2->tgattr,
|
if (trig1->tgnattr != trig2->tgnattr)
|
||||||
sizeof(trig1->tgattr)) != 0)
|
return false;
|
||||||
|
if (trig1->tgnattr > 0 &&
|
||||||
|
memcmp(trig1->tgattr, trig2->tgattr,
|
||||||
|
trig1->tgnattr * sizeof(int2)) != 0)
|
||||||
return false;
|
return false;
|
||||||
for (j = 0; j < trig1->tgnargs; j++)
|
for (j = 0; j < trig1->tgnargs; j++)
|
||||||
if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0)
|
if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.174 2005/03/22 20:13:06 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.175 2005/03/29 00:16:59 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -724,9 +724,17 @@ init_fcache(Oid foid, FuncExprState *fcache, MemoryContext fcacheCxt)
|
|||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
|
aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
|
||||||
|
|
||||||
/* Safety check (should never fail, as parser should check sooner) */
|
/*
|
||||||
|
* Safety check on nargs. Under normal circumstances this should never
|
||||||
|
* fail, as parser should check sooner. But possibly it might fail
|
||||||
|
* if server has been compiled with FUNC_MAX_ARGS smaller than some
|
||||||
|
* functions declared in pg_proc?
|
||||||
|
*/
|
||||||
if (list_length(fcache->args) > FUNC_MAX_ARGS)
|
if (list_length(fcache->args) > FUNC_MAX_ARGS)
|
||||||
elog(ERROR, "too many arguments");
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
|
||||||
|
errmsg("cannot pass more than %d arguments to a function",
|
||||||
|
FUNC_MAX_ARGS)));
|
||||||
|
|
||||||
/* Set up the primary fmgr lookup information */
|
/* Set up the primary fmgr lookup information */
|
||||||
fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
|
fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.93 2005/03/25 21:57:58 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.94 2005/03/29 00:16:59 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -228,7 +228,7 @@ init_sql_fcache(FmgrInfo *finfo)
|
|||||||
|
|
||||||
argOidVect = (Oid *) palloc(nargs * sizeof(Oid));
|
argOidVect = (Oid *) palloc(nargs * sizeof(Oid));
|
||||||
memcpy(argOidVect,
|
memcpy(argOidVect,
|
||||||
procedureStruct->proargtypes,
|
procedureStruct->proargtypes.values,
|
||||||
nargs * sizeof(Oid));
|
nargs * sizeof(Oid));
|
||||||
/* Resolve any polymorphic argument types */
|
/* Resolve any polymorphic argument types */
|
||||||
for (argnum = 0; argnum < nargs; argnum++)
|
for (argnum = 0; argnum < nargs; argnum++)
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.131 2005/03/22 20:13:06 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.132 2005/03/29 00:16:59 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1300,15 +1300,16 @@ ExecInitAgg(Agg *node, EState *estate)
|
|||||||
if (aggtranstype == ANYARRAYOID || aggtranstype == ANYELEMENTOID)
|
if (aggtranstype == ANYARRAYOID || aggtranstype == ANYELEMENTOID)
|
||||||
{
|
{
|
||||||
/* have to fetch the agg's declared input type... */
|
/* have to fetch the agg's declared input type... */
|
||||||
Oid agg_arg_types[FUNC_MAX_ARGS];
|
Oid *agg_arg_types;
|
||||||
int agg_nargs;
|
int agg_nargs;
|
||||||
|
|
||||||
(void) get_func_signature(aggref->aggfnoid,
|
(void) get_func_signature(aggref->aggfnoid,
|
||||||
agg_arg_types, &agg_nargs);
|
&agg_arg_types, &agg_nargs);
|
||||||
Assert(agg_nargs == 1);
|
Assert(agg_nargs == 1);
|
||||||
aggtranstype = resolve_generic_type(aggtranstype,
|
aggtranstype = resolve_generic_type(aggtranstype,
|
||||||
inputType,
|
inputType,
|
||||||
agg_arg_types[0]);
|
agg_arg_types[0]);
|
||||||
|
pfree(agg_arg_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build expression trees using actual argument & result types */
|
/* build expression trees using actual argument & result types */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.190 2005/03/28 00:58:24 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.191 2005/03/29 00:17:02 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -421,15 +421,16 @@ count_agg_clauses_walker(Node *node, AggClauseCounts *counts)
|
|||||||
if (aggtranstype == ANYARRAYOID || aggtranstype == ANYELEMENTOID)
|
if (aggtranstype == ANYARRAYOID || aggtranstype == ANYELEMENTOID)
|
||||||
{
|
{
|
||||||
/* have to fetch the agg's declared input type... */
|
/* have to fetch the agg's declared input type... */
|
||||||
Oid agg_arg_types[FUNC_MAX_ARGS];
|
Oid *agg_arg_types;
|
||||||
int agg_nargs;
|
int agg_nargs;
|
||||||
|
|
||||||
(void) get_func_signature(aggref->aggfnoid,
|
(void) get_func_signature(aggref->aggfnoid,
|
||||||
agg_arg_types, &agg_nargs);
|
&agg_arg_types, &agg_nargs);
|
||||||
Assert(agg_nargs == 1);
|
Assert(agg_nargs == 1);
|
||||||
aggtranstype = resolve_generic_type(aggtranstype,
|
aggtranstype = resolve_generic_type(aggtranstype,
|
||||||
inputType,
|
inputType,
|
||||||
agg_arg_types[0]);
|
agg_arg_types[0]);
|
||||||
|
pfree(agg_arg_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2187,7 +2188,7 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
|||||||
{
|
{
|
||||||
Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
|
Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
|
||||||
bool polymorphic = false;
|
bool polymorphic = false;
|
||||||
Oid argtypes[FUNC_MAX_ARGS];
|
Oid *argtypes;
|
||||||
char *src;
|
char *src;
|
||||||
Datum tmp;
|
Datum tmp;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
@ -2220,22 +2221,6 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
|||||||
if (pg_proc_aclcheck(funcid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
|
if (pg_proc_aclcheck(funcid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Check for polymorphic arguments, and substitute actual arg types */
|
|
||||||
memcpy(argtypes, funcform->proargtypes, FUNC_MAX_ARGS * sizeof(Oid));
|
|
||||||
for (i = 0; i < funcform->pronargs; i++)
|
|
||||||
{
|
|
||||||
if (argtypes[i] == ANYARRAYOID ||
|
|
||||||
argtypes[i] == ANYELEMENTOID)
|
|
||||||
{
|
|
||||||
polymorphic = true;
|
|
||||||
argtypes[i] = exprType((Node *) list_nth(args, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (funcform->prorettype == ANYARRAYOID ||
|
|
||||||
funcform->prorettype == ANYELEMENTOID)
|
|
||||||
polymorphic = true;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup error traceback support for ereport(). This is so that we
|
* Setup error traceback support for ereport(). This is so that we
|
||||||
* can finger the function that bad information came from.
|
* can finger the function that bad information came from.
|
||||||
@ -2256,6 +2241,24 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
|||||||
ALLOCSET_DEFAULT_MAXSIZE);
|
ALLOCSET_DEFAULT_MAXSIZE);
|
||||||
oldcxt = MemoryContextSwitchTo(mycxt);
|
oldcxt = MemoryContextSwitchTo(mycxt);
|
||||||
|
|
||||||
|
/* Check for polymorphic arguments, and substitute actual arg types */
|
||||||
|
argtypes = (Oid *) palloc(funcform->pronargs * sizeof(Oid));
|
||||||
|
memcpy(argtypes, funcform->proargtypes.values,
|
||||||
|
funcform->pronargs * sizeof(Oid));
|
||||||
|
for (i = 0; i < funcform->pronargs; i++)
|
||||||
|
{
|
||||||
|
if (argtypes[i] == ANYARRAYOID ||
|
||||||
|
argtypes[i] == ANYELEMENTOID)
|
||||||
|
{
|
||||||
|
polymorphic = true;
|
||||||
|
argtypes[i] = exprType((Node *) list_nth(args, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (funcform->prorettype == ANYARRAYOID ||
|
||||||
|
funcform->prorettype == ANYELEMENTOID)
|
||||||
|
polymorphic = true;
|
||||||
|
|
||||||
/* Fetch and parse the function body */
|
/* Fetch and parse the function body */
|
||||||
tmp = SysCacheGetAttr(PROCOID,
|
tmp = SysCacheGetAttr(PROCOID,
|
||||||
func_tuple,
|
func_tuple,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.102 2005/03/27 06:29:42 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.103 2005/03/29 00:17:02 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -137,8 +137,8 @@ get_relation_info(Oid relationObjectId, RelOptInfo *rel)
|
|||||||
|
|
||||||
for (i = 0; i < ncolumns; i++)
|
for (i = 0; i < ncolumns; i++)
|
||||||
{
|
{
|
||||||
info->classlist[i] = index->indclass[i];
|
info->classlist[i] = indexRelation->rd_indclass->values[i];
|
||||||
info->indexkeys[i] = index->indkey[i];
|
info->indexkeys[i] = index->indkey.values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
info->relam = indexRelation->rd_rel->relam;
|
info->relam = indexRelation->rd_rel->relam;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.67 2005/03/10 23:21:23 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.68 2005/03/29 00:17:04 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -367,14 +367,13 @@ build_aggregate_fnexprs(Oid agg_input_type,
|
|||||||
Expr **transfnexpr,
|
Expr **transfnexpr,
|
||||||
Expr **finalfnexpr)
|
Expr **finalfnexpr)
|
||||||
{
|
{
|
||||||
Oid transfn_arg_types[FUNC_MAX_ARGS];
|
|
||||||
int transfn_nargs;
|
int transfn_nargs;
|
||||||
Param *arg0;
|
Param *arg0;
|
||||||
Param *arg1;
|
Param *arg1;
|
||||||
List *args;
|
List *args;
|
||||||
|
|
||||||
/* get the transition function signature (only need nargs) */
|
/* get the transition function arg count */
|
||||||
(void) get_func_signature(transfn_oid, transfn_arg_types, &transfn_nargs);
|
transfn_nargs = get_func_nargs(transfn_oid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build arg list to use in the transfn FuncExpr node. We really only
|
* Build arg list to use in the transfn FuncExpr node. We really only
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.126 2004/12/31 22:00:27 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.127 2005/03/29 00:17:04 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -615,9 +615,9 @@ build_coercion_expression(Node *node, Oid funcId,
|
|||||||
Assert(!procstruct->proisagg);
|
Assert(!procstruct->proisagg);
|
||||||
nargs = procstruct->pronargs;
|
nargs = procstruct->pronargs;
|
||||||
Assert(nargs >= 1 && nargs <= 3);
|
Assert(nargs >= 1 && nargs <= 3);
|
||||||
/* Assert(procstruct->proargtypes[0] == exprType(node)); */
|
/* Assert(procstruct->proargtypes.values[0] == exprType(node)); */
|
||||||
Assert(nargs < 2 || procstruct->proargtypes[1] == INT4OID);
|
Assert(nargs < 2 || procstruct->proargtypes.values[1] == INT4OID);
|
||||||
Assert(nargs < 3 || procstruct->proargtypes[2] == BOOLOID);
|
Assert(nargs < 3 || procstruct->proargtypes.values[2] == BOOLOID);
|
||||||
|
|
||||||
ReleaseSysCache(tp);
|
ReleaseSysCache(tp);
|
||||||
|
|
||||||
@ -1672,11 +1672,21 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
|
|||||||
* of array types. If so, and if the element types have a
|
* of array types. If so, and if the element types have a
|
||||||
* suitable cast, use array_type_coerce() or
|
* suitable cast, use array_type_coerce() or
|
||||||
* array_type_length_coerce().
|
* array_type_length_coerce().
|
||||||
|
*
|
||||||
|
* Hack: disallow coercions to oidvector and int2vector, which
|
||||||
|
* otherwise tend to capture coercions that should go to "real" array
|
||||||
|
* types. We want those types to be considered "real" arrays for many
|
||||||
|
* purposes, but not this one. (Also, array_type_coerce isn't
|
||||||
|
* guaranteed to produce an output that meets the restrictions of
|
||||||
|
* these datatypes, such as being 1-dimensional.)
|
||||||
*/
|
*/
|
||||||
Oid targetElemType;
|
Oid targetElemType;
|
||||||
Oid sourceElemType;
|
Oid sourceElemType;
|
||||||
Oid elemfuncid;
|
Oid elemfuncid;
|
||||||
|
|
||||||
|
if (targetTypeId == OIDVECTOROID || targetTypeId == INT2VECTOROID)
|
||||||
|
return false;
|
||||||
|
|
||||||
if ((targetElemType = get_element_type(targetTypeId)) != InvalidOid &&
|
if ((targetElemType = get_element_type(targetTypeId)) != InvalidOid &&
|
||||||
(sourceElemType = get_element_type(sourceTypeId)) != InvalidOid)
|
(sourceElemType = get_element_type(sourceTypeId)) != InvalidOid)
|
||||||
{
|
{
|
||||||
@ -1691,11 +1701,7 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* does the function take a typmod arg? */
|
/* does the function take a typmod arg? */
|
||||||
Oid argtypes[FUNC_MAX_ARGS];
|
if (get_func_nargs(elemfuncid) > 1)
|
||||||
int nargs;
|
|
||||||
|
|
||||||
(void) get_func_signature(elemfuncid, argtypes, &nargs);
|
|
||||||
if (nargs > 1)
|
|
||||||
*funcid = F_ARRAY_TYPE_LENGTH_COERCE;
|
*funcid = F_ARRAY_TYPE_LENGTH_COERCE;
|
||||||
else
|
else
|
||||||
*funcid = F_ARRAY_TYPE_COERCE;
|
*funcid = F_ARRAY_TYPE_COERCE;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tcop/fastpath.c,v 1.77 2004/12/31 22:01:16 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/tcop/fastpath.c,v 1.78 2005/03/29 00:17:05 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* This cruft is the server side of PQfn.
|
* This cruft is the server side of PQfn.
|
||||||
@ -230,9 +230,14 @@ fetch_fp_info(Oid func_id, struct fp_info * fip)
|
|||||||
errmsg("function with OID %u does not exist", func_id)));
|
errmsg("function with OID %u does not exist", func_id)));
|
||||||
pp = (Form_pg_proc) GETSTRUCT(func_htp);
|
pp = (Form_pg_proc) GETSTRUCT(func_htp);
|
||||||
|
|
||||||
|
/* watch out for catalog entries with more than FUNC_MAX_ARGS args */
|
||||||
|
if (pp->pronargs > FUNC_MAX_ARGS)
|
||||||
|
elog(ERROR, "function %s has more than %d arguments",
|
||||||
|
NameStr(pp->proname), FUNC_MAX_ARGS);
|
||||||
|
|
||||||
fip->namespace = pp->pronamespace;
|
fip->namespace = pp->pronamespace;
|
||||||
fip->rettype = pp->prorettype;
|
fip->rettype = pp->prorettype;
|
||||||
memcpy(fip->argtypes, pp->proargtypes, FUNC_MAX_ARGS * sizeof(Oid));
|
memcpy(fip->argtypes, pp->proargtypes.values, pp->pronargs * sizeof(Oid));
|
||||||
|
|
||||||
ReleaseSysCache(func_htp);
|
ReleaseSysCache(func_htp);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.117 2005/03/24 21:50:37 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.118 2005/03/29 00:17:08 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -56,7 +56,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* There are also some "fixed-length array" datatypes, such as NAME and
|
* There are also some "fixed-length array" datatypes, such as NAME and
|
||||||
* OIDVECTOR. These are simply a sequence of a fixed number of items each
|
* POINT. These are simply a sequence of a fixed number of items each
|
||||||
* of a fixed-length datatype, with no overhead; the item size must be
|
* of a fixed-length datatype, with no overhead; the item size must be
|
||||||
* a multiple of its alignment requirement, because we do no padding.
|
* a multiple of its alignment requirement, because we do no padding.
|
||||||
* We support subscripting on these types, but array_in() and array_out()
|
* We support subscripting on these types, but array_in() and array_out()
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/format_type.c,v 1.39 2004/12/31 22:01:21 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/format_type.c,v 1.40 2005/03/29 00:17:08 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -140,12 +140,15 @@ format_type_internal(Oid type_oid, int32 typemod,
|
|||||||
/*
|
/*
|
||||||
* Check if it's an array (and not a domain --- we don't want to show
|
* Check if it's an array (and not a domain --- we don't want to show
|
||||||
* the substructure of a domain type). Fixed-length array types such
|
* the substructure of a domain type). Fixed-length array types such
|
||||||
* as "name" shouldn't get deconstructed either.
|
* as "name" shouldn't get deconstructed either. As of Postgres 8.1,
|
||||||
|
* rather than checking typlen we check the toast property, and don't
|
||||||
|
* deconstruct "plain storage" array types --- this is because we don't
|
||||||
|
* want to show oidvector as oid[].
|
||||||
*/
|
*/
|
||||||
array_base_type = typeform->typelem;
|
array_base_type = typeform->typelem;
|
||||||
|
|
||||||
if (array_base_type != InvalidOid &&
|
if (array_base_type != InvalidOid &&
|
||||||
typeform->typlen == -1 &&
|
typeform->typstorage != 'p' &&
|
||||||
typeform->typtype != 'd')
|
typeform->typtype != 'd')
|
||||||
{
|
{
|
||||||
/* Switch our attention to the array element type */
|
/* Switch our attention to the array element type */
|
||||||
@ -459,29 +462,17 @@ type_maximum_size(Oid type_oid, int32 typemod)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* oidvectortypes - converts a vector of type OIDs to "typname" list
|
* oidvectortypes - converts a vector of type OIDs to "typname" list
|
||||||
*
|
|
||||||
* The interface for this function is wrong: it should be told how many
|
|
||||||
* OIDs are significant in the input vector, so that trailing InvalidOid
|
|
||||||
* argument types can be recognized.
|
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
oidvectortypes(PG_FUNCTION_ARGS)
|
oidvectortypes(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
|
oidvector *oidArray = (oidvector *) PG_GETARG_POINTER(0);
|
||||||
char *result;
|
char *result;
|
||||||
int numargs;
|
int numargs = oidArray->dim1;
|
||||||
int num;
|
int num;
|
||||||
size_t total;
|
size_t total;
|
||||||
size_t left;
|
size_t left;
|
||||||
|
|
||||||
/* Try to guess how many args there are :-( */
|
|
||||||
numargs = 0;
|
|
||||||
for (num = 0; num < FUNC_MAX_ARGS; num++)
|
|
||||||
{
|
|
||||||
if (oidArray[num] != InvalidOid)
|
|
||||||
numargs = num + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
total = 20 * numargs + 1;
|
total = 20 * numargs + 1;
|
||||||
result = palloc(total);
|
result = palloc(total);
|
||||||
result[0] = '\0';
|
result[0] = '\0';
|
||||||
@ -489,7 +480,7 @@ oidvectortypes(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
for (num = 0; num < numargs; num++)
|
for (num = 0; num < numargs; num++)
|
||||||
{
|
{
|
||||||
char *typename = format_type_internal(oidArray[num], -1,
|
char *typename = format_type_internal(oidArray->values[num], -1,
|
||||||
false, true);
|
false, true);
|
||||||
size_t slen = strlen(typename);
|
size_t slen = strlen(typename);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.65 2005/02/27 08:31:30 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.66 2005/03/29 00:17:08 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -33,8 +33,10 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "catalog/pg_type.h"
|
||||||
#include "funcapi.h"
|
#include "funcapi.h"
|
||||||
#include "libpq/pqformat.h"
|
#include "libpq/pqformat.h"
|
||||||
|
#include "utils/array.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
|
|
||||||
@ -47,6 +49,8 @@
|
|||||||
|
|
||||||
#define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
|
#define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
|
||||||
|
|
||||||
|
#define Int2VectorSize(n) (offsetof(int2vector, values) + (n) * sizeof(int2))
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32 current;
|
int32 current;
|
||||||
@ -109,20 +113,49 @@ int2send(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* int2vectorin - converts "num num ..." to internal form
|
* construct int2vector given a raw array of int2s
|
||||||
*
|
*
|
||||||
* Note: Fills any missing slots with zeroes.
|
* If int2s is NULL then caller must fill values[] afterward
|
||||||
|
*/
|
||||||
|
int2vector *
|
||||||
|
buildint2vector(const int2 *int2s, int n)
|
||||||
|
{
|
||||||
|
int2vector *result;
|
||||||
|
|
||||||
|
result = (int2vector *) palloc0(Int2VectorSize(n));
|
||||||
|
|
||||||
|
if (n > 0 && int2s)
|
||||||
|
memcpy(result->values, int2s, n * sizeof(int2));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach standard array header. For historical reasons, we set the
|
||||||
|
* index lower bound to 0 not 1.
|
||||||
|
*/
|
||||||
|
result->size = Int2VectorSize(n);
|
||||||
|
result->ndim = 1;
|
||||||
|
result->flags = 0;
|
||||||
|
result->elemtype = INT2OID;
|
||||||
|
result->dim1 = n;
|
||||||
|
result->lbound1 = 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* int2vectorin - converts "num num ..." to internal form
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
int2vectorin(PG_FUNCTION_ARGS)
|
int2vectorin(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
char *intString = PG_GETARG_CSTRING(0);
|
char *intString = PG_GETARG_CSTRING(0);
|
||||||
int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
|
int2vector *result;
|
||||||
int slot;
|
int n;
|
||||||
|
|
||||||
for (slot = 0; *intString && slot < INDEX_MAX_KEYS; slot++)
|
result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));
|
||||||
|
|
||||||
|
for (n = 0; *intString && n < FUNC_MAX_ARGS; n++)
|
||||||
{
|
{
|
||||||
if (sscanf(intString, "%hd", &result[slot]) != 1)
|
if (sscanf(intString, "%hd", &result->values[n]) != 1)
|
||||||
break;
|
break;
|
||||||
while (*intString && isspace((unsigned char) *intString))
|
while (*intString && isspace((unsigned char) *intString))
|
||||||
intString++;
|
intString++;
|
||||||
@ -136,8 +169,12 @@ int2vectorin(PG_FUNCTION_ARGS)
|
|||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("int2vector has too many elements")));
|
errmsg("int2vector has too many elements")));
|
||||||
|
|
||||||
while (slot < INDEX_MAX_KEYS)
|
result->size = Int2VectorSize(n);
|
||||||
result[slot++] = 0;
|
result->ndim = 1;
|
||||||
|
result->flags = 0;
|
||||||
|
result->elemtype = INT2OID;
|
||||||
|
result->dim1 = n;
|
||||||
|
result->lbound1 = 0;
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
@ -148,24 +185,19 @@ int2vectorin(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
int2vectorout(PG_FUNCTION_ARGS)
|
int2vectorout(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int16 *int2Array = (int16 *) PG_GETARG_POINTER(0);
|
int2vector *int2Array = (int2vector *) PG_GETARG_POINTER(0);
|
||||||
int num,
|
int num,
|
||||||
maxnum;
|
nnums = int2Array->dim1;
|
||||||
char *rp;
|
char *rp;
|
||||||
char *result;
|
char *result;
|
||||||
|
|
||||||
/* find last non-zero value in vector */
|
|
||||||
for (maxnum = INDEX_MAX_KEYS - 1; maxnum >= 0; maxnum--)
|
|
||||||
if (int2Array[maxnum] != 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* assumes sign, 5 digits, ' ' */
|
/* assumes sign, 5 digits, ' ' */
|
||||||
rp = result = (char *) palloc((maxnum + 1) * 7 + 1);
|
rp = result = (char *) palloc(nnums * 7 + 1);
|
||||||
for (num = 0; num <= maxnum; num++)
|
for (num = 0; num < nnums; num++)
|
||||||
{
|
{
|
||||||
if (num != 0)
|
if (num != 0)
|
||||||
*rp++ = ' ';
|
*rp++ = ' ';
|
||||||
pg_itoa(int2Array[num], rp);
|
pg_itoa(int2Array->values[num], rp);
|
||||||
while (*++rp != '\0')
|
while (*++rp != '\0')
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -180,11 +212,19 @@ Datum
|
|||||||
int2vectorrecv(PG_FUNCTION_ARGS)
|
int2vectorrecv(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||||
int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
|
int2vector *result;
|
||||||
int slot;
|
|
||||||
|
|
||||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
result = (int2vector *)
|
||||||
result[slot] = (int16) pq_getmsgint(buf, sizeof(int16));
|
DatumGetPointer(DirectFunctionCall2(array_recv,
|
||||||
|
PointerGetDatum(buf),
|
||||||
|
ObjectIdGetDatum(INT2OID)));
|
||||||
|
/* sanity checks: int2vector must be 1-D, no nulls */
|
||||||
|
if (result->ndim != 1 ||
|
||||||
|
result->flags != 0 ||
|
||||||
|
result->elemtype != INT2OID)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||||
|
errmsg("invalid int2vector data")));
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,14 +234,7 @@ int2vectorrecv(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
int2vectorsend(PG_FUNCTION_ARGS)
|
int2vectorsend(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int16 *int2Array = (int16 *) PG_GETARG_POINTER(0);
|
return array_send(fcinfo);
|
||||||
StringInfoData buf;
|
|
||||||
int slot;
|
|
||||||
|
|
||||||
pq_begintypsend(&buf);
|
|
||||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
|
||||||
pq_sendint(&buf, int2Array[slot], sizeof(int16));
|
|
||||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -211,10 +244,12 @@ int2vectorsend(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
int2vectoreq(PG_FUNCTION_ARGS)
|
int2vectoreq(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int16 *arg1 = (int16 *) PG_GETARG_POINTER(0);
|
int2vector *a = (int2vector *) PG_GETARG_POINTER(0);
|
||||||
int16 *arg2 = (int16 *) PG_GETARG_POINTER(1);
|
int2vector *b = (int2vector *) PG_GETARG_POINTER(1);
|
||||||
|
|
||||||
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(int16)) == 0);
|
if (a->dim1 != b->dim1)
|
||||||
|
PG_RETURN_BOOL(false);
|
||||||
|
PG_RETURN_BOOL(memcmp(a->values, b->values, a->dim1 * sizeof(int2)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,20 +8,24 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.61 2005/02/11 04:08:58 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.62 2005/03/29 00:17:08 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "catalog/pg_type.h"
|
||||||
#include "libpq/pqformat.h"
|
#include "libpq/pqformat.h"
|
||||||
|
#include "utils/array.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define OidVectorSize(n) (offsetof(oidvector, values) + (n) * sizeof(Oid))
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* USER I/O ROUTINES *
|
* USER I/O ROUTINES *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -151,27 +155,54 @@ oidsend(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* construct oidvector given a raw array of Oids
|
||||||
|
*
|
||||||
|
* If oids is NULL then caller must fill values[] afterward
|
||||||
|
*/
|
||||||
|
oidvector *
|
||||||
|
buildoidvector(const Oid *oids, int n)
|
||||||
|
{
|
||||||
|
oidvector *result;
|
||||||
|
|
||||||
|
result = (oidvector *) palloc0(OidVectorSize(n));
|
||||||
|
|
||||||
|
if (n > 0 && oids)
|
||||||
|
memcpy(result->values, oids, n * sizeof(Oid));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach standard array header. For historical reasons, we set the
|
||||||
|
* index lower bound to 0 not 1.
|
||||||
|
*/
|
||||||
|
result->size = OidVectorSize(n);
|
||||||
|
result->ndim = 1;
|
||||||
|
result->flags = 0;
|
||||||
|
result->elemtype = OIDOID;
|
||||||
|
result->dim1 = n;
|
||||||
|
result->lbound1 = 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* oidvectorin - converts "num num ..." to internal form
|
* oidvectorin - converts "num num ..." to internal form
|
||||||
*
|
|
||||||
* Note:
|
|
||||||
* Fills any unsupplied positions with InvalidOid.
|
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
oidvectorin(PG_FUNCTION_ARGS)
|
oidvectorin(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
char *oidString = PG_GETARG_CSTRING(0);
|
char *oidString = PG_GETARG_CSTRING(0);
|
||||||
Oid *result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
|
oidvector *result;
|
||||||
int slot;
|
int n;
|
||||||
|
|
||||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
result = (oidvector *) palloc0(OidVectorSize(FUNC_MAX_ARGS));
|
||||||
|
|
||||||
|
for (n = 0; n < FUNC_MAX_ARGS; n++)
|
||||||
{
|
{
|
||||||
while (*oidString && isspace((unsigned char) *oidString))
|
while (*oidString && isspace((unsigned char) *oidString))
|
||||||
oidString++;
|
oidString++;
|
||||||
if (*oidString == '\0')
|
if (*oidString == '\0')
|
||||||
break;
|
break;
|
||||||
result[slot] = oidin_subr("oidvectorin", oidString, &oidString);
|
result->values[n] = oidin_subr("oidvectorin", oidString, &oidString);
|
||||||
}
|
}
|
||||||
while (*oidString && isspace((unsigned char) *oidString))
|
while (*oidString && isspace((unsigned char) *oidString))
|
||||||
oidString++;
|
oidString++;
|
||||||
@ -179,8 +210,13 @@ oidvectorin(PG_FUNCTION_ARGS)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("oidvector has too many elements")));
|
errmsg("oidvector has too many elements")));
|
||||||
while (slot < INDEX_MAX_KEYS)
|
|
||||||
result[slot++] = InvalidOid;
|
result->size = OidVectorSize(n);
|
||||||
|
result->ndim = 1;
|
||||||
|
result->flags = 0;
|
||||||
|
result->elemtype = OIDOID;
|
||||||
|
result->dim1 = n;
|
||||||
|
result->lbound1 = 0;
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
@ -191,24 +227,19 @@ oidvectorin(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
oidvectorout(PG_FUNCTION_ARGS)
|
oidvectorout(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
|
oidvector *oidArray = (oidvector *) PG_GETARG_POINTER(0);
|
||||||
int num,
|
int num,
|
||||||
maxnum;
|
nnums = oidArray->dim1;
|
||||||
char *rp;
|
char *rp;
|
||||||
char *result;
|
char *result;
|
||||||
|
|
||||||
/* find last non-zero value in vector */
|
|
||||||
for (maxnum = INDEX_MAX_KEYS - 1; maxnum >= 0; maxnum--)
|
|
||||||
if (oidArray[maxnum] != 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* assumes sign, 10 digits, ' ' */
|
/* assumes sign, 10 digits, ' ' */
|
||||||
rp = result = (char *) palloc((maxnum + 1) * 12 + 1);
|
rp = result = (char *) palloc(nnums * 12 + 1);
|
||||||
for (num = 0; num <= maxnum; num++)
|
for (num = 0; num < nnums; num++)
|
||||||
{
|
{
|
||||||
if (num != 0)
|
if (num != 0)
|
||||||
*rp++ = ' ';
|
*rp++ = ' ';
|
||||||
sprintf(rp, "%u", oidArray[num]);
|
sprintf(rp, "%u", oidArray->values[num]);
|
||||||
while (*++rp != '\0')
|
while (*++rp != '\0')
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -223,11 +254,19 @@ Datum
|
|||||||
oidvectorrecv(PG_FUNCTION_ARGS)
|
oidvectorrecv(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||||
Oid *result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
|
oidvector *result;
|
||||||
int slot;
|
|
||||||
|
|
||||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
result = (oidvector *)
|
||||||
result[slot] = (Oid) pq_getmsgint(buf, sizeof(Oid));
|
DatumGetPointer(DirectFunctionCall2(array_recv,
|
||||||
|
PointerGetDatum(buf),
|
||||||
|
ObjectIdGetDatum(OIDOID)));
|
||||||
|
/* sanity checks: oidvector must be 1-D, no nulls */
|
||||||
|
if (result->ndim != 1 ||
|
||||||
|
result->flags != 0 ||
|
||||||
|
result->elemtype != OIDOID)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||||
|
errmsg("invalid oidvector data")));
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,14 +276,7 @@ oidvectorrecv(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
oidvectorsend(PG_FUNCTION_ARGS)
|
oidvectorsend(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
|
return array_send(fcinfo);
|
||||||
StringInfoData buf;
|
|
||||||
int slot;
|
|
||||||
|
|
||||||
pq_begintypsend(&buf);
|
|
||||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
|
||||||
pq_sendint(&buf, oidArray[slot], sizeof(Oid));
|
|
||||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -327,71 +359,49 @@ oidsmaller(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
oidvectoreq(PG_FUNCTION_ARGS)
|
oidvectoreq(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
|
||||||
|
|
||||||
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) == 0);
|
PG_RETURN_BOOL(cmp == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
oidvectorne(PG_FUNCTION_ARGS)
|
oidvectorne(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
|
||||||
|
|
||||||
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) != 0);
|
PG_RETURN_BOOL(cmp != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
oidvectorlt(PG_FUNCTION_ARGS)
|
oidvectorlt(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
PG_RETURN_BOOL(cmp < 0);
|
||||||
if (arg1[i] != arg2[i])
|
|
||||||
PG_RETURN_BOOL(arg1[i] < arg2[i]);
|
|
||||||
PG_RETURN_BOOL(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
oidvectorle(PG_FUNCTION_ARGS)
|
oidvectorle(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
PG_RETURN_BOOL(cmp <= 0);
|
||||||
if (arg1[i] != arg2[i])
|
|
||||||
PG_RETURN_BOOL(arg1[i] <= arg2[i]);
|
|
||||||
PG_RETURN_BOOL(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
oidvectorge(PG_FUNCTION_ARGS)
|
oidvectorge(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
PG_RETURN_BOOL(cmp >= 0);
|
||||||
if (arg1[i] != arg2[i])
|
|
||||||
PG_RETURN_BOOL(arg1[i] >= arg2[i]);
|
|
||||||
PG_RETURN_BOOL(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
oidvectorgt(PG_FUNCTION_ARGS)
|
oidvectorgt(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
PG_RETURN_BOOL(cmp > 0);
|
||||||
if (arg1[i] != arg2[i])
|
|
||||||
PG_RETURN_BOOL(arg1[i] > arg2[i]);
|
|
||||||
PG_RETURN_BOOL(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.92 2004/12/31 22:01:22 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.93 2005/03/29 00:17:08 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -98,7 +98,7 @@ regprocin(PG_FUNCTION_ARGS)
|
|||||||
CStringGetDatum(pro_name_or_oid));
|
CStringGetDatum(pro_name_or_oid));
|
||||||
|
|
||||||
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
|
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
|
||||||
sysscan = systable_beginscan(hdesc, ProcedureNameNspIndex, true,
|
sysscan = systable_beginscan(hdesc, ProcedureNameArgsNspIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
|
||||||
while (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
|
while (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
|
||||||
@ -336,7 +336,7 @@ format_procedure(Oid procedure_oid)
|
|||||||
quote_qualified_identifier(nspname, proname));
|
quote_qualified_identifier(nspname, proname));
|
||||||
for (i = 0; i < nargs; i++)
|
for (i = 0; i < nargs; i++)
|
||||||
{
|
{
|
||||||
Oid thisargtype = procform->proargtypes[i];
|
Oid thisargtype = procform->proargtypes.values[i];
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
appendStringInfoChar(&buf, ',');
|
appendStringInfoChar(&buf, ',');
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* back to source text
|
* back to source text
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.188 2005/01/13 17:19:10 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.189 2005/03/29 00:17:08 tgl Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -553,9 +553,10 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
|
|||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
val = (bytea *) fastgetattr(ht_trig,
|
val = (bytea *)
|
||||||
Anum_pg_trigger_tgargs,
|
DatumGetPointer(fastgetattr(ht_trig,
|
||||||
tgrel->rd_att, &isnull);
|
Anum_pg_trigger_tgargs,
|
||||||
|
tgrel->rd_att, &isnull));
|
||||||
if (isnull)
|
if (isnull)
|
||||||
elog(ERROR, "tgargs is null for trigger %u", trigid);
|
elog(ERROR, "tgargs is null for trigger %u", trigid);
|
||||||
p = (char *) VARDATA(val);
|
p = (char *) VARDATA(val);
|
||||||
@ -637,6 +638,9 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
|||||||
Oid indrelid;
|
Oid indrelid;
|
||||||
int keyno;
|
int keyno;
|
||||||
Oid keycoltype;
|
Oid keycoltype;
|
||||||
|
Datum indclassDatum;
|
||||||
|
bool isnull;
|
||||||
|
oidvector *indclass;
|
||||||
StringInfoData buf;
|
StringInfoData buf;
|
||||||
char *str;
|
char *str;
|
||||||
char *sep;
|
char *sep;
|
||||||
@ -654,6 +658,12 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
|||||||
indrelid = idxrec->indrelid;
|
indrelid = idxrec->indrelid;
|
||||||
Assert(indexrelid == idxrec->indexrelid);
|
Assert(indexrelid == idxrec->indexrelid);
|
||||||
|
|
||||||
|
/* Must get indclass the hard way */
|
||||||
|
indclassDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
|
||||||
|
Anum_pg_index_indclass, &isnull);
|
||||||
|
Assert(!isnull);
|
||||||
|
indclass = (oidvector *) DatumGetPointer(indclassDatum);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch the pg_class tuple of the index relation
|
* Fetch the pg_class tuple of the index relation
|
||||||
*/
|
*/
|
||||||
@ -720,7 +730,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
|||||||
sep = "";
|
sep = "";
|
||||||
for (keyno = 0; keyno < idxrec->indnatts; keyno++)
|
for (keyno = 0; keyno < idxrec->indnatts; keyno++)
|
||||||
{
|
{
|
||||||
AttrNumber attnum = idxrec->indkey[keyno];
|
AttrNumber attnum = idxrec->indkey.values[keyno];
|
||||||
|
|
||||||
if (!colno)
|
if (!colno)
|
||||||
appendStringInfo(&buf, sep);
|
appendStringInfo(&buf, sep);
|
||||||
@ -764,7 +774,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
|||||||
* Add the operator class name
|
* Add the operator class name
|
||||||
*/
|
*/
|
||||||
if (!colno)
|
if (!colno)
|
||||||
get_opclass_name(idxrec->indclass[keyno], keycoltype,
|
get_opclass_name(indclass->values[keyno], keycoltype,
|
||||||
&buf);
|
&buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3537,7 +3547,10 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
|
|||||||
nargs = 0;
|
nargs = 0;
|
||||||
foreach(l, expr->args)
|
foreach(l, expr->args)
|
||||||
{
|
{
|
||||||
Assert(nargs < FUNC_MAX_ARGS);
|
if (nargs >= FUNC_MAX_ARGS)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
|
||||||
|
errmsg("too many arguments")));
|
||||||
argtypes[nargs] = exprType((Node *) lfirst(l));
|
argtypes[nargs] = exprType((Node *) lfirst(l));
|
||||||
nargs++;
|
nargs++;
|
||||||
}
|
}
|
||||||
|
31
src/backend/utils/cache/lsyscache.c
vendored
31
src/backend/utils/cache/lsyscache.c
vendored
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.120 2005/01/27 23:36:12 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.121 2005/03/29 00:17:11 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
@ -773,15 +773,36 @@ get_func_rettype(Oid funcid)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_func_nargs
|
||||||
|
* Given procedure id, return the number of arguments.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
get_func_nargs(Oid funcid)
|
||||||
|
{
|
||||||
|
HeapTuple tp;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
tp = SearchSysCache(PROCOID,
|
||||||
|
ObjectIdGetDatum(funcid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tp))
|
||||||
|
elog(ERROR, "cache lookup failed for function %u", funcid);
|
||||||
|
|
||||||
|
result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;
|
||||||
|
ReleaseSysCache(tp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_func_signature
|
* get_func_signature
|
||||||
* Given procedure id, return the function's argument and result types.
|
* Given procedure id, return the function's argument and result types.
|
||||||
* (The return value is the result type.)
|
* (The return value is the result type.)
|
||||||
*
|
*
|
||||||
* argtypes must point to a vector of size FUNC_MAX_ARGS.
|
* The arguments are returned as a palloc'd array.
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
get_func_signature(Oid funcid, Oid *argtypes, int *nargs)
|
get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
|
||||||
{
|
{
|
||||||
HeapTuple tp;
|
HeapTuple tp;
|
||||||
Form_pg_proc procstruct;
|
Form_pg_proc procstruct;
|
||||||
@ -796,8 +817,10 @@ get_func_signature(Oid funcid, Oid *argtypes, int *nargs)
|
|||||||
procstruct = (Form_pg_proc) GETSTRUCT(tp);
|
procstruct = (Form_pg_proc) GETSTRUCT(tp);
|
||||||
|
|
||||||
result = procstruct->prorettype;
|
result = procstruct->prorettype;
|
||||||
memcpy(argtypes, procstruct->proargtypes, FUNC_MAX_ARGS * sizeof(Oid));
|
|
||||||
*nargs = (int) procstruct->pronargs;
|
*nargs = (int) procstruct->pronargs;
|
||||||
|
Assert(*nargs == procstruct->proargtypes.dim1);
|
||||||
|
*argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
|
||||||
|
memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));
|
||||||
|
|
||||||
ReleaseSysCache(tp);
|
ReleaseSysCache(tp);
|
||||||
return result;
|
return result;
|
||||||
|
117
src/backend/utils/cache/relcache.c
vendored
117
src/backend/utils/cache/relcache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.217 2005/03/28 00:58:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.218 2005/03/29 00:17:11 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -27,7 +27,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -81,6 +80,7 @@ static FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
|
|||||||
static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
|
static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
|
||||||
static FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
|
static FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
|
||||||
static FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
|
static FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
|
||||||
|
static FormData_pg_attribute Desc_pg_index[Natts_pg_index] = {Schema_pg_index};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hash tables that index the relation cache
|
* Hash tables that index the relation cache
|
||||||
@ -267,10 +267,11 @@ static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
|||||||
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
|
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
|
||||||
Relation oldrelation);
|
Relation oldrelation);
|
||||||
static void RelationInitPhysicalAddr(Relation relation);
|
static void RelationInitPhysicalAddr(Relation relation);
|
||||||
|
static TupleDesc GetPgIndexDescriptor(void);
|
||||||
static void AttrDefaultFetch(Relation relation);
|
static void AttrDefaultFetch(Relation relation);
|
||||||
static void CheckConstraintFetch(Relation relation);
|
static void CheckConstraintFetch(Relation relation);
|
||||||
static List *insert_ordered_oid(List *list, Oid datum);
|
static List *insert_ordered_oid(List *list, Oid datum);
|
||||||
static void IndexSupportInitialize(Form_pg_index iform,
|
static void IndexSupportInitialize(oidvector *indclass,
|
||||||
Oid *indexOperator,
|
Oid *indexOperator,
|
||||||
RegProcedure *indexSupport,
|
RegProcedure *indexSupport,
|
||||||
StrategyNumber maxStrategyNumber,
|
StrategyNumber maxStrategyNumber,
|
||||||
@ -918,6 +919,8 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
{
|
{
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Form_pg_am aform;
|
Form_pg_am aform;
|
||||||
|
Datum indclassDatum;
|
||||||
|
bool isnull;
|
||||||
MemoryContext indexcxt;
|
MemoryContext indexcxt;
|
||||||
MemoryContext oldcontext;
|
MemoryContext oldcontext;
|
||||||
Oid *operator;
|
Oid *operator;
|
||||||
@ -945,6 +948,18 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* indclass cannot be referenced directly through the C struct, because
|
||||||
|
* it is after the variable-width indkey field. Therefore we extract
|
||||||
|
* the datum the hard way and provide a direct link in the relcache.
|
||||||
|
*/
|
||||||
|
indclassDatum = fastgetattr(relation->rd_indextuple,
|
||||||
|
Anum_pg_index_indclass,
|
||||||
|
GetPgIndexDescriptor(),
|
||||||
|
&isnull);
|
||||||
|
Assert(!isnull);
|
||||||
|
relation->rd_indclass = (oidvector *) DatumGetPointer(indclassDatum);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make a copy of the pg_am entry for the index's access method
|
* Make a copy of the pg_am entry for the index's access method
|
||||||
*/
|
*/
|
||||||
@ -1014,7 +1029,7 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
* Fill the operator and support procedure OID arrays. (supportinfo is
|
* Fill the operator and support procedure OID arrays. (supportinfo is
|
||||||
* left as zeroes, and is filled on-the-fly when used)
|
* left as zeroes, and is filled on-the-fly when used)
|
||||||
*/
|
*/
|
||||||
IndexSupportInitialize(relation->rd_index,
|
IndexSupportInitialize(relation->rd_indclass,
|
||||||
operator, support,
|
operator, support,
|
||||||
amstrategies, amsupport, natts);
|
amstrategies, amsupport, natts);
|
||||||
|
|
||||||
@ -1028,7 +1043,7 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
/*
|
/*
|
||||||
* IndexSupportInitialize
|
* IndexSupportInitialize
|
||||||
* Initializes an index's cached opclass information,
|
* Initializes an index's cached opclass information,
|
||||||
* given the index's pg_index tuple.
|
* given the index's pg_index.indclass entry.
|
||||||
*
|
*
|
||||||
* Data is returned into *indexOperator and *indexSupport, which are arrays
|
* Data is returned into *indexOperator and *indexSupport, which are arrays
|
||||||
* allocated by the caller.
|
* allocated by the caller.
|
||||||
@ -1040,7 +1055,7 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
* access method.
|
* access method.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
IndexSupportInitialize(Form_pg_index iform,
|
IndexSupportInitialize(oidvector *indclass,
|
||||||
Oid *indexOperator,
|
Oid *indexOperator,
|
||||||
RegProcedure *indexSupport,
|
RegProcedure *indexSupport,
|
||||||
StrategyNumber maxStrategyNumber,
|
StrategyNumber maxStrategyNumber,
|
||||||
@ -1049,19 +1064,15 @@ IndexSupportInitialize(Form_pg_index iform,
|
|||||||
{
|
{
|
||||||
int attIndex;
|
int attIndex;
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX note that the following assumes the INDEX tuple is well formed
|
|
||||||
* and that the *key and *class are 0 terminated.
|
|
||||||
*/
|
|
||||||
for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
|
for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
|
||||||
{
|
{
|
||||||
OpClassCacheEnt *opcentry;
|
OpClassCacheEnt *opcentry;
|
||||||
|
|
||||||
if (!OidIsValid(iform->indclass[attIndex]))
|
if (!OidIsValid(indclass->values[attIndex]))
|
||||||
elog(ERROR, "bogus pg_index tuple");
|
elog(ERROR, "bogus pg_index tuple");
|
||||||
|
|
||||||
/* look up the info for this opclass, using a cache */
|
/* look up the info for this opclass, using a cache */
|
||||||
opcentry = LookupOpclassInfo(iform->indclass[attIndex],
|
opcentry = LookupOpclassInfo(indclass->values[attIndex],
|
||||||
maxStrategyNumber,
|
maxStrategyNumber,
|
||||||
maxSupportNumber);
|
maxSupportNumber);
|
||||||
|
|
||||||
@ -2479,6 +2490,53 @@ RelationCacheInitializePhase3(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetPgIndexDescriptor -- get a predefined tuple descriptor for pg_index
|
||||||
|
*
|
||||||
|
* We need this kluge because we have to be able to access non-fixed-width
|
||||||
|
* fields of pg_index before we have the standard catalog caches available.
|
||||||
|
* We use predefined data that's set up in just the same way as the
|
||||||
|
* bootstrapped reldescs used by formrdesc(). The resulting tupdesc is
|
||||||
|
* not 100% kosher: it does not have the correct relation OID in attrelid,
|
||||||
|
* nor does it have a TupleConstr field. But it's good enough for the
|
||||||
|
* purpose of extracting fields.
|
||||||
|
*/
|
||||||
|
static TupleDesc
|
||||||
|
GetPgIndexDescriptor(void)
|
||||||
|
{
|
||||||
|
static TupleDesc pgindexdesc = NULL;
|
||||||
|
MemoryContext oldcxt;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Already done? */
|
||||||
|
if (pgindexdesc)
|
||||||
|
return pgindexdesc;
|
||||||
|
|
||||||
|
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
|
||||||
|
pgindexdesc = CreateTemplateTupleDesc(Natts_pg_index, false);
|
||||||
|
pgindexdesc->tdtypeid = RECORDOID; /* not right, but we don't care */
|
||||||
|
pgindexdesc->tdtypmod = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < Natts_pg_index; i++)
|
||||||
|
{
|
||||||
|
memcpy(pgindexdesc->attrs[i],
|
||||||
|
&Desc_pg_index[i],
|
||||||
|
ATTRIBUTE_TUPLE_SIZE);
|
||||||
|
/* make sure attcacheoff is valid */
|
||||||
|
pgindexdesc->attrs[i]->attcacheoff = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
|
||||||
|
pgindexdesc->attrs[0]->attcacheoff = 0;
|
||||||
|
|
||||||
|
/* Note: we don't bother to set up a TupleConstr entry */
|
||||||
|
|
||||||
|
MemoryContextSwitchTo(oldcxt);
|
||||||
|
|
||||||
|
return pgindexdesc;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
AttrDefaultFetch(Relation relation)
|
AttrDefaultFetch(Relation relation)
|
||||||
{
|
{
|
||||||
@ -2773,15 +2831,11 @@ RelationGetIndexExpressions(Relation relation)
|
|||||||
* After successfully completing the work, we copy it into the
|
* After successfully completing the work, we copy it into the
|
||||||
* relcache entry. This avoids problems if we get some sort of error
|
* relcache entry. This avoids problems if we get some sort of error
|
||||||
* partway through.
|
* partway through.
|
||||||
*
|
|
||||||
* We make use of the syscache's copy of pg_index's tupledesc to access
|
|
||||||
* the non-fixed fields of the tuple. We assume that the syscache
|
|
||||||
* will be initialized before any access of a partial index could
|
|
||||||
* occur. (This would probably fail if we were to allow partial
|
|
||||||
* indexes on system catalogs.)
|
|
||||||
*/
|
*/
|
||||||
exprsDatum = SysCacheGetAttr(INDEXRELID, relation->rd_indextuple,
|
exprsDatum = heap_getattr(relation->rd_indextuple,
|
||||||
Anum_pg_index_indexprs, &isnull);
|
Anum_pg_index_indexprs,
|
||||||
|
GetPgIndexDescriptor(),
|
||||||
|
&isnull);
|
||||||
Assert(!isnull);
|
Assert(!isnull);
|
||||||
exprsString = DatumGetCString(DirectFunctionCall1(textout, exprsDatum));
|
exprsString = DatumGetCString(DirectFunctionCall1(textout, exprsDatum));
|
||||||
result = (List *) stringToNode(exprsString);
|
result = (List *) stringToNode(exprsString);
|
||||||
@ -2845,15 +2899,11 @@ RelationGetIndexPredicate(Relation relation)
|
|||||||
* After successfully completing the work, we copy it into the
|
* After successfully completing the work, we copy it into the
|
||||||
* relcache entry. This avoids problems if we get some sort of error
|
* relcache entry. This avoids problems if we get some sort of error
|
||||||
* partway through.
|
* partway through.
|
||||||
*
|
|
||||||
* We make use of the syscache's copy of pg_index's tupledesc to access
|
|
||||||
* the non-fixed fields of the tuple. We assume that the syscache
|
|
||||||
* will be initialized before any access of a partial index could
|
|
||||||
* occur. (This would probably fail if we were to allow partial
|
|
||||||
* indexes on system catalogs.)
|
|
||||||
*/
|
*/
|
||||||
predDatum = SysCacheGetAttr(INDEXRELID, relation->rd_indextuple,
|
predDatum = heap_getattr(relation->rd_indextuple,
|
||||||
Anum_pg_index_indpred, &isnull);
|
Anum_pg_index_indpred,
|
||||||
|
GetPgIndexDescriptor(),
|
||||||
|
&isnull);
|
||||||
Assert(!isnull);
|
Assert(!isnull);
|
||||||
predString = DatumGetCString(DirectFunctionCall1(textout, predDatum));
|
predString = DatumGetCString(DirectFunctionCall1(textout, predDatum));
|
||||||
result = (List *) stringToNode(predString);
|
result = (List *) stringToNode(predString);
|
||||||
@ -2990,6 +3040,8 @@ load_relcache_init_file(void)
|
|||||||
Relation rel;
|
Relation rel;
|
||||||
Form_pg_class relform;
|
Form_pg_class relform;
|
||||||
bool has_not_null;
|
bool has_not_null;
|
||||||
|
Datum indclassDatum;
|
||||||
|
bool isnull;
|
||||||
|
|
||||||
/* first read the relation descriptor length */
|
/* first read the relation descriptor length */
|
||||||
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
|
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
|
||||||
@ -3081,6 +3133,14 @@ load_relcache_init_file(void)
|
|||||||
rel->rd_indextuple->t_data = (HeapTupleHeader) ((char *) rel->rd_indextuple + HEAPTUPLESIZE);
|
rel->rd_indextuple->t_data = (HeapTupleHeader) ((char *) rel->rd_indextuple + HEAPTUPLESIZE);
|
||||||
rel->rd_index = (Form_pg_index) GETSTRUCT(rel->rd_indextuple);
|
rel->rd_index = (Form_pg_index) GETSTRUCT(rel->rd_indextuple);
|
||||||
|
|
||||||
|
/* fix up indclass pointer too */
|
||||||
|
indclassDatum = fastgetattr(rel->rd_indextuple,
|
||||||
|
Anum_pg_index_indclass,
|
||||||
|
GetPgIndexDescriptor(),
|
||||||
|
&isnull);
|
||||||
|
Assert(!isnull);
|
||||||
|
rel->rd_indclass = (oidvector *) DatumGetPointer(indclassDatum);
|
||||||
|
|
||||||
/* next, read the access method tuple form */
|
/* next, read the access method tuple form */
|
||||||
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
|
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
|
||||||
goto read_failed;
|
goto read_failed;
|
||||||
@ -3133,6 +3193,7 @@ load_relcache_init_file(void)
|
|||||||
|
|
||||||
Assert(rel->rd_index == NULL);
|
Assert(rel->rd_index == NULL);
|
||||||
Assert(rel->rd_indextuple == NULL);
|
Assert(rel->rd_indextuple == NULL);
|
||||||
|
Assert(rel->rd_indclass == NULL);
|
||||||
Assert(rel->rd_am == NULL);
|
Assert(rel->rd_am == NULL);
|
||||||
Assert(rel->rd_indexcxt == NULL);
|
Assert(rel->rd_indexcxt == NULL);
|
||||||
Assert(rel->rd_operator == NULL);
|
Assert(rel->rd_operator == NULL);
|
||||||
|
12
src/backend/utils/cache/syscache.c
vendored
12
src/backend/utils/cache/syscache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.96 2004/12/31 22:01:25 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.97 2005/03/29 00:17:12 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* These routines allow the parser/planner/executor to perform
|
* These routines allow the parser/planner/executor to perform
|
||||||
@ -334,15 +334,15 @@ static const struct cachedesc cacheinfo[] = {
|
|||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
}},
|
}},
|
||||||
{ProcedureRelationName, /* PROCNAMENSP */
|
{ProcedureRelationName, /* PROCNAMEARGSNSP */
|
||||||
ProcedureNameNspIndex,
|
ProcedureNameArgsNspIndex,
|
||||||
0,
|
0,
|
||||||
4,
|
3,
|
||||||
{
|
{
|
||||||
Anum_pg_proc_proname,
|
Anum_pg_proc_proname,
|
||||||
Anum_pg_proc_pronargs,
|
|
||||||
Anum_pg_proc_proargtypes,
|
Anum_pg_proc_proargtypes,
|
||||||
Anum_pg_proc_pronamespace
|
Anum_pg_proc_pronamespace,
|
||||||
|
0
|
||||||
}},
|
}},
|
||||||
{ProcedureRelationName, /* PROCOID */
|
{ProcedureRelationName, /* PROCOID */
|
||||||
ProcedureOidIndex,
|
ProcedureOidIndex,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.90 2005/03/22 20:13:07 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.91 2005/03/29 00:17:15 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -344,7 +344,7 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
|
|||||||
for (i = 0; i < procedureStruct->pronargs; i++)
|
for (i = 0; i < procedureStruct->pronargs; i++)
|
||||||
{
|
{
|
||||||
fnextra->arg_toastable[i] =
|
fnextra->arg_toastable[i] =
|
||||||
TypeIsToastable(procedureStruct->proargtypes[i]);
|
TypeIsToastable(procedureStruct->proargtypes.values[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/c.h,v 1.180 2005/02/22 04:41:51 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/c.h,v 1.181 2005/03/29 00:17:16 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -428,11 +428,36 @@ typedef struct varlena BpChar; /* blank-padded char, ie SQL char(n) */
|
|||||||
typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */
|
typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fixed-length array types (these are not varlena's!)
|
* Specialized array types. These are physically laid out just the same
|
||||||
|
* as regular arrays (so that the regular array subscripting code works
|
||||||
|
* with them). They exist as distinct types mostly for historical reasons:
|
||||||
|
* they have nonstandard I/O behavior which we don't want to change for fear
|
||||||
|
* of breaking applications that look at the system catalogs. There is also
|
||||||
|
* an implementation issue for oidvector: it's part of the primary key for
|
||||||
|
* pg_proc, and we can't use the normal btree array support routines for that
|
||||||
|
* without circularity.
|
||||||
*/
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32 size; /* these fields must match ArrayType! */
|
||||||
|
int ndim;
|
||||||
|
int flags;
|
||||||
|
Oid elemtype;
|
||||||
|
int dim1;
|
||||||
|
int lbound1;
|
||||||
|
int2 values[1]; /* VARIABLE LENGTH ARRAY */
|
||||||
|
} int2vector; /* VARIABLE LENGTH STRUCT */
|
||||||
|
|
||||||
typedef int2 int2vector[INDEX_MAX_KEYS];
|
typedef struct
|
||||||
typedef Oid oidvector[INDEX_MAX_KEYS];
|
{
|
||||||
|
int32 size; /* these fields must match ArrayType! */
|
||||||
|
int ndim;
|
||||||
|
int flags;
|
||||||
|
Oid elemtype;
|
||||||
|
int dim1;
|
||||||
|
int lbound1;
|
||||||
|
Oid values[1]; /* VARIABLE LENGTH ARRAY */
|
||||||
|
} oidvector; /* VARIABLE LENGTH STRUCT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want NameData to have length NAMEDATALEN and int alignment,
|
* We want NameData to have length NAMEDATALEN and int alignment,
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.260 2005/03/27 23:53:05 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.261 2005/03/29 00:17:16 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200503271
|
#define CATALOG_VERSION_NO 200503281
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.84 2004/12/31 22:03:24 pgsql Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.85 2005/03/29 00:17:17 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -63,7 +63,7 @@
|
|||||||
#define OpclassOidIndex "pg_opclass_oid_index"
|
#define OpclassOidIndex "pg_opclass_oid_index"
|
||||||
#define OperatorNameNspIndex "pg_operator_oprname_l_r_n_index"
|
#define OperatorNameNspIndex "pg_operator_oprname_l_r_n_index"
|
||||||
#define OperatorOidIndex "pg_operator_oid_index"
|
#define OperatorOidIndex "pg_operator_oid_index"
|
||||||
#define ProcedureNameNspIndex "pg_proc_proname_args_nsp_index"
|
#define ProcedureNameArgsNspIndex "pg_proc_proname_args_nsp_index"
|
||||||
#define ProcedureOidIndex "pg_proc_oid_index"
|
#define ProcedureOidIndex "pg_proc_oid_index"
|
||||||
#define RewriteOidIndex "pg_rewrite_oid_index"
|
#define RewriteOidIndex "pg_rewrite_oid_index"
|
||||||
#define RewriteRelRulenameIndex "pg_rewrite_rel_rulename_index"
|
#define RewriteRelRulenameIndex "pg_rewrite_rel_rulename_index"
|
||||||
@ -161,7 +161,7 @@ DECLARE_UNIQUE_INDEX(pg_opclass_oid_index on pg_opclass using btree(oid oid_ops)
|
|||||||
DECLARE_UNIQUE_INDEX(pg_operator_oid_index on pg_operator using btree(oid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_operator_oid_index on pg_operator using btree(oid oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_n_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprnamespace oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_n_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprnamespace oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_proc_oid_index on pg_proc using btree(oid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_proc_oid_index on pg_proc using btree(oid oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_proc_proname_args_nsp_index on pg_proc using btree(proname name_ops, pronargs int2_ops, proargtypes oidvector_ops, pronamespace oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_proc_proname_args_nsp_index on pg_proc using btree(proname name_ops, proargtypes oidvector_ops, pronamespace oid_ops));
|
||||||
/* This following index is not used for a cache and is not unique */
|
/* This following index is not used for a cache and is not unique */
|
||||||
DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index on pg_rewrite using btree(oid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index on pg_rewrite using btree(oid oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index on pg_rewrite using btree(ev_class oid_ops, rulename name_ops));
|
DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index on pg_rewrite using btree(ev_class oid_ops, rulename name_ops));
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.113 2004/12/31 22:03:24 pgsql Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.114 2005/03/29 00:17:17 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -317,7 +317,7 @@ DATA(insert ( 1262 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
|
|||||||
{ 1255, {"provolatile"}, 18, -1, 1, 9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
|
{ 1255, {"provolatile"}, 18, -1, 1, 9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
|
||||||
{ 1255, {"pronargs"}, 21, -1, 2, 10, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
|
{ 1255, {"pronargs"}, 21, -1, 2, 10, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
|
||||||
{ 1255, {"prorettype"}, 26, -1, 4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
|
{ 1255, {"prorettype"}, 26, -1, 4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
|
||||||
{ 1255, {"proargtypes"}, 30, -1, INDEX_MAX_KEYS*4, 12, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
|
{ 1255, {"proargtypes"}, 30, -1, -1, 12, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
|
||||||
{ 1255, {"proargnames"}, 1009, -1, -1, 13, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
|
{ 1255, {"proargnames"}, 1009, -1, -1, 13, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
|
||||||
{ 1255, {"prosrc"}, 25, -1, -1, 14, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
|
{ 1255, {"prosrc"}, 25, -1, -1, 14, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
|
||||||
{ 1255, {"probin"}, 17, -1, -1, 15, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
|
{ 1255, {"probin"}, 17, -1, -1, 15, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
|
||||||
@ -334,7 +334,7 @@ DATA(insert ( 1255 proretset 16 -1 1 8 0 -1 -1 t p c t f f t 0));
|
|||||||
DATA(insert ( 1255 provolatile 18 -1 1 9 0 -1 -1 t p c t f f t 0));
|
DATA(insert ( 1255 provolatile 18 -1 1 9 0 -1 -1 t p c t f f t 0));
|
||||||
DATA(insert ( 1255 pronargs 21 -1 2 10 0 -1 -1 t p s t f f t 0));
|
DATA(insert ( 1255 pronargs 21 -1 2 10 0 -1 -1 t p s t f f t 0));
|
||||||
DATA(insert ( 1255 prorettype 26 -1 4 11 0 -1 -1 t p i t f f t 0));
|
DATA(insert ( 1255 prorettype 26 -1 4 11 0 -1 -1 t p i t f f t 0));
|
||||||
DATA(insert ( 1255 proargtypes 30 -1 INDEX_MAX_KEYS*4 12 0 -1 -1 f p i t f f t 0));
|
DATA(insert ( 1255 proargtypes 30 -1 -1 12 1 -1 -1 f p i t f f t 0));
|
||||||
DATA(insert ( 1255 proargnames 1009 -1 -1 13 1 -1 -1 f x i f f f t 0));
|
DATA(insert ( 1255 proargnames 1009 -1 -1 13 1 -1 -1 f x i f f f t 0));
|
||||||
DATA(insert ( 1255 prosrc 25 -1 -1 14 0 -1 -1 f x i f f f t 0));
|
DATA(insert ( 1255 prosrc 25 -1 -1 14 0 -1 -1 f x i f f f t 0));
|
||||||
DATA(insert ( 1255 probin 17 -1 -1 15 0 -1 -1 f x i f f f t 0));
|
DATA(insert ( 1255 probin 17 -1 -1 15 0 -1 -1 f x i f f f t 0));
|
||||||
@ -511,6 +511,26 @@ DATA(insert ( 1213 xmax 28 0 4 -5 0 -1 -1 t p i t f f t 0));
|
|||||||
DATA(insert ( 1213 cmax 29 0 4 -6 0 -1 -1 t p i t f f t 0));
|
DATA(insert ( 1213 cmax 29 0 4 -6 0 -1 -1 t p i t f f t 0));
|
||||||
DATA(insert ( 1213 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
|
DATA(insert ( 1213 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* pg_index
|
||||||
|
*
|
||||||
|
* pg_index is not bootstrapped in the same way as the other relations that
|
||||||
|
* have hardwired pg_attribute entries in this file. However, we do need
|
||||||
|
* a "Schema_xxx" macro for it --- see relcache.c.
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
#define Schema_pg_index \
|
||||||
|
{ 0, {"indexrelid"}, 26, -1, 4, 1, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
|
||||||
|
{ 0, {"indrelid"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
|
||||||
|
{ 0, {"indnatts"}, 21, -1, 2, 3, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
|
||||||
|
{ 0, {"indisunique"}, 16, -1, 1, 4, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
|
||||||
|
{ 0, {"indisprimary"}, 16, -1, 1, 5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
|
||||||
|
{ 0, {"indisclustered"}, 16, -1, 1, 6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
|
||||||
|
{ 0, {"indkey"}, 22, -1, -1, 7, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
|
||||||
|
{ 0, {"indclass"}, 30, -1, -1, 8, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
|
||||||
|
{ 0, {"indexprs"}, 25, -1, -1, 9, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
|
||||||
|
{ 0, {"indpred"}, 25, -1, -1, 10, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* pg_xactlock - this is not a real relation, but is a placeholder
|
* pg_xactlock - this is not a real relation, but is a placeholder
|
||||||
* to allow a relation OID to be used for transaction
|
* to allow a relation OID to be used for transaction
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_index.h,v 1.35 2004/12/31 22:03:24 pgsql Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_index.h,v 1.36 2005/03/29 00:17:17 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -35,14 +35,14 @@ CATALOG(pg_index) BKI_WITHOUT_OIDS
|
|||||||
{
|
{
|
||||||
Oid indexrelid; /* OID of the index */
|
Oid indexrelid; /* OID of the index */
|
||||||
Oid indrelid; /* OID of the relation it indexes */
|
Oid indrelid; /* OID of the relation it indexes */
|
||||||
int2vector indkey; /* column numbers of indexed cols, or 0 */
|
|
||||||
oidvector indclass; /* opclass identifiers */
|
|
||||||
int2 indnatts; /* number of columns in index */
|
int2 indnatts; /* number of columns in index */
|
||||||
bool indisunique; /* is this a unique index? */
|
bool indisunique; /* is this a unique index? */
|
||||||
bool indisprimary; /* is this index for primary key? */
|
bool indisprimary; /* is this index for primary key? */
|
||||||
bool indisclustered; /* is this the index last clustered by? */
|
bool indisclustered; /* is this the index last clustered by? */
|
||||||
|
|
||||||
/* VARIABLE LENGTH FIELDS: */
|
/* VARIABLE LENGTH FIELDS: */
|
||||||
|
int2vector indkey; /* column numbers of indexed cols, or 0 */
|
||||||
|
oidvector indclass; /* opclass identifiers */
|
||||||
text indexprs; /* expression trees for index attributes
|
text indexprs; /* expression trees for index attributes
|
||||||
* that are not simple column references;
|
* that are not simple column references;
|
||||||
* one for each zero entry in indkey[] */
|
* one for each zero entry in indkey[] */
|
||||||
@ -64,12 +64,12 @@ typedef FormData_pg_index *Form_pg_index;
|
|||||||
#define Natts_pg_index 10
|
#define Natts_pg_index 10
|
||||||
#define Anum_pg_index_indexrelid 1
|
#define Anum_pg_index_indexrelid 1
|
||||||
#define Anum_pg_index_indrelid 2
|
#define Anum_pg_index_indrelid 2
|
||||||
#define Anum_pg_index_indkey 3
|
#define Anum_pg_index_indnatts 3
|
||||||
#define Anum_pg_index_indclass 4
|
#define Anum_pg_index_indisunique 4
|
||||||
#define Anum_pg_index_indnatts 5
|
#define Anum_pg_index_indisprimary 5
|
||||||
#define Anum_pg_index_indisunique 6
|
#define Anum_pg_index_indisclustered 6
|
||||||
#define Anum_pg_index_indisprimary 7
|
#define Anum_pg_index_indkey 7
|
||||||
#define Anum_pg_index_indisclustered 8
|
#define Anum_pg_index_indclass 8
|
||||||
#define Anum_pg_index_indexprs 9
|
#define Anum_pg_index_indexprs 9
|
||||||
#define Anum_pg_index_indpred 10
|
#define Anum_pg_index_indpred 10
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.354 2005/03/27 23:53:05 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.355 2005/03/29 00:17:17 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -48,7 +48,7 @@ CATALOG(pg_proc) BOOTSTRAP
|
|||||||
char provolatile; /* see PROVOLATILE_ categories below */
|
char provolatile; /* see PROVOLATILE_ categories below */
|
||||||
int2 pronargs; /* number of arguments */
|
int2 pronargs; /* number of arguments */
|
||||||
Oid prorettype; /* OID of result type */
|
Oid prorettype; /* OID of result type */
|
||||||
oidvector proargtypes; /* OIDs of argument types */
|
oidvector proargtypes; /* VARIABLE LENGTH FIELD */
|
||||||
text proargnames[1]; /* VARIABLE LENGTH FIELD */
|
text proargnames[1]; /* VARIABLE LENGTH FIELD */
|
||||||
text prosrc; /* VARIABLE LENGTH FIELD */
|
text prosrc; /* VARIABLE LENGTH FIELD */
|
||||||
bytea probin; /* VARIABLE LENGTH FIELD */
|
bytea probin; /* VARIABLE LENGTH FIELD */
|
||||||
|
@ -38,12 +38,12 @@ CATALOG(pg_trigger)
|
|||||||
bool tgisconstraint; /* trigger is a RI constraint */
|
bool tgisconstraint; /* trigger is a RI constraint */
|
||||||
NameData tgconstrname; /* RI constraint name */
|
NameData tgconstrname; /* RI constraint name */
|
||||||
Oid tgconstrrelid; /* RI table of foreign key definition */
|
Oid tgconstrrelid; /* RI table of foreign key definition */
|
||||||
|
|
||||||
/* in the case of ON DELETE or ON UPDATE */
|
|
||||||
bool tgdeferrable; /* RI trigger is deferrable */
|
bool tgdeferrable; /* RI trigger is deferrable */
|
||||||
bool tginitdeferred; /* RI trigger is deferred initially */
|
bool tginitdeferred; /* RI trigger is deferred initially */
|
||||||
int2 tgnargs; /* # of extra arguments in tgargs */
|
int2 tgnargs; /* # of extra arguments in tgargs */
|
||||||
int2vector tgattr; /* UPDATE of attr1, attr2 ... (NI) */
|
|
||||||
|
/* VARIABLE LENGTH FIELDS: */
|
||||||
|
int2vector tgattr; /* reserved for column-specific triggers */
|
||||||
bytea tgargs; /* first\000second\000tgnargs\000 */
|
bytea tgargs; /* first\000second\000tgnargs\000 */
|
||||||
} FormData_pg_trigger;
|
} FormData_pg_trigger;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.158 2004/12/31 22:03:26 pgsql Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.159 2005/03/29 00:17:17 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -88,7 +88,7 @@ CATALOG(pg_type) BOOTSTRAP
|
|||||||
* current type can then be subscripted like an array yielding values
|
* current type can then be subscripted like an array yielding values
|
||||||
* of type typelem. A non-zero typelem does not guarantee this type to
|
* of type typelem. A non-zero typelem does not guarantee this type to
|
||||||
* be a "real" array type; some ordinary fixed-length types can also
|
* be a "real" array type; some ordinary fixed-length types can also
|
||||||
* be subscripted (e.g., oidvector). Variable-length types can *not*
|
* be subscripted (e.g., name, point). Variable-length types can *not*
|
||||||
* be turned into pseudo-arrays like that. Hence, the way to determine
|
* be turned into pseudo-arrays like that. Hence, the way to determine
|
||||||
* whether a type is a "true" array type is if:
|
* whether a type is a "true" array type is if:
|
||||||
*
|
*
|
||||||
@ -268,8 +268,8 @@ DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b t \054 0 0 int2in int2out int2
|
|||||||
DESCR("-32 thousand to 32 thousand, 2-byte storage");
|
DESCR("-32 thousand to 32 thousand, 2-byte storage");
|
||||||
#define INT2OID 21
|
#define INT2OID 21
|
||||||
|
|
||||||
DATA(insert OID = 22 ( int2vector PGNSP PGUID INDEX_MAX_KEYS*2 f b t \054 0 21 int2vectorin int2vectorout int2vectorrecv int2vectorsend - s p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b t \054 0 21 int2vectorin int2vectorout int2vectorrecv int2vectorsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables");
|
DESCR("array of int2, used in system tables");
|
||||||
#define INT2VECTOROID 22
|
#define INT2VECTOROID 22
|
||||||
|
|
||||||
DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 int4in int4out int4recv int4send - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 int4in int4out int4recv int4send - i p f 0 -1 0 _null_ _null_ ));
|
||||||
@ -300,8 +300,8 @@ DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b t \054 0 0 cidin cidout cidrec
|
|||||||
DESCR("command identifier type, sequence in transaction id");
|
DESCR("command identifier type, sequence in transaction id");
|
||||||
#define CIDOID 29
|
#define CIDOID 29
|
||||||
|
|
||||||
DATA(insert OID = 30 ( oidvector PGNSP PGUID INDEX_MAX_KEYS*4 f b t \054 0 26 oidvectorin oidvectorout oidvectorrecv oidvectorsend - i p f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 30 ( oidvector PGNSP PGUID -1 f b t \054 0 26 oidvectorin oidvectorout oidvectorrecv oidvectorsend - i p f 0 -1 0 _null_ _null_ ));
|
||||||
DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
|
DESCR("array of oids, used in system tables");
|
||||||
#define OIDVECTOROID 30
|
#define OIDVECTOROID 30
|
||||||
|
|
||||||
DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c t \054 1247 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ ));
|
DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c t \054 1247 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ ));
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.53 2005/03/24 21:50:38 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.54 2005/03/29 00:17:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -22,6 +22,9 @@
|
|||||||
/*
|
/*
|
||||||
* Arrays are varlena objects, so must meet the varlena convention that
|
* Arrays are varlena objects, so must meet the varlena convention that
|
||||||
* the first int32 of the object contains the total object size in bytes.
|
* the first int32 of the object contains the total object size in bytes.
|
||||||
|
*
|
||||||
|
* CAUTION: if you change the header for ordinary arrays you will also
|
||||||
|
* need to change the headers for oidvector and int2vector!
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.253 2005/02/27 08:31:30 neilc Exp $
|
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.254 2005/03/29 00:17:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -185,6 +185,7 @@ extern Datum int2shl(PG_FUNCTION_ARGS);
|
|||||||
extern Datum int2shr(PG_FUNCTION_ARGS);
|
extern Datum int2shr(PG_FUNCTION_ARGS);
|
||||||
extern Datum generate_series_int4(PG_FUNCTION_ARGS);
|
extern Datum generate_series_int4(PG_FUNCTION_ARGS);
|
||||||
extern Datum generate_series_step_int4(PG_FUNCTION_ARGS);
|
extern Datum generate_series_step_int4(PG_FUNCTION_ARGS);
|
||||||
|
extern int2vector *buildint2vector(const int2 *int2s, int n);
|
||||||
|
|
||||||
/* name.c */
|
/* name.c */
|
||||||
extern Datum namein(PG_FUNCTION_ARGS);
|
extern Datum namein(PG_FUNCTION_ARGS);
|
||||||
@ -392,6 +393,7 @@ extern Datum oidvectorlt(PG_FUNCTION_ARGS);
|
|||||||
extern Datum oidvectorle(PG_FUNCTION_ARGS);
|
extern Datum oidvectorle(PG_FUNCTION_ARGS);
|
||||||
extern Datum oidvectorge(PG_FUNCTION_ARGS);
|
extern Datum oidvectorge(PG_FUNCTION_ARGS);
|
||||||
extern Datum oidvectorgt(PG_FUNCTION_ARGS);
|
extern Datum oidvectorgt(PG_FUNCTION_ARGS);
|
||||||
|
extern oidvector *buildoidvector(const Oid *oids, int n);
|
||||||
|
|
||||||
/* pseudotypes.c */
|
/* pseudotypes.c */
|
||||||
extern Datum cstring_in(PG_FUNCTION_ARGS);
|
extern Datum cstring_in(PG_FUNCTION_ARGS);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.94 2005/01/27 23:36:15 neilc Exp $
|
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.95 2005/03/29 00:17:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -64,7 +64,8 @@ extern RegProcedure get_oprrest(Oid opno);
|
|||||||
extern RegProcedure get_oprjoin(Oid opno);
|
extern RegProcedure get_oprjoin(Oid opno);
|
||||||
extern char *get_func_name(Oid funcid);
|
extern char *get_func_name(Oid funcid);
|
||||||
extern Oid get_func_rettype(Oid funcid);
|
extern Oid get_func_rettype(Oid funcid);
|
||||||
extern Oid get_func_signature(Oid funcid, Oid *argtypes, int *nargs);
|
extern int get_func_nargs(Oid funcid);
|
||||||
|
extern Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs);
|
||||||
extern bool get_func_retset(Oid funcid);
|
extern bool get_func_retset(Oid funcid);
|
||||||
extern bool func_strict(Oid funcid);
|
extern bool func_strict(Oid funcid);
|
||||||
extern char func_volatile(Oid funcid);
|
extern char func_volatile(Oid funcid);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.82 2005/01/10 20:02:24 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.83 2005/03/29 00:17:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -58,7 +58,8 @@ typedef struct Trigger
|
|||||||
bool tgdeferrable;
|
bool tgdeferrable;
|
||||||
bool tginitdeferred;
|
bool tginitdeferred;
|
||||||
int16 tgnargs;
|
int16 tgnargs;
|
||||||
int16 tgattr[FUNC_MAX_ARGS];
|
int16 tgnattr;
|
||||||
|
int16 *tgattr;
|
||||||
char **tgargs;
|
char **tgargs;
|
||||||
} Trigger;
|
} Trigger;
|
||||||
|
|
||||||
@ -137,6 +138,7 @@ typedef struct RelationData
|
|||||||
Form_pg_index rd_index; /* pg_index tuple describing this index */
|
Form_pg_index rd_index; /* pg_index tuple describing this index */
|
||||||
struct HeapTupleData *rd_indextuple; /* all of pg_index tuple */
|
struct HeapTupleData *rd_indextuple; /* all of pg_index tuple */
|
||||||
/* "struct HeapTupleData *" avoids need to include htup.h here */
|
/* "struct HeapTupleData *" avoids need to include htup.h here */
|
||||||
|
oidvector *rd_indclass; /* extracted pointer to rd_index field */
|
||||||
Form_pg_am rd_am; /* pg_am tuple for index's AM */
|
Form_pg_am rd_am; /* pg_am tuple for index's AM */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.58 2004/12/31 22:03:46 pgsql Exp $
|
* $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.59 2005/03/29 00:17:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -52,7 +52,7 @@
|
|||||||
#define NAMESPACEOID 21
|
#define NAMESPACEOID 21
|
||||||
#define OPERNAMENSP 22
|
#define OPERNAMENSP 22
|
||||||
#define OPEROID 23
|
#define OPEROID 23
|
||||||
#define PROCNAMENSP 24
|
#define PROCNAMEARGSNSP 24
|
||||||
#define PROCOID 25
|
#define PROCOID 25
|
||||||
#define RELNAMENSP 26
|
#define RELNAMENSP 26
|
||||||
#define RELOID 27
|
#define RELOID 27
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
* ENHANCEMENTS, OR MODIFICATIONS.
|
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.69 2005/02/23 04:34:05 momjian Exp $
|
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.70 2005/03/29 00:17:20 tgl Exp $
|
||||||
*
|
*
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
@ -1300,14 +1300,14 @@ compile_plperl_function(Oid fn_oid, bool is_trigger)
|
|||||||
for (i = 0; i < prodesc->nargs; i++)
|
for (i = 0; i < prodesc->nargs; i++)
|
||||||
{
|
{
|
||||||
typeTup = SearchSysCache(TYPEOID,
|
typeTup = SearchSysCache(TYPEOID,
|
||||||
ObjectIdGetDatum(procStruct->proargtypes[i]),
|
ObjectIdGetDatum(procStruct->proargtypes.values[i]),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(typeTup))
|
if (!HeapTupleIsValid(typeTup))
|
||||||
{
|
{
|
||||||
free(prodesc->proname);
|
free(prodesc->proname);
|
||||||
free(prodesc);
|
free(prodesc);
|
||||||
elog(ERROR, "cache lookup failed for type %u",
|
elog(ERROR, "cache lookup failed for type %u",
|
||||||
procStruct->proargtypes[i]);
|
procStruct->proargtypes.values[i]);
|
||||||
}
|
}
|
||||||
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
|
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
|
||||||
|
|
||||||
@ -1319,7 +1319,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("plperl functions cannot take type %s",
|
errmsg("plperl functions cannot take type %s",
|
||||||
format_type_be(procStruct->proargtypes[i]))));
|
format_type_be(procStruct->proargtypes.values[i]))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeStruct->typtype == 'c')
|
if (typeStruct->typtype == 'c')
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.84 2005/02/22 07:18:24 neilc Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.85 2005/03/29 00:17:23 tgl Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -1843,7 +1843,7 @@ compute_function_hashkey(FunctionCallInfo fcinfo,
|
|||||||
/* get the argument types */
|
/* get the argument types */
|
||||||
for (i = 0; i < procStruct->pronargs; i++)
|
for (i = 0; i < procStruct->pronargs; i++)
|
||||||
{
|
{
|
||||||
Oid argtypeid = procStruct->proargtypes[i];
|
Oid argtypeid = procStruct->proargtypes.values[i];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for polymorphic arguments. If found, use the actual
|
* Check for polymorphic arguments. If found, use the actual
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.24 2005/02/22 07:18:24 neilc Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.25 2005/03/29 00:17:23 tgl Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -189,16 +189,16 @@ plpgsql_validator(PG_FUNCTION_ARGS)
|
|||||||
haspolyarg = false;
|
haspolyarg = false;
|
||||||
for (i = 0; i < proc->pronargs; i++)
|
for (i = 0; i < proc->pronargs; i++)
|
||||||
{
|
{
|
||||||
if (get_typtype(proc->proargtypes[i]) == 'p')
|
if (get_typtype(proc->proargtypes.values[i]) == 'p')
|
||||||
{
|
{
|
||||||
if (proc->proargtypes[i] == ANYARRAYOID ||
|
if (proc->proargtypes.values[i] == ANYARRAYOID ||
|
||||||
proc->proargtypes[i] == ANYELEMENTOID)
|
proc->proargtypes.values[i] == ANYELEMENTOID)
|
||||||
haspolyarg = true;
|
haspolyarg = true;
|
||||||
else
|
else
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("plpgsql functions cannot take type %s",
|
errmsg("plpgsql functions cannot take type %s",
|
||||||
format_type_be(proc->proargtypes[i]))));
|
format_type_be(proc->proargtypes.values[i]))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.59 2005/03/24 17:22:34 tgl Exp $
|
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.60 2005/03/29 00:17:24 tgl Exp $
|
||||||
*
|
*
|
||||||
*********************************************************************
|
*********************************************************************
|
||||||
*/
|
*/
|
||||||
@ -1082,11 +1082,11 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
|
|||||||
Form_pg_type argTypeStruct;
|
Form_pg_type argTypeStruct;
|
||||||
|
|
||||||
argTypeTup = SearchSysCache(TYPEOID,
|
argTypeTup = SearchSysCache(TYPEOID,
|
||||||
ObjectIdGetDatum(procStruct->proargtypes[i]),
|
ObjectIdGetDatum(procStruct->proargtypes.values[i]),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(argTypeTup))
|
if (!HeapTupleIsValid(argTypeTup))
|
||||||
elog(ERROR, "cache lookup failed for type %u",
|
elog(ERROR, "cache lookup failed for type %u",
|
||||||
procStruct->proargtypes[i]);
|
procStruct->proargtypes.values[i]);
|
||||||
argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
|
argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
|
||||||
|
|
||||||
/* Disallow pseudotype argument */
|
/* Disallow pseudotype argument */
|
||||||
@ -1094,11 +1094,11 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("plpython functions cannot take type %s",
|
errmsg("plpython functions cannot take type %s",
|
||||||
format_type_be(procStruct->proargtypes[i]))));
|
format_type_be(procStruct->proargtypes.values[i]))));
|
||||||
|
|
||||||
if (argTypeStruct->typtype != 'c')
|
if (argTypeStruct->typtype != 'c')
|
||||||
PLy_input_datum_func(&(proc->args[i]),
|
PLy_input_datum_func(&(proc->args[i]),
|
||||||
procStruct->proargtypes[i],
|
procStruct->proargtypes.values[i],
|
||||||
argTypeTup);
|
argTypeTup);
|
||||||
else
|
else
|
||||||
proc->args[i].is_rowtype = 2; /* still need to set I/O
|
proc->args[i].is_rowtype = 2; /* still need to set I/O
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
* ENHANCEMENTS, OR MODIFICATIONS.
|
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.94 2004/11/21 21:17:05 tgl Exp $
|
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.95 2005/03/29 00:17:25 tgl Exp $
|
||||||
*
|
*
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
@ -1128,14 +1128,14 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid)
|
|||||||
for (i = 0; i < prodesc->nargs; i++)
|
for (i = 0; i < prodesc->nargs; i++)
|
||||||
{
|
{
|
||||||
typeTup = SearchSysCache(TYPEOID,
|
typeTup = SearchSysCache(TYPEOID,
|
||||||
ObjectIdGetDatum(procStruct->proargtypes[i]),
|
ObjectIdGetDatum(procStruct->proargtypes.values[i]),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(typeTup))
|
if (!HeapTupleIsValid(typeTup))
|
||||||
{
|
{
|
||||||
free(prodesc->proname);
|
free(prodesc->proname);
|
||||||
free(prodesc);
|
free(prodesc);
|
||||||
elog(ERROR, "cache lookup failed for type %u",
|
elog(ERROR, "cache lookup failed for type %u",
|
||||||
procStruct->proargtypes[i]);
|
procStruct->proargtypes.values[i]);
|
||||||
}
|
}
|
||||||
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
|
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
|
||||||
|
|
||||||
@ -1147,7 +1147,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("pltcl functions cannot take type %s",
|
errmsg("pltcl functions cannot take type %s",
|
||||||
format_type_be(procStruct->proargtypes[i]))));
|
format_type_be(procStruct->proargtypes.values[i]))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeStruct->typtype == 'c')
|
if (typeStruct->typtype == 'c')
|
||||||
|
@ -33,23 +33,13 @@ create function physically_coercible(oid, oid) returns bool as
|
|||||||
language sql;
|
language sql;
|
||||||
-- **************** pg_proc ****************
|
-- **************** pg_proc ****************
|
||||||
-- Look for illegal values in pg_proc fields.
|
-- Look for illegal values in pg_proc fields.
|
||||||
-- NOTE: in reality pronargs could be more than 10, but I'm too lazy to put
|
|
||||||
-- a larger number of proargtypes check clauses in here. If we ever have
|
|
||||||
-- more-than-10-arg functions in the standard catalogs, extend this query.
|
|
||||||
SELECT p1.oid, p1.proname
|
SELECT p1.oid, p1.proname
|
||||||
FROM pg_proc as p1
|
FROM pg_proc as p1
|
||||||
WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
|
WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
|
||||||
p1.pronargs < 0 OR p1.pronargs > 10 OR
|
p1.pronargs < 0 OR
|
||||||
(p1.proargtypes[0] = 0 AND p1.pronargs > 0) OR
|
array_lower(p1.proargtypes, 1) != 0 OR
|
||||||
(p1.proargtypes[1] = 0 AND p1.pronargs > 1) OR
|
array_upper(p1.proargtypes, 1) != p1.pronargs-1 OR
|
||||||
(p1.proargtypes[2] = 0 AND p1.pronargs > 2) OR
|
0::oid = ANY (p1.proargtypes);
|
||||||
(p1.proargtypes[3] = 0 AND p1.pronargs > 3) OR
|
|
||||||
(p1.proargtypes[4] = 0 AND p1.pronargs > 4) OR
|
|
||||||
(p1.proargtypes[5] = 0 AND p1.pronargs > 5) OR
|
|
||||||
(p1.proargtypes[6] = 0 AND p1.pronargs > 6) OR
|
|
||||||
(p1.proargtypes[7] = 0 AND p1.pronargs > 7) OR
|
|
||||||
(p1.proargtypes[8] = 0 AND p1.pronargs > 8) OR
|
|
||||||
(p1.proargtypes[9] = 0 AND p1.pronargs > 9);
|
|
||||||
oid | proname
|
oid | proname
|
||||||
-----+---------
|
-----+---------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
@ -218,7 +208,7 @@ WHERE p1.oid != p2.oid AND
|
|||||||
SELECT p1.oid, p1.proname
|
SELECT p1.oid, p1.proname
|
||||||
FROM pg_proc as p1
|
FROM pg_proc as p1
|
||||||
WHERE p1.prorettype = 'internal'::regtype AND NOT
|
WHERE p1.prorettype = 'internal'::regtype AND NOT
|
||||||
('(' || oidvectortypes(p1.proargtypes) || ')') ~ '[^a-z0-9_]internal[^a-z0-9_]';
|
'internal'::regtype = ANY (p1.proargtypes);
|
||||||
oid | proname
|
oid | proname
|
||||||
------+-------------
|
------+-------------
|
||||||
2304 | internal_in
|
2304 | internal_in
|
||||||
|
@ -106,14 +106,18 @@ ORDER BY 1;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Varlena array types will point to array_in
|
-- Varlena array types will point to array_in
|
||||||
|
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
|
||||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||||
FROM pg_type AS p1, pg_proc AS p2
|
FROM pg_type AS p1, pg_proc AS p2
|
||||||
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND
|
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND
|
||||||
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
||||||
(p2.oid = 'array_in'::regproc);
|
(p2.oid = 'array_in'::regproc)
|
||||||
oid | typname | oid | proname
|
ORDER BY 1;
|
||||||
-----+---------+-----+---------
|
oid | typname | oid | proname
|
||||||
(0 rows)
|
-----+------------+-----+--------------
|
||||||
|
22 | int2vector | 40 | int2vectorin
|
||||||
|
30 | oidvector | 54 | oidvectorin
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
-- Check for bogus typoutput routines
|
-- Check for bogus typoutput routines
|
||||||
-- As of 8.0, this check finds refcursor, which is borrowing
|
-- As of 8.0, this check finds refcursor, which is borrowing
|
||||||
@ -165,14 +169,18 @@ ORDER BY 1;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Varlena array types will point to array_recv
|
-- Varlena array types will point to array_recv
|
||||||
|
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
|
||||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||||
FROM pg_type AS p1, pg_proc AS p2
|
FROM pg_type AS p1, pg_proc AS p2
|
||||||
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND
|
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND
|
||||||
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
||||||
(p2.oid = 'array_recv'::regproc);
|
(p2.oid = 'array_recv'::regproc)
|
||||||
oid | typname | oid | proname
|
ORDER BY 1;
|
||||||
-----+---------+-----+---------
|
oid | typname | oid | proname
|
||||||
(0 rows)
|
-----+------------+------+----------------
|
||||||
|
22 | int2vector | 2410 | int2vectorrecv
|
||||||
|
30 | oidvector | 2420 | oidvectorrecv
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
-- Check for bogus typsend routines
|
-- Check for bogus typsend routines
|
||||||
-- As of 7.4, this check finds refcursor, which is borrowing
|
-- As of 7.4, this check finds refcursor, which is borrowing
|
||||||
@ -203,7 +211,7 @@ WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
|||||||
-- Look for illegal values in pg_class fields
|
-- Look for illegal values in pg_class fields
|
||||||
SELECT p1.oid, p1.relname
|
SELECT p1.oid, p1.relname
|
||||||
FROM pg_class as p1
|
FROM pg_class as p1
|
||||||
WHERE p1.relkind NOT IN ('r', 'i', 's', 'S', 't', 'v');
|
WHERE p1.relkind NOT IN ('r', 'i', 's', 'S', 'c', 't', 'v');
|
||||||
oid | relname
|
oid | relname
|
||||||
-----+---------
|
-----+---------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
@ -39,24 +39,14 @@ language sql;
|
|||||||
-- **************** pg_proc ****************
|
-- **************** pg_proc ****************
|
||||||
|
|
||||||
-- Look for illegal values in pg_proc fields.
|
-- Look for illegal values in pg_proc fields.
|
||||||
-- NOTE: in reality pronargs could be more than 10, but I'm too lazy to put
|
|
||||||
-- a larger number of proargtypes check clauses in here. If we ever have
|
|
||||||
-- more-than-10-arg functions in the standard catalogs, extend this query.
|
|
||||||
|
|
||||||
SELECT p1.oid, p1.proname
|
SELECT p1.oid, p1.proname
|
||||||
FROM pg_proc as p1
|
FROM pg_proc as p1
|
||||||
WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
|
WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
|
||||||
p1.pronargs < 0 OR p1.pronargs > 10 OR
|
p1.pronargs < 0 OR
|
||||||
(p1.proargtypes[0] = 0 AND p1.pronargs > 0) OR
|
array_lower(p1.proargtypes, 1) != 0 OR
|
||||||
(p1.proargtypes[1] = 0 AND p1.pronargs > 1) OR
|
array_upper(p1.proargtypes, 1) != p1.pronargs-1 OR
|
||||||
(p1.proargtypes[2] = 0 AND p1.pronargs > 2) OR
|
0::oid = ANY (p1.proargtypes);
|
||||||
(p1.proargtypes[3] = 0 AND p1.pronargs > 3) OR
|
|
||||||
(p1.proargtypes[4] = 0 AND p1.pronargs > 4) OR
|
|
||||||
(p1.proargtypes[5] = 0 AND p1.pronargs > 5) OR
|
|
||||||
(p1.proargtypes[6] = 0 AND p1.pronargs > 6) OR
|
|
||||||
(p1.proargtypes[7] = 0 AND p1.pronargs > 7) OR
|
|
||||||
(p1.proargtypes[8] = 0 AND p1.pronargs > 8) OR
|
|
||||||
(p1.proargtypes[9] = 0 AND p1.pronargs > 9);
|
|
||||||
|
|
||||||
-- Look for conflicting proc definitions (same names and input datatypes).
|
-- Look for conflicting proc definitions (same names and input datatypes).
|
||||||
-- (This test should be dead code now that we have the unique index
|
-- (This test should be dead code now that we have the unique index
|
||||||
@ -179,7 +169,7 @@ WHERE p1.oid != p2.oid AND
|
|||||||
SELECT p1.oid, p1.proname
|
SELECT p1.oid, p1.proname
|
||||||
FROM pg_proc as p1
|
FROM pg_proc as p1
|
||||||
WHERE p1.prorettype = 'internal'::regtype AND NOT
|
WHERE p1.prorettype = 'internal'::regtype AND NOT
|
||||||
('(' || oidvectortypes(p1.proargtypes) || ')') ~ '[^a-z0-9_]internal[^a-z0-9_]';
|
'internal'::regtype = ANY (p1.proargtypes);
|
||||||
|
|
||||||
|
|
||||||
-- **************** pg_cast ****************
|
-- **************** pg_cast ****************
|
||||||
|
@ -88,11 +88,13 @@ WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
|||||||
ORDER BY 1;
|
ORDER BY 1;
|
||||||
|
|
||||||
-- Varlena array types will point to array_in
|
-- Varlena array types will point to array_in
|
||||||
|
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
|
||||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||||
FROM pg_type AS p1, pg_proc AS p2
|
FROM pg_type AS p1, pg_proc AS p2
|
||||||
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND
|
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND
|
||||||
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
||||||
(p2.oid = 'array_in'::regproc);
|
(p2.oid = 'array_in'::regproc)
|
||||||
|
ORDER BY 1;
|
||||||
|
|
||||||
-- Check for bogus typoutput routines
|
-- Check for bogus typoutput routines
|
||||||
|
|
||||||
@ -132,11 +134,13 @@ WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
|||||||
ORDER BY 1;
|
ORDER BY 1;
|
||||||
|
|
||||||
-- Varlena array types will point to array_recv
|
-- Varlena array types will point to array_recv
|
||||||
|
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
|
||||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||||
FROM pg_type AS p1, pg_proc AS p2
|
FROM pg_type AS p1, pg_proc AS p2
|
||||||
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND
|
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND
|
||||||
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
||||||
(p2.oid = 'array_recv'::regproc);
|
(p2.oid = 'array_recv'::regproc)
|
||||||
|
ORDER BY 1;
|
||||||
|
|
||||||
-- Check for bogus typsend routines
|
-- Check for bogus typsend routines
|
||||||
|
|
||||||
@ -163,7 +167,7 @@ WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
|||||||
|
|
||||||
SELECT p1.oid, p1.relname
|
SELECT p1.oid, p1.relname
|
||||||
FROM pg_class as p1
|
FROM pg_class as p1
|
||||||
WHERE p1.relkind NOT IN ('r', 'i', 's', 'S', 't', 'v');
|
WHERE p1.relkind NOT IN ('r', 'i', 's', 'S', 'c', 't', 'v');
|
||||||
|
|
||||||
-- Indexes should have an access method, others not.
|
-- Indexes should have an access method, others not.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user