]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/backends/gsql/gsqlbackend.cc
Merge pull request #7460 from mind04/updated-masters
[thirdparty/pdns.git] / pdns / backends / gsql / gsqlbackend.cc
index 5e4d9070cad10a2c453bf6bab159799da16e35eb..cbc9caef51b8c4d3e825360184f3c5c61791cc29 100644 (file)
@@ -224,7 +224,7 @@ bool GSQLBackend::setMaster(const DNSName &domain, const string &ip)
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to set master of domain '"+domain.toLogString()+"': "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to set master of domain '"+domain.toLogString()+"' to IP address " + ip + ": "+e.txtReason());
   }
   return true;
 }
@@ -241,7 +241,7 @@ bool GSQLBackend::setKind(const DNSName &domain, const DomainInfo::DomainKind ki
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to set kind of domain '"+domain.toLogString()+"': "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to set kind of domain '"+domain.toLogString()+"' to " + toUpper(DomainInfo::getKindString(kind)) + ": "+e.txtReason());
   }
   return true;
 }
@@ -258,7 +258,7 @@ bool GSQLBackend::setAccount(const DNSName &domain, const string &account)
             reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to set account of domain '"+domain.toLogString()+"': "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to set account of domain '"+domain.toLogString()+"' to '" + account + "': "+e.txtReason());
   }
   return true;
 }
@@ -277,7 +277,7 @@ bool GSQLBackend::getDomainInfo(const DNSName &domain, DomainInfo &di, bool getS
       reset();
   }
   catch(SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to retrieve information about a domain: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to retrieve information about domain '" + domain.toLogString() + "': "+e.txtReason());
   }
 
   int numanswers=d_result.size();
@@ -292,14 +292,16 @@ bool GSQLBackend::getDomainInfo(const DNSName &domain, DomainInfo &di, bool getS
   } catch (...) {
     return false;
   }
+  string type=d_result[0][5];
+  di.account=d_result[0][6];
+  di.kind = DomainInfo::stringToKind(type);
+
   vector<string> masters;
   stringtok(masters, d_result[0][2], " ,\t");
   for(const auto& m : masters)
     di.masters.emplace_back(m, 53);
   di.last_check=pdns_stou(d_result[0][3]);
   di.notified_serial = pdns_stou(d_result[0][4]);
-  string type=d_result[0][5];
-  di.account=d_result[0][6];
   di.backend=this;
 
   di.serial = 0;
@@ -316,8 +318,6 @@ bool GSQLBackend::getDomainInfo(const DNSName &domain, DomainInfo &di, bool getS
     }
   }
 
-  di.kind = DomainInfo::stringToKind(type);
-
   return true;
 }
 
@@ -338,36 +338,78 @@ void GSQLBackend::getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains)
   }
 
   vector<DomainInfo> allSlaves;
