2136{
2137 bool have_poly_anycompatible = false;
2138 bool have_poly_unknowns = false;
2149 bool have_anynonarray = (rettype == ANYNONARRAYOID);
2150 bool have_anyenum = (rettype == ANYENUMOID);
2151 bool have_anymultirange = (rettype == ANYMULTIRANGEOID);
2152 bool have_anycompatible_nonarray = (rettype == ANYCOMPATIBLENONARRAYOID);
2153 bool have_anycompatible_array = (rettype == ANYCOMPATIBLEARRAYOID);
2154 bool have_anycompatible_range = (rettype == ANYCOMPATIBLERANGEOID);
2155 bool have_anycompatible_multirange = (rettype == ANYCOMPATIBLEMULTIRANGEOID);
2156 int n_poly_args = 0; /* this counts all family-1 arguments */
2157 int n_anycompatible_args = 0; /* this counts only non-unknowns */
2159
2160 /*
2161 * Loop through the arguments to see if we have any that are polymorphic.
2162 * If so, require the actual types to be consistent.
2163 */
2165 for (
int j = 0;
j < nargs;
j++)
2166 {
2167 Oid decl_type = declared_arg_types[
j];
2168 Oid actual_type = actual_arg_types[
j];
2169
2170 if (decl_type == ANYELEMENTOID ||
2171 decl_type == ANYNONARRAYOID ||
2172 decl_type == ANYENUMOID)
2173 {
2174 n_poly_args++;
2175 if (decl_type == ANYNONARRAYOID)
2176 have_anynonarray = true;
2177 else if (decl_type == ANYENUMOID)
2178 have_anyenum = true;
2179 if (actual_type == UNKNOWNOID)
2180 {
2181 have_poly_unknowns = true;
2182 continue;
2183 }
2184 if (allow_poly && decl_type == actual_type)
2185 continue; /* no new information here */
2186 if (
OidIsValid(elem_typeid) && actual_type != elem_typeid)
2188 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2189 errmsg(
"arguments declared \"%s\" are not all alike",
"anyelement"),
2193 elem_typeid = actual_type;
2194 }
2195 else if (decl_type == ANYARRAYOID)
2196 {
2197 n_poly_args++;
2198 if (actual_type == UNKNOWNOID)
2199 {
2200 have_poly_unknowns = true;
2201 continue;
2202 }
2203 if (allow_poly && decl_type == actual_type)
2204 continue; /* no new information here */
2205 actual_type =
getBaseType(actual_type);
/* flatten domains */
2206 if (
OidIsValid(array_typeid) && actual_type != array_typeid)
2208 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2209 errmsg(
"arguments declared \"%s\" are not all alike",
"anyarray"),
2213 array_typeid = actual_type;
2214 }
2215 else if (decl_type == ANYRANGEOID)
2216 {
2217 n_poly_args++;
2218 if (actual_type == UNKNOWNOID)
2219 {
2220 have_poly_unknowns = true;
2221 continue;
2222 }
2223 if (allow_poly && decl_type == actual_type)
2224 continue; /* no new information here */
2225 actual_type =
getBaseType(actual_type);
/* flatten domains */
2226 if (
OidIsValid(range_typeid) && actual_type != range_typeid)
2228 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2229 errmsg(
"arguments declared \"%s\" are not all alike",
"anyrange"),
2233 range_typeid = actual_type;
2234 }
2235 else if (decl_type == ANYMULTIRANGEOID)
2236 {
2237 n_poly_args++;
2238 have_anymultirange = true;
2239 if (actual_type == UNKNOWNOID)
2240 {
2241 have_poly_unknowns = true;
2242 continue;
2243 }
2244 if (allow_poly && decl_type == actual_type)
2245 continue; /* no new information here */
2246 actual_type =
getBaseType(actual_type);
/* flatten domains */
2247 if (
OidIsValid(multirange_typeid) && actual_type != multirange_typeid)
2249 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2250 errmsg(
"arguments declared \"%s\" are not all alike",
"anymultirange"),
2254 multirange_typeid = actual_type;
2255 }
2256 else if (decl_type == ANYCOMPATIBLEOID ||
2257 decl_type == ANYCOMPATIBLENONARRAYOID)
2258 {
2259 have_poly_anycompatible = true;
2260 if (decl_type == ANYCOMPATIBLENONARRAYOID)
2261 have_anycompatible_nonarray = true;
2262 if (actual_type == UNKNOWNOID)
2263 continue;
2264 if (allow_poly && decl_type == actual_type)
2265 continue; /* no new information here */
2266 /* collect the actual types of non-unknown COMPATIBLE args */
2267 anycompatible_actual_types[n_anycompatible_args++] = actual_type;
2268 }
2269 else if (decl_type == ANYCOMPATIBLEARRAYOID)
2270 {
2271 Oid anycompatible_elem_type;
2272
2273 have_poly_anycompatible = true;
2274 have_anycompatible_array = true;
2275 if (actual_type == UNKNOWNOID)
2276 continue;
2277 if (allow_poly && decl_type == actual_type)
2278 continue; /* no new information here */
2279 actual_type =
getBaseType(actual_type);
/* flatten domains */
2283 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2284 errmsg(
"argument declared %s is not an array but type %s",
2285 "anycompatiblearray",
2287 /* collect the element type for common-supertype choice */
2288 anycompatible_actual_types[n_anycompatible_args++] = anycompatible_elem_type;
2289 }
2290 else if (decl_type == ANYCOMPATIBLERANGEOID)
2291 {
2292 have_poly_anycompatible = true;
2293 have_anycompatible_range = true;
2294 if (actual_type == UNKNOWNOID)
2295 continue;
2296 if (allow_poly && decl_type == actual_type)
2297 continue; /* no new information here */
2298 actual_type =
getBaseType(actual_type);
/* flatten domains */
2300 {
2301 /* All ANYCOMPATIBLERANGE arguments must be the same type */
2302 if (anycompatible_range_typeid != actual_type)
2304 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2305 errmsg(
"arguments declared \"%s\" are not all alike",
"anycompatiblerange"),
2309 }
2310 else
2311 {
2312 anycompatible_range_typeid = actual_type;
2314 if (!
OidIsValid(anycompatible_range_typelem))
2316 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2317 errmsg(
"argument declared %s is not a range type but type %s",
2318 "anycompatiblerange",
2320 /* collect the subtype for common-supertype choice */
2321 anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem;
2322 }
2323 }
2324 else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID)
2325 {
2326 have_poly_anycompatible = true;
2327 have_anycompatible_multirange = true;
2328 if (actual_type == UNKNOWNOID)
2329 continue;
2330 if (allow_poly && decl_type == actual_type)
2331 continue; /* no new information here */
2332 actual_type =
getBaseType(actual_type);
/* flatten domains */
2333 if (
OidIsValid(anycompatible_multirange_typeid))
2334 {
2335 /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */
2336 if (anycompatible_multirange_typeid != actual_type)
2338 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2339 errmsg(
"arguments declared \"%s\" are not all alike",
"anycompatiblemultirange"),
2343 }
2344 else
2345 {
2346 anycompatible_multirange_typeid = actual_type;
2348 if (!
OidIsValid(anycompatible_multirange_typelem))
2350 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2351 errmsg(
"argument declared %s is not a multirange type but type %s",
2352 "anycompatiblemultirange",
2354 /* we'll consider the subtype below */
2355 }
2356 }
2357 }
2358
2359 /*
2360 * Fast Track: if none of the arguments are polymorphic, return the
2361 * unmodified rettype. Not our job to resolve it if it's polymorphic.
2362 */
2363 if (n_poly_args == 0 && !have_poly_anycompatible)
2364 return rettype;
2365
2366 /* Check matching of family-1 polymorphic arguments, if any */
2367 if (n_poly_args)
2368 {
2369 /* Get the element type based on the array type, if we have one */
2371 {
2373
2374 if (array_typeid == ANYARRAYOID)
2375 {
2376 /*
2377 * Special case for matching ANYARRAY input to an ANYARRAY
2378 * argument: allow it iff no other arguments are family-1
2379 * polymorphics (otherwise we couldn't be sure whether the
2380 * array element type matches up) and the result type doesn't
2381 * require us to infer a specific element type.
2382 */
2383 if (n_poly_args != 1 ||
2384 (rettype != ANYARRAYOID &&
2385 IsPolymorphicTypeFamily1(rettype)))
2387 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2388 errmsg(
"cannot determine element type of \"anyarray\" argument")));
2389 array_typelem = ANYELEMENTOID;
2390 }
2391 else
2392 {
2396 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2397 errmsg(
"argument declared %s is not an array but type %s",
2399 }
2400
2402 {
2403 /*
2404 * if we don't have an element type yet, use the one we just
2405 * got
2406 */
2407 elem_typeid = array_typelem;
2408 }
2409 else if (array_typelem != elem_typeid)
2410 {
2411 /* otherwise, they better match */
2413 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2414 errmsg(
"argument declared %s is not consistent with argument declared %s",
2415 "anyarray", "anyelement"),
2419 }
2420 }
2421
2422 /* Deduce range type from multirange type, or vice versa */
2424 {
2425 Oid multirange_typelem;
2426
2430 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2431 errmsg(
"argument declared %s is not a multirange type but type %s",
2432 "anymultirange",
2434
2436 {
2437 /* if we don't have a range type yet, use the one we just got */
2438 range_typeid = multirange_typelem;
2439 }
2440 else if (multirange_typelem != range_typeid)
2441 {
2442 /* otherwise, they better match */
2444 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2445 errmsg(
"argument declared %s is not consistent with argument declared %s",
2446 "anymultirange", "anyrange"),
2450 }
2451 }
2452 else if (have_anymultirange &&
OidIsValid(range_typeid))
2453 {
2455 /* We'll complain below if that didn't work */
2456 }
2457
2458 /* Get the element type based on the range type, if we have one */
2460 {
2462
2466 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2467 errmsg(
"argument declared %s is not a range type but type %s",
2468 "anyrange",
2470
2472 {
2473 /*
2474 * if we don't have an element type yet, use the one we just
2475 * got
2476 */
2477 elem_typeid = range_typelem;
2478 }
2479 else if (range_typelem != elem_typeid)
2480 {
2481 /* otherwise, they better match */
2483 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2484 errmsg(
"argument declared %s is not consistent with argument declared %s",
2485 "anyrange", "anyelement"),
2489 }
2490 }
2491
2493 {
2494 if (allow_poly)
2495 {
2496 elem_typeid = ANYELEMENTOID;
2497 array_typeid = ANYARRAYOID;
2498 range_typeid = ANYRANGEOID;
2499 multirange_typeid = ANYMULTIRANGEOID;
2500 }
2501 else
2502 {
2503 /*
2504 * Only way to get here is if all the family-1 polymorphic
2505 * arguments have UNKNOWN inputs.
2506 */
2508 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2509 errmsg(
"could not determine polymorphic type because input has type %s",
2510 "unknown")));
2511 }
2512 }
2513
2514 if (have_anynonarray && elem_typeid != ANYELEMENTOID)
2515 {
2516 /*
2517 * require the element type to not be an array or domain over
2518 * array
2519 */
2522 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2523 errmsg(
"type matched to anynonarray is an array type: %s",
2525 }
2526
2527 if (have_anyenum && elem_typeid != ANYELEMENTOID)
2528 {
2529 /* require the element type to be an enum */
2532 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2533 errmsg(
"type matched to anyenum is not an enum type: %s",
2535 }
2536 }
2537
2538 /* Check matching of family-2 polymorphic arguments, if any */
2539 if (have_poly_anycompatible)
2540 {
2541 /* Deduce range type from multirange type, or vice versa */
2542 if (
OidIsValid(anycompatible_multirange_typeid))
2543 {
2545 {
2546 if (anycompatible_multirange_typelem !=
2547 anycompatible_range_typeid)
2549 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2550 errmsg(
"argument declared %s is not consistent with argument declared %s",
2551 "anycompatiblemultirange",
2552 "anycompatiblerange"),
2556 }
2557 else
2558 {
2559 anycompatible_range_typeid = anycompatible_multirange_typelem;
2561 if (!
OidIsValid(anycompatible_range_typelem))
2563 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2564 errmsg(
"argument declared %s is not a multirange type but type %s",
2565 "anycompatiblemultirange",
2567 /* this enables element type matching check below */
2568 have_anycompatible_range = true;
2569 /* collect the subtype for common-supertype choice */
2570 anycompatible_actual_types[n_anycompatible_args++] =
2571 anycompatible_range_typelem;
2572 }
2573 }
2574 else if (have_anycompatible_multirange &&
2576 {
2578 /* We'll complain below if that didn't work */
2579 }
2580
2581 if (n_anycompatible_args > 0)
2582 {
2583 anycompatible_typeid =
2585 anycompatible_actual_types,
2586 false);
2587
2588 /* We have to verify that the selected type actually works */
2590 n_anycompatible_args,
2591 anycompatible_actual_types))
2593 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2594 errmsg(
"arguments of anycompatible family cannot be cast to a common type")));
2595
2596 if (have_anycompatible_array)
2597 {
2598 anycompatible_array_typeid =
get_array_type(anycompatible_typeid);
2601 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2602 errmsg(
"could not find array type for data type %s",
2604 }
2605
2606 if (have_anycompatible_range)
2607 {
2608 /* we can't infer a range type from the others */
2611 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2612 errmsg(
"could not determine polymorphic type %s because input has type %s",
2613 "anycompatiblerange", "unknown")));
2614
2615 /*
2616 * the anycompatible type must exactly match the range element
2617 * type
2618 */
2619 if (anycompatible_range_typelem != anycompatible_typeid)
2621 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2622 errmsg(
"anycompatiblerange type %s does not match anycompatible type %s",
2625 }
2626
2627 if (have_anycompatible_multirange)
2628 {
2629 /* we can't infer a multirange type from the others */
2630 if (!
OidIsValid(anycompatible_multirange_typeid))
2632 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2633 errmsg(
"could not determine polymorphic type %s because input has type %s",
2634 "anycompatiblemultirange", "unknown")));
2635
2636 /*
2637 * the anycompatible type must exactly match the multirange
2638 * element type
2639 */
2640 if (anycompatible_range_typelem != anycompatible_typeid)
2642 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2643 errmsg(
"anycompatiblemultirange type %s does not match anycompatible type %s",
2646 }
2647
2648 if (have_anycompatible_nonarray)
2649 {
2650 /*
2651 * require the element type to not be an array or domain over
2652 * array
2653 */
2656 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2657 errmsg(
"type matched to anycompatiblenonarray is an array type: %s",
2659 }
2660 }
2661 else
2662 {
2663 if (allow_poly)
2664 {
2665 anycompatible_typeid = ANYCOMPATIBLEOID;
2666 anycompatible_array_typeid = ANYCOMPATIBLEARRAYOID;
2667 anycompatible_range_typeid = ANYCOMPATIBLERANGEOID;
2668 anycompatible_multirange_typeid = ANYCOMPATIBLEMULTIRANGEOID;
2669 }
2670 else
2671 {
2672 /*
2673 * Only way to get here is if all the family-2 polymorphic
2674 * arguments have UNKNOWN inputs. Resolve to TEXT as
2675 * select_common_type() would do. That doesn't license us to
2676 * use TEXTRANGE or TEXTMULTIRANGE, though.
2677 */
2678 anycompatible_typeid = TEXTOID;
2679 anycompatible_array_typeid = TEXTARRAYOID;
2680 if (have_anycompatible_range)
2682 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2683 errmsg(
"could not determine polymorphic type %s because input has type %s",
2684 "anycompatiblerange", "unknown")));
2685 if (have_anycompatible_multirange)
2687 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2688 errmsg(
"could not determine polymorphic type %s because input has type %s",
2689 "anycompatiblemultirange", "unknown")));
2690 }
2691 }
2692
2693 /* replace family-2 polymorphic types by selected types */
2694 for (
int j = 0;
j < nargs;
j++)
2695 {
2696 Oid decl_type = declared_arg_types[
j];
2697
2698 if (decl_type == ANYCOMPATIBLEOID ||
2699 decl_type == ANYCOMPATIBLENONARRAYOID)
2700 declared_arg_types[
j] = anycompatible_typeid;
2701 else if (decl_type == ANYCOMPATIBLEARRAYOID)
2702 declared_arg_types[
j] = anycompatible_array_typeid;
2703 else if (decl_type == ANYCOMPATIBLERANGEOID)
2704 declared_arg_types[
j] = anycompatible_range_typeid;
2705 else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID)
2706 declared_arg_types[
j] = anycompatible_multirange_typeid;
2707 }
2708 }
2709
2710 /*
2711 * If we had any UNKNOWN inputs for family-1 polymorphic arguments,
2712 * re-scan to assign correct types to them.
2713 *
2714 * Note: we don't have to consider unknown inputs that were matched to
2715 * family-2 polymorphic arguments, because we forcibly updated their
2716 * declared_arg_types[] positions just above.
2717 */
2718 if (have_poly_unknowns)
2719 {
2720 for (
int j = 0;
j < nargs;
j++)
2721 {
2722 Oid decl_type = declared_arg_types[
j];
2723 Oid actual_type = actual_arg_types[
j];
2724
2725 if (actual_type != UNKNOWNOID)
2726 continue;
2727
2728 if (decl_type == ANYELEMENTOID ||
2729 decl_type == ANYNONARRAYOID ||
2730 decl_type == ANYENUMOID)
2731 declared_arg_types[
j] = elem_typeid;
2732 else if (decl_type == ANYARRAYOID)
2733 {
2735 {
2739 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2740 errmsg(
"could not find array type for data type %s",
2742 }
2743 declared_arg_types[
j] = array_typeid;
2744 }
2745 else if (decl_type == ANYRANGEOID)
2746 {
2748 {
2749 /* we can't infer a range type from the others */
2751 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2752 errmsg(
"could not determine polymorphic type %s because input has type %s",
2753 "anyrange", "unknown")));
2754 }
2755 declared_arg_types[
j] = range_typeid;
2756 }
2757 else if (decl_type == ANYMULTIRANGEOID)
2758 {
2760 {
2761 /* we can't infer a multirange type from the others */
2763 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2764 errmsg(
"could not determine polymorphic type %s because input has type %s",
2765 "anymultirange", "unknown")));
2766 }
2767 declared_arg_types[
j] = multirange_typeid;
2768 }
2769 }
2770 }
2771
2772 /* if we return ANYELEMENT use the appropriate argument type */
2773 if (rettype == ANYELEMENTOID ||
2774 rettype == ANYNONARRAYOID ||
2775 rettype == ANYENUMOID)
2776 return elem_typeid;
2777
2778 /* if we return ANYARRAY use the appropriate argument type */
2779 if (rettype == ANYARRAYOID)
2780 {
2782 {
2786 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2787 errmsg(
"could not find array type for data type %s",
2789 }
2790 return array_typeid;
2791 }
2792
2793 /* if we return ANYRANGE use the appropriate argument type */
2794 if (rettype == ANYRANGEOID)
2795 {
2796 /* this error is unreachable if the function signature is valid: */
2799 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2800 errmsg_internal(
"could not determine polymorphic type %s because input has type %s",
2801 "anyrange", "unknown")));
2802 return range_typeid;
2803 }
2804
2805 /* if we return ANYMULTIRANGE use the appropriate argument type */
2806 if (rettype == ANYMULTIRANGEOID)
2807 {
2808 /* this error is unreachable if the function signature is valid: */
2811 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2812 errmsg_internal(
"could not determine polymorphic type %s because input has type %s",
2813 "anymultirange", "unknown")));
2814 return multirange_typeid;
2815 }
2816
2817 /* if we return ANYCOMPATIBLE use the appropriate type */
2818 if (rettype == ANYCOMPATIBLEOID ||
2819 rettype == ANYCOMPATIBLENONARRAYOID)
2820 {
2821 /* this error is unreachable if the function signature is valid: */
2824 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2826 return anycompatible_typeid;
2827 }
2828
2829 /* if we return ANYCOMPATIBLEARRAY use the appropriate type */
2830 if (rettype == ANYCOMPATIBLEARRAYOID)
2831 {
2832 /* this error is unreachable if the function signature is valid: */
2835 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2837 return anycompatible_array_typeid;
2838 }
2839
2840 /* if we return ANYCOMPATIBLERANGE use the appropriate argument type */
2841 if (rettype == ANYCOMPATIBLERANGEOID)
2842 {
2843 /* this error is unreachable if the function signature is valid: */
2846 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2848 return anycompatible_range_typeid;
2849 }
2850
2851 /* if we return ANYCOMPATIBLEMULTIRANGE use the appropriate argument type */
2852 if (rettype == ANYCOMPATIBLEMULTIRANGEOID)
2853 {
2854 /* this error is unreachable if the function signature is valid: */
2855 if (!
OidIsValid(anycompatible_multirange_typeid))
2857 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2859 return anycompatible_multirange_typeid;
2860 }
2861
2862 /* we don't return a generic type; send back the original return type */
2863 return rettype;
2864}
int errmsg_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
Oid get_range_multirange(Oid rangeOid)
Oid get_array_type(Oid typid)