v11-0009-psql-Add-parameterset-meta-command.patch
application/octet-stream
Filename: v11-0009-psql-Add-parameterset-meta-command.patch
Type: application/octet-stream
Part: 6
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v11-0009
Subject: psql: Add \parameterset meta-command
| File | + | − |
|---|---|---|
| doc/src/sgml/ref/psql-ref.sgml | 13 | 0 |
| src/bin/psql/command.c | 45 | 0 |
| src/bin/psql/common.c | 10 | 0 |
| src/bin/psql/settings.h | 2 | 0 |
| src/test/regress/expected/psql.out | 26 | 0 |
| src/test/regress/sql/psql.sql | 14 | 0 |
From d4b7957870ecd17a1b166a639c032735da9b00be Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <jelte.fennema@microsoft.com>
Date: Mon, 15 Jan 2024 13:01:21 +0100
Subject: [PATCH v11 09/14] psql: Add \parameterset meta-command
To be able to easily test the new ParameterSet protocol message this
introduces a new meta-command to psql: \parameterset
An additional usecase for this meta-command is using it to configure a
connection to connection poolers from the client side.
---
doc/src/sgml/ref/psql-ref.sgml | 13 +++++++++
src/bin/psql/command.c | 45 ++++++++++++++++++++++++++++++
src/bin/psql/common.c | 10 +++++++
src/bin/psql/settings.h | 2 ++
src/test/regress/expected/psql.out | 26 +++++++++++++++++
src/test/regress/sql/psql.sql | 14 ++++++++++
6 files changed, 110 insertions(+)
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index cc7d797159b..4954399874c 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2779,6 +2779,19 @@ lo_import 152801
</listitem>
</varlistentry>
+ <varlistentry id="app-psql-meta-command-parameterset">
+ <term><literal>\parameterset <replaceable class="parameter">name</replaceable> <replaceable class="parameter">value</replaceable></literal></term>
+ <listitem>
+ <para>
+ This command can be used to change a server parameter using the
+ ParameterSet protocol message. This has the effect as using an
+ equivalent <literal>SET</literal> command. The main difference is that
+ Some connection poolers can only intercept parameter changes that are
+ changed using the ParameterSet message.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="app-psql-meta-command-password">
<term><literal>\password [ <replaceable class="parameter">username</replaceable> ]</literal></term>
<listitem>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 9b0fa041f73..6e2da1a01c4 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -116,6 +116,7 @@ static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_bra
static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
+static backslashResult exec_command_parameterset(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch,
const char *cmd);
@@ -378,6 +379,8 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
status = exec_command_print(scan_state, active_branch,
query_buf, previous_buf);
+ else if (strcmp(cmd, "parameterset") == 0)
+ status = exec_command_parameterset(scan_state, active_branch);
else if (strcmp(cmd, "password") == 0)
status = exec_command_password(scan_state, active_branch);
else if (strcmp(cmd, "prompt") == 0)
@@ -2095,6 +2098,48 @@ exec_command_print(PsqlScanState scan_state, bool active_branch,
return PSQL_CMD_SKIP_LINE;
}
+/*
+ * \parameterset -- set query parameters
+ */
+static backslashResult
+exec_command_parameterset(PsqlScanState scan_state, bool active_branch)
+{
+ if (!active_branch)
+ {
+ ignore_slash_options(scan_state);
+ return PSQL_CMD_SKIP_LINE;
+ }
+
+ for (int i = 0; i < lengthof(pset.parameterset_args); i++)
+ pset.parameterset_args[i] = psql_scan_slash_option(scan_state,
+ OT_NORMAL,
+ NULL,
+ true);
+
+ if (pset.parameterset_args[1] == NULL)
+ {
+ pg_log_error("\\parameterset needs two arguments");
+ goto error;
+ }
+
+ if (strncmp("_pq_.", pset.parameterset_args[0], 5) == 0)
+ {
+ pg_log_error("\\parameterset cannot be used to change protocol extensions parameters");
+ goto error;
+ }
+
+ pset.parameterset_flag = true;
+
+ return PSQL_CMD_SEND;
+
+error:
+ free(pset.parameterset_args[0]);
+ free(pset.parameterset_args[1]);
+ pset.parameterset_args[0] = NULL;
+ pset.parameterset_args[1] = NULL;
+ return PSQL_CMD_ERROR;
+}
+
/*
* \password -- set user password
*/
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index 76e01b02a39..a2d223c7fd6 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -1272,6 +1272,14 @@ sendquery_cleanup:
pset.ctv_args[i] = NULL;
}
+ /* reset \parameterset trigger */
+ pset.parameterset_flag = false;
+ for (i = 0; i < lengthof(pset.parameterset_args); i++)
+ {
+ pg_free(pset.parameterset_args[i]);
+ pset.parameterset_args[i] = NULL;
+ }
+
return OK;
}
@@ -1435,6 +1443,8 @@ ExecQueryAndProcessResults(const char *query,
if (pset.bind_flag)
success = PQsendQueryParams(pset.db, query, pset.bind_nparams, NULL, (const char *const *) pset.bind_params, NULL, NULL, 0);
+ else if (pset.parameterset_flag)
+ success = PQsendParameterSet(pset.db, pset.parameterset_args[0], pset.parameterset_args[1]);
else
success = PQsendQuery(pset.db, query);
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index 505f99d8e47..c93f8792443 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -105,6 +105,8 @@ typedef struct _psqlSettings
bool notty; /* stdin or stdout is not a tty (as determined
* on startup) */
+ bool parameterset_flag; /* one-shot request to crosstab result */
+ char *parameterset_args[2]; /* \parameterset arguments */
enum trivalue getPassword; /* prompt the user for a username and password */
FILE *cur_cmd_source; /* describe the status of the current main
* loop */
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 69060fe3c00..117362cd010 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -129,6 +129,31 @@ ERROR: cannot insert multiple commands into a prepared statement
-- bind error
SELECT $1, $2 \bind 'foo' \g
ERROR: bind message supplies 1 parameters, but prepared statement "" requires 2
+-- \parameterset (protocol version 3.1)
+\parameterset work_mem 1234
+SHOW work_mem;
+ work_mem
+----------
+ 1234kB
+(1 row)
+
+\parameterset work_mem 'abc'
+ERROR: invalid value for parameter "work_mem": "abc"
+RESET work_mem;
+\parameterset search_path '"some quoted string",and_one_without,""'
+SHOW search_path;
+ search_path
+-----------------------------------------
+ "some quoted string",and_one_without,""
+(1 row)
+
+RESET search_path;
+-- should fail with wrong number of arguments
+\parameterset work_mem
+\parameterset needs two arguments
+-- should fail because extension is unknown
+\parameterset _pq_.magic_pixie_dust true
+\parameterset cannot be used to change protocol extensions parameters
-- \gset
select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_
\echo :pref01_test01 :pref01_test02 :pref01_test03
@@ -4538,6 +4563,7 @@ invalid command \lo
\lo_list
\o arg1
\p
+ \parameterset abc arg2
\password arg1
\prompt arg1 arg2
\pset arg1 arg2
diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql
index 129f8533537..1057b83542c 100644
--- a/src/test/regress/sql/psql.sql
+++ b/src/test/regress/sql/psql.sql
@@ -59,6 +59,19 @@ SELECT 1 \; SELECT 2 \bind \g
-- bind error
SELECT $1, $2 \bind 'foo' \g
+-- \parameterset (protocol version 3.1)
+\parameterset work_mem 1234
+SHOW work_mem;
+\parameterset work_mem 'abc'
+RESET work_mem;
+\parameterset search_path '"some quoted string",and_one_without,""'
+SHOW search_path;
+RESET search_path;
+-- should fail with wrong number of arguments
+\parameterset work_mem
+-- should fail because extension is unknown
+\parameterset _pq_.magic_pixie_dust true
+
-- \gset
select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_
@@ -1020,6 +1033,7 @@ select \if false \\ (bogus \else \\ 42 \endif \\ forty_two;
\lo_list
\o arg1
\p
+ \parameterset abc arg2
\password arg1
\prompt arg1 arg2
\pset arg1 arg2
--
2.34.1