feat: simplify more regex patterns in promql (#6747)

* feat: simplify more regex patterns in promql

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* add sqlness cases

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* update sqlness case

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

---------

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
This commit is contained in:
Ruihang Xia
2025-08-20 11:51:10 -07:00
committed by GitHub
parent 474a689309
commit 7e573e497c
3 changed files with 184 additions and 11 deletions

View File

@@ -1304,20 +1304,48 @@ impl PromPlanner {
MatchOp::NotEqual => col.not_eq(lit),
MatchOp::Re(re) => {
// TODO(ruihang): a more programmatic way to handle this in datafusion
if re.as_str() == ".*" {
// This is a hack to handle `.+` and `.*`, and is not strictly correct
// `.` doesn't match newline (`\n`). Given this is in PromQL context,
// most of the time it's fine.
if re.as_str() == "^(?:.*)$" {
continue;
}
DfExpr::BinaryExpr(BinaryExpr {
left: Box::new(col),
op: Operator::RegexMatch,
right: Box::new(re.as_str().lit()),
})
if re.as_str() == "^(?:.+)$" {
col.not_eq(DfExpr::Literal(
ScalarValue::Utf8(Some(String::new())),
None,
))
} else {
DfExpr::BinaryExpr(BinaryExpr {
left: Box::new(col),
op: Operator::RegexMatch,
right: Box::new(DfExpr::Literal(
ScalarValue::Utf8(Some(re.as_str().to_string())),
None,
)),
})
}
}
MatchOp::NotRe(re) => {
if re.as_str() == "^(?:.*)$" {
DfExpr::Literal(ScalarValue::Boolean(Some(false)), None)
} else if re.as_str() == "^(?:.+)$" {
col.eq(DfExpr::Literal(
ScalarValue::Utf8(Some(String::new())),
None,
))
} else {
DfExpr::BinaryExpr(BinaryExpr {
left: Box::new(col),
op: Operator::RegexNotMatch,
right: Box::new(DfExpr::Literal(
ScalarValue::Utf8(Some(re.as_str().to_string())),
None,
)),
})
}
}
MatchOp::NotRe(re) => DfExpr::BinaryExpr(BinaryExpr {
left: Box::new(col),
op: Operator::RegexNotMatch,
right: Box::new(re.as_str().lit()),
}),
};
exprs.push(expr);
}