-  int numanswers=d_result.size();
-  for(int n=0;n<numanswers;++n) { // id,name,master,last_check
+
+  bool loggedAssertRowColumns = false;
+  for(const auto& row : d_result) { // id,name,master,last_check
     DomainInfo sd;
-    ASSERT_ROW_COLUMNS("info-all-slaves-query", d_result[n], 4);
-    sd.id=pdns_stou(d_result[n][0]);
     try {
-      sd.zone= DNSName(d_result[n][1]);
-    } catch (...) {
+      ASSERT_ROW_COLUMNS("info-all-slaves-query", row, 4);
+    } catch(const PDNSException &e) {
+      if (!loggedAssertRowColumns) {
+        g_log<<Logger::Warning<<e.reason<<endl;
+      }
+      loggedAssertRowColumns = true;
+      continue;
+    }
+
+    try {
+      sd.zone = DNSName(row[1]);
+    } catch(const std::runtime_error &e) {
+      g_log<<Logger::Warning<<"Domain name '"<<row[1]<<"' is not a valid DNS name: "<<e.what()<<endl;
+      continue;
+    }
+
+    try {
+      sd.id=pdns_stou(row[0]);
+    } catch (const std::exception &e) {
+      g_log<<Logger::Warning<<"Could not convert id ("<<row[0]<<") for domain '"<<sd.zone<<"' into an integer: "<<e.what()<<endl;
       continue;
     }
 
     vector<string> masters;
-    stringtok(masters, d_result[n][2], ", \t");
-    for(const auto& m : masters)
-      sd.masters.emplace_back(m, 53);
+    stringtok(masters, row[2], ", \t");
+    for(const auto& m : masters) {
+      try {
+        sd.masters.emplace_back(m, 53);
+      } catch(const PDNSException &e) {
+        g_log<<Logger::Warning<<"Could not parse master address ("<<m<<") for zone '"<<sd.zone<<"': "<<e.reason<<endl;
+      }
+    }
+    if (sd.masters.empty()) {
+      g_log<<Logger::Warning<<"No masters for slave zone '"<<sd.zone<<"' found in the database"<<endl;
+      continue;
+    }
+
+    try {
+      sd.last_check=pdns_stou(row[3]);
+    } catch (const std::exception &e) {
+      g_log<<Logger::Warning<<"Could not convert last_check ("<<row[3]<<") for domain '"<<sd.zone<<"' into an integer: "<<e.what()<<endl;
+      continue;
+    }
 
-    sd.last_check=pdns_stou(d_result[n][3]);
     sd.backend=this;
     sd.kind=DomainInfo::Slave;
     allSlaves.push_back(sd);
   }
 
-  for(vector<DomainInfo>::iterator i=allSlaves.begin();i!=allSlaves.end();++i) {
-    SOAData sdata;
-    sdata.serial=0;
-    sdata.refresh=0;
-    getSOA(i->zone,sdata);
-    if((time_t)(i->last_check+sdata.refresh) < time(0)) {
-      i->serial=sdata.serial;
-      unfreshDomains->push_back(*i);
+  for (auto& slave : allSlaves) {
+    try {
+      SOAData sdata;
+      sdata.serial=0;
+      sdata.refresh=0;
+      getSOA(slave.zone, sdata);
+      if(static_cast<time_t>(slave.last_check + sdata.refresh) < time(nullptr)) {
+        slave.serial=sdata.serial;
+        unfreshDomains->push_back(slave);
+      }
+    }
+    catch(const std::exception& exp) {
+      g_log<<Logger::Warning<<"Error while parsing SOA data for slave zone '"<<slave.zone.toLogString()<<"': "<<exp.what()<<endl;
+      continue;
+    }
+    catch(...) {
+      g_log<<Logger::Warning<<"Error while parsing SOA data for slave zone '"<<slave.zone.toLogString()<<"', skipping"<<endl;
+      continue;
     }
   }
 }
@@ -438,7 +480,7 @@ bool GSQLBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName
           reset();
       }
       catch(SSqlException &e) {
-        throw PDNSException("GSQLBackend unable to update ordername and auth for domain_id "+itoa(domain_id)+": "+e.txtReason());
+        throw PDNSException("GSQLBackend unable to update ordername and auth for " + qname.toLogString() + " for domain_id "+itoa(domain_id)+", domain name '" + qname.toLogString() + "': "+e.txtReason());
       }
     } else {
       try {
@@ -454,7 +496,7 @@ bool GSQLBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName
           reset();
       }
       catch(SSqlException &e) {
-        throw PDNSException("GSQLBackend unable to update ordername and auth per type for domain_id "+itoa(domain_id)+": "+e.txtReason());
+        throw PDNSException("GSQLBackend unable to update ordername and auth for " + qname.toLogString() + "|" + QType(qtype).getName() + " for domain_id "+itoa(domain_id)+": "+e.txtReason());
       }
     }
   } else {
@@ -470,7 +512,7 @@ bool GSQLBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName
           reset();
       }
       catch(SSqlException &e) {
-        throw PDNSException("GSQLBackend unable to nullify ordername and update auth for domain_id "+itoa(domain_id)+": "+e.txtReason());
+        throw PDNSException("GSQLBackend unable to nullify ordername and update auth for " + qname.toLogString() + " for domain_id "+itoa(domain_id)+": "+e.txtReason());
       }
     } else {
       try {
@@ -485,7 +527,7 @@ bool GSQLBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName
           reset();
       }
       catch(SSqlException &e) {
-        throw PDNSException("GSQLBackend unable to nullify ordername and update auth per type for domain_id "+itoa(domain_id)+": "+e.txtReason());
+        throw PDNSException("GSQLBackend unable to nullify ordername and update auth for " + qname.toLogString() + "|" + QType(qtype).getName() + " for domain_id "+itoa(domain_id)+": "+e.txtReason());
       }
     }
   }
