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>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><literal>TIMELINE_HISTORY</literal> <replaceable class="parameter">tli</replaceable>
|
<term><literal>TIMELINE_HISTORY</literal> <replaceable class="parameter">tli</replaceable>
|
||||||
<indexterm><primary>TIMELINE_HISTORY</primary></indexterm>
|
<indexterm><primary>TIMELINE_HISTORY</primary></indexterm>
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
|
#include "catalog/pg_collation.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
|
@ -553,6 +554,84 @@ TupleDescInitEntry(TupleDesc desc,
|
||||||
ReleaseSysCache(tuple);
|
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
|
* TupleDescInitEntryCollation
|
||||||
*
|
*
|
||||||
|
|
|
@ -61,6 +61,7 @@ Node *replication_parse_result;
|
||||||
/* Keyword tokens. */
|
/* Keyword tokens. */
|
||||||
%token K_BASE_BACKUP
|
%token K_BASE_BACKUP
|
||||||
%token K_IDENTIFY_SYSTEM
|
%token K_IDENTIFY_SYSTEM
|
||||||
|
%token K_SHOW
|
||||||
%token K_START_REPLICATION
|
%token K_START_REPLICATION
|
||||||
%token K_CREATE_REPLICATION_SLOT
|
%token K_CREATE_REPLICATION_SLOT
|
||||||
%token K_DROP_REPLICATION_SLOT
|
%token K_DROP_REPLICATION_SLOT
|
||||||
|
@ -82,14 +83,14 @@ Node *replication_parse_result;
|
||||||
%type <node> command
|
%type <node> command
|
||||||
%type <node> base_backup start_replication start_logical_replication
|
%type <node> base_backup start_replication start_logical_replication
|
||||||
create_replication_slot drop_replication_slot identify_system
|
create_replication_slot drop_replication_slot identify_system
|
||||||
timeline_history
|
timeline_history show
|
||||||
%type <list> base_backup_opt_list
|
%type <list> base_backup_opt_list
|
||||||
%type <defelt> base_backup_opt
|
%type <defelt> base_backup_opt
|
||||||
%type <uintval> opt_timeline
|
%type <uintval> opt_timeline
|
||||||
%type <list> plugin_options plugin_opt_list
|
%type <list> plugin_options plugin_opt_list
|
||||||
%type <defelt> plugin_opt_elem
|
%type <defelt> plugin_opt_elem
|
||||||
%type <node> plugin_opt_arg
|
%type <node> plugin_opt_arg
|
||||||
%type <str> opt_slot
|
%type <str> opt_slot var_name
|
||||||
%type <boolval> opt_reserve_wal opt_temporary
|
%type <boolval> opt_reserve_wal opt_temporary
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@ -112,6 +113,7 @@ command:
|
||||||
| create_replication_slot
|
| create_replication_slot
|
||||||
| drop_replication_slot
|
| drop_replication_slot
|
||||||
| timeline_history
|
| 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]
|
* BASE_BACKUP [LABEL '<label>'] [PROGRESS] [FAST] [WAL] [NOWAIT]
|
||||||
* [MAX_RATE %d] [TABLESPACE_MAP]
|
* [MAX_RATE %d] [TABLESPACE_MAP]
|
||||||
|
|
|
@ -83,6 +83,7 @@ identifier {ident_start}{ident_cont}*
|
||||||
BASE_BACKUP { return K_BASE_BACKUP; }
|
BASE_BACKUP { return K_BASE_BACKUP; }
|
||||||
FAST { return K_FAST; }
|
FAST { return K_FAST; }
|
||||||
IDENTIFY_SYSTEM { return K_IDENTIFY_SYSTEM; }
|
IDENTIFY_SYSTEM { return K_IDENTIFY_SYSTEM; }
|
||||||
|
SHOW { return K_SHOW; }
|
||||||
LABEL { return K_LABEL; }
|
LABEL { return K_LABEL; }
|
||||||
NOWAIT { return K_NOWAIT; }
|
NOWAIT { return K_NOWAIT; }
|
||||||
PROGRESS { return K_PROGRESS; }
|
PROGRESS { return K_PROGRESS; }
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "access/printtup.h"
|
||||||
#include "access/timeline.h"
|
#include "access/timeline.h"
|
||||||
#include "access/transam.h"
|
#include "access/transam.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
|
@ -72,11 +73,13 @@
|
||||||
#include "storage/pmsignal.h"
|
#include "storage/pmsignal.h"
|
||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
#include "storage/procarray.h"
|
#include "storage/procarray.h"
|
||||||
|
#include "tcop/dest.h"
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/pg_lsn.h"
|
#include "utils/pg_lsn.h"
|
||||||
|
#include "utils/portal.h"
|
||||||
#include "utils/ps_status.h"
|
#include "utils/ps_status.h"
|
||||||
#include "utils/resowner.h"
|
#include "utils/resowner.h"
|
||||||
#include "utils/timeout.h"
|
#include "utils/timeout.h"
|
||||||
|
@ -1365,6 +1368,15 @@ exec_replication_command(const char *cmd_string)
|
||||||
SendTimeLineHistory((TimeLineHistoryCmd *) cmd_node);
|
SendTimeLineHistory((TimeLineHistoryCmd *) cmd_node);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_VariableShowStmt:
|
||||||
|
{
|
||||||
|
DestReceiver *dest = CreateDestReceiver(DestRemoteSimple);
|
||||||
|
VariableShowStmt *n = (VariableShowStmt *) cmd_node;
|
||||||
|
|
||||||
|
GetPGVariable(n->name, dest);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "unrecognized replication command node tag: %u",
|
elog(ERROR, "unrecognized replication command node tag: %u",
|
||||||
cmd_node->type);
|
cmd_node->type);
|
||||||
|
|
|
@ -7878,8 +7878,8 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest)
|
||||||
|
|
||||||
/* need a tuple descriptor representing a single TEXT column */
|
/* need a tuple descriptor representing a single TEXT column */
|
||||||
tupdesc = CreateTemplateTupleDesc(1, false);
|
tupdesc = CreateTemplateTupleDesc(1, false);
|
||||||
TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
|
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, varname,
|
||||||
TEXTOID, -1, 0);
|
TEXTOID, -1, 0);
|
||||||
|
|
||||||
/* prepare for projection of tuples */
|
/* prepare for projection of tuples */
|
||||||
tstate = begin_tup_output_tupdesc(dest, tupdesc);
|
tstate = begin_tup_output_tupdesc(dest, tupdesc);
|
||||||
|
@ -7905,12 +7905,12 @@ ShowAllGUCConfig(DestReceiver *dest)
|
||||||
|
|
||||||
/* need a tuple descriptor representing three TEXT columns */
|
/* need a tuple descriptor representing three TEXT columns */
|
||||||
tupdesc = CreateTemplateTupleDesc(3, false);
|
tupdesc = CreateTemplateTupleDesc(3, false);
|
||||||
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
|
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "name",
|
||||||
TEXTOID, -1, 0);
|
TEXTOID, -1, 0);
|
||||||
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
|
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "setting",
|
||||||
TEXTOID, -1, 0);
|
TEXTOID, -1, 0);
|
||||||
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
|
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "description",
|
||||||
TEXTOID, -1, 0);
|
TEXTOID, -1, 0);
|
||||||
|
|
||||||
/* prepare for projection of tuples */
|
/* prepare for projection of tuples */
|
||||||
tstate = begin_tup_output_tupdesc(dest, tupdesc);
|
tstate = begin_tup_output_tupdesc(dest, tupdesc);
|
||||||
|
|
|
@ -119,6 +119,13 @@ extern void TupleDescInitEntry(TupleDesc desc,
|
||||||
int32 typmod,
|
int32 typmod,
|
||||||
int attdim);
|
int attdim);
|
||||||
|
|
||||||
|
extern void TupleDescInitBuiltinEntry(TupleDesc desc,
|
||||||
|
AttrNumber attributeNumber,
|
||||||
|
const char *attributeName,
|
||||||
|
Oid oidtypeid,
|
||||||
|
int32 typmod,
|
||||||
|
int attdim);
|
||||||
|
|
||||||
extern void TupleDescInitEntryCollation(TupleDesc desc,
|
extern void TupleDescInitEntryCollation(TupleDesc desc,
|
||||||
AttrNumber attributeNumber,
|
AttrNumber attributeNumber,
|
||||||
Oid collationid);
|
Oid collationid);
|
||||||
|
|
Loading…
Reference in New Issue