Panu Matilainen f7ecc5
From cc897d03255e2a5aa672c40c043ca3fde88b8480 Mon Sep 17 00:00:00 2001
Panu Matilainen f7ecc5
Message-Id: <cc897d03255e2a5aa672c40c043ca3fde88b8480.1591774714.git.pmatilai@redhat.com>
Panu Matilainen f7ecc5
From: Panu Matilainen <pmatilai@redhat.com>
Panu Matilainen f7ecc5
Date: Wed, 10 Jun 2020 10:33:06 +0300
Panu Matilainen f7ecc5
Subject: [PATCH] Fix completely broken prefix search on sqlite backend
Panu Matilainen f7ecc5
Panu Matilainen f7ecc5
The prefix search was so wrong it's a small miracle it ever did anything
Panu Matilainen f7ecc5
at all. What have I been thinking? Well, I do remember thinking this
Panu Matilainen f7ecc5
prefix stuff looks kinda fishy but then it seems to work so...
Panu Matilainen f7ecc5
Panu Matilainen f7ecc5
The prefix search belongs to the keyed iterator fetch case of course,
Panu Matilainen f7ecc5
not the case where we're otherwise iterating over all keys.
Panu Matilainen f7ecc5
Panu Matilainen f7ecc5
Fixes: #1260
Panu Matilainen f7ecc5
---
Panu Matilainen f7ecc5
 lib/backend/sqlite.c | 51 +++++++++++++++++++++++---------------------
Panu Matilainen f7ecc5
 1 file changed, 27 insertions(+), 24 deletions(-)
Panu Matilainen f7ecc5
Panu Matilainen f7ecc5
diff --git a/lib/backend/sqlite.c b/lib/backend/sqlite.c
Panu Matilainen f7ecc5
index 8520838df..ee9c62706 100644
Panu Matilainen f7ecc5
--- a/lib/backend/sqlite.c
Panu Matilainen f7ecc5
+++ b/lib/backend/sqlite.c
Panu Matilainen f7ecc5
@@ -548,13 +548,24 @@ static unsigned int sqlite_pkgdbKey(dbiIndex dbi, dbiCursor dbc)
Panu Matilainen f7ecc5
     return sqlite3_column_int(dbc->stmt, 0);
Panu Matilainen f7ecc5
 }
Panu Matilainen f7ecc5
 
