Add a SHOW command to the replication command language.

This is useful infrastructure for an upcoming proposed patch to
allow the WAL segment size to be changed at initdb time; tools like
pg_basebackup need the ability to interrogate the server setting.
But it also doesn't seem like a bad thing to have independently of
that; it may find other uses in the future.

Robert Haas and Beena Emerson.  (The original patch here was by
Beena, but I rewrote it to such a degree that most of the code
being committed here is mine.)

Discussion: http://postgr.es/m/CA+TgmobNo4qz06wHEmy9DszAre3dYx-WNhHSCbU9SAwf+9Ft6g@mail.gmail.com
This commit is contained in:
Robert Haas 2017-01-24 16:59:18 -05:00
parent a84069d935
commit d1ecd53947
7 changed files with 151 additions and 10 deletions

View File

@ -1393,6 +1393,30 @@ The commands accepted in walsender mode are:
</listitem>
</varlistentry>
<varlistentry>
<term><literal>SHOW</literal> <replaceable class="parameter">name</replaceable>
<indexterm><primary>SHOW</primary></indexterm>
</term>
<listitem>
<para>
Requests the server to send the current setting of a run-time parameter.
This is similar to the SQL command <xref linkend="sql-show">.
</para>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">name</></term>
<listitem>
<para>
The name of a run-time parameter. Available parameters are documented
in <xref linkend="runtime-config">.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>TIMELINE_HISTORY</literal> <replaceable class="parameter">tli</replaceable>
<indexterm><primary>TIMELINE_HISTORY</primary></indexterm>

View File

