File: 60sql_fun_typecheck.patch

package info (click to toggle)
postgresql 7.4.7-6sarge6
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 11,168 kB
  • ctags: 27
  • sloc: sh: 1,903; makefile: 337; ansic: 204; perl: 69; sed: 6; tcl: 1
file content (153 lines) | stat: -rw-r--r-- 5,351 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
diff -ruN postgresql-7.4.7-old/src/backend/executor/functions.c postgresql-7.4.7/src/backend/executor/functions.c
--- postgresql-7.4.7-old/src/backend/executor/functions.c	2004-09-06 20:23:09.000000000 +0200
+++ postgresql-7.4.7/src/backend/executor/functions.c	2007-02-04 21:50:39.000000000 +0100
@@ -56,7 +56,7 @@
  */
 typedef struct
 {
-	int			typlen;			/* length of the return type */
+	int16		typlen;			/* length of the return type */
 	bool		typbyval;		/* true if return type is pass by value */
 	bool		returnsTuple;	/* true if return type is a tuple */
 	bool		shutdown_reg;	/* true if registered shutdown callback */
@@ -77,7 +77,7 @@
 /* non-export function prototypes */
 static execution_state *init_execution_state(char *src,
 					 Oid *argOidVect, int nargs,
-					 Oid rettype, bool haspolyarg);
+					 Oid rettype);
 static void init_sql_fcache(FmgrInfo *finfo);
 static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache);
 static TupleTableSlot *postquel_getnext(execution_state *es);
@@ -93,7 +93,7 @@
 
 static execution_state *
 init_execution_state(char *src, Oid *argOidVect, int nargs,
-					 Oid rettype, bool haspolyarg)
+					 Oid rettype)
 {
 	execution_state *firstes;
 	execution_state *preves;
@@ -103,11 +103,13 @@
 	queryTree_list = pg_parse_and_rewrite(src, argOidVect, nargs);
 
 	/*
-	 * If the function has any arguments declared as polymorphic types,
-	 * then it wasn't type-checked at definition time; must do so now.
+	 * Check that the function returns the type it claims to.  Although
+	 * in simple cases this was already done when the function was defined,
+	 * we have to recheck because database objects used in the function's
+	 * queries might have changed type.  We'd have to do it anyway if the
+	 * function had any polymorphic arguments.
 	 */
-	if (haspolyarg)
-		check_sql_fn_retval(rettype, get_typtype(rettype), queryTree_list);
+	check_sql_fn_retval(rettype, get_typtype(rettype), queryTree_list);
 
 	firstes = NULL;
 	preves = NULL;
@@ -150,7 +152,6 @@
 	Form_pg_type typeStruct;
 	SQLFunctionCachePtr fcache;
 	Oid		   *argOidVect;
-	bool		haspolyarg;
 	char	   *src;
 	int			nargs;
 	Datum		tmp;
@@ -226,12 +227,9 @@
 		fcache->funcSlot = NULL;
 
 	/*
-	 * Parse and plan the queries.	We need the argument type info to pass
-	 * to the parser.
+	 * We need the argument type info to pass to the parser.
 	 */
 	nargs = procedureStruct->pronargs;
-	haspolyarg = false;
-
 	if (nargs > 0)
 	{
 		int			argnum;
@@ -254,13 +252,15 @@
 							 errmsg("could not determine actual type of argument declared %s",
 									format_type_be(argOidVect[argnum]))));
 				argOidVect[argnum] = argtype;
-				haspolyarg = true;
 			}
 		}
 	}
 	else
 		argOidVect = (Oid *) NULL;
 
+	/*
+	 * Parse and rewrite the queries in the function text.
+	 */
 	tmp = SysCacheGetAttr(PROCOID,
 						  procedureTuple,
 						  Anum_pg_proc_prosrc,
@@ -269,8 +269,7 @@
 		elog(ERROR, "null prosrc for function %u", foid);
 	src = DatumGetCString(DirectFunctionCall1(textout, tmp));
 
-	fcache->func_state = init_execution_state(src, argOidVect, nargs,
-											  rettype, haspolyarg);
+	fcache->func_state = init_execution_state(src, argOidVect, nargs, rettype);
 
 	pfree(src);
 
diff -ruN postgresql-7.4.7-old/src/backend/optimizer/util/clauses.c postgresql-7.4.7/src/backend/optimizer/util/clauses.c
--- postgresql-7.4.7-old/src/backend/optimizer/util/clauses.c	2004-01-28 01:05:25.000000000 +0100
+++ postgresql-7.4.7/src/backend/optimizer/util/clauses.c	2007-02-04 21:50:39.000000000 +0100
@@ -1747,7 +1747,6 @@
 {
 	Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
 	char		result_typtype;
-	bool		polymorphic = false;
 	Oid			argtypes[FUNC_MAX_ARGS];
 	char	   *src;
 	Datum		tmp;
@@ -1781,10 +1780,8 @@
 	if (result_typtype != 'b' &&
 		result_typtype != 'd')
 	{
-		if (funcform->prorettype == ANYARRAYOID ||
-			funcform->prorettype == ANYELEMENTOID)
-			polymorphic = true;
-		else
+		if (funcform->prorettype != ANYARRAYOID &&
+			funcform->prorettype != ANYELEMENTOID)
 			return NULL;
 	}
 
@@ -1803,7 +1800,6 @@
 		if (argtypes[i] == ANYARRAYOID ||
 			argtypes[i] == ANYELEMENTOID)
 		{
-			polymorphic = true;
 			argtypes[i] = exprType((Node *) nth(i, args));
 		}
 	}
@@ -1880,16 +1876,14 @@
 	newexpr = (Node *) ((TargetEntry *) lfirst(querytree->targetList))->expr;
 
 	/*
-	 * If the function has any arguments declared as polymorphic types,
-	 * then it wasn't type-checked at definition time; must do so now.
-	 * (This will raise an error if wrong, but that's okay since the
-	 * function would fail at runtime anyway.  Note we do not try this
-	 * until we have verified that no rewriting was needed; that's
-	 * probably not important, but let's be careful.)
+	 * Make sure the function (still) returns what it's declared to.  This will
+	 * raise an error if wrong, but that's okay since the function would fail
+	 * at runtime anyway.  Note we do not try this until we have verified that
+	 * no rewriting was needed; that's probably not important, but let's be
+	 * careful.
 	 */
-	if (polymorphic)
-		check_sql_fn_retval(result_type, get_typtype(result_type),
-							querytree_list);
+	check_sql_fn_retval(result_type, get_typtype(result_type),
+						querytree_list);
 
 	/*
 	 * Additional validity checks on the expression.  It mustn't return a