# HG changeset patch # User i7tiol # Date 1456571464 0 # Node ID 1af86934c14e67b0687711ce357d6236ed8358f2 # Parent 87989220360f9bd988e0d09b42b7ddcad3cced9b Make compatible with Octaves new exception-based error handling. Retain compatibility with Octaves old error handling based on error_state. * src/error_helpers.[h,cc]: Added. * src/Makefile.in: Integrate error-helpers.[h,cc]. * src/config.h.in: Added. * configure.ac, src/config.h.in: Test presence of 'error_state' and presence of 'verror (octave_execution_exception&, const char *, va_list)'. * src/__pq_connect__.cc, src/command.cc, src/command.h, src/converters.cc, src/converters_arr_comp.cc, src/pq_connection.cc, src/pq_conninfo.cc, src/pq_exec.cc, src/pq_lo.cc, src/pq_update_types.cc: If necessary, include error-helpers.h, replace error() with c_verror(), set and check a different error indicator than error_state, use CHECK_ERROR or SET_ERR, explicitely check for errors instead of relying on Octave checking error_state when returning to the prompt. diff -r 87989220360f -r 1af86934c14e main/database/NEWS --- a/main/database/NEWS Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/NEWS Sat Feb 27 11:11:04 2016 +0000 @@ -1,3 +1,7 @@ + ** Compatible with Octaves new exception-based error + handling. Compatibility with old error handling up to Octave-4.0 + is retained. + ** Fix: remove autoloaded function at package unload. database 2.3.2 diff -r 87989220360f -r 1af86934c14e main/database/src/Makefile.in --- a/main/database/src/Makefile.in Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/Makefile.in Sat Feb 27 11:11:04 2016 +0000 @@ -8,27 +8,29 @@ ifndef CXXFLAGS CXXFLAGS_NSA := "-g -O2 -fno-strict-aliasing" +CXXFLAGS := "-g -O2" else CXXFLAGS_NSA := "$(CXXFLAGS) -fno-strict-aliasing" endif OBJECTS := __pq_connect__.o pq_close.o pq_exec.o converters.o \ converters_arr_comp.o pq_connection.o command.o \ - pq_update_types.o pq_lo.o pq_conninfo.o __pq_internal_exit__.o + pq_update_types.o pq_lo.o pq_conninfo.o __pq_internal_exit__.o \ + error-helpers.o pq_interface.oct: $(OBJECTS) @MKOCTFILE@ -o pq_interface.oct -L`@PG_CONFIG@ --libdir` -lpq $(OBJECTS) $(EXTRALIBS) -converters.o: converters.cc converters.h wrap_endian.h +converters.o: converters.cc converters.h wrap_endian.h config.h error-helpers.h CXX=$(CXX) CXXFLAGS=$(CXXFLAGS_NSA) @MKOCTFILE@ -I`@PG_CONFIG@ --includedir` -c converters.cc converters_arr_comp.o: converters_arr_comp.cc converters.h wrap_endian.h \ - pq_connection.h command.h + pq_connection.h command.h config.h error-helpers.h CXX=$(CXX) CXXFLAGS=$(CXXFLAGS_NSA) @MKOCTFILE@ -I`@PG_CONFIG@ --includedir` -c converters_arr_comp.cc # be on the safe side with respect to include files -%.o: %.cc converters.h pq_connection.h command.h - CXX=$(CXX) @MKOCTFILE@ -I`@PG_CONFIG@ --includedir` -c $< +%.o: %.cc converters.h pq_connection.h command.h config.h error-helpers.h + CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) @MKOCTFILE@ -I`@PG_CONFIG@ --includedir` -c $< .PHONY: clean clean: ; rm -f *.o *.oct diff -r 87989220360f -r 1af86934c14e main/database/src/__pq_connect__.cc --- a/main/database/src/__pq_connect__.cc Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/__pq_connect__.cc Sat Feb 27 11:11:04 2016 +0000 @@ -20,6 +20,7 @@ #include #include "pq_connection.h" +#include "error-helpers.h" // PKG_ADD: autoload ("__pq_connect__", "pq_interface.oct"); @@ -34,6 +35,8 @@ { std::string fname ("__pq_connect__"); + octave_value retval; + if (args.length () != 1) { print_usage (); @@ -41,21 +44,16 @@ return octave_value_list (); } - std::string opt_string = args(0).string_value (); + std::string opt_string; + CHECK_ERROR (opt_string = args(0).string_value (), retval, + "%s: argument not a string", fname.c_str ()); - if (error_state) - { - error ("%s: argument not a string", fname.c_str ()); + octave_pq_connection *oct_pq_conn = new octave_pq_connection (opt_string); - return octave_value_list (); - } - - octave_value retval (new octave_pq_connection (opt_string)); + if (! oct_pq_conn->get_rep ()->octave_pq_get_conn ()) + error ("%s failed", fname.c_str ()); + else + retval = oct_pq_conn; - // We spare checking - // bool(octave_pq_connection_rep::octave_pq_get_conn()), since in - // case of false there was an error thrown, so destruction of the - // octave_pq_connection object will be caused by Octaves reference - // counting scheme. return retval; } diff -r 87989220360f -r 1af86934c14e main/database/src/command.cc --- a/main/database/src/command.cc Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/command.cc Sat Feb 27 11:11:04 2016 +0000 @@ -27,6 +27,7 @@ #include "command.h" #include "converters.h" +#include "error-helpers.h" #define COPY_HEADER_SIZE 19 @@ -40,14 +41,14 @@ if (! (cptr = conn.octave_pq_get_conn ())) { valid = 0; - error ("%s: connection not open", caller.c_str ()); + c_verror ("%s: connection not open", caller.c_str ()); } if (! PQsendQuery (cptr, cmd.c_str ())) { valid = 0; - error ("%s: could not dispatch command: %s", caller.c_str (), - PQerrorMessage (cptr)); + c_verror ("%s: could not dispatch command: %s", caller.c_str (), + PQerrorMessage (cptr)); } else { @@ -64,10 +65,10 @@ if (! (cptr = conn.octave_pq_get_conn ())) { valid = 0; - error ("%s: connection not open", caller.c_str ()); + c_verror ("%s: connection not open", caller.c_str ()); } - int npars = params.length (); + int npars = params.numel (); char *vals [npars]; std::vector valsvec; @@ -106,12 +107,14 @@ } else { - std::string s = ptypes(i).string_value (); - if (error_state) + bool err; + std::string s; + SET_ERR (s = ptypes(i).string_value (), err); + if (err) { - error ("%s: parameter type specification no string", - caller.c_str ()); valid = 0; + c_verror ("%s: parameter type specification no string", + caller.c_str ()); break; } @@ -146,10 +149,10 @@ default: // should not get here - error ("%s: internal error, undefined type identifier", - caller.c_str ()); + valid = 0; + c_verror ("%s: internal error, undefined type identifier", + caller.c_str ()); - valid = 0; } if (! valid) break; @@ -241,12 +244,12 @@ { case PGRES_BAD_RESPONSE: valid = 0; - error ("%s: server response not understood", caller.c_str ()); + c_verror ("%s: server response not understood", caller.c_str ()); break; case PGRES_FATAL_ERROR: valid = 0; - error ("%s: fatal error: %s", caller.c_str (), - PQresultErrorMessage (res)); + c_verror ("%s: fatal error: %s", caller.c_str (), + PQresultErrorMessage (res)); break; case PGRES_COMMAND_OK: retval = command_ok_handler (); @@ -264,7 +267,7 @@ break; default: valid = 0; - error ("internal error, unexpected server response"); + c_verror ("internal error, unexpected server response"); } if (res) // could have been changed by a handler @@ -294,13 +297,14 @@ octave_map types (dim_vector (1, nf)); bool rtypes_given; - int l = rettypes.length (); + int l = rettypes.numel (); if (l > 0) { if (l != nf) { - error ("%s: wrong number of given returned types", caller.c_str ()); valid = 0; + c_verror ("%s: wrong number of given returned types", + caller.c_str ()); return octave_value_list (); } rtypes_given = true; @@ -324,25 +328,27 @@ if (rtypes_given) // for internal reading of system tables { - std::string type = rettypes(j).string_value (); - if (error_state) - error ("%s: could not convert given type to string", - caller.c_str ()); - else - conv = pgtype_from_spec (conn, type, oct_type); - - if (error_state) + std::string type; + bool err; + SET_ERR (type = rettypes(j).string_value (), err); + if (err) + { + valid = 0; + c_verror ("%s: could not convert given type to string", + caller.c_str ()); + break; + } + else if (! (conv = pgtype_from_spec (conn, type, oct_type))) { valid = 0; break; } } - else - if (! (conv = pgtype_from_spec (conn, PQftype (res, j), oct_type))) - { - valid = 0; - break; - } + else if (! (conv = pgtype_from_spec (conn, PQftype (res, j), oct_type))) + { + valid = 0; + break; + } if (f) { @@ -413,8 +419,8 @@ default: // should not get here - error ("%s: internal error, undefined type identifier", - caller.c_str ()); + c_verror ("%s: internal error, undefined type identifier", + caller.c_str ()); valid = 0; } @@ -430,7 +436,7 @@ break; } - if (error_state) + if (! valid) return octave_value_list (); else { @@ -456,19 +462,14 @@ { // store unchecked output in file - if (outfile.empty ()) + std::ofstream ostr (outfile.c_str (), std::ios_base::out); + if (ostr.fail ()) { - error ("no output file given"); - valid = 0; - + c_verror ("could not open output file %s", outfile.c_str ()); return retval; } - std::ofstream ostr (outfile.c_str (), std::ios_base::out); - if (ostr.fail ()) - error ("could not open output file %s", outfile.c_str ()); - char *data; int nb; while ((nb = PQgetCopyData (cptr, &data, 0)) > 0) @@ -477,16 +478,19 @@ { ostr.write (data, nb); if (ostr.bad ()) - error ("write to file failed"); + c_verror ("write to file failed"); } PQfreemem (data); } - if (! error_state) + if (! ostr.bad ()) ostr.close (); if (nb == -2) - error ("server error in copy-out: %s", PQerrorMessage (cptr)); + { + valid = 0; + c_verror ("server error in copy-out: %s", PQerrorMessage (cptr)); + } else { PQclear (res); @@ -494,17 +498,24 @@ if ((res = PQgetResult (cptr))) { if ((state = PQresultStatus (res)) == PGRES_FATAL_ERROR) - error ("server error in copy-out: %s", PQerrorMessage (cptr)); + { + valid = 0; + c_verror ("server error in copy-out: %s", + PQerrorMessage (cptr)); + } } else - error ("unexpectedly got no result information"); + { + valid = 0; + c_verror ("unexpectedly got no result information"); + } } } else - error ("no output file given"); - - if (error_state) - valid = 0; + { + valid = 0; + c_verror ("no output file given"); + } return octave_value (std::string ("copy out")); } @@ -527,9 +538,9 @@ if (infile.empty ()) { - error ("no input file given"); + valid = 0; - valid = 0; + c_verror ("no input file given"); return retval; } @@ -537,11 +548,11 @@ std::ifstream istr (infile.c_str (), std::ios_base::in); if (istr.fail ()) { - error ("could not open input file %s", infile.c_str ()); + c_verror ("could not open input file %s", infile.c_str ()); PQputCopyEnd (cptr, "could not open input file"); - error ("server error: %s", PQerrorMessage (cptr)); + c_verror ("server error: %s", PQerrorMessage (cptr)); valid = 0; @@ -554,7 +565,9 @@ if (istr.bad ()) { - error ("could not read file %s", infile.c_str ()); + valid = 0; + + c_verror ("could not read file %s", infile.c_str ()); break; } @@ -565,7 +578,9 @@ if ((nb = istr.gcount ()) > 0) if (PQputCopyData (cptr, buff, nb) == -1) { - error ("%s", PQerrorMessage (cptr)); + valid = 0; + + c_verror ("%s", PQerrorMessage (cptr)); break; } @@ -575,16 +590,19 @@ istr.close (); - if (error_state) + if (! valid) { PQputCopyEnd (cptr, "copy-in interrupted"); - error ("%s", PQerrorMessage (cptr)); + c_verror ("%s", PQerrorMessage (cptr)); } else { if (PQputCopyEnd (cptr, NULL) == -1) - error ("%s", PQerrorMessage (cptr)); + { + valid = 0; + c_verror ("%s", PQerrorMessage (cptr)); + } else { PQclear (res); @@ -592,10 +610,17 @@ if ((res = PQgetResult (cptr))) { if ((state = PQresultStatus (res)) == PGRES_FATAL_ERROR) - error ("server error in copy-in: %s", PQerrorMessage (cptr)); + { + valid = 0; + c_verror ("server error in copy-in: %s", + PQerrorMessage (cptr)); + } } else - error ("unexpectedly got no result information"); + { + valid = 0; + c_verror ("unexpectedly got no result information"); + } } } } @@ -610,15 +635,19 @@ octave_idx_type nf = PQnfields (res); if (c != nf + oids) { - error ("variable for copy-in has %i columns, but should have %i", - c, nf + oids); + valid = 0; + + c_verror ("variable for copy-in has %i columns, but should have %i", + c, nf + oids); PQputCopyEnd (cptr, "variable for copy-in has wrong number of columns"); } else if (! PQbinaryTuples (res)) { - error ("copy-in from variable must use binary mode"); + valid = 0; + + c_verror ("copy-in from variable must use binary mode"); PQputCopyEnd (cptr, "copy-in from variable must use binary mode"); } @@ -627,7 +656,9 @@ for (octave_idx_type j = 0; j < nf; j++) if (! PQfformat (res, j)) { - error ("copy-in from variable must use binary mode in all columns"); + valid = 0; + + c_verror ("copy-in from variable must use binary mode in all columns"); PQputCopyEnd (cptr, "copy-in from variable must use binary mode in all columns"); @@ -635,11 +666,9 @@ } } - if (error_state) + if (! valid) { - error ("server error: %s", PQerrorMessage (cptr)); - - valid = 0; + c_verror ("server error: %s", PQerrorMessage (cptr)); return retval; } @@ -658,7 +687,9 @@ { PQputCopyEnd (cptr, "could not send header"); - error ("server error: %s", PQerrorMessage (cptr)); + valid = 0; + + c_verror ("server error: %s", PQerrorMessage (cptr)); } else { @@ -671,11 +702,13 @@ int16_t fc = htobe16 (int16_t (nf)); if (PQputCopyData (cptr, (char *) &fc, 2) == -1) { - error ("%s", PQerrorMessage (cptr)); + c_verror ("%s", PQerrorMessage (cptr)); PQputCopyEnd (cptr, "error sending field count"); - error ("server error: %s", PQerrorMessage (cptr)); + c_verror ("server error: %s", PQerrorMessage (cptr)); + + valid = 0; break; } @@ -689,7 +722,9 @@ int32_t t = htobe32 (int32_t (-1)); if (PQputCopyData (cptr, (char *) &t, 4) == -1) { - error ("could not send NULL in copy-in"); + valid = 0; + + c_verror ("could not send NULL in copy-in"); break; } @@ -701,8 +736,14 @@ if ((j == 0) && oids) { std::string t ("oid"); - convs[0] = pgtype_from_spec (conn, t, - oct_types[0]); + if (! (convs[0] = + pgtype_from_spec (conn, t, oct_types[0]))) + { + valid = 0; + + c_verror ("could not get converter for oid in copy-in"); + break; + } } else { @@ -714,18 +755,25 @@ pgtype_from_octtype (conn, data(i, j)))) { - error ("could not determine type in column %i for copy-in", - j); + valid = 0; + + c_verror ("could not determine type in column %i for copy-in", + j); break; } } else { - std::string s = cin_types(j).string_value (); - if (error_state) + bool err; + std::string s; + SET_ERR (s = cin_types(j).string_value (), + err); + if (err) { - error ("column type specification no string"); + valid = 0; + + c_verror ("column type specification no string"); break; } @@ -734,7 +782,9 @@ pgtype_from_spec (conn, s, oct_types[j]))) { - error ("invalid column type specification"); + valid = 0; + + c_verror ("invalid column type specification"); break; } @@ -766,49 +816,64 @@ default: // should not get here - error ("internal error, undefined type identifier"); + c_verror ("internal error, undefined type identifier"); + conversion_failed = true; } if (conversion_failed) - error ("could not convert data(%i, %i) for copy-in", - i, j); + { + valid = 0; + error ("could not convert data(%i, %i) for copy-in", + i, j); + } else { uint32_t t = htobe32 (uint32_t (val.size ())); if (PQputCopyData (cptr, (char *) &t, 4) == -1) - error ("could not send data length in copy-in"); + { + valid = 0; + c_verror ("could not send data length in copy-in"); + } else if (PQputCopyData (cptr, &(val.front ()), val.size ()) == -1) - error ("could not send copy-in data"); + { + valid = 0; + c_verror ("could not send copy-in data"); + } } - if (error_state) break; + if (! valid) break; } } // columns of argument data - if (error_state) + if (! valid) { PQputCopyEnd (cptr, "error sending copy-in data"); - error ("server error: %s", PQerrorMessage (cptr)); + c_verror ("server error: %s", PQerrorMessage (cptr)); break; } } // rows of argument data } - if (! error_state) + if (valid) if (PQputCopyData (cptr, trailer, 2) == -1) { + valid = 0; + PQputCopyEnd (cptr, "could not send trailer"); - error ("%s", PQerrorMessage (cptr)); + c_verror ("%s", PQerrorMessage (cptr)); } - if (! error_state) + if (valid) { if (PQputCopyEnd (cptr, NULL) == -1) - error ("%s", PQerrorMessage (cptr)); + { + valid = 0; + c_verror ("%s", PQerrorMessage (cptr)); + } else { PQclear (res); @@ -816,17 +881,20 @@ if ((res = PQgetResult (cptr))) { if ((state = PQresultStatus (res)) == PGRES_FATAL_ERROR) - error ("server error in copy-in: %s", - PQerrorMessage (cptr)); + { + valid = 0; + c_verror ("server error in copy-in: %s", + PQerrorMessage (cptr)); + } } else - error ("unexpectedly got no result information"); + { + valid = 0; + c_verror ("unexpectedly got no result information"); + } } } } // copy from variable - if (error_state) - valid = 0; - return octave_value (std::string ("copy in")); } diff -r 87989220360f -r 1af86934c14e main/database/src/command.h --- a/main/database/src/command.h Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/command.h Sat Feb 27 11:11:04 2016 +0000 @@ -26,6 +26,7 @@ #include #include "pq_connection.h" +#include "error-helpers.h" class command @@ -87,14 +88,14 @@ if (! res) { valid = 0; - error ("%s: could not execute command: %s", caller.c_str (), - PQerrorMessage (cptr)); + c_verror ("%s: could not execute command: %s", caller.c_str (), + PQerrorMessage (cptr)); } else if ((state = PQresultStatus (res)) == PGRES_EMPTY_QUERY) { valid = 0; - error ("%s: empty command", caller.c_str ()); + c_verror ("%s: empty command", caller.c_str ()); } } diff -r 87989220360f -r 1af86934c14e main/database/src/config.h.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/database/src/config.h.in Sat Feb 27 11:11:04 2016 +0000 @@ -0,0 +1,6 @@ +/* Define as 1 if liboctinterp is old enough to provide error_state. */ +#undef HAVE_OCTAVE_ERROR_STATE + +/* Define as 1 if liboctinterp has +'verror (octave_execution_exception&, const char *, va_list)'. */ +#undef HAVE_OCTAVE_VERROR_ARG_EXC diff -r 87989220360f -r 1af86934c14e main/database/src/configure.ac --- a/main/database/src/configure.ac Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/configure.ac Sat Feb 27 11:11:04 2016 +0000 @@ -4,6 +4,7 @@ AC_PREREQ([2.67]) AC_INIT([database], [2.2.0], [i7tiol@t-online.de]) AC_CONFIG_SRCDIR([__pq_connect__.cc]) +AC_CONFIG_HEADERS([config.h]) # Checks for programs. AC_PROG_CXX @@ -13,6 +14,7 @@ AC_CHECK_PROG(OCTAVE, octave, octave) AC_CHECK_PROG(MKOCTFILE, mkoctfile, mkoctfile) +AC_CHECK_PROG(OCTAVE_CONFIG, octave-config, octave-config) AC_CHECK_PROG(PG_CONFIG, pg_config, pg_config) if test -z "$PG_CONFIG"; then AC_MSG_ERROR([pg_config not found], 1); @@ -38,5 +40,39 @@ AC_MSG_RESULT(yes) fi +# Start of checks for Octave features, preparations for checks. +OCTLIBDIR=${OCTLIBDIR:-`$OCTAVE_CONFIG -p OCTLIBDIR`} +OCTINCLUDEDIR=${OCTINCLUDEDIR:-`$OCTAVE_CONFIG -p OCTINCLUDEDIR`} +AC_LANG_PUSH([C++]) +TCXXFLAGS=$CXXFLAGS +TLDFLAGS=$LDFLAGS +TLIBS=$LIBS +LDFLAGS="-L$OCTLIBDIR $LDFLAGS" +LIBS="-loctinterp $LIBS" +CXXFLAGS="-I$OCTINCLUDEDIR $CXXFLAGS" + +## Presence of 'error_state' -- does _not_ indicate no exceptions are +## used. +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[#include ] + [#include ]], + [[printf ("%i", error_state);]])], + [AC_DEFINE([HAVE_OCTAVE_ERROR_STATE], 1)]) + +## Presence of 'verror (octave_execution_exception&, const char *, +## va_list)' +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[octave_execution_exception e;] + [va_list args;] + [verror (e, "test", args);]])], + [AC_DEFINE([HAVE_OCTAVE_VERROR_ARG_EXC], 1)]) + +LIBS=$TLIBS +LDFLAGS=$TLDFLAGS +CXXFLAGS=$TCXXFLAGS +AC_LANG_POP([C++]) +# End of checks for Octave features. + AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff -r 87989220360f -r 1af86934c14e main/database/src/converters.cc --- a/main/database/src/converters.cc Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/converters.cc Sat Feb 27 11:11:04 2016 +0000 @@ -33,6 +33,7 @@ #include "converters.h" #include "pq_connection.h" +#include "error-helpers.h" // remember to adjust OCT_PQ_NUM_CONVERTERS in converters.h @@ -75,11 +76,12 @@ int from_octave_str_bool (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - bool b = ov.bool_value (); - - if (error_state) + bool b, err; + SET_ERR (b = ov.bool_value (), err); + + if (err) { - error ("can not convert octave_value to bool value"); + c_verror ("can not convert octave_value to bool value"); return 1; } @@ -92,11 +94,12 @@ int from_octave_bin_bool (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - bool b = ov.bool_value (); - - if (error_state) + bool b, err; + SET_ERR (b = ov.bool_value (), err); + + if (err) { - error ("can not convert octave_value to bool value"); + c_verror ("can not convert octave_value to bool value"); return 1; } @@ -145,11 +148,13 @@ int from_octave_bin_oid (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - uint32_t oid = ov.uint_value (); - - if (error_state) + uint32_t oid; + bool err; + SET_ERR (oid = ov.uint_value (), err); + + if (err) { - error ("can not convert octave_value to oid value"); + c_verror ("can not convert octave_value to oid value"); return 1; } @@ -218,11 +223,12 @@ } swap; - swap.d = ov.double_value (); - - if (error_state) + bool err; + SET_ERR (swap.d = ov.double_value (), err); + + if (err) { - error ("can not convert octave_value to float8 value"); + c_verror ("can not convert octave_value to float8 value"); return 1; } @@ -291,11 +297,12 @@ } swap; - swap.f = ov.float_value (); - - if (error_state) + bool err; + SET_ERR (swap.f = ov.float_value (), err); + + if (err) { - error ("can not convert octave_value to float4 value"); + c_verror ("can not convert octave_value to float4 value"); return 1; } @@ -350,11 +357,13 @@ int from_octave_bin_bytea (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - uint8NDArray b = ov.uint8_array_value (); - - if (error_state) + uint8NDArray b; + bool err; + SET_ERR (b = ov.uint8_array_value (), err); + + if (err) { - error ("can not convert octave_value to bytea representation"); + c_verror ("can not convert octave_value to bytea representation"); return 1; } @@ -408,11 +417,13 @@ int from_octave_bin_text (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - std::string s = ov.string_value (); - - if (error_state) + std::string s; + bool err; + SET_ERR (s = ov.string_value (), err); + + if (err) { - error ("can not convert octave_value to string"); + c_verror ("can not convert octave_value to string"); return 1; } @@ -515,11 +526,13 @@ int from_octave_bin_int2 (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - int16_t i2 = ov.int_value (); - - if (error_state) + int16_t i2; + bool err; + SET_ERR (i2 = ov.int_value (), err); + + if (err) { - error ("can not convert octave_value to int2 value"); + c_verror ("can not convert octave_value to int2 value"); return 1; } @@ -569,11 +582,13 @@ int from_octave_bin_int4 (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - int32_t i4 = ov.int_value (); - - if (error_state) + int32_t i4; + bool err; + SET_ERR (i4 = ov.int_value (), err); + + if (err) { - error ("can not convert octave_value to int4 value"); + c_verror ("can not convert octave_value to int4 value"); return 1; } @@ -623,11 +638,13 @@ int from_octave_bin_int8 (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - int64_t i8 = ov.int64_scalar_value (); - - if (error_state) + int64_t i8; + bool err; + SET_ERR (i8 = ov.int64_scalar_value (), err); + + if (err) { - error ("can not convert octave_value to int8 value"); + c_verror ("can not convert octave_value to int8 value"); return 1; } @@ -702,15 +719,17 @@ // don't convert automatically because of possible overflow if (ov.is_float_type ()) { - error ("floating point octave_value provided for 8-byte time value, but postgresql is configured for int64"); + c_verror ("floating point octave_value provided for 8-byte time value, but postgresql is configured for int64"); return 1; } - int64_t i8 = ov.int64_scalar_value (); - - if (error_state) + int64_t i8; + bool err; + SET_ERR (i8 = ov.int64_scalar_value (), err); + + if (err) { - error ("can not convert octave_value to int64 time value"); + c_verror ("can not convert octave_value to int64 time value"); return 1; } @@ -723,7 +742,7 @@ // don't convert automatically because of possible loss of accuracy if (ov.is_integer_type ()) { - error ("integer type octave_value provided for 8-byte time value, but postgresql is configured for double"); + c_verror ("integer type octave_value provided for 8-byte time value, but postgresql is configured for double"); return 1; } @@ -734,11 +753,12 @@ } swap; - swap.d = ov.double_value (); - - if (error_state) + bool err; + SET_ERR (swap.d = ov.double_value (), err); + + if (err) { - error ("can not convert octave_value to double time value"); + c_verror ("can not convert octave_value to double time value"); return 1; } @@ -847,10 +867,12 @@ int from_octave_bin_interval (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - Cell iv = ov.cell_value (); - if (error_state || iv.numel () != 3) + Cell iv; + bool err; + SET_ERR (iv = ov.cell_value (), err); + if (err || iv.numel () != 3) { - error ("interval: can not convert octave_value to cell with 3 elements"); + c_verror ("interval: can not convert octave_value to cell with 3 elements"); return 1; } @@ -859,11 +881,13 @@ for (int id = 1; id < 3; id++) { - int32_t i4 = iv(id).int_value (); - - if (error_state) + int32_t i4; + bool err; + SET_ERR (i4 = iv(id).int_value (), err); + + if (err) { - error ("interval: can not convert octave_value to int4 value"); + c_verror ("interval: can not convert octave_value to int4 value"); return 1; } @@ -964,21 +988,24 @@ int from_octave_bin_timetz (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - Cell iv = ov.cell_value (); - if (error_state || iv.numel () != 2) + Cell iv; + bool err; + SET_ERR (iv = ov.cell_value (), err); + if (err || iv.numel () != 2) { - error ("timetz: can not convert octave_value to cell with 2 elements"); + c_verror ("timetz: can not convert octave_value to cell with 2 elements"); return 1; } if (time_8byte_from_octave (iv(0), val, conn.get_integer_datetimes ())) return 1; - int32_t i4 = iv(1).int_value (); - - if (error_state) + int32_t i4; + SET_ERR (i4 = iv(1).int_value (), err); + + if (err) { - error ("timetz: can not convert octave_value to int4 value"); + c_verror ("timetz: can not convert octave_value to int4 value"); return 1; } @@ -1027,11 +1054,13 @@ int from_octave_bin_date (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - int32_t i4 = ov.int_value (); - - if (error_state) + int32_t i4; + bool err; + SET_ERR (i4 = ov.int_value (), err); + + if (err) { - error ("date: can not convert octave_value to int4 value"); + c_verror ("date: can not convert octave_value to int4 value"); return 1; } @@ -1096,11 +1125,13 @@ int from_octave_bin_point (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - NDArray m = ov.array_value (); - - if (error_state || m.numel () != 2) + NDArray m; + bool err; + SET_ERR (m = ov.array_value (), err); + + if (err || m.numel () != 2) { - error ("can not convert octave_value to point representation"); + c_verror ("can not convert octave_value to point representation"); return 1; } @@ -1177,11 +1208,13 @@ int from_octave_bin_lseg (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - NDArray m = ov.array_value (); - - if (error_state || m.numel () != 4) + NDArray m; + bool err; + SET_ERR (m = ov.array_value (), err); + + if (err || m.numel () != 4) { - error ("can not convert octave_value to 4 doubles"); + c_verror ("can not convert octave_value to 4 doubles"); return 1; } @@ -1292,11 +1325,13 @@ int from_octave_bin_circle (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - NDArray m = ov.array_value (); - - if (error_state || m.numel () != 3) + NDArray m; + bool err; + SET_ERR (m = ov.array_value (), err); + + if (err || m.numel () != 3) { - error ("can not convert octave_value to circle representation"); + c_verror ("can not convert octave_value to circle representation"); return 1; } @@ -1379,11 +1414,13 @@ { octave_idx_type nel; - NDArray m = ov.array_value (); - - if (error_state || (nel = m.numel ()) % 2) + NDArray m; + bool err; + SET_ERR (m = ov.array_value (), err); + + if (err || (nel = m.numel ()) % 2) { - error ("can not convert octave_value to polygon representation"); + c_verror ("can not convert octave_value to polygon representation"); return 1; } @@ -1474,22 +1511,29 @@ int from_octave_bin_path (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - octave_scalar_map tp = ov.scalar_map_value (); - if (error_state || ! tp.isfield ("closed") || ! tp.isfield ("path")) + octave_scalar_map tp; + bool err; + SET_ERR (tp = ov.scalar_map_value (), err); + if (err || ! tp.isfield ("closed") || ! tp.isfield ("path")) { - error ("can not convert octave_value to path representation"); + c_verror ("can not convert octave_value to path representation"); return 1; } octave_idx_type nel; - char closed = char (tp.contents ("closed").bool_value ()); - - NDArray m = tp.contents ("path").array_value (); - - if (error_state || (nel = m.numel ()) % 2) + char closed; + SET_ERR (closed = char (tp.contents ("closed").bool_value ()), err); + + NDArray m; + if (! err) { - error ("can not convert octave_value to path representation"); + SET_ERR (m = tp.contents ("path").array_value (), err); + } + + if (err || (nel = m.numel ()) % 2) + { + c_verror ("can not convert octave_value to path representation"); return 1; } @@ -1542,7 +1586,7 @@ int to_octave_str_unknown (const octave_pq_connection_rep &conn, const char *c, octave_value &ov, int nb) { - error ("can not convert postgresql type 'unknown'"); + c_verror ("can not convert postgresql type 'unknown'"); return 1; } @@ -1550,7 +1594,7 @@ int to_octave_bin_unknown (const octave_pq_connection_rep &conn, const char *c, octave_value &ov, int nb) { - error ("can not convert postgresql type 'unknown'"); + c_verror ("can not convert postgresql type 'unknown'"); return 1; } @@ -1558,7 +1602,7 @@ int from_octave_str_unknown (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - error ("can not convert postgresql type 'unknown'"); + c_verror ("can not convert postgresql type 'unknown'"); return 1; } @@ -1566,7 +1610,7 @@ int from_octave_bin_unknown (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - error ("can not convert postgresql type 'unknown'"); + c_verror ("can not convert postgresql type 'unknown'"); return 1; } @@ -1608,7 +1652,7 @@ if (nb > 4) { - error ("internal error: received too many bytes for AF_INET type"); + c_verror ("internal error: received too many bytes for AF_INET type"); return 1; } @@ -1633,7 +1677,7 @@ if (nb > 16) { - error ("internal error: received too many bytes for AF_INET6 type"); + c_verror ("internal error: received too many bytes for AF_INET6 type"); return 1; } @@ -1665,13 +1709,16 @@ uint8_t n_mbits; + bool err; + if (nl == 4 || nl == 5) { - uint8NDArray a = ov.uint8_array_value (); - - if (error_state) + uint8NDArray a; + SET_ERR (a = ov.uint8_array_value (), err); + + if (err) { - error ("can not convert octave_value to network type representation"); + c_verror ("can not convert octave_value to network type representation"); return 1; } @@ -1689,11 +1736,12 @@ } else if (nl == 8 || nl == 9) { - uint16NDArray a = ov.uint16_array_value (); - - if (error_state) + uint16NDArray a; + SET_ERR (a = ov.uint16_array_value (), err); + + if (err) { - error ("can not convert octave_value to network type representation"); + c_verror ("can not convert octave_value to network type representation"); return 1; } @@ -1713,7 +1761,7 @@ } else { - error ("invalid network type representation"); + c_verror ("invalid network type representation"); return 1; } @@ -1740,7 +1788,7 @@ if (! cidr) { - error ("internal error: unexpected flag in cidr type"); + c_verror ("internal error: unexpected flag in cidr type"); return 1; } @@ -1793,7 +1841,7 @@ if (cidr) { - error ("internal error: unexpected flag in inet type"); + c_verror ("internal error: unexpected flag in inet type"); return 1; } @@ -1858,17 +1906,19 @@ int from_octave_bin_macaddr (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - uint8NDArray a = ov.uint8_array_value (); - - if (error_state) + uint8NDArray a; + bool err; + SET_ERR (a = ov.uint8_array_value (), err); + + if (err) { - error ("can not convert octave_value to macaddr representation"); + c_verror ("can not convert octave_value to macaddr representation"); return 1; } if (a.numel () != 6) { - error ("macaddr representation must have 6 elements"); + c_verror ("macaddr representation must have 6 elements"); return 1; } @@ -1933,20 +1983,27 @@ int from_octave_bin_bit (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - octave_scalar_map tp = ov.scalar_map_value (); - if (error_state || ! tp.isfield ("bitlen") || ! tp.isfield ("bits")) + octave_scalar_map tp; + bool err; + SET_ERR (tp = ov.scalar_map_value (), err); + if (err || ! tp.isfield ("bitlen") || ! tp.isfield ("bits")) { - error ("can not convert octave_value to bitstring representation"); + c_verror ("can not convert octave_value to bitstring representation"); return 1; } - int32_t nbits = tp.contents ("bitlen").int_value (); - - uint8NDArray a = tp.contents ("bits").uint8_array_value (); - - if (error_state || nbits < 0) + int32_t nbits; + SET_ERR (nbits = tp.contents ("bitlen").int_value (), err); + + uint8NDArray a; + if (! err) { - error ("can not convert octave_value to bitstring representation"); + SET_ERR (a = tp.contents ("bits").uint8_array_value (), err); + } + + if (err || nbits < 0) + { + c_verror ("can not convert octave_value to bitstring representation"); return 1; } @@ -1954,7 +2011,7 @@ if (a.numel () != nbytes) { - error ("wrong number of elements in bitstring representation"); + c_verror ("wrong number of elements in bitstring representation"); return 1; } @@ -2029,17 +2086,19 @@ int from_octave_bin_uuid (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - uint8NDArray b = ov.uint8_array_value (); - - if (error_state) + uint8NDArray b; + bool err; + SET_ERR (b = ov.uint8_array_value (), err); + + if (err) { - error ("can not convert octave_value to uuid representation"); + c_verror ("can not convert octave_value to uuid representation"); return 1; } if (b.numel () != 16) { - error ("uuid representation must have 16 elements"); + c_verror ("uuid representation must have 16 elements"); return 1; } @@ -2091,11 +2150,13 @@ int from_octave_bin_xml (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - std::string s = ov.string_value (); - - if (error_state) + std::string s; + bool err; + SET_ERR (s = ov.string_value (), err); + + if (err) { - error ("can not convert octave_value to string"); + c_verror ("can not convert octave_value to string"); return 1; } @@ -2180,7 +2241,7 @@ default: // should not get here - error ("'record' converter: internal error, undefined type identifier"); + c_verror ("'record' converter: internal error, undefined type identifier"); return 1; } @@ -2204,7 +2265,7 @@ int from_octave_bin_record (const octave_pq_connection_rep &conn, const octave_value &ov, oct_pq_dynvec_t &val) { - error ("Type 'record' can't be sent to postgresql."); + c_verror ("Type 'record' can't be sent to postgresql."); return 1; } diff -r 87989220360f -r 1af86934c14e main/database/src/converters_arr_comp.cc --- a/main/database/src/converters_arr_comp.cc Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/converters_arr_comp.cc Sat Feb 27 11:11:04 2016 +0000 @@ -26,10 +26,11 @@ #include "converters.h" #include "pq_connection.h" +#include "error-helpers.h" #define ERROR_RETURN_NO_PG_TYPE \ { \ - error ("could not determine postgresql type for Octave parameter"); \ + c_verror ("could not determine postgresql type for Octave parameter"); \ return NULL; \ } @@ -55,8 +56,11 @@ if ((iter = conn.name_conv_map.find (name.c_str ())) == conn.name_conv_map.end ()) - error ("no converter found for type %s", - name.c_str ()); + { + c_verror ("no converter found for type %s", + name.c_str ()); + return NULL; + } else { // printf ("(looked up in name map) "); @@ -65,8 +69,8 @@ if (oct_type == array && ! conv->aoid) { - error ("%s: internal error, type %s, specified as array, has no array type in system catalog", name.c_str ()); - return conv; + c_verror ("%s: internal error, type %s, specified as array, has no array type in system catalog", name.c_str ()); + return NULL; } if (! (oct_type == array) && conv->is_composite) @@ -93,8 +97,8 @@ if ((iter = conn.conv_map.find (oid)) == conn.conv_map.end ()) { - error ("no converter found for element oid %u", oid); - return conv; + c_verror ("no converter found for element oid %u", oid); + return NULL; } conv = iter->second.get_copy (); // printf ("(looked up %s in oid map) ", conv->name.c_str ()); @@ -273,24 +277,32 @@ const octave_value &oct_arr, oct_pq_dynvec_t &val, oct_pq_conv_t *conv) { - octave_scalar_map m = oct_arr.scalar_map_value (); - if (error_state) + octave_scalar_map m; + bool err; + SET_ERR (m= oct_arr.scalar_map_value (), err); + if (err) { - error ("Postgresql array parameter no Octave structure"); + c_verror ("Postgresql array parameter no Octave structure"); return 1; } if (! m.isfield ("ndims") || ! m.isfield ("data")) { - error ("field 'ndims' or 'data' missing in parameter for Postgresql array"); + c_verror ("field 'ndims' or 'data' missing in parameter for Postgresql array"); return 1; } - octave_idx_type nd_pq = m.contents ("ndims").int_value (); - Cell arr = m.contents ("data").cell_value (); - if (error_state || nd_pq < 0) + octave_idx_type nd_pq; + SET_ERR (nd_pq = m.contents ("ndims").int_value (), err); + + Cell arr; + if (! err) { - error ("'ndims' and 'data' could not be converted to non-negative integer and cell-array in parameter for Postgresql array"); + SET_ERR (arr = m.contents ("data").cell_value (), err); + } + if (err || nd_pq < 0) + { + c_verror ("'ndims' and 'data' could not be converted to non-negative integer and cell-array in parameter for Postgresql array"); return 1; } @@ -299,10 +311,10 @@ // Are lbounds given? if (m.isfield ("lbounds")) { - lb = m.contents ("lbounds").row_vector_value (); - if (error_state) + SET_ERR (lb = m.contents ("lbounds").row_vector_value (), err); + if (err) { - error ("could not convert given enumeration bases for array to row vector"); + c_verror ("could not convert given enumeration bases for array to row vector"); return 1; } } @@ -319,16 +331,16 @@ // check dimensions if (nd_oct > nd_pq) { - error ("given representation of postgresql array has more dimensions than specified"); + c_verror ("given representation of postgresql array has more dimensions than specified"); return 1; } // check lbounds if (nd_pq > 0 && lb.is_empty ()) lb.resize (nd_pq, 1); // fill with 1 - else if (lb.length () != nd_pq) + else if (lb.numel () != nd_pq) { - error ("number of specified enumeration bases for array does not match specified number of dimensions"); + c_verror ("number of specified enumeration bases for array does not match specified number of dimensions"); return 1; } @@ -382,10 +394,12 @@ oct_pq_dynvec_t &val, oct_pq_conv_t *conv) { - Cell rec (oct_comp.cell_value ()); - if (error_state) + Cell rec; + bool err; + SET_ERR (rec = oct_comp.cell_value (), err); + if (err) { - error ("Octaves representation of a composite type could not be converted to cell-array"); + c_verror ("Octaves representation of a composite type could not be converted to cell-array"); return 1; } @@ -393,7 +407,7 @@ if (size_t (nl) != conv->el_oids.size ()) { - error ("Octaves representation of a composite type has incorrect number of elements (%i, should have %i)", + c_verror ("Octaves representation of a composite type has incorrect number of elements (%i, should have %i)", nl, conv->el_oids.size ()); return 1; @@ -442,7 +456,7 @@ default: // should not get here - error ("internal error, undefined type identifier"); + c_verror ("internal error, undefined type identifier"); return 1; } @@ -458,7 +472,7 @@ oct_pq_dynvec_t &val, octave_value &type) { // not implemented - error ("not implemented"); + c_verror ("not implemented"); return 1; return 0; @@ -470,7 +484,7 @@ octave_value &type) { // not implemented - error ("not implemented"); + c_verror ("not implemented"); return 1; return 0; @@ -496,7 +510,7 @@ // check element OID if (oid != conv->oid) { - error ("element oid %i sent by server does not match element oid %i expected for array with oid %i", + c_verror ("element oid %i sent by server does not match element oid %i expected for array with oid %i", oid, conv->oid, conv->aoid); return 1; } @@ -613,7 +627,7 @@ default: // should not get here - error ("internal error, undefined type identifier"); + c_verror ("internal error, undefined type identifier"); return 1; } @@ -634,7 +648,7 @@ oct_pq_conv_t *conv) { // not implemented - error ("not implemented"); + c_verror ("not implemented"); return 1; return 0; @@ -645,7 +659,7 @@ oct_pq_conv_t *conv) { // not implemented - error ("not implemented"); + c_verror ("not implemented"); return 1; return 0; diff -r 87989220360f -r 1af86934c14e main/database/src/error-helpers.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/database/src/error-helpers.cc Sat Feb 27 11:11:04 2016 +0000 @@ -0,0 +1,53 @@ +/* + +Copyright (C) 2016 Olaf Till + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; If not, see . + +*/ + +#include + +#include "error-helpers.h" + +// call verror +#ifdef HAVE_OCTAVE_VERROR_ARG_EXC +void +c_verror (octave_execution_exception& e, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + verror (e, fmt, args); + va_end (args); +} +#else +void +c_verror (const octave_execution_exception&, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + verror (fmt, args); + va_end (args); +} +#endif + +// call verror +void +c_verror (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + verror (fmt, args); + va_end (args); +} diff -r 87989220360f -r 1af86934c14e main/database/src/error-helpers.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/database/src/error-helpers.h Sat Feb 27 11:11:04 2016 +0000 @@ -0,0 +1,137 @@ +/* + +Copyright (C) 2016 Olaf Till + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; If not, see . + +*/ + +#include "config.h" + +// call verror +#ifdef HAVE_OCTAVE_VERROR_ARG_EXC +void c_verror (octave_execution_exception&, const char *, ...); +#else +void c_verror (const octave_execution_exception&, const char *, ...); +#endif + +// call verror +void c_verror (const char *fmt, ...); + +// Print a message if 'code' causes an error and raise an error again, +// both if Octave uses exceptions for errors and if it still uses +// error_state. In the latter case return 'retval'. +#ifdef HAVE_OCTAVE_ERROR_STATE + // can throw octave_execution_exception despite of this + #define CHECK_ERROR(code, retval, ...) \ + try \ + { \ + code ; \ + \ + if (error_state) \ + { \ + error (__VA_ARGS__); \ + \ + return retval; \ + } \ + } \ + catch (octave_execution_exception& e) \ + { \ + c_verror (e, __VA_ARGS__); \ + \ + throw e; \ + } +#else + #define CHECK_ERROR(code, retval, ...) \ + try \ + { \ + code ; \ + } \ + catch (octave_execution_exception& e) \ + { \ + c_verror (e, __VA_ARGS__); \ + \ + throw e; \ + } +#endif + +// If 'code' causes an error, print a message and call exit(1) if +// Octave doesn't throw exceptions for errors but still uses +// error_state. +#ifdef HAVE_OCTAVE_ERROR_STATE + // can throw octave_execution_exception despite of this + #define CHECK_ERROR_EXIT1(code, ...) \ + try \ + { \ + code ; \ + \ + if (error_state) \ + { \ + c_verror (__VA_ARGS__); \ + \ + exit (1); \ + } \ + } \ + catch (octave_execution_exception& e) \ + { \ + c_verror (e, __VA_ARGS__); \ + \ + exit (1); \ + } +#else + #define CHECK_ERROR_EXIT1(code, ...) \ + try \ + { \ + code ; \ + } \ + catch (octave_execution_exception& e) \ + { \ + c_verror (e, __VA_ARGS__); \ + \ + exit (1); \ + } +#endif + +// Set 'err' to true if 'code' causes an error, else to false; both if +// Octave uses exceptions for errors and if it still uses +// error_state. In the latter case reset error_state to 0. +#ifdef HAVE_OCTAVE_ERROR_STATE + // can throw octave_execution_exception despite of this + #define SET_ERR(code, err) \ + err = false; \ + \ + try \ + { \ + code ; \ + if (error_state) \ + { \ + error_state = 0; \ + err = true; \ + } \ + } \ + catch (octave_execution_exception&) \ + { \ + err = true; \ + } +#else + #define SET_ERR(code, err) \ + try \ + { \ + code ; \ + } \ + catch (octave_execution_exception&) \ + { \ + err = true; \ + } +#endif diff -r 87989220360f -r 1af86934c14e main/database/src/pq_connection.cc --- a/main/database/src/pq_connection.cc Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/pq_connection.cc Sat Feb 27 11:11:04 2016 +0000 @@ -19,6 +19,7 @@ #include "pq_connection.h" #include "command.h" +#include "error-helpers.h" DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_pq_connection, "PGconn", "PGconn") @@ -57,7 +58,7 @@ { if (conn) { - error ("%s", PQerrorMessage (conn)); + c_verror ("%s", PQerrorMessage (conn)); PGconn *t_conn = conn; @@ -68,7 +69,7 @@ END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; } - error ("PQ connection attempt failed"); + c_verror ("PQ connection attempt failed"); } else { @@ -94,7 +95,7 @@ PQfinish (t_conn); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - error ("could not read types"); + c_verror ("could not read types"); } else { @@ -133,6 +134,9 @@ octave_pq_delete_non_constant_types (); } else + // deliberately left the 'error' call here, since + // 'octave_pq_close()' is only called by 'pq_close' immediately + // before returning error ("PGconn object not open"); } @@ -189,17 +193,17 @@ command c (*this, cmd, p, pt, rt, caller); if (! c.good ()) { - error ("could not read pg_roles"); + c_verror ("could not read pg_roles"); return 1; } octave_value res = c.process_single_result (); - if (error_state) + if (! c.good ()) return 1; - postgres = res.scalar_map_value ().contents ("data").cell_value ()(0). - int_value (); - if (error_state) + bool err; + SET_ERR (postgres = res.scalar_map_value ().contents ("data").cell_value ()(0).int_value (), err); + if (err) return 1; return 0; @@ -223,18 +227,21 @@ command c (*this, cmd, p, pt, rt, caller); if (! c.good ()) { - error ("octave_pq_fill_base_types: could not read pg_type"); + c_verror ("octave_pq_fill_base_types: could not read pg_type"); return 1; } octave_value res = c.process_single_result (); - if (error_state) + if (! c.good ()) return 1; - Cell tpls = res.scalar_map_value ().contents ("data").cell_value (); - if (error_state) + Cell tpls; + bool err; + SET_ERR (tpls = res.scalar_map_value ().contents ("data").cell_value (), + err); + if (err) { - error + c_verror ("octave_pq_fill_base_types: could not convert result data to cell"); return 1; } @@ -245,10 +252,14 @@ bt_map_t; bt_map_t bt_map (&map_string_cmp); for (int i = 0; i < tpls.rows (); i++) - bt_map[tpls(i, 1).string_value ()] = i; - if (error_state) { - error ("octave_pq_fill_base_types: could not read returned result"); + SET_ERR (bt_map[tpls(i, 1).string_value ()] = i, err); + if (err) + break; + } + if (err) + { + c_verror ("octave_pq_fill_base_types: could not read returned result"); return 1; } @@ -258,13 +269,19 @@ if ((bt_it = bt_map.find (conv_ptrs[i]->name.c_str () + pq_bpl)) == bt_map.end ()) { - error ("octave_pq_fill_base_types: type %s not found in pg_type", - conv_ptrs[i]->name.c_str () + pq_bpl); + c_verror ("octave_pq_fill_base_types: type %s not found in pg_type", + conv_ptrs[i]->name.c_str () + pq_bpl); return 1; } // fill in oid and aoid into static records of converters - conv_ptrs[i]->oid = tpls(bt_it->second, 0).int_value (); - conv_ptrs[i]->aoid = tpls(bt_it->second, 2).int_value (); + SET_ERR (conv_ptrs[i]->oid = tpls(bt_it->second, 0).int_value (), err); + if (! err) + { + SET_ERR (conv_ptrs[i]->aoid = tpls(bt_it->second, 2).int_value (), + err); + } + if (err) + break; // fill in map of converters over oid with oid and, if not zero, // also with aoid @@ -272,9 +289,9 @@ if (conv_ptrs[i]->aoid != 0) conv_map[conv_ptrs[i]->aoid] = conv_ptrs[i]; } - if (error_state) + if (err) { - error ("octave_pq_fill_base_types: could not read returned result"); + c_verror ("octave_pq_fill_base_types: could not read returned result"); return 1; } @@ -291,41 +308,69 @@ command c (*this, cmd, p, pt, rt, caller); if (! c.good ()) { - error ("octave_pq_get_composite_types: could not read pg_type"); + c_verror ("octave_pq_get_composite_types: could not read pg_type"); return 1; } octave_value res = c.process_single_result (); - if (error_state) + if (! c.good ()) return 1; - Cell tpls = res.scalar_map_value ().contents ("data").cell_value (); - if (error_state) + Cell tpls; + bool err; + SET_ERR (tpls = res.scalar_map_value ().contents ("data").cell_value (), + err) + if (err) { - error ("octave_pq_get_composite_types: could not convert result data to cell"); + c_verror ("octave_pq_get_composite_types: could not convert result data to cell"); return 1; } for (int i = 0; i < tpls.rows (); i++) { - Oid oid = tpls(i, 0).uint_value (); - Oid aoid = tpls(i, 2).uint_value (); - std::string name = tpls(i, 1).string_value (); - std::string nspace = tpls(i, 3).string_value (); - bool visible = tpls(i, 4).bool_value (); - Cell r_el_oids = - tpls(i, 5).scalar_map_value ().contents ("data").cell_value (); - Cell r_el_pos = - tpls(i, 6).scalar_map_value ().contents ("data").cell_value (); - if (error_state) + Oid oid; + SET_ERR (oid = tpls(i, 0).uint_value (), err); + Oid aoid; + if (! err) + { + SET_ERR (aoid = tpls(i, 2).uint_value (), err); + } + std::string name; + if (! err) + { + SET_ERR (name = tpls(i, 1).string_value (), err); + } + std::string nspace; + if (! err) { - error ("octave_pq_get_composite_types: could not read returned result"); + SET_ERR (nspace = tpls(i, 3).string_value (), err); + } + bool visible; + if (! err) + { + SET_ERR (visible = tpls(i, 4).bool_value (), err); + } + Cell r_el_oids; + if (! err) + { + SET_ERR (r_el_oids = tpls(i, 5).scalar_map_value () + .contents ("data").cell_value (), err); + } + Cell r_el_pos; + if (! err) + { + SET_ERR (r_el_pos = tpls(i, 6).scalar_map_value () + .contents ("data").cell_value (), err); + } + if (err) + { + c_verror ("octave_pq_get_composite_types: could not read returned result"); return 1; } octave_idx_type nel = r_el_oids.numel (); if (nel != r_el_pos.numel ()) { - error ("octave_pq_get_composite_types: internal error, inconsistent content of pg_attribute?"); + c_verror ("octave_pq_get_composite_types: internal error, inconsistent content of pg_attribute?"); return 1; } @@ -335,27 +380,28 @@ conv_cache.resize (nel); for (octave_idx_type i = 0; i < nel; i++) { + octave_idx_type pos; // "column" number (attnum) is one-based, so subtract 1 - octave_idx_type pos = r_el_pos(i).idx_type_value () - 1; - if (! error_state) + SET_ERR (pos = r_el_pos(i).idx_type_value () - 1, err); + if (! err) { if (pos >= nel) { - error ("octave_pq_get_composite_types: internal error (?system catalog erroneous?): column position %i greater than ncols %i for type %s, namespace %s", + c_verror ("octave_pq_get_composite_types: internal error (?system catalog erroneous?): column position %i greater than ncols %i for type %s, namespace %s", pos, nel, name.c_str (), nspace.c_str ()); return 1; } - el_oids[pos] = r_el_oids(i).uint_value (); + SET_ERR (el_oids[pos] = r_el_oids(i).uint_value (), err); conv_cache[pos] = NULL; } - } - if (error_state) - { - error ("octave_pq_get_composite_types: could not fill in element oids."); + if (err) + { + c_verror ("octave_pq_get_composite_types: could not fill in element oids."); - return 1; + return 1; + } } // must be allocated and filled before creating the name map @@ -379,7 +425,7 @@ *&by_name = name_conv_map[t_conv->name.c_str ()]; if (by_oid || by_name) { - error ("octave_pq_get_composite_types: internal error, key already in typemap (by_oid: %u/%li, by name: %s/%li)", + c_verror ("octave_pq_get_composite_types: internal error, key already in typemap (by_oid: %u/%li, by name: %s/%li)", oid, by_oid, t_conv->name.c_str (), by_name); if (! by_oid) conv_map.erase (oid); if (! by_name) name_conv_map.erase (t_conv->name.c_str ()); @@ -410,7 +456,7 @@ oct_pq_conv_t *&by_aoid = conv_map[aoid]; if (by_aoid) { - error ("octave_pq_get_composite_types: internal error, aoid key %u already in typemap", aoid); + c_verror ("octave_pq_get_composite_types: internal error, aoid key %u already in typemap", aoid); conv_map.erase (oid); name_conv_map.erase (t_conv->name.c_str ()); delete t_conv; @@ -440,31 +486,51 @@ command c (*this, cmd, p, pt, rt, caller); if (! c.good ()) { - error ("octave_pq_get_enum_types: could not read pg_type"); + c_verror ("octave_pq_get_enum_types: could not read pg_type"); return 1; } octave_value res = c.process_single_result (); - if (error_state) + if (! c.good ()) return 1; - Cell tpls = res.scalar_map_value ().contents ("data").cell_value (); - if (error_state) + Cell tpls; + bool err; + SET_ERR (tpls = res.scalar_map_value ().contents ("data").cell_value (), + err); + if (err) { - error ("octave_pq_get_enum_types: could not convert result data to cell"); + c_verror ("octave_pq_get_enum_types: could not convert result data to cell"); return 1; } for (int i = 0; i < tpls.rows (); i++) { - Oid oid = tpls(i, 0).uint_value (); - Oid aoid = tpls(i, 2).uint_value (); - std::string name = tpls(i, 1).string_value (); - std::string nspace = tpls(i, 3).string_value (); - bool visible = tpls(i, 4).bool_value (); - if (error_state) + Oid oid; + SET_ERR (oid = tpls(i, 0).uint_value (), err); + Oid aoid; + if (! err) + { + SET_ERR (aoid = tpls(i, 2).uint_value (), err); + } + std::string name; + if (! err) { - error ("octave_pq_get_enum_types: could not read returned result"); + SET_ERR (name = tpls(i, 1).string_value (), err); + } + std::string nspace; + if (! err) + { + SET_ERR (nspace = tpls(i, 3).string_value (), err); + } + bool visible; + if (! err) + { + SET_ERR (visible = tpls(i, 4).bool_value (), err); + } + if (err) + { + c_verror ("octave_pq_get_enum_types: could not read returned result"); return 1; } @@ -490,7 +556,7 @@ *&by_name = name_conv_map[t_conv->name.c_str ()]; if (by_oid || by_aoid || by_name) { - error ("octave_pq_get_enum_types: internal error, key already in typemap"); + c_verror ("octave_pq_get_enum_types: internal error, key already in typemap"); if (! by_oid) conv_map.erase (oid); if (! by_aoid) conv_map.erase (aoid); if (! by_name) name_conv_map.erase (t_conv->name.c_str ()); @@ -539,7 +605,7 @@ END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; } - error ("octave_pq_refresh_types: could not read types"); + c_verror ("octave_pq_refresh_types: could not read types"); return 1; } else diff -r 87989220360f -r 1af86934c14e main/database/src/pq_conninfo.cc --- a/main/database/src/pq_conninfo.cc Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/pq_conninfo.cc Sat Feb 27 11:11:04 2016 +0000 @@ -20,6 +20,7 @@ #include #include "pq_connection.h" +#include "error-helpers.h" // PKG_ADD: autoload ("pq_conninfo", "pq_interface.oct"); // PKG_DEL: autoload ("pq_conninfo", "pq_interface.oct", "remove"); @@ -42,15 +43,10 @@ return retval; } - std::string label (args(1).string_value ()); - - if (error_state) - { - error ("%s: second argument can not be converted to a string", - fname.c_str ()); - - return retval; - } + std::string label; + CHECK_ERROR (label = args(1).string_value (), retval, + "%s: second argument can not be converted to a string", + fname.c_str ()); if (label.compare ("integer_datetimes")) { diff -r 87989220360f -r 1af86934c14e main/database/src/pq_exec.cc --- a/main/database/src/pq_exec.cc Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/pq_exec.cc Sat Feb 27 11:11:04 2016 +0000 @@ -23,6 +23,7 @@ #include #include "command.h" +#include "error-helpers.h" // PKG_disabled_ADD: autoload ("pq_exec", "pq_interface.oct"); // PKG_disabled_DEL: autoload ("pq_exec", "pq_interface.oct", "remove"); @@ -122,14 +123,10 @@ return retval; } - std::string cmd (args(1).string_value ()); - - if (error_state) - { - error ("%s: second argument can not be converted to a string", fname.c_str ()); - - return retval; - } + std::string cmd; + CHECK_ERROR (cmd = args(1).string_value (), retval, + "%s: second argument can not be converted to a string", + fname.c_str ()); const octave_base_value &rep = args(0).get_rep (); @@ -162,14 +159,20 @@ octave_scalar_map settings; + bool err; + if (nargs == 3) { if (args(2).is_cell ()) - params = args(2).cell_value (); + { + SET_ERR (params = args(2).cell_value (), err); + } else - settings = args(2).scalar_map_value (); + { + SET_ERR (settings = args(2).scalar_map_value (), err); + } - if (error_state) + if (err) { error ("%s: third argument neither cell-array nor scalar structure", fname.c_str ()); @@ -179,24 +182,14 @@ } else if (nargs == 4) { - params = args(2).cell_value (); - if (error_state) - { - error ("%s: could not convert third argument to cell-array", - fname.c_str ()); - - return retval; - } - settings = args(3).scalar_map_value (); - if (error_state) - { - error ("%s: could not convert fourth argument to scalar structure"); - - return retval; - } + CHECK_ERROR (params = args(2).cell_value (), retval, + "%s: could not convert third argument to cell-array", + fname.c_str ()); + CHECK_ERROR (settings = args(3).scalar_map_value (), retval, + "%s: could not convert fourth argument to scalar structure"); } - int nparams = params.length (); + int nparams = params.numel (); dim_vector pdims = params.dims (); @@ -218,97 +211,72 @@ f_args(1) = octave_value ("param_types"); f_args(2) = octave_value (Cell (1, nparams)); - f_ret = feval ("getdbopts", f_args, 1); - Cell ptypes = f_ret(0).cell_value (); - if (error_state) - { - error ("%s: could not convert param_types to cell", - fname.c_str ()); - - return retval; - } + CHECK_ERROR (f_ret = feval ("getdbopts", f_args, 1), retval, + "%s: error calling getdbopts", + fname.c_str ()); + Cell ptypes; + CHECK_ERROR (ptypes = f_ret(0).cell_value (), retval, + "%s: could not convert param_types to cell", fname.c_str ()); f_args(1) = octave_value ("copy_in_path"); f_args(2) = octave_value (""); - f_ret = feval ("getdbopts", f_args, 1); - std::string cin_path = f_ret(0).string_value (); - if (error_state) - { - error ("%s: could not convert copy_in_path to string", - fname.c_str ()); - - return retval; - } + CHECK_ERROR (f_ret = feval ("getdbopts", f_args, 1), retval, + "%s: error calling getdbopts", fname.c_str ()); + std::string cin_path; + CHECK_ERROR (cin_path = f_ret(0).string_value (), retval, + "%s: could not convert copy_in_path to string", fname.c_str ()); f_args(1) = octave_value ("copy_out_path"); f_args(2) = octave_value (""); - f_ret = feval ("getdbopts", f_args, 1); - std::string cout_path = f_ret(0).string_value (); - if (error_state) - { - error ("%s: could not convert copy_out_path to string", - fname.c_str ()); - - return retval; - } + CHECK_ERROR (f_ret = feval ("getdbopts", f_args, 1), retval, + "%s: error calling getdbopts", fname.c_str ()); + std::string cout_path; + CHECK_ERROR (cout_path = f_ret(0).string_value (), retval, + "%s: could not convert copy_out_path to string", fname.c_str ()); f_args(1) = octave_value ("copy_in_data"); f_args(2) = octave_value (Cell ()); - f_ret = feval ("getdbopts", f_args, 1); - Cell cin_data = f_ret(0).cell_value (); - if (error_state) - { - error ("%s: could not convert copy_in_data to cell", - fname.c_str ()); - - return retval; - } + CHECK_ERROR (f_ret = feval ("getdbopts", f_args, 1), retval, + "%s: error calling getdbopts", fname.c_str ()); + Cell cin_data; + CHECK_ERROR (cin_data = f_ret(0).cell_value (), retval, + "%s: could not convert copy_in_data to cell", fname.c_str ()); f_args(1) = octave_value ("copy_in_with_oids"); f_args(2) = octave_value (false); - f_ret = feval ("getdbopts", f_args, 1); - bool cin_with_oids = f_ret(0).bool_value (); - if (error_state) - { - error ("%s: could not convert copy_in_with_oids to bool", - fname.c_str ()); - - return retval; - } + CHECK_ERROR (f_ret = feval ("getdbopts", f_args, 1), retval, + "%s: error calling getdbopts", fname.c_str ()); + bool cin_with_oids; + CHECK_ERROR (cin_with_oids = f_ret(0).bool_value (), retval, + "%s: could not convert copy_in_with_oids to bool", + fname.c_str ()); f_args(1) = octave_value ("copy_in_types"); f_args(2) = octave_value (Cell ()); - f_ret = feval ("getdbopts", f_args, 1); - Cell cin_types = f_ret(0).cell_value (); - if (error_state) - { - error ("%s: could not convert copy_in_types to cell", - fname.c_str ()); - - return retval; - } + CHECK_ERROR (f_ret = feval ("getdbopts", f_args, 1), retval, + "%s: error calling getdbopts", fname.c_str ()); + Cell cin_types; + CHECK_ERROR (cin_types = f_ret(0).cell_value (), retval, + "%s: could not convert copy_in_types to cell", fname.c_str ()); f_args(1) = octave_value ("copy_in_from_variable"); f_args(2) = octave_value (false); - f_ret = feval ("getdbopts", f_args, 1); - bool cin_from_variable = f_ret(0).bool_value (); - if (error_state) - { - error ("%s: could not convert copy_in_from_variable to bool", - fname.c_str ()); - - return retval; - } + CHECK_ERROR (f_ret = feval ("getdbopts", f_args, 1), retval, + "%s: error calling getdbopts", fname.c_str ()); + bool cin_from_variable; + CHECK_ERROR (cin_from_variable = f_ret(0).bool_value (), retval, + "%s: could not convert copy_in_from_variable to bool", + fname.c_str ()); // check option settings - if (ptypes.length () != nparams) + if (ptypes.numel () != nparams) { error ("%s: if given, cell-array of parameter types must have same length as cell-array of parameters", fname.c_str ()); @@ -345,5 +313,8 @@ (cin_path, cout_path, cin_data, cin_types, cin_with_oids, cin_from_variable); + if (! c.good ()) + error ("%s: error processing result", fname.c_str ()); + return retval; } diff -r 87989220360f -r 1af86934c14e main/database/src/pq_lo.cc --- a/main/database/src/pq_lo.cc Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/pq_lo.cc Sat Feb 27 11:11:04 2016 +0000 @@ -24,6 +24,7 @@ #include #include "command.h" +#include "error-helpers.h" #include // PKG_ADD: autoload ("pq_lo_import", "pq_interface.oct"); @@ -128,7 +129,7 @@ if (nb) return; if (pclose (fp) == -1) - error ("error closing pipe"); + c_verror ("error closing pipe"); fp = NULL; @@ -145,7 +146,7 @@ if (lod != -1) { if (lo_close (conn, lod)) - error ("%s", PQerrorMessage (conn)); + c_verror ("%s", PQerrorMessage (conn)); lod = -1; } @@ -153,7 +154,7 @@ if (oid && ! oid_valid) { if (lo_unlink (conn, oid) == -1) - error ("error unlinking new large object with oid %i", oid); + c_verror ("error unlinking new large object with oid %i", oid); } else oid = 0; @@ -161,7 +162,7 @@ if (fp) { if (pclose (fp) == -1) - error ("error closing pipe"); + c_verror ("error closing pipe"); fp = NULL; } @@ -179,7 +180,7 @@ c.process_single_result (); if (! c.good ()) - error ("pq_lo_import: could not commit"); + c_verror ("%s: could not commit", caller.c_str ()); } } @@ -269,7 +270,7 @@ if (pnb) return; if (pclose (fp) == -1) - error ("error closing pipe"); + c_verror ("error closing pipe"); fp = NULL; @@ -286,7 +287,7 @@ if (lod != -1) { if (lo_close (conn, lod)) - error ("%s", PQerrorMessage (conn)); + c_verror ("%s", PQerrorMessage (conn)); lod = -1; } @@ -294,7 +295,7 @@ if (fp) { if (pclose (fp) == -1) - error ("error closing pipe"); + c_verror ("error closing pipe"); fp = NULL; } @@ -312,7 +313,7 @@ c.process_single_result (); if (! c.good ()) - error ("pq_lo_export: could not commit"); + c_verror ("%s: could not commit", caller.c_str ()); } } @@ -334,15 +335,10 @@ return retval; } - std::string path (args(1).string_value ()); - - if (error_state) - { - error ("%s: second argument can not be converted to a string", - fname.c_str ()); - - return retval; - } + std::string path; + CHECK_ERROR (path = args(1).string_value (), retval, + "%s: second argument can not be converted to a string", + fname.c_str ()); bool from_pipe = false; unsigned int l = path.size (); @@ -389,17 +385,15 @@ case PQTRANS_INERROR: error ("%s: can't manipulate large objects within a failed transaction block", fname.c_str ()); - break; + return retval; case PQTRANS_UNKNOWN: error ("%s: connection is bad", fname.c_str ()); - break; + return retval; default: // includes PQTRANS_ACTIVE error ("%s: unexpected connection state", fname.c_str ()); + return retval; } - if (error_state) - return retval; - if (make_tblock) { std::string cmd ("begin;"); @@ -459,13 +453,17 @@ } if (import_error) - error ("%s: large object import failed: %s", fname.c_str (), msg.c_str ()); + c_verror ("%s: large object import failed: %s", + fname.c_str (), msg.c_str ()); if (commit_error) - error ("%s: could not commit transaction", fname.c_str ()); + c_verror ("%s: could not commit transaction", fname.c_str ()); - if (error_state) - return retval; + if (import_error || commit_error) + { + error ("%s failed", fname.c_str ()); + return retval; + } retval = octave_value (octave_uint32 (oid)); @@ -491,15 +489,10 @@ return retval; } - std::string path (args(2).string_value ()); - - if (error_state) - { - error ("%s: third argument can not be converted to a string", - fname.c_str ()); - - return retval; - } + std::string path; + CHECK_ERROR (path = args(2).string_value (), retval, + "%s: third argument can not be converted to a string", + fname.c_str ()); bool to_pipe = false; if (! path.empty () && path[0] == '|') @@ -517,15 +510,10 @@ to_pipe = true; } - Oid oid = args(1).uint_value (); - - if (error_state) - { - error ("%s: second argument can not be converted to an oid", - fname.c_str ()); - - return retval; - } + Oid oid; + CHECK_ERROR (oid = args(1).uint_value (), retval, + "%s: second argument can not be converted to an oid", + fname.c_str ()); const octave_base_value& rep = (args(0).get_rep ()); @@ -551,17 +539,15 @@ case PQTRANS_INERROR: error ("%s: can't manipulate large objects within a failed transaction block", fname.c_str ()); - break; + return retval; case PQTRANS_UNKNOWN: error ("%s: connection is bad", fname.c_str ()); - break; + return retval; default: // includes PQTRANS_ACTIVE error ("%s: unexpected connection state", fname.c_str ()); + return retval; } - if (error_state) - return retval; - if (make_tblock) { std::string cmd ("begin;"); @@ -617,10 +603,14 @@ } if (export_error) - error ("%s: large object export failed: %s", fname.c_str (), msg.c_str ()); + c_verror ("%s: large object export failed: %s", + fname.c_str (), msg.c_str ()); if (commit_error) - error ("%s: could not commit transaction", fname.c_str ()); + c_verror ("%s: could not commit transaction", fname.c_str ()); + + if (export_error || commit_error) + error ("%s failed", fname.c_str ()); return retval; } @@ -644,15 +634,10 @@ return retval; } - Oid oid = args(1).uint_value (); - - if (error_state) - { - error ("%s: second argument can not be converted to an oid", - fname.c_str ()); - - return retval; - } + Oid oid; + CHECK_ERROR (oid = args(1).uint_value (), retval, + "%s: second argument can not be converted to an oid", + fname.c_str ()); const octave_base_value& rep = (args(0).get_rep ()); @@ -678,17 +663,15 @@ case PQTRANS_INERROR: error ("%s: can't manipulate large objects within a failed transaction block", fname.c_str ()); - break; + return retval; case PQTRANS_UNKNOWN: error ("%s: connection is bad", fname.c_str ()); - break; + return retval; default: // includes PQTRANS_ACTIVE error ("%s: unexpected connection state", fname.c_str ()); + return retval; } - if (error_state) - return retval; - if (make_tblock) { std::string cmd ("begin;"); @@ -734,10 +717,14 @@ } if (unlink_error) - error ("%s: large object unlink failed: %s", fname.c_str (), msg.c_str ()); + c_verror ("%s: large object unlink failed: %s", + fname.c_str (), msg.c_str ()); if (commit_error) - error ("%s: could not commit transaction", fname.c_str ()); + c_verror ("%s: could not commit transaction", fname.c_str ()); + + if (unlink_error || commit_error) + error ("%s failed", fname.c_str ()); return retval; } diff -r 87989220360f -r 1af86934c14e main/database/src/pq_update_types.cc --- a/main/database/src/pq_update_types.cc Fri Feb 26 15:07:46 2016 +0000 +++ b/main/database/src/pq_update_types.cc Sat Feb 27 11:11:04 2016 +0000 @@ -48,7 +48,8 @@ const octave_pq_connection &oct_pq_conn = dynamic_cast (rep); - oct_pq_conn.get_rep ()->octave_pq_refresh_types (); + if (oct_pq_conn.get_rep ()->octave_pq_refresh_types ()) + error ("%s failed", fname.c_str ()); return retval; }