PostgreSQL Source Code git master
Loading...
Searching...
No Matches
parse_coerce.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_class.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "parser/parse_coerce.h"
#include "parser/parse_relation.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/typcache.h"
Include dependency graph for parse_coerce.c:

Go to the source code of this file.

Functions

static Nodecoerce_type_typmod (Node *node, Oid targetTypeId, int32 targetTypMod, CoercionContext ccontext, CoercionForm cformat, int location, bool hideInputCoercion)
 
static void hide_coercion_node (Node *node)
 
static Nodebuild_coercion_expression (Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, CoercionContext ccontext, CoercionForm cformat, int location)
 
static Nodecoerce_record_to_complex (ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, CoercionForm cformat, int location)
 
static bool is_complex_array (Oid typid)
 
static bool typeIsOfTypedTable (Oid reltypeId, Oid reloftypeId)
 
Nodecoerce_to_target_type (ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
 
Nodecoerce_type (ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, CoercionContext ccontext, CoercionForm cformat, int location)
 
bool can_coerce_type (int nargs, const Oid *input_typeids, const Oid *target_typeids, CoercionContext ccontext)
 
Nodecoerce_to_domain (Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, CoercionContext ccontext, CoercionForm cformat, int location, bool hideInputCoercion)
 
Nodecoerce_to_boolean (ParseState *pstate, Node *node, const char *constructName)
 
Nodecoerce_to_specific_type_typmod (ParseState *pstate, Node *node, Oid targetTypeId, int32 targetTypmod, const char *constructName)
 
Nodecoerce_to_specific_type (ParseState *pstate, Node *node, Oid targetTypeId, const char *constructName)
 
Nodecoerce_null_to_domain (Oid typid, int32 typmod, Oid collation, int typlen, bool typbyval)
 
int parser_coercion_errposition (ParseState *pstate, int coerce_location, Node *input_expr)
 
Oid select_common_type (ParseState *pstate, List *exprs, const char *context, Node **which_expr)
 
static Oid select_common_type_from_oids (int nargs, const Oid *typeids, bool noerror)
 
Nodecoerce_to_common_type (ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
 
bool verify_common_type (Oid common_type, List *exprs)
 
static bool verify_common_type_from_oids (Oid common_type, int nargs, const Oid *typeids)
 
int32 select_common_typmod (ParseState *pstate, List *exprs, Oid common_type)
 
bool check_generic_type_consistency (const Oid *actual_arg_types, const Oid *declared_arg_types, int nargs)
 
Oid enforce_generic_type_consistency (const Oid *actual_arg_types, Oid *declared_arg_types, int nargs, Oid rettype, bool allow_poly)
 
charcheck_valid_polymorphic_signature (Oid ret_type, const Oid *declared_arg_types, int nargs)
 
charcheck_valid_internal_signature (Oid ret_type, const Oid *declared_arg_types, int nargs)
 
TYPCATEGORY TypeCategory (Oid type)
 
bool IsPreferredType (TYPCATEGORY category, Oid type)
 
bool IsBinaryCoercible (Oid srctype, Oid targettype)
 
bool IsBinaryCoercibleWithCast (Oid srctype, Oid targettype, Oid *castoid)
 
CoercionPathType find_coercion_pathway (Oid targetTypeId, Oid sourceTypeId, CoercionContext ccontext, Oid *funcid)
 
CoercionPathType find_typmod_coercion_function (Oid typeId, Oid *funcid)
 

Function Documentation

◆ build_coercion_expression()

static Node * build_coercion_expression ( Node node,
CoercionPathType  pathtype,
Oid  funcId,
Oid  targetTypeId,
int32  targetTypMod,
CoercionContext  ccontext,
CoercionForm  cformat,
int  location 
)
static

Definition at line 838 of file parse_coerce.c.

844{
845 int nargs = 0;
846
847 if (OidIsValid(funcId))
848 {
849 HeapTuple tp;
851
853 if (!HeapTupleIsValid(tp))
854 elog(ERROR, "cache lookup failed for function %u", funcId);
856
857 /*
858 * These Asserts essentially check that function is a legal coercion
859 * function. We can't make the seemingly obvious tests on prorettype
860 * and proargtypes[0], even in the COERCION_PATH_FUNC case, because of
861 * various binary-compatibility cases.
862 */
863 /* Assert(targetTypeId == procstruct->prorettype); */
864 Assert(!procstruct->proretset);
866 nargs = procstruct->pronargs;
867 Assert(nargs >= 1 && nargs <= 3);
868 /* Assert(procstruct->proargtypes.values[0] == exprType(node)); */
871
872 ReleaseSysCache(tp);
873 }
874
875 if (pathtype == COERCION_PATH_FUNC)
876 {
877 /* We build an ordinary FuncExpr with special arguments */
879 List *args;
880 Const *cons;
881
883
884 args = list_make1(node);
885
886 if (nargs >= 2)
887 {
888 /* Pass target typmod as an int4 constant */
890 -1,
892 sizeof(int32),
894 false,
895 true);
896
897 args = lappend(args, cons);
898 }
899
900 if (nargs == 3)
901 {
902 /* Pass it a boolean isExplicit parameter, too */
904 -1,
906 sizeof(bool),
908 false,
909 true);
910
911 args = lappend(args, cons);
912 }
913
916 fexpr->location = location;
917 return (Node *) fexpr;
918 }
919 else if (pathtype == COERCION_PATH_ARRAYCOERCE)
920 {
921 /* We need to build an ArrayCoerceExpr */
927 Node *elemexpr;
928
929 /*
930 * Look through any domain over the source array type. Note we don't
931 * expect that the target type is a domain; it must be a plain array.
932 * (To get to a domain target type, we'll do coerce_to_domain later.)
933 */
937
938 /*
939 * Set up a CaseTestExpr representing one element of the source array.
940 * This is an abuse of CaseTestExpr, but it's OK as long as there
941 * can't be any CaseExpr or ArrayCoerceExpr within the completed
942 * elemexpr.
943 */
945 Assert(OidIsValid(ctest->typeId));
946 ctest->typeMod = sourceBaseTypeMod;
947 ctest->collation = InvalidOid; /* Assume coercions don't care */
948
949 /* And coerce it to the target element type */
952
953 elemexpr = coerce_to_target_type(NULL,
954 (Node *) ctest,
955 ctest->typeId,
958 ccontext,
959 cformat,
960 location);
961 if (elemexpr == NULL) /* shouldn't happen */
962 elog(ERROR, "failed to coerce array element type as expected");
963
964 acoerce->arg = (Expr *) node;
965 acoerce->elemexpr = (Expr *) elemexpr;
966 acoerce->resulttype = targetTypeId;
967
968 /*
969 * Label the output as having a particular element typmod only if we
970 * ended up with a per-element expression that is labeled that way.
971 */
972 acoerce->resulttypmod = exprTypmod(elemexpr);
973 /* resultcollid will be set by parse_collate.c */
974 acoerce->coerceformat = cformat;
975 acoerce->location = location;
976
977 return (Node *) acoerce;
978 }
979 else if (pathtype == COERCION_PATH_COERCEVIAIO)
980 {
981 /* We need to build a CoerceViaIO node */
982 CoerceViaIO *iocoerce = makeNode(CoerceViaIO);
983
985
986 iocoerce->arg = (Expr *) node;
987 iocoerce->resulttype = targetTypeId;
988 /* resultcollid will be set by parse_collate.c */
989 iocoerce->coerceformat = cformat;
990 iocoerce->location = location;
991
992 return (Node *) iocoerce;
993 }
994 else
995 {
996 elog(ERROR, "unsupported pathtype %d in build_coercion_expression",
997 (int) pathtype);
998 return NULL; /* keep compiler quiet */
999 }
1000}
#define Assert(condition)
Definition c.h:943
int32_t int32
Definition c.h:620
#define OidIsValid(objectId)
Definition c.h:858
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
List * lappend(List *list, void *datum)
Definition list.c:339
Oid get_element_type(Oid typid)
Definition lsyscache.c:3067
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition lsyscache.c:2846
FuncExpr * makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat)
Definition makefuncs.c:594
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition makefuncs.c:350
Oid exprType(const Node *expr)
Definition nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:304
#define makeNode(_type_)
Definition nodes.h:161
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
@ COERCION_PATH_COERCEVIAIO
@ COERCION_PATH_ARRAYCOERCE
@ COERCION_PATH_FUNC
#define list_make1(x1)
Definition pg_list.h:244
END_CATALOG_STRUCT typedef FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:140
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#define InvalidOid
unsigned int Oid
static int fb(int x)
@ COERCION_EXPLICIT
Definition primnodes.h:750
ParseLoc location
Definition primnodes.h:1249
Definition pg_list.h:54
Definition nodes.h:135
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221

References CoerceViaIO::arg, Assert, BoolGetDatum(), coerce_to_target_type(), COERCION_EXPLICIT, COERCION_PATH_ARRAYCOERCE, COERCION_PATH_COERCEVIAIO, COERCION_PATH_FUNC, elog, ERROR, exprType(), exprTypmod(), fb(), Form_pg_proc, get_element_type(), getBaseTypeAndTypmod(), GETSTRUCT(), HeapTupleIsValid, Int32GetDatum(), InvalidOid, lappend(), list_make1, CoerceViaIO::location, makeConst(), makeFuncExpr(), makeNode, ObjectIdGetDatum(), OidIsValid, ReleaseSysCache(), CoerceViaIO::resulttype, and SearchSysCache1().

Referenced by coerce_type(), and coerce_type_typmod().

◆ can_coerce_type()

bool can_coerce_type ( int  nargs,
const Oid input_typeids,
const Oid target_typeids,
CoercionContext  ccontext 
)

Definition at line 558 of file parse_coerce.c.

560{
561 bool have_generics = false;
562 int i;
563
564 /* run through argument list... */
565 for (i = 0; i < nargs; i++)
566 {
569 CoercionPathType pathtype;
570 Oid funcId;
571
572 /* no problem if same type */
574 continue;
575
576 /* accept if target is ANY */
577 if (targetTypeId == ANYOID)
578 continue;
579
580 /* accept if target is polymorphic, for now */
582 {
583 have_generics = true; /* do more checking later */
584 continue;
585 }
586
587 /*
588 * If input is an untyped string constant, assume we can convert it to
589 * anything.
590 */
591 if (inputTypeId == UNKNOWNOID)
592 continue;
593
594 /*
595 * If pg_cast shows that we can coerce, accept. This test now covers
596 * both binary-compatible and coercion-function cases.
597 */
599 &funcId);
600 if (pathtype != COERCION_PATH_NONE)
601 continue;
602
603 /*
604 * If input is RECORD and target is a composite type, assume we can
605 * coerce (may need tighter checking here)
606 */
607 if (inputTypeId == RECORDOID &&
609 continue;
610
611 /*
612 * If input is a composite type and target is RECORD, accept
613 */
614 if (targetTypeId == RECORDOID &&
616 continue;
617
618#ifdef NOT_USED /* not implemented yet */
619
620 /*
621 * If input is record[] and target is a composite array type, assume
622 * we can coerce (may need tighter checking here)
623 */
626 continue;
627#endif
628
629 /*
630 * If input is a composite array type and target is record[], accept
631 */
634 continue;
635
636 /*
637 * If input is a class type that inherits from target, accept
638 */
641 continue;
642
643 /*
644 * Else, cannot coerce at this argument position
645 */
646 return false;
647 }
648
649 /* If we found any generic argument types, cross-check them */
650 if (have_generics)
651 {
653 nargs))
654 return false;
655 }
656
657 return true;
658}
int i
Definition isn.c:77
static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId)
bool check_generic_type_consistency(const Oid *actual_arg_types, const Oid *declared_arg_types, int nargs)
CoercionPathType find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, CoercionContext ccontext, Oid *funcid)
static bool is_complex_array(Oid typid)
CoercionPathType
@ COERCION_PATH_NONE
#define ISCOMPLEX(typeid)
Definition parse_type.h:59
bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)

