Add a "provariadic" column to pg_proc to eliminate the remarkably expensive

need to deconstruct proargmodes for each pg_proc entry inspected by
FuncnameGetCandidates().  Fixes function lookup performance regression
caused by yesterday's variadic-functions patch.

In passing, make pg_proc.probin be NULL, rather than a dummy value '-',
in cases where it is not actually used for the particular type of function.
This should buy back some of the space cost of the extra column.
This commit is contained in:
Tom Lane 2008-07-16 16:55:24 +00:00
parent 895a4bccb6
commit 6563e9e2e8
14 changed files with 2286 additions and 2213 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.169 2008/07/16 01:30:21 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.170 2008/07/16 16:55:23 tgl Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
@ -3569,6 +3569,14 @@
<entry>Estimated number of result rows (zero if not <structfield>proretset</>)</entry>
</row>
<row>
<entry><structfield>provariadic</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
<entry>Data type of the variadic array parameter's elements,
or zero if the function does not have a variadic parameter</entry>
</row>
<row>
<entry><structfield>proisagg</structfield></entry>
<entry><type>bool</type></entry>

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.108 2008/07/16 01:30:21 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.109 2008/07/16 16:55:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -619,50 +619,23 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
int pronargs = procform->pronargs;
int effective_nargs;
int pathpos = 0;
bool variadic = false;
Oid va_elem_type = InvalidOid;
bool variadic;
Oid va_elem_type;
FuncCandidateList newResult;
/*
* Check if function is variadic, and get variadic element type if so.
* If expand_variadic is false, we can just ignore variadic-ness.
*
* XXX it's annoying to inject something as expensive as this even
* when there are no variadic functions involved. Find a better way.
* If expand_variadic is false, we should just ignore variadic-ness.
*/
if (expand_variadic)
{
Datum proargmodes;
bool isnull;
proargmodes = SysCacheGetAttr(PROCOID, proctup,
Anum_pg_proc_proargmodes, &isnull);
if (!isnull)
{
ArrayType *ar = DatumGetArrayTypeP(proargmodes);
char *argmodes;
int j;
argmodes = ARR_DATA_PTR(ar);
j = ARR_DIMS(ar)[0] - 1;
if (j >= 0 && argmodes[j] == PROARGMODE_VARIADIC)
{
variadic = any_variadic = true;
switch (procform->proargtypes.values[j])
{
case ANYOID:
va_elem_type = ANYOID;
break;
case ANYARRAYOID:
va_elem_type = ANYELEMENTOID;
break;
default:
va_elem_type = get_element_type(procform->proargtypes.values[j]);
Assert(OidIsValid(va_elem_type));
break;
}
}
}
va_elem_type = procform->provariadic;
variadic = OidIsValid(va_elem_type);
}
else
{
va_elem_type = InvalidOid;
variadic = false;
}
/* Ignore if it doesn't match requested argument count */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.94 2008/07/16 01:30:22 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.95 2008/07/16 16:55:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -202,7 +202,7 @@ AggregateCreate(const char *aggName,
INTERNALlanguageId, /* languageObjectId */
InvalidOid, /* no validator */
"aggregate_dummy", /* placeholder proc */
"-", /* probin */
NULL, /* probin */
true, /* isAgg */
false, /* security invoker (currently not
* definable for agg) */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.151 2008/03/27 03:57:33 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.152 2008/07/16 16:55:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -85,6 +85,7 @@ ProcedureCreate(const char *procedureName,
bool genericOutParam = false;
bool internalInParam = false;
bool internalOutParam = false;
Oid variadicType = InvalidOid;
Relation rel;
HeapTuple tup;
HeapTuple oldtup;
@ -103,7 +104,6 @@ ProcedureCreate(const char *procedureName,
* sanity checks
*/
Assert(PointerIsValid(prosrc));
Assert(PointerIsValid(probin));
parameterCount = parameterTypes->dim1;
if (parameterCount < 0 || parameterCount > FUNC_MAX_ARGS)
@ -211,6 +211,64 @@ ProcedureCreate(const char *procedureName,
procedureName,
format_type_be(parameterTypes->values[0]))));
if (parameterModes != PointerGetDatum(NULL))
{
/*
* We expect the array to be a 1-D CHAR array; verify that. We don't
* need to use deconstruct_array() since the array data is just going
* to look like a C array of char values.
*/
ArrayType *modesArray = (ArrayType *) DatumGetPointer(parameterModes);
char *modes;
if (ARR_NDIM(modesArray) != 1 ||
ARR_DIMS(modesArray)[0] != allParamCount ||
ARR_HASNULL(modesArray) ||
ARR_ELEMTYPE(modesArray) != CHAROID)
elog(ERROR, "parameterModes is not a 1-D char array");
modes = (char *) ARR_DATA_PTR(modesArray);
/*
* Only the last input parameter can be variadic; if it is, save
* its element type. Errors here are just elog since caller should
* have checked this already.
*/
for (i = 0; i < allParamCount; i++)
{
switch (modes[i])
{
case PROARGMODE_IN:
case PROARGMODE_INOUT:
if (OidIsValid(variadicType))
elog(ERROR, "variadic parameter must be last");
break;
case PROARGMODE_OUT:
/* okay */
break;
case PROARGMODE_VARIADIC:
if (OidIsValid(variadicType))
elog(ERROR, "variadic parameter must be last");
switch (allParams[i])
{
case ANYOID:
variadicType = ANYOID;
break;
case ANYARRAYOID:
variadicType = ANYELEMENTOID;
break;
default:
variadicType = get_element_type(allParams[i]);
if (!OidIsValid(variadicType))
elog(ERROR, "variadic parameter is not an array");
break;
}
break;
default:
elog(ERROR, "invalid parameter mode '%c'", modes[i]);
break;
}
}
}
/*
* All seems OK; prepare the data to be inserted into pg_proc.
*/
@ -229,6 +287,7 @@ ProcedureCreate(const char *procedureName,
values[Anum_pg_proc_prolang - 1] = ObjectIdGetDatum(languageObjectId);
values[Anum_pg_proc_procost - 1] = Float4GetDatum(procost);
values[Anum_pg_proc_prorows - 1] = Float4GetDatum(prorows);
values[Anum_pg_proc_provariadic - 1] = ObjectIdGetDatum(variadicType);
values[Anum_pg_proc_proisagg - 1] = BoolGetDatum(isAgg);
values[Anum_pg_proc_prosecdef - 1] = BoolGetDatum(security_definer);
values[Anum_pg_proc_proisstrict - 1] = BoolGetDatum(isStrict);
@ -250,7 +309,10 @@ ProcedureCreate(const char *procedureName,
else
nulls[Anum_pg_proc_proargnames - 1] = 'n';
values[Anum_pg_proc_prosrc - 1] = CStringGetTextDatum(prosrc);
values[Anum_pg_proc_probin - 1] = CStringGetTextDatum(probin);
if (probin)
values[Anum_pg_proc_probin - 1] = CStringGetTextDatum(probin);
else
nulls[Anum_pg_proc_probin - 1] = 'n';
if (proconfig != PointerGetDatum(NULL))
values[Anum_pg_proc_proconfig - 1] = proconfig;
else
@ -497,12 +559,12 @@ fmgr_c_validator(PG_FUNCTION_ARGS)
tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
if (isnull)
elog(ERROR, "null prosrc");
elog(ERROR, "null prosrc for C function %u", funcoid);
prosrc = TextDatumGetCString(tmp);
tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_probin, &isnull);
if (isnull)
elog(ERROR, "null probin");
elog(ERROR, "null probin for C function %u", funcoid);
probin = TextDatumGetCString(tmp);
(void) load_external_function(probin, prosrc, true, &libraryhandle);

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.96 2008/07/16 01:30:22 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.97 2008/07/16 16:55:23 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
@ -590,7 +590,8 @@ compute_attributes_with_style(List *parameters, bool *isStrict_p, char *volatili
* AS <object reference, or sql code>
*/
static void
interpret_AS_clause(Oid languageOid, const char *languageName, List *as,
interpret_AS_clause(Oid languageOid, const char *languageName,
char *funcname, List *as,
char **prosrc_str_p, char **probin_str_p)
{
Assert(as != NIL);
@ -599,25 +600,47 @@ interpret_AS_clause(Oid languageOid, const char *languageName, List *as,
{
/*
* For "C" language, store the file name in probin and, when given,
* the link symbol name in prosrc.
* the link symbol name in prosrc. If link symbol is omitted,
* substitute procedure name. We also allow link symbol to be
* specified as "-", since that was the habit in PG versions before
* 8.4, and there might be dump files out there that don't translate
* that back to "omitted".
*/
*probin_str_p = strVal(linitial(as));
if (list_length(as) == 1)
*prosrc_str_p = "-";
*prosrc_str_p = funcname;
else
{
*prosrc_str_p = strVal(lsecond(as));
if (strcmp(*prosrc_str_p, "-") == 0)
*prosrc_str_p = funcname;
}
}
else
{
/* Everything else wants the given string in prosrc. */
*prosrc_str_p = strVal(linitial(as));
*probin_str_p = "-";
*probin_str_p = NULL;
if (list_length(as) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("only one AS item needed for language \"%s\"",
languageName)));
if (languageOid == INTERNALlanguageId)
{
/*
* In PostgreSQL versions before 6.5, the SQL name of the created
* function could not be different from the internal name, and
* "prosrc" wasn't used. So there is code out there that does
* CREATE FUNCTION xyz AS '' LANGUAGE internal. To preserve some
* modicum of backwards compatibility, accept an empty "prosrc"
* value as meaning the supplied SQL function name.
*/
if (strlen(*prosrc_str_p) == 0)
*prosrc_str_p = funcname;
}
}
}
@ -759,30 +782,9 @@ CreateFunction(CreateFunctionStmt *stmt)
compute_attributes_with_style(stmt->withClause, &isStrict, &volatility);
interpret_AS_clause(languageOid, languageName, as_clause,
interpret_AS_clause(languageOid, languageName, funcname, as_clause,
&prosrc_str, &probin_str);
if (languageOid == INTERNALlanguageId)
{
/*
* In PostgreSQL versions before 6.5, the SQL name of the created
* function could not be different from the internal name, and
* "prosrc" wasn't used. So there is code out there that does CREATE
* FUNCTION xyz AS '' LANGUAGE internal. To preserve some modicum of
* backwards compatibility, accept an empty "prosrc" value as meaning
* the supplied SQL function name.
*/
if (strlen(prosrc_str) == 0)
prosrc_str = funcname;
}
if (languageOid == ClanguageId)
{
/* If link symbol is specified as "-", substitute procedure name */
if (strcmp(prosrc_str, "-") == 0)
prosrc_str = funcname;
}
/*
* Set default values for COST and ROWS depending on other parameters;
* reject ROWS if it's not returnsSet. NB: pg_dump knows these default

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.276 2008/07/16 01:30:22 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.277 2008/07/16 16:55:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -5389,29 +5389,12 @@ generate_function_name(Oid funcid, int nargs, Oid *argtypes,
/* Check variadic-ness if caller cares */
if (is_variadic)
{
/* XXX change this if we simplify code in FuncnameGetCandidates */
Datum proargmodes;
bool isnull;
*is_variadic = false;
proargmodes = SysCacheGetAttr(PROCOID, proctup,
Anum_pg_proc_proargmodes, &isnull);
if (!isnull)
{
ArrayType *ar = DatumGetArrayTypeP(proargmodes);
char *argmodes;
int j;
argmodes = ARR_DATA_PTR(ar);
j = ARR_DIMS(ar)[0] - 1;
if (j >= 0 && argmodes[j] == PROARGMODE_VARIADIC)
{
/* "any" variadics are not treated as variadics for listing */
if (procform->proargtypes.values[j] != ANYOID)
*is_variadic = true;
}
}
/* "any" variadics are not treated as variadics for listing */
if (OidIsValid(procform->provariadic) &&
procform->provariadic != ANYOID)
*is_variadic = true;
else
*is_variadic = false;
}
ReleaseSysCache(proctup);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.120 2008/06/06 22:35:22 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.121 2008/07/16 16:55:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -324,18 +324,20 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
void *libraryhandle;
/*
* Get prosrc and probin strings (link symbol and library filename)
* Get prosrc and probin strings (link symbol and library filename).
* While in general these columns might be null, that's not allowed
* for C-language functions.
*/
prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
Anum_pg_proc_prosrc, &isnull);
if (isnull)
elog(ERROR, "null prosrc for function %u", functionId);
elog(ERROR, "null prosrc for C function %u", functionId);
prosrcstring = TextDatumGetCString(prosrcattr);
probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
Anum_pg_proc_probin, &isnull);
if (isnull)
elog(ERROR, "null probin for function %u", functionId);
elog(ERROR, "null probin for C function %u", functionId);
probinstring = TextDatumGetCString(probinattr);
/* Look up the function itself */

View File

@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.494 2008/07/16 01:30:22 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.495 2008/07/16 16:55:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -6671,10 +6671,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
/*
* See backend/commands/define.c for details of how the 'AS' clause is
* used.
* See backend/commands/functioncmds.c for details of how the 'AS' clause
* is used. In 8.4 and up, an unused probin is NULL (here ""); previous
* versions would set it to "-". There are no known cases in which prosrc
* is unused, so the tests below for "-" are probably useless.
*/
if (strcmp(probin, "-") != 0)
if (probin[0] != '\0' && strcmp(probin, "-") != 0)
{
appendPQExpBuffer(asPart, "AS ");
appendStringLiteralAH(asPart, probin, fout);

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.469 2008/07/16 01:30:23 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.470 2008/07/16 16:55:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200807152
#define CATALOG_VERSION_NO 200807161
#endif

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.138 2008/06/24 17:58:27 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.139 2008/07/16 16:55:24 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -289,21 +289,22 @@ DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
{ 1255, {"prolang"}, 26, -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"procost"}, 700, -1, 4, 5, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"prorows"}, 700, -1, 4, 6, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proisagg"}, 16, -1, 1, 7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"prosecdef"}, 16, -1, 1, 8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"proisstrict"}, 16, -1, 1, 9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"proretset"}, 16, -1, 1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"provolatile"}, 18, -1, 1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"pronargs"}, 21, -1, 2, 12, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
{ 1255, {"prorettype"}, 26, -1, 4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proargtypes"}, 30, -1, -1, 14, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proallargtypes"}, 1028, -1, -1, 15, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proargmodes"}, 1002, -1, -1, 16, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proargnames"}, 1009, -1, -1, 17, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"prosrc"}, 25, -1, -1, 18, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"probin"}, 17, -1, -1, 19, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proconfig"}, 1009, -1, -1, 20, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proacl"}, 1034, -1, -1, 21, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
{ 1255, {"provariadic"}, 26, -1, 4, 7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proisagg"}, 16, -1, 1, 8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"prosecdef"}, 16, -1, 1, 9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"proisstrict"}, 16, -1, 1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"proretset"}, 16, -1, 1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"provolatile"}, 18, -1, 1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"pronargs"}, 21, -1, 2, 13, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
{ 1255, {"prorettype"}, 26, -1, 4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proargtypes"}, 30, -1, -1, 15, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proallargtypes"}, 1028, -1, -1, 16, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proargmodes"}, 1002, -1, -1, 17, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proargnames"}, 1009, -1, -1, 18, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"prosrc"}, 25, -1, -1, 19, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"probin"}, 17, -1, -1, 20, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proconfig"}, 1009, -1, -1, 21, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proacl"}, 1034, -1, -1, 22, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
DATA(insert ( 1255 proname 19 -1 NAMEDATALEN 1 0 -1 -1 f p c t f f t 0));
DATA(insert ( 1255 pronamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
@ -311,21 +312,22 @@ DATA(insert ( 1255 proowner 26 -1 4 3 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 prolang 26 -1 4 4 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 procost 700 -1 4 5 0 -1 -1 FLOAT4PASSBYVAL p i t f f t 0));
DATA(insert ( 1255 prorows 700 -1 4 6 0 -1 -1 FLOAT4PASSBYVAL p i t f f t 0));
DATA(insert ( 1255 proisagg 16 -1 1 7 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 prosecdef 16 -1 1 8 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 proisstrict 16 -1 1 9 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 proretset 16 -1 1 10 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 provolatile 18 -1 1 11 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 pronargs 21 -1 2 12 0 -1 -1 t p s t f f t 0));
DATA(insert ( 1255 prorettype 26 -1 4 13 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 proargtypes 30 -1 -1 14 1 -1 -1 f p i t f f t 0));
DATA(insert ( 1255 proallargtypes 1028 -1 -1 15 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 proargmodes 1002 -1 -1 16 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 proargnames 1009 -1 -1 17 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 prosrc 25 -1 -1 18 0 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 probin 17 -1 -1 19 0 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 proconfig 1009 -1 -1 20 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 proacl 1034 -1 -1 21 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 provariadic 26 -1 4 7 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 proisagg 16 -1 1 8 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 prosecdef 16 -1 1 9 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 proisstrict 16 -1 1 10 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 proretset 16 -1 1 11 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 provolatile 18 -1 1 12 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 pronargs 21 -1 2 13 0 -1 -1 t p s t f f t 0));
DATA(insert ( 1255 prorettype 26 -1 4 14 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 proargtypes 30 -1 -1 15 1 -1 -1 f p i t f f t 0));
DATA(insert ( 1255 proallargtypes 1028 -1 -1 16 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 proargmodes 1002 -1 -1 17 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 proargnames 1009 -1 -1 18 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 prosrc 25 -1 -1 19 0 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 probin 17 -1 -1 20 0 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 proconfig 1009 -1 -1 21 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 proacl 1034 -1 -1 22 1 -1 -1 f x i f f f t 0));
DATA(insert ( 1255 ctid 27 0 6 -1 0 -1 -1 f p s t f f t 0));
DATA(insert ( 1255 oid 26 0 4 -2 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 xmin 28 0 4 -3 0 -1 -1 t p i t f f t 0));

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.105 2008/03/27 03:57:34 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.106 2008/07/16 16:55:24 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -131,7 +131,7 @@ DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 26 0 0
DESCR("");
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f 3 _null_ _null_ ));
DESCR("");
DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f r 21 0 0 0 0 0 t f f f 3 _null_ _null_ ));
DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f r 22 0 0 0 0 0 t f f f 3 _null_ _null_ ));
DESCR("");
DATA(insert OID = 1259 ( pg_class PGNSP 83 PGUID 0 1259 0 0 0 0 0 f f r 27 0 0 0 0 0 t f f f 3 _null_ _null_ ));
DESCR("");

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,29 @@ WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
-----+---------
(0 rows)
-- prosrc should never be null or empty
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE prosrc IS NULL OR prosrc = '' OR prosrc = '-';
oid | proname
-----+---------
(0 rows)
-- probin should be non-empty for C functions, null everywhere else
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE prolang = 13 AND (probin IS NULL OR probin = '' OR probin = '-');
oid | proname
-----+---------
(0 rows)
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE prolang != 13 AND probin IS NOT NULL;
oid | proname
-----+---------
(0 rows)
-- Look for conflicting proc definitions (same names and input datatypes).
-- (This test should be dead code now that we have the unique index
-- pg_proc_proname_args_nsp_index, but I'll leave it in anyway.)

View File

@ -57,6 +57,20 @@ WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
procost <= 0 OR
CASE WHEN proretset THEN prorows <= 0 ELSE prorows != 0 END;
-- prosrc should never be null or empty
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE prosrc IS NULL OR prosrc = '' OR prosrc = '-';
-- probin should be non-empty for C functions, null everywhere else
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE prolang = 13 AND (probin IS NULL OR probin = '' OR probin = '-');
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE prolang != 13 AND probin IS NOT NULL;
-- Look for conflicting proc definitions (same names and input datatypes).
-- (This test should be dead code now that we have the unique index
-- pg_proc_proname_args_nsp_index, but I'll leave it in anyway.)