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");
311 ((
RowExpr *) expr)->row_typeid == RECORDOID)
337 *resultTypeId = rexpr->row_typeid;
342 else if (expr &&
IsA(expr,
Const) &&
343 ((
Const *) expr)->consttype == RECORDOID &&
344 !((
Const *) expr)->constisnull)
359 *resultTypeId = tupType;
360 if (tupType != RECORDOID || tupTypmod >= 0)
372 *resultTupleDesc = NULL;
383 *resultTypeId = typid;
385 *resultTupleDesc = NULL;
439 elog(
ERROR,
"cache lookup failed for function %u", funcid);
442 rettype = procform->prorettype;
454 *resultTypeId = rettype;
457 &procform->proargtypes,
460 if (tupdesc->
tdtypeid == RECORDOID &&
464 *resultTupleDesc = tupdesc;
470 *resultTupleDesc = NULL;
482 if (IsPolymorphicType(rettype))
488 (
errcode(ERRCODE_DATATYPE_MISMATCH),
489 errmsg(
"could not determine actual result type for function \"%s\" declared to return type %s",
492 rettype = newrettype;
496 *resultTypeId = rettype;
498 *resultTupleDesc = NULL;
558 if (exprTypeId != RECORDOID)
560 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
561 errmsg(
"type %s is not composite",
565 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
566 errmsg(
"record type has not been registered")));
591 (
errcode(ERRCODE_DATATYPE_MISMATCH),
592 errmsg(
"argument declared %s is not an array but type %s",
605 (
errcode(ERRCODE_DATATYPE_MISMATCH),
606 errmsg(
"argument declared %s is not a range type but type %s",
614 Oid multirange_base_type;
615 Oid multirange_typelem;
623 (
errcode(ERRCODE_DATATYPE_MISMATCH),
624 errmsg(
"argument declared %s is not a multirange type but type %s",
633 (
errcode(ERRCODE_DATATYPE_MISMATCH),
634 errmsg(
"argument declared %s does not contain a range type but type %s",
640 elog(
ERROR,
"could not determine polymorphic type");
660 (
errcode(ERRCODE_UNDEFINED_OBJECT),
661 errmsg(
"could not find array type for data type %s",
666 elog(
ERROR,
"could not determine polymorphic type");
688 (
errcode(ERRCODE_DATATYPE_MISMATCH),
689 errmsg(
"argument declared %s is not a multirange type but type %s",
695 elog(
ERROR,
"could not determine polymorphic type");
716 (
errcode(ERRCODE_UNDEFINED_OBJECT),
717 errmsg(
"could not find multirange type for data type %s",
722 elog(
ERROR,
"could not determine polymorphic type");
739 int natts = tupdesc->
natts;
740 int nargs = declared_args->
dim1;
741 bool have_polymorphic_result =
false;
742 bool have_anyelement_result =
false;
743 bool have_anyarray_result =
false;
744 bool have_anyrange_result =
false;
745 bool have_anymultirange_result =
false;
746 bool have_anycompatible_result =
false;
747 bool have_anycompatible_array_result =
false;
748 bool have_anycompatible_range_result =
false;
749 bool have_anycompatible_multirange_result =
false;
757 for (
i = 0;
i < natts;
i++)
764 have_polymorphic_result =
true;
765 have_anyelement_result =
true;
768 have_polymorphic_result =
true;
769 have_anyarray_result =
true;
772 have_polymorphic_result =
true;
773 have_anyrange_result =
true;
775 case ANYMULTIRANGEOID:
776 have_polymorphic_result =
true;
777 have_anymultirange_result =
true;
779 case ANYCOMPATIBLEOID:
780 case ANYCOMPATIBLENONARRAYOID:
781 have_polymorphic_result =
true;
782 have_anycompatible_result =
true;
784 case ANYCOMPATIBLEARRAYOID:
785 have_polymorphic_result =
true;
786 have_anycompatible_array_result =
true;
788 case ANYCOMPATIBLERANGEOID:
789 have_polymorphic_result =
true;
790 have_anycompatible_range_result =
true;
792 case ANYCOMPATIBLEMULTIRANGEOID:
793 have_polymorphic_result =
true;
794 have_anycompatible_multirange_result =
true;
800 if (!have_polymorphic_result)
813 memset(&poly_actuals, 0,
sizeof(poly_actuals));
814 memset(&anyc_actuals, 0,
sizeof(anyc_actuals));
816 for (
i = 0;
i < nargs;
i++)
818 switch (declared_args->
values[
i])
849 case ANYMULTIRANGEOID:
858 case ANYCOMPATIBLEOID:
859 case ANYCOMPATIBLENONARRAYOID:
868 case ANYCOMPATIBLEARRAYOID:
877 case ANYCOMPATIBLERANGEOID:
886 case ANYCOMPATIBLEMULTIRANGEOID:
954 anycollation = inputcollation;
956 anycompatcollation = inputcollation;
961 for (
i = 0;
i < natts;
i++)
965 switch (att->atttypid)
993 case ANYMULTIRANGEOID:
1001 case ANYCOMPATIBLEOID:
1002 case ANYCOMPATIBLENONARRAYOID:
1010 case ANYCOMPATIBLEARRAYOID:
1018 case ANYCOMPATIBLERANGEOID:
1026 case ANYCOMPATIBLEMULTIRANGEOID:
1059 bool have_polymorphic_result =
false;
1060 bool have_anyelement_result =
false;
1061 bool have_anyarray_result =
false;
1062 bool have_anyrange_result =
false;
1063 bool have_anymultirange_result =
false;
1064 bool have_anycompatible_result =
false;
1065 bool have_anycompatible_array_result =
false;
1066 bool have_anycompatible_range_result =
false;
1067 bool have_anycompatible_multirange_result =
false;
1078 memset(&poly_actuals, 0,
sizeof(poly_actuals));
1079 memset(&anyc_actuals, 0,
sizeof(anyc_actuals));
1081 for (
i = 0;
i < numargs;
i++)
1083 char argmode = argmodes ? argmodes[
i] : PROARGMODE_IN;
1085 switch (argtypes[
i])
1088 case ANYNONARRAYOID:
1090 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1092 have_polymorphic_result =
true;
1093 have_anyelement_result =
true;
1108 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1110 have_polymorphic_result =
true;
1111 have_anyarray_result =
true;
1126 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1128 have_polymorphic_result =
true;
1129 have_anyrange_result =
true;
1143 case ANYMULTIRANGEOID:
1144 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1146 have_polymorphic_result =
true;
1147 have_anymultirange_result =
true;
1161 case ANYCOMPATIBLEOID:
1162 case ANYCOMPATIBLENONARRAYOID:
1163 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1165 have_polymorphic_result =
true;
1166 have_anycompatible_result =
true;
1180 case ANYCOMPATIBLEARRAYOID:
1181 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1183 have_polymorphic_result =
true;
1184 have_anycompatible_array_result =
true;
1198 case ANYCOMPATIBLERANGEOID:
1199 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1201 have_polymorphic_result =
true;
1202 have_anycompatible_range_result =
true;
1216 case ANYCOMPATIBLEMULTIRANGEOID:
1217 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
1219 have_polymorphic_result =
true;
1220 have_anycompatible_multirange_result =
true;
1237 if (argmode != PROARGMODE_OUT && argmode != PROARGMODE_TABLE)
1242 if (!have_polymorphic_result)
1271 for (
i = 0;
i < numargs;
i++)
1273 switch (argtypes[
i])
1276 case ANYNONARRAYOID:
1286 case ANYMULTIRANGEOID:
1289 case ANYCOMPATIBLEOID:
1290 case ANYCOMPATIBLENONARRAYOID:
1293 case ANYCOMPATIBLEARRAYOID:
1296 case ANYCOMPATIBLERANGEOID:
1299 case ANYCOMPATIBLEMULTIRANGEOID:
1322 *base_typeid = typid;
1326 case TYPTYPE_COMPOSITE:
1331 case TYPTYPE_MULTIRANGE:
1333 case TYPTYPE_DOMAIN:
1339 case TYPTYPE_PSEUDO:
1340 if (typid == RECORDOID)
1349 if (typid == VOIDOID || typid == CSTRINGOID)
1372 Oid **p_argtypes,
char ***p_argnames,
char **p_argmodes)
1375 Datum proallargtypes;
1387 Anum_pg_proc_proallargtypes,
1403 elog(
ERROR,
"proallargtypes is not a 1-D Oid array or it contains nulls");
1404 Assert(numargs >= procStruct->pronargs);
1407 numargs *
sizeof(
Oid));
1412 numargs = procStruct->proargtypes.dim1;
1413 Assert(numargs == procStruct->pronargs);
1415 memcpy(*p_argtypes, procStruct->proargtypes.values,
1416 numargs *
sizeof(
Oid));
1421 Anum_pg_proc_proargnames,
1428 &elems, NULL, &nelems);
1429 if (nelems != numargs)
1430 elog(
ERROR,
"proargnames must have the same number of elements as the function has arguments");
1431 *p_argnames = (
char **)
palloc(
sizeof(
char *) * numargs);
1432 for (
i = 0;
i < numargs;
i++)
1438 Anum_pg_proc_proargmodes,
1449 elog(
ERROR,
"proargmodes is not a 1-D char array of length %d or it contains nulls",
1451 *p_argmodes = (
char *)
palloc(numargs *
sizeof(
char));
1453 numargs *
sizeof(
char));
1476 Anum_pg_proc_protrftypes,
1492 elog(
ERROR,
"protrftypes is not a 1-D Oid array or it contains nulls");
1495 nelems *
sizeof(
Oid));
1541 elog(
ERROR,
"proargnames is not a 1-D text array or it contains nulls");
1550 elog(
ERROR,
"proargmodes is not a 1-D char array of length %d or it contains nulls",
1565 inargnames = (
char **)
palloc(numargs *
sizeof(
char *));
1567 for (
i = 0;
i < numargs;
i++)
1569 if (argmodes == NULL ||
1570 argmodes[
i] == PROARGMODE_IN ||
1571 argmodes[
i] == PROARGMODE_INOUT ||
1572 argmodes[
i] == PROARGMODE_VARIADIC)
1576 if (pname[0] !=
'\0')
1577 inargnames[numinargs] = pname;
1579 inargnames[numinargs] = NULL;
1584 *arg_names = inargnames;
1616 elog(
ERROR,
"cache lookup failed for function %u", functionId);
1626 Anum_pg_proc_proargmodes);
1628 Anum_pg_proc_proargnames);
1642 elog(
ERROR,
"proargmodes is not a 1-D char array or it contains nulls");
1649 elog(
ERROR,
"proargnames is not a 1-D text array of length %d or it contains nulls",
1652 Assert(nargnames == numargs);
1657 for (
i = 0;
i < numargs;
i++)
1659 if (argmodes[
i] == PROARGMODE_IN ||
1660 argmodes[
i] == PROARGMODE_VARIADIC)
1662 Assert(argmodes[
i] == PROARGMODE_OUT ||
1663 argmodes[
i] == PROARGMODE_INOUT ||
1664 argmodes[
i] == PROARGMODE_TABLE);
1665 if (++numoutargs > 1)
1672 if (result == NULL || result[0] ==
'\0')
1700 Datum proallargtypes;
1706 if (procform->prorettype != RECORDOID)
1710 if (
heap_attisnull(procTuple, Anum_pg_proc_proallargtypes, NULL) ||
1716 Anum_pg_proc_proallargtypes);
1718 Anum_pg_proc_proargmodes);
1720 Anum_pg_proc_proargnames,
1744 Datum proallargtypes,
1753 Datum *argnames = NULL;
1776 elog(
ERROR,
"proallargtypes is not a 1-D Oid array or it contains nulls");
1783 elog(
ERROR,
"proargmodes is not a 1-D char array of length %d or it contains nulls",
1793 elog(
ERROR,
"proargnames is not a 1-D text array of length %d or it contains nulls",
1796 Assert(nargnames == numargs);
1805 outargnames = (
char **)
palloc(numargs *
sizeof(
char *));
1807 for (
i = 0;
i < numargs;
i++)
1811 if (argmodes[
i] == PROARGMODE_IN ||
1812 argmodes[
i] == PROARGMODE_VARIADIC)
1814 Assert(argmodes[
i] == PROARGMODE_OUT ||
1815 argmodes[
i] == PROARGMODE_INOUT ||
1816 argmodes[
i] == PROARGMODE_TABLE);
1817 outargtypes[numoutargs] = argtypes[
i];
1822 if (pname == NULL || pname[0] ==
'\0')
1825 pname =
psprintf(
"column%d", numoutargs + 1);
1827 outargnames[numoutargs] = pname;
1835 if (numoutargs < 2 && prokind != PROKIND_PROCEDURE)
1839 for (
i = 0;
i < numoutargs;
i++)
1912 if (colaliases !=
NIL)
1914 int natts = tupdesc->
natts;
1920 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1921 errmsg(
"number of aliases does not match number of columns")));
1924 for (varattno = 0; varattno < natts; varattno++)
1944 if (colaliases ==
NIL)
1946 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1947 errmsg(
"no column alias was provided")));
1952 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1953 errmsg(
"number of aliases does not match number of columns")));
1970 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1971 errmsg(
"could not determine row description for function returning record")));
1976 elog(
ERROR,
"function in FROM has unsupported return type");
2036 for (
i = 0;
i < nargs;
i++)
2037 types_res[
i] = element_type;
2041 nargs =
PG_NARGS() - variadic_start;
2043 nulls_res = (
bool *)
palloc0(nargs *
sizeof(
bool));
2047 for (
i = 0;
i < nargs;
i++)
2051 i + variadic_start);
2060 if (convert_unknown &&
2061 types_res[
i] == UNKNOWNOID &&
2064 types_res[
i] = TEXTOID;
2079 (convert_unknown && types_res[
i] == UNKNOWNOID))
2081 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2082 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 OidIsValid(objectId)
elog(ERROR, "%s: %s", p2, msg)
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)
Assert(fmt[strlen(fmt) - 1] !='\n')
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_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
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,...)
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)