@@ -577,7 +619,7 @@ bool GSQLBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qna
     d_afterOrderQuery_stmt->reset();
   }
   catch(SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to find before/after (after) for domain_id "+itoa(id)+": "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to find before/after (after) for domain_id "+itoa(id)+" and qname '"+ qname.toLogString() +"': "+e.txtReason());
   }
 
   if(after.empty()) {
@@ -595,7 +637,7 @@ bool GSQLBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qna
       d_firstOrderQuery_stmt->reset();
     }
     catch(SSqlException &e) {
-      throw PDNSException("GSQLBackend unable to find before/after (first) for domain_id "+itoa(id)+": "+e.txtReason());
+      throw PDNSException("GSQLBackend unable to find before/after (first) for domain_id "+itoa(id)+" and qname '"+ qname.toLogString() + "': "+e.txtReason());
     }
   }
 
@@ -622,7 +664,7 @@ bool GSQLBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qna
       d_beforeOrderQuery_stmt->reset();
     }
     catch(SSqlException &e) {
-      throw PDNSException("GSQLBackend unable to find before/after (before) for domain_id "+itoa(id)+": "+e.txtReason());
+      throw PDNSException("GSQLBackend unable to find before/after (before) for domain_id "+itoa(id)+" and qname '"+ qname.toLogString() + ": "+e.txtReason());
     }
 
     if(! unhashed.empty())
@@ -650,7 +692,7 @@ bool GSQLBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qna
       d_lastOrderQuery_stmt->reset();
     }
     catch(SSqlException &e) {
-      throw PDNSException("GSQLBackend unable to find before/after (last) for domain_id "+itoa(id)+": "+e.txtReason());
+      throw PDNSException("GSQLBackend unable to find before/after (last) for domain_id "+itoa(id)+" and qname '"+ qname.toLogString() + ": "+e.txtReason());
     }
   } else {
     before=qname;
@@ -676,7 +718,7 @@ bool GSQLBackend::addDomainKey(const DNSName& name, const KeyData& key, int64_t&
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to store key: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to store key for domain '"+ name.toLogString() + "': "+e.txtReason());
   }
 
   try {
@@ -717,7 +759,7 @@ bool GSQLBackend::activateDomainKey(const DNSName& name, unsigned int id)
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to activate key: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to activate key with id "+ std::to_string(id) + " for domain '" + name.toLogString() + "': "+e.txtReason());
   }
   return true;
 }
@@ -737,7 +779,7 @@ bool GSQLBackend::deactivateDomainKey(const DNSName& name, unsigned int id)
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to deactivate key: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to deactivate key with id "+ std::to_string(id) + " for domain '" + name.toLogString() + "': "+e.txtReason());
   }
   return true;
 }
@@ -757,7 +799,7 @@ bool GSQLBackend::removeDomainKey(const DNSName& name, unsigned int id)
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to remove key: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to remove key with id "+ std::to_string(id) + " for domain '" + name.toLogString() + "': "+e.txtReason());
   }
   return true;
 }
