mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[2301] Update ANY_SUB query to use LIKE clause efficiently
See <https://lists.isc.org/pipermail/bind10-dev/2012-March/003167.html> for discussion. We should not do concatenation in the SQL clause (i.e., pass an expression to LIKE). We also query on the 'rname' column (labels in reverse order) instead of 'name'.
This commit is contained in:
@@ -20,6 +20,8 @@
|
||||
|
||||
#include <exceptions/exceptions.h>
|
||||
|
||||
#include <dns/name.h>
|
||||
|
||||
#include <datasrc/sqlite3_accessor.h>
|
||||
#include <datasrc/logger.h>
|
||||
#include <datasrc/data_source.h>
|
||||
@@ -85,7 +87,7 @@ const char* const text_statements[NUM_STATEMENTS] = {
|
||||
"SELECT rdtype, ttl, sigtype, rdata FROM records " // ANY
|
||||
"WHERE zone_id=?1 AND name=?2",
|
||||
"SELECT rdtype, ttl, sigtype, rdata " // ANY_SUB
|
||||
"FROM records WHERE zone_id=?1 AND name LIKE (\"%.\" || ?2)",
|
||||
"FROM records WHERE zone_id=?1 AND rname LIKE ?2",
|
||||
"BEGIN", // BEGIN
|
||||
"COMMIT", // COMMIT
|
||||
"ROLLBACK", // ROLLBACK
|
||||
@@ -660,17 +662,27 @@ public:
|
||||
statement_(NULL),
|
||||
name_(name)
|
||||
{
|
||||
// Choose the statement text depending on the query type
|
||||
const char* statement(NULL);
|
||||
// Choose the statement text depending on the query type, and
|
||||
// prepare a statement to get data from it.
|
||||
switch (qtype) {
|
||||
case QT_ANY:
|
||||
statement = text_statements[ANY];
|
||||
statement_ = prepare(accessor->dbparameters_->db_,
|
||||
text_statements[ANY]);
|
||||
bindZoneId(id);
|
||||
bindName(name_);
|
||||
break;
|
||||
case QT_SUBDOMAINS:
|
||||
statement = text_statements[ANY_SUB];
|
||||
statement_ = prepare(accessor->dbparameters_->db_,
|
||||
text_statements[ANY_SUB]);
|
||||
bindZoneId(id);
|
||||
// Done once, this should not be very inefficient.
|
||||
bindName(isc::dns::Name(name_).reverse().toText() + "%");
|
||||
break;
|
||||
case QT_NSEC3:
|
||||
statement = text_statements[NSEC3];
|
||||
statement_ = prepare(accessor->dbparameters_->db_,
|
||||
text_statements[NSEC3]);
|
||||
bindZoneId(id);
|
||||
bindName(name_);
|
||||
break;
|
||||
default:
|
||||
// Can Not Happen - there isn't any other type of query
|
||||
@@ -680,11 +692,6 @@ public:
|
||||
"Invalid qtype passed - unreachable code branch "
|
||||
"reached");
|
||||
}
|
||||
|
||||
// We create the statement now and then just keep getting data from it
|
||||
statement_ = prepare(accessor->dbparameters_->db_, statement);
|
||||
bindZoneId(id);
|
||||
bindName(name_);
|
||||
}
|
||||
|
||||
bool getNext(std::string (&data)[COLUMN_COUNT]) {
|
||||
|
Reference in New Issue
Block a user