@ -20,6 +20,7 @@
#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "parser/parse_type.h"
@ -553,6 +554,84 @@ TupleDescInitEntry(TupleDesc desc,
ReleaseSysCache(tuple);
}
/*
* TupleDescInitBuiltinEntry
* Initialize a tuple descriptor without catalog access. Only
* a limited range of builtin types are supported.
*/
void
TupleDescInitBuiltinEntry(TupleDesc desc,
AttrNumber attributeNumber,
const char *attributeName,
Oid oidtypeid,
int32 typmod,
int attdim)
{
Form_pg_attribute att;
/* sanity checks */
AssertArg(PointerIsValid(desc));
AssertArg(attributeNumber >= 1);
AssertArg(attributeNumber <= desc->natts);
/* initialize the attribute fields */
att = desc->attrs[attributeNumber - 1];
att->attrelid = 0; /* dummy value */
/* unlike TupleDescInitEntry, we require an attribute name */
Assert(attributeName != NULL);
namestrcpy(&(att->attname), attributeName);
att->attstattarget = -1;
att->attcacheoff = -1;
att->atttypmod = typmod;
att->attnum = attributeNumber;
att->attndims = attdim;
att->attnotnull = false;
att->atthasdef = false;
att->attisdropped = false;
att->attislocal = true;
att->attinhcount = 0;
/* attacl, attoptions and attfdwoptions are not present in tupledescs */
att->atttypid = oidtypeid;
/*
* Our goal here is to support just enough types to let basic builtin
* commands work without catalog access - e.g. so that we can do certain
* things even in processes that are not connected to a database.
*/
switch (oidtypeid)
{
case TEXTOID:
case TEXTARRAYOID:
att->attlen = -1;
att->attbyval = false;
att->attalign = 'i';
att->attstorage = 'x';
att->attcollation = DEFAULT_COLLATION_OID;
break;
case BOOLOID:
att->attlen = 1;
att->attbyval = true;
att->attalign = 'c';
att->attstorage = 'p';
att->attcollation = InvalidOid;
break;
case INT4OID:
att->attlen = 4;
att->attbyval = true;
att->attalign = 'i';
att->attstorage = 'p';
att->attcollation = InvalidOid;
break;
}
}
/*
* TupleDescInitEntryCollation
*

View File

@ -61,6 +61,7 @@ Node *replication_parse_result;
/* Keyword tokens. */
%token K_BASE_BACKUP
%token K_IDENTIFY_SYSTEM
%token K_SHOW
%token K_START_REPLICATION
%token K_CREATE_REPLICATION_SLOT
%token K_DROP_REPLICATION_SLOT
@ -82,14 +83,14 @@ Node *replication_parse_result;
%type <node> command
%type <node> base_backup start_replication start_logical_replication
create_replication_slot drop_replication_slot identify_system
timeline_history
timeline_history show
%type <list> base_backup_opt_list
%type <defelt> base_backup_opt
%type <uintval> opt_timeline
%type <list> plugin_options plugin_opt_list
%type <defelt> plugin_opt_elem
%type <node> plugin_opt_arg
%type <str> opt_slot
%type <str> opt_slot var_name
%type <boolval> opt_reserve_wal opt_temporary
%%
@ -112,6 +113,7 @@ command:
| create_replication_slot
| drop_replication_slot
| timeline_history
| show
;
/*
@ -124,6 +126,22 @@ identify_system:
}
;
/*
* SHOW setting
*/
show:
K_SHOW var_name
{
VariableShowStmt *n = makeNode(VariableShowStmt);
n->name = $2;
$$ = (Node *) n;
}
var_name: IDENT { $$ = $1; }
| var_name '.' IDENT
{ $$ = psprintf("%s.%s", $1, $3); }
;
/*
* BASE_BACKUP [LABEL '<label>'] [PROGRESS] [FAST] [WAL] [NOWAIT]
* [MAX_RATE %d] [TABLESPACE_MAP]

View File

@ -83,6 +83,7 @@ identifier {ident_start}{ident_cont}*
BASE_BACKUP { return K_BASE_BACKUP; }
FAST { return K_FAST; }
IDENTIFY_SYSTEM { return K_IDENTIFY_SYSTEM; }
SHOW { return K_SHOW; }
LABEL { return K_LABEL; }
NOWAIT { return K_NOWAIT; }
PROGRESS { return K_PROGRESS; }

View File

@ -43,6 +43,7 @@
#include <signal.h>
#include <unistd.h>
#include "access/printtup.h"
#include "access/timeline.h"
#include "access/transam.h"
#include "access/xact.h"
@ -72,11 +73,13 @@
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "tcop/dest.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/pg_lsn.h"
#include "utils/portal.h"
#include "utils/ps_status.h"
#include "utils/resowner.h"
#include "utils/timeout.h"
@ -1365,6 +1368,15 @@ exec_replication_command(const char *cmd_string)
SendTimeLineHistory((TimeLineHistoryCmd *) cmd_node);
break;
case T_VariableShowStmt:
{
DestReceiver *dest = CreateDestReceiver(DestRemoteSimple);
VariableShowStmt *n = (VariableShowStmt *) cmd_node;
GetPGVariable(n->name, dest);
}
break;
default:
elog(ERROR, "unrecognized replication command node tag: %u",
cmd_node->type);

View File

@ -7878,8 +7878,8 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest)
/* need a tuple descriptor representing a single TEXT column */
tupdesc = CreateTemplateTupleDesc(1, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
TEXTOID, -1, 0);
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, varname,
TEXTOID, -1, 0);
/* prepare for projection of tuples */
tstate = begin_tup_output_tupdesc(dest, tupdesc);
@ -7905,12 +7905,12 @@ ShowAllGUCConfig(DestReceiver *dest)
/* need a tuple descriptor representing three TEXT columns */
tupdesc = CreateTemplateTupleDesc(3, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
TEXTOID, -1, 0);
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "name",
TEXTOID, -1, 0);
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "setting",
TEXTOID, -1, 0);
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "description",
TEXTOID, -1, 0);
/* prepare for projection of tuples */
tstate = begin_tup_output_tupdesc(dest, tupdesc);

View File

@ -119,6 +119,13 @@ extern void TupleDescInitEntry(TupleDesc desc,
int32 typmod,
int attdim);
extern void TupleDescInitBuiltinEntry(TupleDesc desc,
AttrNumber attributeNumber,
const char *attributeName,
Oid oidtypeid,
int32 typmod,
int attdim);
extern void TupleDescInitEntryCollation(TupleDesc desc,
AttrNumber attributeNumber,
Oid collationid);