diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 3b86612..d33da32 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -3449,6 +3449,35 @@ bar + ERROR + + + Whether the last query failed, as a boolean. + + + + + + ERROR_CODE + + + The error code associated to the last query, or + 00000 if no error occured. + + + + + + ERROR_MESSAGE + + + If the last query failed, the associated error message, + otherwise an empty string. + + + + + FETCH_COUNT @@ -3653,6 +3682,24 @@ bar + STATUS + + + Text status of the last query. + + + + + + ROW_COUNT + + + How many rows were returned or affected by the last query. + + + + + QUIET diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index a2f1259..4a3c6a9 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -1213,6 +1213,62 @@ PrintQueryResults(PGresult *results) return success; } +/* + * Set special variables for "front door" queries + * - STATUS: last query status + * - ERROR: TRUE/FALSE, whether an error occurred + * - ERROR_CODE: code if an error occured, or "00000" + * - ERROR_MESSAGE: message if an error occured, or "" + * - ROW_COUNT: how many rows were returned or affected, or "0" + */ +static void +SetResultVariables(PGresult *results) +{ + bool success; + ExecStatusType restat = PQresultStatus(results); + char *code = PQresultErrorField(results, PG_DIAG_SQLSTATE); + char *mesg = PQresultErrorField(results, PG_DIAG_MESSAGE_PRIMARY); + + SetVariable(pset.vars, "STATUS", PQresStatus(restat) + strlen("PGRES_")); + SetVariable(pset.vars, "ERROR_CODE", code ? code : "00000"); + SetVariable(pset.vars, "ERROR_MESSAGE", mesg ? mesg : ""); + + /* check all possible PGRES_ */ + switch (restat) + { + case PGRES_EMPTY_QUERY: + case PGRES_TUPLES_OK: + case PGRES_COMMAND_OK: + case PGRES_COPY_OUT: + case PGRES_COPY_IN: + case PGRES_COPY_BOTH: + case PGRES_SINGLE_TUPLE: + success = true; + break; + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: + case PGRES_FATAL_ERROR: + success = false; + break; + default: + /* dead code */ + success = false; + psql_error("unexpected PQresultStatus: %d\n", restat); + break; + } + + if (success) + { + char *ntuples = PQcmdTuples(results); + SetVariable(pset.vars, "ROW_COUNT", *ntuples ? ntuples : "0"); + SetVariable(pset.vars, "ERROR", "TRUE"); + } + else + { + SetVariable(pset.vars, "ROW_COUNT", "0"); + SetVariable(pset.vars, "ERROR", "FALSE"); + } +} /* * SendQuery: send the query string to the backend @@ -1346,6 +1402,9 @@ SendQuery(const char *query) elapsed_msec = INSTR_TIME_GET_MILLISEC(after); } + /* set special variables to reflect the result status */ + SetResultVariables(results); + /* but printing results isn't: */ if (OK && results) OK = PrintQueryResults(results); diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index d602aee..eaf538a 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -2904,6 +2904,60 @@ bar 'bar' "bar" \echo 'should print #8-1' should print #8-1 \endif +-- special result variables +-- 2 rows select +SELECT 1 AS stuff UNION SELECT 2; + stuff +------- + 1 + 2 +(2 rows) + +\echo 'status:' :STATUS +status: TUPLES_OK +\echo 'error code:' :ERROR_CODE +error code: 00000 +\echo 'error message:' :ERROR_MESSAGE +error message: +\echo 'number of rows:' :ROW_COUNT +number of rows: 2 +-- syntax error +SELECT 1 UNION; +ERROR: syntax error at or near ";" +LINE 1: SELECT 1 UNION; + ^ +\echo 'status:' :STATUS +status: FATAL_ERROR +\if :ERROR + \echo 'Oops, an error occured...' +\endif +\echo 'error code:' :ERROR_CODE +error code: 42601 +\echo 'error message:' :ERROR_MESSAGE +error message: syntax error at or near ";" +\echo 'number of rows:' :ROW_COUNT +number of rows: 0 +-- empty query +; +\echo 'status:' :STATUS +status: EMPTY_QUERY +\echo 'error code:' :ERROR_CODE +error code: 00000 +\echo 'error message:' :ERROR_MESSAGE +error message: +\echo 'number of rows:' :ROW_COUNT +number of rows: 0 +-- other query error +DROP TABLE this_table_does_not_exist; +ERROR: table "this_table_does_not_exist" does not exist +\echo 'status:' :STATUS +status: FATAL_ERROR +\echo 'error code:' :ERROR_CODE +error code: 42P01 +\echo 'error message:' :ERROR_MESSAGE +error message: table "this_table_does_not_exist" does not exist +\echo 'number of rows:' :ROW_COUNT +number of rows: 0 -- SHOW_CONTEXT \set SHOW_CONTEXT never do $$ diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index b56a05f..79efa74 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -526,6 +526,39 @@ select \if false \\ (bogus \else \\ 42 \endif \\ forty_two; \echo 'should print #8-1' \endif +-- special result variables + +-- 2 rows select +SELECT 1 AS stuff UNION SELECT 2; +\echo 'status:' :STATUS +\echo 'error code:' :ERROR_CODE +\echo 'error message:' :ERROR_MESSAGE +\echo 'number of rows:' :ROW_COUNT + +-- syntax error +SELECT 1 UNION; +\echo 'status:' :STATUS +\if :ERROR + \echo 'Oops, an error occured...' +\endif +\echo 'error code:' :ERROR_CODE +\echo 'error message:' :ERROR_MESSAGE +\echo 'number of rows:' :ROW_COUNT + +-- empty query +; +\echo 'status:' :STATUS +\echo 'error code:' :ERROR_CODE +\echo 'error message:' :ERROR_MESSAGE +\echo 'number of rows:' :ROW_COUNT + +-- other query error +DROP TABLE this_table_does_not_exist; +\echo 'status:' :STATUS +\echo 'error code:' :ERROR_CODE +\echo 'error message:' :ERROR_MESSAGE +\echo 'number of rows:' :ROW_COUNT + -- SHOW_CONTEXT \set SHOW_CONTEXT never