-
Johnny authored
Add support for CEL exists() comprehension with startsWith, endsWith, and contains predicates to enable powerful tag filtering patterns. Features: - tags.exists(t, t.startsWith("prefix")) - Match tags by prefix - tags.exists(t, t.endsWith("suffix")) - Match tags by suffix - tags.exists(t, t.contains("substring")) - Match tags by substring - Negation: !tags.exists(...) to exclude matching tags - Works with all operators (AND, OR, NOT) and other filters Implementation: - Added ListComprehensionCondition IR type for comprehension expressions - Parser detects exists() macro and extracts predicates - Renderer generates optimized SQL for SQLite, MySQL, PostgreSQL - Proper NULL/empty array handling across all database dialects - Helper functions reduce code duplication Design decisions: - Only exists() supported (all() rejected at parse time with clear error) - Only simple predicates (matches() excluded to avoid regex complexity) - Fail-fast validation with helpful error messages Tests: - Comprehensive test suite covering all predicates and edge cases - Tests for NULL/empty arrays, combined filters, negation - Real-world use case test for Issue #5480 (archive workflow) - All tests pass on SQLite, MySQL, PostgreSQL Closes #5480cbf46a29