List:MySQL++« Previous MessageNext Message »
From:Warren Young Date:December 11 2007 3:58am
Subject:Re: Mismatch between query results and SSQLS column count
View as plain text  
Drew M. wrote:
> 
> My original thinking was simply to replace an obscure exception with
> one that was a little more informative. If your ssqls structure and
> table (or query) didn't match, I think this would be hard to track
> down unless the code threw an exception.

This I did perceive, but I think making the library resilient in the 
face of DB schema changes makes more sense than making it complain. 
Neither crashes nor exceptions -- no matter how helpfully worded their 
error text -- are a good response to the database changing out from 
under the program.  In my experience, the most common such "problem" is 
just a new column being added, so the app should just cruise right on, 
ignoring the new column, doing what it always did with the subset of 
columns it already knows about.

I wish we could make it optional, so the B&D types can get "fail hard" 
behavior if they want it, but the only way I can think of to do that is 
through the OptionalExceptions mechanism, but I think you'd have to turn 
off the flag too early in a lot of cases to make it desirable.  Consider 
Query::storein(): many things happen before it starts translating data 
from Row form to SSQLS, and you might want exceptions for failures here 
but not in the translation.

We can solve this in SSQLS v2, where we can set a flag on the SSQLS 
itself to control such behavior.

> -       $popul .= "    s->I$j = row.at(O$j).conv(T$j());";
> -       $popul .= "\n" unless $j == $i;
> +       $popul .= "   if( (*i) == s->names[O$j]) {\n";
> +       $popul .= "       s->I$j = row[(*i).c_str()].conv(T$j());\n";
> +       $popul .= "       continue;\n";
> +       $popul .= "   }\n";

I guess this patch is against 2.3.2?  I didn't try it, but it seems 
reasonable if so.  In fact, I think it's the only way it could work in 
2.3.2 if you wish to keep the ABI intact.  If anyone wants this behavior 
in 2.3.2, they should apply this.

I had this feature in mind for v3.0, though, where the core of it can be 
done much more simply due to recent changes in Row:

Index: lib/custom.pl
===================================================================
--- lib/custom.pl       (revision 1988)
+++ lib/custom.pl       (working copy)
@@ -57,6 +57,7 @@
  #ifndef MYSQLPP_CUSTOM_H
  #define MYSQLPP_CUSTOM_H

+#include "noexceptions.h"
  #include "sql_types.h"

  #include <string>
@@ -295,7 +296,7 @@
         $parm_simple2c_b .= ", " unless $j == $i;
         $defs  .= "    T$j I$j;";
         $defs  .= "\n" unless $j == $i;
-       $popul .= "    s->I$j = row.at(O$j).conv(T$j());";
+       $popul .= "    s->I$j = row[N$j].conv(T$j());";
         $popul .= "\n" unless $j == $i;
          $names .= "    N$j ";
         $names .= ",\n" unless $j == $i;
@@ -846,6 +847,7 @@

    template <mysqlpp::sql_dummy_type dummy>
    void populate_##NAME (NAME *s, const mysqlpp::Row &row) {
+       mysqlpp::NoExceptions ignore_schema_mismatches(row);
  $popul
    }

That last change is the key: Row::operator[](const char*) used to throw 
an exception unconditionally when you indexed it on a field that doesn't 
exist.  Now it's optional, allowing the code to just go right on 
truckin' if there's a schema mismatch.

There were a bunch of ancillary changes required due to heretofore 
unrecognized limitations in MySQL++, plus some side things I needed to 
tackle for completeness.  Say 'svn diff -r1989:1991' if you want to see 
the whole story.

Thanks anyway for your effort.  The patch directed me to the right area 
of the code.
Thread
Mismatch between query results and SSQLS column countDrew M.7 Dec
  • Re: Mismatch between query results and SSQLS column countWarren Young8 Dec
    • Re: Mismatch between query results and SSQLS column countDrew M.10 Dec
      • Re: Mismatch between query results and SSQLS column countWarren Young11 Dec