in src/tleextension.c [186:286]
static Oid get_required_extension(char *reqExtensionName,
char *extensionName,
char *origSchemaName,
bool cascade,
List *parents,
bool is_create);
static Oid get_tlefunc_oid_if_exists(const char *funcname);
static void get_available_versions_for_extension(ExtensionControlFile *pcontrol,
Tuplestorestate *tupstore,
TupleDesc tupdesc);
static Datum convert_requires_to_datum(List *requires);
static void ApplyExtensionUpdates(Oid extensionOid,
ExtensionControlFile *pcontrol,
const char *initialVersion,
List *updateVersions,
char *origSchemaName,
bool cascade,
bool is_create);
static char *read_whole_file(const char *filename, int *length);
static void pg_tle_xact_callback(XactEvent event, void *arg);
static List *textarray_to_stringlist(ArrayType *textarray);
static bool validate_tle_sql(char *sql);
static void check_requires_list(List *requires);
static bool is_pgtle_defined_c_func(Oid funcid, bool *is_operator_func);
static bool is_pgtle_used_user_func(Oid funcid, bool *is_operator_func);
static void check_pgtle_used_func(Oid funcid);
static void available_extensions_before_1_5_0(ReturnSetInfo *rsinfo,
char *fname);
static void available_extensions_on_or_after_1_5_0(ReturnSetInfo *rsinfo,
char *fname);
#if PG_VERSION_NUM < 150001
/* flag bits for InitMaterializedSRF() */
#define MAT_SRF_USE_EXPECTED_DESC 0x01 /* use expectedDesc as tupdesc. */
#define MAT_SRF_BLESS 0x02 /* "Bless" a tuple descriptor with
* BlessTupleDesc(). */
/*
* InitMaterializedSRF
*
* Helper function to build the state of a set-returning function used
* in the context of a single call with materialize mode. This code
* includes sanity checks on ReturnSetInfo, creates the Tuplestore and
* the TupleDesc used with the function and stores them into the
* function's ReturnSetInfo.
*
* "flags" can be set to MAT_SRF_USE_EXPECTED_DESC, to use the tuple
* descriptor coming from expectedDesc, which is the tuple descriptor
* expected by the caller. MAT_SRF_BLESS can be set to complete the
* information associated to the tuple descriptor, which is necessary
* in some cases where the tuple descriptor comes from a transient
* RECORD datatype.
*/
static void
InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
{
bool random_access;
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
Tuplestorestate *tupstore;
MemoryContext old_context,
per_query_ctx;
TupleDesc stored_tupdesc;
/* check to see if caller supports returning a tuplestore */
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("set-valued function called in context that cannot accept a set")));
if (!(rsinfo->allowedModes & SFRM_Materialize) ||
((flags & MAT_SRF_USE_EXPECTED_DESC) != 0 && rsinfo->expectedDesc == NULL))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("materialize mode required, but it is not allowed in this context")));
/*
* Store the tuplestore and the tuple descriptor in ReturnSetInfo. This
* must be done in the per-query memory context.
*/
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
old_context = MemoryContextSwitchTo(per_query_ctx);
/* build a tuple descriptor for our result type */
if ((flags & MAT_SRF_USE_EXPECTED_DESC) != 0)
stored_tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);
else
{
if (get_call_result_type(fcinfo, NULL, &stored_tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
}
/* If requested, bless the tuple descriptor */
if ((flags & MAT_SRF_BLESS) != 0)
BlessTupleDesc(stored_tupdesc);
random_access = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0;
tupstore = tuplestore_begin_heap(random_access, false, work_mem);
rsinfo->returnMode = SFRM_Materialize;
rsinfo->setResult = tupstore;
rsinfo->setDesc = stored_tupdesc;
MemoryContextSwitchTo(old_context);
}