Postgres:select 使用列作为正则表达式,当只有一些行是有效的正则表达式时

Postgres: select using column as regex, when only some rows are valid regexes

TLDR

如何使用列值 ('input' ~ t.somecolumn) 执行正则表达式匹配查询,其中只有行的已知子集在该列中具有有效的正则表达式?

完整示例

要检查域是否被阻止,我调用此查询并将有问题的 URL 作为 </code> 参数传递:</p> <pre><code>SELECT 1 FROM blocked_items WHERE type = 'DOMAIN_REGEX' AND ~ value LIMIT 1

问题:在某些数据库实例上 如果具有另一个 type 的行 value 不是有效的正则表达式,则查询失败。在一个数据库上,此查询正确运行,而在另一个实例上,无论输入如何,都会抛出:invalid regular expression: quantifier operand invalid.

示例测试数据:

| type         | value               |
|--------------+---------------------|
| EMAIL        | test+++1@test.com   |
| DOMAIN_REGEX | test\d\.com         |

问题

我知道我的错误的原因是数据库引擎可以选择首先检查第二个条件 ( ~ value) -- 我已经为我的查询检查了 EXPLAIN,确实是这两个数据库实例不同。

有什么办法吗

// 我知道更改架构或使用 LIKE 可能就足够了,但既然我偶然发现了这一点,我很好奇是否有使用像这样的正则表达式的解决方案:)

你是对的,架构不是很好。如果您仍然确实必须保留架构,您可以尝试CASE/WHEN、https://www.postgresqltutorial.com/postgresql-case/

您应该能够使用 case:

强制执行操作顺序
SELECT 1
FROM blocked_items
WHERE (CASE WHEN type <> 'DOMAIN_REGEX' THEN false
            ELSE  ~ value
       END)
LIMIT 1;

一般来说,SQL(和 Postgres)对表达式求值的顺序提供很少的控制。但是,CASE 在许多情况下应该提供这种控制。