@@ -788,7 +830,7 @@ bool GSQLBackend::getTSIGKey(const DNSName& name, DNSName* algorithm, string* co
     d_getTSIGKeyQuery_stmt->reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to retrieve named TSIG key: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to retrieve TSIG key with name '" + name.toLogString() + "': "+e.txtReason());
   }
 
   return !content->empty();
@@ -807,7 +849,7 @@ bool GSQLBackend::setTSIGKey(const DNSName& name, const DNSName& algorithm, cons
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to store named TSIG key: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to store TSIG key with name '" + name.toLogString() + "' and algorithm '" + algorithm.toString() + "': "+e.txtReason());
   }
   return true;
 }
@@ -823,7 +865,7 @@ bool GSQLBackend::deleteTSIGKey(const DNSName& name)
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to store named TSIG key: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to delete TSIG key with name '" + name.toLogString() + "': "+e.txtReason());
   }
   return true;
 }
@@ -921,14 +963,14 @@ bool GSQLBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string
       d_GetAllDomainMetadataQuery_stmt->nextRow(row);
       ASSERT_ROW_COLUMNS("get-all-domain-metadata-query", row, 2);
 
-      if (!isDnssecDomainMetadata(row[0]))
+      if (d_dnssecQueries || !isDnssecDomainMetadata(row[0]))
         meta[row[0]].push_back(row[1]);
     }
 
     d_GetAllDomainMetadataQuery_stmt->reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to list metadata: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to list metadata for domain '" + name.toLogString() + "': "+e.txtReason());
   }
 
   return true;
@@ -959,7 +1001,7 @@ bool GSQLBackend::getDomainMetadata(const DNSName& name, const std::string& kind
     d_GetDomainMetadataQuery_stmt->reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to list metadata: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to get metadata kind '" + kind + "' for domain '" + name.toLogString() + "': "+e.txtReason());
   }
 
   return true;
@@ -990,7 +1032,7 @@ bool GSQLBackend::setDomainMetadata(const DNSName& name, const std::string& kind
     }
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to store metadata key: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to set metadata kind '" + kind + "' for domain '" + name.toLogString() + "': "+e.txtReason());
   }
   
   return true;
@@ -1036,7 +1078,7 @@ void GSQLBackend::lookup(const QType &qtype,const DNSName &qname, DNSPacket *pkt
       execute();
   }
   catch(SSqlException &e) {
-    throw PDNSException("GSQLBackend lookup query:"+e.txtReason());
+    throw PDNSException("GSQLBackend unable to lookup '" + qname.toLogString() + "|" + qtype.getName() + "':"+e.txtReason());
   }
 
   d_qname=qname;
@@ -1057,7 +1099,7 @@ bool GSQLBackend::list(const DNSName &target, int domain_id, bool include_disabl
       execute();
   }
   catch(SSqlException &e) {
-    throw PDNSException("GSQLBackend list query: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to list domain '" + target.toLogString() + "': "+e.txtReason());
   }
 
   d_qname.clear();
@@ -1080,7 +1122,7 @@ bool GSQLBackend::listSubZone(const DNSName &zone, int domain_id) {
       execute();      
   }
   catch(SSqlException &e) {
-    throw PDNSException("GSQLBackend listSubZone query: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to list SubZones for domain '" + zone.toLogString() + "': "+e.txtReason());
   }
   d_qname.clear();
   return true;
