# HG changeset patch # User i7tiol # Date 1368382351 0 # Node ID b3cbebad8a26c5ffebb7bf83884f64f8e29ed7c5 # Parent 9e624fa135a1a4147985466203ab748b34c430b1 Fix segfault after internal error. Add converter for type 'unknown'. The segfault happened if reading of system tables in octave_pq_connection constructor went wrong. The new type fixes a corner case query. diff -r 9e624fa135a1 -r b3cbebad8a26 main/database/src/converters.cc --- a/main/database/src/converters.cc Sun May 12 10:19:34 2013 +0000 +++ b/main/database/src/converters.cc Sun May 12 18:12:31 2013 +0000 @@ -1529,6 +1529,61 @@ /* end type path */ +/* type unknown */ + +// These are pseudo-converters for postgresql type 'unknown'. They do +// nothing except signalling an error. The rationale is that the only +// values of type 'unknown' may be NULL, in which case the converter +// will not be called, but because a converter exists there won't be a +// "no converter found" error thrown. + +int to_octave_str_unknown (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + error ("can not convert postgresql type 'unknown'"); + + return 1; +} + +int to_octave_bin_unknown (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + error ("can not convert postgresql type 'unknown'"); + + return 1; +} + +int from_octave_str_unknown (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + error ("can not convert postgresql type 'unknown'"); + + return 1; +} + +int from_octave_bin_unknown (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + error ("can not convert postgresql type 'unknown'"); + + return 1; +} + +oct_pq_conv_t conv_unknown = {0, + 0, + oct_pq_el_oids_t (), + oct_pq_conv_cache_t (), + false, + false, + false, + "unknown", + &to_octave_str_unknown, + &to_octave_bin_unknown, + &from_octave_str_unknown, + &from_octave_bin_unknown}; + +/* end type unknown */ + oct_pq_conv_t *t_conv_ptrs[OCT_PQ_NUM_CONVERTERS] = {&conv_bool, &conv_oid, &conv_float8, @@ -1554,6 +1609,7 @@ &conv_box, &conv_circle, &conv_polygon, - &conv_path}; + &conv_path, + &conv_unknown}; oct_pq_conv_ptrs_t conv_ptrs (OCT_PQ_NUM_CONVERTERS, t_conv_ptrs); diff -r 9e624fa135a1 -r b3cbebad8a26 main/database/src/converters.h --- a/main/database/src/converters.h Sun May 12 10:19:34 2013 +0000 +++ b/main/database/src/converters.h Sun May 12 18:12:31 2013 +0000 @@ -32,7 +32,7 @@ #include "wrap_endian.h" -#define OCT_PQ_NUM_CONVERTERS 26 +#define OCT_PQ_NUM_CONVERTERS 27 typedef std::vector oct_pq_dynvec_t; diff -r 9e624fa135a1 -r b3cbebad8a26 main/database/src/pq_connection.cc --- a/main/database/src/pq_connection.cc Sun May 12 10:19:34 2013 +0000 +++ b/main/database/src/pq_connection.cc Sun May 12 18:12:31 2013 +0000 @@ -100,11 +100,13 @@ error ("could not read types"); } - - if (strcmp (PQparameterStatus (conn, "integer_datetimes"), "on")) - integer_datetimes = false; else - integer_datetimes = true; + { + if (strcmp (PQparameterStatus (conn, "integer_datetimes"), "on")) + integer_datetimes = false; + else + integer_datetimes = true; + } } } @@ -219,7 +221,7 @@ rt(1) = octave_value ("name"); rt(2) = octave_value ("oid"); - std::string cmd ("select oid, typname, typarray from pg_type where (typowner = $1 AND typtype = 'b' AND typarray != 0) OR typname = 'record';"), + std::string cmd ("select oid, typname, typarray from pg_type where (typowner = $1 AND typtype = 'b' AND typarray != 0) OR typname = 'record' OR typname = 'unknown';"), caller ("octave_pq_fill_base_types"); command c (*this, cmd, p, pt, rt, caller); @@ -260,7 +262,7 @@ 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_types", + error ("octave_pq_fill_base_types: type %s not found in pg_type", conv_ptrs[i]->name.c_str () + pq_bpl); return 1; }