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:
parent
a84069d935
commit
d1ecd53947
@ -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>
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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]
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user