References check_generic_type_consistency(), COERCION_PATH_NONE, fb(), find_coercion_pathway(), i, is_complex_array(), ISCOMPLEX, typeInheritsFrom(), and typeIsOfTypedTable().

Referenced by ATAddForeignKeyConstraint(), coerce_to_common_type(), coerce_to_target_type(), func_match_argtypes(), func_select_candidate(), jsonb_subscript_transform(), propgraph_edge_get_ref_keys(), select_common_type(), select_common_type_from_oids(), transformForPortionOfClause(), transformFrameOffset(), verify_common_type(), and verify_common_type_from_oids().

◆ check_generic_type_consistency()

bool check_generic_type_consistency ( const Oid actual_arg_types,
const Oid declared_arg_types,
int  nargs 
)

Definition at line 1737 of file parse_coerce.c.

1740{
1750 bool have_anynonarray = false;
1751 bool have_anyenum = false;
1752 bool have_anycompatible_nonarray = false;
1753 int n_anycompatible_args = 0;
1755
1756 /*
1757 * Loop through the arguments to see if we have any that are polymorphic.
1758 * If so, require the actual types to be consistent.
1759 */
1760 Assert(nargs <= FUNC_MAX_ARGS);
1761 for (int j = 0; j < nargs; j++)
1762 {
1765
1766 if (decl_type == ANYELEMENTOID ||
1769 {
1771 have_anynonarray = true;
1772 else if (decl_type == ANYENUMOID)
1773 have_anyenum = true;
1774 if (actual_type == UNKNOWNOID)
1775 continue;
1777 return false;
1779 }
1780 else if (decl_type == ANYARRAYOID)
1781 {
1782 if (actual_type == UNKNOWNOID)
1783 continue;
1784 actual_type = getBaseType(actual_type); /* flatten domains */
1786 return false;
1788 }
1789 else if (decl_type == ANYRANGEOID)
1790 {
1791 if (actual_type == UNKNOWNOID)
1792 continue;
1793 actual_type = getBaseType(actual_type); /* flatten domains */
1795 return false;
1797 }
1798 else if (decl_type == ANYMULTIRANGEOID)
1799 {
1800 if (actual_type == UNKNOWNOID)
1801 continue;
1802 actual_type = getBaseType(actual_type); /* flatten domains */
1804 return false;
1806 }
1807 else if (decl_type == ANYCOMPATIBLEOID ||
1809 {
1812 if (actual_type == UNKNOWNOID)
1813 continue;
1814 /* collect the actual types of non-unknown COMPATIBLE args */
1816 }
1817 else if (decl_type == ANYCOMPATIBLEARRAYOID)
1818 {
1819 Oid elem_type;
1820
1821 if (actual_type == UNKNOWNOID)
1822 continue;
1823 actual_type = getBaseType(actual_type); /* flatten domains */
1825 if (!OidIsValid(elem_type))
1826 return false; /* not an array */
1827 /* collect the element type for common-supertype choice */
1829 }
1830 else if (decl_type == ANYCOMPATIBLERANGEOID)
1831 {
1832 if (actual_type == UNKNOWNOID)
1833 continue;
1834 actual_type = getBaseType(actual_type); /* flatten domains */
1836 {
1837 /* All ANYCOMPATIBLERANGE arguments must be the same type */
1839 return false;
1840 }
1841 else
1842 {
1846 return false; /* not a range type */
1847 /* collect the subtype for common-supertype choice */
1849 }
1850 }
1852 {
1853 if (actual_type == UNKNOWNOID)
1854 continue;
1855 actual_type = getBaseType(actual_type); /* flatten domains */
1857 {
1858 /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */
1860 return false;
1861 }
1862 else
1863 {
1867 return false; /* not a multirange type */
1868 /* we'll consider the subtype below */
1869 }
1870 }
1871 }
1872
1873 /* Get the element type based on the array type, if we have one */
1875 {
1877 {
1878 /*
1879 * Special case for matching ANYARRAY input to an ANYARRAY
1880 * argument: allow it for now. enforce_generic_type_consistency()
1881 * might complain later, depending on the presence of other
1882 * polymorphic arguments or results, but it will deliver a less
1883 * surprising error message than "function does not exist".
1884 *
1885 * (If you think to change this, note that can_coerce_type will
1886 * consider such a situation as a match, so that we might not even
1887 * get here.)
1888 */
1889 }
1890 else
1891 {
1893
1896 return false; /* should be an array, but isn't */
1897
1898 if (!OidIsValid(elem_typeid))
1899 {
1900 /*
1901 * if we don't have an element type yet, use the one we just
1902 * got
1903 */
1905 }
1906 else if (array_typelem != elem_typeid)
1907 {
1908 /* otherwise, they better match */
1909 return false;
1910 }
1911 }
1912 }
1913
1914 /* Deduce range type from multirange type, or check that they agree */
1916 {
1918
1921 return false; /* should be a multirange, but isn't */
1922
1924 {
1925 /* If we don't have a range type yet, use the one we just got */
1929 return false; /* should be a range, but isn't */
1930 }
1931 else if (multirange_typelem != range_typeid)
1932 {
1933 /* otherwise, they better match */
1934 return false;
1935 }
1936 }
1937
1938 /* Get the element type based on the range type, if we have one */
1940 {
1943 return false; /* should be a range, but isn't */
1944
1945 if (!OidIsValid(elem_typeid))
1946 {
1947 /*
1948 * If we don't have an element type yet, use the one we just got
1949 */
1951 }
1952 else if (range_typelem != elem_typeid)
1953 {
1954 /* otherwise, they better match */
1955 return false;
1956 }
1957 }
1958
1959 if (have_anynonarray)
1960 {
1961 /* require the element type to not be an array or domain over array */
1963 return false;
1964 }
1965
1966 if (have_anyenum)
1967 {
1968 /* require the element type to be an enum */
1970 return false;
1971 }
1972
1973 /* Deduce range type from multirange type, or check that they agree */
1975 {
1977 {
1980 return false;
1981 }
1982 else
1983 {
1987 return false; /* not a range type */
1988 /* collect the subtype for common-supertype choice */
1991 }
1992 }
1993
1994 /* Check matching of ANYCOMPATIBLE-family arguments, if any */
1995 if (n_anycompatible_args > 0)
1996 {
1998
2002 true);
2003
2005 return false; /* there's definitely no common supertype */
2006
2007 /* We have to verify that the selected type actually works */
2011 return false;
2012
2014 {
2015 /*
2016 * require the anycompatible type to not be an array or domain
2017 * over array
2018 */
2020 return false;
2021 }
2022
2023 /*
2024 * The anycompatible type must exactly match the range element type,
2025 * if we were able to identify one. This checks compatibility for
2026 * anycompatiblemultirange too since that also sets
2027 * anycompatible_range_typelem above.
2028 */
2031 return false;
2032 }
2033
2034 /* Looks valid */
2035 return true;
2036}
int j
Definition isn.c:78
Oid get_range_subtype(Oid rangeOid)
Definition lsyscache.c:3735
bool type_is_enum(Oid typid)
Definition lsyscache.c:2986
Oid get_multirange_range(Oid multirangeOid)
Definition lsyscache.c:3836
Oid getBaseType(Oid typid)
Definition lsyscache.c:2829
#define type_is_array_domain(typid)
Definition lsyscache.h:225
static bool verify_common_type_from_oids(Oid common_type, int nargs, const Oid *typeids)
static Oid select_common_type_from_oids(int nargs, const Oid *typeids, bool noerror)
#define FUNC_MAX_ARGS

References Assert, fb(), FUNC_MAX_ARGS, get_element_type(), get_multirange_range(), get_range_subtype(), getBaseType(), InvalidOid, j, OidIsValid, select_common_type_from_oids(), type_is_array_domain, type_is_enum(), and verify_common_type_from_oids().

Referenced by can_coerce_type().

◆ check_valid_internal_signature()

char * check_valid_internal_signature ( Oid  ret_type,
const Oid declared_arg_types,
int  nargs 
)

Definition at line 2952 of file parse_coerce.c.

2955{
2956 if (ret_type == INTERNALOID)
2957 {
2958 for (int i = 0; i < nargs; i++)
2959 {
2961 return NULL; /* OK */
2962 }
2963 return pstrdup(_("A result of type internal requires at least one input of type internal."));
2964 }
2965 else
2966 return NULL; /* OK, ret_type is not INTERNAL */
2967}
#define _(x)
Definition elog.c:96
char * pstrdup(const char *in)
Definition mcxt.c:1910

References _, fb(), i, and pstrdup().

Referenced by AggregateCreate(), and ProcedureCreate().

◆ check_valid_polymorphic_signature()

char * check_valid_polymorphic_signature ( Oid  ret_type,
const Oid declared_arg_types,
int  nargs 
)

Definition at line 2875 of file parse_coerce.c.

2878{
2880 {
2881 /*
2882 * ANYRANGE and ANYMULTIRANGE require an ANYRANGE or ANYMULTIRANGE
2883 * input, else we can't tell which of several range types with the
2884 * same element type to use.
2885 */
2886 for (int i = 0; i < nargs; i++)
2887 {
2890 return NULL; /* OK */
2891 }
2892 return psprintf(_("A result of type %s requires at least one input of type anyrange or anymultirange."),
2894 }
2896 {
2897 /*
2898 * ANYCOMPATIBLERANGE and ANYCOMPATIBLEMULTIRANGE require an
2899 * ANYCOMPATIBLERANGE or ANYCOMPATIBLEMULTIRANGE input, else we can't
2900 * tell which of several range types with the same element type to
2901 * use.
2902 */
2903 for (int i = 0; i < nargs; i++)
2904 {
2907 return NULL; /* OK */
2908 }
2909 return psprintf(_("A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange."),
2911 }
2913 {
2914 /* Otherwise, any family-1 type can be deduced from any other */
2915 for (int i = 0; i < nargs; i++)
2916 {
2918 return NULL; /* OK */
2919 }
2920 /* Keep this list in sync with IsPolymorphicTypeFamily1! */
2921 return psprintf(_("A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange."),
2923 }
2925 {
2926 /* Otherwise, any family-2 type can be deduced from any other */
2927 for (int i = 0; i < nargs; i++)
2928 {
2930 return NULL; /* OK */
2931 }
2932 /* Keep this list in sync with IsPolymorphicTypeFamily2! */
2933 return psprintf(_("A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, anycompatiblerange, or anycompatiblemultirange."),
2935 }
2936 else
2937 return NULL; /* OK, ret_type is not polymorphic */
2938}
char * format_type_be(Oid type_oid)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43

References _, fb(), format_type_be(), i, and psprintf().

Referenced by AggregateCreate(), and ProcedureCreate().

◆ coerce_null_to_domain()

Node * coerce_null_to_domain ( Oid  typid,
int32  typmod,
Oid  collation,
int  typlen,
bool  typbyval 
)

Definition at line 1271 of file parse_coerce.c.

1273{
1274 Node *result;
1276 int32 baseTypeMod = typmod;
1277
1278 /*
1279 * The constant must appear to have the domain's base type/typmod, else
1280 * coerce_to_domain() will apply a length coercion which is useless.
1281 */
1285 collation,
1286 typlen,
1287 (Datum) 0,
1288 true, /* isnull */
1289 typbyval);
1290 if (typid != baseTypeId)
1293 typid,
1296 -1,
1297 false);
1298 return result;
1299}
uint32 result
Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, CoercionContext ccontext, CoercionForm cformat, int location, bool hideInputCoercion)
uint64_t Datum
Definition postgres.h:70
@ COERCE_IMPLICIT_CAST
Definition primnodes.h:769
@ COERCION_IMPLICIT
Definition primnodes.h:747

References COERCE_IMPLICIT_CAST, coerce_to_domain(), COERCION_IMPLICIT, fb(), getBaseTypeAndTypmod(), makeConst(), and result.

Referenced by expand_insert_targetlist(), ReplaceVarFromTargetList(), rewriteTargetListIU(), and rewriteValuesRTE().

◆ coerce_record_to_complex()

static Node * coerce_record_to_complex ( ParseState pstate,
Node node,
Oid  targetTypeId,
CoercionContext  ccontext,
CoercionForm  cformat,
int  location 
)
static

Definition at line 1011 of file parse_coerce.c.

1016{
1017 RowExpr *rowexpr;
1019 int32 baseTypeMod = -1;
1020 TupleDesc tupdesc;
1021 List *args = NIL;
1022 List *newargs;
1023 int i;
1024 int ucolno;
1025 ListCell *arg;
1026
1027 if (node && IsA(node, RowExpr))
1028 {
1029 /*
1030 * Since the RowExpr must be of type RECORD, we needn't worry about it
1031 * containing any dropped columns.
1032 */
1033 args = ((RowExpr *) node)->args;
1034 }
1035 else if (node && IsA(node, Var) &&
1036 ((Var *) node)->varattno == InvalidAttrNumber)
1037 {
1038 Var *var = (Var *) node;
1040
1041 nsitem = GetNSItemByVar(pstate, var);
1042 args = expandNSItemVars(pstate, nsitem, var->varlevelsup,
1043 var->location, NULL);
1044 }
1045 else
1046 ereport(ERROR,
1048 errmsg("cannot cast type %s to %s",
1051 parser_coercion_errposition(pstate, location, node)));
1052
1053 /*
1054 * Look up the composite type, accounting for possibility that what we are
1055 * given is a domain over composite.
1056 */
1059
1060 /* Process the fields */
1061 newargs = NIL;
1062 ucolno = 1;
1063 arg = list_head(args);
1064 for (i = 0; i < tupdesc->natts; i++)
1065 {
1066 Node *expr;
1067 Node *cexpr;
1068 Oid exprtype;
1069 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
1070
1071 /* Fill in NULLs for dropped columns in rowtype */
1072 if (attr->attisdropped)
1073 {
1074 /*
1075 * can't use atttypid here, but it doesn't really matter what type
1076 * the Const claims to be.
1077 */
1080 continue;
1081 }
1082
1083 if (arg == NULL)
1084 ereport(ERROR,
1086 errmsg("cannot cast type %s to %s",
1089 errdetail("Input has too few columns."),
1090 parser_coercion_errposition(pstate, location, node)));
1091 expr = (Node *) lfirst(arg);
1092 exprtype = exprType(expr);
1093
1094 cexpr = coerce_to_target_type(pstate,
1095 expr, exprtype,
1096 attr->atttypid,
1097 attr->atttypmod,
1098 ccontext,
1100 -1);
1101 if (cexpr == NULL)
1102 ereport(ERROR,
1104 errmsg("cannot cast type %s to %s",
1107 errdetail("Cannot cast type %s to %s in column %d.",
1108 format_type_be(exprtype),
1109 format_type_be(attr->atttypid),
1110 ucolno),
1111 parser_coercion_errposition(pstate, location, expr)));
1112 newargs = lappend(newargs, cexpr);
1113 ucolno++;
1114 arg = lnext(args, arg);
1115 }
1116 if (arg != NULL)
1117 ereport(ERROR,
1119 errmsg("cannot cast type %s to %s",
1122 errdetail("Input has too many columns."),
1123 parser_coercion_errposition(pstate, location, node)));
1124
1125 ReleaseTupleDesc(tupdesc);
1126
1127 rowexpr = makeNode(RowExpr);
1128 rowexpr->args = newargs;
1129 rowexpr->row_typeid = baseTypeId;
1130 rowexpr->row_format = cformat;
1131 rowexpr->colnames = NIL; /* not needed for named target type */
1132 rowexpr->location = location;
1133
1134 /* If target is a domain, apply constraints */
1135 if (baseTypeId != targetTypeId)
1136 {
1137 rowexpr->row_format = COERCE_IMPLICIT_CAST;
1138 return coerce_to_domain((Node *) rowexpr,
1141 ccontext, cformat, location,
1142 false);
1143 }
1144
1145 return (Node *) rowexpr;
1146}
#define InvalidAttrNumber
Definition attnum.h:23
Datum arg
Definition elog.c:1323
int errcode(int sqlerrcode)
Definition elog.c:875
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
Definition elog.h:152
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Definition makefuncs.c:388
#define IsA(nodeptr, _type_)
Definition nodes.h:164
static char * errmsg
int parser_coercion_errposition(ParseState *pstate, int coerce_location, Node *input_expr)
List * expandNSItemVars(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location, List **colnames)
ParseNamespaceItem * GetNSItemByVar(ParseState *pstate, Var *var)
FormData_pg_attribute * Form_pg_attribute
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
static ListCell * list_head(const List *l)
Definition pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition pg_list.h:375
List * args
Definition primnodes.h:1450
ParseLoc location
Definition primnodes.h:1474
ParseLoc location
Definition primnodes.h:311
Index varlevelsup
Definition primnodes.h:295
#define ReleaseTupleDesc(tupdesc)
Definition tupdesc.h:240
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition typcache.c:1940

References arg, RowExpr::args, COERCE_IMPLICIT_CAST, coerce_to_domain(), coerce_to_target_type(), ereport, errcode(), errdetail(), errmsg, ERROR, expandNSItemVars(), exprType(), fb(), format_type_be(), getBaseTypeAndTypmod(), GetNSItemByVar(), i, InvalidAttrNumber, InvalidOid, IsA, lappend(), lfirst, list_head(), lnext(), Var::location, RowExpr::location, lookup_rowtype_tupdesc(), makeNode, makeNullConst(), TupleDescData::natts, NIL, parser_coercion_errposition(), ReleaseTupleDesc, TupleDescAttr(), and Var::varlevelsup.

Referenced by coerce_type().

◆ coerce_to_boolean()

Node * coerce_to_boolean ( ParseState pstate,
Node node,
const char constructName 
)

Definition at line 1159 of file parse_coerce.c.

1161{
1162 Oid inputTypeId = exprType(node);
1163
1164 if (inputTypeId != BOOLOID)
1165 {
1166 Node *newnode;
1167
1169 BOOLOID, -1,
1172 -1);
1173 if (newnode == NULL)
1174 ereport(ERROR,
1176 /* translator: first %s is name of a SQL construct, eg WHERE */
1177 errmsg("argument of %s must be type %s, not type %s",
1178 constructName, "boolean",
1180 parser_errposition(pstate, exprLocation(node))));
1181 node = newnode;
1182 }
1183
1184 if (expression_returns_set(node))
1185 ereport(ERROR,
1187 /* translator: %s is name of a SQL construct, eg WHERE */
1188 errmsg("argument of %s must not return a set",
1190 parser_errposition(pstate, exprLocation(node))));
1191
1192 return node;
1193}
int exprLocation(const Node *expr)
Definition nodeFuncs.c:1403
bool expression_returns_set(Node *clause)
Definition nodeFuncs.c:768
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
@ COERCION_ASSIGNMENT
Definition primnodes.h:748

References COERCE_IMPLICIT_CAST, coerce_to_target_type(), COERCION_ASSIGNMENT, ereport, errcode(), errmsg, ERROR, expression_returns_set(), exprLocation(), exprType(), fb(), format_type_be(), and parser_errposition().

Referenced by cookConstraint(), DoCopy(), domainAddCheckConstraint(), transformAExprIn(), transformBooleanTest(), transformBoolExpr(), transformCaseExpr(), transformJoinUsingClause(), transformWhereClause(), and transformXmlExpr().

◆ coerce_to_common_type()

Node * coerce_to_common_type ( ParseState pstate,
Node node,
Oid  targetTypeId,
const char context 
)

Definition at line 1572 of file parse_coerce.c.

1574{
1575 Oid inputTypeId = exprType(node);
1576
1578 return node; /* no work */
1580 node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
1582 else
1583 ereport(ERROR,
1585 /* translator: first %s is name of a SQL construct, eg CASE */
1586 errmsg("%s could not convert type %s to %s",
1587 context,
1590 parser_errposition(pstate, exprLocation(node))));
1591 return node;
1592}
Node * coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, CoercionContext ccontext, CoercionForm cformat, int location)
bool can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids, CoercionContext ccontext)

