diff options
Diffstat (limited to 'src/bin/psql/command.c')
-rw-r--r-- | src/bin/psql/command.c | 130 |
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 |