@@ -1131,7 +1173,7 @@ bool GSQLBackend::superMasterBackend(const string &ip, const DNSName &domain, co
         reset();
     }
     catch (SSqlException &e) {
-      throw PDNSException("GSQLBackend unable to search for a domain: "+e.txtReason());
+      throw PDNSException("GSQLBackend unable to search for a supermaster with IP " + ip + " and nameserver name '" + i->content + "' for domain '" + domain.toLogString() + "': "+e.txtReason());
     }
     if(!d_result.empty()) {
       ASSERT_ROW_COLUMNS("supermaster-query", d_result[0], 1);
@@ -1256,12 +1298,28 @@ void GSQLBackend::getAllDomains(vector<DomainInfo> *domains, bool include_disabl
       } catch (...) {
         continue;
       }
+
+      if (pdns_iequals(row[3], "MASTER")) {
+        di.kind = DomainInfo::Master;
+      } else if (pdns_iequals(row[3], "SLAVE")) {
+        di.kind = DomainInfo::Slave;
+      } else if (pdns_iequals(row[3], "NATIVE")) {
+        di.kind = DomainInfo::Native;
+      } else {
+        g_log<<Logger::Warning<<"Could not parse domain kind '"<<row[3]<<"' as one of 'MASTER', 'SLAVE' or 'NATIVE'. Setting zone kind to 'NATIVE'"<<endl;
+        di.kind = DomainInfo::Native;
+      }
   
       if (!row[4].empty()) {
         vector<string> masters;
         stringtok(masters, row[4], " ,\t");
-        for(const auto& m : masters)
-          di.masters.emplace_back(m, 53);
+        for(const auto& m : masters) {
+          try {
+            di.masters.emplace_back(m, 53);
+          } catch(const PDNSException &e) {
+            g_log<<Logger::Warning<<"Could not parse master address ("<<m<<") for zone '"<<di.zone<<"': "<<e.reason;
+          }
+        }
       }
 
       SOAData sd;
@@ -1271,13 +1329,6 @@ void GSQLBackend::getAllDomains(vector<DomainInfo> *domains, bool include_disabl
       di.last_check = pdns_stou(row[6]);
       di.account = row[7];
 
-      if (pdns_iequals(row[3], "MASTER"))
-        di.kind = DomainInfo::Master;
-      else if (pdns_iequals(row[3], "SLAVE"))
-        di.kind = DomainInfo::Slave;
-      else
-        di.kind = DomainInfo::Native;
-  
       di.backend = this;
   
       domains->push_back(di);
@@ -1310,7 +1361,7 @@ bool GSQLBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const Q
     }
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to delete RRSet: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to delete RRSet " + qname.toLogString() + "|" + qt.getName() + ": "+e.txtReason());
   }
 
   if (rrset.empty()) {
@@ -1325,7 +1376,7 @@ bool GSQLBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const Q
         reset();
     }
     catch (SSqlException &e) {
-      throw PDNSException("GSQLBackend unable to delete comment: "+e.txtReason());
+      throw PDNSException("GSQLBackend unable to delete comment for RRSet " + qname.toLogString() + "|" + qt.getName() + ": "+e.txtReason());
     }
   }
   for(const auto& rr: rrset) {
@@ -1335,7 +1386,7 @@ bool GSQLBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const Q
   return true;
 }
 
-bool GSQLBackend::feedRecord(const DNSResourceRecord &r, const DNSName &ordername)
+bool GSQLBackend::feedRecord(const DNSResourceRecord &r, const DNSName &ordername, bool ordernameIsNSEC3)
 {
   int prio=0;
   string content(r.content);
@@ -1375,7 +1426,7 @@ bool GSQLBackend::feedRecord(const DNSResourceRecord &r, const DNSName &ordernam
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to feed record: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to feed record " + r.qname.toLogString() + "|" + r.qtype.getName() + ": "+e.txtReason());
   }
   return true; // XXX FIXME this API should not return 'true' I think -ahu 
 }
@@ -1395,7 +1446,7 @@ bool GSQLBackend::feedEnts(int domain_id, map<DNSName,bool>& nonterm)
         reset();
     }
     catch (SSqlException &e) {
-      throw PDNSException("GSQLBackend unable to feed empty non-terminal: "+e.txtReason());
+      throw PDNSException("GSQLBackend unable to feed empty non-terminal with name '" + nt.first.toLogString() + "': "+e.txtReason());
     }
   }
   return true;
