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:873
int32_t int32
Definition c.h:542
#define OidIsValid(objectId)
Definition c.h:788
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#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:2909
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition lsyscache.c:2688
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:301
#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:212
FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:136
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
#define InvalidOid
unsigned int Oid
static int fb(int x)
@ COERCION_EXPLICIT
Definition primnodes.h:749
ParseLoc location
Definition primnodes.h:1247
Definition pg_list.h:54
Definition nodes.h:135
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition syscache.c:220

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(), 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(), select_common_type(), select_common_type_from_oids(), 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 1738 of file parse_coerce.c.

1741{
1751 bool have_anynonarray = false;
1752 bool have_anyenum = false;
1753 bool have_anycompatible_nonarray = false;
1754 int n_anycompatible_args = 0;
1756
1757 /*
1758 * Loop through the arguments to see if we have any that are polymorphic.
1759 * If so, require the actual types to be consistent.
1760 */
1761 Assert(nargs <= FUNC_MAX_ARGS);
1762 for (int j = 0; j < nargs; j++)
1763 {
1766
1767 if (decl_type == ANYELEMENTOID ||
1770 {
1772 have_anynonarray = true;
1773 else if (decl_type == ANYENUMOID)
1774 have_anyenum = true;
1775 if (actual_type == UNKNOWNOID)
1776 continue;
1778 return false;
1780 }
1781 else if (decl_type == ANYARRAYOID)
1782 {
1783 if (actual_type == UNKNOWNOID)
1784 continue;
1785 actual_type = getBaseType(actual_type); /* flatten domains */
1787 return false;
1789 }
1790 else if (decl_type == ANYRANGEOID)
1791 {
1792 if (actual_type == UNKNOWNOID)
1793 continue;
1794 actual_type = getBaseType(actual_type); /* flatten domains */
1796 return false;
1798 }
1799 else if (decl_type == ANYMULTIRANGEOID)
1800 {
1801 if (actual_type == UNKNOWNOID)
1802 continue;
1803 actual_type = getBaseType(actual_type); /* flatten domains */
1805 return false;
1807 }
1808 else if (decl_type == ANYCOMPATIBLEOID ||
1810 {
1813 if (actual_type == UNKNOWNOID)
1814 continue;
1815 /* collect the actual types of non-unknown COMPATIBLE args */
1817 }
1818 else if (decl_type == ANYCOMPATIBLEARRAYOID)
1819 {
1820 Oid elem_type;
1821
1822 if (actual_type == UNKNOWNOID)
1823 continue;
1824 actual_type = getBaseType(actual_type); /* flatten domains */
1826 if (!OidIsValid(elem_type))
1827 return false; /* not an array */
1828 /* collect the element type for common-supertype choice */
1830 }
1831 else if (decl_type == ANYCOMPATIBLERANGEOID)
1832 {
1833 if (actual_type == UNKNOWNOID)
1834 continue;
1835 actual_type = getBaseType(actual_type); /* flatten domains */
1837 {
1838 /* All ANYCOMPATIBLERANGE arguments must be the same type */
1840 return false;
1841 }
1842 else
1843 {
1847 return false; /* not a range type */
1848 /* collect the subtype for common-supertype choice */
1850 }
1851 }
1853 {
1854 if (actual_type == UNKNOWNOID)
1855 continue;
1856 actual_type = getBaseType(actual_type); /* flatten domains */
1858 {
1859 /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */
1861 return false;
1862 }
1863 else
1864 {
1868 return false; /* not a multirange type */
1869 /* we'll consider the subtype below */
1870 }
1871 }
1872 }
1873
1874 /* Get the element type based on the array type, if we have one */
1876 {
1878 {
1879 /*
1880 * Special case for matching ANYARRAY input to an ANYARRAY
1881 * argument: allow it for now. enforce_generic_type_consistency()
1882 * might complain later, depending on the presence of other
1883 * polymorphic arguments or results, but it will deliver a less
1884 * surprising error message than "function does not exist".
1885 *
1886 * (If you think to change this, note that can_coerce_type will
1887 * consider such a situation as a match, so that we might not even
1888 * get here.)
1889 */
1890 }
1891 else
1892 {
1894
1897 return false; /* should be an array, but isn't */
1898
1899 if (!OidIsValid(elem_typeid))
1900 {
1901 /*
1902 * if we don't have an element type yet, use the one we just
1903 * got
1904 */
1906 }
1907 else if (array_typelem != elem_typeid)
1908 {
1909 /* otherwise, they better match */
1910 return false;
1911 }
1912 }
1913 }
1914
1915 /* Deduce range type from multirange type, or check that they agree */
1917 {
1919
1922 return false; /* should be a multirange, but isn't */
1923
1925 {
1926 /* If we don't have a range type yet, use the one we just got */
1930 return false; /* should be a range, but isn't */
1931 }
1932 else if (multirange_typelem != range_typeid)
1933 {
1934 /* otherwise, they better match */
1935 return false;
1936 }
1937 }
1938
1939 /* Get the element type based on the range type, if we have one */
1941 {
1944 return false; /* should be a range, but isn't */
1945
1946 if (!OidIsValid(elem_typeid))
1947 {
1948 /*
1949 * If we don't have an element type yet, use the one we just got
1950 */
1952 }
1953 else if (range_typelem != elem_typeid)
1954 {
1955 /* otherwise, they better match */
1956 return false;
1957 }
1958 }
1959
1960 if (have_anynonarray)
1961 {
1962 /* require the element type to not be an array or domain over array */
1964 return false;
1965 }
1966
1967 if (have_anyenum)
1968 {
1969 /* require the element type to be an enum */
1971 return false;
1972 }
1973
1974 /* Deduce range type from multirange type, or check that they agree */
1976 {
1978 {
1981 return false;
1982 }
1983 else
1984 {
1988 return false; /* not a range type */
1989 /* collect the subtype for common-supertype choice */
1992 }
1993 }
1994
1995 /* Check matching of ANYCOMPATIBLE-family arguments, if any */
1996 if (n_anycompatible_args > 0)
1997 {
1999
2003 true);
2004
2006 return false; /* there's definitely no common supertype */
2007
2008 /* We have to verify that the selected type actually works */
2012 return false;
2013
2015 {
2016 /*
2017 * require the anycompatible type to not be an array or domain
2018 * over array
2019 */
2021 return false;
2022 }
2023
2024 /*
2025 * The anycompatible type must exactly match the range element type,
2026 * if we were able to identify one. This checks compatibility for
2027 * anycompatiblemultirange too since that also sets
2028 * anycompatible_range_typelem above.
2029 */
2032 return false;
2033 }
2034
2035 /* Looks valid */
2036 return true;
2037}
int j
Definition isn.c:78
Oid get_range_subtype(Oid rangeOid)
Definition lsyscache.c:3557
bool type_is_enum(Oid typid)
Definition lsyscache.c:2828
Oid get_multirange_range(Oid multirangeOid)
Definition lsyscache.c:3633
Oid getBaseType(Oid typid)
Definition lsyscache.c:2671
#define type_is_array_domain(typid)
Definition lsyscache.h:216
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 2953 of file parse_coerce.c.

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

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 2876 of file parse_coerce.c.

2879{
2881 {
2882 /*
2883 * ANYRANGE and ANYMULTIRANGE require an ANYRANGE or ANYMULTIRANGE
2884 * input, else we can't tell which of several range types with the
2885 * same element type to use.
2886 */
2887 for (int i = 0; i < nargs; i++)
2888 {
2891 return NULL; /* OK */
2892 }
2893 return psprintf(_("A result of type %s requires at least one input of type anyrange or anymultirange."),
2895 }
2897 {
2898 /*
2899 * ANYCOMPATIBLERANGE and ANYCOMPATIBLEMULTIRANGE require an
2900 * ANYCOMPATIBLERANGE or ANYCOMPATIBLEMULTIRANGE input, else we can't
2901 * tell which of several range types with the same element type to
2902 * use.
2903 */
2904 for (int i = 0; i < nargs; i++)
2905 {
2908 return NULL; /* OK */
2909 }
2910 return psprintf(_("A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange."),
2912 }
2914 {
2915 /* Otherwise, any family-1 type can be deduced from any other */
2916 for (int i = 0; i < nargs; i++)
2917 {
2919 return NULL; /* OK */
2920 }
2921 /* Keep this list in sync with IsPolymorphicTypeFamily1! */
2922 return psprintf(_("A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange."),
2924 }
2926 {
2927 /* Otherwise, any family-2 type can be deduced from any other */
2928 for (int i = 0; i < nargs; i++)
2929 {
2931 return NULL; /* OK */
2932 }
2933 /* Keep this list in sync with IsPolymorphicTypeFamily2! */
2934 return psprintf(_("A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, anycompatiblerange, or anycompatiblemultirange."),
2936 }
2937 else
2938 return NULL; /* OK, ret_type is not polymorphic */
2939}
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 1272 of file parse_coerce.c.

1274{
1275 Node *result;
1277 int32 baseTypeMod = typmod;
1278
1279 /*
1280 * The constant must appear to have the domain's base type/typmod, else
1281 * coerce_to_domain() will apply a length coercion which is useless.
1282 */
1284 result = (Node *) makeConst(baseTypeId,
1286 collation,
1287 typlen,
1288 (Datum) 0,
1289 true, /* isnull */
1290 typbyval);
1291 if (typid != baseTypeId)
1292 result = coerce_to_domain(result,
1294 typid,
1297 -1,
1298 false);
1299 return result;
1300}
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:768
@ COERCION_IMPLICIT
Definition primnodes.h:746

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

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 int rtindex = ((Var *) node)->varno;
1039 int sublevels_up = ((Var *) node)->varlevelsup;
1040 int vlocation = ((Var *) node)->location;
1042
1043 nsitem = GetNSItemByRangeTablePosn(pstate, rtindex, sublevels_up);
1044 args = expandNSItemVars(pstate, nsitem, sublevels_up, vlocation, NULL);
1045 }
1046 else
1047 ereport(ERROR,
1049 errmsg("cannot cast type %s to %s",
1052 parser_coercion_errposition(pstate, location, node)));
1053
1054 /*
1055 * Look up the composite type, accounting for possibility that what we are
1056 * given is a domain over composite.
1057 */
1060
1061 /* Process the fields */
1062 newargs = NIL;
1063 ucolno = 1;
1064 arg = list_head(args);
1065 for (i = 0; i < tupdesc->natts; i++)
1066 {
1067 Node *expr;
1068 Node *cexpr;
1069 Oid exprtype;
1070 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
1071
1072 /* Fill in NULLs for dropped columns in rowtype */
1073 if (attr->attisdropped)
1074 {
1075 /*
1076 * can't use atttypid here, but it doesn't really matter what type
1077 * the Const claims to be.
1078 */
1081 continue;
1082 }
1083
1084 if (arg == NULL)
1085 ereport(ERROR,
1087 errmsg("cannot cast type %s to %s",
1090 errdetail("Input has too few columns."),
1091 parser_coercion_errposition(pstate, location, node)));
1092 expr = (Node *) lfirst(arg);
1093 exprtype = exprType(expr);
1094
1095 cexpr = coerce_to_target_type(pstate,
1096 expr, exprtype,
1097 attr->atttypid,
1098 attr->atttypmod,
1099 ccontext,
1101 -1);
1102 if (cexpr == NULL)
1103 ereport(ERROR,
1105 errmsg("cannot cast type %s to %s",
1108 errdetail("Cannot cast type %s to %s in column %d.",
1109 format_type_be(exprtype),
1110 format_type_be(attr->atttypid),
1111 ucolno),
1112 parser_coercion_errposition(pstate, location, expr)));
1113 newargs = lappend(newargs, cexpr);
1114 ucolno++;
1115 arg = lnext(args, arg);
1116 }
1117 if (arg != NULL)
1118 ereport(ERROR,
1120 errmsg("cannot cast type %s to %s",
1123 errdetail("Input has too many columns."),
1124 parser_coercion_errposition(pstate, location, node)));
1125
1126 ReleaseTupleDesc(tupdesc);
1127
1128 rowexpr = makeNode(RowExpr);
1129 rowexpr->args = newargs;
1130 rowexpr->row_typeid = baseTypeId;
1131 rowexpr->row_format = cformat;
1132 rowexpr->colnames = NIL; /* not needed for named target type */
1133 rowexpr->location = location;
1134
1135 /* If target is a domain, apply constraints */
1136 if (baseTypeId != targetTypeId)
1137 {
1138 rowexpr->row_format = COERCE_IMPLICIT_CAST;
1139 return coerce_to_domain((Node *) rowexpr,
1142 ccontext, cformat, location,
1143 false);
1144 }
1145
1146 return (Node *) rowexpr;
1147}
#define InvalidAttrNumber
Definition attnum.h:23
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ereport(elevel,...)
Definition elog.h:150
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Definition makefuncs.c:388
#define IsA(nodeptr, _type_)
Definition nodes.h:164
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 * GetNSItemByRangeTablePosn(ParseState *pstate, int varno, int sublevels_up)
FormData_pg_attribute * Form_pg_attribute
void * arg
#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:343
List * args
Definition primnodes.h:1448
ParseLoc location
Definition primnodes.h:1472
#define ReleaseTupleDesc(tupdesc)
Definition tupdesc.h:219
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:160
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition typcache.c:1921

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(), GetNSItemByRangeTablePosn(), i, InvalidAttrNumber, InvalidOid, IsA, lappend(), lfirst, list_head(), lnext(), RowExpr::location, lookup_rowtype_tupdesc(), makeNode, makeNullConst(), TupleDescData::natts, NIL, parser_coercion_errposition(), ReleaseTupleDesc, and TupleDescAttr().

Referenced by coerce_type().

◆ coerce_to_boolean()

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

Definition at line 1160 of file parse_coerce.c.

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

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 1573 of file parse_coerce.c.

1575{
1576 Oid inputTypeId = exprType(node);
1577
1579 return node; /* no work */
1581 node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
1583 else
1584 ereport(ERROR,
1586 /* translator: first %s is name of a SQL construct, eg CASE */
1587 errmsg("%s could not convert type %s to %s",
1588 context,
1591 parser_errposition(pstate, exprLocation(node))));
1592 return node;
1593}
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(), generate_setop_tlist(), transformAExprIn(), transformArrayExpr(), transformCaseExpr(), transformCoalesceExpr(), transformMinMaxExpr(), transformSetOperationTree(), 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{
680 CoerceToDomain *result;
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 */
715 result = makeNode(CoerceToDomain);
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)
ParseLoc location
Definition primnodes.h:2061

References arg, CoerceToDomain::arg, Assert, COERCE_IMPLICIT_CAST, coerce_type_typmod(), fb(), hide_coercion_node(), CoerceToDomain::location, makeNode, OidIsValid, and CoerceToDomain::resulttype.

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 1256 of file parse_coerce.c.

1259{
1260 return coerce_to_specific_type_typmod(pstate, node,
1261 targetTypeId, -1,
1263}
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 1207 of file parse_coerce.c.

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

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 */
114 result = coerce_type_typmod(result,
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 */
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:3231

References arg, can_coerce_type(), coerce_type(), coerce_type_typmod(), fb(), IsA, makeNode, 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. */
363 result = coerce_to_domain(result,
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 */
442 result = coerce_to_domain(result, baseTypeId, baseTypeMod,
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 */
470 RelabelType *r = makeRelabelType((Expr *) result,
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:36
#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 Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static char * DatumGetCString(Datum X)
Definition postgres.h:365
CoerceParamHook p_coerce_param_hook
Definition parse_node.h:241
ParseLoc location
Definition primnodes.h:1225

References ConvertRowtypeExpr::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, DatumGetCString(), datumIsEqual(), elog, ERROR, fb(), find_coercion_pathway(), format_type_be(), getBaseType(), getBaseTypeAndTypmod(), InvalidOid, is_complex_array(), IsA, ISCOMPLEX, RelabelType::location, ConvertRowtypeExpr::location, makeNode, makeRelabelType(), ParseState::p_coerce_param_hook, PG_DETOAST_DATUM, PointerGetDatum(), ReleaseSysCache(), 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(), 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:821
Node * applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
Definition nodeFuncs.c:636
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 2132 of file parse_coerce.c.

2137{
2138 bool have_poly_anycompatible = false;
2139 bool have_poly_unknowns = false;
2150 bool have_anynonarray = (rettype == ANYNONARRAYOID);
2151 bool have_anyenum = (rettype == ANYENUMOID);
2152 bool have_anymultirange = (rettype == ANYMULTIRANGEOID);
2157 int n_poly_args = 0; /* this counts all family-1 arguments */
2158 int n_anycompatible_args = 0; /* this counts only non-unknowns */
2160
2161 /*
2162 * Loop through the arguments to see if we have any that are polymorphic.
2163 * If so, require the actual types to be consistent.
2164 */
2165 Assert(nargs <= FUNC_MAX_ARGS);
2166 for (int j = 0; j < nargs; j++)
2167 {
2170
2171 if (decl_type == ANYELEMENTOID ||
2174 {
2175 n_poly_args++;
2177 have_anynonarray = true;
2178 else if (decl_type == ANYENUMOID)
2179 have_anyenum = true;
2180 if (actual_type == UNKNOWNOID)
2181 {
2182 have_poly_unknowns = true;
2183 continue;
2184 }
2186 continue; /* no new information here */
2188 ereport(ERROR,
2190 errmsg("arguments declared \"%s\" are not all alike", "anyelement"),
2191 errdetail("%s versus %s",
2195 }
2196 else if (decl_type == ANYARRAYOID)
2197 {
2198 n_poly_args++;
2199 if (actual_type == UNKNOWNOID)
2200 {
2201 have_poly_unknowns = true;
2202 continue;
2203 }
2205 continue; /* no new information here */
2206 actual_type = getBaseType(actual_type); /* flatten domains */
2208 ereport(ERROR,
2210 errmsg("arguments declared \"%s\" are not all alike", "anyarray"),
2211 errdetail("%s versus %s",
2215 }
2216 else if (decl_type == ANYRANGEOID)
2217 {
2218 n_poly_args++;
2219 if (actual_type == UNKNOWNOID)
2220 {
2221 have_poly_unknowns = true;
2222 continue;
2223 }
2225 continue; /* no new information here */
2226 actual_type = getBaseType(actual_type); /* flatten domains */
2228 ereport(ERROR,
2230 errmsg("arguments declared \"%s\" are not all alike", "anyrange"),
2231 errdetail("%s versus %s",
2235 }
2236 else if (decl_type == ANYMULTIRANGEOID)
2237 {
2238 n_poly_args++;
2239 have_anymultirange = true;
2240 if (actual_type == UNKNOWNOID)
2241 {
2242 have_poly_unknowns = true;
2243 continue;
2244 }
2246 continue; /* no new information here */
2247 actual_type = getBaseType(actual_type); /* flatten domains */
2249 ereport(ERROR,
2251 errmsg("arguments declared \"%s\" are not all alike", "anymultirange"),
2252 errdetail("%s versus %s",
2256 }
2257 else if (decl_type == ANYCOMPATIBLEOID ||
2259 {
2263 if (actual_type == UNKNOWNOID)
2264 continue;
2266 continue; /* no new information here */
2267 /* collect the actual types of non-unknown COMPATIBLE args */
2269 }
2270 else if (decl_type == ANYCOMPATIBLEARRAYOID)
2271 {
2273
2276 if (actual_type == UNKNOWNOID)
2277 continue;
2279 continue; /* no new information here */
2280 actual_type = getBaseType(actual_type); /* flatten domains */
2283 ereport(ERROR,
2285 errmsg("argument declared %s is not an array but type %s",
2286 "anycompatiblearray",
2288 /* collect the element type for common-supertype choice */
2290 }
2291 else if (decl_type == ANYCOMPATIBLERANGEOID)
2292 {
2295 if (actual_type == UNKNOWNOID)
2296 continue;
2298 continue; /* no new information here */
2299 actual_type = getBaseType(actual_type); /* flatten domains */
2301 {
2302 /* All ANYCOMPATIBLERANGE arguments must be the same type */
2304 ereport(ERROR,
2306 errmsg("arguments declared \"%s\" are not all alike", "anycompatiblerange"),
2307 errdetail("%s versus %s",
2310 }
2311 else
2312 {
2316 ereport(ERROR,
2318 errmsg("argument declared %s is not a range type but type %s",
2319 "anycompatiblerange",
2321 /* collect the subtype for common-supertype choice */
2323 }
2324 }
2326 {
2329 if (actual_type == UNKNOWNOID)
2330 continue;
2332 continue; /* no new information here */
2333 actual_type = getBaseType(actual_type); /* flatten domains */
2335 {
2336 /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */
2338 ereport(ERROR,
2340 errmsg("arguments declared \"%s\" are not all alike", "anycompatiblemultirange"),
2341 errdetail("%s versus %s",
2344 }
2345 else
2346 {
2350 ereport(ERROR,
2352 errmsg("argument declared %s is not a multirange type but type %s",
2353 "anycompatiblemultirange",
2355 /* we'll consider the subtype below */
2356 }
2357 }
2358 }
2359
2360 /*
2361 * Fast Track: if none of the arguments are polymorphic, return the
2362 * unmodified rettype. Not our job to resolve it if it's polymorphic.
2363 */
2365 return rettype;
2366
2367 /* Check matching of family-1 polymorphic arguments, if any */
2368 if (n_poly_args)
2369 {
2370 /* Get the element type based on the array type, if we have one */
2372 {
2374
2376 {
2377 /*
2378 * Special case for matching ANYARRAY input to an ANYARRAY
2379 * argument: allow it iff no other arguments are family-1
2380 * polymorphics (otherwise we couldn't be sure whether the
2381 * array element type matches up) and the result type doesn't
2382 * require us to infer a specific element type.
2383 */
2384 if (n_poly_args != 1 ||
2385 (rettype != ANYARRAYOID &&
2386 IsPolymorphicTypeFamily1(rettype)))
2387 ereport(ERROR,
2389 errmsg("cannot determine element type of \"anyarray\" argument")));
2391 }
2392 else
2393 {
2396 ereport(ERROR,
2398 errmsg("argument declared %s is not an array but type %s",
2399 "anyarray", format_type_be(array_typeid))));
2400 }
2401
2402 if (!OidIsValid(elem_typeid))
2403 {
2404 /*
2405 * if we don't have an element type yet, use the one we just
2406 * got
2407 */
2409 }
2410 else if (array_typelem != elem_typeid)
2411 {
2412 /* otherwise, they better match */
2413 ereport(ERROR,
2415 errmsg("argument declared %s is not consistent with argument declared %s",
2416 "anyarray", "anyelement"),
2417 errdetail("%s versus %s",
2420 }
2421 }
2422
2423 /* Deduce range type from multirange type, or vice versa */
2425 {
2427
2430 ereport(ERROR,
2432 errmsg("argument declared %s is not a multirange type but type %s",
2433 "anymultirange",
2435
2437 {
2438 /* if we don't have a range type yet, use the one we just got */
2440 }
2441 else if (multirange_typelem != range_typeid)
2442 {
2443 /* otherwise, they better match */
2444 ereport(ERROR,
2446 errmsg("argument declared %s is not consistent with argument declared %s",
2447 "anymultirange", "anyrange"),
2448 errdetail("%s versus %s",
2451 }
2452 }
2454 {
2456 /* We'll complain below if that didn't work */
2457 }
2458
2459 /* Get the element type based on the range type, if we have one */
2461 {
2463
2466 ereport(ERROR,
2468 errmsg("argument declared %s is not a range type but type %s",
2469 "anyrange",
2471
2472 if (!OidIsValid(elem_typeid))
2473 {
2474 /*
2475 * if we don't have an element type yet, use the one we just
2476 * got
2477 */
2479 }
2480 else if (range_typelem != elem_typeid)
2481 {
2482 /* otherwise, they better match */
2483 ereport(ERROR,
2485 errmsg("argument declared %s is not consistent with argument declared %s",
2486 "anyrange", "anyelement"),
2487 errdetail("%s versus %s",
2490 }
2491 }
2492
2493 if (!OidIsValid(elem_typeid))
2494 {
2495 if (allow_poly)
2496 {
2501 }
2502 else
2503 {
2504 /*
2505 * Only way to get here is if all the family-1 polymorphic
2506 * arguments have UNKNOWN inputs.
2507 */
2508 ereport(ERROR,
2510 errmsg("could not determine polymorphic type because input has type %s",
2511 "unknown")));
2512 }
2513 }
2514
2516 {
2517 /*
2518 * require the element type to not be an array or domain over
2519 * array
2520 */
2522 ereport(ERROR,
2524 errmsg("type matched to anynonarray is an array type: %s",
2526 }
2527
2529 {
2530 /* require the element type to be an enum */
2532 ereport(ERROR,
2534 errmsg("type matched to anyenum is not an enum type: %s",
2536 }
2537 }
2538
2539 /* Check matching of family-2 polymorphic arguments, if any */
2541 {
2542 /* Deduce range type from multirange type, or vice versa */
2544 {
2546 {
2549 ereport(ERROR,
2551 errmsg("argument declared %s is not consistent with argument declared %s",
2552 "anycompatiblemultirange",
2553 "anycompatiblerange"),
2554 errdetail("%s versus %s",
2557 }
2558 else
2559 {
2563 ereport(ERROR,
2565 errmsg("argument declared %s is not a multirange type but type %s",
2566 "anycompatiblemultirange",
2568 /* this enables element type matching check below */
2570 /* collect the subtype for common-supertype choice */
2573 }
2574 }
2577 {
2579 /* We'll complain below if that didn't work */
2580 }
2581
2582 if (n_anycompatible_args > 0)
2583 {
2587 false);
2588
2589 /* We have to verify that the selected type actually works */
2593 ereport(ERROR,
2595 errmsg("arguments of anycompatible family cannot be cast to a common type")));
2596
2598 {
2601 ereport(ERROR,
2603 errmsg("could not find array type for data type %s",
2605 }
2606
2608 {
2609 /* we can't infer a range type from the others */
2611 ereport(ERROR,
2613 errmsg("could not determine polymorphic type %s because input has type %s",
2614 "anycompatiblerange", "unknown")));
2615
2616 /*
2617 * the anycompatible type must exactly match the range element
2618 * type
2619 */
2621 ereport(ERROR,
2623 errmsg("anycompatiblerange type %s does not match anycompatible type %s",
2626 }
2627
2629 {
2630 /* we can't infer a multirange type from the others */
2632 ereport(ERROR,
2634 errmsg("could not determine polymorphic type %s because input has type %s",
2635 "anycompatiblemultirange", "unknown")));
2636
2637 /*
2638 * the anycompatible type must exactly match the multirange
2639 * element type
2640 */
2642 ereport(ERROR,
2644 errmsg("anycompatiblemultirange type %s does not match anycompatible type %s",
2647 }
2648
2650 {
2651 /*
2652 * require the element type to not be an array or domain over
2653 * array
2654 */
2656 ereport(ERROR,
2658 errmsg("type matched to anycompatiblenonarray is an array type: %s",
2660 }
2661 }
2662 else
2663 {
2664 if (allow_poly)
2665 {
2670 }
2671 else
2672 {
2673 /*
2674 * Only way to get here is if all the family-2 polymorphic
2675 * arguments have UNKNOWN inputs. Resolve to TEXT as
2676 * select_common_type() would do. That doesn't license us to
2677 * use TEXTRANGE or TEXTMULTIRANGE, though.
2678 */
2682 ereport(ERROR,
2684 errmsg("could not determine polymorphic type %s because input has type %s",
2685 "anycompatiblerange", "unknown")));
2687 ereport(ERROR,
2689 errmsg("could not determine polymorphic type %s because input has type %s",
2690 "anycompatiblemultirange", "unknown")));
2691 }
2692 }
2693
2694 /* replace family-2 polymorphic types by selected types */
2695 for (int j = 0; j < nargs; j++)
2696 {
2698
2699 if (decl_type == ANYCOMPATIBLEOID ||
2702 else if (decl_type == ANYCOMPATIBLEARRAYOID)
2704 else if (decl_type == ANYCOMPATIBLERANGEOID)
2708 }
2709 }
2710
2711 /*
2712 * If we had any UNKNOWN inputs for family-1 polymorphic arguments,
2713 * re-scan to assign correct types to them.
2714 *
2715 * Note: we don't have to consider unknown inputs that were matched to
2716 * family-2 polymorphic arguments, because we forcibly updated their
2717 * declared_arg_types[] positions just above.
2718 */
2720 {
2721 for (int j = 0; j < nargs; j++)
2722 {
2725
2726 if (actual_type != UNKNOWNOID)
2727 continue;
2728
2729 if (decl_type == ANYELEMENTOID ||
2733 else if (decl_type == ANYARRAYOID)
2734 {
2736 {
2739 ereport(ERROR,
2741 errmsg("could not find array type for data type %s",
2743 }
2745 }
2746 else if (decl_type == ANYRANGEOID)
2747 {
2749 {
2750 /* we can't infer a range type from the others */
2751 ereport(ERROR,
2753 errmsg("could not determine polymorphic type %s because input has type %s",
2754 "anyrange", "unknown")));
2755 }
2757 }
2758 else if (decl_type == ANYMULTIRANGEOID)
2759 {
2761 {
2762 /* we can't infer a multirange type from the others */
2763 ereport(ERROR,
2765 errmsg("could not determine polymorphic type %s because input has type %s",
2766 "anymultirange", "unknown")));
2767 }
2769 }
2770 }
2771 }
2772
2773 /* if we return ANYELEMENT use the appropriate argument type */
2774 if (rettype == ANYELEMENTOID ||
2775 rettype == ANYNONARRAYOID ||
2776 rettype == ANYENUMOID)
2777 return elem_typeid;
2778
2779 /* if we return ANYARRAY use the appropriate argument type */
2780 if (rettype == ANYARRAYOID)
2781 {
2783 {
2786 ereport(ERROR,
2788 errmsg("could not find array type for data type %s",
2790 }
2791 return array_typeid;
2792 }
2793
2794 /* if we return ANYRANGE use the appropriate argument type */
2795 if (rettype == ANYRANGEOID)
2796 {
2797 /* this error is unreachable if the function signature is valid: */
2799 ereport(ERROR,
2801 errmsg_internal("could not determine polymorphic type %s because input has type %s",
2802 "anyrange", "unknown")));
2803 return range_typeid;
2804 }
2805
2806 /* if we return ANYMULTIRANGE use the appropriate argument type */
2807 if (rettype == ANYMULTIRANGEOID)
2808 {
2809 /* this error is unreachable if the function signature is valid: */
2811 ereport(ERROR,
2813 errmsg_internal("could not determine polymorphic type %s because input has type %s",
2814 "anymultirange", "unknown")));
2815 return multirange_typeid;
2816 }
2817
2818 /* if we return ANYCOMPATIBLE use the appropriate type */
2819 if (rettype == ANYCOMPATIBLEOID ||
2820 rettype == ANYCOMPATIBLENONARRAYOID)
2821 {
2822 /* this error is unreachable if the function signature is valid: */
2824 ereport(ERROR,
2826 errmsg_internal("could not identify anycompatible type")));
2827 return anycompatible_typeid;
2828 }
2829
2830 /* if we return ANYCOMPATIBLEARRAY use the appropriate type */
2831 if (rettype == ANYCOMPATIBLEARRAYOID)
2832 {
2833 /* this error is unreachable if the function signature is valid: */
2835 ereport(ERROR,
2837 errmsg_internal("could not identify anycompatiblearray type")));
2839 }
2840
2841 /* if we return ANYCOMPATIBLERANGE use the appropriate argument type */
2842 if (rettype == ANYCOMPATIBLERANGEOID)
2843 {
2844 /* this error is unreachable if the function signature is valid: */
2846 ereport(ERROR,
2848 errmsg_internal("could not identify anycompatiblerange type")));
2850 }
2851
2852 /* if we return ANYCOMPATIBLEMULTIRANGE use the appropriate argument type */
2853 if (rettype == ANYCOMPATIBLEMULTIRANGEOID)
2854 {
2855 /* this error is unreachable if the function signature is valid: */
2857 ereport(ERROR,
2859 errmsg_internal("could not identify anycompatiblemultirange type")));
2861 }
2862
2863 /* we don't return a generic type; send back the original return type */
2864 return rettype;
2865}
int errmsg_internal(const char *fmt,...)
Definition elog.c:1170
Oid get_range_multirange(Oid rangeOid)
Definition lsyscache.c:3608
Oid get_array_type(Oid typid)
Definition lsyscache.c:2937

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 3154 of file parse_coerce.c.

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

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(), get_element_type(), getBaseType(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), OidIsValid, ReleaseSysCache(), 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 3317 of file parse_coerce.c.

3319{
3320 CoercionPathType result;
3323 HeapTuple tuple;
3324
3325 *funcid = InvalidOid;
3326 result = COERCION_PATH_FUNC;
3327
3328 targetType = typeidType(typeId);
3330
3331 /* Check for a "true" array type */
3333 {
3334 /* Yes, switch our attention to the element type */
3335 typeId = typeForm->typelem;
3337 }
3339
3340 /* Look in pg_cast */
3342 ObjectIdGetDatum(typeId),
3343 ObjectIdGetDatum(typeId));
3344
3345 if (HeapTupleIsValid(tuple))
3346 {
3348
3349 *funcid = castForm->castfunc;
3350 ReleaseSysCache(tuple);
3351 }
3352
3353 if (!OidIsValid(*funcid))
3354 result = COERCION_PATH_NONE;
3355
3356 return result;
3357}
FormData_pg_type * Form_pg_type
Definition pg_type.h:261

References COERCION_PATH_ARRAYCOERCE, COERCION_PATH_FUNC, COERCION_PATH_NONE, fb(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), OidIsValid, ReleaseSysCache(), 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 3367 of file parse_coerce.c.

3368{
3369 Oid elemtype = get_element_type(typid);
3370
3371 return (OidIsValid(elemtype) && ISCOMPLEX(elemtype));
3372}

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 3046 of file parse_coerce.c.

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

References fb(), getBaseType(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, is_complex_array(), ISCOMPLEX, ObjectIdGetDatum(), OidIsValid, ReleaseSysCache(), 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 2996 of file parse_coerce.c.

2997{
2998 char typcategory;
2999 bool typispreferred;
3000
3002 if (category == typcategory || category == TYPCATEGORY_INVALID)
3003 return typispreferred;
3004 else
3005 return false;
3006}
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition lsyscache.c:2860
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 1313 of file parse_coerce.c.

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

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 1343 of file parse_coerce.c.

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

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

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 1645 of file parse_coerce.c.

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

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

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

◆ TypeCategory()

◆ typeIsOfTypedTable()

static bool typeIsOfTypedTable ( Oid  reltypeId,
Oid  reloftypeId 
)
static

Definition at line 3381 of file parse_coerce.c.

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

References elog, ERROR, fb(), GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), 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 1607 of file parse_coerce.c.

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

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 1627 of file parse_coerce.c.

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

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

Referenced by check_generic_type_consistency(), and enforce_generic_type_consistency().