1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-05 23:56:58 +03:00
postgres/src/backend/utils/misc/pg_config.c
Michael Paquier d61a361d1a Remove all traces of tuplestore_donestoring() in the C code
This routine is a no-op since dd04e95 from 2003, with a macro kept
around for compatibility purposes.  This has led to the same code
patterns being copy-pasted around for no effect, sometimes in confusing
ways like in pg_logical_slot_get_changes_guts() from logical.c where the
code was actually incorrect.

This issue has been discussed on two different threads recently, so
rather than living with this legacy, remove any uses of this routine in
the C code to simplify things.  The compatibility macro is kept to avoid
breaking any out-of-core modules that depend on it.

Reported-by: Tatsuhito Kasahara, Justin Pryzby
Author: Tatsuhito Kasahara
Discussion: https://postgr.es/m/20211217200419.GQ17618@telsasoft.com
Discussion: https://postgr.es/m/CAP0=ZVJeeYfAeRfmzqAF2Lumdiv4S4FewyBnZd4DPTrsSQKJKw@mail.gmail.com
2022-02-17 09:52:02 +09:00

102 lines
2.8 KiB
C

/*-------------------------------------------------------------------------
*
* pg_config.c
* Expose same output as pg_config except as an SRF
*
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/backend/utils/misc/pg_config.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/pg_type.h"
#include "common/config_info.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "port.h"
#include "utils/builtins.h"
Datum
pg_config(PG_FUNCTION_ARGS)
{
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
Tuplestorestate *tupstore;
HeapTuple tuple;
TupleDesc tupdesc;
AttInMetadata *attinmeta;
MemoryContext per_query_ctx;
MemoryContext oldcontext;
ConfigData *configdata;
size_t configdata_len;
char *values[2];
int i = 0;
/* check to see if caller supports us returning a tuplestore */
if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("materialize mode required, but it is not "
"allowed in this context")));
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
oldcontext = MemoryContextSwitchTo(per_query_ctx);
/* get the requested return tuple description */
tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);
/*
* Check to make sure we have a reasonable tuple descriptor
*/
if (tupdesc->natts != 2 ||
TupleDescAttr(tupdesc, 0)->atttypid != TEXTOID ||
TupleDescAttr(tupdesc, 1)->atttypid != TEXTOID)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("query-specified return tuple and "
"function return type are not compatible")));
/* OK to use it */
attinmeta = TupleDescGetAttInMetadata(tupdesc);
/* let the caller know we're sending back a tuplestore */
rsinfo->returnMode = SFRM_Materialize;
/* initialize our tuplestore */
tupstore = tuplestore_begin_heap(true, false, work_mem);
configdata = get_configdata(my_exec_path, &configdata_len);
for (i = 0; i < configdata_len; i++)
{
values[0] = configdata[i].name;
values[1] = configdata[i].setting;
tuple = BuildTupleFromCStrings(attinmeta, values);
tuplestore_puttuple(tupstore, tuple);
}
/*
* no longer need the tuple descriptor reference created by
* TupleDescGetAttInMetadata()
*/
ReleaseTupleDesc(tupdesc);
rsinfo->setResult = tupstore;
/*
* SFRM_Materialize mode expects us to return a NULL Datum. The actual
* tuples are in our tuplestore and passed back through rsinfo->setResult.
* rsinfo->setDesc is set to the tuple description that we actually used
* to build our tuples with, so the caller can verify we did what it was
* expecting.
*/
rsinfo->setDesc = tupdesc;
MemoryContextSwitchTo(oldcontext);
return (Datum) 0;
}