List:MySQL++« Previous MessageNext Message »
From:Warren Young Date:April 12 2011 11:35pm
Subject:Re: Crash in DBDriver::fetch_row on a heavily loaded system...
View as plain text  
On 4/12/2011 4:45 PM, Dan Cook (dancook) wrote:
>>> http://dev.mysql.com/doc/refman/5.5/en/null-mysql-store-result.html
>
> What kind of workaround are you suggesting?

That page is pretty much a functional spec for a MySQL++ patch.  It's 
saying that Query::storein_sequence() shouldn't blindly assume the 
underlying C API library will never somehow barf and therefore return 
bogus results.

Try this patch:

Index: lib/query.cpp
===================================================================
--- lib/query.cpp   (revision 2683)
+++ lib/query.cpp   (working copy)
@@ -476,6 +476,13 @@
  }


+bool
+Query::result_empty()
+{
+   return conn_->driver()->result_empty();
+}
+
+
  StoreQueryResult
  Query::store()
  {
Index: lib/query.h
===================================================================
--- lib/query.h (revision 2683)
+++ lib/query.h (working copy)
@@ -274,6 +274,11 @@
     /// or the stream interface.)
     void reset();

+   /// \brief Returns true if the most recent result set was empty
+   ///
+   /// Wraps DBDriver::result_empty()
+   bool result_empty();
+
     /// \brief Get built query as a C++ string
     std::string str() { return str(template_defaults); }

@@ -748,17 +753,32 @@
     template <class Sequence>
     void storein_sequence(Sequence& con, const SQLTypeAdapter& s)
     {
-       UseQueryResult result = use(s);
-       while (1) {
-           MYSQL_ROW d = result.fetch_raw_row();
-           if (!d)
-               break;
-           Row row(d, &result, result.fetch_lengths(),
-                   throw_exceptions());
-           if (!row)
-               break;
-           con.push_back(typename Sequence::value_type(row));
+       if (UseQueryResult result = use(s)) {
+           while (1) {
+               MYSQL_ROW d = result.fetch_raw_row();
+               if (!d)
+                   break;
+               Row row(d, &result, result.fetch_lengths(),
+                       throw_exceptions());
+               if (!row)
+                   break;
+               con.push_back(typename Sequence::value_type(row));
+           }
         }
+       else if (!result_empty()) {
+           // Underlying MySQL C API returned an empty result for this
+           // query, but it also says it should have returned
+           // something.  Reasons it can do that are given here:
+           // 
http://dev.mysql.com/doc/refman/5.5/en/null-mysql-store-result.html
+           // Regardless, it means the C library barfed, so we can't
+           // just return an empty result set.
+           copacetic_ = false;
+           if (throw_exceptions()) {
+               throw UseQueryError("Bogus empty result");
+           }
+       }
+       // else, it was *supposed* to return nothing, because query was
+       // an INSERT, CREATE, etc. sort.  So, leave con untouched.
     }

     /// \brief Execute template query using given parameters, storing


Be careful, my mailer wrapped the URL in the big comment above.  Fix it 
before applying the patch.

I don't see a way to distinguish the "malloc() returned 0" case, but if 
that's happening, installing this patch will cause your program to start 
crashing under the same conditions when *its* memory allocations fail 
instead.

If that fixes your symptom, please let me know, as I haven't checked 
this into svn.  It is certainly incomplete, if for no other reason than 
because it doesn't fix Query::storein_set() as well.

I also wonder whether, given the potential circumstances for this 
problem to crop up, if Query::result_empty() should have additional 
checks on conn_ and conn->driver().
Thread
Crash in DBDriver::fetch_row on a heavily loaded system...dancook)12 Apr
  • Re: Crash in DBDriver::fetch_row on a heavily loaded system...Adrian Cornish12 Apr
    • RE: Crash in DBDriver::fetch_row on a heavily loaded system...dancook)12 Apr
    • RE: Crash in DBDriver::fetch_row on a heavily loaded system...dancook)13 Apr
      • Re: Crash in DBDriver::fetch_row on a heavily loaded system...Warren Young13 Apr
        • Re: Crash in DBDriver::fetch_row on a heavily loaded system...Adrian Cornish13 Apr
          • Re: Crash in DBDriver::fetch_row on a heavily loaded system...Warren Young13 Apr
        • RE: Crash in DBDriver::fetch_row on a heavily loaded system...dancook)15 Apr
          • Re: Crash in DBDriver::fetch_row on a heavily loaded system...Warren Young15 Apr
            • Re: Crash in DBDriver::fetch_row on a heavily loaded system...Warren Young15 Apr
            • RE: Crash in DBDriver::fetch_row on a heavily loaded system...dancook)16 Apr
              • Re: Crash in DBDriver::fetch_row on a heavily loaded system...Warren Young16 Apr
          • SSQLS: Number of colomns in a tabledancook)19 May
            • Re: SSQLS: Number of colomns in a tableAdrian Cornish19 May
            • Re: SSQLS: Number of colomns in a tableAdrian Cornish19 May
              • Re: SSQLS: Number of colomns in a tableWarren Young19 May
                • Re: SSQLS: Number of colomns in a tableAdrian Cornish19 May
                  • RE: SSQLS: Number of colomns in a tabledancook)19 May
                  • Re: SSQLS: Number of colomns in a tableWarren Young19 May
                    • Re: SSQLS: Number of colomns in a tableWarren Young20 May
      • Re: Crash in DBDriver::fetch_row on a heavily loaded system...Adrian Cornish13 Apr
        • Re: Crash in DBDriver::fetch_row on a heavily loaded system...Warren Young13 Apr