Panu Matilainen f7ecc5
-static rpmRC sqlite_idxdbByKey(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexSet *set)
Panu Matilainen f7ecc5
+static rpmRC sqlite_idxdbByKey(dbiIndex dbi, dbiCursor dbc,
Panu Matilainen f7ecc5
+			    const char *keyp, size_t keylen, int searchType,
Panu Matilainen f7ecc5
+			    dbiIndexSet *set)
Panu Matilainen f7ecc5
 {
Panu Matilainen f7ecc5
-    int rc = dbiCursorPrep(dbc, "SELECT hnum, idx FROM '%q' WHERE key=?",
Panu Matilainen f7ecc5
+    int rc = RPMRC_NOTFOUND;
Panu Matilainen f7ecc5
+
Panu Matilainen f7ecc5
+    if (searchType == DBC_PREFIX_SEARCH) {
Panu Matilainen f7ecc5
+	rc = dbiCursorPrep(dbc, "SELECT hnum, idx FROM '%q' "
Panu Matilainen f7ecc5
+				"WHERE MATCH(key,'%q',%d) "
Panu Matilainen f7ecc5
+				"ORDER BY key",
Panu Matilainen f7ecc5
+				dbi->dbi_file, keyp, keylen);
Panu Matilainen f7ecc5
+    } else {
Panu Matilainen f7ecc5
+	rc = dbiCursorPrep(dbc, "SELECT hnum, idx FROM '%q' WHERE key=?",
Panu Matilainen f7ecc5
 			dbi->dbi_file);
Panu Matilainen f7ecc5
+	if (!rc)
Panu Matilainen f7ecc5
+	    rc = dbiCursorBindIdx(dbc, keyp, keylen, NULL);
Panu Matilainen f7ecc5
+    }
Panu Matilainen f7ecc5
 
Panu Matilainen f7ecc5
-    if (!rc)
Panu Matilainen f7ecc5
-	rc = dbiCursorBindIdx(dbc, keyp, keylen, NULL);
Panu Matilainen f7ecc5
 
Panu Matilainen f7ecc5
     if (!rc) {
Panu Matilainen f7ecc5
 	while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {
Panu Matilainen f7ecc5
@@ -576,21 +587,13 @@ static rpmRC sqlite_idxdbByKey(dbiIndex dbi, dbiCursor dbc, const char *keyp, si
Panu Matilainen f7ecc5
     return rc;
Panu Matilainen f7ecc5
 }
Panu Matilainen f7ecc5
 
Panu Matilainen f7ecc5
-static rpmRC sqlite_idxdbIter(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexSet *set, int searchType)
Panu Matilainen f7ecc5
+static rpmRC sqlite_idxdbIter(dbiIndex dbi, dbiCursor dbc, dbiIndexSet *set)
Panu Matilainen f7ecc5
 {
Panu Matilainen f7ecc5
     int rc = RPMRC_OK;
Panu Matilainen f7ecc5
 
Panu Matilainen f7ecc5
     if (dbc->stmt == NULL) {
Panu Matilainen f7ecc5
-	if (searchType == DBC_PREFIX_SEARCH) {
Panu Matilainen f7ecc5
-	    rc = dbiCursorPrep(dbc, "SELECT DISTINCT key FROM '%q' "
Panu Matilainen f7ecc5
-				    "WHERE MATCH(key,'%q',%d) "
Panu Matilainen f7ecc5
-				    "ORDER BY key",
Panu Matilainen f7ecc5
-				    dbi->dbi_file, keyp, keylen);
Panu Matilainen f7ecc5
-	} else {
Panu Matilainen f7ecc5
-	    rc = dbiCursorPrep(dbc, "SELECT DISTINCT key FROM '%q' "
Panu Matilainen f7ecc5
-				    "ORDER BY key",
Panu Matilainen f7ecc5
+	rc = dbiCursorPrep(dbc, "SELECT DISTINCT key FROM '%q' ORDER BY key",
Panu Matilainen f7ecc5
 				dbi->dbi_file);
Panu Matilainen f7ecc5
-	}
Panu Matilainen f7ecc5
 	if (set)
Panu Matilainen f7ecc5
 	    dbc->subc = dbiCursorInit(dbi, 0);
Panu Matilainen f7ecc5
     }
Panu Matilainen f7ecc5
@@ -605,14 +608,14 @@ static rpmRC sqlite_idxdbIter(dbiIndex dbi, dbiCursor dbc, const char *keyp, siz
Panu Matilainen f7ecc5
 	    dbc->key = sqlite3_column_blob(dbc->stmt, 0);
Panu Matilainen f7ecc5
 	}
Panu Matilainen f7ecc5
 	dbc->keylen = sqlite3_column_bytes(dbc->stmt, 0);
Panu Matilainen f7ecc5
-	if (set)
Panu Matilainen f7ecc5
-	    rc = sqlite_idxdbByKey(dbi, dbc->subc, dbc->key, dbc->keylen, set);
Panu Matilainen f7ecc5
-	rc = RPMRC_OK;
Panu Matilainen f7ecc5
-    } else if (rc == SQLITE_DONE) {
Panu Matilainen f7ecc5
-	if (searchType == DBC_PREFIX_SEARCH && (*set))
Panu Matilainen f7ecc5
+	if (dbc->subc) {
Panu Matilainen f7ecc5
+	    rc = sqlite_idxdbByKey(dbi, dbc->subc, dbc->key, dbc->keylen,
Panu Matilainen f7ecc5
+				    DBC_NORMAL_SEARCH, set);
Panu Matilainen f7ecc5
+	} else {
Panu Matilainen f7ecc5
 	    rc = RPMRC_OK;
Panu Matilainen f7ecc5
-	else
Panu Matilainen f7ecc5
-	    rc = RPMRC_NOTFOUND;
Panu Matilainen f7ecc5
+	}
Panu Matilainen f7ecc5
+    } else if (rc == SQLITE_DONE) {
Panu Matilainen f7ecc5
+	rc = RPMRC_NOTFOUND;
Panu Matilainen f7ecc5
     } else {
Panu Matilainen f7ecc5
 	rc = dbiCursorResult(dbc);
Panu Matilainen f7ecc5
     }
Panu Matilainen f7ecc5
@@ -623,10 +626,10 @@ static rpmRC sqlite_idxdbIter(dbiIndex dbi, dbiCursor dbc, const char *keyp, siz
Panu Matilainen f7ecc5
 static rpmRC sqlite_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexSet *set, int searchType)
Panu Matilainen f7ecc5
 {
Panu Matilainen f7ecc5
     int rc;
Panu Matilainen f7ecc5
-    if (keyp && searchType != DBC_PREFIX_SEARCH) {
Panu Matilainen f7ecc5
-	rc = sqlite_idxdbByKey(dbi, dbc, keyp, keylen, set);
Panu Matilainen f7ecc5
+    if (keyp) {
Panu Matilainen f7ecc5
+	rc = sqlite_idxdbByKey(dbi, dbc, keyp, keylen, searchType, set);
Panu Matilainen f7ecc5
     } else {
Panu Matilainen f7ecc5
-	rc = sqlite_idxdbIter(dbi, dbc, keyp, keylen, set, searchType);
Panu Matilainen f7ecc5
+	rc = sqlite_idxdbIter(dbi, dbc, set);
Panu Matilainen f7ecc5
     }
Panu Matilainen f7ecc5
 
Panu Matilainen f7ecc5
     return rc;
Panu Matilainen f7ecc5
-- 
Panu Matilainen f7ecc5
2.26.2
Panu Matilainen f7ecc5