88 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
89 errmsg(
"set-valued function called in context that cannot accept a set")));
93 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
94 errmsg(
"materialize mode required, but it is not allowed in this context")));
109 elog(
ERROR,
"return type must be a row type");
121 rsinfo->
setDesc = stored_tupdesc;
142 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
143 errmsg(
"set-valued function called in context that cannot accept a set")));
145 if (fcinfo->flinfo->fn_extra == NULL)
157 "SRF multi-call context",
180 fcinfo->flinfo->fn_extra = retval;
193 elog(
ERROR,
"init_MultiFuncCall cannot be called more than once");
318 ((
RowExpr *) expr)->row_typeid == RECORDOID)
344 *resultTypeId = rexpr->row_typeid;
349 else if (expr &&
IsA(expr,
Const) &&
350 ((
Const *) expr)->consttype == RECORDOID &&
351 !((
Const *) expr)->constisnull)
366 *resultTypeId = tupType;
367 if (tupType != RECORDOID || tupTypmod >= 0)
379 *resultTupleDesc = NULL;
390 *resultTypeId = typid;
392 *resultTupleDesc = NULL;
446 elog(
ERROR,
"cache lookup failed for function %u", funcid);
449 rettype = procform->prorettype;
461 *resultTypeId = rettype;
464 &procform->proargtypes,
467 if (tupdesc->
tdtypeid == RECORDOID &&
471 *resultTupleDesc = tupdesc;
477 *resultTupleDesc = NULL;
489 if (IsPolymorphicType(rettype))
495 (
errcode(ERRCODE_DATATYPE_MISMATCH),
496 errmsg(
"could not determine actual result type for function \"%s\" declared to return type %s",
499 rettype = newrettype;
503 *resultTypeId = rettype;
505 *resultTupleDesc = NULL;
566 if (exprTypeId != RECORDOID)
568 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
569 errmsg(
"type %s is not composite",
573 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
574 errmsg(
"record type has not been registered")));
599 (
errcode(ERRCODE_DATATYPE_MISMATCH),
600 errmsg(
"argument declared %s is not an array but type %s",
613 (
errcode(ERRCODE_DATATYPE_MISMATCH),
614 errmsg(
"argument declared %s is not a range type but type %s",
622 Oid multirange_base_type;
623 Oid multirange_typelem;
631 (
errcode(ERRCODE_DATATYPE_MISMATCH),
632 errmsg(
"argument declared %s is not a multirange type but type %s",
641 (
errcode(ERRCODE_DATATYPE_MISMATCH),
642 errmsg(
"argument declared %s does not contain a range type but type %s",
648 elog(
ERROR,
"could not determine polymorphic type");
668 (
errcode(ERRCODE_UNDEFINED_OBJECT),
669 errmsg(
"could not find array type for data type %s",
674 elog(
ERROR,
"could not determine polymorphic type");
696 (
errcode(ERRCODE_DATATYPE_MISMATCH),
697 errmsg(
"argument declared %s is not a multirange type but type %s",
703 elog(
ERROR,
"could not determine polymorphic type");
724 (
errcode(ERRCODE_UNDEFINED_OBJECT),
725 errmsg(
"could not find multirange type for data type %s",
730 elog(
ERROR,
"could not determine polymorphic type");
747 int natts = tupdesc->
natts;
748 int nargs = declared_args->
dim1;
749 bool have_polymorphic_result =
false;
750 bool have_anyelement_result =
false;
751 bool have_anyarray_result =
false;
752 bool have_anyrange_result =
false;
753 bool have_anymultirange_result =
false;
754 bool have_anycompatible_result =
false;
755 bool have_anycompatible_array_result =
false;
756 bool have_anycompatible_range_result =
false;
757 bool have_anycompatible_multirange_result =
false;
765 for (
i = 0;
i < natts;
i++)
772 have_polymorphic_result =
true;
773 have_anyelement_result =
true;
776 have_polymorphic_result =
true;
777 have_anyarray_result =
true;
780 have_polymorphic_result =
true;
781 have_anyrange_result =
true;
783 case ANYMULTIRANGEOID:
784 have_polymorphic_result =
true;
785 have_anymultirange_result =
true;
787 case ANYCOMPATIBLEOID:
788 case ANYCOMPATIBLENONARRAYOID:
789 have_polymorphic_result =
true;
790 have_anycompatible_result =
true;
792 case ANYCOMPATIBLEARRAYOID:
793 have_polymorphic_result =
true;
794 have_anycompatible_array_result =
true;
796 case ANYCOMPATIBLERANGEOID:
797 have_polymorphic_result =
true;
798 have_anycompatible_range_result =
true;
800 case ANYCOMPATIBLEMULTIRANGEOID:
801 have_polymorphic_result =
true;
802 have_anycompatible_multirange_result =
true;
808 if (!have_polymorphic_result)
821 memset(&poly_actuals, 0,
sizeof(poly_actuals));
822 memset(&anyc_actuals, 0,
sizeof(anyc_actuals));
824 for (
i = 0;
i < nargs;
i++)
826 switch (declared_args->
values[
i])
857 case ANYMULTIRANGEOID:
866 case ANYCOMPATIBLEOID:
867 case ANYCOMPATIBLENONARRAYOID:
876 case ANYCOMPATIBLEARRAYOID:
885 case ANYCOMPATIBLERANGEOID:
894 case ANYCOMPATIBLEMULTIRANGEOID:
962 anycollation = inputcollation;
964 anycompatcollation = inputcollation;
969 for (
i = 0;
i < natts;
i++)
973 switch (att->atttypid)
1001 case ANYMULTIRANGEOID:
1009 case ANYCOMPATIBLEOID:
1010 case ANYCOMPATIBLENONARRAYOID:
1018 case ANYCOMPATIBLEARRAYOID:
1026 case ANYCOMPATIBLERANGEOID:
1034 case ANYCOMPATIBLEMULTIRANGEOID:
1067 bool have_polymorphic_result =
false;
1068 bool have_anyelement_result =
false;
1069 bool have_anyarray_result =
false;
1070 bool have_anyrange_result =
false;
1071 bool have_anymultirange_result =
false;
1072 bool have_anycompatible_result =
false;
1073 bool have_anycompatible_array_result =
false;
1074 bool have_anycompatible_range_result =
false;
1075 bool have_anycompatible_multirange_result =
false;
1086 memset(&poly_actuals, 0,
sizeof(poly_actuals));
1087 memset(&anyc_actuals, 0,
sizeof(anyc_actuals));
1089 for (
i = 0;
i < numargs;
i++)
1091 char argmode = argmodes ? argmodes[
i] : PROARGMODE_IN;
1093 switch (argtypes[
i])
1096 case ANYNONARRAYOID:
1098 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1100 have_polymorphic_result =
true;
1101 have_anyelement_result =
true;
1116 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1118 have_polymorphic_result =
true;
1119 have_anyarray_result =
true;
1134 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1136 have_polymorphic_result =
true;
1137 have_anyrange_result =
true;
1151 case ANYMULTIRANGEOID:
1152 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1154 have_polymorphic_result =
true;
1155 have_anymultirange_result =
true;
1169 case ANYCOMPATIBLEOID:
1170 case ANYCOMPATIBLENONARRAYOID:
1171 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1173 have_polymorphic_result =
true;
1174 have_anycompatible_result =
true;
1188 case ANYCOMPATIBLEARRAYOID:
1189 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1191 have_polymorphic_result =
true;
1192 have_anycompatible_array_result =
true;
1206 case ANYCOMPATIBLERANGEOID:
1207 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1209 have_polymorphic_result =
true;
1210 have_anycompatible_range_result =
true;
1224 case ANYCOMPATIBLEMULTIRANGEOID:
1225 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1227 have_polymorphic_result =
true;
1228 have_anycompatible_multirange_result =
true;
1245 if (argmode != PROARGMODE_OUT && argmode != PROARGMODE_TABLE)
1250 if (!have_polymorphic_result)
1279 for (
i = 0;
i < numargs;
i++)
1281 switch (argtypes[
i])
1284 case ANYNONARRAYOID:
1294 case ANYMULTIRANGEOID:
1297 case ANYCOMPATIBLEOID:
1298 case ANYCOMPATIBLENONARRAYOID:
1301 case ANYCOMPATIBLEARRAYOID:
1304 case ANYCOMPATIBLERANGEOID:
1307 case ANYCOMPATIBLEMULTIRANGEOID:
1330 *base_typeid = typid;
1334 case TYPTYPE_COMPOSITE:
1339 case TYPTYPE_MULTIRANGE:
1341 case TYPTYPE_DOMAIN:
1347 case TYPTYPE_PSEUDO:
1348 if (typid == RECORDOID)
1357 if (typid == VOIDOID || typid == CSTRINGOID)
1380 Oid **p_argtypes,
char ***p_argnames,
char **p_argmodes)
1383 Datum proallargtypes;
1395 Anum_pg_proc_proallargtypes,
1411 elog(
ERROR,
"proallargtypes is not a 1-D Oid array or it contains nulls");
1412 Assert(numargs >= procStruct->pronargs);
1415 numargs *
sizeof(
Oid));
1420 numargs = procStruct->proargtypes.dim1;
1421 Assert(numargs == procStruct->pronargs);
1423 memcpy(*p_argtypes, procStruct->proargtypes.values,
1424 numargs *
sizeof(
Oid));
1429 Anum_pg_proc_proargnames,
1436 &elems, NULL, &nelems);
1437 if (nelems != numargs)
1438 elog(
ERROR,
"proargnames must have the same number of elements as the function has arguments");
1439 *p_argnames = (
char **)
palloc(
sizeof(
char *) * numargs);
1440 for (
i = 0;
i < numargs;
i++)
1446 Anum_pg_proc_proargmodes,
1457 elog(
ERROR,
"proargmodes is not a 1-D char array of length %d or it contains nulls",
1459 *p_argmodes = (
char *)
palloc(numargs *
sizeof(
char));
1461 numargs *
sizeof(
char));
1484 Anum_pg_proc_protrftypes,
1500 elog(
ERROR,
"protrftypes is not a 1-D Oid array or it contains nulls");
1503 nelems *
sizeof(
Oid));
1549 elog(
ERROR,
"proargnames is not a 1-D text array or it contains nulls");
1558 elog(
ERROR,
"proargmodes is not a 1-D char array of length %d or it contains nulls",
1573 inargnames = (
char **)
palloc(numargs *
sizeof(
char *));
1575 for (
i = 0;
i < numargs;
i++)
1577 if (argmodes == NULL ||
1578 argmodes[
i] == PROARGMODE_IN ||
1579 argmodes[
i] == PROARGMODE_INOUT ||
1580 argmodes[
i] == PROARGMODE_VARIADIC)
1584 if (pname[0] !=
'\0')
1585 inargnames[numinargs] = pname;
1587 inargnames[numinargs] = NULL;
1592 *arg_names = inargnames;
1624 elog(
ERROR,
"cache lookup failed for function %u", functionId);
1634 Anum_pg_proc_proargmodes);
1636 Anum_pg_proc_proargnames);
1650 elog(
ERROR,
"proargmodes is not a 1-D char array or it contains nulls");
1657 elog(
ERROR,
"proargnames is not a 1-D text array of length %d or it contains nulls",
1660 Assert(nargnames == numargs);
1665 for (
i = 0;
i < numargs;
i++)
1667 if (argmodes[
i] == PROARGMODE_IN ||
1668 argmodes[
i] == PROARGMODE_VARIADIC)
1670 Assert(argmodes[
i] == PROARGMODE_OUT ||
1671 argmodes[
i] == PROARGMODE_INOUT ||
1672 argmodes[
i] == PROARGMODE_TABLE);
1673 if (++numoutargs > 1)
1680 if (result == NULL || result[0] ==
'\0')
1708 Datum proallargtypes;
1714 if (procform->prorettype != RECORDOID)
1718 if (
heap_attisnull(procTuple, Anum_pg_proc_proallargtypes, NULL) ||
1724 Anum_pg_proc_proallargtypes);
1726 Anum_pg_proc_proargmodes);
1728 Anum_pg_proc_proargnames,
1752 Datum proallargtypes,
1761 Datum *argnames = NULL;
1784 elog(
ERROR,
"proallargtypes is not a 1-D Oid array or it contains nulls");
1791 elog(
ERROR,
"proargmodes is not a 1-D char array of length %d or it contains nulls",
1801 elog(
ERROR,
"proargnames is not a 1-D text array of length %d or it contains nulls",
1804 Assert(nargnames == numargs);
1813 outargnames = (
char **)
palloc(numargs *
sizeof(
char *));
1815 for (
i = 0;
i < numargs;
i++)
1819 if (argmodes[
i] == PROARGMODE_IN ||
1820 argmodes[
i] == PROARGMODE_VARIADIC)
1822 Assert(argmodes[
i] == PROARGMODE_OUT ||
1823 argmodes[
i] == PROARGMODE_INOUT ||
1824 argmodes[
i] == PROARGMODE_TABLE);
1825 outargtypes[numoutargs] = argtypes[
i];
1830 if (pname == NULL || pname[0] ==
'\0')
1833 pname =
psprintf(
"column%d", numoutargs + 1);
1835 outargnames[numoutargs] = pname;
1843 if (numoutargs < 2 && prokind != PROKIND_PROCEDURE)
1847 for (
i = 0;
i < numoutargs;
i++)
1920 if (colaliases !=
NIL)
1922 int natts = tupdesc->
natts;
1928 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1929 errmsg(
"number of aliases does not match number of columns")));
1932 for (varattno = 0; varattno < natts; varattno++)
1952 if (colaliases ==
NIL)
1954 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1955 errmsg(
"no column alias was provided")));
1960 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1961 errmsg(
"number of aliases does not match number of columns")));
1978 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1979 errmsg(
"could not determine row description for function returning record")));
1984 elog(
ERROR,
"function in FROM has unsupported return type");
2044 for (
i = 0;
i < nargs;
i++)
2045 types_res[
i] = element_type;
2049 nargs =
PG_NARGS() - variadic_start;
2051 nulls_res = (
bool *)
palloc0(nargs *
sizeof(
bool));
2055 for (
i = 0;
i < nargs;
i++)
2059 i + variadic_start);
2068 if (convert_unknown &&
2069 types_res[
i] == UNKNOWNOID &&
2072 types_res[
i] = TEXTOID;
2087 (convert_unknown && types_res[
i] == UNKNOWNOID))
2089 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2090 errmsg(
"could not determine data type for argument %d",
#define PG_GETARG_ARRAYTYPE_P(n)
#define DatumGetArrayTypeP(X)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Datum array_in(PG_FUNCTION_ARGS)
#define CStringGetTextDatum(s)
#define TextDatumGetCString(d)
#define Assert(condition)
#define OidIsValid(objectId)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
@ SFRM_Materialize_Random
bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Oid get_call_expr_argtype(Node *expr, int argnum)
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
#define DatumGetHeapTupleHeader(X)
#define PG_GETARG_POINTER(n)
#define PG_GETARG_DATUM(n)
static TypeFuncClass get_type_func_class(Oid typid, Oid *base_typeid)
struct polymorphic_actuals polymorphic_actuals
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
static TypeFuncClass internal_get_result_type(Oid funcid, Node *call_expr, ReturnSetInfo *rsinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
int get_func_trftypes(HeapTuple procTup, Oid **p_trftypes)
TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple)
TupleDesc build_function_result_tupdesc_d(char prokind, Datum proallargtypes, Datum proargmodes, Datum proargnames)
bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr)
char * get_func_result_name(Oid functionId)
void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
static void resolve_anyelement_from_others(polymorphic_actuals *actuals)
int get_func_input_arg_names(Datum proargnames, Datum proargmodes, char ***arg_names)
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
static bool resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, Node *call_expr)
TupleDesc RelationNameGetTupleDesc(const char *relname)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
FuncCallContext * init_MultiFuncCall(PG_FUNCTION_ARGS)
static void resolve_anyrange_from_others(polymorphic_actuals *actuals)
static void shutdown_MultiFuncCall(Datum arg)
TupleDesc get_expr_result_tupdesc(Node *expr, bool noError)
static void resolve_anymultirange_from_others(polymorphic_actuals *actuals)
TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)
TypeFuncClass get_func_result_type(Oid functionId, Oid *resultTypeId, TupleDesc *resultTupleDesc)
static void resolve_anyarray_from_others(polymorphic_actuals *actuals)
TypeFuncClass get_expr_result_type(Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
FuncCallContext * per_MultiFuncCall(PG_FUNCTION_ARGS)
@ TYPEFUNC_COMPOSITE_DOMAIN
#define MAT_SRF_USE_EXPECTED_DESC
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
#define HeapTupleIsValid(tuple)
#define HeapTupleHeaderGetTypMod(tup)
#define HeapTupleHeaderGetTypeId(tup)
if(TABLE==NULL||TABLE_index==NULL)
Oid get_range_subtype(Oid rangeOid)
Oid get_element_type(Oid typid)
Oid get_multirange_range(Oid multirangeOid)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
RegProcedure get_opcode(Oid opno)
Oid get_typcollation(Oid typid)
Oid get_range_multirange(Oid rangeOid)
char get_typtype(Oid typid)
Oid getBaseType(Oid typid)
Oid get_array_type(Oid typid)
void * palloc0(Size size)
void * MemoryContextAllocZero(MemoryContext context, Size size)
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
void namestrcpy(Name name, const char *str)
RangeVar * makeRangeVarFromNameList(const List *names)
Oid exprType(const Node *expr)
Oid exprInputCollation(const Node *expr)
int32 exprTypmod(const Node *expr)
Oid exprCollation(const Node *expr)
#define IsA(nodeptr, _type_)
FormData_pg_attribute * Form_pg_attribute
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
static void * list_nth(const List *list, int n)
FormData_pg_proc * Form_pg_proc
static Datum PointerGetDatum(const void *X)
static Datum ObjectIdGetDatum(Oid X)
static Pointer DatumGetPointer(Datum X)
char * psprintf(const char *fmt,...)
MemoryContextSwitchTo(old_ctx)
List * stringToQualifiedNameList(const char *string, Node *escontext)
#define RelationGetDescr(relation)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
MemoryContext ecxt_per_query_memory
AttInMetadata * attinmeta
MemoryContext multi_call_memory_ctx
SetFunctionReturnMode returnMode
Tuplestorestate * setResult
Oid values[FLEXIBLE_ARRAY_MEMBER]
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
TupleDesc CreateTemplateTupleDesc(int natts)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
#define TupleDescAttr(tupdesc, i)
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
void assign_record_type_typmod(TupleDesc tupDesc)
TupleDesc lookup_rowtype_tupdesc_copy(Oid type_id, int32 typmod)