An index or partition can only prune when the column appears bare in the predicate. Wrap it in a function — CAST(ts AS DATE), UPPER(email) — and the planner must evaluate every row. The rows are identical; the plan is not.
SELECT id FROM logins WHERE CAST(ts AS DATE) = DATE '2024-03-05' ORDER BY id;
SELECT id FROM logins WHERE ts >= TIMESTAMP '2024-03-05' AND ts < TIMESTAMP '2024-03-06' ORDER BY id;
Both return the same two logins — but wrapping the column in CAST(ts AS DATE) hides it from the index, so the query scans every row instead of pruning.
Rewrite the predicate so the column stands alone: a half-open timestamp range instead of CAST(ts AS DATE); a stored lowercased column or a functional index instead of UPPER().
order_ts >= DATE '2024-06-15' AND order_ts < DATE '2024-06-16'
Engines with functional/expression indexes can index the wrapped form directly; without one, the bare-column rewrite is the portable fix.