References can_coerce_type(), COERCE_IMPLICIT_CAST, coerce_type(), COERCION_IMPLICIT, ereport, errcode(), errmsg, ERROR, exprLocation(), exprType(), fb(), format_type_be(), and parser_errposition().

Referenced by analyzeCTE(), constructSetOpTargetlist(), generate_setop_tlist(), transformAExprIn(), transformArrayExpr(), transformCaseExpr(), transformCoalesceExpr(), transformMinMaxExpr(), and transformValuesClause().

◆ coerce_to_domain()

Node * coerce_to_domain ( Node arg,
Oid  baseTypeId,
int32  baseTypeMod,
Oid  typeId,
CoercionContext  ccontext,
CoercionForm  cformat,
int  location,
bool  hideInputCoercion 
)

Definition at line 676 of file parse_coerce.c.

679{
681
682 /* We now require the caller to supply correct baseTypeId/baseTypeMod */
684
685 /* If it isn't a domain, return the node as it was passed in */
686 if (baseTypeId == typeId)
687 return arg;
688
689 /* Suppress display of nested coercion steps */
692
693 /*
694 * If the domain applies a typmod to its base type, build the appropriate
695 * coercion step. Mark it implicit for display purposes, because we don't
696 * want it shown separately by ruleutils.c; but the isExplicit flag passed
697 * to the conversion function depends on the manner in which the domain
698 * coercion is invoked, so that the semantics of implicit and explicit
699 * coercion differ. (Is that really the behavior we want?)
700 *
701 * NOTE: because we apply this as part of the fixed expression structure,
702 * ALTER DOMAIN cannot alter the typtypmod. But it's unclear that that
703 * would be safe to do anyway, without lots of knowledge about what the
704 * base type thinks the typmod means.
705 */
708 false);
709
710 /*
711 * Now build the domain coercion node. This represents run-time checking
712 * of any constraints currently attached to the domain. This also ensures
713 * that the expression is properly labeled as to result type.
714 */
716 result->arg = (Expr *) arg;
717 result->resulttype = typeId;
718 result->resulttypmod = -1; /* currently, always -1 for domains */
719 /* resultcollid will be set by parse_collate.c */
720 result->coercionformat = cformat;
721 result->location = location;
722
723 return (Node *) result;
724}
static Node * coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, CoercionContext ccontext, CoercionForm cformat, int location, bool hideInputCoercion)
static void hide_coercion_node(Node *node)

