/* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "mail-namespace.h"
#include "mail-search.h"
#include "fts-api-private.h"
#include "fts-tokenizer.h"
#include "fts-filter.h"
#include "fts-user.h"
#include "fts-search-args.h"
{
const char *const *strings;
unsigned int i, count;
for (i = 1; i < count; ) {
} else {
i++;
}
}
}
static struct mail_search_arg *
{
const char *const *tokenp;
/* create the OR arg first as the parent */
/* now create all the child args for the OR */
}
return or_arg;
}
static int
struct mail_search_arg *parent_arg,
const struct mail_search_arg *orig_arg,
const char *orig_token, const char *token,
const char **error_r)
{
int ret;
/* first add the word exactly as it without any tokenization */
/* then add it tokenized, but without filtering */
/* add the word filtered */
if (ret > 0) {
} else if (ret < 0) {
return -1;
} else {
/* The filter dropped the token, which means it was
never even indexed. Ignore this word entirely in the
search query. */
return 0;
}
}
return 0;
}
static int
struct mail_search_arg *orig_arg,
const char *orig_token, const char **error_r)
{
int ret;
/* we want all the tokens found from the string to be found, so create
a parent AND and place all the filtered token alternatives under
it */
/* reset tokenizer between search args in case there's any state left
from some previous failure */
(const void *)orig_token,
return -1;
}
while (ret >= 0 &&
return -1;
}
if (ret < 0) {
return -1;
}
/* nothing was actually expanded, remove the empty and_arg */
}
return 0;
}
struct mail_search_arg **argp)
{
/* use only the data-language */
} else {
}
/* OR together all the different expansions for different languages.
it's enough for one of them to match. */
return -1;
}
}
/* we couldn't parse any tokens from the input */
}
return 0;
}
static int
struct mail_search_arg **argp)
{
int ret;
case SEARCH_OR:
case SEARCH_SUB:
case SEARCH_INTHREAD:
return -1;
break;
case SEARCH_HEADER:
case SEARCH_HEADER_ADDRESS:
/* we're testing for the existence of
the header */
break;
}
/* fall through */
case SEARCH_BODY:
case SEARCH_TEXT:
T_BEGIN {
} T_END;
if (ret < 0)
return -1;
break;
default:
break;
}
}
return 0;
}
struct mail_search_args *args)
{
/* don't keep re-expanding every time the search args are used.
this is especially important to avoid an assert-crash in
index_search_result_update_flags(). */
if (args->fts_expanded)
return 0;
/* duplicate the args, so if expansion fails we haven't changed
anything */
return -1;
/* we'll need to re-simplify the args if we changed anything */
/* duplicated args aren't initialized */
return 0;
}