8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.110 2001/08/09 18:28:18 petere Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.111 2001/10/04 22:06:46 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -427,12 +427,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
427
427
}
428
428
429
429
/*
430
- * func_get_detail looks up the function in the catalogs, does
431
- * disambiguation for polymorphic functions, handles inheritance, and
432
- * returns the funcid and type and set or singleton status of the
433
- * function's return value. it also returns the true argument types
434
- * to the function. if func_get_detail returns true, the function
435
- * exists. otherwise, there was an error.
430
+ * Is it a set, or a function?
436
431
*/
437
432
if (attisset )
438
433
{ /* we know all of these fields already */
@@ -454,61 +449,29 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
454
449
}
455
450
else
456
451
{
457
- bool exists ;
452
+ FuncDetailCode fdresult ;
458
453
459
- exists = func_get_detail (funcname , nargs , oid_array , & funcid ,
460
- & rettype , & retset , & true_oid_array );
461
- if (!exists )
454
+ /*
455
+ * func_get_detail looks up the function in the catalogs, does
456
+ * disambiguation for polymorphic functions, handles inheritance, and
457
+ * returns the funcid and type and set or singleton status of the
458
+ * function's return value. it also returns the true argument types
459
+ * to the function.
460
+ */
461
+ fdresult = func_get_detail (funcname , fargs , nargs , oid_array ,
462
+ & funcid , & rettype , & retset ,
463
+ & true_oid_array );
464
+ if (fdresult == FUNCDETAIL_COERCION )
462
465
{
463
-
464
466
/*
465
- * If we can't find a function (or can't find a unique
466
- * function), see if this is really a type-coercion request:
467
- * single-argument function call where the function name is a
468
- * type name. If so, and if we can do the coercion trivially,
469
- * just go ahead and do it without requiring there to be a
470
- * real function for it.
471
- *
472
- * "Trivial" coercions are ones that involve binary-compatible
473
- * types and ones that are coercing a previously-unknown-type
474
- * literal constant to a specific type.
475
- *
476
- * DO NOT try to generalize this code to nontrivial coercions,
477
- * because you'll just set up an infinite recursion between
478
- * this routine and coerce_type! We have already failed to
479
- * find a suitable "real" coercion function, so we have to
480
- * fail unless this is a coercion that coerce_type can handle
481
- * by itself. Make sure this code stays in sync with what
482
- * coerce_type does!
467
+ * We can do it as a trivial coercion.
468
+ * coerce_type can handle these cases, so why duplicate code...
483
469
*/
484
- if (nargs == 1 )
485
- {
486
- Oid targetType ;
487
-
488
- targetType = GetSysCacheOid (TYPENAME ,
489
- PointerGetDatum (funcname ),
490
- 0 , 0 , 0 );
491
- if (OidIsValid (targetType ))
492
- {
493
- Oid sourceType = oid_array [0 ];
494
- Node * arg1 = lfirst (fargs );
495
-
496
- if ((sourceType == UNKNOWNOID && IsA (arg1 , Const )) ||
497
- sourceType == targetType ||
498
- IS_BINARY_COMPATIBLE (sourceType , targetType ))
499
- {
500
-
501
- /*
502
- * Ah-hah, we can do it as a trivial coercion.
503
- * coerce_type can handle these cases, so why
504
- * duplicate code...
505
- */
506
- return coerce_type (pstate , arg1 ,
507
- sourceType , targetType , -1 );
508
- }
509
- }
510
- }
511
-
470
+ return coerce_type (pstate , lfirst (fargs ),
471
+ oid_array [0 ], rettype , -1 );
472
+ }
473
+ if (fdresult != FUNCDETAIL_NORMAL )
474
+ {
512
475
/*
513
476
* Oops. Time to die.
514
477
*
@@ -1130,26 +1093,29 @@ func_select_candidate(int nargs,
1130
1093
1131
1094
1132
1095
/* func_get_detail()
1096
+ *
1133
1097
* Find the named function in the system catalogs.
1134
1098
*
1135
1099
* Attempt to find the named function in the system catalogs with
1136
1100
* arguments exactly as specified, so that the normal case
1137
1101
* (exact match) is as quick as possible.
1138
1102
*
1139
1103
* If an exact match isn't found:
1140
- * 1) get a vector of all possible input arg type arrays constructed
1104
+ * 1) check for possible interpretation as a trivial type coercion
1105
+ * 2) get a vector of all possible input arg type arrays constructed
1141
1106
* from the superclasses of the original input arg types
1142
- * 2 ) get a list of all possible argument type arrays to the function
1107
+ * 3 ) get a list of all possible argument type arrays to the function
1143
1108
* with given name and number of arguments
1144
- * 3 ) for each input arg type array from vector #1:
1109
+ * 4 ) for each input arg type array from vector #1:
1145
1110
* a) find how many of the function arg type arrays from list #2
1146
1111
* it can be coerced to
1147
1112
* b) if the answer is one, we have our function
1148
1113
* c) if the answer is more than one, attempt to resolve the conflict
1149
1114
* d) if the answer is zero, try the next array from vector #1
1150
1115
*/
1151
- bool
1116
+ FuncDetailCode
1152
1117
func_get_detail (char * funcname ,
1118
+ List * fargs ,
1153
1119
int nargs ,
1154
1120
Oid * argtypes ,
1155
1121
Oid * funcid , /* return value */
@@ -1158,6 +1124,7 @@ func_get_detail(char *funcname,
1158
1124
Oid * * true_typeids ) /* return value */
1159
1125
{
1160
1126
HeapTuple ftup ;
1127
+ CandidateList function_typeids ;
1161
1128
1162
1129
/* attempt to find with arguments exactly as specified... */
1163
1130
ftup = SearchSysCache (PROCNAME ,
@@ -1173,12 +1140,59 @@ func_get_detail(char *funcname,
1173
1140
}
1174
1141
else
1175
1142
{
1143
+ /*
1144
+ * If we didn't find an exact match, next consider the possibility
1145
+ * that this is really a type-coercion request: a single-argument
1146
+ * function call where the function name is a type name. If so,
1147
+ * and if we can do the coercion trivially (no run-time function
1148
+ * call needed), then go ahead and treat the "function call" as
1149
+ * a coercion. This interpretation needs to be given higher
1150
+ * priority than interpretations involving a type coercion followed
1151
+ * by a function call, otherwise we can produce surprising results.
1152
+ * For example, we want "text(varchar)" to be interpreted as a
1153
+ * trivial coercion, not as "text(name(varchar))" which the code
1154
+ * below this point is entirely capable of selecting.
1155
+ *
1156
+ * "Trivial" coercions are ones that involve binary-compatible
1157
+ * types and ones that are coercing a previously-unknown-type
1158
+ * literal constant to a specific type.
1159
+ *
1160
+ * NB: it's important that this code stays in sync with what
1161
+ * coerce_type can do, because the caller will try to apply
1162
+ * coerce_type if we return FUNCDETAIL_COERCION. If we return
1163
+ * that result for something coerce_type can't handle, we'll
1164
+ * cause infinite recursion between this module and coerce_type!
1165
+ */
1166
+ if (nargs == 1 )
1167
+ {
1168
+ Oid targetType ;
1169
+
1170
+ targetType = GetSysCacheOid (TYPENAME ,
1171
+ PointerGetDatum (funcname ),
1172
+ 0 , 0 , 0 );
1173
+ if (OidIsValid (targetType ))
1174
+ {
1175
+ Oid sourceType = argtypes [0 ];
1176
+ Node * arg1 = lfirst (fargs );
1177
+
1178
+ if ((sourceType == UNKNOWNOID && IsA (arg1 , Const )) ||
1179
+ sourceType == targetType ||
1180
+ IS_BINARY_COMPATIBLE (sourceType , targetType ))
1181
+ {
1182
+ /* Yup, it's a type coercion */
1183
+ * funcid = InvalidOid ;
1184
+ * rettype = targetType ;
1185
+ * retset = false;
1186
+ * true_typeids = argtypes ;
1187
+ return FUNCDETAIL_COERCION ;
1188
+ }
1189
+ }
1190
+ }
1176
1191
1177
1192
/*
1178
1193
* didn't find an exact match, so now try to match up
1179
1194
* candidates...
1180
1195
*/
1181
- CandidateList function_typeids ;
1182
1196
1183
1197
function_typeids = func_get_candidates (funcname , nargs );
1184
1198
@@ -1268,9 +1282,10 @@ func_get_detail(char *funcname,
1268
1282
* rettype = pform -> prorettype ;
1269
1283
* retset = pform -> proretset ;
1270
1284
ReleaseSysCache (ftup );
1271
- return true ;
1285
+ return FUNCDETAIL_NORMAL ;
1272
1286
}
1273
- return false;
1287
+
1288
+ return FUNCDETAIL_NOTFOUND ;
1274
1289
} /* func_get_detail() */
1275
1290
1276
1291
/*
0 commit comments