Mercurial > dovecot > core-2.2
changeset 21260:0dd59dcdd804
lib-storage: Fix simplifying sequence sets and UID sets.
They were being handled completely wrong. The unit tests testing them
were also completely wrong.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 01 Dec 2016 02:29:44 +0200 |
parents | 5c75425daf63 |
children | 00f1de810983 |
files | src/lib-storage/mail-search-args-simplify.c src/lib-storage/test-mail-search-args-simplify.c |
diffstat | 2 files changed, 50 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/mail-search-args-simplify.c Thu Dec 01 02:26:08 2016 +0200 +++ b/src/lib-storage/mail-search-args-simplify.c Thu Dec 01 02:29:44 2016 +0200 @@ -1,6 +1,7 @@ /* Copyright (c) 2002-2016 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "array.h" #include "hash.h" #include "mail-search.h" @@ -105,15 +106,35 @@ } } +static void mail_search_args_simplify_set(struct mail_search_arg *args) +{ + const struct seq_range *seqset; + unsigned int count; + + if (args->match_not) { + /* invert the set to drop the NOT */ + args->match_not = FALSE; + seq_range_array_invert(&args->value.seqset, 1, (uint32_t)-1); + } + seqset = array_get(&args->value.seqset, &count); + if (count == 1 && seqset->seq1 == 1 && seqset->seq2 == (uint32_t)-1) { + /* 1:* is the same as ALL. */ + args->type = SEARCH_ALL; + } else if (count == 0) { + /* empty set is the same as NOT ALL. this is mainly coming + from mail_search_args_merge_set() intersection. */ + args->type = SEARCH_ALL; + args->match_not = TRUE; + } +} + static bool mail_search_args_merge_set(struct mail_search_simplify_ctx *ctx, struct mail_search_arg *args) { struct mail_search_simplify_prev_arg mask; struct mail_search_arg **prev_argp; - if (!((!args->match_not && ctx->parent_and) || - (args->match_not && !ctx->parent_and))) - return FALSE; + i_assert(!args->match_not); mail_search_arg_get_base_mask(args, &mask); prev_argp = mail_search_args_simplify_get_prev_argp(ctx, &mask); @@ -121,6 +142,10 @@ if (*prev_argp == NULL) { *prev_argp = args; return FALSE; + } else if (ctx->parent_and) { + seq_range_array_intersect(&(*prev_argp)->value.seqset, + &args->value.seqset); + return TRUE; } else { seq_range_array_merge(&(*prev_argp)->value.seqset, &args->value.seqset); @@ -526,6 +551,9 @@ args->type != SEARCH_OR)) ctx.removals = TRUE; } + if (args->type == SEARCH_SEQSET || + args->type == SEARCH_UIDSET) + mail_search_args_simplify_set(args); /* try to merge arguments */ merged = FALSE;
--- a/src/lib-storage/test-mail-search-args-simplify.c Thu Dec 01 02:26:08 2016 +0200 +++ b/src/lib-storage/test-mail-search-args-simplify.c Thu Dec 01 02:29:44 2016 +0200 @@ -46,20 +46,28 @@ { "ANSWERED NOT FLAGGED SEEN NOT DRAFT", "(ANSWERED SEEN) NOT (FLAGGED) NOT (DRAFT)" }, { "OR NOT ANSWERED NOT SEEN", "NOT (ANSWERED SEEN)" }, - { "1:5 10:20", "1:5,10:20" }, - { "1:5 NOT 10:20", "1:5 NOT 10:20" }, - { "1:5 NOT 10:20 NOT 30:40", "1:5 NOT 10:20 NOT 30:40" }, - { "OR 1:5 NOT 10:20", "(OR 1:5 NOT 10:20)" }, - { "OR 1:5 OR NOT 10:20 NOT 30:40", "(OR 1:5 NOT 10:20,30:40)" }, + { "1:* 1:*", "ALL" }, + { "OR 1:5 6:*", "ALL" }, + + { "2:* 2:*", "2:4294967295" }, + { "OR 2:* 2:*", "2:4294967295" }, - { "UID 1:5 UID 10:20", "UID 1:5,10:20" }, - { "UID 1:5 NOT UID 10:20", "UID 1:5 NOT UID 10:20" }, - { "UID 1:5 NOT UID 10:20 NOT UID 30:40", "UID 1:5 NOT UID 10:20 NOT UID 30:40" }, - { "OR UID 1:5 NOT UID 10:20", "(OR UID 1:5 NOT UID 10:20)" }, - { "OR UID 1:5 OR NOT UID 10:20 NOT UID 30:40", "(OR UID 1:5 NOT UID 10:20,30:40)" }, + { "1:5 6:7", "NOT ALL" }, + { "1:5 3:7", "3:5" }, + { "1:5 3:7 4:9", "4:5" }, + { "1:5 OR 3:4 4:6", "3:5" }, + { "OR 1 2", "1:2" }, + { "NOT 1,3:5", "2,6:4294967295" }, + { "NOT 1:100 NOT 50:200", "201:4294967295" }, + { "OR NOT 1:100 NOT 50:200", "1:49,101:4294967295" }, + + { "UID 1:5 UID 6:7", "NOT ALL" }, + { "UID 1:5 UID 3:7", "UID 3:5" }, + { "OR UID 1 UID 2", "UID 1:2" }, + { "NOT UID 1,3:5", "UID 2,6:4294967295" }, { "1:5 UID 10:20", "1:5 UID 10:20" }, - { "1:5 NOT UID 10:20", "1:5 NOT UID 10:20" }, + { "1:5 NOT UID 10:20", "1:5 UID 1:9,21:4294967295" }, { "BEFORE 03-Aug-2014 BEFORE 01-Aug-2014 BEFORE 02-Aug-2014", "BEFORE \"01-Aug-2014\"" }, { "OR BEFORE 01-Aug-2014 BEFORE 02-Aug-2014", "BEFORE \"02-Aug-2014\"" },