References arg, Assert, COERCE_IMPLICIT_CAST, coerce_type_typmod(), fb(), hide_coercion_node(), makeNode, OidIsValid, and result.

Referenced by coerce_null_to_domain(), coerce_record_to_complex(), coerce_type(), and transformAssignmentIndirection().

◆ coerce_to_specific_type()

Node * coerce_to_specific_type ( ParseState pstate,
Node node,
Oid  targetTypeId,
const char constructName 
)

Definition at line 1255 of file parse_coerce.c.

1258{
1259 return coerce_to_specific_type_typmod(pstate, node,
1260 targetTypeId, -1,
1262}
Node * coerce_to_specific_type_typmod(ParseState *pstate, Node *node, Oid targetTypeId, int32 targetTypmod, const char *constructName)

References coerce_to_specific_type_typmod(), and fb().

Referenced by coerceJsonFuncExpr(), interpret_function_parameter_list(), transformFrameOffset(), transformJsonScalarExpr(), transformJsonValueExpr(), transformLimitClause(), transformRangeTableFunc(), transformRangeTableSample(), transformXmlExpr(), and transformXmlSerialize().

◆ coerce_to_specific_type_typmod()

Node * coerce_to_specific_type_typmod ( ParseState pstate,
Node node,
Oid  targetTypeId,
int32  targetTypmod,
const char constructName 
)

Definition at line 1206 of file parse_coerce.c.

1209{
1210 Oid inputTypeId = exprType(node);
1211
1213 {
1214 Node *newnode;
1215
1220 -1);
1221 if (newnode == NULL)
1222 ereport(ERROR,
1224 /* translator: first %s is name of a SQL construct, eg LIMIT */
1225 errmsg("argument of %s must be type %s, not type %s",
1229 parser_errposition(pstate, exprLocation(node))));
1230 node = newnode;
1231 }
1232
1233 if (expression_returns_set(node))
1234 ereport(ERROR,
1236 /* translator: %s is name of a SQL construct, eg LIMIT */
1237 errmsg("argument of %s must not return a set",
1239 parser_errposition(pstate, exprLocation(node))));
1240
1241 return node;
1242}

References COERCE_IMPLICIT_CAST, coerce_to_target_type(), COERCION_ASSIGNMENT, ereport, errcode(), errmsg, ERROR, expression_returns_set(), exprLocation(), exprType(), fb(), format_type_be(), and parser_errposition().

Referenced by coerce_to_specific_type(), and transformRangeTableFunc().

◆ coerce_to_target_type()

Node * coerce_to_target_type ( ParseState pstate,
Node expr,
Oid  exprtype,
Oid  targettype,
int32  targettypmod,
CoercionContext  ccontext,
CoercionForm  cformat,
int  location 
)

Definition at line 79 of file parse_coerce.c.

84{
85 Node *result;
87
88 if (!can_coerce_type(1, &exprtype, &targettype, ccontext))
89 return NULL;
90
91 /*
92 * If the input has a CollateExpr at the top, strip it off, perform the
93 * coercion, and put a new one back on. This is annoying since it
94 * duplicates logic in coerce_type, but if we don't do this then it's too
95 * hard to tell whether coerce_type actually changed anything, and we
96 * *must* know that to avoid possibly calling hide_coercion_node on
97 * something that wasn't generated by coerce_type. Note that if there are
98 * multiple stacked CollateExprs, we just discard all but the topmost.
99 * Also, if the target type isn't collatable, we discard the CollateExpr.
100 */
101 origexpr = expr;
102 while (expr && IsA(expr, CollateExpr))
103 expr = (Node *) ((CollateExpr *) expr)->arg;
104
105 result = coerce_type(pstate, expr, exprtype,
106 targettype, targettypmod,
107 ccontext, cformat, location);
108
109 /*
110 * If the target is a fixed-length type, it may need a length coercion as
111 * well as a type coercion. If we find ourselves adding both, force the
112 * inner coercion node to implicit display form.
113 */
115 targettype, targettypmod,
116 ccontext, cformat, location,
117 (result != expr && !IsA(result, Const)));
118
119 if (expr != origexpr && type_is_collatable(targettype))
120 {
121 /* Reinstall top CollateExpr */
122 CollateExpr *coll = (CollateExpr *) origexpr;
124
125 newcoll->arg = (Expr *) result;
126 newcoll->collOid = coll->collOid;
127 newcoll->location = coll->location;
128 result = (Node *) newcoll;
129 }
130
131 return result;
132}
bool type_is_collatable(Oid typid)
Definition lsyscache.c:3389
ParseLoc location
Definition primnodes.h:1316

References arg, can_coerce_type(), coerce_type(), coerce_type_typmod(), CollateExpr::collOid, fb(), IsA, CollateExpr::location, makeNode, result, and type_is_collatable().

