aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/psql/command.c')
-rw-r--r--src/bin/psql/command.c130
1 files changed, 129 insertions, 1 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 180781ecd05..4dfc7b2d857 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -64,10 +64,14 @@ static backslashResult exec_command(const char *cmd,
PQExpBuffer previous_buf);
static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_bind(PsqlScanState scan_state, bool active_branch);
+static backslashResult exec_command_bind_named(PsqlScanState scan_state, bool active_branch,
+ const char *cmd);
static backslashResult exec_command_C(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch,
const char *cmd);
+static backslashResult exec_command_close(PsqlScanState scan_state, bool active_branch,
+ const char *cmd);
static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch);
@@ -116,6 +120,8 @@ 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_parse(PsqlScanState scan_state, bool active_branch,
+ const char *cmd);
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);
@@ -312,12 +318,16 @@ exec_command(const char *cmd,
status = exec_command_a(scan_state, active_branch);
else if (strcmp(cmd, "bind") == 0)
status = exec_command_bind(scan_state, active_branch);
+ else if (strcmp(cmd, "bind_named") == 0)
+ status = exec_command_bind_named(scan_state, active_branch, cmd);
else if (strcmp(cmd, "C") == 0)
status = exec_command_C(scan_state, active_branch);
else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
status = exec_command_connect(scan_state, active_branch);
else if (strcmp(cmd, "cd") == 0)
status = exec_command_cd(scan_state, active_branch, cmd);
+ else if (strcmp(cmd, "close") == 0)
+ status = exec_command_close(scan_state, active_branch, cmd);
else if (strcmp(cmd, "conninfo") == 0)
status = exec_command_conninfo(scan_state, active_branch);
else if (pg_strcasecmp(cmd, "copy") == 0)
@@ -379,6 +389,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, "parse") == 0)
+ status = exec_command_parse(scan_state, active_branch, cmd);
else if (strcmp(cmd, "password") == 0)
status = exec_command_password(scan_state, active_branch);
else if (strcmp(cmd, "prompt") == 0)
@@ -472,6 +484,7 @@ exec_command_bind(PsqlScanState scan_state, bool active_branch)
int nalloc = 0;
pset.bind_params = NULL;
+ pset.stmtName = NULL;
while ((opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false)))
{
@@ -485,7 +498,57 @@ exec_command_bind(PsqlScanState scan_state, bool active_branch)
}
pset.bind_nparams = nparams;
- pset.bind_flag = true;
+ pset.send_mode = PSQL_SEND_EXTENDED_QUERY_PARAMS;
+ }
+ else
+ ignore_slash_options(scan_state);
+
+ return status;
+}
+
+/*
+ * \bind_named -- set query parameters for an existing prepared statement
+ */
+static backslashResult
+exec_command_bind_named(PsqlScanState scan_state, bool active_branch,
+ const char *cmd)
+{
+ backslashResult status = PSQL_CMD_SKIP_LINE;
+
+ if (active_branch)
+ {
+ char *opt;
+ int nparams = 0;
+ int nalloc = 0;
+
+ pset.bind_params = NULL;
+ pset.stmtName = NULL;
+
+ /* get the mandatory prepared statement name */
+ opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
+ if (!opt)
+ {
+ pg_log_error("\\%s: missing required argument", cmd);
+ status = PSQL_CMD_ERROR;
+ }
+ else
+ {
+ pset.stmtName = opt;
+ pset.send_mode = PSQL_SEND_EXTENDED_QUERY_PREPARED;
+
+ /* set of parameters */
+ while ((opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false)))
+ {
+ nparams++;
+ if (nparams > nalloc)
+ {
+ nalloc = nalloc ? nalloc * 2 : 1;
+ pset.bind_params = pg_realloc_array(pset.bind_params, char *, nalloc);
+ }
+ pset.bind_params[nparams - 1] = opt;
+ }
+ pset.bind_nparams = nparams;
+ }
}
else
ignore_slash_options(scan_state);
@@ -644,6 +707,38 @@ exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
/*
+ * \close -- close a previously prepared statement
+ */
+static backslashResult
+exec_command_close(PsqlScanState scan_state, bool active_branch, const char *cmd)
+{
+ backslashResult status = PSQL_CMD_SKIP_LINE;
+
+ if (active_branch)
+ {
+ char *opt = psql_scan_slash_option(scan_state,
+ OT_NORMAL, NULL, false);
+
+ pset.stmtName = NULL;
+ if (!opt)
+ {
+ pg_log_error("\\%s: missing required argument", cmd);
+ status = PSQL_CMD_ERROR;
+ }
+ else
+ {
+ pset.stmtName = opt;
+ pset.send_mode = PSQL_SEND_EXTENDED_CLOSE;
+ status = PSQL_CMD_SEND;
+ }
+ }
+ else
+ ignore_slash_options(scan_state);
+
+ return status;
+}
+
+/*
* \conninfo -- display information about the current connection
*/
static backslashResult
@@ -2097,6 +2192,39 @@ exec_command_print(PsqlScanState scan_state, bool active_branch,
}
/*
+ * \parse -- parse query
+ */
+static backslashResult
+exec_command_parse(PsqlScanState scan_state, bool active_branch,
+ const char *cmd)
+{
+ backslashResult status = PSQL_CMD_SKIP_LINE;
+
+ if (active_branch)
+ {
+ char *opt = psql_scan_slash_option(scan_state,
+ OT_NORMAL, NULL, false);
+
+ pset.stmtName = NULL;
+ if (!opt)
+ {
+ pg_log_error("\\%s: missing required argument", cmd);
+ status = PSQL_CMD_ERROR;
+ }
+ else
+ {
+ pset.stmtName = opt;
+ pset.send_mode = PSQL_SEND_EXTENDED_PARSE;
+ status = PSQL_CMD_SEND;
+ }
+ }
+ else
+ ignore_slash_options(scan_state);
+
+ return status;
+}
+
+/*
* \password -- set user password
*/
static backslashResult