PG_FUNCTION_INFO_V1(pg_old_snapshot_time_mapping);
static OldSnapshotTimeMapping *GetOldSnapshotTimeMapping(void);
-static TupleDesc MakeOldSnapshotTimeMappingTupleDesc(void);
static HeapTuple MakeOldSnapshotTimeMappingTuple(TupleDesc tupdesc,
OldSnapshotTimeMapping *mapping);
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcontext;
+ TupleDesc tupdesc;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
mapping = GetOldSnapshotTimeMapping();
funcctx->user_fctx = mapping;
- funcctx->tuple_desc = MakeOldSnapshotTimeMappingTupleDesc();
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+ funcctx->tuple_desc = tupdesc;
MemoryContextSwitchTo(oldcontext);
}
return mapping;
}
-/*
- * Build a tuple descriptor for the pg_old_snapshot_time_mapping() SRF.
- */
-static TupleDesc
-MakeOldSnapshotTimeMappingTupleDesc(void)
-{
- TupleDesc tupdesc;
-
- tupdesc = CreateTemplateTupleDesc(NUM_TIME_MAPPING_COLUMNS);
-
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "array_offset",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "end_timestamp",
- TIMESTAMPTZOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "newest_xmin",
- XIDOID, -1, 0);
-
- return BlessTupleDesc(tupdesc);
-}
-
/*
* Convert one entry from the old snapshot time mapping to a HeapTuple.
*/
ReleaseBuffer(vmbuffer);
relation_close(rel, AccessShareLock);
- tupdesc = CreateTemplateTupleDesc(2);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "all_visible", INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "all_frozen", INT8OID, -1, 0);
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
values[0] = Int64GetDatum(all_visible);
values[1] = Int64GetDatum(all_frozen);
/* and construct a tuple with our data */
xid = GetLatestCommitTsData(&ts, &nodeid);
- /*
- * Construct a tuple descriptor for the result row. This must match this
- * function's pg_proc entry!
- */
- tupdesc = CreateTemplateTupleDesc(3);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "timestamp",
- TIMESTAMPTZOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "roident",
- OIDOID, -1, 0);
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
if (!TransactionIdIsNormal(xid))
{
found = TransactionIdGetCommitTsData(xid, &ts, &nodeid);
- /*
- * Construct a tuple descriptor for the result row. This must match this
- * function's pg_proc entry!
- */
- tupdesc = CreateTemplateTupleDesc(2);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "timestamp",
- TIMESTAMPTZOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "roident",
- OIDOID, -1, 0);
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
if (!found)
{
false);
multi->iter = 0;
- tupdesc = CreateTemplateTupleDesc(2);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "mode",
- TEXTOID, -1, 0);
-
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+ funccxt->tuple_desc = tupdesc;
funccxt->attinmeta = TupleDescGetAttInMetadata(tupdesc);
funccxt->user_fctx = multi;
if (relation)
relation_close(relation, AccessShareLock);
- tupdesc = CreateTemplateTupleDesc(3);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "classid",
- OIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "objid",
- OIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "objsubid",
- INT4OID, -1, 0);
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
values[0] = ObjectIdGetDatum(addr.classId);
values[1] = ObjectIdGetDatum(addr.objectId);
address.objectId = objid;
address.objectSubId = objsubid;
- /*
- * Construct a tuple descriptor for the result row. This must match this
- * function's pg_proc entry!
- */
- tupdesc = CreateTemplateTupleDesc(4);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "type",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "schema",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "name",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "identity",
- TEXTOID, -1, 0);
-
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
if (is_objectclass_supported(address.classId))
{
address.objectId = objid;
address.objectSubId = objsubid;
- /*
- * Construct a tuple descriptor for the result row. This must match this
- * function's pg_proc entry!
- */
- tupdesc = CreateTemplateTupleDesc(3);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "type",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "object_names",
- TEXTARRAYOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "object_args",
- TEXTARRAYOID, -1, 0);
-
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
/* object type, which can never be NULL */
values[0] = CStringGetTextDatum(getObjectTypeDescription(&address, true));
errmsg("permission denied for sequence %s",
get_rel_name(relid))));
- tupdesc = CreateTemplateTupleDesc(7);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "start_value",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "minimum_value",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "maximum_value",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "increment",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 5, "cycle_option",
- BOOLOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 6, "cache_size",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 7, "data_type",
- OIDOID, -1, 0);
-
- BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
memset(isnull, 0, sizeof(isnull));
static text *headline_json_value(void *_state, char *elem_value, int elem_len);
static void
-tt_setup_firstcall(FuncCallContext *funcctx, Oid prsid)
+tt_setup_firstcall(FuncCallContext *funcctx, FunctionCallInfo fcinfo,
+ Oid prsid)
{
TupleDesc tupdesc;
MemoryContext oldcontext;
(Datum) 0));
funcctx->user_fctx = (void *) st;
- tupdesc = CreateTemplateTupleDesc(3);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "alias",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
- TEXTOID, -1, 0);
-
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+ funcctx->tuple_desc = tupdesc;
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
+
MemoryContextSwitchTo(oldcontext);
}
if (SRF_IS_FIRSTCALL())
{
funcctx = SRF_FIRSTCALL_INIT();
- tt_setup_firstcall(funcctx, PG_GETARG_OID(0));
+ tt_setup_firstcall(funcctx, fcinfo, PG_GETARG_OID(0));
}
funcctx = SRF_PERCALL_SETUP();
funcctx = SRF_FIRSTCALL_INIT();
prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
- tt_setup_firstcall(funcctx, prsId);
+ tt_setup_firstcall(funcctx, fcinfo, prsId);
}
funcctx = SRF_PERCALL_SETUP();
static void
-prs_setup_firstcall(FuncCallContext *funcctx, Oid prsid, text *txt)
+prs_setup_firstcall(FuncCallContext *funcctx, FunctionCallInfo fcinfo,
+ Oid prsid, text *txt)
{
TupleDesc tupdesc;
MemoryContext oldcontext;
st->cur = 0;
funcctx->user_fctx = (void *) st;
- tupdesc = CreateTemplateTupleDesc(2);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "token",
- TEXTOID, -1, 0);
-
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+ funcctx->tuple_desc = tupdesc;
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
MemoryContextSwitchTo(oldcontext);
}
text *txt = PG_GETARG_TEXT_PP(1);
funcctx = SRF_FIRSTCALL_INIT();
- prs_setup_firstcall(funcctx, PG_GETARG_OID(0), txt);
+ prs_setup_firstcall(funcctx, fcinfo, PG_GETARG_OID(0), txt);
PG_FREE_IF_COPY(txt, 1);
}
funcctx = SRF_FIRSTCALL_INIT();
prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
- prs_setup_firstcall(funcctx, prsId, txt);
+ prs_setup_firstcall(funcctx, fcinfo, prsId, txt);
}
funcctx = SRF_PERCALL_SETUP();
*pindex = 0;
funcctx->user_fctx = (void *) pindex;
- /*
- * build tupdesc for result tuples. This must match this function's
- * pg_proc entry!
- */
- tupdesc = CreateTemplateTupleDesc(3);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "abbrev",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "utc_offset",
- INTERVALOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "is_dst",
- BOOLOID, -1, 0);
-
- funcctx->tuple_desc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+ funcctx->tuple_desc = tupdesc;
+
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
- tupdesc = CreateTemplateTupleDesc(5);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode",
- CHAROID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "barelabel",
- BOOLOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "catdesc",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 5, "baredesc",
- TEXTOID, -1, 0);
-
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+ funcctx->tuple_desc = tupdesc;
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
MemoryContextSwitchTo(oldcontext);
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
- tupdesc = CreateTemplateTupleDesc(6);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "fktable",
- REGCLASSOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "fkcols",
- TEXTARRAYOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "pktable",
- REGCLASSOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "pkcols",
- TEXTARRAYOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 5, "is_array",
- BOOLOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 6, "is_opt",
- BOOLOID, -1, 0);
-
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
/*
*/
partitions = find_all_inheritors(rootrelid, AccessShareLock, NULL);
- tupdesc = CreateTemplateTupleDesc(PG_PARTITION_TREE_COLS);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "relid",
- REGCLASSOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "parentid",
- REGCLASSOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "isleaf",
- BOOLOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "level",
- INT4OID, -1, 0);
-
- funcctx->tuple_desc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+ funcctx->tuple_desc = tupdesc;
/* The only state we need is the partition list */
funcctx->user_fctx = (void *) partitions;
INT2ARRAYOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "weights",
TEXTARRAYOID, -1, 0);
- funcctx->tuple_desc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+ funcctx->tuple_desc = tupdesc;
funcctx->user_fctx = PG_GETARG_TSVECTOR_COPY(0);
}
Assert(stat->stackpos <= stat->maxdepth);
- tupdesc = CreateTemplateTupleDesc(3);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "ndoc",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "nentry",
- INT4OID, -1, 0);
- funcctx->tuple_desc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+ funcctx->tuple_desc = tupdesc;
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
MemoryContextSwitchTo(oldcontext);
ControlFileData *ControlFile;
bool crc_ok;
- /*
- * Construct a tuple descriptor for the result row. This must match this
- * function's pg_proc entry!
- */
- tupdesc = CreateTemplateTupleDesc(4);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pg_control_version",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catalog_version_no",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "system_identifier",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "pg_control_last_modified",
- TIMESTAMPTZOID, -1, 0);
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
/* read the control file */
ControlFile = get_controlfile(DataDir, &crc_ok);
char xlogfilename[MAXFNAMELEN];
bool crc_ok;
- /*
- * Construct a tuple descriptor for the result row. This must match this
- * function's pg_proc entry!
- */
- tupdesc = CreateTemplateTupleDesc(18);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "checkpoint_lsn",
- PG_LSNOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "redo_lsn",
- PG_LSNOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "redo_wal_file",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "timeline_id",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 5, "prev_timeline_id",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 6, "full_page_writes",
- BOOLOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 7, "next_xid",
- TEXTOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 8, "next_oid",
- OIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 9, "next_multixact_id",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 10, "next_multi_offset",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 11, "oldest_xid",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 12, "oldest_xid_dbid",
- OIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 13, "oldest_active_xid",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 14, "oldest_multi_xid",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 15, "oldest_multi_dbid",
- OIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 16, "oldest_commit_ts_xid",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 17, "newest_commit_ts_xid",
- XIDOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 18, "checkpoint_time",
- TIMESTAMPTZOID, -1, 0);
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
/* Read the control file. */
ControlFile = get_controlfile(DataDir, &crc_ok);
ControlFileData *ControlFile;
bool crc_ok;
- /*
- * Construct a tuple descriptor for the result row. This must match this
- * function's pg_proc entry!
- */
- tupdesc = CreateTemplateTupleDesc(5);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "min_recovery_end_lsn",
- PG_LSNOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "min_recovery_end_timeline",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "backup_start_lsn",
- PG_LSNOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "backup_end_lsn",
- PG_LSNOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 5, "end_of_backup_record_required",
- BOOLOID, -1, 0);
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
/* read the control file */
ControlFile = get_controlfile(DataDir, &crc_ok);
ControlFileData *ControlFile;
bool crc_ok;
- /*
- * Construct a tuple descriptor for the result row. This must match this
- * function's pg_proc entry!
- */
- tupdesc = CreateTemplateTupleDesc(11);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "max_data_alignment",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database_block_size",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "blocks_per_segment",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_block_size",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 5, "bytes_per_wal_segment",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 6, "max_identifier_length",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 7, "max_index_columns",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 8, "max_toast_chunk_size",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 9, "large_object_chunk_size",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 10, "float8_pass_by_value",
- BOOLOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 11, "data_page_checksum_version",
- INT4OID, -1, 0);
- tupdesc = BlessTupleDesc(tupdesc);
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
/* read the control file */
ControlFile = get_controlfile(DataDir, &crc_ok);