Referenced by array_subscript_transform(), ATExecAddColumn(), ATExecAlterColumnType(), ATPrepAlterColumnType(), build_coercion_expression(), build_column_default(), coerce_fn_result_column(), coerce_record_to_complex(), coerce_to_boolean(), coerce_to_specific_type_typmod(), coerceJsonFuncExpr(), cookDefault(), EvaluateParams(), get_cast_hashentry(), hstore_subscript_transform(), transformArrayExpr(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformJsonBehavior(), transformJsonFuncExpr(), transformJsonParseArg(), transformJsonValueExpr(), transformPartitionBoundValue(), transformPLAssignStmtTarget(), transformTypeCast(), and transformXmlSerialize().

◆ coerce_type()

Node * coerce_type ( ParseState pstate,
Node node,
Oid  inputTypeId,
Oid  targetTypeId,
int32  targetTypeMod,
CoercionContext  ccontext,
CoercionForm  cformat,
int  location 
)

Definition at line 158 of file parse_coerce.c.

161{
162 Node *result;
163 CoercionPathType pathtype;
164 Oid funcId;
165
166 if (targetTypeId == inputTypeId ||
167 node == NULL)
168 {
169 /* no conversion needed */
170 return node;
171 }
172 if (targetTypeId == ANYOID ||
177 {
178 /*
179 * Assume can_coerce_type verified that implicit coercion is okay.
180 *
181 * Note: by returning the unmodified node here, we are saying that
182 * it's OK to treat an UNKNOWN constant as a valid input for a
183 * function accepting one of these pseudotypes. This should be all
184 * right, since an UNKNOWN value is still a perfectly valid Datum.
185 *
186 * NB: we do NOT want a RelabelType here: the exposed type of the
187 * function argument must be its actual type, not the polymorphic
188 * pseudotype.
189 */
190 return node;
191 }
192 if (targetTypeId == ANYARRAYOID ||
199 {
200 /*
201 * Assume can_coerce_type verified that implicit coercion is okay.
202 *
203 * These cases are unlike the ones above because the exposed type of
204 * the argument must be an actual array, enum, range, or multirange
205 * type. In particular the argument must *not* be an UNKNOWN
206 * constant. If it is, we just fall through; below, we'll call the
207 * pseudotype's input function, which will produce an error. Also, if
208 * what we have is a domain over array, enum, range, or multirange, we
209 * have to relabel it to its base type.
210 *
211 * Note: currently, we can't actually see a domain-over-enum here,
212 * since the other functions in this file will not match such a
213 * parameter to ANYENUM. But that should get changed eventually.
214 */
215 if (inputTypeId != UNKNOWNOID)
216 {
218
219 if (baseTypeId != inputTypeId)
220 {
221 RelabelType *r = makeRelabelType((Expr *) node,
222 baseTypeId, -1,
224 cformat);
225
226 r->location = location;
227 return (Node *) r;
228 }
229 /* Not a domain type, so return it as-is */
230 return node;
231 }
232 }
233 if (inputTypeId == UNKNOWNOID && IsA(node, Const))
234 {
235 /*
236 * Input is a string constant with previously undetermined type. Apply
237 * the target type's typinput function to it to produce a constant of
238 * the target type.
239 *
240 * NOTE: this case cannot be folded together with the other
241 * constant-input case, since the typinput function does not
242 * necessarily behave the same as a type conversion function. For
243 * example, int4's typinput function will reject "1.2", whereas
244 * float-to-int type conversion will round to integer.
245 *
246 * XXX if the typinput function is not immutable, we really ought to
247 * postpone evaluation of the function call until runtime. But there
248 * is no way to represent a typinput function call as an expression
249 * tree, because C-string values are not Datums. (XXX This *is*
250 * possible as of 7.3, do we want to do it?)
251 */
252 Const *con = (Const *) node;
257 Type baseType;
259
260 /*
261 * If the target type is a domain, we want to call its base type's
262 * input routine, not domain_in(). This is to avoid premature failure
263 * when the domain applies a typmod: existing input routines follow
264 * implicit-coercion semantics for length checks, which is not always
265 * what we want here. The needed check will be applied properly
266 * inside coerce_to_domain().
267 */
270
271 /*
272 * For most types we pass typmod -1 to the input routine, because
273 * existing input routines follow implicit-coercion semantics for
274 * length checks, which is not always what we want here. Any length
275 * constraint will be applied later by our caller. An exception
276 * however is the INTERVAL type, for which we *must* pass the typmod
277 * or it won't be able to obey the bizarre SQL-spec input rules. (Ugly
278 * as sin, but so is this part of the spec...)
279 */
280 if (baseTypeId == INTERVALOID)
282 else
283 inputTypeMod = -1;
284
285 baseType = typeidType(baseTypeId);
286
287 newcon->consttype = baseTypeId;
288 newcon->consttypmod = inputTypeMod;
289 newcon->constcollid = typeTypeCollation(baseType);
290 newcon->constlen = typeLen(baseType);
291 newcon->constbyval = typeByVal(baseType);
292 newcon->constisnull = con->constisnull;
293
294 /*
295 * We use the original literal's location regardless of the position
296 * of the coercion. This is a change from pre-9.2 behavior, meant to
297 * simplify life for pg_stat_statements.
298 */
299 newcon->location = con->location;
300
301 /*
302 * Set up to point at the constant's text if the input routine throws
303 * an error.
304 */
305 setup_parser_errposition_callback(&pcbstate, pstate, con->location);
306
307 /*
308 * We assume here that UNKNOWN's internal representation is the same
309 * as CSTRING.
310 */
311 if (!con->constisnull)
312 newcon->constvalue = stringTypeDatum(baseType,
313 DatumGetCString(con->constvalue),
315 else
316 newcon->constvalue = stringTypeDatum(baseType,
317 NULL,
319
320 /*
321 * If it's a varlena value, force it to be in non-expanded
322 * (non-toasted) format; this avoids any possible dependency on
323 * external values and improves consistency of representation.
324 */
325 if (!con->constisnull && newcon->constlen == -1)
326 newcon->constvalue =
328
329#ifdef RANDOMIZE_ALLOCATED_MEMORY
330
331 /*
332 * For pass-by-reference data types, repeat the conversion to see if
333 * the input function leaves any uninitialized bytes in the result. We
334 * can only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is
335 * enabled, so we don't bother testing otherwise. The reason we don't
336 * want any instability in the input function is that comparison of
337 * Const nodes relies on bytewise comparison of the datums, so if the
338 * input function leaves garbage then subexpressions that should be
339 * identical may not get recognized as such. See pgsql-hackers
340 * discussion of 2008-04-04.
341 */
342 if (!con->constisnull && !newcon->constbyval)
343 {
344 Datum val2;
345
346 val2 = stringTypeDatum(baseType,
347 DatumGetCString(con->constvalue),
349 if (newcon->constlen == -1)
351 if (!datumIsEqual(newcon->constvalue, val2, false, newcon->constlen))
352 elog(WARNING, "type %s has unstable input conversion for \"%s\"",
353 typeTypeName(baseType), DatumGetCString(con->constvalue));
354 }
355#endif
356
358
359 result = (Node *) newcon;
360
361 /* If target is a domain, apply constraints. */
366 ccontext, cformat, location,
367 false);
368
369 ReleaseSysCache(baseType);
370
371 return result;
372 }
373 if (IsA(node, Param) &&
374 pstate != NULL && pstate->p_coerce_param_hook != NULL)
375 {
376 /*
377 * Allow the CoerceParamHook to decide what happens. It can return a
378 * transformed node (very possibly the same Param node), or return
379 * NULL to indicate we should proceed with normal coercion.
380 */
381 result = pstate->p_coerce_param_hook(pstate,
382 (Param *) node,
385 location);
386 if (result)
387 return result;
388 }
389 if (IsA(node, CollateExpr))
390 {
391 /*
392 * If we have a COLLATE clause, we have to push the coercion
393 * underneath the COLLATE; or discard the COLLATE if the target type
394 * isn't collatable. This is really ugly, but there is little choice
395 * because the above hacks on Consts and Params wouldn't happen
396 * otherwise. This kluge has consequences in coerce_to_target_type.
397 */
398 CollateExpr *coll = (CollateExpr *) node;
399
400 result = coerce_type(pstate, (Node *) coll->arg,
402 ccontext, cformat, location);
404 {
406
407 newcoll->arg = (Expr *) result;
408 newcoll->collOid = coll->collOid;
409 newcoll->location = coll->location;
410 result = (Node *) newcoll;
411 }
412 return result;
413 }
415 &funcId);
416 if (pathtype != COERCION_PATH_NONE)
417 {
420
423
424 if (pathtype != COERCION_PATH_RELABELTYPE)
425 {
426 /*
427 * Generate an expression tree representing run-time application
428 * of the conversion function. If we are dealing with a domain
429 * target type, the conversion function will yield the base type,
430 * and we need to extract the correct typmod to use from the
431 * domain's typtypmod.
432 */
433 result = build_coercion_expression(node, pathtype, funcId,
435 ccontext, cformat, location);
436
437 /*
438 * If domain, coerce to the domain type and relabel with domain
439 * type ID, hiding the previous coercion node.
440 */
444 ccontext, cformat, location,
445 true);
446 }
447 else
448 {
449 /*
450 * We don't need to do a physical conversion, but we do need to
451 * attach a RelabelType node so that the expression will be seen
452 * to have the intended type when inspected by higher-level code.
453 *
454 * Also, domains may have value restrictions beyond the base type
455 * that must be accounted for. If the destination is a domain
456 * then we won't need a RelabelType node.
457 */
460 ccontext, cformat, location,
461 false);
462 if (result == node)
463 {
464 /*
465 * XXX could we label result with exprTypmod(node) instead of
466 * default -1 typmod, to save a possible length-coercion
467 * later? Would work if both types have same interpretation of
468 * typmod, which is likely but not certain.
469 */
471 targetTypeId, -1,
473 cformat);
474
475 r->location = location;
476 result = (Node *) r;
477 }
478 }
479 return result;
480 }
481 if (inputTypeId == RECORDOID &&
483 {
484 /* Coerce a RECORD to a specific complex type */
485 return coerce_record_to_complex(pstate, node, targetTypeId,
486 ccontext, cformat, location);
487 }
488 if (targetTypeId == RECORDOID &&
490 {
491 /* Coerce a specific complex type to RECORD */
492 /* NB: we do NOT want a RelabelType here */
493 return node;
494 }
495#ifdef NOT_USED
498 {
499 /* Coerce record[] to a specific complex array type */
500 /* not implemented yet ... */
501 }
502#endif
505 {
506 /* Coerce a specific complex array type to record[] */
507 /* NB: we do NOT want a RelabelType here */
508 return node;
509 }
512 {
513 /*
514 * Input class type is a subclass of target, so generate an
515 * appropriate runtime conversion (removing unneeded columns and
516 * possibly rearranging the ones that are wanted).
517 *
518 * We will also get here when the input is a domain over a subclass of
519 * the target type. To keep life simple for the executor, we define
520 * ConvertRowtypeExpr as only working between regular composite types;
521 * therefore, in such cases insert a RelabelType to smash the input
522 * expression down to its base type.
523 */
526
527 if (baseTypeId != inputTypeId)
528 {
530 baseTypeId, -1,
533
534 rt->location = location;
535 node = (Node *) rt;
536 }
537 r->arg = (Expr *) node;
539 r->convertformat = cformat;
540 r->location = location;
541 return (Node *) r;
542 }
543 /* If we get here, caller blew it */
544 elog(ERROR, "failed to find conversion function from %s to %s",
546 return NULL; /* keep compiler quiet */
547}
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
Definition datum.c:223
#define WARNING
Definition elog.h:37
#define PG_DETOAST_DATUM(datum)
Definition fmgr.h:240
RelabelType * makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat)
Definition makefuncs.c:453
static Node * coerce_record_to_complex(ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, CoercionForm cformat, int location)
static Node * build_coercion_expression(Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, CoercionContext ccontext, CoercionForm cformat, int location)
@ COERCION_PATH_RELABELTYPE
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition parse_node.c:156
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition parse_node.c:140
Type typeidType(Oid id)
Definition parse_type.c:578
Oid typeTypeCollation(Type typ)
Definition parse_type.c:640
char * typeTypeName(Type t)
Definition parse_type.c:619
Datum stringTypeDatum(Type tp, char *string, int32 atttypmod)
Definition parse_type.c:654
bool typeByVal(Type t)
Definition parse_type.c:609
int16 typeLen(Type t)
Definition parse_type.c:599
static char * DatumGetCString(Datum X)
Definition postgres.h:365
#define PointerGetDatum(X)
Definition postgres.h:354
CoerceParamHook p_coerce_param_hook
Definition parse_node.h:261
ParseLoc location
Definition primnodes.h:1227

References ConvertRowtypeExpr::arg, CollateExpr::arg, build_coercion_expression(), cancel_parser_errposition_callback(), COERCE_IMPLICIT_CAST, coerce_record_to_complex(), coerce_to_domain(), coerce_type(), COERCION_PATH_NONE, COERCION_PATH_RELABELTYPE, CollateExpr::collOid, DatumGetCString(), datumIsEqual(), elog, ERROR, fb(), find_coercion_pathway(), format_type_be(), getBaseType(), getBaseTypeAndTypmod(), InvalidOid, is_complex_array(), IsA, ISCOMPLEX, RelabelType::location, ConvertRowtypeExpr::location, CollateExpr::location, makeNode, makeRelabelType(), ParseState::p_coerce_param_hook, PG_DETOAST_DATUM, PointerGetDatum, ReleaseSysCache(), result, ConvertRowtypeExpr::resulttype, setup_parser_errposition_callback(), stringTypeDatum(), type_is_collatable(), typeByVal(), typeidType(), typeInheritsFrom(), typeIsOfTypedTable(), typeLen(), typeTypeCollation(), typeTypeName(), and WARNING.

Referenced by addTargetToGroupList(), addTargetToSortList(), buildMergedJoinVar(), coerce_to_common_type(), coerce_to_target_type(), coerce_type(), jsonb_subscript_transform(), make_fn_arguments(), ParseFuncOrColumn(), resolveTargetListUnknowns(), transformArrayExpr(), transformForPortionOfClause(), and unify_hypothetical_args().

◆ coerce_type_typmod()

static Node * coerce_type_typmod ( Node node,
Oid  targetTypeId,
int32  targetTypMod,
CoercionContext  ccontext,
CoercionForm  cformat,
int  location,
bool  hideInputCoercion 
)
static

Definition at line 752 of file parse_coerce.c.

756{
757 CoercionPathType pathtype;
758 Oid funcId;
759
760 /* Skip coercion if already done */
761 if (targetTypMod == exprTypmod(node))
762 return node;
763
764 /* Suppress display of nested coercion steps */
766 hide_coercion_node(node);
767
768 /*
769 * A negative typmod means that no actual coercion is needed, but we still
770 * want a RelabelType to ensure that the expression exposes the intended
771 * typmod.
772 */
773 if (targetTypMod < 0)
774 pathtype = COERCION_PATH_NONE;
775 else
777
778 if (pathtype != COERCION_PATH_NONE)
779 {
780 node = build_coercion_expression(node, pathtype, funcId,
782 ccontext, cformat, location);
783 }
784 else
785 {
786 /*
787 * We don't need to perform any actual coercion step, but we should
788 * apply a RelabelType to ensure that the expression exposes the
789 * intended typmod.
790 */
792 exprCollation(node),
793 cformat, location, false);
794 }
795
796 return node;
797}
Oid exprCollation(const Node *expr)
Definition nodeFuncs.c:826
Node * applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
Definition nodeFuncs.c:641
CoercionPathType find_typmod_coercion_function(Oid typeId, Oid *funcid)

References applyRelabelType(), build_coercion_expression(), COERCION_PATH_NONE, exprCollation(), exprTypmod(), fb(), find_typmod_coercion_function(), and hide_coercion_node().

Referenced by coerce_to_domain(), and coerce_to_target_type().

◆ enforce_generic_type_consistency()

Oid enforce_generic_type_consistency ( const Oid actual_arg_types,
Oid declared_arg_types,
int  nargs,
Oid  rettype,
bool  allow_poly 
)

Definition at line 2131 of file parse_coerce.c.

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);
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 */
2164 Assert(nargs <= FUNC_MAX_ARGS);
2165 for (int j = 0; j < nargs; j++)
2166 {
2169
2170 if (decl_type == ANYELEMENTOID ||
2173 {
2174 n_poly_args++;
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 }
2185 continue; /* no new information here */
2187 ereport(ERROR,
2189 errmsg("arguments declared \"%s\" are not all alike", "anyelement"),
2190 errdetail("%s versus %s",
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 }
2204 continue; /* no new information here */
2205 actual_type = getBaseType(actual_type); /* flatten domains */
2207 ereport(ERROR,
2209 errmsg("arguments declared \"%s\" are not all alike", "anyarray"),
2210 errdetail("%s versus %s",
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 }
2224 continue; /* no new information here */
2225 actual_type = getBaseType(actual_type); /* flatten domains */
2227 ereport(ERROR,
2229 errmsg("arguments declared \"%s\" are not all alike", "anyrange"),
2230 errdetail("%s versus %s",
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 }
2245 continue; /* no new information here */
2246 actual_type = getBaseType(actual_type); /* flatten domains */
2248 ereport(ERROR,
2250 errmsg("arguments declared \"%s\" are not all alike", "anymultirange"),
2251 errdetail("%s versus %s",
2255 }
2256 else if (decl_type == ANYCOMPATIBLEOID ||
2258 {
2262 if (actual_type == UNKNOWNOID)
2263 continue;
2265 continue; /* no new information here */
2266 /* collect the actual types of non-unknown COMPATIBLE args */
2268 }
2269 else if (decl_type == ANYCOMPATIBLEARRAYOID)
2270 {
2272
2275 if (actual_type == UNKNOWNOID)
2276 continue;
2278 continue; /* no new information here */
2279 actual_type = getBaseType(actual_type); /* flatten domains */
2282 ereport(ERROR,
2284 errmsg("argument declared %s is not an array but type %s",
2285 "anycompatiblearray",
2287 /* collect the element type for common-supertype choice */
2289 }
2290 else if (decl_type == ANYCOMPATIBLERANGEOID)
2291 {
2294 if (actual_type == UNKNOWNOID)
2295 continue;
2297 continue; /* no new information here */
2298 actual_type = getBaseType(actual_type); /* flatten domains */
2300 {
2301 /* All ANYCOMPATIBLERANGE arguments must be the same type */
2303 ereport(ERROR,
2305 errmsg("arguments declared \"%s\" are not all alike", "anycompatiblerange"),
2306 errdetail("%s versus %s",
2309 }
2310 else
2311 {
2315 ereport(ERROR,
2317 errmsg("argument declared %s is not a range type but type %s",
2318 "anycompatiblerange",
2320 /* collect the subtype for common-supertype choice */
2322 }
2323 }
2325 {
2328 if (actual_type == UNKNOWNOID)
2329 continue;
2331 continue; /* no new information here */
2332 actual_type = getBaseType(actual_type); /* flatten domains */
2334 {
2335 /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */
2337 ereport(ERROR,
2339 errmsg("arguments declared \"%s\" are not all alike", "anycompatiblemultirange"),
2340 errdetail("%s versus %s",
2343 }
2344 else
2345 {
2349 ereport(ERROR,
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 */
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
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)))
2386 ereport(ERROR,
2388 errmsg("cannot determine element type of \"anyarray\" argument")));
2390 }
2391 else
2392 {
2395 ereport(ERROR,
2397 errmsg("argument declared %s is not an array but type %s",
2398 "anyarray", format_type_be(array_typeid))));
2399 }
2400
2401 if (!OidIsValid(elem_typeid))
2402 {
2403 /*
2404 * if we don't have an element type yet, use the one we just
2405 * got
2406 */
2408 }
2409 else if (array_typelem != elem_typeid)
2410 {
2411 /* otherwise, they better match */
2412 ereport(ERROR,
2414 errmsg("argument declared %s is not consistent with argument declared %s",
2415 "anyarray", "anyelement"),
2416 errdetail("%s versus %s",
2419 }
2420 }
2421
2422 /* Deduce range type from multirange type, or vice versa */
2424 {
2426
2429 ereport(ERROR,
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 */
2439 }
2440 else if (multirange_typelem != range_typeid)
2441 {
2442 /* otherwise, they better match */
2443 ereport(ERROR,
2445 errmsg("argument declared %s is not consistent with argument declared %s",
2446 "anymultirange", "anyrange"),
2447 errdetail("%s versus %s",
2450 }
2451 }
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
2465 ereport(ERROR,
2467 errmsg("argument declared %s is not a range type but type %s",
2468 "anyrange",
2470
2471 if (!OidIsValid(elem_typeid))
2472 {
2473 /*
2474 * if we don't have an element type yet, use the one we just
2475 * got
2476 */
2478 }
2479 else if (range_typelem != elem_typeid)
2480 {
2481 /* otherwise, they better match */
2482 ereport(ERROR,
2484 errmsg("argument declared %s is not consistent with argument declared %s",
2485 "anyrange", "anyelement"),
2486 errdetail("%s versus %s",
2489 }
2490 }
2491
2492 if (!OidIsValid(elem_typeid))
2493 {
2494 if (allow_poly)
2495 {
2500 }
2501 else
2502 {
2503 /*
2504 * Only way to get here is if all the family-1 polymorphic
2505 * arguments have UNKNOWN inputs.
2506 */
2507 ereport(ERROR,
2509 errmsg("could not determine polymorphic type because input has type %s",
2510 "unknown")));
2511 }
2512 }
2513
2515 {
2516 /*
2517 * require the element type to not be an array or domain over
2518 * array
2519 */
2521 ereport(ERROR,
2523 errmsg("type matched to anynonarray is an array type: %s",
2525 }
2526
2528 {
2529 /* require the element type to be an enum */
2531 ereport(ERROR,
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 */
2540 {
2541 /* Deduce range type from multirange type, or vice versa */
2543 {
2545 {
2548 ereport(ERROR,
2550 errmsg("argument declared %s is not consistent with argument declared %s",
2551 "anycompatiblemultirange",
2552 "anycompatiblerange"),
2553 errdetail("%s versus %s",
2556 }
2557 else
2558 {
2562 ereport(ERROR,
2564 errmsg("argument declared %s is not a multirange type but type %s",
2565 "anycompatiblemultirange",
2567 /* this enables element type matching check below */
2569 /* collect the subtype for common-supertype choice */
2572 }
2573 }
2576 {
2578 /* We'll complain below if that didn't work */
2579 }
2580
2581 if (n_anycompatible_args > 0)
2582 {
2586 false);
2587
2588 /* We have to verify that the selected type actually works */
2592 ereport(ERROR,
2594 errmsg("arguments of anycompatible family cannot be cast to a common type")));
2595
2597 {
2600 ereport(ERROR,
2602 errmsg("could not find array type for data type %s",
2604 }
2605
2607 {
2608 /* we can't infer a range type from the others */
2610 ereport(ERROR,
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 */
2620 ereport(ERROR,
2622 errmsg("anycompatiblerange type %s does not match anycompatible type %s",
2625 }
2626
2628 {
2629 /* we can't infer a multirange type from the others */
2631 ereport(ERROR,
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 */
2641 ereport(ERROR,
2643 errmsg("anycompatiblemultirange type %s does not match anycompatible type %s",
2646 }
2647
2649 {
2650 /*
2651 * require the element type to not be an array or domain over
2652 * array
2653 */
2655 ereport(ERROR,
2657 errmsg("type matched to anycompatiblenonarray is an array type: %s",
2659 }
2660 }
2661 else
2662 {
2663 if (allow_poly)
2664 {
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 */
2681 ereport(ERROR,
2683 errmsg("could not determine polymorphic type %s because input has type %s",
2684 "anycompatiblerange", "unknown")));
2686 ereport(ERROR,
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 {
2697
2698 if (decl_type == ANYCOMPATIBLEOID ||
2701 else if (decl_type == ANYCOMPATIBLEARRAYOID)
2703 else if (decl_type == ANYCOMPATIBLERANGEOID)
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 */
2719 {
2720 for (int j = 0; j < nargs; j++)
2721 {
2724
2725 if (actual_type != UNKNOWNOID)
2726 continue;
2727
2728 if (decl_type == ANYELEMENTOID ||
2732 else if (decl_type == ANYARRAYOID)
2733 {
2735 {
2738 ereport(ERROR,
2740 errmsg("could not find array type for data type %s",
2742 }
2744 }
2745 else if (decl_type == ANYRANGEOID)
2746 {
2748 {
2749 /* we can't infer a range type from the others */
2750 ereport(ERROR,
2752 errmsg("could not determine polymorphic type %s because input has type %s",
2753 "anyrange", "unknown")));
2754 }
2756 }
2757 else if (decl_type == ANYMULTIRANGEOID)
2758 {
2760 {
2761 /* we can't infer a multirange type from the others */
2762 ereport(ERROR,
2764 errmsg("could not determine polymorphic type %s because input has type %s",
2765 "anymultirange", "unknown")));
2766 }
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 {
2785 ereport(ERROR,
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: */
2798 ereport(ERROR,
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: */
2810 ereport(ERROR,
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: */
2823 ereport(ERROR,
2825 errmsg_internal("could not identify anycompatible type")));
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: */
2834 ereport(ERROR,
2836 errmsg_internal("could not identify anycompatiblearray type")));
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: */
2845 ereport(ERROR,
2847 errmsg_internal("could not identify anycompatiblerange type")));
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: */
2856 ereport(ERROR,
2858 errmsg_internal("could not identify anycompatiblemultirange type")));
2860 }
2861
2862 /* we don't return a generic type; send back the original return type */
2863 return rettype;
2864}
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
Oid get_range_multirange(Oid rangeOid)
Definition lsyscache.c:3811
Oid get_array_type(Oid typid)
Definition lsyscache.c:3095

References Assert, ereport, errcode(), errdetail(), errmsg, errmsg_internal(), ERROR, fb(), format_type_be(), FUNC_MAX_ARGS, get_array_type(), get_element_type(), get_multirange_range(), get_range_multirange(), get_range_subtype(), getBaseType(), InvalidOid, j, OidIsValid, select_common_type_from_oids(), type_is_array_domain, type_is_enum(), and verify_common_type_from_oids().

Referenced by lookup_agg_function(), make_op(), make_scalar_array_op(), ParseFuncOrColumn(), recheck_cast_function_args(), and resolve_aggregate_transtype().

◆ find_coercion_pathway()

CoercionPathType find_coercion_pathway ( Oid  targetTypeId,
Oid  sourceTypeId,
CoercionContext  ccontext,
Oid funcid 
)

Definition at line 3157 of file parse_coerce.c.

3160{
3162 HeapTuple tuple;
3163
3164 *funcid = InvalidOid;
3165
3166 /* Perhaps the types are domains; if so, look at their base types */
3171
3172 /* Domains are always coercible to and from their base type */
3175
3176 /* Look in pg_cast */
3180
3181 if (HeapTupleIsValid(tuple))
3182 {
3184 CoercionContext castcontext;
3185
3186 /* convert char value for castcontext to CoercionContext enum */
3187 switch (castForm->castcontext)
3188 {
3190 castcontext = COERCION_IMPLICIT;
3191 break;
3193 castcontext = COERCION_ASSIGNMENT;
3194 break;
3196 castcontext = COERCION_EXPLICIT;
3197 break;
3198 default:
3199 elog(ERROR, "unrecognized castcontext: %d",
3200 (int) castForm->castcontext);
3201 castcontext = 0; /* keep compiler quiet */
3202 break;
3203 }
3204
3205 /* Rely on ordering of enum for correct behavior here */
3206 if (ccontext >= castcontext)
3207 {
3208 switch (castForm->castmethod)
3209 {
3212 *funcid = castForm->castfunc;
3213 break;
3216 break;
3219 break;
3220 default:
3221 elog(ERROR, "unrecognized castmethod: %d",
3222 (int) castForm->castmethod);
3223 break;
3224 }
3225 }
3226
3227 ReleaseSysCache(tuple);
3228 }
3229 else
3230 {
3231 /*
3232 * If there's no pg_cast entry, perhaps we are dealing with a pair of
3233 * array types. If so, and if their element types have a conversion
3234 * pathway, report that we can coerce with an ArrayCoerceExpr.
3235 *
3236 * Hack: disallow coercions to oidvector and int2vector, which
3237 * otherwise tend to capture coercions that should go to "real" array
3238 * types. We want those types to be considered "real" arrays for many
3239 * purposes, but not this one. (Also, ArrayCoerceExpr isn't
3240 * guaranteed to produce an output that meets the restrictions of
3241 * these datatypes, such as being 1-dimensional.)
3242 */
3244 {
3247
3250 {
3253
3255 sourceElem,
3256 ccontext,
3257 &elemfuncid);
3259 {
3261 }
3262 }
3263 }
3264
3265 /*
3266 * If we still haven't found a possibility, consider automatic casting
3267 * using I/O functions. We allow assignment casts to string types and
3268 * explicit casts from string types to be handled this way. (The
3269 * CoerceViaIO mechanism is a lot more general than that, but this is
3270 * all we want to allow in the absence of a pg_cast entry.) It would
3271 * probably be better to insist on explicit casts in both directions,
3272 * but this is a compromise to preserve something of the pre-8.3
3273 * behavior that many types had implicit (yipes!) casts to text.
3274 */
3276 {
3280 else if (ccontext >= COERCION_EXPLICIT &&
3283 }
3284 }
3285
3286 /*
3287 * When parsing PL/pgSQL assignments, allow an I/O cast to be used
3288 * whenever no normal coercion is available.
3289 */
3290 if (result == COERCION_PATH_NONE &&
3293
3294 return result;
3295}
TYPCATEGORY TypeCategory(Oid type)
END_CATALOG_STRUCT typedef FormData_pg_cast * Form_pg_cast
Definition pg_cast.h:61
CoercionContext
Definition primnodes.h:746
@ COERCION_PLPGSQL
Definition primnodes.h:749
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:231

References COERCION_ASSIGNMENT, COERCION_EXPLICIT, COERCION_IMPLICIT, COERCION_PATH_ARRAYCOERCE, COERCION_PATH_COERCEVIAIO, COERCION_PATH_FUNC, COERCION_PATH_NONE, COERCION_PATH_RELABELTYPE, COERCION_PLPGSQL, elog, ERROR, fb(), find_coercion_pathway(), Form_pg_cast, get_element_type(), getBaseType(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), OidIsValid, ReleaseSysCache(), result, SearchSysCache2(), and TypeCategory().

Referenced by can_coerce_type(), coerce_type(), find_coercion_pathway(), findFkeyCast(), func_get_detail(), json_categorize_type(), and ri_HashCompareOp().

◆ find_typmod_coercion_function()

CoercionPathType find_typmod_coercion_function ( Oid  typeId,
Oid funcid 
)

Definition at line 3320 of file parse_coerce.c.

3322{
3326 HeapTuple tuple;
3327
3328 *funcid = InvalidOid;
3330
3331 targetType = typeidType(typeId);
3333
3334 /* Check for a "true" array type */
3336 {
3337 /* Yes, switch our attention to the element type */
3338 typeId = typeForm->typelem;
3340 }
3342
3343 /* Look in pg_cast */
3345 ObjectIdGetDatum(typeId),
3346 ObjectIdGetDatum(typeId));
3347
3348 if (HeapTupleIsValid(tuple))
3349 {
3351
3352 *funcid = castForm->castfunc;
3353 ReleaseSysCache(tuple);
3354 }
3355
3356 if (!OidIsValid(*funcid))
3358
3359 return result;
3360}
END_CATALOG_STRUCT typedef FormData_pg_type * Form_pg_type
Definition pg_type.h:265

References COERCION_PATH_ARRAYCOERCE, COERCION_PATH_FUNC, COERCION_PATH_NONE, fb(), Form_pg_cast, Form_pg_type, GETSTRUCT(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), OidIsValid, ReleaseSysCache(), result, SearchSysCache2(), and typeidType().

Referenced by coerce_type_typmod().

◆ hide_coercion_node()

static void hide_coercion_node ( Node node)
static

Definition at line 810 of file parse_coerce.c.

811{
812 if (IsA(node, FuncExpr))
813 ((FuncExpr *) node)->funcformat = COERCE_IMPLICIT_CAST;
814 else if (IsA(node, RelabelType))
816 else if (IsA(node, CoerceViaIO))
818 else if (IsA(node, ArrayCoerceExpr))
820 else if (IsA(node, ConvertRowtypeExpr))
822 else if (IsA(node, RowExpr))
824 else if (IsA(node, CoerceToDomain))
826 else
827 elog(ERROR, "unsupported node type: %d", (int) nodeTag(node));
828}
#define nodeTag(nodeptr)
Definition nodes.h:139

References COERCE_IMPLICIT_CAST, elog, ERROR, fb(), IsA, and nodeTag.

Referenced by coerce_to_domain(), and coerce_type_typmod().

◆ is_complex_array()

static bool is_complex_array ( Oid  typid)
static

Definition at line 3370 of file parse_coerce.c.

3371{
3372 Oid elemtype = get_element_type(typid);
3373
3374 return (OidIsValid(elemtype) && ISCOMPLEX(elemtype));
3375}

References get_element_type(), ISCOMPLEX, and OidIsValid.

Referenced by can_coerce_type(), coerce_type(), and IsBinaryCoercibleWithCast().

◆ IsBinaryCoercible()

bool IsBinaryCoercible ( Oid  srctype,
Oid  targettype 
)

◆ IsBinaryCoercibleWithCast()

bool IsBinaryCoercibleWithCast ( Oid  srctype,
Oid  targettype,
Oid castoid 
)

Definition at line 3049 of file parse_coerce.c.

3051{
3052 HeapTuple tuple;
3054 bool result;
3055
3057
3058 /* Fast path if same type */
3059 if (srctype == targettype)
3060 return true;
3061
3062 /* Anything is coercible to ANY or ANYELEMENT or ANYCOMPATIBLE */
3063 if (targettype == ANYOID || targettype == ANYELEMENTOID ||
3064 targettype == ANYCOMPATIBLEOID)
3065 return true;
3066
3067 /* If srctype is a domain, reduce to its base type */
3068 if (OidIsValid(srctype))
3069 srctype = getBaseType(srctype);
3070
3071 /* Somewhat-fast path for domain -> base type case */
3072 if (srctype == targettype)
3073 return true;
3074
3075 /* Also accept any array type as coercible to ANY[COMPATIBLE]ARRAY */
3076 if (targettype == ANYARRAYOID || targettype == ANYCOMPATIBLEARRAYOID)
3077 if (type_is_array(srctype))
3078 return true;
3079
3080 /* Also accept any non-array type as coercible to ANY[COMPATIBLE]NONARRAY */
3081 if (targettype == ANYNONARRAYOID || targettype == ANYCOMPATIBLENONARRAYOID)
3082 if (!type_is_array(srctype))
3083 return true;
3084
3085 /* Also accept any enum type as coercible to ANYENUM */
3086 if (targettype == ANYENUMOID)
3087 if (type_is_enum(srctype))
3088 return true;
3089
3090 /* Also accept any range type as coercible to ANY[COMPATIBLE]RANGE */
3091 if (targettype == ANYRANGEOID || targettype == ANYCOMPATIBLERANGEOID)
3092 if (type_is_range(srctype))
3093 return true;
3094
3095 /* Also, any multirange type is coercible to ANY[COMPATIBLE]MULTIRANGE */
3096 if (targettype == ANYMULTIRANGEOID || targettype == ANYCOMPATIBLEMULTIRANGEOID)
3097 if (type_is_multirange(srctype))
3098 return true;
3099
3100 /* Also accept any composite type as coercible to RECORD */
3101 if (targettype == RECORDOID)
3102 if (ISCOMPLEX(srctype))
3103 return true;
3104
3105 /* Also accept any composite array type as coercible to RECORD[] */
3106 if (targettype == RECORDARRAYOID)
3107 if (is_complex_array(srctype))
3108 return true;
3109
3110 /* Else look in pg_cast */
3112 ObjectIdGetDatum(srctype),
3113 ObjectIdGetDatum(targettype));
3114 if (!HeapTupleIsValid(tuple))
3115 return false; /* no cast */
3116 castForm = (Form_pg_cast) GETSTRUCT(tuple);
3117
3118 result = (castForm->castmethod == COERCION_METHOD_BINARY &&
3119 castForm->castcontext == COERCION_CODE_IMPLICIT);
3120
3121 if (result)
3122 *castoid = castForm->oid;
3123
3124 ReleaseSysCache(tuple);
3125
3126 return result;
3127}
bool type_is_range(Oid typid)
Definition lsyscache.c:2996
bool type_is_multirange(Oid typid)
Definition lsyscache.c:3006
#define type_is_array(typid)
Definition lsyscache.h:223

References fb(), Form_pg_cast, getBaseType(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, is_complex_array(), ISCOMPLEX, ObjectIdGetDatum(), OidIsValid, ReleaseSysCache(), result, SearchSysCache2(), type_is_array, type_is_enum(), type_is_multirange(), and type_is_range().

Referenced by CreateCast(), and IsBinaryCoercible().

◆ IsPreferredType()

bool IsPreferredType ( TYPCATEGORY  category,
Oid  type 
)

Definition at line 2997 of file parse_coerce.c.

2998{
2999 char typcategory;
3000 bool typispreferred;
3001
3003 if (category == typcategory || category == TYPCATEGORY_INVALID)
3004 return typispreferred;
3005 else
3006 return false;
3007}
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition lsyscache.c:3018
const char * type

References fb(), get_type_category_preferred(), and type.

Referenced by func_select_candidate(), and GetDefaultOpClass().

◆ parser_coercion_errposition()

int parser_coercion_errposition ( ParseState pstate,
int  coerce_location,
Node input_expr 
)

Definition at line 1312 of file parse_coerce.c.

1315{
1316 if (coerce_location >= 0)
1317 return parser_errposition(pstate, coerce_location);
1318 else
1320}

References exprLocation(), fb(), and parser_errposition().

Referenced by coerce_record_to_complex(), coerceJsonFuncExpr(), and transformTypeCast().

◆ select_common_type()

Oid select_common_type ( ParseState pstate,
List exprs,
const char context,
Node **  which_expr 
)

Definition at line 1342 of file parse_coerce.c.

1344{
1345 Node *pexpr;
1346 Oid ptype;
1348 bool pispreferred;
1349 ListCell *lc;
1350
1351 Assert(exprs != NIL);
1352 pexpr = (Node *) linitial(exprs);
1353 lc = list_second_cell(exprs);
1354 ptype = exprType(pexpr);
1355
1356 /*
1357 * If all input types are valid and exactly the same, just pick that type.
1358 * This is the only way that we will resolve the result as being a domain
1359 * type; otherwise domains are smashed to their base types for comparison.
1360 */
1361 if (ptype != UNKNOWNOID)
1362 {
1363 for_each_cell(lc, exprs, lc)
1364 {
1365 Node *nexpr = (Node *) lfirst(lc);
1367
1368 if (ntype != ptype)
1369 break;
1370 }
1371 if (lc == NULL) /* got to the end of the list? */
1372 {
1373 if (which_expr)
1374 *which_expr = pexpr;
1375 return ptype;
1376 }
1377 }
1378
1379 /*
1380 * Nope, so set up for the full algorithm. Note that at this point, lc
1381 * points to the first list item with type different from pexpr's; we need
1382 * not re-examine any items the previous loop advanced over.
1383 */
1384 ptype = getBaseType(ptype);
1386
1387 for_each_cell(lc, exprs, lc)
1388 {
1389 Node *nexpr = (Node *) lfirst(lc);
1391
1392 /* move on to next one if no new information... */
1393 if (ntype != UNKNOWNOID && ntype != ptype)
1394 {
1396 bool nispreferred;
1397
1399 if (ptype == UNKNOWNOID)
1400 {
1401 /* so far, only unknowns so take anything... */
1402 pexpr = nexpr;
1403 ptype = ntype;
1406 }
1407 else if (ncategory != pcategory)
1408 {
1409 /*
1410 * both types in different categories? then not much hope...
1411 */
1412 if (context == NULL)
1413 return InvalidOid;
1414 ereport(ERROR,
1416 /*------
1417 translator: first %s is name of a SQL construct, eg CASE */
1418 errmsg("%s types %s and %s cannot be matched",
1419 context,
1420 format_type_be(ptype),
1423 }
1424 else if (!pispreferred &&
1425 can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
1427 {
1428 /*
1429 * take new type if can coerce to it implicitly but not the
1430 * other way; but if we have a preferred type, stay on it.
1431 */
1432 pexpr = nexpr;
1433 ptype = ntype;
1436 }
1437 }
1438 }
1439
1440 /*
1441 * If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
1442 * then resolve as type TEXT. This situation comes up with constructs
1443 * like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
1444 * UNION SELECT 'bar'; It might seem desirable to leave the construct's
1445 * output type as UNKNOWN, but that really doesn't work, because we'd
1446 * probably end up needing a runtime coercion from UNKNOWN to something
1447 * else, and we usually won't have it. We need to coerce the unknown
1448 * literals while they are still literals, so a decision has to be made
1449 * now.
1450 */
1451 if (ptype == UNKNOWNOID)
1452 ptype = TEXTOID;
1453
1454 if (which_expr)
1455 *which_expr = pexpr;
1456 return ptype;
1457}
char TYPCATEGORY
#define for_each_cell(cell, lst, initcell)
Definition pg_list.h:470
#define linitial(l)
Definition pg_list.h:178
static ListCell * list_second_cell(const List *l)
Definition pg_list.h:142

References Assert, can_coerce_type(), COERCION_IMPLICIT, ereport, errcode(), errmsg, ERROR, exprLocation(), exprType(), fb(), for_each_cell, format_type_be(), get_type_category_preferred(), getBaseType(), InvalidOid, lfirst, linitial, list_second_cell(), NIL, and parser_errposition().

Referenced by analyzeCTE(), buildMergedJoinVar(), constructSetOpTargetlist(), transformAExprIn(), transformArrayExpr(), transformCaseExpr(), transformCoalesceExpr(), transformMinMaxExpr(), transformValuesClause(), and unify_hypothetical_args().

◆ select_common_type_from_oids()

static Oid select_common_type_from_oids ( int  nargs,
const Oid typeids,
bool  noerror 
)
static

Definition at line 1478 of file parse_coerce.c.

1479{
1480 Oid ptype;
1482 bool pispreferred;
1483 int i = 1;
1484
1485 Assert(nargs > 0);
1486 ptype = typeids[0];
1487
1488 /* If all input types are valid and exactly the same, pick that type. */
1489 if (ptype != UNKNOWNOID)
1490 {
1491 for (; i < nargs; i++)
1492 {
1493 if (typeids[i] != ptype)
1494 break;
1495 }
1496 if (i == nargs)
1497 return ptype;
1498 }
1499
1500 /*
1501 * Nope, so set up for the full algorithm. Note that at this point, we
1502 * can skip array entries before "i"; they are all equal to ptype.
1503 */
1504 ptype = getBaseType(ptype);
1506
1507 for (; i < nargs; i++)
1508 {
1510
1511 /* move on to next one if no new information... */
1512 if (ntype != UNKNOWNOID && ntype != ptype)
1513 {
1515 bool nispreferred;
1516
1518 if (ptype == UNKNOWNOID)
1519 {
1520 /* so far, only unknowns so take anything... */
1521 ptype = ntype;
1524 }
1525 else if (ncategory != pcategory)
1526 {
1527 /*
1528 * both types in different categories? then not much hope...
1529 */
1530 if (noerror)
1531 return InvalidOid;
1532 ereport(ERROR,
1534 errmsg("argument types %s and %s cannot be matched",
1535 format_type_be(ptype),
1537 }
1538 else if (!pispreferred &&
1539 can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
1541 {
1542 /*
1543 * take new type if can coerce to it implicitly but not the
1544 * other way; but if we have a preferred type, stay on it.
1545 */
1546 ptype = ntype;
1549 }
1550 }
1551 }
1552
1553 /* Like select_common_type(), choose TEXT if all inputs were UNKNOWN */
1554 if (ptype == UNKNOWNOID)
1555 ptype = TEXTOID;
1556
1557 return ptype;
1558}

References Assert, can_coerce_type(), COERCION_IMPLICIT, ereport, errcode(), errmsg, ERROR, fb(), format_type_be(), get_type_category_preferred(), getBaseType(), i, and InvalidOid.

Referenced by check_generic_type_consistency(), and enforce_generic_type_consistency().

◆ select_common_typmod()

int32 select_common_typmod ( ParseState pstate,
List exprs,
Oid  common_type 
)

Definition at line 1644 of file parse_coerce.c.

1645{
1646 ListCell *lc;
1647 bool first = true;
1648 int32 result = -1;
1649
1650 foreach(lc, exprs)
1651 {
1652 Node *expr = (Node *) lfirst(lc);
1653
1654 /* Types must match */
1655 if (exprType(expr) != common_type)
1656 return -1;
1657 else if (first)
1658 {
1659 result = exprTypmod(expr);
1660 first = false;
1661 }
1662 else
1663 {
1664 /* As soon as we see a non-matching typmod, fall back to -1 */
1665 if (result != exprTypmod(expr))
1666 return -1;
1667 }
1668 }
1669
1670 return result;
1671}

References exprType(), exprTypmod(), fb(), lfirst, and result.

Referenced by analyzeCTE(), buildMergedJoinVar(), constructSetOpTargetlist(), transformValuesClause(), and unify_hypothetical_args().

◆ TypeCategory()

◆ typeIsOfTypedTable()

static bool typeIsOfTypedTable ( Oid  reltypeId,
Oid  reloftypeId 
)
static

Definition at line 3384 of file parse_coerce.c.

3385{
3387 bool result = false;
3388
3389 if (relid)
3390 {
3391 HeapTuple tp;
3393
3395 if (!HeapTupleIsValid(tp))
3396 elog(ERROR, "cache lookup failed for relation %u", relid);
3397
3399 if (reltup->reloftype == reloftypeId)
3400 result = true;
3401
3402 ReleaseSysCache(tp);
3403 }
3404
3405 return result;
3406}
Oid typeOrDomainTypeRelid(Oid type_id)
Definition parse_type.c:689
FormData_pg_class * Form_pg_class
Definition pg_class.h:160

References elog, ERROR, fb(), GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), result, SearchSysCache1(), and typeOrDomainTypeRelid().

Referenced by can_coerce_type(), and coerce_type().

◆ verify_common_type()

bool verify_common_type ( Oid  common_type,
List exprs 
)

Definition at line 1606 of file parse_coerce.c.

1607{
1608 ListCell *lc;
1609
1610 foreach(lc, exprs)
1611 {
1612 Node *nexpr = (Node *) lfirst(lc);
1614
1616 return false;
1617 }
1618 return true;
1619}

References can_coerce_type(), COERCION_IMPLICIT, exprType(), fb(), and lfirst.

Referenced by transformAExprIn().

◆ verify_common_type_from_oids()

static bool verify_common_type_from_oids ( Oid  common_type,
int  nargs,
const Oid typeids 
)
static

Definition at line 1626 of file parse_coerce.c.

1627{
1628 for (int i = 0; i < nargs; i++)
1629 {
1631 return false;
1632 }
1633 return true;
1634}

References can_coerce_type(), COERCION_IMPLICIT, fb(), and i.

Referenced by check_generic_type_consistency(), and enforce_generic_type_consistency().