mail-search-args-simplify.c revision 7000810786f2959f02cd6d2f4151a9eb61ff5db8
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
e28fa207d1a097fa6e4a867f74ee0761472ef1ceTimo Sirainen struct mail_search_arg *prev_flags, *prev_not_flags;
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen struct mail_search_arg *prev_seqset, *prev_not_seqset;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen struct mail_search_arg *prev_uidset, *prev_not_uidset;
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainenstatic bool mail_search_args_merge_flags(struct mail_search_simplify_ctx *ctx,
13d98ffa534f2e7d04a832c9d0153fc9c568b878Timo Sirainen prev_argp = !args->match_not ? &ctx->prev_flags : &ctx->prev_not_flags;
5694eeb99b69dea8033ca77ad69743c6b4871370Timo Sirainen (*prev_argp)->value.flags |= args->value.flags;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic bool mail_search_args_merge_set(struct mail_search_simplify_ctx *ctx,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen prev_argp = !args->match_not ? &ctx->prev_seqset :
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen prev_argp = !args->match_not ? &ctx->prev_uidset :
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen seq_range_array_merge(&(*prev_argp)->value.seqset,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmail_search_args_simplify_sub(struct mailbox *box,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct mail_search_arg *args, bool parent_and)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct mail_search_arg *sub, *prev_arg = NULL;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (args->match_not && (args->type == SEARCH_SUB ||
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* neg(p and q and ..) == neg(p) or neg(q) or ..
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen neg(p or q or ..) == neg(p) and neg(q) and .. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if ((args->type == SEARCH_SUB && parent_and) ||
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ((args->type == SEARCH_SUB || args->type == SEARCH_OR) &&
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* p and (q and ..) == p and q and ..
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen p or (q or ..) == p or q or ..
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen if (mail_search_args_simplify_sub(box, args->value.subargs,
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen /* try to merge arguments */
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen merged = mail_search_args_merge_flags(&ctx, args);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen merged = mail_search_args_merge_set(&ctx, args);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenmail_search_args_unnest_inthreads(struct mail_search_args *args,
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen struct mail_search_arg *arg, *thread_arg, *or_arg;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen bool child_inthreads = FALSE, non_inthreads = FALSE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen for (arg = *argp; arg != NULL; arg = arg->next) {
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen /* children converted to SEARCH_INTHREADs */
5214b67a7dabab87da74e04bb8b227f94b95bce4Timo Sirainen if (!parent_inthreads || !child_inthreads || !non_inthreads)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* put all non-INTHREADs under a single INTHREAD */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen thread_arg = p_new(args->pool, struct mail_search_arg, 1);
7920a47321690c932ffd4d286cd16b4048d22d41Timo Sirainen /* not an INTHREAD or a SUB/OR with only INTHREADs */
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk /* We want to OR the args */
7920a47321690c932ffd4d286cd16b4048d22d41Timo Sirainen or_arg = p_new(args->pool, struct mail_search_arg, 1);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen or_arg->value.subargs = thread_arg->value.subargs;
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainenvoid mail_search_args_simplify(struct mail_search_args *args)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen removals = mail_search_args_simplify_sub(args->box, args->args, TRUE);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen if (mail_search_args_unnest_inthreads(args, &args->args,
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen /* we may have added some extra SUBs that could be dropped */
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen mail_search_args_simplify_sub(args->box, args->args, TRUE);