@@ -1429,7 +1480,7 @@ bool GSQLBackend::feedEnts3(int domain_id, const DNSName &domain, map<DNSName,bo
         reset();
     }
     catch (SSqlException &e) {
-      throw PDNSException("GSQLBackend unable to feed empty non-terminal: "+e.txtReason());
+      throw PDNSException("GSQLBackend unable to feed empty non-terminal with name '" + nt.first.toLogString() + "' (hashed name '"+ toBase32Hex(hashQNameWithSalt(ns3prc, nt.first)) + "') : "+e.txtReason());
     }
   }
   return true;
@@ -1451,7 +1502,7 @@ bool GSQLBackend::startTransaction(const DNSName &domain, int domain_id)
   }
   catch (SSqlException &e) {
     d_inTransaction = false;
-    throw PDNSException("Database failed to start transaction: "+e.txtReason());
+    throw PDNSException("Database failed to start transaction for domain '" + domain.toLogString() + "': "+e.txtReason());
   }
 
   return true;
@@ -1495,7 +1546,7 @@ bool GSQLBackend::listComments(const uint32_t domain_id)
       execute();
   }
   catch(SSqlException &e) {
-    throw PDNSException("GSQLBackend list comments query: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to list comments for domain id " + std::to_string(domain_id) + ": "+e.txtReason());
   }
 
   return true;
@@ -1547,7 +1598,7 @@ void GSQLBackend::feedComment(const Comment& comment)
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to feed comment: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to feed comment for RRSet '" + comment.qname.toLogString() + "|" + comment.qtype.getName() + "': "+e.txtReason());
   }
 }
 
@@ -1564,7 +1615,7 @@ bool GSQLBackend::replaceComments(const uint32_t domain_id, const DNSName& qname
       reset();
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to delete comment: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to delete comment for RRSet '" + qname.toLogString() + "|" + qt.getName() + "': "+e.txtReason());
   }
 
   for(const auto& comment: comments) {
@@ -1597,7 +1648,7 @@ string GSQLBackend::directBackendCmd(const string &query)
    return out.str();
  }
  catch (SSqlException &e) {
-   throw PDNSException("GSQLBackend unable to execute query: "+e.txtReason());
+   throw PDNSException("GSQLBackend unable to execute direct command query '" + query + "': "+e.txtReason());
  }
 }
 
@@ -1614,9 +1665,8 @@ string GSQLBackend::pattern2SQLPattern(const string &pattern)
 bool GSQLBackend::searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result)
 {
   d_qname.clear();
+  string escaped_pattern = pattern2SQLPattern(pattern);
   try {
-    string escaped_pattern = pattern2SQLPattern(pattern);
-
     reconnectIfNeeded();
 
     d_SearchRecordsQuery_stmt->
@@ -1644,7 +1694,7 @@ bool GSQLBackend::searchRecords(const string &pattern, int maxResults, vector<DN
     return true;
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to execute query: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to search for records with pattern '" + pattern + "' (escaped pattern '" + escaped_pattern + "'): "+e.txtReason());
   }
 
   return false;
@@ -1653,9 +1703,8 @@ bool GSQLBackend::searchRecords(const string &pattern, int maxResults, vector<DN
 bool GSQLBackend::searchComments(const string &pattern, int maxResults, vector<Comment>& result)
 {
   Comment c;
+  string escaped_pattern = pattern2SQLPattern(pattern);
   try {
-    string escaped_pattern = pattern2SQLPattern(pattern);
-
     reconnectIfNeeded();
 
     d_SearchCommentsQuery_stmt->
@@ -1673,12 +1722,12 @@ bool GSQLBackend::searchComments(const string &pattern, int maxResults, vector<C
       result.push_back(comment);
     }
 
-    d_SearchRecordsQuery_stmt->reset();
+    d_SearchCommentsQuery_stmt->reset();
 
     return true;
   }
   catch (SSqlException &e) {
-    throw PDNSException("GSQLBackend unable to execute query: "+e.txtReason());
+    throw PDNSException("GSQLBackend unable to search for comments with pattern '" + pattern + "' (escaped pattern '" + escaped_pattern + "'): "+e.txtReason());
   }
 
   return false;