}
static void
-mail_search_arg_change_uidset(struct mail_search_args *args,
- struct mail_search_arg *arg,
- const ARRAY_TYPE(seq_range) *search_saved_uidset)
+mailbox_seqset_change(struct mail_search_arg *arg, struct mailbox *box)
+{
+ const struct seq_range *seqset;
+ unsigned int count;
+ uint32_t seq1, seq2;
+
+ seqset = array_get(&arg->value.seqset, &count);
+ if (count > 0 && seqset[count-1].seq2 == (uint32_t)-1) {
+ /* n:* -> n:maxseq. */
+ mailbox_get_seq_range(box, 1, (uint32_t)-1,
+ &seq1, &seq2);
+ if (seq2 == 0) {
+ /* no mails in mailbox - nothing can match */
+ array_clear(&arg->value.seqset);
+ } else if (seqset[count-1].seq1 == (uint32_t)-1) {
+ /* "*" alone needs a bit special handling
+ NOTE: This could be e.g. 5,* so use
+ seqset[last] */
+ seq_range_array_remove(&arg->value.seqset, (uint32_t)-1);
+ seq_range_array_add(&arg->value.seqset, seq2);
+ } else {
+ seq_range_array_remove_range(&arg->value.seqset,
+ seq2+1, (uint32_t)-1);
+ }
+ }
+}
+
+static void
+mail_search_arg_change_sets(struct mail_search_args *args,
+ struct mail_search_arg *arg,
+ const ARRAY_TYPE(seq_range) *search_saved_uidset)
{
for (; arg != NULL; arg = arg->next) {
switch (arg->type) {
+ case SEARCH_SEQSET:
+ mailbox_seqset_change(arg, args->box);
+ break;
case SEARCH_UIDSET:
T_BEGIN {
mailbox_uidset_change(arg, args->box,
case SEARCH_INTHREAD:
case SEARCH_SUB:
case SEARCH_OR:
- mail_search_arg_change_uidset(args, arg->value.subargs,
- search_saved_uidset);
+ mail_search_arg_change_sets(args, arg->value.subargs,
+ search_saved_uidset);
break;
default:
break;
}
void mail_search_args_init(struct mail_search_args *args,
- struct mailbox *box, bool change_uidsets,
+ struct mailbox *box, bool change_sets,
const ARRAY_TYPE(seq_range) *search_saved_uidset)
{
i_assert(args->init_refcount <= args->refcount);
}
args->box = box;
- if (change_uidsets) {
- /* Change uidsets before simplifying the args, since it can't
- handle search_saved_uidset. */
- mail_search_arg_change_uidset(args, args->args,
- search_saved_uidset);
+ if (change_sets) {
+ /* Change seqsets/uidsets before simplifying the args, since it
+ can't handle search_saved_uidset. */
+ mail_search_arg_change_sets(args, args->args,
+ search_saved_uidset);
}
if (!args->simplified)
mail_search_args_simplify(args);
typedef void mail_search_foreach_callback_t(struct mail_search_arg *arg,
void *context);
-/* Allocate keywords for search arguments. If change_uidsets is TRUE,
- change uidsets to seqsets. */
+/* Allocate keywords for search arguments. If change_sets is TRUE,
+ change uidsets to seqsets and convert "*" in seqsets to the current highest
+ message sequence. */
void mail_search_args_init(struct mail_search_args *args,
- struct mailbox *box, bool change_uidsets,
+ struct mailbox *box, bool change_sets,
const ARRAY_TYPE(seq_range) *search_saved_uidset)
ATTR_NULL(4);
/* Initialize arg and its children. args is used for getting mailbox and