Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

Commit

Permalink
Fix query result mismatches versus Prometheus
Browse files Browse the repository at this point in the history
Some queries returned wrong results because of defined SQL query logic
conditions. There was also an error in the empty regex matcher anchoring
logic which caused wrong results to be returned.
  • Loading branch information
antekresic committed Apr 15, 2020
1 parent 27b6b6f commit 7122d16
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 105 deletions.
18 changes: 9 additions & 9 deletions pkg/pgmodel/pgx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ func TestPGXQuerierQuery(t *testing.T) {
FROM _prom_catalog.series s
INNER JOIN _prom_catalog.metric m
ON (m.id = s.metric_id)
WHERE labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value != $2)
WHERE NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value = $2)
GROUP BY m.metric_name`},
sqlArgs: [][]interface{}{{metricNameLabelName, "bar"}},
queryResults: []rowResults{
Expand All @@ -686,7 +686,7 @@ func TestPGXQuerierQuery(t *testing.T) {
FROM _prom_catalog.series s
INNER JOIN _prom_catalog.metric m
ON (m.id = s.metric_id)
WHERE labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value != $2)
WHERE NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value = $2)
GROUP BY m.metric_name`},
sqlArgs: [][]interface{}{{"__name__", "bar"}},
queryResults: []rowResults{
Expand All @@ -707,7 +707,7 @@ func TestPGXQuerierQuery(t *testing.T) {
FROM _prom_catalog.series s
INNER JOIN _prom_catalog.metric m
ON (m.id = s.metric_id)
WHERE labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value != $2)
WHERE NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value = $2)
GROUP BY m.metric_name`,
`SELECT table_name FROM prom.get_metric_table_name_if_exists($1)`},
sqlArgs: [][]interface{}{
Expand All @@ -732,7 +732,7 @@ func TestPGXQuerierQuery(t *testing.T) {
FROM _prom_catalog.series s
INNER JOIN _prom_catalog.metric m
ON (m.id = s.metric_id)
WHERE labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value != $2)
WHERE NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value = $2)
GROUP BY m.metric_name`,
`SELECT table_name FROM prom.get_metric_table_name_if_exists($1)`,
`SELECT (prom.label_array_to_key_value_array(s.labels)).*, array_agg(m.time ORDER BY time), array_agg(m.value ORDER BY time)
Expand Down Expand Up @@ -767,7 +767,7 @@ func TestPGXQuerierQuery(t *testing.T) {
FROM _prom_catalog.series s
INNER JOIN _prom_catalog.metric m
ON (m.id = s.metric_id)
WHERE labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value != $2)
WHERE NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value = $2)
GROUP BY m.metric_name`},
sqlArgs: [][]interface{}{{"__name__", "bar"}},
queryResults: []rowResults{
Expand Down Expand Up @@ -827,7 +827,7 @@ func TestPGXQuerierQuery(t *testing.T) {
FROM _prom_catalog.series s
INNER JOIN _prom_catalog.metric m
ON (m.id = s.metric_id)
WHERE labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value != $2)
WHERE NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value = $2)
GROUP BY m.metric_name`,
`SELECT table_name FROM prom.get_metric_table_name_if_exists($1)`,
`SELECT (prom.label_array_to_key_value_array(s.labels)).*, array_agg(m.time ORDER BY time), array_agg(m.value ORDER BY time)
Expand Down Expand Up @@ -922,7 +922,7 @@ func TestPGXQuerierQuery(t *testing.T) {
AND time <= '1970-01-01T00:00:02Z'
GROUP BY s.id`},
sqlArgs: [][]interface{}{
{"__name__", ""},
{"__name__", "^$"},
{"foo"},
nil,
{"bar"},
Expand Down Expand Up @@ -1062,7 +1062,7 @@ func TestPGXQuerierQuery(t *testing.T) {
FROM _prom_catalog.series s
INNER JOIN _prom_catalog.metric m
ON (m.id = s.metric_id)
WHERE labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value = $2) AND labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $3 and l.value != $4) AND labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $5 and l.value ~ $6) AND labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $7 and l.value !~ $8)
WHERE labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value = $2) AND NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $3 and l.value = $4) AND labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $5 and l.value ~ $6) AND NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $7 and l.value ~ $8)
GROUP BY m.metric_name`,
`SELECT table_name FROM prom.get_metric_table_name_if_exists($1)`,
`SELECT (prom.label_array_to_key_value_array(s.labels)).*, array_agg(m.time ORDER BY time), array_agg(m.value ORDER BY time)
Expand Down Expand Up @@ -1109,7 +1109,7 @@ func TestPGXQuerierQuery(t *testing.T) {
FROM _prom_catalog.series s
INNER JOIN _prom_catalog.metric m
ON (m.id = s.metric_id)
WHERE NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value != $2) AND labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $3 and l.value != $4) AND labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $5 and l.value ~ $6) AND labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $7 and l.value !~ $8)
WHERE NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $1 and l.value != $2) AND NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $3 and l.value = $4) AND labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $5 and l.value ~ $6) AND NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $7 and l.value ~ $8)
GROUP BY m.metric_name`,
`SELECT table_name FROM prom.get_metric_table_name_if_exists($1)`,
`SELECT (prom.label_array_to_key_value_array(s.labels)).*, array_agg(m.time ORDER BY time), array_agg(m.value ORDER BY time)
Expand Down
44 changes: 24 additions & 20 deletions pkg/pgmodel/query_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import (
const (
subQueryEQ = "labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value = $%d)"
subQueryEQMatchEmpty = "NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value != $%d)"
subQueryNEQ = "NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value = $%d) "
subQueryNEQMatchEmpty = "labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value != $%d)"
subQueryRE = "labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value ~ $%d) "
subQueryNEQ = "labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value != $%d)"
subQueryNEQMatchEmpty = "NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value = $%d)"
subQueryRE = "labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value ~ $%d)"
subQueryREMatchEmpty = "NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value !~ $%d)"
subQueryNRE = "NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value ~ $%d)"
subQueryNREMatchEmpty = "labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value !~ $%d)"
subQueryNRE = "labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value !~ $%d)"
subQueryNREMatchEmpty = "NOT labels && (SELECT COALESCE(array_agg(l.id), array[]::int[]) FROM _prom_catalog.label l WHERE l.key = $%d and l.value ~ $%d)"

metricNameSeriesIDSQLFormat = `SELECT m.metric_name, array_agg(s.id)
FROM _prom_catalog.series s
Expand Down Expand Up @@ -70,34 +70,34 @@ func buildSubQueries(query *prompb.Query) (string, []string, []interface{}, erro
matchesEmpty := m.Matches("")

switch m.Type {
case labels.MatchRegexp:
sq := subQueryRE
case labels.MatchEqual:
if m.Name == metricNameLabelName {
metricMatcherCount++
metric = m.Value
}
sq := subQueryEQ
if matchesEmpty {
sq = subQueryREMatchEmpty
sq = subQueryEQMatchEmpty
}
err = cb.addClause(sq, m.Name, anchorValue(m.Value))
err = cb.addClause(sq, m.Name, m.Value)
case labels.MatchNotEqual:
sq := subQueryNEQ
if matchesEmpty {
sq = subQueryNEQMatchEmpty
}
err = cb.addClause(sq, m.Name, m.Value)
case labels.MatchRegexp:
sq := subQueryRE
if matchesEmpty {
sq = subQueryREMatchEmpty
}
err = cb.addClause(sq, m.Name, anchorValue(m.Value))
case labels.MatchNotRegexp:
sq := subQueryNRE
if matchesEmpty {
sq = subQueryNREMatchEmpty
}
err = cb.addClause(sq, m.Name, anchorValue(m.Value))
case labels.MatchEqual:
if m.Name == metricNameLabelName {
metricMatcherCount++
metric = m.Value
}
sq := subQueryEQ
if matchesEmpty {
sq = subQueryEQMatchEmpty
}
err = cb.addClause(sq, m.Name, m.Value)
}

if err != nil {
Expand Down Expand Up @@ -295,7 +295,11 @@ func getSeriesPerMetric(rows pgx.Rows) ([]string, [][]SeriesID, error) {
func anchorValue(str string) string {
l := len(str)

if l == 0 || (str[0] == '^' && str[l-1] == '$') {
if l == 0 {
return "^$"
}

if str[0] == '^' && str[l-1] == '$' {
return str
}

Expand Down

0 comments on commit 7122d16

Please sign in to comment.