|
|
|
@ -411,11 +411,11 @@ AcceptResult(const PGresult *result) |
|
|
|
|
* entered by the user, not queries generated by slash commands. |
|
|
|
|
*/ |
|
|
|
|
static void |
|
|
|
|
SetResultVariables(PGresult *results, bool success) |
|
|
|
|
SetResultVariables(PGresult *result, bool success) |
|
|
|
|
{ |
|
|
|
|
if (success) |
|
|
|
|
{ |
|
|
|
|
const char *ntuples = PQcmdTuples(results); |
|
|
|
|
const char *ntuples = PQcmdTuples(result); |
|
|
|
|
|
|
|
|
|
SetVariable(pset.vars, "ERROR", "false"); |
|
|
|
|
SetVariable(pset.vars, "SQLSTATE", "00000"); |
|
|
|
@ -423,8 +423,8 @@ SetResultVariables(PGresult *results, bool success) |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
const char *code = PQresultErrorField(results, PG_DIAG_SQLSTATE); |
|
|
|
|
const char *mesg = PQresultErrorField(results, PG_DIAG_MESSAGE_PRIMARY); |
|
|
|
|
const char *code = PQresultErrorField(result, PG_DIAG_SQLSTATE); |
|
|
|
|
const char *mesg = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY); |
|
|
|
|
|
|
|
|
|
SetVariable(pset.vars, "ERROR", "true"); |
|
|
|
|
|
|
|
|
@ -587,7 +587,7 @@ PSQLexec(const char *query) |
|
|
|
|
* PSQLexecWatch |
|
|
|
|
* |
|
|
|
|
* This function is used for \watch command to send the query to |
|
|
|
|
* the server and print out the results. |
|
|
|
|
* the server and print out the result. |
|
|
|
|
* |
|
|
|
|
* Returns 1 if the query executed successfully, 0 if it cannot be repeated, |
|
|
|
|
* e.g., because of the interrupt, -1 on error. |
|
|
|
@ -714,9 +714,9 @@ PrintNotifications(void) |
|
|
|
|
* Returns true if successful, false otherwise. |
|
|
|
|
*/ |
|
|
|
|
static bool |
|
|
|
|
PrintQueryTuples(const PGresult *results) |
|
|
|
|
PrintQueryTuples(const PGresult *result) |
|
|
|
|
{ |
|
|
|
|
bool result = true; |
|
|
|
|
bool ok = true; |
|
|
|
|
|
|
|
|
|
/* write output to \g argument, if any */ |
|
|
|
|
if (pset.gfname) |
|
|
|
@ -729,11 +729,11 @@ PrintQueryTuples(const PGresult *results) |
|
|
|
|
if (is_pipe) |
|
|
|
|
disable_sigpipe_trap(); |
|
|
|
|
|
|
|
|
|
printQuery(results, &pset.popt, fout, false, pset.logfile); |
|
|
|
|
printQuery(result, &pset.popt, fout, false, pset.logfile); |
|
|
|
|
if (ferror(fout)) |
|
|
|
|
{ |
|
|
|
|
pg_log_error("could not print result table: %m"); |
|
|
|
|
result = false; |
|
|
|
|
ok = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (is_pipe) |
|
|
|
@ -746,15 +746,15 @@ PrintQueryTuples(const PGresult *results) |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
printQuery(results, &pset.popt, pset.queryFout, false, pset.logfile); |
|
|
|
|
printQuery(result, &pset.popt, pset.queryFout, false, pset.logfile); |
|
|
|
|
if (ferror(pset.queryFout)) |
|
|
|
|
{ |
|
|
|
|
pg_log_error("could not print result table: %m"); |
|
|
|
|
result = false; |
|
|
|
|
ok = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
return ok; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -912,7 +912,7 @@ loop_exit: |
|
|
|
|
* server-side opinion. |
|
|
|
|
*/ |
|
|
|
|
static bool |
|
|
|
|
ProcessResult(PGresult **results) |
|
|
|
|
ProcessResult(PGresult **resultp) |
|
|
|
|
{ |
|
|
|
|
bool success = true; |
|
|
|
|
bool first_cycle = true; |
|
|
|
@ -923,7 +923,7 @@ ProcessResult(PGresult **results) |
|
|
|
|
bool is_copy; |
|
|
|
|
PGresult *next_result; |
|
|
|
|
|
|
|
|
|
if (!AcceptResult(*results)) |
|
|
|
|
if (!AcceptResult(*resultp)) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
* Failure at this point is always a server-side failure or a |
|
|
|
@ -934,7 +934,7 @@ ProcessResult(PGresult **results) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
result_status = PQresultStatus(*results); |
|
|
|
|
result_status = PQresultStatus(*resultp); |
|
|
|
|
switch (result_status) |
|
|
|
|
{ |
|
|
|
|
case PGRES_EMPTY_QUERY: |
|
|
|
@ -1037,7 +1037,7 @@ ProcessResult(PGresult **results) |
|
|
|
|
copystream = pset.copyStream ? pset.copyStream : pset.cur_cmd_source; |
|
|
|
|
success = handleCopyIn(pset.db, |
|
|
|
|
copystream, |
|
|
|
|
PQbinaryTuples(*results), |
|
|
|
|
PQbinaryTuples(*resultp), |
|
|
|
|
©_result) && success; |
|
|
|
|
} |
|
|
|
|
ResetCancelConn(); |
|
|
|
@ -1046,8 +1046,8 @@ ProcessResult(PGresult **results) |
|
|
|
|
* Replace the PGRES_COPY_OUT/IN result with COPY command's exit |
|
|
|
|
* status, or with NULL if we want to suppress printing anything. |
|
|
|
|
*/ |
|
|
|
|
PQclear(*results); |
|
|
|
|
*results = copy_result; |
|
|
|
|
PQclear(*resultp); |
|
|
|
|
*resultp = copy_result; |
|
|
|
|
} |
|
|
|
|
else if (first_cycle) |
|
|
|
|
{ |
|
|
|
@ -1064,12 +1064,12 @@ ProcessResult(PGresult **results) |
|
|
|
|
if (!next_result) |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
PQclear(*results); |
|
|
|
|
*results = next_result; |
|
|
|
|
PQclear(*resultp); |
|
|
|
|
*resultp = next_result; |
|
|
|
|
first_cycle = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SetResultVariables(*results, success); |
|
|
|
|
SetResultVariables(*resultp, success); |
|
|
|
|
|
|
|
|
|
/* may need this to recover from conn loss during COPY */ |
|
|
|
|
if (!first_cycle && !CheckConnection()) |
|
|
|
@ -1082,10 +1082,10 @@ ProcessResult(PGresult **results) |
|
|
|
|
/*
|
|
|
|
|
* PrintQueryStatus: report command status as required |
|
|
|
|
* |
|
|
|
|
* Note: Utility function for use by PrintQueryResults() only. |
|
|
|
|
* Note: Utility function for use by PrintQueryResult() only. |
|
|
|
|
*/ |
|
|
|
|
static void |
|
|
|
|
PrintQueryStatus(PGresult *results) |
|
|
|
|
PrintQueryStatus(PGresult *result) |
|
|
|
|
{ |
|
|
|
|
char buf[16]; |
|
|
|
|
|
|
|
|
@ -1094,59 +1094,59 @@ PrintQueryStatus(PGresult *results) |
|
|
|
|
if (pset.popt.topt.format == PRINT_HTML) |
|
|
|
|
{ |
|
|
|
|
fputs("<p>", pset.queryFout); |
|
|
|
|
html_escaped_print(PQcmdStatus(results), pset.queryFout); |
|
|
|
|
html_escaped_print(PQcmdStatus(result), pset.queryFout); |
|
|
|
|
fputs("</p>\n", pset.queryFout); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
fprintf(pset.queryFout, "%s\n", PQcmdStatus(results)); |
|
|
|
|
fprintf(pset.queryFout, "%s\n", PQcmdStatus(result)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pset.logfile) |
|
|
|
|
fprintf(pset.logfile, "%s\n", PQcmdStatus(results)); |
|
|
|
|
fprintf(pset.logfile, "%s\n", PQcmdStatus(result)); |
|
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results)); |
|
|
|
|
snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(result)); |
|
|
|
|
SetVariable(pset.vars, "LASTOID", buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* PrintQueryResults: print out (or store or execute) query results as required |
|
|
|
|
* PrintQueryResult: print out (or store or execute) query result as required |
|
|
|
|
* |
|
|
|
|
* Note: Utility function for use by SendQuery() only. |
|
|
|
|
* |
|
|
|
|
* Returns true if the query executed successfully, false otherwise. |
|
|
|
|
*/ |
|
|
|
|
static bool |
|
|
|
|
PrintQueryResults(PGresult *results) |
|
|
|
|
PrintQueryResult(PGresult *result) |
|
|
|
|
{ |
|
|
|
|
bool success; |
|
|
|
|
const char *cmdstatus; |
|
|
|
|
|
|
|
|
|
if (!results) |
|
|
|
|
if (!result) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
switch (PQresultStatus(results)) |
|
|
|
|
switch (PQresultStatus(result)) |
|
|
|
|
{ |
|
|
|
|
case PGRES_TUPLES_OK: |
|
|
|
|
/* store or execute or print the data ... */ |
|
|
|
|
if (pset.gset_prefix) |
|
|
|
|
success = StoreQueryTuple(results); |
|
|
|
|
success = StoreQueryTuple(result); |
|
|
|
|
else if (pset.gexec_flag) |
|
|
|
|
success = ExecQueryTuples(results); |
|
|
|
|
success = ExecQueryTuples(result); |
|
|
|
|
else if (pset.crosstab_flag) |
|
|
|
|
success = PrintResultsInCrosstab(results); |
|
|
|
|
success = PrintResultInCrosstab(result); |
|
|
|
|
else |
|
|
|
|
success = PrintQueryTuples(results); |
|
|
|
|
success = PrintQueryTuples(result); |
|
|
|
|
/* if it's INSERT/UPDATE/DELETE RETURNING, also print status */ |
|
|
|
|
cmdstatus = PQcmdStatus(results); |
|
|
|
|
cmdstatus = PQcmdStatus(result); |
|
|
|
|
if (strncmp(cmdstatus, "INSERT", 6) == 0 || |
|
|
|
|
strncmp(cmdstatus, "UPDATE", 6) == 0 || |
|
|
|
|
strncmp(cmdstatus, "DELETE", 6) == 0) |
|
|
|
|
PrintQueryStatus(results); |
|
|
|
|
PrintQueryStatus(result); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case PGRES_COMMAND_OK: |
|
|
|
|
PrintQueryStatus(results); |
|
|
|
|
PrintQueryStatus(result); |
|
|
|
|
success = true; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
@ -1169,7 +1169,7 @@ PrintQueryResults(PGresult *results) |
|
|
|
|
default: |
|
|
|
|
success = false; |
|
|
|
|
pg_log_error("unexpected PQresultStatus: %d", |
|
|
|
|
PQresultStatus(results)); |
|
|
|
|
PQresultStatus(result)); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1181,7 +1181,7 @@ PrintQueryResults(PGresult *results) |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* SendQuery: send the query string to the backend |
|
|
|
|
* (and print out results) |
|
|
|
|
* (and print out result) |
|
|
|
|
* |
|
|
|
|
* Note: This is the "front door" way to send a query. That is, use it to |
|
|
|
|
* send queries actually entered by the user. These queries will be subject to |
|
|
|
@ -1195,7 +1195,7 @@ bool |
|
|
|
|
SendQuery(const char *query) |
|
|
|
|
{ |
|
|
|
|
bool timing = pset.timing; |
|
|
|
|
PGresult *results; |
|
|
|
|
PGresult *result; |
|
|
|
|
PGTransactionStatusType transaction_status; |
|
|
|
|
double elapsed_msec = 0; |
|
|
|
|
bool OK = false; |
|
|
|
@ -1247,15 +1247,15 @@ SendQuery(const char *query) |
|
|
|
|
!pset.autocommit && |
|
|
|
|
!command_no_begin(query)) |
|
|
|
|
{ |
|
|
|
|
results = PQexec(pset.db, "BEGIN"); |
|
|
|
|
if (PQresultStatus(results) != PGRES_COMMAND_OK) |
|
|
|
|
result = PQexec(pset.db, "BEGIN"); |
|
|
|
|
if (PQresultStatus(result) != PGRES_COMMAND_OK) |
|
|
|
|
{ |
|
|
|
|
pg_log_info("%s", PQerrorMessage(pset.db)); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
ResetCancelConn(); |
|
|
|
|
goto sendquery_cleanup; |
|
|
|
|
} |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
transaction_status = PQtransactionStatus(pset.db); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1264,15 +1264,15 @@ SendQuery(const char *query) |
|
|
|
|
(pset.cur_cmd_interactive || |
|
|
|
|
pset.on_error_rollback == PSQL_ERROR_ROLLBACK_ON)) |
|
|
|
|
{ |
|
|
|
|
results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint"); |
|
|
|
|
if (PQresultStatus(results) != PGRES_COMMAND_OK) |
|
|
|
|
result = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint"); |
|
|
|
|
if (PQresultStatus(result) != PGRES_COMMAND_OK) |
|
|
|
|
{ |
|
|
|
|
pg_log_info("%s", PQerrorMessage(pset.db)); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
ResetCancelConn(); |
|
|
|
|
goto sendquery_cleanup; |
|
|
|
|
} |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
on_error_rollback_savepoint = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1281,7 +1281,7 @@ SendQuery(const char *query) |
|
|
|
|
/* Describe query's result columns, without executing it */ |
|
|
|
|
OK = DescribeQuery(query, &elapsed_msec); |
|
|
|
|
ResetCancelConn(); |
|
|
|
|
results = NULL; /* PQclear(NULL) does nothing */ |
|
|
|
|
result = NULL; /* PQclear(NULL) does nothing */ |
|
|
|
|
} |
|
|
|
|
else if (pset.fetch_count <= 0 || pset.gexec_flag || |
|
|
|
|
pset.crosstab_flag || !is_select_command(query)) |
|
|
|
@ -1293,11 +1293,11 @@ SendQuery(const char *query) |
|
|
|
|
if (timing) |
|
|
|
|
INSTR_TIME_SET_CURRENT(before); |
|
|
|
|
|
|
|
|
|
results = PQexec(pset.db, query); |
|
|
|
|
result = PQexec(pset.db, query); |
|
|
|
|
|
|
|
|
|
/* these operations are included in the timing result: */ |
|
|
|
|
ResetCancelConn(); |
|
|
|
|
OK = ProcessResult(&results); |
|
|
|
|
OK = ProcessResult(&result); |
|
|
|
|
|
|
|
|
|
if (timing) |
|
|
|
|
{ |
|
|
|
@ -1306,16 +1306,16 @@ SendQuery(const char *query) |
|
|
|
|
elapsed_msec = INSTR_TIME_GET_MILLISEC(after); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* but printing results isn't: */ |
|
|
|
|
if (OK && results) |
|
|
|
|
OK = PrintQueryResults(results); |
|
|
|
|
/* but printing result isn't: */ |
|
|
|
|
if (OK && result) |
|
|
|
|
OK = PrintQueryResult(result); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
/* Fetch-in-segments mode */ |
|
|
|
|
OK = ExecQueryUsingCursor(query, &elapsed_msec); |
|
|
|
|
ResetCancelConn(); |
|
|
|
|
results = NULL; /* PQclear(NULL) does nothing */ |
|
|
|
|
result = NULL; /* PQclear(NULL) does nothing */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!OK && pset.echo == PSQL_ECHO_ERRORS) |
|
|
|
@ -1347,11 +1347,11 @@ SendQuery(const char *query) |
|
|
|
|
* savepoint is gone. If they issued a SAVEPOINT, releasing |
|
|
|
|
* ours would remove theirs. |
|
|
|
|
*/ |
|
|
|
|
if (results && |
|
|
|
|
(strcmp(PQcmdStatus(results), "COMMIT") == 0 || |
|
|
|
|
strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 || |
|
|
|
|
strcmp(PQcmdStatus(results), "RELEASE") == 0 || |
|
|
|
|
strcmp(PQcmdStatus(results), "ROLLBACK") == 0)) |
|
|
|
|
if (result && |
|
|
|
|
(strcmp(PQcmdStatus(result), "COMMIT") == 0 || |
|
|
|
|
strcmp(PQcmdStatus(result), "SAVEPOINT") == 0 || |
|
|
|
|
strcmp(PQcmdStatus(result), "RELEASE") == 0 || |
|
|
|
|
strcmp(PQcmdStatus(result), "ROLLBACK") == 0)) |
|
|
|
|
svptcmd = NULL; |
|
|
|
|
else |
|
|
|
|
svptcmd = "RELEASE pg_psql_temporary_savepoint"; |
|
|
|
@ -1379,7 +1379,7 @@ SendQuery(const char *query) |
|
|
|
|
ClearOrSaveResult(svptres); |
|
|
|
|
OK = false; |
|
|
|
|
|
|
|
|
|
PQclear(results); |
|
|
|
|
PQclear(result); |
|
|
|
|
ResetCancelConn(); |
|
|
|
|
goto sendquery_cleanup; |
|
|
|
|
} |
|
|
|
@ -1387,7 +1387,7 @@ SendQuery(const char *query) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
|
|
|
|
|
/* Possible microtiming output */ |
|
|
|
|
if (timing) |
|
|
|
@ -1462,7 +1462,7 @@ static bool |
|
|
|
|
DescribeQuery(const char *query, double *elapsed_msec) |
|
|
|
|
{ |
|
|
|
|
bool timing = pset.timing; |
|
|
|
|
PGresult *results; |
|
|
|
|
PGresult *result; |
|
|
|
|
bool OK; |
|
|
|
|
instr_time before, |
|
|
|
|
after; |
|
|
|
@ -1480,22 +1480,22 @@ DescribeQuery(const char *query, double *elapsed_msec) |
|
|
|
|
* anyway. (So there's no great need to clear it when done, which is a |
|
|
|
|
* good thing because libpq provides no easy way to do that.) |
|
|
|
|
*/ |
|
|
|
|
results = PQprepare(pset.db, "", query, 0, NULL); |
|
|
|
|
if (PQresultStatus(results) != PGRES_COMMAND_OK) |
|
|
|
|
result = PQprepare(pset.db, "", query, 0, NULL); |
|
|
|
|
if (PQresultStatus(result) != PGRES_COMMAND_OK) |
|
|
|
|
{ |
|
|
|
|
pg_log_info("%s", PQerrorMessage(pset.db)); |
|
|
|
|
SetResultVariables(results, false); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
SetResultVariables(result, false); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
PQclear(results); |
|
|
|
|
PQclear(result); |
|
|
|
|
|
|
|
|
|
results = PQdescribePrepared(pset.db, ""); |
|
|
|
|
OK = AcceptResult(results) && |
|
|
|
|
(PQresultStatus(results) == PGRES_COMMAND_OK); |
|
|
|
|
if (OK && results) |
|
|
|
|
result = PQdescribePrepared(pset.db, ""); |
|
|
|
|
OK = AcceptResult(result) && |
|
|
|
|
(PQresultStatus(result) == PGRES_COMMAND_OK); |
|
|
|
|
if (OK && result) |
|
|
|
|
{ |
|
|
|
|
if (PQnfields(results) > 0) |
|
|
|
|
if (PQnfields(result) > 0) |
|
|
|
|
{ |
|
|
|
|
PQExpBufferData buf; |
|
|
|
|
int i; |
|
|
|
@ -1508,7 +1508,7 @@ DescribeQuery(const char *query, double *elapsed_msec) |
|
|
|
|
gettext_noop("Column"), |
|
|
|
|
gettext_noop("Type")); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < PQnfields(results); i++) |
|
|
|
|
for (i = 0; i < PQnfields(result); i++) |
|
|
|
|
{ |
|
|
|
|
const char *name; |
|
|
|
|
char *escname; |
|
|
|
@ -1516,30 +1516,30 @@ DescribeQuery(const char *query, double *elapsed_msec) |
|
|
|
|
if (i > 0) |
|
|
|
|
appendPQExpBufferStr(&buf, ","); |
|
|
|
|
|
|
|
|
|
name = PQfname(results, i); |
|
|
|
|
name = PQfname(result, i); |
|
|
|
|
escname = PQescapeLiteral(pset.db, name, strlen(name)); |
|
|
|
|
|
|
|
|
|
if (escname == NULL) |
|
|
|
|
{ |
|
|
|
|
pg_log_info("%s", PQerrorMessage(pset.db)); |
|
|
|
|
PQclear(results); |
|
|
|
|
PQclear(result); |
|
|
|
|
termPQExpBuffer(&buf); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
appendPQExpBuffer(&buf, "(%s, '%u'::pg_catalog.oid, %d)", |
|
|
|
|
escname, |
|
|
|
|
PQftype(results, i), |
|
|
|
|
PQfmod(results, i)); |
|
|
|
|
PQftype(result, i), |
|
|
|
|
PQfmod(result, i)); |
|
|
|
|
|
|
|
|
|
PQfreemem(escname); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
appendPQExpBufferStr(&buf, ") s(name, tp, tpm)"); |
|
|
|
|
PQclear(results); |
|
|
|
|
PQclear(result); |
|
|
|
|
|
|
|
|
|
results = PQexec(pset.db, buf.data); |
|
|
|
|
OK = AcceptResult(results); |
|
|
|
|
result = PQexec(pset.db, buf.data); |
|
|
|
|
OK = AcceptResult(result); |
|
|
|
|
|
|
|
|
|
if (timing) |
|
|
|
|
{ |
|
|
|
@ -1548,8 +1548,8 @@ DescribeQuery(const char *query, double *elapsed_msec) |
|
|
|
|
*elapsed_msec += INSTR_TIME_GET_MILLISEC(after); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (OK && results) |
|
|
|
|
OK = PrintQueryResults(results); |
|
|
|
|
if (OK && result) |
|
|
|
|
OK = PrintQueryResult(result); |
|
|
|
|
|
|
|
|
|
termPQExpBuffer(&buf); |
|
|
|
|
} |
|
|
|
@ -1558,8 +1558,8 @@ DescribeQuery(const char *query, double *elapsed_msec) |
|
|
|
|
_("The command has no result, or the result has no columns.\n")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SetResultVariables(results, OK); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
SetResultVariables(result, OK); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
|
|
|
|
|
return OK; |
|
|
|
|
} |
|
|
|
@ -1579,7 +1579,7 @@ static bool |
|
|
|
|
ExecQueryUsingCursor(const char *query, double *elapsed_msec) |
|
|
|
|
{ |
|
|
|
|
bool OK = true; |
|
|
|
|
PGresult *results; |
|
|
|
|
PGresult *result; |
|
|
|
|
PQExpBufferData buf; |
|
|
|
|
printQueryOpt my_popt = pset.popt; |
|
|
|
|
bool timing = pset.timing; |
|
|
|
@ -1608,10 +1608,10 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) |
|
|
|
|
/* if we're not in a transaction, start one */ |
|
|
|
|
if (PQtransactionStatus(pset.db) == PQTRANS_IDLE) |
|
|
|
|
{ |
|
|
|
|
results = PQexec(pset.db, "BEGIN"); |
|
|
|
|
OK = AcceptResult(results) && |
|
|
|
|
(PQresultStatus(results) == PGRES_COMMAND_OK); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
result = PQexec(pset.db, "BEGIN"); |
|
|
|
|
OK = AcceptResult(result) && |
|
|
|
|
(PQresultStatus(result) == PGRES_COMMAND_OK); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
if (!OK) |
|
|
|
|
return false; |
|
|
|
|
started_txn = true; |
|
|
|
@ -1622,12 +1622,12 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) |
|
|
|
|
appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s", |
|
|
|
|
query); |
|
|
|
|
|
|
|
|
|
results = PQexec(pset.db, buf.data); |
|
|
|
|
OK = AcceptResult(results) && |
|
|
|
|
(PQresultStatus(results) == PGRES_COMMAND_OK); |
|
|
|
|
result = PQexec(pset.db, buf.data); |
|
|
|
|
OK = AcceptResult(result) && |
|
|
|
|
(PQresultStatus(result) == PGRES_COMMAND_OK); |
|
|
|
|
if (!OK) |
|
|
|
|
SetResultVariables(results, OK); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
SetResultVariables(result, OK); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
termPQExpBuffer(&buf); |
|
|
|
|
if (!OK) |
|
|
|
|
goto cleanup; |
|
|
|
@ -1678,7 +1678,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) |
|
|
|
|
INSTR_TIME_SET_CURRENT(before); |
|
|
|
|
|
|
|
|
|
/* get fetch_count tuples at a time */ |
|
|
|
|
results = PQexec(pset.db, fetch_cmd); |
|
|
|
|
result = PQexec(pset.db, fetch_cmd); |
|
|
|
|
|
|
|
|
|
if (timing) |
|
|
|
|
{ |
|
|
|
@ -1687,7 +1687,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) |
|
|
|
|
*elapsed_msec += INSTR_TIME_GET_MILLISEC(after); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (PQresultStatus(results) != PGRES_TUPLES_OK) |
|
|
|
|
if (PQresultStatus(result) != PGRES_TUPLES_OK) |
|
|
|
|
{ |
|
|
|
|
/* shut down pager before printing error message */ |
|
|
|
|
if (is_pager) |
|
|
|
@ -1696,18 +1696,18 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) |
|
|
|
|
is_pager = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
OK = AcceptResult(results); |
|
|
|
|
OK = AcceptResult(result); |
|
|
|
|
Assert(!OK); |
|
|
|
|
SetResultVariables(results, OK); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
SetResultVariables(result, OK); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pset.gset_prefix) |
|
|
|
|
{ |
|
|
|
|
/* StoreQueryTuple will complain if not exactly one row */ |
|
|
|
|
OK = StoreQueryTuple(results); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
OK = StoreQueryTuple(result); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1715,7 +1715,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) |
|
|
|
|
* Note we do not deal with \gdesc, \gexec or \crosstabview modes here |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
ntuples = PQntuples(results); |
|
|
|
|
ntuples = PQntuples(result); |
|
|
|
|
total_tuples += ntuples; |
|
|
|
|
|
|
|
|
|
if (ntuples < fetch_count) |
|
|
|
@ -1733,9 +1733,9 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) |
|
|
|
|
is_pager = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
printQuery(results, &my_popt, fout, is_pager, pset.logfile); |
|
|
|
|
printQuery(result, &my_popt, fout, is_pager, pset.logfile); |
|
|
|
|
|
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
|
|
|
|
|
/* after the first result set, disallow header decoration */ |
|
|
|
|
my_popt.topt.start_table = false; |
|
|
|
@ -1802,22 +1802,22 @@ cleanup: |
|
|
|
|
* ignore the result (it's probably just a bleat about being in an aborted |
|
|
|
|
* transaction) |
|
|
|
|
*/ |
|
|
|
|
results = PQexec(pset.db, "CLOSE _psql_cursor"); |
|
|
|
|
result = PQexec(pset.db, "CLOSE _psql_cursor"); |
|
|
|
|
if (OK) |
|
|
|
|
{ |
|
|
|
|
OK = AcceptResult(results) && |
|
|
|
|
(PQresultStatus(results) == PGRES_COMMAND_OK); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
OK = AcceptResult(result) && |
|
|
|
|
(PQresultStatus(result) == PGRES_COMMAND_OK); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
PQclear(results); |
|
|
|
|
PQclear(result); |
|
|
|
|
|
|
|
|
|
if (started_txn) |
|
|
|
|
{ |
|
|
|
|
results = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK"); |
|
|
|
|
OK &= AcceptResult(results) && |
|
|
|
|
(PQresultStatus(results) == PGRES_COMMAND_OK); |
|
|
|
|
ClearOrSaveResult(results); |
|
|
|
|
result = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK"); |
|
|
|
|
OK &= AcceptResult(result) && |
|
|
|
|
(PQresultStatus(result) == PGRES_COMMAND_OK); |
|
|
|
|
ClearOrSaveResult(result); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (timing) |
|
|
|
|