changeset 11698:b3cbebad8a26 octave-forge

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.
author i7tiol
date Sun, 12 May 2013 18:12:31 +0000
parents 9e624fa135a1
children dafee4563c36
files main/database/src/converters.cc main/database/src/converters.h main/database/src/pq_connection.cc
diffstat 3 files changed, 66 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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<char> oct_pq_dynvec_t;
 
--- 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;
         }