Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 02b5d8e

Browse files
committed
Dept. of second thoughts: supporting inlining of polymorphic SQL functions
takes only a few more lines of code than preventing it, so might as well support it.
1 parent dc8dec6 commit 02b5d8e

File tree

1 file changed

+34
-11
lines changed

1 file changed

+34
-11
lines changed

src/backend/optimizer/util/clauses.c

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.143 2003/07/01 00:04:37 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.144 2003/07/01 19:07:02 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHOR DATE MAJOR EVENT
@@ -30,6 +30,7 @@
3030
#include "optimizer/var.h"
3131
#include "parser/analyze.h"
3232
#include "parser/parse_clause.h"
33+
#include "parser/parse_expr.h"
3334
#include "tcop/tcopprot.h"
3435
#include "utils/acl.h"
3536
#include "utils/builtins.h"
@@ -1719,6 +1720,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
17191720
{
17201721
Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
17211722
char result_typtype;
1723+
bool polymorphic = false;
1724+
Oid argtypes[FUNC_MAX_ARGS];
17221725
char *src;
17231726
Datum tmp;
17241727
bool isNull;
@@ -1731,7 +1734,6 @@ inline_function(Oid funcid, Oid result_type, List *args,
17311734
int *usecounts;
17321735
List *arg;
17331736
int i;
1734-
int j;
17351737

17361738
/*
17371739
* Forget it if the function is not SQL-language or has other
@@ -1743,17 +1745,15 @@ inline_function(Oid funcid, Oid result_type, List *args,
17431745
funcform->pronargs != length(args))
17441746
return NULL;
17451747

1746-
/* Forget it if declared return type is not base or domain */
1748+
/* Forget it if declared return type is not base, domain, or polymorphic */
17471749
result_typtype = get_typtype(funcform->prorettype);
17481750
if (result_typtype != 'b' &&
17491751
result_typtype != 'd')
1750-
return NULL;
1751-
1752-
/* Forget it if any declared argument type is polymorphic */
1753-
for (j = 0; j < funcform->pronargs; j++)
17541752
{
1755-
if (funcform->proargtypes[j] == ANYARRAYOID ||
1756-
funcform->proargtypes[j] == ANYELEMENTOID)
1753+
if (funcform->prorettype == ANYARRAYOID ||
1754+
funcform->prorettype == ANYELEMENTOID)
1755+
polymorphic = true;
1756+
else
17571757
return NULL;
17581758
}
17591759

@@ -1765,6 +1765,18 @@ inline_function(Oid funcid, Oid result_type, List *args,
17651765
if (pg_proc_aclcheck(funcid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
17661766
return NULL;
17671767

1768+
/* Check for polymorphic arguments, and substitute actual arg types */
1769+
memcpy(argtypes, funcform->proargtypes, FUNC_MAX_ARGS * sizeof(Oid));
1770+
for (i = 0; i < funcform->pronargs; i++)
1771+
{
1772+
if (argtypes[i] == ANYARRAYOID ||
1773+
argtypes[i] == ANYELEMENTOID)
1774+
{
1775+
polymorphic = true;
1776+
argtypes[i] = exprType((Node *) nth(i, args));
1777+
}
1778+
}
1779+
17681780
/*
17691781
* Make a temporary memory context, so that we don't leak all the
17701782
* stuff that parsing might create.
@@ -1797,8 +1809,7 @@ inline_function(Oid funcid, Oid result_type, List *args,
17971809
goto fail;
17981810

17991811
querytree_list = parse_analyze(lfirst(raw_parsetree_list),
1800-
funcform->proargtypes,
1801-
funcform->pronargs);
1812+
argtypes, funcform->pronargs);
18021813

18031814
if (length(querytree_list) != 1)
18041815
goto fail;
@@ -1829,6 +1840,18 @@ inline_function(Oid funcid, Oid result_type, List *args,
18291840

18301841
newexpr = (Node *) ((TargetEntry *) lfirst(querytree->targetList))->expr;
18311842

1843+
/*
1844+
* If the function has any arguments declared as polymorphic types,
1845+
* then it wasn't type-checked at definition time; must do so now.
1846+
* (This will raise an error if wrong, but that's okay since the
1847+
* function would fail at runtime anyway. Note we do not try this
1848+
* until we have verified that no rewriting was needed; that's probably
1849+
* not important, but let's be careful.)
1850+
*/
1851+
if (polymorphic)
1852+
check_sql_fn_retval(result_type, get_typtype(result_type),
1853+
querytree_list);
1854+
18321855
/*
18331856
* Additional validity checks on the expression. It mustn't return a
18341857
* set, and it mustn't be more volatile than the surrounding function

0 commit comments

Comments
 (0)