mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 23:56:58 +03:00
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
102 lines
2.8 KiB
C
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;
|
|
}
|