@@ -91,7 +91,7 @@ ProcedureCreate(const char *procedureName,
91
91
int parameterCount ;
92
92
int allParamCount ;
93
93
Oid * allParams ;
94
- char * modes = NULL ;
94
+ char * paramModes = NULL ;
95
95
bool genericInParam = false;
96
96
bool genericOutParam = false;
97
97
bool anyrangeInParam = false;
@@ -130,6 +130,7 @@ ProcedureCreate(const char *procedureName,
130
130
FUNC_MAX_ARGS )));
131
131
/* note: the above is correct, we do NOT count output arguments */
132
132
133
+ /* Deconstruct array inputs */
133
134
if (allParameterTypes != PointerGetDatum (NULL ))
134
135
{
135
136
/*
@@ -169,28 +170,27 @@ ProcedureCreate(const char *procedureName,
169
170
ARR_HASNULL (modesArray ) ||
170
171
ARR_ELEMTYPE (modesArray ) != CHAROID )
171
172
elog (ERROR , "parameterModes is not a 1-D char array" );
172
- modes = (char * ) ARR_DATA_PTR (modesArray );
173
+ paramModes = (char * ) ARR_DATA_PTR (modesArray );
173
174
}
174
175
175
-
176
176
/*
177
- * Do not allow polymorphic return type unless at least one input argument
178
- * is polymorphic. Also, do not allow return type INTERNAL unless at
179
- * least one input argument is INTERNAL.
177
+ * Detect whether we have polymorphic or INTERNAL arguments. The first
178
+ * loop checks input arguments, the second output arguments.
180
179
*/
181
180
for (i = 0 ; i < parameterCount ; i ++ )
182
181
{
183
182
switch (parameterTypes -> values [i ])
184
183
{
185
- case ANYRANGEOID :
186
- anyrangeInParam = true;
187
- /* FALL THROUGH */
188
184
case ANYARRAYOID :
189
185
case ANYELEMENTOID :
190
186
case ANYNONARRAYOID :
191
187
case ANYENUMOID :
192
188
genericInParam = true;
193
189
break ;
190
+ case ANYRANGEOID :
191
+ genericInParam = true;
192
+ anyrangeInParam = true;
193
+ break ;
194
194
case INTERNALOID :
195
195
internalInParam = true;
196
196
break ;
@@ -201,30 +201,37 @@ ProcedureCreate(const char *procedureName,
201
201
{
202
202
for (i = 0 ; i < allParamCount ; i ++ )
203
203
{
204
- if (modes == NULL ||
205
- (modes [i ] != PROARGMODE_OUT &&
206
- modes [i ] != PROARGMODE_INOUT &&
207
- modes [i ] != PROARGMODE_TABLE ))
208
- continue ;
204
+ if (paramModes == NULL ||
205
+ paramModes [i ] == PROARGMODE_IN ||
206
+ paramModes [i ] == PROARGMODE_VARIADIC )
207
+ continue ; /* ignore input-only params */
209
208
210
209
switch (allParams [i ])
211
210
{
212
- case ANYRANGEOID :
213
- anyrangeOutParam = true;
214
- /* FALL THROUGH */
215
211
case ANYARRAYOID :
216
212
case ANYELEMENTOID :
217
213
case ANYNONARRAYOID :
218
214
case ANYENUMOID :
219
215
genericOutParam = true;
220
216
break ;
217
+ case ANYRANGEOID :
218
+ genericOutParam = true;
219
+ anyrangeOutParam = true;
220
+ break ;
221
221
case INTERNALOID :
222
222
internalOutParam = true;
223
223
break ;
224
224
}
225
225
}
226
226
}
227
227
228
+ /*
229
+ * Do not allow polymorphic return type unless at least one input argument
230
+ * is polymorphic. ANYRANGE return type is even stricter: must have an
231
+ * ANYRANGE input (since we can't deduce the specific range type from
232
+ * ANYELEMENT). Also, do not allow return type INTERNAL unless at least
233
+ * one input argument is INTERNAL.
234
+ */
228
235
if ((IsPolymorphicType (returnType ) || genericOutParam )
229
236
&& !genericInParam )
230
237
ereport (ERROR ,
@@ -259,7 +266,7 @@ ProcedureCreate(const char *procedureName,
259
266
procedureName ,
260
267
format_type_be (parameterTypes -> values [0 ]))));
261
268
262
- if (modes != NULL )
269
+ if (paramModes != NULL )
263
270
{
264
271
/*
265
272
* Only the last input parameter can be variadic; if it is, save its
@@ -268,7 +275,7 @@ ProcedureCreate(const char *procedureName,
268
275
*/
269
276
for (i = 0 ; i < allParamCount ; i ++ )
270
277
{
271
- switch (modes [i ])
278
+ switch (paramModes [i ])
272
279
{
273
280
case PROARGMODE_IN :
274
281
case PROARGMODE_INOUT :
@@ -298,7 +305,7 @@ ProcedureCreate(const char *procedureName,
298
305
}
299
306
break ;
300
307
default :
301
- elog (ERROR , "invalid parameter mode '%c'" , modes [i ]);
308
+ elog (ERROR , "invalid parameter mode '%c'" , paramModes [i ]);
302
309
break ;
303
310
}
304
311
}
0 commit comments