Divide functions into three volatility classes (immutable, stable, and
volatile), rather than the old cachable/noncachable distinction. This allows indexscan optimizations in many places where we formerly didn't. Also, add a pronamespace column to pg_proc (it doesn't do anything yet, however).
This commit is contained in:
parent
0e11aea246
commit
4bdb4be62e
@ -1,6 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.39 2002/03/29 19:05:57 tgl Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.40 2002/04/05 00:31:22 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="catalogs">
|
<chapter id="catalogs">
|
||||||
@ -1653,6 +1653,15 @@
|
|||||||
<entry>Name of the function</entry>
|
<entry>Name of the function</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>pronamespace</entry>
|
||||||
|
<entry><type>oid</type></entry>
|
||||||
|
<entry>pg_namespace.oid</entry>
|
||||||
|
<entry>
|
||||||
|
The OID of the namespace that contains this function
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry>proowner</entry>
|
<entry>proowner</entry>
|
||||||
<entry><type>int4</type></entry>
|
<entry><type>int4</type></entry>
|
||||||
@ -1681,13 +1690,6 @@
|
|||||||
<entry>not functional</entry>
|
<entry>not functional</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>proiscachable</entry>
|
|
||||||
<entry><type>bool</type></entry>
|
|
||||||
<entry></entry>
|
|
||||||
<entry>Function returns same result for same input values</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry>proisstrict</entry>
|
<entry>proisstrict</entry>
|
||||||
<entry><type>bool</type></entry>
|
<entry><type>bool</type></entry>
|
||||||
@ -1700,6 +1702,25 @@
|
|||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>provolatile</entry>
|
||||||
|
<entry><type>char</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>
|
||||||
|
<structfield>provolatile</structfield> tells whether the function's
|
||||||
|
result depends only on its input arguments, or is affected by outside
|
||||||
|
factors.
|
||||||
|
It is <literal>i</literal> for <quote>immutable</> functions,
|
||||||
|
which always deliver the same result for the same inputs.
|
||||||
|
It is <literal>s</literal> for <quote>stable</> functions,
|
||||||
|
whose results (for fixed inputs) do not change within a scan.
|
||||||
|
It is <literal>v</literal> for <quote>volatile</> functions,
|
||||||
|
whose results may change at any time. (Use <literal>v</literal> also
|
||||||
|
for functions with side-effects, so that calls to them cannot get
|
||||||
|
optimized away.)
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry>pronargs</entry>
|
<entry>pronargs</entry>
|
||||||
<entry><type>int2</type></entry>
|
<entry><type>int2</type></entry>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.34 2002/03/22 19:20:37 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.35 2002/04/05 00:31:24 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<refentry id="SQL-CREATEFUNCTION">
|
<refentry id="SQL-CREATEFUNCTION">
|
||||||
@ -160,35 +160,63 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
|
|||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>iscachable</term>
|
<term>isStrict</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<option>Iscachable</option> indicates that the function always
|
<option>isStrict</option> indicates that the function always
|
||||||
returns the same result when given the same argument values (i.e.,
|
|
||||||
it does not do database lookups or otherwise use information not
|
|
||||||
directly present in its parameter list). The optimizer uses
|
|
||||||
<option>iscachable</option> to know whether it is safe to
|
|
||||||
pre-evaluate a call of the function.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>isstrict</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<option>isstrict</option> indicates that the function always
|
|
||||||
returns NULL whenever any of its arguments are NULL. If this
|
returns NULL whenever any of its arguments are NULL. If this
|
||||||
attribute is specified, the function is not executed when there
|
attribute is specified, the function is not executed when there
|
||||||
are NULL arguments; instead a NULL result is assumed automatically.
|
are NULL arguments; instead a NULL result is assumed automatically.
|
||||||
When <option>isstrict</option> is not specified, the function will
|
When <option>isStrict</option> is not specified, the function will
|
||||||
be called for NULL inputs. It is then the function author's
|
be called for NULL inputs. It is then the function author's
|
||||||
responsibility to check for NULLs if necessary and respond
|
responsibility to check for NULLs if necessary and respond
|
||||||
appropriately.
|
appropriately.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>isImmutable</term>
|
||||||
|
<term>isCachable</term>
|
||||||
|
<term>isStable</term>
|
||||||
|
<term>isVolatile</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
These attributes inform the system whether it is safe to replace
|
||||||
|
multiple evaluations of the function with a single evaluation.
|
||||||
|
At most one choice should be specified. (If none of these appear,
|
||||||
|
<option>isVolatile</option> is the default assumption.)
|
||||||
|
<option>isImmutable</option> indicates that the function always
|
||||||
|
returns the same result when given the same argument values; that
|
||||||
|
is, it does not do database lookups or otherwise use information not
|
||||||
|
directly present in its parameter list. If this option is given,
|
||||||
|
any call of the function with all-constant arguments can be
|
||||||
|
immediately replaced with the function value.
|
||||||
|
<option>isCachable</option> is an
|
||||||
|
obsolete equivalent of <option>isImmutable</option>; it's still
|
||||||
|
accepted for backwards-compatibility reasons.
|
||||||
|
<option>isStable</option> indicates that within a single table scan
|
||||||
|
the function will consistently
|
||||||
|
return the same result for the same argument values, but that its
|
||||||
|
result could change across SQL statements. This is the appropriate
|
||||||
|
selection for functions whose results depend on database lookups,
|
||||||
|
parameter variables (such as the current timezone), etc. Also note
|
||||||
|
that the <literal>CURRENT_TIMESTAMP</> family of functions qualify
|
||||||
|
as stable, since their values do not change within a transaction.
|
||||||
|
<option>isVolatile</option> indicates that the function value can
|
||||||
|
change even within a single table scan, so no optimizations can be
|
||||||
|
made. Relatively few database functions are volatile in this sense;
|
||||||
|
some examples are <literal>random()</>, <literal>currval()</>,
|
||||||
|
<literal>timeofday()</>. Note that any function that has side-effects
|
||||||
|
must be classified volatile, even if its result is quite predictable,
|
||||||
|
to prevent calls from being optimized away; an example is
|
||||||
|
<literal>setval()</>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
|
Attribute names are not case-sensitive.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
@ -342,7 +370,7 @@ CREATE TABLE product (
|
|||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE FUNCTION point(complex) RETURNS point
|
CREATE FUNCTION point(complex) RETURNS point
|
||||||
AS '/home/bernie/pgsql/lib/complex.so', 'complex_to_point'
|
AS '/home/bernie/pgsql/lib/complex.so', 'complex_to_point'
|
||||||
LANGUAGE C;
|
LANGUAGE C WITH (isStrict);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
The C declaration of the function could be:
|
The C declaration of the function could be:
|
||||||
@ -359,6 +387,9 @@ Point * complex_to_point (Complex *z)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
|
Note that the function is marked <quote>strict</>; this allows us
|
||||||
|
to skip checking for NULL input in the function body.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.130 2002/04/03 05:39:28 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.131 2002/04/05 00:31:23 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<appendix id="release">
|
<appendix id="release">
|
||||||
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
|
|||||||
worries about funny characters.
|
worries about funny characters.
|
||||||
-->
|
-->
|
||||||
<literallayout><![CDATA[
|
<literallayout><![CDATA[
|
||||||
|
Define a third class of function volatility to allow indexscans in more cases
|
||||||
Locale support is now built by default; choice of locale is set by initdb and/or at run-time
|
Locale support is now built by default; choice of locale is set by initdb and/or at run-time
|
||||||
ALTER TABLE ALTER COLUMN SET/DROP NOT NULL
|
ALTER TABLE ALTER COLUMN SET/DROP NOT NULL
|
||||||
EXPLAIN output comes out as a query result, not a NOTICE message
|
EXPLAIN output comes out as a query result, not a NOTICE message
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.86 2002/03/29 19:06:00 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.87 2002/04/05 00:31:24 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -64,7 +64,7 @@ char *Name_pg_opclass_indices[Num_pg_opclass_indices] =
|
|||||||
char *Name_pg_operator_indices[Num_pg_operator_indices] =
|
char *Name_pg_operator_indices[Num_pg_operator_indices] =
|
||||||
{OperatorOidIndex, OperatorNameIndex};
|
{OperatorOidIndex, OperatorNameIndex};
|
||||||
char *Name_pg_proc_indices[Num_pg_proc_indices] =
|
char *Name_pg_proc_indices[Num_pg_proc_indices] =
|
||||||
{ProcedureOidIndex, ProcedureNameIndex};
|
{ProcedureOidIndex, ProcedureNameNspIndex};
|
||||||
char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] =
|
char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] =
|
||||||
{RelCheckIndex};
|
{RelCheckIndex};
|
||||||
char *Name_pg_rewrite_indices[Num_pg_rewrite_indices] =
|
char *Name_pg_rewrite_indices[Num_pg_rewrite_indices] =
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.67 2002/03/29 19:06:02 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.68 2002/04/05 00:31:25 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -40,17 +40,17 @@ static void checkretval(Oid rettype, List *queryTreeList);
|
|||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
ProcedureCreate(char *procedureName,
|
ProcedureCreate(const char *procedureName,
|
||||||
Oid procNamespace,
|
Oid procNamespace,
|
||||||
bool replace,
|
bool replace,
|
||||||
bool returnsSet,
|
bool returnsSet,
|
||||||
Oid returnType,
|
Oid returnType,
|
||||||
Oid languageObjectId,
|
Oid languageObjectId,
|
||||||
char *prosrc,
|
const char *prosrc,
|
||||||
char *probin,
|
const char *probin,
|
||||||
bool trusted,
|
bool trusted,
|
||||||
bool canCache,
|
|
||||||
bool isStrict,
|
bool isStrict,
|
||||||
|
char volatility,
|
||||||
int32 byte_pct,
|
int32 byte_pct,
|
||||||
int32 perbyte_cpu,
|
int32 perbyte_cpu,
|
||||||
int32 percall_cpu,
|
int32 percall_cpu,
|
||||||
@ -167,7 +167,7 @@ ProcedureCreate(char *procedureName,
|
|||||||
*/
|
*/
|
||||||
if (parameterCount == 1 && OidIsValid(typev[0]) &&
|
if (parameterCount == 1 && OidIsValid(typev[0]) &&
|
||||||
(relid = typeidTypeRelid(typev[0])) != 0 &&
|
(relid = typeidTypeRelid(typev[0])) != 0 &&
|
||||||
get_attnum(relid, procedureName) != InvalidAttrNumber)
|
get_attnum(relid, (char *) procedureName) != InvalidAttrNumber)
|
||||||
elog(ERROR, "method %s already an attribute of type %s",
|
elog(ERROR, "method %s already an attribute of type %s",
|
||||||
procedureName, typeidTypeName(typev[0]));
|
procedureName, typeidTypeName(typev[0]));
|
||||||
|
|
||||||
@ -180,7 +180,9 @@ ProcedureCreate(char *procedureName,
|
|||||||
|
|
||||||
if (languageObjectId == SQLlanguageId)
|
if (languageObjectId == SQLlanguageId)
|
||||||
{
|
{
|
||||||
querytree_list = pg_parse_and_rewrite(prosrc, typev, parameterCount);
|
querytree_list = pg_parse_and_rewrite((char *) prosrc,
|
||||||
|
typev,
|
||||||
|
parameterCount);
|
||||||
/* typecheck return value */
|
/* typecheck return value */
|
||||||
checkretval(returnType, querytree_list);
|
checkretval(returnType, querytree_list);
|
||||||
}
|
}
|
||||||
@ -196,12 +198,11 @@ ProcedureCreate(char *procedureName,
|
|||||||
* of backwards compatibility, accept an empty 'prosrc' value as
|
* of backwards compatibility, accept an empty 'prosrc' value as
|
||||||
* meaning the supplied SQL function name.
|
* meaning the supplied SQL function name.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (languageObjectId == INTERNALlanguageId)
|
if (languageObjectId == INTERNALlanguageId)
|
||||||
{
|
{
|
||||||
if (strlen(prosrc) == 0)
|
if (strlen(prosrc) == 0)
|
||||||
prosrc = procedureName;
|
prosrc = procedureName;
|
||||||
if (fmgr_internal_function(prosrc) == InvalidOid)
|
if (fmgr_internal_function((char *) prosrc) == InvalidOid)
|
||||||
elog(ERROR,
|
elog(ERROR,
|
||||||
"there is no built-in function named \"%s\"",
|
"there is no built-in function named \"%s\"",
|
||||||
prosrc);
|
prosrc);
|
||||||
@ -216,7 +217,6 @@ ProcedureCreate(char *procedureName,
|
|||||||
* called, but it seems friendlier to verify the library's validity at
|
* called, but it seems friendlier to verify the library's validity at
|
||||||
* CREATE FUNCTION time.
|
* CREATE FUNCTION time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (languageObjectId == ClanguageId)
|
if (languageObjectId == ClanguageId)
|
||||||
{
|
{
|
||||||
void *libraryhandle;
|
void *libraryhandle;
|
||||||
@ -224,9 +224,11 @@ ProcedureCreate(char *procedureName,
|
|||||||
/* If link symbol is specified as "-", substitute procedure name */
|
/* If link symbol is specified as "-", substitute procedure name */
|
||||||
if (strcmp(prosrc, "-") == 0)
|
if (strcmp(prosrc, "-") == 0)
|
||||||
prosrc = procedureName;
|
prosrc = procedureName;
|
||||||
(void) load_external_function(probin, prosrc, true,
|
(void) load_external_function((char *) probin,
|
||||||
|
(char *) prosrc,
|
||||||
|
true,
|
||||||
&libraryhandle);
|
&libraryhandle);
|
||||||
(void) fetch_finfo_record(libraryhandle, prosrc);
|
(void) fetch_finfo_record(libraryhandle, (char *) prosrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -242,18 +244,18 @@ ProcedureCreate(char *procedureName,
|
|||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
namestrcpy(&procname, procedureName);
|
namestrcpy(&procname, procedureName);
|
||||||
values[i++] = NameGetDatum(&procname);
|
values[i++] = NameGetDatum(&procname); /* proname */
|
||||||
values[i++] = Int32GetDatum(GetUserId());
|
values[i++] = ObjectIdGetDatum(procNamespace); /* pronamespace */
|
||||||
values[i++] = ObjectIdGetDatum(languageObjectId);
|
values[i++] = Int32GetDatum(GetUserId()); /* proowner */
|
||||||
/* XXX isinherited is always false for now */
|
values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */
|
||||||
values[i++] = BoolGetDatum(false);
|
values[i++] = BoolGetDatum(false); /* proisinh (unused) */
|
||||||
values[i++] = BoolGetDatum(trusted);
|
values[i++] = BoolGetDatum(trusted); /* proistrusted */
|
||||||
values[i++] = BoolGetDatum(canCache);
|
values[i++] = BoolGetDatum(isStrict); /* proisstrict */
|
||||||
values[i++] = BoolGetDatum(isStrict);
|
values[i++] = CharGetDatum(volatility); /* provolatile */
|
||||||
values[i++] = UInt16GetDatum(parameterCount);
|
values[i++] = UInt16GetDatum(parameterCount); /* pronargs */
|
||||||
values[i++] = BoolGetDatum(returnsSet);
|
values[i++] = BoolGetDatum(returnsSet); /* proretset */
|
||||||
values[i++] = ObjectIdGetDatum(returnType);
|
values[i++] = ObjectIdGetDatum(returnType); /* prorettype */
|
||||||
values[i++] = PointerGetDatum(typev);
|
values[i++] = PointerGetDatum(typev); /* proargtypes */
|
||||||
values[i++] = Int32GetDatum(byte_pct); /* probyte_pct */
|
values[i++] = Int32GetDatum(byte_pct); /* probyte_pct */
|
||||||
values[i++] = Int32GetDatum(perbyte_cpu); /* properbyte_cpu */
|
values[i++] = Int32GetDatum(perbyte_cpu); /* properbyte_cpu */
|
||||||
values[i++] = Int32GetDatum(percall_cpu); /* propercall_cpu */
|
values[i++] = Int32GetDatum(percall_cpu); /* propercall_cpu */
|
||||||
@ -262,6 +264,8 @@ ProcedureCreate(char *procedureName,
|
|||||||
CStringGetDatum(prosrc));
|
CStringGetDatum(prosrc));
|
||||||
values[i++] = DirectFunctionCall1(textin, /* probin */
|
values[i++] = DirectFunctionCall1(textin, /* probin */
|
||||||
CStringGetDatum(probin));
|
CStringGetDatum(probin));
|
||||||
|
/* proacl will be handled below */
|
||||||
|
|
||||||
|
|
||||||
rel = heap_openr(ProcedureRelationName, RowExclusiveLock);
|
rel = heap_openr(ProcedureRelationName, RowExclusiveLock);
|
||||||
tupDesc = rel->rd_att;
|
tupDesc = rel->rd_att;
|
||||||
@ -294,7 +298,7 @@ ProcedureCreate(char *procedureName,
|
|||||||
elog(ERROR, "ProcedureCreate: cannot change return type of existing function."
|
elog(ERROR, "ProcedureCreate: cannot change return type of existing function."
|
||||||
"\n\tUse DROP FUNCTION first.");
|
"\n\tUse DROP FUNCTION first.");
|
||||||
|
|
||||||
/* do not change existing permissions */
|
/* do not change existing permissions, either */
|
||||||
replaces[Anum_pg_proc_proacl-1] = ' ';
|
replaces[Anum_pg_proc_proacl-1] = ' ';
|
||||||
|
|
||||||
/* Okay, do it... */
|
/* Okay, do it... */
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.72 2002/03/29 19:06:06 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.73 2002/04/05 00:31:25 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
|
||||||
@ -145,7 +145,7 @@ static void
|
|||||||
compute_full_attributes(List *parameters,
|
compute_full_attributes(List *parameters,
|
||||||
int32 *byte_pct_p, int32 *perbyte_cpu_p,
|
int32 *byte_pct_p, int32 *perbyte_cpu_p,
|
||||||
int32 *percall_cpu_p, int32 *outin_ratio_p,
|
int32 *percall_cpu_p, int32 *outin_ratio_p,
|
||||||
bool *canCache_p, bool *isStrict_p)
|
bool *isStrict_p, char *volatility_p)
|
||||||
{
|
{
|
||||||
/*-------------
|
/*-------------
|
||||||
* Interpret the parameters *parameters and return their contents as
|
* Interpret the parameters *parameters and return their contents as
|
||||||
@ -156,18 +156,15 @@ compute_full_attributes(List *parameters,
|
|||||||
*
|
*
|
||||||
* Note: currently, only two of these parameters actually do anything:
|
* Note: currently, only two of these parameters actually do anything:
|
||||||
*
|
*
|
||||||
* * canCache means the optimizer's constant-folder is allowed to
|
|
||||||
* pre-evaluate the function when all its inputs are constants.
|
|
||||||
*
|
|
||||||
* * isStrict means the function should not be called when any NULL
|
* * isStrict means the function should not be called when any NULL
|
||||||
* inputs are present; instead a NULL result value should be assumed.
|
* inputs are present; instead a NULL result value should be assumed.
|
||||||
*
|
*
|
||||||
|
* * volatility tells the optimizer whether the function's result can
|
||||||
|
* be assumed to be repeatable over multiple evaluations.
|
||||||
|
*
|
||||||
* The other four parameters are not used anywhere. They used to be
|
* The other four parameters are not used anywhere. They used to be
|
||||||
* used in the "expensive functions" optimizer, but that's been dead code
|
* used in the "expensive functions" optimizer, but that's been dead code
|
||||||
* for a long time.
|
* for a long time.
|
||||||
*
|
|
||||||
* Since canCache and isStrict are useful for any function, we now allow
|
|
||||||
* attributes to be supplied for all functions regardless of language.
|
|
||||||
*------------
|
*------------
|
||||||
*/
|
*/
|
||||||
List *pl;
|
List *pl;
|
||||||
@ -177,17 +174,26 @@ compute_full_attributes(List *parameters,
|
|||||||
*perbyte_cpu_p = PERBYTE_CPU;
|
*perbyte_cpu_p = PERBYTE_CPU;
|
||||||
*percall_cpu_p = PERCALL_CPU;
|
*percall_cpu_p = PERCALL_CPU;
|
||||||
*outin_ratio_p = OUTIN_RATIO;
|
*outin_ratio_p = OUTIN_RATIO;
|
||||||
*canCache_p = false;
|
|
||||||
*isStrict_p = false;
|
*isStrict_p = false;
|
||||||
|
*volatility_p = PROVOLATILE_VOLATILE;
|
||||||
|
|
||||||
foreach(pl, parameters)
|
foreach(pl, parameters)
|
||||||
{
|
{
|
||||||
DefElem *param = (DefElem *) lfirst(pl);
|
DefElem *param = (DefElem *) lfirst(pl);
|
||||||
|
|
||||||
if (strcasecmp(param->defname, "iscachable") == 0)
|
if (strcasecmp(param->defname, "isstrict") == 0)
|
||||||
*canCache_p = true;
|
|
||||||
else if (strcasecmp(param->defname, "isstrict") == 0)
|
|
||||||
*isStrict_p = true;
|
*isStrict_p = true;
|
||||||
|
else if (strcasecmp(param->defname, "isimmutable") == 0)
|
||||||
|
*volatility_p = PROVOLATILE_IMMUTABLE;
|
||||||
|
else if (strcasecmp(param->defname, "isstable") == 0)
|
||||||
|
*volatility_p = PROVOLATILE_STABLE;
|
||||||
|
else if (strcasecmp(param->defname, "isvolatile") == 0)
|
||||||
|
*volatility_p = PROVOLATILE_VOLATILE;
|
||||||
|
else if (strcasecmp(param->defname, "iscachable") == 0)
|
||||||
|
{
|
||||||
|
/* obsolete spelling of isImmutable */
|
||||||
|
*volatility_p = PROVOLATILE_IMMUTABLE;
|
||||||
|
}
|
||||||
else if (strcasecmp(param->defname, "trusted") == 0)
|
else if (strcasecmp(param->defname, "trusted") == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -273,8 +279,8 @@ CreateFunction(ProcedureStmt *stmt)
|
|||||||
perbyte_cpu,
|
perbyte_cpu,
|
||||||
percall_cpu,
|
percall_cpu,
|
||||||
outin_ratio;
|
outin_ratio;
|
||||||
bool canCache,
|
bool isStrict;
|
||||||
isStrict;
|
char volatility;
|
||||||
HeapTuple languageTuple;
|
HeapTuple languageTuple;
|
||||||
Form_pg_language languageStruct;
|
Form_pg_language languageStruct;
|
||||||
|
|
||||||
@ -311,7 +317,7 @@ CreateFunction(ProcedureStmt *stmt)
|
|||||||
|
|
||||||
compute_full_attributes(stmt->withClause,
|
compute_full_attributes(stmt->withClause,
|
||||||
&byte_pct, &perbyte_cpu, &percall_cpu,
|
&byte_pct, &perbyte_cpu, &percall_cpu,
|
||||||
&outin_ratio, &canCache, &isStrict);
|
&outin_ratio, &isStrict, &volatility);
|
||||||
|
|
||||||
interpret_AS_clause(languageOid, languageName, stmt->as,
|
interpret_AS_clause(languageOid, languageName, stmt->as,
|
||||||
&prosrc_str, &probin_str);
|
&prosrc_str, &probin_str);
|
||||||
@ -329,8 +335,8 @@ CreateFunction(ProcedureStmt *stmt)
|
|||||||
prosrc_str, /* converted to text later */
|
prosrc_str, /* converted to text later */
|
||||||
probin_str, /* converted to text later */
|
probin_str, /* converted to text later */
|
||||||
true, /* (obsolete "trusted") */
|
true, /* (obsolete "trusted") */
|
||||||
canCache,
|
|
||||||
isStrict,
|
isStrict,
|
||||||
|
volatility,
|
||||||
byte_pct,
|
byte_pct,
|
||||||
perbyte_cpu,
|
perbyte_cpu,
|
||||||
percall_cpu,
|
percall_cpu,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.66 2002/03/31 06:26:30 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.67 2002/04/05 00:31:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -21,6 +21,7 @@
|
|||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_opclass.h"
|
#include "catalog/pg_opclass.h"
|
||||||
|
#include "catalog/pg_proc.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "optimizer/clauses.h"
|
#include "optimizer/clauses.h"
|
||||||
@ -233,11 +234,11 @@ CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid)
|
|||||||
elog(ERROR, "Cannot use aggregate in index predicate");
|
elog(ERROR, "Cannot use aggregate in index predicate");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A predicate using noncachable functions is probably wrong, for the
|
* A predicate using mutable functions is probably wrong, for the
|
||||||
* same reasons that we don't allow a functional index to use one.
|
* same reasons that we don't allow a functional index to use one.
|
||||||
*/
|
*/
|
||||||
if (contain_noncachable_functions((Node *) predList))
|
if (contain_mutable_functions((Node *) predList))
|
||||||
elog(ERROR, "Cannot use non-cachable function in index predicate");
|
elog(ERROR, "Functions in index predicate must be marked isImmutable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -320,13 +321,13 @@ FuncIndexArgs(IndexInfo *indexInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Require that the function be marked cachable. Using a noncachable
|
* Require that the function be marked immutable. Using a mutable
|
||||||
* function for a functional index is highly questionable, since if
|
* function for a functional index is highly questionable, since if
|
||||||
* you aren't going to get the same result for the same data every
|
* you aren't going to get the same result for the same data every
|
||||||
* time, it's not clear what the index entries mean at all.
|
* time, it's not clear what the index entries mean at all.
|
||||||
*/
|
*/
|
||||||
if (!func_iscachable(funcid))
|
if (func_volatile(funcid) != PROVOLATILE_IMMUTABLE)
|
||||||
elog(ERROR, "DefineIndex: index function must be marked iscachable");
|
elog(ERROR, "DefineIndex: index function must be marked isImmutable");
|
||||||
|
|
||||||
/* Process opclass, using func return type as default type */
|
/* Process opclass, using func return type as default type */
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.114 2002/03/20 19:44:09 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.115 2002/04/05 00:31:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -783,7 +783,7 @@ match_clause_to_indexkey(RelOptInfo *rel,
|
|||||||
* Check for an indexqual that could be handled by a nestloop
|
* Check for an indexqual that could be handled by a nestloop
|
||||||
* join. We need the index key to be compared against an
|
* join. We need the index key to be compared against an
|
||||||
* expression that uses none of the indexed relation's vars and
|
* expression that uses none of the indexed relation's vars and
|
||||||
* contains no non-cachable functions.
|
* contains no volatile functions.
|
||||||
*/
|
*/
|
||||||
if (match_index_to_operand(indexkey, leftop, rel, index))
|
if (match_index_to_operand(indexkey, leftop, rel, index))
|
||||||
{
|
{
|
||||||
@ -792,7 +792,7 @@ match_clause_to_indexkey(RelOptInfo *rel,
|
|||||||
|
|
||||||
isIndexable =
|
isIndexable =
|
||||||
!intMember(lfirsti(rel->relids), othervarnos) &&
|
!intMember(lfirsti(rel->relids), othervarnos) &&
|
||||||
!contain_noncachable_functions((Node *) rightop) &&
|
!contain_volatile_functions((Node *) rightop) &&
|
||||||
is_indexable_operator(clause, opclass, true);
|
is_indexable_operator(clause, opclass, true);
|
||||||
freeList(othervarnos);
|
freeList(othervarnos);
|
||||||
return isIndexable;
|
return isIndexable;
|
||||||
@ -804,7 +804,7 @@ match_clause_to_indexkey(RelOptInfo *rel,
|
|||||||
|
|
||||||
isIndexable =
|
isIndexable =
|
||||||
!intMember(lfirsti(rel->relids), othervarnos) &&
|
!intMember(lfirsti(rel->relids), othervarnos) &&
|
||||||
!contain_noncachable_functions((Node *) leftop) &&
|
!contain_volatile_functions((Node *) leftop) &&
|
||||||
is_indexable_operator(clause, opclass, false);
|
is_indexable_operator(clause, opclass, false);
|
||||||
freeList(othervarnos);
|
freeList(othervarnos);
|
||||||
return isIndexable;
|
return isIndexable;
|
||||||
@ -1142,7 +1142,7 @@ static const StrategyNumber
|
|||||||
* implies another. A simple and general way is to see if they are
|
* implies another. A simple and general way is to see if they are
|
||||||
* equal(); this works for any kind of expression. (Actually, there
|
* equal(); this works for any kind of expression. (Actually, there
|
||||||
* is an implied assumption that the functions in the expression are
|
* is an implied assumption that the functions in the expression are
|
||||||
* cachable, ie dependent only on their input arguments --- but this
|
* immutable, ie dependent only on their input arguments --- but this
|
||||||
* was checked for the predicate by CheckPredicate().)
|
* was checked for the predicate by CheckPredicate().)
|
||||||
*
|
*
|
||||||
* Our other way works only for (binary boolean) operators that are
|
* Our other way works only for (binary boolean) operators that are
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.95 2002/03/21 16:00:44 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.96 2002/04/05 00:31:27 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -52,7 +52,8 @@ static bool contain_subplans_walker(Node *node, void *context);
|
|||||||
static bool pull_subplans_walker(Node *node, List **listptr);
|
static bool pull_subplans_walker(Node *node, List **listptr);
|
||||||
static bool check_subplans_for_ungrouped_vars_walker(Node *node,
|
static bool check_subplans_for_ungrouped_vars_walker(Node *node,
|
||||||
check_subplans_for_ungrouped_vars_context * context);
|
check_subplans_for_ungrouped_vars_context * context);
|
||||||
static bool contain_noncachable_functions_walker(Node *node, void *context);
|
static bool contain_mutable_functions_walker(Node *node, void *context);
|
||||||
|
static bool contain_volatile_functions_walker(Node *node, void *context);
|
||||||
static Node *eval_const_expressions_mutator(Node *node, void *context);
|
static Node *eval_const_expressions_mutator(Node *node, void *context);
|
||||||
static Expr *simplify_op_or_func(Expr *expr, List *args);
|
static Expr *simplify_op_or_func(Expr *expr, List *args);
|
||||||
|
|
||||||
@ -698,29 +699,29 @@ check_subplans_for_ungrouped_vars_walker(Node *node,
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Check clauses for noncachable functions
|
* Check clauses for mutable functions
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* contain_noncachable_functions
|
* contain_mutable_functions
|
||||||
* Recursively search for noncachable functions within a clause.
|
* Recursively search for mutable functions within a clause.
|
||||||
*
|
*
|
||||||
* Returns true if any noncachable function (or operator implemented by a
|
* Returns true if any mutable function (or operator implemented by a
|
||||||
* noncachable function) is found. This test is needed so that we don't
|
* mutable function) is found. This test is needed so that we don't
|
||||||
* mistakenly think that something like "WHERE random() < 0.5" can be treated
|
* mistakenly think that something like "WHERE random() < 0.5" can be treated
|
||||||
* as a constant qualification.
|
* as a constant qualification.
|
||||||
*
|
*
|
||||||
* XXX we do not examine sublinks/subplans to see if they contain uses of
|
* XXX we do not examine sublinks/subplans to see if they contain uses of
|
||||||
* noncachable functions. It's not real clear if that is correct or not...
|
* mutable functions. It's not real clear if that is correct or not...
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
contain_noncachable_functions(Node *clause)
|
contain_mutable_functions(Node *clause)
|
||||||
{
|
{
|
||||||
return contain_noncachable_functions_walker(clause, NULL);
|
return contain_mutable_functions_walker(clause, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
contain_noncachable_functions_walker(Node *node, void *context)
|
contain_mutable_functions_walker(Node *node, void *context)
|
||||||
{
|
{
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return false;
|
return false;
|
||||||
@ -731,18 +732,67 @@ contain_noncachable_functions_walker(Node *node, void *context)
|
|||||||
switch (expr->opType)
|
switch (expr->opType)
|
||||||
{
|
{
|
||||||
case OP_EXPR:
|
case OP_EXPR:
|
||||||
if (!op_iscachable(((Oper *) expr->oper)->opno))
|
if (op_volatile(((Oper *) expr->oper)->opno) != PROVOLATILE_IMMUTABLE)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case FUNC_EXPR:
|
case FUNC_EXPR:
|
||||||
if (!func_iscachable(((Func *) expr->oper)->funcid))
|
if (func_volatile(((Func *) expr->oper)->funcid) != PROVOLATILE_IMMUTABLE)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return expression_tree_walker(node, contain_noncachable_functions_walker,
|
return expression_tree_walker(node, contain_mutable_functions_walker,
|
||||||
|
context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Check clauses for volatile functions
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* contain_volatile_functions
|
||||||
|
* Recursively search for volatile functions within a clause.
|
||||||
|
*
|
||||||
|
* Returns true if any volatile function (or operator implemented by a
|
||||||
|
* volatile function) is found. This test prevents invalid conversions
|
||||||
|
* of volatile expressions into indexscan quals.
|
||||||
|
*
|
||||||
|
* XXX we do not examine sublinks/subplans to see if they contain uses of
|
||||||
|
* volatile functions. It's not real clear if that is correct or not...
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
contain_volatile_functions(Node *clause)
|
||||||
|
{
|
||||||
|
return contain_volatile_functions_walker(clause, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
contain_volatile_functions_walker(Node *node, void *context)
|
||||||
|
{
|
||||||
|
if (node == NULL)
|
||||||
|
return false;
|
||||||
|
if (IsA(node, Expr))
|
||||||
|
{
|
||||||
|
Expr *expr = (Expr *) node;
|
||||||
|
|
||||||
|
switch (expr->opType)
|
||||||
|
{
|
||||||
|
case OP_EXPR:
|
||||||
|
if (op_volatile(((Oper *) expr->oper)->opno) == PROVOLATILE_VOLATILE)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case FUNC_EXPR:
|
||||||
|
if (func_volatile(((Func *) expr->oper)->funcid) == PROVOLATILE_VOLATILE)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return expression_tree_walker(node, contain_volatile_functions_walker,
|
||||||
context);
|
context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,23 +804,25 @@ contain_noncachable_functions_walker(Node *node, void *context)
|
|||||||
/*
|
/*
|
||||||
* is_pseudo_constant_clause
|
* is_pseudo_constant_clause
|
||||||
* Detect whether a clause is "constant", ie, it contains no variables
|
* Detect whether a clause is "constant", ie, it contains no variables
|
||||||
* of the current query level and no uses of noncachable functions.
|
* of the current query level and no uses of volatile functions.
|
||||||
* Such a clause is not necessarily a true constant: it can still contain
|
* Such a clause is not necessarily a true constant: it can still contain
|
||||||
* Params and outer-level Vars. However, its value will be constant over
|
* Params and outer-level Vars, not to mention functions whose results
|
||||||
* any one scan of the current query, so it can be used as an indexscan
|
* may vary from one statement to the next. However, the clause's value
|
||||||
* key or (if a top-level qual) can be pushed up to become a gating qual.
|
* will be constant over any one scan of the current query, so it can be
|
||||||
|
* used as an indexscan key or (if a top-level qual) can be pushed up to
|
||||||
|
* become a gating qual.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
is_pseudo_constant_clause(Node *clause)
|
is_pseudo_constant_clause(Node *clause)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We could implement this check in one recursive scan. But since the
|
* We could implement this check in one recursive scan. But since the
|
||||||
* check for noncachable functions is both moderately expensive and
|
* check for volatile functions is both moderately expensive and
|
||||||
* unlikely to fail, it seems better to look for Vars first and only
|
* unlikely to fail, it seems better to look for Vars first and only
|
||||||
* check for noncachable functions if we find no Vars.
|
* check for volatile functions if we find no Vars.
|
||||||
*/
|
*/
|
||||||
if (!contain_var_clause(clause) &&
|
if (!contain_var_clause(clause) &&
|
||||||
!contain_noncachable_functions(clause))
|
!contain_volatile_functions(clause))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1019,7 +1071,7 @@ CommuteClause(Expr *clause)
|
|||||||
*
|
*
|
||||||
* We do understand that certain functions may deliver non-constant
|
* We do understand that certain functions may deliver non-constant
|
||||||
* results even with constant inputs, "nextval()" being the classic
|
* results even with constant inputs, "nextval()" being the classic
|
||||||
* example. Functions that are not marked "proiscachable" in pg_proc
|
* example. Functions that are not marked "immutable" in pg_proc
|
||||||
* will not be pre-evaluated here, although we will reduce their
|
* will not be pre-evaluated here, although we will reduce their
|
||||||
* arguments as far as possible. Functions that are the arguments
|
* arguments as far as possible. Functions that are the arguments
|
||||||
* of Iter nodes are also not evaluated.
|
* of Iter nodes are also not evaluated.
|
||||||
@ -1412,7 +1464,7 @@ simplify_op_or_func(Expr *expr, List *args)
|
|||||||
Oid result_typeid;
|
Oid result_typeid;
|
||||||
HeapTuple func_tuple;
|
HeapTuple func_tuple;
|
||||||
Form_pg_proc funcform;
|
Form_pg_proc funcform;
|
||||||
bool proiscachable;
|
char provolatile;
|
||||||
bool proisstrict;
|
bool proisstrict;
|
||||||
bool proretset;
|
bool proretset;
|
||||||
int16 resultTypLen;
|
int16 resultTypLen;
|
||||||
@ -1447,7 +1499,7 @@ simplify_op_or_func(Expr *expr, List *args)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the function procedure's OID and look to see whether it is
|
* Get the function procedure's OID and look to see whether it is
|
||||||
* marked proiscachable.
|
* marked immutable.
|
||||||
*
|
*
|
||||||
* XXX would it be better to take the result type from the pg_proc tuple,
|
* XXX would it be better to take the result type from the pg_proc tuple,
|
||||||
* rather than the Oper or Func node?
|
* rather than the Oper or Func node?
|
||||||
@ -1469,7 +1521,7 @@ simplify_op_or_func(Expr *expr, List *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we could use func_iscachable() here, but we need several fields out
|
* we could use func_volatile() here, but we need several fields out
|
||||||
* of the func tuple, so might as well just look it up once.
|
* of the func tuple, so might as well just look it up once.
|
||||||
*/
|
*/
|
||||||
func_tuple = SearchSysCache(PROCOID,
|
func_tuple = SearchSysCache(PROCOID,
|
||||||
@ -1478,12 +1530,12 @@ simplify_op_or_func(Expr *expr, List *args)
|
|||||||
if (!HeapTupleIsValid(func_tuple))
|
if (!HeapTupleIsValid(func_tuple))
|
||||||
elog(ERROR, "Function OID %u does not exist", funcid);
|
elog(ERROR, "Function OID %u does not exist", funcid);
|
||||||
funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
|
funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
|
||||||
proiscachable = funcform->proiscachable;
|
provolatile = funcform->provolatile;
|
||||||
proisstrict = funcform->proisstrict;
|
proisstrict = funcform->proisstrict;
|
||||||
proretset = funcform->proretset;
|
proretset = funcform->proretset;
|
||||||
ReleaseSysCache(func_tuple);
|
ReleaseSysCache(func_tuple);
|
||||||
|
|
||||||
if (!proiscachable)
|
if (provolatile != PROVOLATILE_IMMUTABLE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.122 2002/03/29 22:10:33 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.123 2002/04/05 00:31:27 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -525,7 +525,7 @@ func_get_candidates(char *funcname, int nargs)
|
|||||||
(RegProcedure) F_INT2EQ,
|
(RegProcedure) F_INT2EQ,
|
||||||
Int16GetDatum(nargs));
|
Int16GetDatum(nargs));
|
||||||
|
|
||||||
funcscan = systable_beginscan(heapRelation, ProcedureNameIndex, true,
|
funcscan = systable_beginscan(heapRelation, ProcedureNameNspIndex, true,
|
||||||
SnapshotNow, 2, skey);
|
SnapshotNow, 2, skey);
|
||||||
|
|
||||||
while (HeapTupleIsValid(tuple = systable_getnext(funcscan)))
|
while (HeapTupleIsValid(tuple = systable_getnext(funcscan)))
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh,v 1.21 2002/02/18 23:11:20 petere Exp $
|
# $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh,v 1.22 2002/04/05 00:31:28 tgl Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ sed -e 's/^.*OID[^=]*=[^0-9]*//' \
|
|||||||
-e 's/[ ]*).*$//' | \
|
-e 's/[ ]*).*$//' | \
|
||||||
$AWK '
|
$AWK '
|
||||||
/^#/ { print; next; }
|
/^#/ { print; next; }
|
||||||
$4 == "12" { print; next; }' > $CPPTMPFILE
|
$5 == "12" { print; next; }' > $CPPTMPFILE
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
cleanup
|
cleanup
|
||||||
@ -232,7 +232,7 @@ $AWK 'BEGIN {
|
|||||||
Bool["f"] = "false"
|
Bool["f"] = "false"
|
||||||
}
|
}
|
||||||
{ printf (" { %d, \"%s\", %d, %s, %s, %s },\n"), \
|
{ printf (" { %d, \"%s\", %d, %s, %s, %s },\n"), \
|
||||||
$1, $(NF-2), $9, Bool[$8], Bool[$10], $(NF-2)
|
$1, $(NF-2), $10, Bool[$8], Bool[$11], $(NF-2)
|
||||||
}' $RAWFILE >> "$$-$TABLEFILE"
|
}' $RAWFILE >> "$$-$TABLEFILE"
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.64 2001/10/25 05:49:45 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.65 2002/04/05 00:31:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -42,13 +42,13 @@ regprocin(PG_FUNCTION_ARGS)
|
|||||||
char *pro_name_or_oid = PG_GETARG_CSTRING(0);
|
char *pro_name_or_oid = PG_GETARG_CSTRING(0);
|
||||||
RegProcedure result = InvalidOid;
|
RegProcedure result = InvalidOid;
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
ScanKeyData skey[1];
|
|
||||||
|
|
||||||
if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '\0')
|
if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '\0')
|
||||||
PG_RETURN_OID(InvalidOid);
|
PG_RETURN_OID(InvalidOid);
|
||||||
|
|
||||||
if (pro_name_or_oid[0] >= '0' &&
|
if (pro_name_or_oid[0] >= '0' &&
|
||||||
pro_name_or_oid[0] <= '9')
|
pro_name_or_oid[0] <= '9' &&
|
||||||
|
strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))
|
||||||
{
|
{
|
||||||
Oid searchOid;
|
Oid searchOid;
|
||||||
|
|
||||||
@ -61,67 +61,33 @@ regprocin(PG_FUNCTION_ARGS)
|
|||||||
elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
|
elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
|
||||||
matches = 1;
|
matches = 1;
|
||||||
}
|
}
|
||||||
else if (!IsIgnoringSystemIndexes())
|
|
||||||
{
|
|
||||||
Relation hdesc;
|
|
||||||
Relation idesc;
|
|
||||||
IndexScanDesc sd;
|
|
||||||
RetrieveIndexResult indexRes;
|
|
||||||
HeapTupleData tuple;
|
|
||||||
Buffer buffer;
|
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
|
||||||
(AttrNumber) 1,
|
|
||||||
(RegProcedure) F_NAMEEQ,
|
|
||||||
CStringGetDatum(pro_name_or_oid));
|
|
||||||
|
|
||||||
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
|
|
||||||
idesc = index_openr(ProcedureNameIndex);
|
|
||||||
sd = index_beginscan(idesc, false, 1, skey);
|
|
||||||
|
|
||||||
while ((indexRes = index_getnext(sd, ForwardScanDirection)))
|
|
||||||
{
|
|
||||||
tuple.t_datamcxt = NULL;
|
|
||||||
tuple.t_data = NULL;
|
|
||||||
tuple.t_self = indexRes->heap_iptr;
|
|
||||||
heap_fetch(hdesc, SnapshotNow, &tuple, &buffer, sd);
|
|
||||||
pfree(indexRes);
|
|
||||||
if (tuple.t_data != NULL)
|
|
||||||
{
|
|
||||||
result = (RegProcedure) tuple.t_data->t_oid;
|
|
||||||
ReleaseBuffer(buffer);
|
|
||||||
if (++matches > 1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
index_endscan(sd);
|
|
||||||
index_close(idesc);
|
|
||||||
heap_close(hdesc, AccessShareLock);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Relation proc;
|
Relation hdesc;
|
||||||
HeapScanDesc procscan;
|
ScanKeyData skey[1];
|
||||||
HeapTuple proctup;
|
SysScanDesc funcscan;
|
||||||
|
HeapTuple tuple;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0x0,
|
||||||
(AttrNumber) Anum_pg_proc_proname,
|
(AttrNumber) Anum_pg_proc_proname,
|
||||||
(RegProcedure) F_NAMEEQ,
|
(RegProcedure) F_NAMEEQ,
|
||||||
CStringGetDatum(pro_name_or_oid));
|
CStringGetDatum(pro_name_or_oid));
|
||||||
|
|
||||||
proc = heap_openr(ProcedureRelationName, AccessShareLock);
|
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
|
||||||
procscan = heap_beginscan(proc, 0, SnapshotNow, 1, skey);
|
|
||||||
|
|
||||||
while (HeapTupleIsValid(proctup = heap_getnext(procscan, 0)))
|
funcscan = systable_beginscan(hdesc, ProcedureNameNspIndex, true,
|
||||||
|
SnapshotNow, 1, skey);
|
||||||
|
|
||||||
|
while (HeapTupleIsValid(tuple = systable_getnext(funcscan)))
|
||||||
{
|
{
|
||||||
result = proctup->t_data->t_oid;
|
result = (RegProcedure) tuple->t_data->t_oid;
|
||||||
if (++matches > 1)
|
if (++matches > 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_endscan(procscan);
|
systable_endscan(funcscan);
|
||||||
heap_close(proc, AccessShareLock);
|
|
||||||
|
heap_close(hdesc, AccessShareLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matches > 1)
|
if (matches > 1)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.41 2002/03/29 19:06:14 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.42 2002/04/05 00:31:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -61,8 +61,8 @@ SetDefine(char *querystr, Oid elemType)
|
|||||||
querystr, /* sourceCode */
|
querystr, /* sourceCode */
|
||||||
fileName, /* fileName */
|
fileName, /* fileName */
|
||||||
true, /* trusted */
|
true, /* trusted */
|
||||||
false, /* canCache (assume unsafe) */
|
|
||||||
false, /* isStrict (irrelevant, no args) */
|
false, /* isStrict (irrelevant, no args) */
|
||||||
|
PROVOLATILE_VOLATILE, /* assume unsafe */
|
||||||
100, /* byte_pct */
|
100, /* byte_pct */
|
||||||
0, /* perbyte_cpu */
|
0, /* perbyte_cpu */
|
||||||
0, /* percall_cpu */
|
0, /* percall_cpu */
|
||||||
|
24
src/backend/utils/cache/lsyscache.c
vendored
24
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
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.68 2002/04/02 01:03:07 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.69 2002/04/05 00:31:30 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
@ -470,19 +470,19 @@ op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* op_iscachable
|
* op_volatile
|
||||||
*
|
*
|
||||||
* Get the proiscachable flag for the operator's underlying function.
|
* Get the provolatile flag for the operator's underlying function.
|
||||||
*/
|
*/
|
||||||
bool
|
char
|
||||||
op_iscachable(Oid opno)
|
op_volatile(Oid opno)
|
||||||
{
|
{
|
||||||
RegProcedure funcid = get_opcode(opno);
|
RegProcedure funcid = get_opcode(opno);
|
||||||
|
|
||||||
if (funcid == (RegProcedure) InvalidOid)
|
if (funcid == (RegProcedure) InvalidOid)
|
||||||
elog(ERROR, "Operator OID %u does not exist", opno);
|
elog(ERROR, "Operator OID %u does not exist", opno);
|
||||||
|
|
||||||
return func_iscachable((Oid) funcid);
|
return func_volatile((Oid) funcid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -613,14 +613,14 @@ get_func_rettype(Oid funcid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* func_iscachable
|
* func_volatile
|
||||||
* Given procedure id, return the function's proiscachable flag.
|
* Given procedure id, return the function's provolatile flag.
|
||||||
*/
|
*/
|
||||||
bool
|
char
|
||||||
func_iscachable(Oid funcid)
|
func_volatile(Oid funcid)
|
||||||
{
|
{
|
||||||
HeapTuple tp;
|
HeapTuple tp;
|
||||||
bool result;
|
char result;
|
||||||
|
|
||||||
tp = SearchSysCache(PROCOID,
|
tp = SearchSysCache(PROCOID,
|
||||||
ObjectIdGetDatum(funcid),
|
ObjectIdGetDatum(funcid),
|
||||||
@ -628,7 +628,7 @@ func_iscachable(Oid funcid)
|
|||||||
if (!HeapTupleIsValid(tp))
|
if (!HeapTupleIsValid(tp))
|
||||||
elog(ERROR, "Function OID %u does not exist", funcid);
|
elog(ERROR, "Function OID %u does not exist", funcid);
|
||||||
|
|
||||||
result = ((Form_pg_proc) GETSTRUCT(tp))->proiscachable;
|
result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
|
||||||
ReleaseSysCache(tp);
|
ReleaseSysCache(tp);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
4
src/backend/utils/cache/syscache.c
vendored
4
src/backend/utils/cache/syscache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.72 2002/03/31 06:26:32 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.73 2002/04/05 00:31:31 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* These routines allow the parser/planner/executor to perform
|
* These routines allow the parser/planner/executor to perform
|
||||||
@ -304,7 +304,7 @@ static const struct cachedesc cacheinfo[] = {
|
|||||||
0
|
0
|
||||||
}},
|
}},
|
||||||
{ProcedureRelationName, /* PROCNAME */
|
{ProcedureRelationName, /* PROCNAME */
|
||||||
ProcedureNameIndex,
|
ProcedureNameNspIndex, /* XXX very temporary */
|
||||||
0,
|
0,
|
||||||
3,
|
3,
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.244 2002/03/21 05:47:14 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.245 2002/04/05 00:31:31 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,7 @@
|
|||||||
#include "access/attnum.h"
|
#include "access/attnum.h"
|
||||||
#include "access/htup.h"
|
#include "access/htup.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_trigger.h"
|
#include "catalog/pg_trigger.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
|
|
||||||
@ -1953,7 +1954,7 @@ getFuncs(int *numFuncs)
|
|||||||
int i_proretset;
|
int i_proretset;
|
||||||
int i_prosrc;
|
int i_prosrc;
|
||||||
int i_probin;
|
int i_probin;
|
||||||
int i_iscachable;
|
int i_provolatile;
|
||||||
int i_isstrict;
|
int i_isstrict;
|
||||||
int i_usename;
|
int i_usename;
|
||||||
|
|
||||||
@ -1965,7 +1966,20 @@ getFuncs(int *numFuncs)
|
|||||||
"SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
|
"SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
|
||||||
"proretset, proargtypes, prosrc, probin, "
|
"proretset, proargtypes, prosrc, probin, "
|
||||||
"(select usename from pg_user where proowner = usesysid) as usename, "
|
"(select usename from pg_user where proowner = usesysid) as usename, "
|
||||||
"proiscachable, 'f'::boolean as proisstrict "
|
"case when proiscachable then 'i' else 'v' end as provolatile, "
|
||||||
|
"'f'::boolean as proisstrict "
|
||||||
|
"from pg_proc "
|
||||||
|
"where pg_proc.oid > '%u'::oid",
|
||||||
|
g_last_builtin_oid);
|
||||||
|
}
|
||||||
|
else if (g_fout->remoteVersion < 70300)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(query,
|
||||||
|
"SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
|
||||||
|
"proretset, proargtypes, prosrc, probin, "
|
||||||
|
"(select usename from pg_user where proowner = usesysid) as usename, "
|
||||||
|
"case when proiscachable then 'i' else 'v' end as provolatile, "
|
||||||
|
"proisstrict "
|
||||||
"from pg_proc "
|
"from pg_proc "
|
||||||
"where pg_proc.oid > '%u'::oid",
|
"where pg_proc.oid > '%u'::oid",
|
||||||
g_last_builtin_oid);
|
g_last_builtin_oid);
|
||||||
@ -1976,7 +1990,7 @@ getFuncs(int *numFuncs)
|
|||||||
"SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
|
"SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
|
||||||
"proretset, proargtypes, prosrc, probin, "
|
"proretset, proargtypes, prosrc, probin, "
|
||||||
"(select usename from pg_user where proowner = usesysid) as usename, "
|
"(select usename from pg_user where proowner = usesysid) as usename, "
|
||||||
"proiscachable, proisstrict "
|
"provolatile, proisstrict "
|
||||||
"from pg_proc "
|
"from pg_proc "
|
||||||
"where pg_proc.oid > '%u'::oid",
|
"where pg_proc.oid > '%u'::oid",
|
||||||
g_last_builtin_oid);
|
g_last_builtin_oid);
|
||||||
@ -2008,7 +2022,7 @@ getFuncs(int *numFuncs)
|
|||||||
i_proretset = PQfnumber(res, "proretset");
|
i_proretset = PQfnumber(res, "proretset");
|
||||||
i_prosrc = PQfnumber(res, "prosrc");
|
i_prosrc = PQfnumber(res, "prosrc");
|
||||||
i_probin = PQfnumber(res, "probin");
|
i_probin = PQfnumber(res, "probin");
|
||||||
i_iscachable = PQfnumber(res, "proiscachable");
|
i_provolatile = PQfnumber(res, "provolatile");
|
||||||
i_isstrict = PQfnumber(res, "proisstrict");
|
i_isstrict = PQfnumber(res, "proisstrict");
|
||||||
i_usename = PQfnumber(res, "usename");
|
i_usename = PQfnumber(res, "usename");
|
||||||
|
|
||||||
@ -2025,7 +2039,7 @@ getFuncs(int *numFuncs)
|
|||||||
finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
|
finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
|
||||||
finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
|
finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
|
||||||
finfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
|
finfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
|
||||||
finfo[i].iscachable = (strcmp(PQgetvalue(res, i, i_iscachable), "t") == 0);
|
finfo[i].provolatile = (PQgetvalue(res, i, i_provolatile))[0];
|
||||||
finfo[i].isstrict = (strcmp(PQgetvalue(res, i, i_isstrict), "t") == 0);
|
finfo[i].isstrict = (strcmp(PQgetvalue(res, i, i_isstrict), "t") == 0);
|
||||||
|
|
||||||
if (strlen(finfo[i].usename) == 0)
|
if (strlen(finfo[i].usename) == 0)
|
||||||
@ -3559,20 +3573,32 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
|
|||||||
asPart->data);
|
asPart->data);
|
||||||
formatStringLiteral(q, func_lang, CONV_ALL);
|
formatStringLiteral(q, func_lang, CONV_ALL);
|
||||||
|
|
||||||
if (finfo[i].iscachable || finfo[i].isstrict) /* OR in new attrs here */
|
if (finfo[i].provolatile != PROVOLATILE_VOLATILE ||
|
||||||
|
finfo[i].isstrict) /* OR in new attrs here */
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(q, " WITH (");
|
appendPQExpBuffer(q, " WITH (");
|
||||||
listSep = listSepNone;
|
listSep = listSepNone;
|
||||||
|
|
||||||
if (finfo[i].iscachable)
|
if (finfo[i].provolatile == PROVOLATILE_IMMUTABLE)
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(q, "%s iscachable", listSep);
|
appendPQExpBuffer(q, "%s isImmutable", listSep);
|
||||||
listSep = listSepComma;
|
listSep = listSepComma;
|
||||||
}
|
}
|
||||||
|
else if (finfo[i].provolatile == PROVOLATILE_STABLE)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(q, "%s isStable", listSep);
|
||||||
|
listSep = listSepComma;
|
||||||
|
}
|
||||||
|
else if (finfo[i].provolatile != PROVOLATILE_VOLATILE)
|
||||||
|
{
|
||||||
|
write_msg(NULL, "Unexpected provolatile value for function %s\n",
|
||||||
|
finfo[i].proname);
|
||||||
|
exit_nicely();
|
||||||
|
}
|
||||||
|
|
||||||
if (finfo[i].isstrict)
|
if (finfo[i].isstrict)
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(q, "%s isstrict", listSep);
|
appendPQExpBuffer(q, "%s isStrict", listSep);
|
||||||
listSep = listSepComma;
|
listSep = listSepComma;
|
||||||
}
|
}
|
||||||
appendPQExpBuffer(q, " )");
|
appendPQExpBuffer(q, " )");
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_dump.h,v 1.78 2002/02/11 00:18:20 tgl Exp $
|
* $Id: pg_dump.h,v 1.79 2002/04/05 00:31:32 tgl Exp $
|
||||||
*
|
*
|
||||||
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
|
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
|
||||||
*
|
*
|
||||||
@ -71,8 +71,8 @@ typedef struct _funcInfo
|
|||||||
char *prosrc;
|
char *prosrc;
|
||||||
char *probin;
|
char *probin;
|
||||||
char *usename;
|
char *usename;
|
||||||
int iscachable; /* Attr */
|
char provolatile; /* Attr */
|
||||||
int isstrict; /* Attr */
|
bool isstrict; /* Attr */
|
||||||
int dumped; /* 1 if already dumped */
|
int dumped; /* 1 if already dumped */
|
||||||
} FuncInfo;
|
} FuncInfo;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: catversion.h,v 1.112 2002/03/29 19:06:17 tgl Exp $
|
* $Id: catversion.h,v 1.113 2002/04/05 00:31:32 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200203261
|
#define CATALOG_VERSION_NO 200204031
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: indexing.h,v 1.60 2002/03/29 19:06:17 tgl Exp $
|
* $Id: indexing.h,v 1.61 2002/04/05 00:31:32 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -77,7 +77,7 @@
|
|||||||
#define OpclassOidIndex "pg_opclass_oid_index"
|
#define OpclassOidIndex "pg_opclass_oid_index"
|
||||||
#define OperatorNameIndex "pg_operator_oprname_l_r_k_index"
|
#define OperatorNameIndex "pg_operator_oprname_l_r_k_index"
|
||||||
#define OperatorOidIndex "pg_operator_oid_index"
|
#define OperatorOidIndex "pg_operator_oid_index"
|
||||||
#define ProcedureNameIndex "pg_proc_proname_narg_type_index"
|
#define ProcedureNameNspIndex "pg_proc_proname_args_nsp_index"
|
||||||
#define ProcedureOidIndex "pg_proc_oid_index"
|
#define ProcedureOidIndex "pg_proc_oid_index"
|
||||||
#define RelCheckIndex "pg_relcheck_rcrelid_index"
|
#define RelCheckIndex "pg_relcheck_rcrelid_index"
|
||||||
#define RewriteOidIndex "pg_rewrite_oid_index"
|
#define RewriteOidIndex "pg_rewrite_oid_index"
|
||||||
@ -176,7 +176,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_k_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprkind char_ops));
|
DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_k_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprkind char_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_narg_type_index on pg_proc using btree(proname name_ops, pronargs int2_ops, proargtypes oidvector_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));
|
||||||
/* 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_INDEX(pg_relcheck_rcrelid_index on pg_relcheck using btree(rcrelid oid_ops));
|
DECLARE_INDEX(pg_relcheck_rcrelid_index on pg_relcheck using btree(rcrelid oid_ops));
|
||||||
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));
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_attribute.h,v 1.88 2002/04/02 08:51:49 inoue Exp $
|
* $Id: pg_attribute.h,v 1.89 2002/04/05 00:31:33 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -295,42 +295,44 @@ DATA(insert ( 1262 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
|
|||||||
*/
|
*/
|
||||||
#define Schema_pg_proc \
|
#define Schema_pg_proc \
|
||||||
{ 1255, {"proname"}, 19, DEFAULT_ATTSTATTARGET, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \
|
{ 1255, {"proname"}, 19, DEFAULT_ATTSTATTARGET, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"proowner"}, 23, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1255, {"pronamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"prolang"}, 26, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1255, {"proowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"proisinh"}, 16, 0, 1, 4, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
{ 1255, {"prolang"}, 26, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"proistrusted"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
{ 1255, {"proisinh"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||||
{ 1255, {"proiscachable"}, 16, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
{ 1255, {"proistrusted"}, 16, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||||
{ 1255, {"proisstrict"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
{ 1255, {"proisstrict"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||||
{ 1255, {"pronargs"}, 21, 0, 2, 8, 0, -1, -1, true, 'p', false, 's', false, false }, \
|
{ 1255, {"provolatile"}, 18, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||||
{ 1255, {"proretset"}, 16, 0, 1, 9, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
{ 1255, {"pronargs"}, 21, 0, 2, 9, 0, -1, -1, true, 'p', false, 's', false, false }, \
|
||||||
{ 1255, {"prorettype"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1255, {"proretset"}, 16, 0, 1, 10, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||||
{ 1255, {"proargtypes"}, 30, 0, INDEX_MAX_KEYS*4, 11, 0, -1, -1, false, 'p', false, 'i', false, false }, \
|
{ 1255, {"prorettype"}, 26, 0, 4, 11, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"probyte_pct"}, 23, 0, 4, 12, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1255, {"proargtypes"}, 30, 0, INDEX_MAX_KEYS*4, 12, 0, -1, -1, false, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"properbyte_cpu"}, 23, 0, 4, 13, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1255, {"probyte_pct"}, 23, 0, 4, 13, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"propercall_cpu"}, 23, 0, 4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1255, {"properbyte_cpu"}, 23, 0, 4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"prooutin_ratio"}, 23, 0, 4, 15, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1255, {"propercall_cpu"}, 23, 0, 4, 15, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"prosrc"}, 25, 0, -1, 16, 0, -1, -1, false, 'x', false, 'i', false, false }, \
|
{ 1255, {"prooutin_ratio"}, 23, 0, 4, 16, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"probin"}, 17, 0, -1, 17, 0, -1, -1, false, 'x', false, 'i', false, false }, \
|
{ 1255, {"prosrc"}, 25, 0, -1, 17, 0, -1, -1, false, 'x', false, 'i', false, false }, \
|
||||||
{ 1255, {"proacl"}, 1034, 0, -1, 18, 0, -1, -1, false, 'x', false, 'i', false, false }
|
{ 1255, {"probin"}, 17, 0, -1, 18, 0, -1, -1, false, 'x', false, 'i', false, false }, \
|
||||||
|
{ 1255, {"proacl"}, 1034, 0, -1, 19, 0, -1, -1, false, 'x', false, 'i', false, false }
|
||||||
|
|
||||||
DATA(insert ( 1255 proname 19 DEFAULT_ATTSTATTARGET NAMEDATALEN 1 0 -1 -1 f p f i f f));
|
DATA(insert ( 1255 proname 19 DEFAULT_ATTSTATTARGET NAMEDATALEN 1 0 -1 -1 f p f i f f));
|
||||||
DATA(insert ( 1255 proowner 23 0 4 2 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 pronamespace 26 0 4 2 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 prolang 26 0 4 3 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 proowner 23 0 4 3 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 proisinh 16 0 1 4 0 -1 -1 t p f c f f));
|
DATA(insert ( 1255 prolang 26 0 4 4 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 proistrusted 16 0 1 5 0 -1 -1 t p f c f f));
|
DATA(insert ( 1255 proisinh 16 0 1 5 0 -1 -1 t p f c f f));
|
||||||
DATA(insert ( 1255 proiscachable 16 0 1 6 0 -1 -1 t p f c f f));
|
DATA(insert ( 1255 proistrusted 16 0 1 6 0 -1 -1 t p f c f f));
|
||||||
DATA(insert ( 1255 proisstrict 16 0 1 7 0 -1 -1 t p f c f f));
|
DATA(insert ( 1255 proisstrict 16 0 1 7 0 -1 -1 t p f c f f));
|
||||||
DATA(insert ( 1255 pronargs 21 0 2 8 0 -1 -1 t p f s f f));
|
DATA(insert ( 1255 provolatile 18 0 1 8 0 -1 -1 t p f c f f));
|
||||||
DATA(insert ( 1255 proretset 16 0 1 9 0 -1 -1 t p f c f f));
|
DATA(insert ( 1255 pronargs 21 0 2 9 0 -1 -1 t p f s f f));
|
||||||
DATA(insert ( 1255 prorettype 26 0 4 10 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 proretset 16 0 1 10 0 -1 -1 t p f c f f));
|
||||||
DATA(insert ( 1255 proargtypes 30 0 INDEX_MAX_KEYS*4 11 0 -1 -1 f p f i f f));
|
DATA(insert ( 1255 prorettype 26 0 4 11 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 probyte_pct 23 0 4 12 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 proargtypes 30 0 INDEX_MAX_KEYS*4 12 0 -1 -1 f p f i f f));
|
||||||
DATA(insert ( 1255 properbyte_cpu 23 0 4 13 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 probyte_pct 23 0 4 13 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 propercall_cpu 23 0 4 14 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 properbyte_cpu 23 0 4 14 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 prooutin_ratio 23 0 4 15 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 propercall_cpu 23 0 4 15 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 prosrc 25 0 -1 16 0 -1 -1 f x f i f f));
|
DATA(insert ( 1255 prooutin_ratio 23 0 4 16 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 probin 17 0 -1 17 0 -1 -1 f x f i f f));
|
DATA(insert ( 1255 prosrc 25 0 -1 17 0 -1 -1 f x f i f f));
|
||||||
DATA(insert ( 1255 proacl 1034 0 -1 18 0 -1 -1 f x f i f f));
|
DATA(insert ( 1255 probin 17 0 -1 18 0 -1 -1 f x f i f f));
|
||||||
|
DATA(insert ( 1255 proacl 1034 0 -1 19 0 -1 -1 f x f i f f));
|
||||||
DATA(insert ( 1255 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
|
DATA(insert ( 1255 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
|
||||||
DATA(insert ( 1255 oid 26 0 4 -2 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 oid 26 0 4 -2 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_class.h,v 1.64 2002/03/29 19:06:18 tgl Exp $
|
* $Id: pg_class.h,v 1.65 2002/04/05 00:31:33 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -138,7 +138,7 @@ DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 f f r 23 0 0 0
|
|||||||
DESCR("");
|
DESCR("");
|
||||||
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ ));
|
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 f f r 18 0 0 0 0 0 t f f f _null_ ));
|
DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 f f r 19 0 0 0 0 0 t f f f _null_ ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
DATA(insert OID = 1259 ( pg_class PGNSP 83 PGUID 0 1259 0 0 0 0 f f r 24 0 0 0 0 0 t f f f _null_ ));
|
DATA(insert OID = 1259 ( pg_class PGNSP 83 PGUID 0 1259 0 0 0 0 f f r 24 0 0 0 0 0 t f f f _null_ ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: clauses.h,v 1.50 2001/12/10 22:54:12 tgl Exp $
|
* $Id: clauses.h,v 1.51 2002/04/05 00:31:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -48,7 +48,8 @@ extern bool contain_subplans(Node *clause);
|
|||||||
extern List *pull_subplans(Node *clause);
|
extern List *pull_subplans(Node *clause);
|
||||||
extern void check_subplans_for_ungrouped_vars(Query *query);
|
extern void check_subplans_for_ungrouped_vars(Query *query);
|
||||||
|
|
||||||
extern bool contain_noncachable_functions(Node *clause);
|
extern bool contain_mutable_functions(Node *clause);
|
||||||
|
extern bool contain_volatile_functions(Node *clause);
|
||||||
|
|
||||||
extern bool is_pseudo_constant_clause(Node *clause);
|
extern bool is_pseudo_constant_clause(Node *clause);
|
||||||
extern List *pull_constant_clauses(List *quals, List **constantQual);
|
extern List *pull_constant_clauses(List *quals, List **constantQual);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: lsyscache.h,v 1.48 2002/04/02 01:03:07 tgl Exp $
|
* $Id: lsyscache.h,v 1.49 2002/04/05 00:31:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -32,13 +32,13 @@ extern bool op_mergejoinable(Oid opno, Oid ltype, Oid rtype,
|
|||||||
extern void op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop,
|
extern void op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop,
|
||||||
RegProcedure *ltproc, RegProcedure *gtproc);
|
RegProcedure *ltproc, RegProcedure *gtproc);
|
||||||
extern Oid op_hashjoinable(Oid opno, Oid ltype, Oid rtype);
|
extern Oid op_hashjoinable(Oid opno, Oid ltype, Oid rtype);
|
||||||
extern bool op_iscachable(Oid opno);
|
extern char op_volatile(Oid opno);
|
||||||
extern Oid get_commutator(Oid opno);
|
extern Oid get_commutator(Oid opno);
|
||||||
extern Oid get_negator(Oid opno);
|
extern Oid get_negator(Oid opno);
|
||||||
extern RegProcedure get_oprrest(Oid opno);
|
extern RegProcedure get_oprrest(Oid opno);
|
||||||
extern RegProcedure get_oprjoin(Oid opno);
|
extern RegProcedure get_oprjoin(Oid opno);
|
||||||
extern Oid get_func_rettype(Oid funcid);
|
extern Oid get_func_rettype(Oid funcid);
|
||||||
extern bool func_iscachable(Oid funcid);
|
extern char func_volatile(Oid funcid);
|
||||||
extern Oid get_relname_relid(const char *relname, Oid relnamespace);
|
extern Oid get_relname_relid(const char *relname, Oid relnamespace);
|
||||||
extern char *get_rel_name(Oid relid);
|
extern char *get_rel_name(Oid relid);
|
||||||
extern Oid get_rel_type_id(Oid relid);
|
extern Oid get_rel_type_id(Oid relid);
|
||||||
|
@ -62,7 +62,7 @@ WHERE p1.oid != p2.oid AND
|
|||||||
(p1.prolang != p2.prolang OR
|
(p1.prolang != p2.prolang OR
|
||||||
p1.proisinh != p2.proisinh OR
|
p1.proisinh != p2.proisinh OR
|
||||||
p1.proistrusted != p2.proistrusted OR
|
p1.proistrusted != p2.proistrusted OR
|
||||||
p1.proiscachable != p2.proiscachable OR
|
p1.provolatile != p2.provolatile OR
|
||||||
p1.pronargs != p2.pronargs OR
|
p1.pronargs != p2.pronargs OR
|
||||||
p1.proretset != p2.proretset);
|
p1.proretset != p2.proretset);
|
||||||
oid | proname | oid | proname
|
oid | proname | oid | proname
|
||||||
|
@ -61,7 +61,7 @@ WHERE p1.oid != p2.oid AND
|
|||||||
(p1.prolang != p2.prolang OR
|
(p1.prolang != p2.prolang OR
|
||||||
p1.proisinh != p2.proisinh OR
|
p1.proisinh != p2.proisinh OR
|
||||||
p1.proistrusted != p2.proistrusted OR
|
p1.proistrusted != p2.proistrusted OR
|
||||||
p1.proiscachable != p2.proiscachable OR
|
p1.provolatile != p2.provolatile OR
|
||||||
p1.pronargs != p2.pronargs OR
|
p1.pronargs != p2.pronargs OR
|
||||||
p1.proretset != p2.proretset);
|
p1.proretset != p2.proretset);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user