8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
* HISTORY
14
14
* AUTHOR DATE MAJOR EVENT
30
30
#include "optimizer/var.h"
31
31
#include "parser/analyze.h"
32
32
#include "parser/parse_clause.h"
33
+ #include "parser/parse_expr.h"
33
34
#include "tcop/tcopprot.h"
34
35
#include "utils/acl.h"
35
36
#include "utils/builtins.h"
@@ -1719,6 +1720,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
1719
1720
{
1720
1721
Form_pg_proc funcform = (Form_pg_proc ) GETSTRUCT (func_tuple );
1721
1722
char result_typtype ;
1723
+ bool polymorphic = false;
1724
+ Oid argtypes [FUNC_MAX_ARGS ];
1722
1725
char * src ;
1723
1726
Datum tmp ;
1724
1727
bool isNull ;
@@ -1731,7 +1734,6 @@ inline_function(Oid funcid, Oid result_type, List *args,
1731
1734
int * usecounts ;
1732
1735
List * arg ;
1733
1736
int i ;
1734
- int j ;
1735
1737
1736
1738
/*
1737
1739
* 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,
1743
1745
funcform -> pronargs != length (args ))
1744
1746
return NULL ;
1745
1747
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 */
1747
1749
result_typtype = get_typtype (funcform -> prorettype );
1748
1750
if (result_typtype != 'b' &&
1749
1751
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 ++ )
1754
1752
{
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
1757
1757
return NULL ;
1758
1758
}
1759
1759
@@ -1765,6 +1765,18 @@ inline_function(Oid funcid, Oid result_type, List *args,
1765
1765
if (pg_proc_aclcheck (funcid , GetUserId (), ACL_EXECUTE ) != ACLCHECK_OK )
1766
1766
return NULL ;
1767
1767
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
+
1768
1780
/*
1769
1781
* Make a temporary memory context, so that we don't leak all the
1770
1782
* stuff that parsing might create.
@@ -1797,8 +1809,7 @@ inline_function(Oid funcid, Oid result_type, List *args,
1797
1809
goto fail ;
1798
1810
1799
1811
querytree_list = parse_analyze (lfirst (raw_parsetree_list ),
1800
- funcform -> proargtypes ,
1801
- funcform -> pronargs );
1812
+ argtypes , funcform -> pronargs );
1802
1813
1803
1814
if (length (querytree_list ) != 1 )
1804
1815
goto fail ;
@@ -1829,6 +1840,18 @@ inline_function(Oid funcid, Oid result_type, List *args,
1829
1840
1830
1841
newexpr = (Node * ) ((TargetEntry * ) lfirst (querytree -> targetList ))-> expr ;
1831
1842
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
+
1832
1855
/*
1833
1856
* Additional validity checks on the expression. It mustn't return a
1834
1857
* set, and it mustn't be more volatile than the surrounding function
0 commit comments