# # # patch "database.cc" # from [be08533085302ee988bac5508aec2f28d90992ae] # to [7d05335695a344d562e1c81daed3f0bf525259d8] # # patch "tests/i_selector/__driver__.lua" # from [14129e3631b885efa53c2b3cd38ea18075c6518e] # to [89082b8caae184d6184476c5b28229343c1c4b06] # ============================================================ --- database.cc be08533085302ee988bac5508aec2f28d90992ae +++ database.cc 7d05335695a344d562e1c81daed3f0bf525259d8 @@ -3137,15 +3137,15 @@ database_impl::add_prefix_matching_const string const & prefix, query & q) { - L(FL("add_prefix_matching_constraint for '%s'") - % encode_hexenc(prefix)); + L(FL("add_prefix_matching_constraint for '%s'") % prefix); if (prefix.empty()) q.sql_cmd += "1"; // always true else { - string lower_bound(prefix); - string upper_bound(prefix); + string binary_prefix = decode_hexenc(prefix); + string lower_bound(binary_prefix); + string upper_bound(binary_prefix); string::reverse_iterator ity(upper_bound.rbegin()); ++(*ity); @@ -3177,6 +3177,17 @@ database_impl::add_prefix_matching_const q.args.push_back(blob(lower_bound)); q.args.push_back(blob(upper_bound)); } + + // encode_hexenc might have lost a nibble a the end, thus we possibly + // need to add a second check, with a LIKE operator on the hex + // encoded string. + + if (prefix.size() % 2 == 1) + { + string pattern = prefix + '%'; + q.sql_cmd += " AND (hex(" + colname + ") LIKE ?)"; + q.args.push_back(text(pattern)); + } } } @@ -3188,7 +3199,7 @@ database::complete(string const & partia completions.clear(); query q("SELECT id FROM revisions WHERE "); - imp->add_prefix_matching_constraint("id", decode_hexenc(partial), q); + imp->add_prefix_matching_constraint("id", partial, q); imp->fetch(res, 1, any_rows, q); for (size_t i = 0; i < res.size(); ++i) @@ -3204,7 +3215,7 @@ database::complete(string const & partia completions.clear(); query q("SELECT id FROM files WHERE "); - imp->add_prefix_matching_constraint("id", decode_hexenc(partial), q); + imp->add_prefix_matching_constraint("id", partial, q); imp->fetch(res, 1, any_rows, q); for (size_t i = 0; i < res.size(); ++i) @@ -3213,7 +3224,7 @@ database::complete(string const & partia res.clear(); q = query("SELECT id FROM file_deltas WHERE "); - imp->add_prefix_matching_constraint("id", decode_hexenc(partial), q); + imp->add_prefix_matching_constraint("id", partial, q); imp->fetch(res, 1, any_rows, q); for (size_t i = 0; i < res.size(); ++i) @@ -3228,7 +3239,7 @@ database::complete(string const & partia completions.clear(); query q("SELECT hash, id FROM public_keys WHERE "); - imp->add_prefix_matching_constraint("hash", decode_hexenc(partial), q); + imp->add_prefix_matching_constraint("hash", partial, q); imp->fetch(res, 2, any_rows, q); for (size_t i = 0; i < res.size(); ++i) @@ -3246,7 +3257,7 @@ database::select_parent(string const & p completions.clear(); query q("SELECT DISTINCT parent FROM revision_ancestry WHERE "); - imp->add_prefix_matching_constraint("child", partial, q); + imp->add_prefix_matching_constraint("child", encode_hexenc(partial), q); imp->fetch(res, 1, any_rows, q); for (size_t i = 0; i < res.size(); ++i) ============================================================ --- tests/i_selector/__driver__.lua 14129e3631b885efa53c2b3cd38ea18075c6518e +++ tests/i_selector/__driver__.lua 89082b8caae184d6184476c5b28229343c1c4b06 @@ -29,6 +29,6 @@ selmap("i:" .. string.sub(REV2, 1, 2), { selmap("i:" .. string.sub(REV2, 1, 2), {REV2}) -- expanding from the first char only -selmap_xfail("i:" .. string.sub(REV1, 1, 1), {REV1}) -selmap_xfail("i:" .. string.sub(REV2, 1, 1), {REV2}) +selmap("i:" .. string.sub(REV1, 1, 1), {REV1}) +selmap("i:" .. string.sub(REV2, 1, 1), {REV2})