cloudflare/pint
Publicmirrored from https://github.com/cloudflare/pintAvailable
internal/parser/utils/source_test.go
3859lines · modecode
| 1 | package utils_test |
| 2 | |
| 3 | import ( |
| 4 | "strings" |
| 5 | "testing" |
| 6 | |
| 7 | "github.com/google/go-cmp/cmp" |
| 8 | "github.com/google/go-cmp/cmp/cmpopts" |
| 9 | "github.com/stretchr/testify/require" |
| 10 | |
| 11 | "github.com/cloudflare/pint/internal/parser" |
| 12 | "github.com/cloudflare/pint/internal/parser/utils" |
| 13 | |
| 14 | "github.com/prometheus/prometheus/model/labels" |
| 15 | promParser "github.com/prometheus/prometheus/promql/parser" |
| 16 | "github.com/prometheus/prometheus/promql/parser/posrange" |
| 17 | ) |
| 18 | |
| 19 | func mustParse[T any](t *testing.T, s string, offset int) T { |
| 20 | m, err := promParser.ParseExpr(strings.Repeat(" ", offset) + s) |
| 21 | require.NoErrorf(t, err, "failed to parse vector selector: %s", s) |
| 22 | n, ok := m.(T) |
| 23 | require.True(t, ok, "failed to convert %q to %t\n", s, n) |
| 24 | return n |
| 25 | } |
| 26 | |
| 27 | func TestLabelsSource(t *testing.T) { |
| 28 | type testCaseT struct { |
| 29 | expr string |
| 30 | output []utils.Source |
| 31 | } |
| 32 | |
| 33 | testCases := []testCaseT{ |
| 34 | { |
| 35 | expr: "1", |
| 36 | output: []utils.Source{ |
| 37 | { |
| 38 | Type: utils.NumberSource, |
| 39 | Returns: promParser.ValueTypeScalar, |
| 40 | FixedLabels: true, |
| 41 | AlwaysReturns: true, |
| 42 | KnownReturn: true, |
| 43 | ReturnedNumber: 1, |
| 44 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 45 | "": { |
| 46 | Reason: "This query returns a number value with no labels.", |
| 47 | }, |
| 48 | }, |
| 49 | }, |
| 50 | }, |
| 51 | }, |
| 52 | { |
| 53 | expr: "1 / 5", |
| 54 | output: []utils.Source{ |
| 55 | { |
| 56 | Type: utils.NumberSource, |
| 57 | Returns: promParser.ValueTypeScalar, |
| 58 | FixedLabels: true, |
| 59 | AlwaysReturns: true, |
| 60 | KnownReturn: true, |
| 61 | ReturnedNumber: 0.2, |
| 62 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 63 | "": { |
| 64 | Reason: "This query returns a number value with no labels.", |
| 65 | }, |
| 66 | }, |
| 67 | }, |
| 68 | }, |
| 69 | }, |
| 70 | { |
| 71 | expr: "(2 ^ 5) == bool 5", |
| 72 | output: []utils.Source{ |
| 73 | { |
| 74 | Type: utils.NumberSource, |
| 75 | Returns: promParser.ValueTypeScalar, |
| 76 | FixedLabels: true, |
| 77 | AlwaysReturns: true, |
| 78 | KnownReturn: true, |
| 79 | IsDead: true, |
| 80 | IsDeadReason: "this query always evaluates to `32 == 5` which is not possible, so it will never return anything", |
| 81 | ReturnedNumber: 32, |
| 82 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 83 | "": { |
| 84 | Reason: "This query returns a number value with no labels.", |
| 85 | }, |
| 86 | }, |
| 87 | IsConditional: true, |
| 88 | }, |
| 89 | }, |
| 90 | }, |
| 91 | { |
| 92 | expr: "(2 ^ 5 + 11) % 5 <= bool 2", |
| 93 | output: []utils.Source{ |
| 94 | { |
| 95 | Type: utils.NumberSource, |
| 96 | Returns: promParser.ValueTypeScalar, |
| 97 | FixedLabels: true, |
| 98 | AlwaysReturns: true, |
| 99 | KnownReturn: true, |
| 100 | IsDead: true, |
| 101 | IsDeadReason: "this query always evaluates to `3 <= 2` which is not possible, so it will never return anything", |
| 102 | ReturnedNumber: 3, |
| 103 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 104 | "": { |
| 105 | Reason: "This query returns a number value with no labels.", |
| 106 | }, |
| 107 | }, |
| 108 | IsConditional: true, |
| 109 | }, |
| 110 | }, |
| 111 | }, |
| 112 | { |
| 113 | expr: "(2 ^ 5 + 11) % 5 >= bool 20", |
| 114 | output: []utils.Source{ |
| 115 | { |
| 116 | Type: utils.NumberSource, |
| 117 | Returns: promParser.ValueTypeScalar, |
| 118 | FixedLabels: true, |
| 119 | AlwaysReturns: true, |
| 120 | KnownReturn: true, |
| 121 | IsDead: true, |
| 122 | IsDeadReason: "this query always evaluates to `3 >= 20` which is not possible, so it will never return anything", |
| 123 | ReturnedNumber: 3, |
| 124 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 125 | "": { |
| 126 | Reason: "This query returns a number value with no labels.", |
| 127 | }, |
| 128 | }, |
| 129 | IsConditional: true, |
| 130 | }, |
| 131 | }, |
| 132 | }, |
| 133 | { |
| 134 | expr: "(2 ^ 5 + 11) % 5 <= bool 3", |
| 135 | output: []utils.Source{ |
| 136 | { |
| 137 | Type: utils.NumberSource, |
| 138 | Returns: promParser.ValueTypeScalar, |
| 139 | FixedLabels: true, |
| 140 | AlwaysReturns: true, |
| 141 | KnownReturn: true, |
| 142 | ReturnedNumber: 3, |
| 143 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 144 | "": { |
| 145 | Reason: "This query returns a number value with no labels.", |
| 146 | }, |
| 147 | }, |
| 148 | IsConditional: true, |
| 149 | }, |
| 150 | }, |
| 151 | }, |
| 152 | { |
| 153 | expr: "(2 ^ 5 + 11) % 5 < bool 1", |
| 154 | output: []utils.Source{ |
| 155 | { |
| 156 | Type: utils.NumberSource, |
| 157 | Returns: promParser.ValueTypeScalar, |
| 158 | FixedLabels: true, |
| 159 | AlwaysReturns: true, |
| 160 | KnownReturn: true, |
| 161 | IsDead: true, |
| 162 | IsDeadReason: "this query always evaluates to `3 < 1` which is not possible, so it will never return anything", |
| 163 | ReturnedNumber: 3, |
| 164 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 165 | "": { |
| 166 | Reason: "This query returns a number value with no labels.", |
| 167 | }, |
| 168 | }, |
| 169 | IsConditional: true, |
| 170 | }, |
| 171 | }, |
| 172 | }, |
| 173 | { |
| 174 | expr: "20 - 15 < bool 1", |
| 175 | output: []utils.Source{ |
| 176 | { |
| 177 | Type: utils.NumberSource, |
| 178 | Returns: promParser.ValueTypeScalar, |
| 179 | FixedLabels: true, |
| 180 | AlwaysReturns: true, |
| 181 | KnownReturn: true, |
| 182 | IsDead: true, |
| 183 | IsDeadReason: "this query always evaluates to `5 < 1` which is not possible, so it will never return anything", |
| 184 | ReturnedNumber: 5, |
| 185 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 186 | "": { |
| 187 | Reason: "This query returns a number value with no labels.", |
| 188 | }, |
| 189 | }, |
| 190 | IsConditional: true, |
| 191 | }, |
| 192 | }, |
| 193 | }, |
| 194 | { |
| 195 | expr: "2 * 5", |
| 196 | output: []utils.Source{ |
| 197 | { |
| 198 | Type: utils.NumberSource, |
| 199 | Returns: promParser.ValueTypeScalar, |
| 200 | FixedLabels: true, |
| 201 | AlwaysReturns: true, |
| 202 | KnownReturn: true, |
| 203 | ReturnedNumber: 10, |
| 204 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 205 | "": { |
| 206 | Reason: "This query returns a number value with no labels.", |
| 207 | }, |
| 208 | }, |
| 209 | }, |
| 210 | }, |
| 211 | }, |
| 212 | { |
| 213 | expr: "(foo or bar) * 5", |
| 214 | output: []utils.Source{ |
| 215 | { |
| 216 | Type: utils.SelectorSource, |
| 217 | Returns: promParser.ValueTypeVector, |
| 218 | Operation: promParser.CardManyToMany.String(), |
| 219 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 1), |
| 220 | }, |
| 221 | { |
| 222 | Type: utils.SelectorSource, |
| 223 | Returns: promParser.ValueTypeVector, |
| 224 | Operation: promParser.CardManyToMany.String(), |
| 225 | Selector: mustParse[*promParser.VectorSelector](t, "bar", 8), |
| 226 | }, |
| 227 | }, |
| 228 | }, |
| 229 | { |
| 230 | expr: "(foo or vector(2)) * 5", |
| 231 | output: []utils.Source{ |
| 232 | { |
| 233 | Type: utils.SelectorSource, |
| 234 | Returns: promParser.ValueTypeVector, |
| 235 | Operation: promParser.CardManyToMany.String(), |
| 236 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 1), |
| 237 | }, |
| 238 | { |
| 239 | Type: utils.FuncSource, |
| 240 | Returns: promParser.ValueTypeVector, |
| 241 | Operation: "vector", |
| 242 | FixedLabels: true, |
| 243 | AlwaysReturns: true, |
| 244 | KnownReturn: true, |
| 245 | ReturnedNumber: 10, |
| 246 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 247 | "": { |
| 248 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 249 | }, |
| 250 | }, |
| 251 | Call: mustParse[*promParser.Call](t, "vector(2)", 8), |
| 252 | }, |
| 253 | }, |
| 254 | }, |
| 255 | { |
| 256 | expr: "(foo or vector(5)) * (vector(2) or bar)", |
| 257 | output: []utils.Source{ |
| 258 | { |
| 259 | Type: utils.SelectorSource, |
| 260 | Returns: promParser.ValueTypeVector, |
| 261 | Operation: promParser.CardManyToMany.String(), |
| 262 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 1), |
| 263 | Joins: []utils.Join{ |
| 264 | { |
| 265 | Src: utils.Source{ |
| 266 | Type: utils.FuncSource, |
| 267 | Returns: promParser.ValueTypeVector, |
| 268 | Operation: "vector", |
| 269 | FixedLabels: true, |
| 270 | AlwaysReturns: true, |
| 271 | KnownReturn: true, |
| 272 | ReturnedNumber: 2, |
| 273 | Call: mustParse[*promParser.Call](t, "vector(2)", 22), |
| 274 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 275 | "": { |
| 276 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 277 | }, |
| 278 | }, |
| 279 | }, |
| 280 | }, |
| 281 | { |
| 282 | Src: utils.Source{ |
| 283 | Type: utils.SelectorSource, |
| 284 | Returns: promParser.ValueTypeVector, |
| 285 | Operation: promParser.CardManyToMany.String(), |
| 286 | Selector: mustParse[*promParser.VectorSelector](t, "bar", 35), |
| 287 | IsDead: true, |
| 288 | IsDeadReason: "the left hand side always returs something and so the right hand side is never used", |
| 289 | }, |
| 290 | }, |
| 291 | }, |
| 292 | }, |
| 293 | { |
| 294 | Type: utils.FuncSource, |
| 295 | Returns: promParser.ValueTypeVector, |
| 296 | Operation: "vector", |
| 297 | FixedLabels: true, |
| 298 | AlwaysReturns: true, |
| 299 | KnownReturn: true, |
| 300 | ReturnedNumber: 10, |
| 301 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 302 | "": { |
| 303 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 304 | }, |
| 305 | }, |
| 306 | Call: mustParse[*promParser.Call](t, "vector(5)", 8), |
| 307 | Joins: []utils.Join{ |
| 308 | { |
| 309 | Src: utils.Source{ |
| 310 | Type: utils.FuncSource, |
| 311 | Returns: promParser.ValueTypeVector, |
| 312 | Operation: "vector", |
| 313 | FixedLabels: true, |
| 314 | AlwaysReturns: true, |
| 315 | KnownReturn: true, |
| 316 | ReturnedNumber: 2, |
| 317 | Call: mustParse[*promParser.Call](t, "vector(2)", 22), |
| 318 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 319 | "": { |
| 320 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 321 | }, |
| 322 | }, |
| 323 | }, |
| 324 | }, |
| 325 | { |
| 326 | Src: utils.Source{ |
| 327 | Type: utils.SelectorSource, |
| 328 | Returns: promParser.ValueTypeVector, |
| 329 | Operation: promParser.CardManyToMany.String(), |
| 330 | Selector: mustParse[*promParser.VectorSelector](t, "bar", 35), |
| 331 | IsDead: true, |
| 332 | IsDeadReason: "the left hand side always returs something and so the right hand side is never used", |
| 333 | }, |
| 334 | }, |
| 335 | }, |
| 336 | }, |
| 337 | }, |
| 338 | }, |
| 339 | { |
| 340 | expr: `1 > bool 0`, |
| 341 | output: []utils.Source{ |
| 342 | { |
| 343 | Type: utils.NumberSource, |
| 344 | Returns: promParser.ValueTypeScalar, |
| 345 | FixedLabels: true, |
| 346 | AlwaysReturns: true, |
| 347 | KnownReturn: true, |
| 348 | ReturnedNumber: 1, |
| 349 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 350 | "": { |
| 351 | Reason: "This query returns a number value with no labels.", |
| 352 | }, |
| 353 | }, |
| 354 | IsConditional: true, |
| 355 | }, |
| 356 | }, |
| 357 | }, |
| 358 | { |
| 359 | expr: `20 > bool 10`, |
| 360 | output: []utils.Source{ |
| 361 | { |
| 362 | Type: utils.NumberSource, |
| 363 | Returns: promParser.ValueTypeScalar, |
| 364 | FixedLabels: true, |
| 365 | AlwaysReturns: true, |
| 366 | KnownReturn: true, |
| 367 | ReturnedNumber: 20, |
| 368 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 369 | "": { |
| 370 | Reason: "This query returns a number value with no labels.", |
| 371 | }, |
| 372 | }, |
| 373 | IsConditional: true, |
| 374 | }, |
| 375 | }, |
| 376 | }, |
| 377 | { |
| 378 | expr: `"test"`, |
| 379 | output: []utils.Source{ |
| 380 | { |
| 381 | Type: utils.StringSource, |
| 382 | Returns: promParser.ValueTypeString, |
| 383 | FixedLabels: true, |
| 384 | AlwaysReturns: true, |
| 385 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 386 | "": { |
| 387 | Reason: "This query returns a string value with no labels.", |
| 388 | }, |
| 389 | }, |
| 390 | }, |
| 391 | }, |
| 392 | }, |
| 393 | { |
| 394 | expr: "foo", |
| 395 | output: []utils.Source{ |
| 396 | { |
| 397 | Type: utils.SelectorSource, |
| 398 | Returns: promParser.ValueTypeVector, |
| 399 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 0), |
| 400 | }, |
| 401 | }, |
| 402 | }, |
| 403 | { |
| 404 | expr: "foo offset 5m", |
| 405 | output: []utils.Source{ |
| 406 | { |
| 407 | Type: utils.SelectorSource, |
| 408 | Returns: promParser.ValueTypeVector, |
| 409 | Selector: mustParse[*promParser.VectorSelector](t, "foo offset 5m", 0), |
| 410 | }, |
| 411 | }, |
| 412 | }, |
| 413 | { |
| 414 | expr: `foo{job="bar"}`, |
| 415 | output: []utils.Source{ |
| 416 | { |
| 417 | Type: utils.SelectorSource, |
| 418 | Returns: promParser.ValueTypeVector, |
| 419 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 0), |
| 420 | GuaranteedLabels: []string{"job"}, |
| 421 | }, |
| 422 | }, |
| 423 | }, |
| 424 | { |
| 425 | expr: `foo{job=""}`, |
| 426 | output: []utils.Source{ |
| 427 | { |
| 428 | Type: utils.SelectorSource, |
| 429 | Returns: promParser.ValueTypeVector, |
| 430 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job=""}`, 0), |
| 431 | ExcludedLabels: []string{"job"}, |
| 432 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 433 | "job": { |
| 434 | Reason: "Query uses `{job=\"\"}` selector which will filter out any time series with the `job` label set.", |
| 435 | }, |
| 436 | }, |
| 437 | }, |
| 438 | }, |
| 439 | }, |
| 440 | { |
| 441 | expr: `foo{job="bar"} or bar{job="foo"}`, |
| 442 | output: []utils.Source{ |
| 443 | { |
| 444 | Type: utils.SelectorSource, |
| 445 | Returns: promParser.ValueTypeVector, |
| 446 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 0), |
| 447 | Operation: promParser.CardManyToMany.String(), |
| 448 | GuaranteedLabels: []string{"job"}, |
| 449 | }, |
| 450 | { |
| 451 | Type: utils.SelectorSource, |
| 452 | Returns: promParser.ValueTypeVector, |
| 453 | Selector: mustParse[*promParser.VectorSelector](t, `bar{job="foo"}`, 18), |
| 454 | Operation: promParser.CardManyToMany.String(), |
| 455 | GuaranteedLabels: []string{"job"}, |
| 456 | }, |
| 457 | }, |
| 458 | }, |
| 459 | { |
| 460 | expr: `foo{a="bar"} or bar{b="foo"}`, |
| 461 | output: []utils.Source{ |
| 462 | { |
| 463 | Type: utils.SelectorSource, |
| 464 | Returns: promParser.ValueTypeVector, |
| 465 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="bar"}`, 0), |
| 466 | Operation: promParser.CardManyToMany.String(), |
| 467 | GuaranteedLabels: []string{"a"}, |
| 468 | }, |
| 469 | { |
| 470 | Type: utils.SelectorSource, |
| 471 | Returns: promParser.ValueTypeVector, |
| 472 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="foo"}`, 16), |
| 473 | Operation: promParser.CardManyToMany.String(), |
| 474 | GuaranteedLabels: []string{"b"}, |
| 475 | }, |
| 476 | }, |
| 477 | }, |
| 478 | { |
| 479 | expr: "foo[5m]", |
| 480 | output: []utils.Source{ |
| 481 | { |
| 482 | Type: utils.SelectorSource, |
| 483 | Returns: promParser.ValueTypeVector, // FIXME Matrix ?? |
| 484 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 0), |
| 485 | }, |
| 486 | }, |
| 487 | }, |
| 488 | { |
| 489 | expr: "prometheus_build_info[2m:1m]", |
| 490 | output: []utils.Source{ |
| 491 | { |
| 492 | Type: utils.SelectorSource, |
| 493 | Returns: promParser.ValueTypeVector, |
| 494 | Selector: mustParse[*promParser.VectorSelector](t, "prometheus_build_info", 0), |
| 495 | }, |
| 496 | }, |
| 497 | }, |
| 498 | { |
| 499 | expr: "deriv(rate(distance_covered_meters_total[1m])[5m:1m])", |
| 500 | output: []utils.Source{ |
| 501 | { |
| 502 | Type: utils.FuncSource, |
| 503 | Returns: promParser.ValueTypeVector, |
| 504 | Operation: "deriv", |
| 505 | Selector: mustParse[*promParser.VectorSelector](t, "distance_covered_meters_total", 11), |
| 506 | Call: mustParse[*promParser.Call](t, "deriv(rate(distance_covered_meters_total[1m])[5m:1m])", 0), |
| 507 | }, |
| 508 | }, |
| 509 | }, |
| 510 | { |
| 511 | expr: "foo - 1", |
| 512 | output: []utils.Source{ |
| 513 | { |
| 514 | Type: utils.SelectorSource, |
| 515 | Returns: promParser.ValueTypeVector, |
| 516 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 0), |
| 517 | }, |
| 518 | }, |
| 519 | }, |
| 520 | { |
| 521 | expr: "foo / 5", |
| 522 | output: []utils.Source{ |
| 523 | { |
| 524 | Type: utils.SelectorSource, |
| 525 | Returns: promParser.ValueTypeVector, |
| 526 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 0), |
| 527 | }, |
| 528 | }, |
| 529 | }, |
| 530 | { |
| 531 | expr: "-foo", |
| 532 | output: []utils.Source{ |
| 533 | { |
| 534 | Type: utils.SelectorSource, |
| 535 | Returns: promParser.ValueTypeVector, |
| 536 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 1), |
| 537 | }, |
| 538 | }, |
| 539 | }, |
| 540 | { |
| 541 | expr: `sum(foo{job="myjob"})`, |
| 542 | output: []utils.Source{ |
| 543 | { |
| 544 | Type: utils.AggregateSource, |
| 545 | Returns: promParser.ValueTypeVector, |
| 546 | Operation: "sum", |
| 547 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 548 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{job="myjob"})`, 0), |
| 549 | FixedLabels: true, |
| 550 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 551 | "": { |
| 552 | Reason: "Query is using aggregation that removes all labels.", |
| 553 | }, |
| 554 | }, |
| 555 | }, |
| 556 | }, |
| 557 | }, |
| 558 | { |
| 559 | expr: `sum(count(foo{job="myjob"}) by(instance))`, |
| 560 | output: []utils.Source{ |
| 561 | { |
| 562 | Type: utils.AggregateSource, |
| 563 | Returns: promParser.ValueTypeVector, |
| 564 | Operation: "sum", |
| 565 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 10), |
| 566 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(count(foo{job="myjob"}) by(instance))`, 0), |
| 567 | FixedLabels: true, |
| 568 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 569 | "": { |
| 570 | Reason: "Query is using aggregation that removes all labels.", |
| 571 | }, |
| 572 | }, |
| 573 | }, |
| 574 | }, |
| 575 | }, |
| 576 | { |
| 577 | expr: `sum(foo{job="myjob"}) > 20`, |
| 578 | output: []utils.Source{ |
| 579 | { |
| 580 | Type: utils.AggregateSource, |
| 581 | Returns: promParser.ValueTypeVector, |
| 582 | Operation: "sum", |
| 583 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 584 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{job="myjob"})`, 0), |
| 585 | FixedLabels: true, |
| 586 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 587 | "": { |
| 588 | Reason: "Query is using aggregation that removes all labels.", |
| 589 | }, |
| 590 | }, |
| 591 | IsConditional: true, |
| 592 | }, |
| 593 | }, |
| 594 | }, |
| 595 | { |
| 596 | expr: `sum(foo{job="myjob"}) without(job)`, |
| 597 | output: []utils.Source{ |
| 598 | { |
| 599 | Type: utils.AggregateSource, |
| 600 | Returns: promParser.ValueTypeVector, |
| 601 | Operation: "sum", |
| 602 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 603 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{job="myjob"}) without(job)`, 0), |
| 604 | ExcludedLabels: []string{"job"}, |
| 605 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 606 | "job": { |
| 607 | Reason: "Query is using aggregation with `without(job)`, all labels included inside `without(...)` will be removed from the results.", |
| 608 | }, |
| 609 | }, |
| 610 | }, |
| 611 | }, |
| 612 | }, |
| 613 | { |
| 614 | expr: `sum(foo) by(job)`, |
| 615 | output: []utils.Source{ |
| 616 | { |
| 617 | Type: utils.AggregateSource, |
| 618 | Returns: promParser.ValueTypeVector, |
| 619 | Operation: "sum", |
| 620 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 4), |
| 621 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo) by(job)`, 0), |
| 622 | IncludedLabels: []string{"job"}, |
| 623 | FixedLabels: true, |
| 624 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 625 | "": { |
| 626 | Reason: "Query is using aggregation with `by(job)`, only labels included inside `by(...)` will be present on the results.", |
| 627 | }, |
| 628 | }, |
| 629 | }, |
| 630 | }, |
| 631 | }, |
| 632 | { |
| 633 | expr: `sum(foo{job="myjob"}) by(job)`, |
| 634 | output: []utils.Source{ |
| 635 | { |
| 636 | Type: utils.AggregateSource, |
| 637 | Returns: promParser.ValueTypeVector, |
| 638 | Operation: "sum", |
| 639 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 640 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{job="myjob"}) by(job)`, 0), |
| 641 | IncludedLabels: []string{"job"}, |
| 642 | GuaranteedLabels: []string{"job"}, |
| 643 | FixedLabels: true, |
| 644 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 645 | "": { |
| 646 | Reason: "Query is using aggregation with `by(job)`, only labels included inside `by(...)` will be present on the results.", |
| 647 | }, |
| 648 | }, |
| 649 | }, |
| 650 | }, |
| 651 | }, |
| 652 | { |
| 653 | expr: `abs(foo{job="myjob"} offset 5m)`, |
| 654 | output: []utils.Source{ |
| 655 | { |
| 656 | Type: utils.FuncSource, |
| 657 | Returns: promParser.ValueTypeVector, |
| 658 | Operation: "abs", |
| 659 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"} offset 5m`, 4), |
| 660 | Call: mustParse[*promParser.Call](t, `abs(foo{job="myjob"} offset 5m)`, 0), |
| 661 | GuaranteedLabels: []string{"job"}, |
| 662 | }, |
| 663 | }, |
| 664 | }, |
| 665 | { |
| 666 | expr: `abs(foo{job="myjob"} or bar{cluster="dev"})`, |
| 667 | output: []utils.Source{ |
| 668 | { |
| 669 | Type: utils.FuncSource, |
| 670 | Returns: promParser.ValueTypeVector, |
| 671 | Operation: "abs", |
| 672 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 673 | GuaranteedLabels: []string{"job"}, |
| 674 | Call: mustParse[*promParser.Call](t, `abs(foo{job="myjob"} or bar{cluster="dev"})`, 0), |
| 675 | }, |
| 676 | { |
| 677 | Type: utils.FuncSource, |
| 678 | Returns: promParser.ValueTypeVector, |
| 679 | Operation: "abs", |
| 680 | Selector: mustParse[*promParser.VectorSelector](t, `bar{cluster="dev"}`, 24), |
| 681 | Call: mustParse[*promParser.Call](t, `abs(foo{job="myjob"} or bar{cluster="dev"})`, 0), |
| 682 | GuaranteedLabels: []string{"cluster"}, |
| 683 | }, |
| 684 | }, |
| 685 | }, |
| 686 | { |
| 687 | expr: `sum(foo{job="myjob"} or bar{cluster="dev"}) without(instance)`, |
| 688 | output: []utils.Source{ |
| 689 | { |
| 690 | Type: utils.AggregateSource, |
| 691 | Returns: promParser.ValueTypeVector, |
| 692 | Operation: "sum", |
| 693 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 694 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{job="myjob"} or bar{cluster="dev"}) without(instance)`, 0), |
| 695 | GuaranteedLabels: []string{"job"}, |
| 696 | ExcludedLabels: []string{"instance"}, |
| 697 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 698 | "instance": { |
| 699 | Reason: "Query is using aggregation with `without(instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 700 | }, |
| 701 | }, |
| 702 | }, |
| 703 | { |
| 704 | Type: utils.AggregateSource, |
| 705 | Returns: promParser.ValueTypeVector, |
| 706 | Operation: "sum", |
| 707 | Selector: mustParse[*promParser.VectorSelector](t, `bar{cluster="dev"}`, 24), |
| 708 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{job="myjob"} or bar{cluster="dev"}) without(instance)`, 0), |
| 709 | GuaranteedLabels: []string{"cluster"}, |
| 710 | ExcludedLabels: []string{"instance"}, |
| 711 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 712 | "instance": { |
| 713 | Reason: "Query is using aggregation with `without(instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 714 | }, |
| 715 | }, |
| 716 | }, |
| 717 | }, |
| 718 | }, |
| 719 | { |
| 720 | expr: `sum(foo{job="myjob"}) without(instance)`, |
| 721 | output: []utils.Source{ |
| 722 | { |
| 723 | Type: utils.AggregateSource, |
| 724 | Returns: promParser.ValueTypeVector, |
| 725 | Operation: "sum", |
| 726 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 727 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{job="myjob"}) without(instance)`, 0), |
| 728 | GuaranteedLabels: []string{"job"}, |
| 729 | ExcludedLabels: []string{"instance"}, |
| 730 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 731 | "instance": { |
| 732 | Reason: "Query is using aggregation with `without(instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 733 | }, |
| 734 | }, |
| 735 | }, |
| 736 | }, |
| 737 | }, |
| 738 | { |
| 739 | expr: `min(foo{job="myjob"}) / max(foo{job="myjob"})`, |
| 740 | output: []utils.Source{ |
| 741 | { |
| 742 | Type: utils.AggregateSource, |
| 743 | Returns: promParser.ValueTypeVector, |
| 744 | Operation: "min", |
| 745 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 746 | Aggregation: mustParse[*promParser.AggregateExpr](t, `min(foo{job="myjob"})`, 0), |
| 747 | FixedLabels: true, |
| 748 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 749 | "": { |
| 750 | Reason: "Query is using aggregation that removes all labels.", |
| 751 | }, |
| 752 | }, |
| 753 | Joins: []utils.Join{ |
| 754 | { |
| 755 | Src: utils.Source{ |
| 756 | Type: utils.AggregateSource, |
| 757 | Operation: "max", |
| 758 | Returns: promParser.ValueTypeVector, |
| 759 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 28), |
| 760 | Aggregation: mustParse[*promParser.AggregateExpr](t, `max(foo{job="myjob"})`, 24), |
| 761 | FixedLabels: true, |
| 762 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 763 | "": { |
| 764 | Reason: "Query is using aggregation that removes all labels.", |
| 765 | }, |
| 766 | }, |
| 767 | }, |
| 768 | }, |
| 769 | }, |
| 770 | }, |
| 771 | }, |
| 772 | }, |
| 773 | { |
| 774 | expr: `max(foo{job="myjob"}) / min(foo{job="myjob"})`, |
| 775 | output: []utils.Source{ |
| 776 | { |
| 777 | Type: utils.AggregateSource, |
| 778 | Returns: promParser.ValueTypeVector, |
| 779 | Operation: "max", |
| 780 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 781 | Aggregation: mustParse[*promParser.AggregateExpr](t, `max(foo{job="myjob"})`, 0), |
| 782 | FixedLabels: true, |
| 783 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 784 | "": { |
| 785 | Reason: "Query is using aggregation that removes all labels.", |
| 786 | }, |
| 787 | }, |
| 788 | Joins: []utils.Join{ |
| 789 | { |
| 790 | Src: utils.Source{ |
| 791 | Type: utils.AggregateSource, |
| 792 | Operation: "min", |
| 793 | Returns: promParser.ValueTypeVector, |
| 794 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 28), |
| 795 | Aggregation: mustParse[*promParser.AggregateExpr](t, `min(foo{job="myjob"})`, 24), |
| 796 | FixedLabels: true, |
| 797 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 798 | "": { |
| 799 | Reason: "Query is using aggregation that removes all labels.", |
| 800 | }, |
| 801 | }, |
| 802 | }, |
| 803 | }, |
| 804 | }, |
| 805 | }, |
| 806 | }, |
| 807 | }, |
| 808 | { |
| 809 | expr: `avg(foo{job="myjob"}) by(job)`, |
| 810 | output: []utils.Source{ |
| 811 | { |
| 812 | Type: utils.AggregateSource, |
| 813 | Returns: promParser.ValueTypeVector, |
| 814 | Operation: "avg", |
| 815 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), |
| 816 | Aggregation: mustParse[*promParser.AggregateExpr](t, `avg(foo{job="myjob"}) by(job)`, 0), |
| 817 | GuaranteedLabels: []string{"job"}, |
| 818 | IncludedLabels: []string{"job"}, |
| 819 | FixedLabels: true, |
| 820 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 821 | "": { |
| 822 | Reason: "Query is using aggregation with `by(job)`, only labels included inside `by(...)` will be present on the results.", |
| 823 | }, |
| 824 | }, |
| 825 | }, |
| 826 | }, |
| 827 | }, |
| 828 | { |
| 829 | expr: `group(foo) by(job)`, |
| 830 | output: []utils.Source{ |
| 831 | { |
| 832 | Type: utils.AggregateSource, |
| 833 | Returns: promParser.ValueTypeVector, |
| 834 | Operation: "group", |
| 835 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 6), |
| 836 | Aggregation: mustParse[*promParser.AggregateExpr](t, `group(foo) by(job)`, 0), |
| 837 | IncludedLabels: []string{"job"}, |
| 838 | FixedLabels: true, |
| 839 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 840 | "": { |
| 841 | Reason: "Query is using aggregation with `by(job)`, only labels included inside `by(...)` will be present on the results.", |
| 842 | }, |
| 843 | }, |
| 844 | }, |
| 845 | }, |
| 846 | }, |
| 847 | { |
| 848 | expr: `stddev(rate(foo[5m]))`, |
| 849 | output: []utils.Source{ |
| 850 | { |
| 851 | Type: utils.AggregateSource, |
| 852 | Returns: promParser.ValueTypeVector, |
| 853 | Operation: "stddev", |
| 854 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 12), |
| 855 | Call: mustParse[*promParser.Call](t, "rate(foo[5m])", 7), |
| 856 | Aggregation: mustParse[*promParser.AggregateExpr](t, `stddev(rate(foo[5m]))`, 0), |
| 857 | FixedLabels: true, |
| 858 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 859 | "": { |
| 860 | Reason: "Query is using aggregation that removes all labels.", |
| 861 | }, |
| 862 | }, |
| 863 | }, |
| 864 | }, |
| 865 | }, |
| 866 | { |
| 867 | expr: `stdvar(rate(foo[5m]))`, |
| 868 | output: []utils.Source{ |
| 869 | { |
| 870 | Type: utils.AggregateSource, |
| 871 | Returns: promParser.ValueTypeVector, |
| 872 | Operation: "stdvar", |
| 873 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 12), |
| 874 | Call: mustParse[*promParser.Call](t, "rate(foo[5m])", 7), |
| 875 | Aggregation: mustParse[*promParser.AggregateExpr](t, `stdvar(rate(foo[5m]))`, 0), |
| 876 | FixedLabels: true, |
| 877 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 878 | "": { |
| 879 | Reason: "Query is using aggregation that removes all labels.", |
| 880 | }, |
| 881 | }, |
| 882 | }, |
| 883 | }, |
| 884 | }, |
| 885 | { |
| 886 | expr: `stddev_over_time(foo[5m])`, |
| 887 | output: []utils.Source{ |
| 888 | { |
| 889 | Type: utils.FuncSource, |
| 890 | Returns: promParser.ValueTypeVector, |
| 891 | Operation: "stddev_over_time", |
| 892 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 17), |
| 893 | Call: mustParse[*promParser.Call](t, `stddev_over_time(foo[5m])`, 0), |
| 894 | }, |
| 895 | }, |
| 896 | }, |
| 897 | { |
| 898 | expr: `stdvar_over_time(foo[5m])`, |
| 899 | output: []utils.Source{ |
| 900 | { |
| 901 | Type: utils.FuncSource, |
| 902 | Returns: promParser.ValueTypeVector, |
| 903 | Operation: "stdvar_over_time", |
| 904 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 17), |
| 905 | Call: mustParse[*promParser.Call](t, `stdvar_over_time(foo[5m])`, 0), |
| 906 | }, |
| 907 | }, |
| 908 | }, |
| 909 | { |
| 910 | expr: `quantile(0.9, rate(foo[5m]))`, |
| 911 | output: []utils.Source{ |
| 912 | { |
| 913 | Type: utils.AggregateSource, |
| 914 | Returns: promParser.ValueTypeVector, |
| 915 | Operation: "quantile", |
| 916 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 19), |
| 917 | Call: mustParse[*promParser.Call](t, "rate(foo[5m])", 14), |
| 918 | Aggregation: mustParse[*promParser.AggregateExpr](t, `quantile(0.9, rate(foo[5m]))`, 0), |
| 919 | FixedLabels: true, |
| 920 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 921 | "": { |
| 922 | Reason: "Query is using aggregation that removes all labels.", |
| 923 | }, |
| 924 | }, |
| 925 | }, |
| 926 | }, |
| 927 | }, |
| 928 | { |
| 929 | expr: `count_values("version", build_version)`, |
| 930 | output: []utils.Source{ |
| 931 | { |
| 932 | Type: utils.AggregateSource, |
| 933 | Returns: promParser.ValueTypeVector, |
| 934 | Operation: "count_values", |
| 935 | Selector: mustParse[*promParser.VectorSelector](t, `build_version`, 24), |
| 936 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count_values("version", build_version)`, 0), |
| 937 | GuaranteedLabels: []string{"version"}, |
| 938 | IncludedLabels: []string{"version"}, |
| 939 | FixedLabels: true, |
| 940 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 941 | "": { |
| 942 | Reason: "Query is using aggregation that removes all labels.", |
| 943 | }, |
| 944 | }, |
| 945 | }, |
| 946 | }, |
| 947 | }, |
| 948 | { |
| 949 | expr: `count_values("version", build_version) without(job)`, |
| 950 | output: []utils.Source{ |
| 951 | { |
| 952 | Type: utils.AggregateSource, |
| 953 | Returns: promParser.ValueTypeVector, |
| 954 | Operation: "count_values", |
| 955 | Selector: mustParse[*promParser.VectorSelector](t, `build_version`, 24), |
| 956 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count_values("version", build_version) without(job)`, 0), |
| 957 | IncludedLabels: []string{"version"}, |
| 958 | GuaranteedLabels: []string{"version"}, |
| 959 | ExcludedLabels: []string{"job"}, |
| 960 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 961 | "job": { |
| 962 | Reason: "Query is using aggregation with `without(job)`, all labels included inside `without(...)` will be removed from the results.", |
| 963 | }, |
| 964 | }, |
| 965 | }, |
| 966 | }, |
| 967 | }, |
| 968 | { |
| 969 | expr: `count_values("version", build_version{job="foo"}) without(job)`, |
| 970 | output: []utils.Source{ |
| 971 | { |
| 972 | Type: utils.AggregateSource, |
| 973 | Returns: promParser.ValueTypeVector, |
| 974 | Operation: "count_values", |
| 975 | Selector: mustParse[*promParser.VectorSelector](t, `build_version{job="foo"}`, 24), |
| 976 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count_values("version", build_version{job="foo"}) without(job)`, 0), |
| 977 | IncludedLabels: []string{"version"}, |
| 978 | GuaranteedLabels: []string{"version"}, |
| 979 | ExcludedLabels: []string{"job"}, |
| 980 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 981 | "job": { |
| 982 | Reason: "Query is using aggregation with `without(job)`, all labels included inside `without(...)` will be removed from the results.", |
| 983 | }, |
| 984 | }, |
| 985 | }, |
| 986 | }, |
| 987 | }, |
| 988 | { |
| 989 | expr: `count_values("version", build_version) by(job)`, |
| 990 | output: []utils.Source{ |
| 991 | { |
| 992 | Type: utils.AggregateSource, |
| 993 | Returns: promParser.ValueTypeVector, |
| 994 | Operation: "count_values", |
| 995 | Selector: mustParse[*promParser.VectorSelector](t, `build_version`, 24), |
| 996 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count_values("version", build_version) by(job)`, 0), |
| 997 | GuaranteedLabels: []string{"version"}, |
| 998 | IncludedLabels: []string{"job", "version"}, |
| 999 | FixedLabels: true, |
| 1000 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1001 | "": { |
| 1002 | Reason: "Query is using aggregation with `by(job)`, only labels included inside `by(...)` will be present on the results.", |
| 1003 | }, |
| 1004 | }, |
| 1005 | }, |
| 1006 | }, |
| 1007 | }, |
| 1008 | { |
| 1009 | expr: `topk(10, foo{job="myjob"}) > 10`, |
| 1010 | output: []utils.Source{ |
| 1011 | { |
| 1012 | Type: utils.AggregateSource, |
| 1013 | Returns: promParser.ValueTypeVector, |
| 1014 | Operation: "topk", |
| 1015 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 9), |
| 1016 | Aggregation: mustParse[*promParser.AggregateExpr](t, `topk(10, foo{job="myjob"})`, 0), |
| 1017 | GuaranteedLabels: []string{"job"}, |
| 1018 | IsConditional: true, |
| 1019 | }, |
| 1020 | }, |
| 1021 | }, |
| 1022 | { |
| 1023 | expr: `topk(10, foo or bar)`, |
| 1024 | output: []utils.Source{ |
| 1025 | { |
| 1026 | Type: utils.AggregateSource, |
| 1027 | Returns: promParser.ValueTypeVector, |
| 1028 | Operation: "topk", |
| 1029 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), |
| 1030 | Aggregation: mustParse[*promParser.AggregateExpr](t, `topk(10, foo or bar)`, 0), |
| 1031 | }, |
| 1032 | { |
| 1033 | Type: utils.AggregateSource, |
| 1034 | Operation: "topk", |
| 1035 | Returns: promParser.ValueTypeVector, |
| 1036 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 16), |
| 1037 | Aggregation: mustParse[*promParser.AggregateExpr](t, `topk(10, foo or bar)`, 0), |
| 1038 | }, |
| 1039 | }, |
| 1040 | }, |
| 1041 | { |
| 1042 | expr: `rate(foo[10m])`, |
| 1043 | output: []utils.Source{ |
| 1044 | { |
| 1045 | Type: utils.FuncSource, |
| 1046 | Returns: promParser.ValueTypeVector, |
| 1047 | Operation: "rate", |
| 1048 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 5), |
| 1049 | Call: mustParse[*promParser.Call](t, `rate(foo[10m])`, 0), |
| 1050 | }, |
| 1051 | }, |
| 1052 | }, |
| 1053 | { |
| 1054 | expr: `sum(rate(foo[10m])) without(instance)`, |
| 1055 | output: []utils.Source{ |
| 1056 | { |
| 1057 | Type: utils.AggregateSource, |
| 1058 | Returns: promParser.ValueTypeVector, |
| 1059 | Operation: "sum", |
| 1060 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), |
| 1061 | Call: mustParse[*promParser.Call](t, "rate(foo[10m])", 4), |
| 1062 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(rate(foo[10m])) without(instance)`, 0), |
| 1063 | ExcludedLabels: []string{"instance"}, |
| 1064 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1065 | "instance": { |
| 1066 | Reason: "Query is using aggregation with `without(instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 1067 | }, |
| 1068 | }, |
| 1069 | }, |
| 1070 | }, |
| 1071 | }, |
| 1072 | { |
| 1073 | expr: `foo{job="foo"} / bar`, |
| 1074 | output: []utils.Source{ |
| 1075 | { |
| 1076 | Type: utils.SelectorSource, |
| 1077 | Returns: promParser.ValueTypeVector, |
| 1078 | Operation: promParser.CardOneToOne.String(), |
| 1079 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), |
| 1080 | GuaranteedLabels: []string{"job"}, |
| 1081 | Joins: []utils.Join{ |
| 1082 | { |
| 1083 | Src: utils.Source{ |
| 1084 | Type: utils.SelectorSource, |
| 1085 | Returns: promParser.ValueTypeVector, |
| 1086 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 17), |
| 1087 | }, |
| 1088 | }, |
| 1089 | }, |
| 1090 | }, |
| 1091 | }, |
| 1092 | }, |
| 1093 | { |
| 1094 | expr: `foo{job="foo"} * on(instance) bar`, |
| 1095 | output: []utils.Source{ |
| 1096 | { |
| 1097 | Type: utils.SelectorSource, |
| 1098 | Returns: promParser.ValueTypeVector, |
| 1099 | Operation: promParser.CardOneToOne.String(), |
| 1100 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), |
| 1101 | IncludedLabels: []string{"instance"}, |
| 1102 | FixedLabels: true, |
| 1103 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1104 | "": { |
| 1105 | Reason: "Query is using one-to-one vector matching with `on(instance)`, only labels included inside `on(...)` will be present on the results.", |
| 1106 | }, |
| 1107 | }, |
| 1108 | Joins: []utils.Join{ |
| 1109 | { |
| 1110 | Src: utils.Source{ |
| 1111 | Type: utils.SelectorSource, |
| 1112 | Returns: promParser.ValueTypeVector, |
| 1113 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 30), |
| 1114 | }, |
| 1115 | }, |
| 1116 | }, |
| 1117 | }, |
| 1118 | }, |
| 1119 | }, |
| 1120 | { |
| 1121 | expr: `foo{job="foo"} * on(instance) group_left(bar) bar`, |
| 1122 | output: []utils.Source{ |
| 1123 | { |
| 1124 | Type: utils.SelectorSource, |
| 1125 | Returns: promParser.ValueTypeVector, |
| 1126 | Operation: promParser.CardManyToOne.String(), |
| 1127 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), |
| 1128 | IncludedLabels: []string{"bar", "instance"}, |
| 1129 | GuaranteedLabels: []string{"job"}, |
| 1130 | Joins: []utils.Join{ |
| 1131 | { |
| 1132 | Src: utils.Source{ |
| 1133 | Type: utils.SelectorSource, |
| 1134 | Returns: promParser.ValueTypeVector, |
| 1135 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 46), |
| 1136 | }, |
| 1137 | }, |
| 1138 | }, |
| 1139 | }, |
| 1140 | }, |
| 1141 | }, |
| 1142 | { |
| 1143 | expr: `foo{job="foo"} * on(instance) group_left(cluster) bar{cluster="bar", ignored="true"}`, |
| 1144 | output: []utils.Source{ |
| 1145 | { |
| 1146 | Type: utils.SelectorSource, |
| 1147 | Returns: promParser.ValueTypeVector, |
| 1148 | Operation: promParser.CardManyToOne.String(), |
| 1149 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), |
| 1150 | IncludedLabels: []string{"cluster", "instance"}, |
| 1151 | GuaranteedLabels: []string{"job"}, |
| 1152 | Joins: []utils.Join{ |
| 1153 | { |
| 1154 | Src: utils.Source{ |
| 1155 | Type: utils.SelectorSource, |
| 1156 | Returns: promParser.ValueTypeVector, |
| 1157 | Selector: mustParse[*promParser.VectorSelector](t, `bar{cluster="bar", ignored="true"}`, 50), |
| 1158 | GuaranteedLabels: []string{"cluster", "ignored"}, |
| 1159 | }, |
| 1160 | }, |
| 1161 | }, |
| 1162 | }, |
| 1163 | }, |
| 1164 | }, |
| 1165 | { |
| 1166 | expr: `foo{job="foo", ignored="true"} * on(instance) group_right(job) bar{cluster="bar"}`, |
| 1167 | output: []utils.Source{ |
| 1168 | { |
| 1169 | Type: utils.SelectorSource, |
| 1170 | Returns: promParser.ValueTypeVector, |
| 1171 | Operation: promParser.CardOneToMany.String(), |
| 1172 | Selector: mustParse[*promParser.VectorSelector](t, `bar{cluster="bar"}`, 63), |
| 1173 | IncludedLabels: []string{"job", "instance"}, |
| 1174 | GuaranteedLabels: []string{"cluster"}, |
| 1175 | Joins: []utils.Join{ |
| 1176 | { |
| 1177 | Src: utils.Source{ |
| 1178 | Type: utils.SelectorSource, |
| 1179 | Returns: promParser.ValueTypeVector, |
| 1180 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo", ignored="true"}`, 0), |
| 1181 | GuaranteedLabels: []string{"job", "ignored"}, |
| 1182 | }, |
| 1183 | }, |
| 1184 | }, |
| 1185 | }, |
| 1186 | }, |
| 1187 | }, |
| 1188 | { |
| 1189 | expr: `count(foo / bar)`, |
| 1190 | output: []utils.Source{ |
| 1191 | { |
| 1192 | Type: utils.AggregateSource, |
| 1193 | Returns: promParser.ValueTypeVector, |
| 1194 | Operation: "count", |
| 1195 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 6), |
| 1196 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count(foo / bar)`, 0), |
| 1197 | FixedLabels: true, |
| 1198 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1199 | "": { |
| 1200 | Reason: "Query is using aggregation that removes all labels.", |
| 1201 | }, |
| 1202 | }, |
| 1203 | Joins: []utils.Join{ |
| 1204 | { |
| 1205 | Src: utils.Source{ |
| 1206 | Type: utils.SelectorSource, |
| 1207 | Returns: promParser.ValueTypeVector, |
| 1208 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 12), |
| 1209 | }, |
| 1210 | }, |
| 1211 | }, |
| 1212 | }, |
| 1213 | }, |
| 1214 | }, |
| 1215 | { |
| 1216 | expr: `count(up{job="a"} / on () up{job="b"})`, |
| 1217 | output: []utils.Source{ |
| 1218 | { |
| 1219 | Type: utils.AggregateSource, |
| 1220 | Returns: promParser.ValueTypeVector, |
| 1221 | Operation: "count", |
| 1222 | Selector: mustParse[*promParser.VectorSelector](t, `up{job="a"}`, 6), |
| 1223 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count(up{job="a"} / on () up{job="b"})`, 0), |
| 1224 | FixedLabels: true, |
| 1225 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1226 | "": { |
| 1227 | Reason: "Query is using aggregation that removes all labels.", |
| 1228 | }, |
| 1229 | }, |
| 1230 | Joins: []utils.Join{ |
| 1231 | { |
| 1232 | Src: utils.Source{ |
| 1233 | Type: utils.SelectorSource, |
| 1234 | Returns: promParser.ValueTypeVector, |
| 1235 | Selector: mustParse[*promParser.VectorSelector](t, `up{job="b"}`, 26), |
| 1236 | GuaranteedLabels: []string{"job"}, |
| 1237 | }, |
| 1238 | }, |
| 1239 | }, |
| 1240 | }, |
| 1241 | }, |
| 1242 | }, |
| 1243 | { |
| 1244 | expr: `count(up{job="a"} / on (env) up{job="b"})`, |
| 1245 | output: []utils.Source{ |
| 1246 | { |
| 1247 | Type: utils.AggregateSource, |
| 1248 | Returns: promParser.ValueTypeVector, |
| 1249 | Operation: "count", |
| 1250 | Selector: mustParse[*promParser.VectorSelector](t, `up{job="a"}`, 6), |
| 1251 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count(up{job="a"} / on (env) up{job="b"})`, 0), |
| 1252 | FixedLabels: true, |
| 1253 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1254 | "": { |
| 1255 | Reason: "Query is using aggregation that removes all labels.", |
| 1256 | }, |
| 1257 | }, |
| 1258 | Joins: []utils.Join{ |
| 1259 | { |
| 1260 | Src: utils.Source{ |
| 1261 | Type: utils.SelectorSource, |
| 1262 | Returns: promParser.ValueTypeVector, |
| 1263 | Selector: mustParse[*promParser.VectorSelector](t, `up{job="b"}`, 29), |
| 1264 | GuaranteedLabels: []string{"job"}, |
| 1265 | }, |
| 1266 | }, |
| 1267 | }, |
| 1268 | }, |
| 1269 | }, |
| 1270 | }, |
| 1271 | { |
| 1272 | expr: `foo{job="foo", instance="1"} and bar`, |
| 1273 | output: []utils.Source{ |
| 1274 | { |
| 1275 | Type: utils.SelectorSource, |
| 1276 | Returns: promParser.ValueTypeVector, |
| 1277 | Operation: promParser.CardManyToMany.String(), |
| 1278 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo", instance="1"}`, 0), |
| 1279 | GuaranteedLabels: []string{"job", "instance"}, |
| 1280 | Joins: []utils.Join{ |
| 1281 | { |
| 1282 | Src: utils.Source{ |
| 1283 | Type: utils.SelectorSource, |
| 1284 | Returns: promParser.ValueTypeVector, |
| 1285 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 33), |
| 1286 | }, |
| 1287 | }, |
| 1288 | }, |
| 1289 | }, |
| 1290 | }, |
| 1291 | }, |
| 1292 | { |
| 1293 | expr: `foo{job="foo", instance="1"} and on(cluster) bar`, |
| 1294 | output: []utils.Source{ |
| 1295 | { |
| 1296 | Type: utils.SelectorSource, |
| 1297 | Returns: promParser.ValueTypeVector, |
| 1298 | Operation: promParser.CardManyToMany.String(), |
| 1299 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo", instance="1"}`, 0), |
| 1300 | IncludedLabels: []string{"cluster"}, |
| 1301 | GuaranteedLabels: []string{"job", "instance"}, |
| 1302 | Joins: []utils.Join{ |
| 1303 | { |
| 1304 | Src: utils.Source{ |
| 1305 | Type: utils.SelectorSource, |
| 1306 | Returns: promParser.ValueTypeVector, |
| 1307 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 45), |
| 1308 | }, |
| 1309 | }, |
| 1310 | }, |
| 1311 | }, |
| 1312 | }, |
| 1313 | }, |
| 1314 | { |
| 1315 | expr: `topk(10, foo)`, |
| 1316 | output: []utils.Source{ |
| 1317 | { |
| 1318 | Type: utils.AggregateSource, |
| 1319 | Returns: promParser.ValueTypeVector, |
| 1320 | Operation: "topk", |
| 1321 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), |
| 1322 | Aggregation: mustParse[*promParser.AggregateExpr](t, `topk(10, foo)`, 0), |
| 1323 | }, |
| 1324 | }, |
| 1325 | }, |
| 1326 | { |
| 1327 | expr: `topk(10, foo) without(cluster)`, |
| 1328 | output: []utils.Source{ |
| 1329 | { |
| 1330 | Type: utils.AggregateSource, |
| 1331 | Returns: promParser.ValueTypeVector, |
| 1332 | Operation: "topk", |
| 1333 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), |
| 1334 | Aggregation: mustParse[*promParser.AggregateExpr](t, `topk(10, foo) without(cluster)`, 0), |
| 1335 | }, |
| 1336 | }, |
| 1337 | }, |
| 1338 | { |
| 1339 | expr: `topk(10, foo) by(cluster)`, |
| 1340 | output: []utils.Source{ |
| 1341 | { |
| 1342 | Type: utils.AggregateSource, |
| 1343 | Returns: promParser.ValueTypeVector, |
| 1344 | Operation: "topk", |
| 1345 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), |
| 1346 | Aggregation: mustParse[*promParser.AggregateExpr](t, `topk(10, foo) by(cluster)`, 0), |
| 1347 | }, |
| 1348 | }, |
| 1349 | }, |
| 1350 | { |
| 1351 | expr: `bottomk(10, sum(rate(foo[5m])) without(job))`, |
| 1352 | output: []utils.Source{ |
| 1353 | { |
| 1354 | Type: utils.AggregateSource, |
| 1355 | Returns: promParser.ValueTypeVector, |
| 1356 | Operation: "bottomk", |
| 1357 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 21), |
| 1358 | Call: mustParse[*promParser.Call](t, "rate(foo[5m])", 16), |
| 1359 | Aggregation: mustParse[*promParser.AggregateExpr](t, `bottomk(10, sum(rate(foo[5m])) without(job))`, 0), |
| 1360 | ExcludedLabels: []string{"job"}, |
| 1361 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1362 | "job": { |
| 1363 | Reason: "Query is using aggregation with `without(job)`, all labels included inside `without(...)` will be removed from the results.", |
| 1364 | }, |
| 1365 | }, |
| 1366 | }, |
| 1367 | }, |
| 1368 | }, |
| 1369 | { |
| 1370 | expr: `foo or bar`, |
| 1371 | output: []utils.Source{ |
| 1372 | { |
| 1373 | Type: utils.SelectorSource, |
| 1374 | Returns: promParser.ValueTypeVector, |
| 1375 | Operation: promParser.CardManyToMany.String(), |
| 1376 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), |
| 1377 | }, |
| 1378 | { |
| 1379 | Type: utils.SelectorSource, |
| 1380 | Returns: promParser.ValueTypeVector, |
| 1381 | Operation: promParser.CardManyToMany.String(), |
| 1382 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 7), |
| 1383 | }, |
| 1384 | }, |
| 1385 | }, |
| 1386 | { |
| 1387 | expr: `foo or bar or baz`, |
| 1388 | output: []utils.Source{ |
| 1389 | { |
| 1390 | Type: utils.SelectorSource, |
| 1391 | Returns: promParser.ValueTypeVector, |
| 1392 | Operation: promParser.CardManyToMany.String(), |
| 1393 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), |
| 1394 | }, |
| 1395 | { |
| 1396 | Type: utils.SelectorSource, |
| 1397 | Returns: promParser.ValueTypeVector, |
| 1398 | Operation: promParser.CardManyToMany.String(), |
| 1399 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 7), |
| 1400 | }, |
| 1401 | { |
| 1402 | Type: utils.SelectorSource, |
| 1403 | Returns: promParser.ValueTypeVector, |
| 1404 | Operation: promParser.CardManyToMany.String(), |
| 1405 | Selector: mustParse[*promParser.VectorSelector](t, `baz`, 14), |
| 1406 | }, |
| 1407 | }, |
| 1408 | }, |
| 1409 | { |
| 1410 | expr: `(foo or bar) or baz`, |
| 1411 | output: []utils.Source{ |
| 1412 | { |
| 1413 | Type: utils.SelectorSource, |
| 1414 | Returns: promParser.ValueTypeVector, |
| 1415 | Operation: promParser.CardManyToMany.String(), |
| 1416 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 1), |
| 1417 | }, |
| 1418 | { |
| 1419 | Type: utils.SelectorSource, |
| 1420 | Returns: promParser.ValueTypeVector, |
| 1421 | Operation: promParser.CardManyToMany.String(), |
| 1422 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 8), |
| 1423 | }, |
| 1424 | { |
| 1425 | Type: utils.SelectorSource, |
| 1426 | Returns: promParser.ValueTypeVector, |
| 1427 | Operation: promParser.CardManyToMany.String(), |
| 1428 | Selector: mustParse[*promParser.VectorSelector](t, `baz`, 16), |
| 1429 | }, |
| 1430 | }, |
| 1431 | }, |
| 1432 | { |
| 1433 | expr: `foo unless bar`, |
| 1434 | output: []utils.Source{ |
| 1435 | { |
| 1436 | Type: utils.SelectorSource, |
| 1437 | Returns: promParser.ValueTypeVector, |
| 1438 | Operation: promParser.CardManyToMany.String(), |
| 1439 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), |
| 1440 | Unless: []utils.Join{ |
| 1441 | { |
| 1442 | Src: utils.Source{ |
| 1443 | Type: utils.SelectorSource, |
| 1444 | Returns: promParser.ValueTypeVector, |
| 1445 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 11), |
| 1446 | }, |
| 1447 | }, |
| 1448 | }, |
| 1449 | }, |
| 1450 | }, |
| 1451 | }, |
| 1452 | { |
| 1453 | expr: `foo unless bar > 5`, |
| 1454 | output: []utils.Source{ |
| 1455 | { |
| 1456 | Type: utils.SelectorSource, |
| 1457 | Returns: promParser.ValueTypeVector, |
| 1458 | Operation: promParser.CardManyToMany.String(), |
| 1459 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), |
| 1460 | Unless: []utils.Join{ |
| 1461 | { |
| 1462 | Src: utils.Source{ |
| 1463 | Type: utils.SelectorSource, |
| 1464 | Returns: promParser.ValueTypeVector, |
| 1465 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 11), |
| 1466 | IsConditional: true, |
| 1467 | }, |
| 1468 | }, |
| 1469 | }, |
| 1470 | }, |
| 1471 | }, |
| 1472 | }, |
| 1473 | { |
| 1474 | expr: `foo unless bar unless baz`, |
| 1475 | output: []utils.Source{ |
| 1476 | { |
| 1477 | Type: utils.SelectorSource, |
| 1478 | Returns: promParser.ValueTypeVector, |
| 1479 | Operation: promParser.CardManyToMany.String(), |
| 1480 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), |
| 1481 | Unless: []utils.Join{ |
| 1482 | { |
| 1483 | Src: utils.Source{ |
| 1484 | Type: utils.SelectorSource, |
| 1485 | Returns: promParser.ValueTypeVector, |
| 1486 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 11), |
| 1487 | }, |
| 1488 | }, |
| 1489 | { |
| 1490 | Src: utils.Source{ |
| 1491 | Type: utils.SelectorSource, |
| 1492 | Returns: promParser.ValueTypeVector, |
| 1493 | Selector: mustParse[*promParser.VectorSelector](t, `baz`, 22), |
| 1494 | }, |
| 1495 | }, |
| 1496 | }, |
| 1497 | }, |
| 1498 | }, |
| 1499 | }, |
| 1500 | { |
| 1501 | expr: `count(sum(up{job="foo", cluster="dev"}) by(job, cluster) == 0) without(job, cluster)`, |
| 1502 | output: []utils.Source{ |
| 1503 | { |
| 1504 | Type: utils.AggregateSource, |
| 1505 | Returns: promParser.ValueTypeVector, |
| 1506 | Operation: "count", |
| 1507 | Selector: mustParse[*promParser.VectorSelector](t, `up{job="foo", cluster="dev"}`, 10), |
| 1508 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count(sum(up{job="foo", cluster="dev"}) by(job, cluster) == 0) without(job, cluster)`, 0), |
| 1509 | ExcludedLabels: []string{"job", "cluster"}, // FIXME empty |
| 1510 | FixedLabels: true, |
| 1511 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1512 | "": { |
| 1513 | Reason: "Query is using aggregation with `by(job, cluster)`, only labels included inside `by(...)` will be present on the results.", |
| 1514 | }, |
| 1515 | "job": { |
| 1516 | Reason: "Query is using aggregation with `without(job, cluster)`, all labels included inside `without(...)` will be removed from the results.", |
| 1517 | }, |
| 1518 | "cluster": { |
| 1519 | Reason: "Query is using aggregation with `without(job, cluster)`, all labels included inside `without(...)` will be removed from the results.", |
| 1520 | }, |
| 1521 | }, |
| 1522 | IsConditional: true, |
| 1523 | }, |
| 1524 | }, |
| 1525 | }, |
| 1526 | { |
| 1527 | expr: "year()", |
| 1528 | output: []utils.Source{ |
| 1529 | { |
| 1530 | Type: utils.FuncSource, |
| 1531 | Returns: promParser.ValueTypeVector, |
| 1532 | Operation: "year", |
| 1533 | FixedLabels: true, |
| 1534 | AlwaysReturns: true, |
| 1535 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1536 | "": { |
| 1537 | Reason: "Calling `year()` with no arguments will return an empty time series with no labels.", |
| 1538 | }, |
| 1539 | }, |
| 1540 | Call: mustParse[*promParser.Call](t, `year()`, 0), |
| 1541 | }, |
| 1542 | }, |
| 1543 | }, |
| 1544 | { |
| 1545 | expr: "year(foo)", |
| 1546 | output: []utils.Source{ |
| 1547 | { |
| 1548 | Type: utils.FuncSource, |
| 1549 | Returns: promParser.ValueTypeVector, |
| 1550 | Operation: "year", |
| 1551 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 5), |
| 1552 | Call: mustParse[*promParser.Call](t, `year(foo)`, 0), |
| 1553 | }, |
| 1554 | }, |
| 1555 | }, |
| 1556 | { |
| 1557 | expr: `label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")`, |
| 1558 | output: []utils.Source{ |
| 1559 | { |
| 1560 | Type: utils.FuncSource, |
| 1561 | Returns: promParser.ValueTypeVector, |
| 1562 | Operation: "label_join", |
| 1563 | Selector: mustParse[*promParser.VectorSelector](t, `up{job="api-server",src1="a",src2="b",src3="c"}`, 11), |
| 1564 | GuaranteedLabels: []string{"job", "src1", "src2", "src3", "foo"}, |
| 1565 | Call: mustParse[*promParser.Call](t, `label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")`, 0), |
| 1566 | }, |
| 1567 | }, |
| 1568 | }, |
| 1569 | { |
| 1570 | expr: ` |
| 1571 | ( |
| 1572 | sum(foo:sum > 0) without(notify) |
| 1573 | * on(job) group_left(notify) |
| 1574 | job:notify |
| 1575 | ) |
| 1576 | and on(job) |
| 1577 | sum(foo:count) by(job) > 20`, |
| 1578 | output: []utils.Source{ |
| 1579 | { |
| 1580 | Type: utils.AggregateSource, |
| 1581 | Returns: promParser.ValueTypeVector, |
| 1582 | Operation: "sum", |
| 1583 | Selector: mustParse[*promParser.VectorSelector](t, `foo:sum`, 8), |
| 1584 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo:sum > 0) without(notify)`, 4), |
| 1585 | IncludedLabels: []string{"notify", "job"}, |
| 1586 | ExcludeReason: map[string]utils.ExcludedLabel{}, |
| 1587 | IsConditional: true, |
| 1588 | Joins: []utils.Join{ |
| 1589 | { |
| 1590 | Src: utils.Source{ |
| 1591 | Type: utils.SelectorSource, |
| 1592 | Returns: promParser.ValueTypeVector, |
| 1593 | Selector: mustParse[*promParser.VectorSelector](t, `job:notify`, 68), |
| 1594 | }, |
| 1595 | }, |
| 1596 | { |
| 1597 | Src: utils.Source{ |
| 1598 | Type: utils.AggregateSource, |
| 1599 | Returns: promParser.ValueTypeVector, |
| 1600 | Operation: "sum", |
| 1601 | Selector: mustParse[*promParser.VectorSelector](t, `foo:count`, 97), |
| 1602 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo:count) by(job)`, 93), |
| 1603 | IncludedLabels: []string{"job"}, |
| 1604 | FixedLabels: true, |
| 1605 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1606 | "": { |
| 1607 | Reason: "Query is using aggregation with `by(job)`, only labels included inside `by(...)` will be present on the results.", |
| 1608 | }, |
| 1609 | }, |
| 1610 | IsConditional: true, |
| 1611 | }, |
| 1612 | }, |
| 1613 | }, |
| 1614 | }, |
| 1615 | }, |
| 1616 | }, |
| 1617 | { |
| 1618 | expr: `container_file_descriptors / on (instance, app_name) container_ulimits_soft{ulimit="max_open_files"}`, |
| 1619 | output: []utils.Source{ |
| 1620 | { |
| 1621 | Type: utils.SelectorSource, |
| 1622 | Returns: promParser.ValueTypeVector, |
| 1623 | Operation: promParser.CardOneToOne.String(), |
| 1624 | Selector: mustParse[*promParser.VectorSelector](t, `container_file_descriptors`, 0), |
| 1625 | IncludedLabels: []string{"instance", "app_name"}, |
| 1626 | FixedLabels: true, |
| 1627 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1628 | "": { |
| 1629 | Reason: "Query is using one-to-one vector matching with `on(instance, app_name)`, only labels included inside `on(...)` will be present on the results.", |
| 1630 | }, |
| 1631 | }, |
| 1632 | Joins: []utils.Join{ |
| 1633 | { |
| 1634 | Src: utils.Source{ |
| 1635 | Type: utils.SelectorSource, |
| 1636 | Returns: promParser.ValueTypeVector, |
| 1637 | Selector: mustParse[*promParser.VectorSelector](t, `container_ulimits_soft{ulimit="max_open_files"}`, 53), |
| 1638 | GuaranteedLabels: []string{"ulimit"}, |
| 1639 | }, |
| 1640 | }, |
| 1641 | }, |
| 1642 | }, |
| 1643 | }, |
| 1644 | }, |
| 1645 | { |
| 1646 | expr: `container_file_descriptors / on (instance, app_name) group_left() container_ulimits_soft{ulimit="max_open_files"}`, |
| 1647 | output: []utils.Source{ |
| 1648 | { |
| 1649 | Type: utils.SelectorSource, |
| 1650 | Returns: promParser.ValueTypeVector, |
| 1651 | Operation: promParser.CardManyToOne.String(), |
| 1652 | Selector: mustParse[*promParser.VectorSelector](t, `container_file_descriptors`, 0), |
| 1653 | IncludedLabels: []string{"instance", "app_name"}, |
| 1654 | Joins: []utils.Join{ |
| 1655 | { |
| 1656 | Src: utils.Source{ |
| 1657 | Type: utils.SelectorSource, |
| 1658 | Returns: promParser.ValueTypeVector, |
| 1659 | Selector: mustParse[*promParser.VectorSelector](t, `container_ulimits_soft{ulimit="max_open_files"}`, 66), |
| 1660 | GuaranteedLabels: []string{"ulimit"}, |
| 1661 | }, |
| 1662 | }, |
| 1663 | }, |
| 1664 | }, |
| 1665 | }, |
| 1666 | }, |
| 1667 | { |
| 1668 | expr: `absent(foo{job="bar"})`, |
| 1669 | output: []utils.Source{ |
| 1670 | { |
| 1671 | Type: utils.FuncSource, |
| 1672 | Returns: promParser.ValueTypeVector, |
| 1673 | Operation: "absent", |
| 1674 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 7), |
| 1675 | IncludedLabels: []string{"job"}, |
| 1676 | GuaranteedLabels: []string{"job"}, |
| 1677 | FixedLabels: true, |
| 1678 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1679 | "": { |
| 1680 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1681 | }, |
| 1682 | }, |
| 1683 | Call: mustParse[*promParser.Call](t, `absent(foo{job="bar"})`, 0), |
| 1684 | }, |
| 1685 | }, |
| 1686 | }, |
| 1687 | { |
| 1688 | expr: `absent(foo{job="bar", cluster!="dev", instance=~".+", env="prod"})`, |
| 1689 | output: []utils.Source{ |
| 1690 | { |
| 1691 | Type: utils.FuncSource, |
| 1692 | Returns: promParser.ValueTypeVector, |
| 1693 | Operation: "absent", |
| 1694 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="bar", cluster!="dev", instance=~".+", env="prod"}`, 7), |
| 1695 | IncludedLabels: []string{"job", "env"}, |
| 1696 | GuaranteedLabels: []string{"job", "env"}, |
| 1697 | FixedLabels: true, |
| 1698 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1699 | "": { |
| 1700 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1701 | }, |
| 1702 | }, |
| 1703 | Call: mustParse[*promParser.Call](t, `absent(foo{job="bar", cluster!="dev", instance=~".+", env="prod"})`, 0), |
| 1704 | }, |
| 1705 | }, |
| 1706 | }, |
| 1707 | { |
| 1708 | expr: `absent(sum(foo) by(job, instance))`, |
| 1709 | output: []utils.Source{ |
| 1710 | { |
| 1711 | Type: utils.FuncSource, |
| 1712 | Returns: promParser.ValueTypeVector, |
| 1713 | Operation: "absent", |
| 1714 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 11), |
| 1715 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo) by(job, instance)`, 7), |
| 1716 | FixedLabels: true, |
| 1717 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1718 | "": { |
| 1719 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1720 | }, |
| 1721 | }, |
| 1722 | Call: mustParse[*promParser.Call](t, `absent(sum(foo) by(job, instance))`, 0), |
| 1723 | }, |
| 1724 | }, |
| 1725 | }, |
| 1726 | { |
| 1727 | expr: `absent(foo{job="prometheus", xxx="1"}) AND on(job) prometheus_build_info`, |
| 1728 | output: []utils.Source{ |
| 1729 | { |
| 1730 | Type: utils.FuncSource, |
| 1731 | Returns: promParser.ValueTypeVector, |
| 1732 | Operation: "absent", |
| 1733 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="prometheus", xxx="1"}`, 7), |
| 1734 | IncludedLabels: []string{"job", "xxx"}, |
| 1735 | GuaranteedLabels: []string{"job", "xxx"}, |
| 1736 | FixedLabels: true, |
| 1737 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1738 | "": { |
| 1739 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1740 | }, |
| 1741 | }, |
| 1742 | Call: mustParse[*promParser.Call](t, `absent(foo{job="prometheus", xxx="1"})`, 0), |
| 1743 | Joins: []utils.Join{ |
| 1744 | { |
| 1745 | Src: utils.Source{ |
| 1746 | Type: utils.SelectorSource, |
| 1747 | Returns: promParser.ValueTypeVector, |
| 1748 | Selector: mustParse[*promParser.VectorSelector](t, "prometheus_build_info", 51), |
| 1749 | }, |
| 1750 | }, |
| 1751 | }, |
| 1752 | }, |
| 1753 | }, |
| 1754 | }, |
| 1755 | { |
| 1756 | expr: `1 + sum(foo) by(notjob)`, |
| 1757 | output: []utils.Source{ |
| 1758 | { |
| 1759 | Type: utils.AggregateSource, |
| 1760 | Returns: promParser.ValueTypeVector, |
| 1761 | Operation: "sum", |
| 1762 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 8), |
| 1763 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo) by(notjob)`, 4), |
| 1764 | IncludedLabels: []string{"notjob"}, |
| 1765 | FixedLabels: true, |
| 1766 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1767 | "": { |
| 1768 | Reason: "Query is using aggregation with `by(notjob)`, only labels included inside `by(...)` will be present on the results.", |
| 1769 | }, |
| 1770 | }, |
| 1771 | }, |
| 1772 | }, |
| 1773 | }, |
| 1774 | { |
| 1775 | expr: `count(node_exporter_build_info) by (instance, version) != ignoring(package,version) group_left(foo) count(deb_package_version) by (instance, version, package)`, |
| 1776 | output: []utils.Source{ |
| 1777 | { |
| 1778 | Type: utils.AggregateSource, |
| 1779 | Returns: promParser.ValueTypeVector, |
| 1780 | Operation: "count", |
| 1781 | Selector: mustParse[*promParser.VectorSelector](t, `node_exporter_build_info`, 6), |
| 1782 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count(node_exporter_build_info) by (instance, version)`, 0), |
| 1783 | IncludedLabels: []string{"instance", "version", "foo"}, |
| 1784 | FixedLabels: true, |
| 1785 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1786 | "": { |
| 1787 | Reason: "Query is using aggregation with `by(instance, version)`, only labels included inside `by(...)` will be present on the results.", |
| 1788 | }, |
| 1789 | }, |
| 1790 | IsConditional: true, |
| 1791 | Joins: []utils.Join{ |
| 1792 | { |
| 1793 | Src: utils.Source{ |
| 1794 | Type: utils.AggregateSource, |
| 1795 | Returns: promParser.ValueTypeVector, |
| 1796 | Operation: "count", |
| 1797 | Selector: mustParse[*promParser.VectorSelector](t, "deb_package_version", 106), |
| 1798 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count(deb_package_version) by (instance, version, package)`, 100), |
| 1799 | IncludedLabels: []string{"instance", "version", "package"}, |
| 1800 | FixedLabels: true, |
| 1801 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1802 | "": { |
| 1803 | Reason: "Query is using aggregation with `by(instance, version, package)`, only labels included inside `by(...)` will be present on the results.", |
| 1804 | }, |
| 1805 | }, |
| 1806 | }, |
| 1807 | }, |
| 1808 | }, |
| 1809 | }, |
| 1810 | }, |
| 1811 | }, |
| 1812 | { |
| 1813 | expr: `absent(foo) or absent(bar)`, |
| 1814 | output: []utils.Source{ |
| 1815 | { |
| 1816 | Type: utils.FuncSource, |
| 1817 | Returns: promParser.ValueTypeVector, |
| 1818 | Operation: "absent", |
| 1819 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 7), |
| 1820 | FixedLabels: true, |
| 1821 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1822 | "": { |
| 1823 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1824 | }, |
| 1825 | }, |
| 1826 | Call: mustParse[*promParser.Call](t, `absent(foo)`, 0), |
| 1827 | }, |
| 1828 | { |
| 1829 | Type: utils.FuncSource, |
| 1830 | Returns: promParser.ValueTypeVector, |
| 1831 | Operation: "absent", |
| 1832 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 22), |
| 1833 | FixedLabels: true, |
| 1834 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1835 | "": { |
| 1836 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1837 | }, |
| 1838 | }, |
| 1839 | Call: mustParse[*promParser.Call](t, `absent(bar)`, 15), |
| 1840 | }, |
| 1841 | }, |
| 1842 | }, |
| 1843 | { |
| 1844 | expr: `absent_over_time(foo[5m]) or absent(bar)`, |
| 1845 | output: []utils.Source{ |
| 1846 | { |
| 1847 | Type: utils.FuncSource, |
| 1848 | Returns: promParser.ValueTypeVector, |
| 1849 | Operation: "absent_over_time", |
| 1850 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 17), |
| 1851 | FixedLabels: true, |
| 1852 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1853 | "": { |
| 1854 | Reason: "The [absent_over_time()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent_over_time) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1855 | }, |
| 1856 | }, |
| 1857 | Call: mustParse[*promParser.Call](t, `absent_over_time(foo[5m])`, 0), |
| 1858 | }, |
| 1859 | { |
| 1860 | Type: utils.FuncSource, |
| 1861 | Returns: promParser.ValueTypeVector, |
| 1862 | Operation: "absent", |
| 1863 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 36), |
| 1864 | FixedLabels: true, |
| 1865 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1866 | "": { |
| 1867 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1868 | }, |
| 1869 | }, |
| 1870 | Call: mustParse[*promParser.Call](t, `absent(bar)`, 29), |
| 1871 | }, |
| 1872 | }, |
| 1873 | }, |
| 1874 | { |
| 1875 | expr: `bar * on() group_right(cluster, env) absent(foo{job="xxx"})`, |
| 1876 | output: []utils.Source{ |
| 1877 | { |
| 1878 | Type: utils.FuncSource, |
| 1879 | Returns: promParser.ValueTypeVector, |
| 1880 | Operation: "absent", |
| 1881 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="xxx"}`, 44), |
| 1882 | IncludedLabels: []string{"job", "cluster", "env"}, |
| 1883 | GuaranteedLabels: []string{"job"}, |
| 1884 | FixedLabels: true, |
| 1885 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1886 | "": { |
| 1887 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1888 | }, |
| 1889 | }, |
| 1890 | Call: mustParse[*promParser.Call](t, `absent(foo{job="xxx"})`, 37), |
| 1891 | Joins: []utils.Join{ |
| 1892 | { |
| 1893 | Src: utils.Source{ |
| 1894 | Type: utils.SelectorSource, |
| 1895 | Returns: promParser.ValueTypeVector, |
| 1896 | Selector: mustParse[*promParser.VectorSelector](t, "bar", 0), |
| 1897 | }, |
| 1898 | }, |
| 1899 | }, |
| 1900 | }, |
| 1901 | }, |
| 1902 | }, |
| 1903 | { |
| 1904 | expr: `bar * on() group_right() absent(foo{job="xxx"})`, |
| 1905 | output: []utils.Source{ |
| 1906 | { |
| 1907 | Type: utils.FuncSource, |
| 1908 | Returns: promParser.ValueTypeVector, |
| 1909 | Operation: "absent", |
| 1910 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="xxx"}`, 32), |
| 1911 | IncludedLabels: []string{"job"}, |
| 1912 | GuaranteedLabels: []string{"job"}, |
| 1913 | FixedLabels: true, |
| 1914 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1915 | "": { |
| 1916 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 1917 | }, |
| 1918 | }, |
| 1919 | Call: mustParse[*promParser.Call](t, `absent(foo{job="xxx"})`, 25), |
| 1920 | Joins: []utils.Join{ |
| 1921 | { |
| 1922 | Src: utils.Source{ |
| 1923 | Type: utils.SelectorSource, |
| 1924 | Returns: promParser.ValueTypeVector, |
| 1925 | Selector: mustParse[*promParser.VectorSelector](t, "bar", 0), |
| 1926 | }, |
| 1927 | }, |
| 1928 | }, |
| 1929 | }, |
| 1930 | }, |
| 1931 | }, |
| 1932 | { |
| 1933 | expr: "vector(1)", |
| 1934 | output: []utils.Source{ |
| 1935 | { |
| 1936 | Type: utils.FuncSource, |
| 1937 | Returns: promParser.ValueTypeVector, |
| 1938 | Operation: "vector", |
| 1939 | FixedLabels: true, |
| 1940 | AlwaysReturns: true, |
| 1941 | KnownReturn: true, |
| 1942 | ReturnedNumber: 1, |
| 1943 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1944 | "": { |
| 1945 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 1946 | }, |
| 1947 | }, |
| 1948 | Call: mustParse[*promParser.Call](t, `vector(1)`, 0), |
| 1949 | }, |
| 1950 | }, |
| 1951 | }, |
| 1952 | { |
| 1953 | expr: "vector(scalar(foo))", |
| 1954 | output: []utils.Source{ |
| 1955 | { |
| 1956 | Type: utils.FuncSource, |
| 1957 | Returns: promParser.ValueTypeVector, |
| 1958 | Operation: "vector", |
| 1959 | FixedLabels: true, |
| 1960 | AlwaysReturns: true, |
| 1961 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1962 | "": { |
| 1963 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 1964 | }, |
| 1965 | }, |
| 1966 | Call: mustParse[*promParser.Call](t, `vector(scalar(foo))`, 0), |
| 1967 | }, |
| 1968 | }, |
| 1969 | }, |
| 1970 | { |
| 1971 | expr: "vector(0.0 >= bool 0.5) == 1", |
| 1972 | output: []utils.Source{ |
| 1973 | { |
| 1974 | Type: utils.FuncSource, |
| 1975 | Returns: promParser.ValueTypeVector, |
| 1976 | Operation: "vector", |
| 1977 | FixedLabels: true, |
| 1978 | AlwaysReturns: true, |
| 1979 | KnownReturn: true, |
| 1980 | IsDead: true, |
| 1981 | IsDeadReason: "this query always evaluates to `0 == 1` which is not possible, so it will never return anything", |
| 1982 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 1983 | "": { |
| 1984 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 1985 | }, |
| 1986 | }, |
| 1987 | Call: mustParse[*promParser.Call](t, `vector(0.0 >= bool 0.5)`, 0), |
| 1988 | IsConditional: true, |
| 1989 | }, |
| 1990 | }, |
| 1991 | }, |
| 1992 | { |
| 1993 | expr: `sum_over_time(foo{job="myjob"}[5m])`, |
| 1994 | output: []utils.Source{ |
| 1995 | { |
| 1996 | Type: utils.FuncSource, |
| 1997 | Returns: promParser.ValueTypeVector, |
| 1998 | Operation: "sum_over_time", |
| 1999 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 14), |
| 2000 | GuaranteedLabels: []string{"job"}, |
| 2001 | Call: mustParse[*promParser.Call](t, `sum_over_time(foo{job="myjob"}[5m])`, 0), |
| 2002 | }, |
| 2003 | }, |
| 2004 | }, |
| 2005 | { |
| 2006 | expr: `days_in_month()`, |
| 2007 | output: []utils.Source{ |
| 2008 | { |
| 2009 | Type: utils.FuncSource, |
| 2010 | Returns: promParser.ValueTypeVector, |
| 2011 | Operation: "days_in_month", |
| 2012 | FixedLabels: true, |
| 2013 | AlwaysReturns: true, |
| 2014 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2015 | "": { |
| 2016 | Reason: "Calling `days_in_month()` with no arguments will return an empty time series with no labels.", |
| 2017 | }, |
| 2018 | }, |
| 2019 | Call: mustParse[*promParser.Call](t, `days_in_month()`, 0), |
| 2020 | }, |
| 2021 | }, |
| 2022 | }, |
| 2023 | { |
| 2024 | expr: `days_in_month(foo{job="foo"})`, |
| 2025 | output: []utils.Source{ |
| 2026 | { |
| 2027 | Type: utils.FuncSource, |
| 2028 | Returns: promParser.ValueTypeVector, |
| 2029 | Operation: "days_in_month", |
| 2030 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 14), |
| 2031 | GuaranteedLabels: []string{"job"}, |
| 2032 | Call: mustParse[*promParser.Call](t, `days_in_month(foo{job="foo"})`, 0), |
| 2033 | }, |
| 2034 | }, |
| 2035 | }, |
| 2036 | { |
| 2037 | expr: `label_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.*):.*")`, |
| 2038 | output: []utils.Source{ |
| 2039 | { |
| 2040 | Type: utils.FuncSource, |
| 2041 | Returns: promParser.ValueTypeVector, |
| 2042 | Operation: "label_replace", |
| 2043 | Selector: mustParse[*promParser.VectorSelector](t, `up{job="api-server",service="a:c"}`, 14), |
| 2044 | GuaranteedLabels: []string{"job", "service", "foo"}, |
| 2045 | Call: mustParse[*promParser.Call](t, `label_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.*):.*")`, 0), |
| 2046 | }, |
| 2047 | }, |
| 2048 | }, |
| 2049 | { |
| 2050 | expr: `label_replace(sum by (pod) (pod_status) > 0, "cluster", "$1", "pod", "(.*)")`, |
| 2051 | output: []utils.Source{ |
| 2052 | { |
| 2053 | Type: utils.FuncSource, |
| 2054 | Returns: promParser.ValueTypeVector, |
| 2055 | Operation: "label_replace", |
| 2056 | Selector: mustParse[*promParser.VectorSelector](t, `pod_status`, 28), |
| 2057 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum by (pod) (pod_status)`, 14), |
| 2058 | FixedLabels: true, |
| 2059 | IsConditional: true, |
| 2060 | IncludedLabels: []string{"pod"}, |
| 2061 | GuaranteedLabels: []string{"cluster"}, |
| 2062 | Call: mustParse[*promParser.Call](t, `label_replace(sum by (pod) (pod_status) > 0, "cluster", "$1", "pod", "(.*)")`, 0), |
| 2063 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2064 | "": { |
| 2065 | Reason: "Query is using aggregation with `by(pod)`, only labels included inside `by(...)` will be present on the results.", |
| 2066 | }, |
| 2067 | }, |
| 2068 | }, |
| 2069 | }, |
| 2070 | }, |
| 2071 | { |
| 2072 | expr: `(time() - my_metric) > 5*3600`, |
| 2073 | output: []utils.Source{ |
| 2074 | { |
| 2075 | Type: utils.SelectorSource, |
| 2076 | Returns: promParser.ValueTypeVector, |
| 2077 | Selector: mustParse[*promParser.VectorSelector](t, "my_metric", 10), |
| 2078 | IsConditional: true, |
| 2079 | }, |
| 2080 | }, |
| 2081 | }, |
| 2082 | { |
| 2083 | expr: `up{instance="a", job="prometheus"} * ignoring(job) up{instance="a", job="pint"}`, |
| 2084 | output: []utils.Source{ |
| 2085 | { |
| 2086 | Type: utils.SelectorSource, |
| 2087 | Returns: promParser.ValueTypeVector, |
| 2088 | Operation: promParser.CardOneToOne.String(), |
| 2089 | Selector: mustParse[*promParser.VectorSelector](t, `up{instance="a", job="prometheus"}`, 0), |
| 2090 | GuaranteedLabels: []string{"instance"}, |
| 2091 | ExcludedLabels: []string{"job"}, |
| 2092 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2093 | "job": { |
| 2094 | Reason: "Query is using one-to-one vector matching with `ignoring(job)`, all labels included inside `ignoring(...)` will be removed on the results.", |
| 2095 | }, |
| 2096 | }, |
| 2097 | Joins: []utils.Join{ |
| 2098 | { |
| 2099 | Src: utils.Source{ |
| 2100 | Type: utils.SelectorSource, |
| 2101 | Returns: promParser.ValueTypeVector, |
| 2102 | Selector: mustParse[*promParser.VectorSelector](t, `up{instance="a", job="pint"}`, 51), |
| 2103 | GuaranteedLabels: []string{"instance", "job"}, |
| 2104 | }, |
| 2105 | }, |
| 2106 | }, |
| 2107 | }, |
| 2108 | }, |
| 2109 | }, |
| 2110 | { |
| 2111 | expr: ` |
| 2112 | avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_use_case!~".*offpeak.*"}) |
| 2113 | < 0.5 > 0 |
| 2114 | or sum without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_use_case=~".*tier1.*"}) |
| 2115 | < on() count(colo_router_tier:disabled_pops:max{tier="1",router=~"edge.*"}) * 0.4 > 0 |
| 2116 | or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_use_case=~".*regional.*"}) |
| 2117 | < 0.1 > 0 |
| 2118 | `, |
| 2119 | output: []utils.Source{ |
| 2120 | { |
| 2121 | Type: utils.AggregateSource, |
| 2122 | Returns: promParser.ValueTypeVector, |
| 2123 | Operation: "avg", |
| 2124 | Selector: mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case!~".*offpeak.*"}`, 41), |
| 2125 | Aggregation: mustParse[*promParser.AggregateExpr](t, `avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_use_case!~".*offpeak.*"})`, 1), |
| 2126 | |
| 2127 | ExcludedLabels: []string{"router", "colo_id", "instance"}, |
| 2128 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2129 | "router": { |
| 2130 | Reason: "Query is using aggregation with `without(router, colo_id, instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 2131 | }, |
| 2132 | "colo_id": { |
| 2133 | Reason: "Query is using aggregation with `without(router, colo_id, instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 2134 | }, |
| 2135 | "instance": { |
| 2136 | Reason: "Query is using aggregation with `without(router, colo_id, instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 2137 | }, |
| 2138 | }, |
| 2139 | IsConditional: true, |
| 2140 | }, |
| 2141 | { |
| 2142 | Type: utils.AggregateSource, |
| 2143 | Returns: promParser.ValueTypeVector, |
| 2144 | Operation: "sum", |
| 2145 | Selector: mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case=~".*tier1.*"}`, 155), |
| 2146 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_use_case=~".*tier1.*"})`, 115), |
| 2147 | ExcludedLabels: []string{"router", "colo_id", "instance"}, |
| 2148 | FixedLabels: true, |
| 2149 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2150 | "router": { |
| 2151 | Reason: "Query is using aggregation with `without(router, colo_id, instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 2152 | }, |
| 2153 | "colo_id": { |
| 2154 | Reason: "Query is using aggregation with `without(router, colo_id, instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 2155 | }, |
| 2156 | "instance": { |
| 2157 | Reason: "Query is using aggregation with `without(router, colo_id, instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 2158 | }, |
| 2159 | "": { |
| 2160 | Reason: "Query is using one-to-one vector matching with `on()`, only labels included inside `on(...)` will be present on the results.", |
| 2161 | }, |
| 2162 | }, |
| 2163 | IsConditional: true, |
| 2164 | Joins: []utils.Join{ |
| 2165 | { |
| 2166 | Src: utils.Source{ |
| 2167 | Type: utils.AggregateSource, |
| 2168 | Returns: promParser.ValueTypeVector, |
| 2169 | Operation: "count", |
| 2170 | Selector: mustParse[*promParser.VectorSelector](t, `colo_router_tier:disabled_pops:max{tier="1",router=~"edge.*"}`, 227), |
| 2171 | Aggregation: mustParse[*promParser.AggregateExpr](t, `count(colo_router_tier:disabled_pops:max{tier="1",router=~"edge.*"})`, 221), |
| 2172 | FixedLabels: true, |
| 2173 | IsConditional: false, // FIXME true? |
| 2174 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2175 | "": { |
| 2176 | Reason: "Query is using aggregation that removes all labels.", |
| 2177 | }, |
| 2178 | }, |
| 2179 | }, |
| 2180 | }, |
| 2181 | }, |
| 2182 | }, |
| 2183 | { |
| 2184 | Type: utils.AggregateSource, |
| 2185 | Returns: promParser.ValueTypeVector, |
| 2186 | Operation: "avg", |
| 2187 | Selector: mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case=~".*regional.*"}`, 343), |
| 2188 | Aggregation: mustParse[*promParser.AggregateExpr](t, `avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_use_case=~".*regional.*"})`, 303), |
| 2189 | GuaranteedLabels: []string{"cidr_use_case"}, |
| 2190 | ExcludedLabels: []string{"router", "colo_id", "instance"}, |
| 2191 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2192 | "router": { |
| 2193 | Reason: "Query is using aggregation with `without(router, colo_id, instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 2194 | }, |
| 2195 | "colo_id": { |
| 2196 | Reason: "Query is using aggregation with `without(router, colo_id, instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 2197 | }, |
| 2198 | "instance": { |
| 2199 | Reason: "Query is using aggregation with `without(router, colo_id, instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 2200 | }, |
| 2201 | }, |
| 2202 | IsConditional: true, |
| 2203 | }, |
| 2204 | }, |
| 2205 | }, |
| 2206 | { |
| 2207 | expr: `label_replace(sum(foo) without(instance), "instance", "none", "", "")`, |
| 2208 | output: []utils.Source{ |
| 2209 | { |
| 2210 | Type: utils.FuncSource, |
| 2211 | Returns: promParser.ValueTypeVector, |
| 2212 | Operation: "label_replace", |
| 2213 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 18), |
| 2214 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo) without(instance)`, 14), |
| 2215 | GuaranteedLabels: []string{"instance"}, |
| 2216 | ExcludeReason: map[string]utils.ExcludedLabel{}, |
| 2217 | Call: mustParse[*promParser.Call](t, `label_replace(sum(foo) without(instance), "instance", "none", "", "")`, 0), |
| 2218 | }, |
| 2219 | }, |
| 2220 | }, |
| 2221 | { |
| 2222 | expr: ` |
| 2223 | sum by (region, target, colo_name) ( |
| 2224 | sum_over_time(probe_success{job="abc"}[5m]) |
| 2225 | or |
| 2226 | vector(1) |
| 2227 | ) == 0`, |
| 2228 | output: []utils.Source{ |
| 2229 | { |
| 2230 | Type: utils.AggregateSource, |
| 2231 | Returns: promParser.ValueTypeVector, |
| 2232 | Operation: "sum", |
| 2233 | Selector: mustParse[*promParser.VectorSelector](t, `probe_success{job="abc"}`, 56), |
| 2234 | Call: mustParse[*promParser.Call](t, `sum_over_time(probe_success{job="abc"}[5m])`, 42), |
| 2235 | Aggregation: mustParse[*promParser.AggregateExpr](t, ` |
| 2236 | sum by (region, target, colo_name) ( |
| 2237 | sum_over_time(probe_success{job="abc"}[5m]) |
| 2238 | or |
| 2239 | vector(1) |
| 2240 | )`, 0), // FIXME 0? should be 1 |
| 2241 | IncludedLabels: []string{"region", "target", "colo_name"}, |
| 2242 | FixedLabels: true, |
| 2243 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2244 | "": { |
| 2245 | Reason: "Query is using aggregation with `by(region, target, colo_name)`, only labels included inside `by(...)` will be present on the results.", |
| 2246 | }, |
| 2247 | }, |
| 2248 | IsConditional: true, |
| 2249 | }, |
| 2250 | { |
| 2251 | Type: utils.AggregateSource, |
| 2252 | Returns: promParser.ValueTypeVector, |
| 2253 | Operation: "sum", |
| 2254 | Call: mustParse[*promParser.Call](t, `vector(1)`, 91), |
| 2255 | Aggregation: mustParse[*promParser.AggregateExpr](t, ` |
| 2256 | sum by (region, target, colo_name) ( |
| 2257 | sum_over_time(probe_success{job="abc"}[5m]) |
| 2258 | or |
| 2259 | vector(1) |
| 2260 | )`, 0), // FIXME 0? should be 1 |
| 2261 | FixedLabels: true, |
| 2262 | AlwaysReturns: true, |
| 2263 | KnownReturn: true, |
| 2264 | IsDead: true, |
| 2265 | IsDeadReason: "this query always evaluates to `1 == 0` which is not possible, so it will never return anything", |
| 2266 | ReturnedNumber: 1, |
| 2267 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2268 | "": { |
| 2269 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2270 | }, |
| 2271 | }, |
| 2272 | IsConditional: true, |
| 2273 | }, |
| 2274 | }, |
| 2275 | }, |
| 2276 | { |
| 2277 | expr: `vector(1) or foo`, |
| 2278 | output: []utils.Source{ |
| 2279 | { |
| 2280 | Type: utils.FuncSource, |
| 2281 | Returns: promParser.ValueTypeVector, |
| 2282 | Operation: "vector", |
| 2283 | FixedLabels: true, |
| 2284 | AlwaysReturns: true, |
| 2285 | KnownReturn: true, |
| 2286 | ReturnedNumber: 1, |
| 2287 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2288 | "": { |
| 2289 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2290 | }, |
| 2291 | }, |
| 2292 | Call: mustParse[*promParser.Call](t, "vector(1)", 0), |
| 2293 | }, |
| 2294 | { |
| 2295 | Type: utils.SelectorSource, |
| 2296 | Operation: promParser.CardManyToMany.String(), |
| 2297 | Returns: promParser.ValueTypeVector, |
| 2298 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 13), |
| 2299 | IsDead: true, |
| 2300 | IsDeadReason: "the left hand side always returs something and so the right hand side is never used", |
| 2301 | }, |
| 2302 | }, |
| 2303 | }, |
| 2304 | { |
| 2305 | expr: `vector(0) > 0`, |
| 2306 | output: []utils.Source{ |
| 2307 | { |
| 2308 | Type: utils.FuncSource, |
| 2309 | Returns: promParser.ValueTypeVector, |
| 2310 | Operation: "vector", |
| 2311 | FixedLabels: true, |
| 2312 | AlwaysReturns: true, |
| 2313 | KnownReturn: true, |
| 2314 | ReturnedNumber: 0, |
| 2315 | IsDead: true, |
| 2316 | IsDeadReason: "this query always evaluates to `0 > 0` which is not possible, so it will never return anything", |
| 2317 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2318 | "": { |
| 2319 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2320 | }, |
| 2321 | }, |
| 2322 | Call: mustParse[*promParser.Call](t, "vector(0)", 0), |
| 2323 | IsConditional: true, |
| 2324 | }, |
| 2325 | }, |
| 2326 | }, |
| 2327 | { |
| 2328 | expr: `vector(0) > vector(1)`, |
| 2329 | output: []utils.Source{ |
| 2330 | { |
| 2331 | Type: utils.FuncSource, |
| 2332 | Returns: promParser.ValueTypeVector, |
| 2333 | Operation: "vector", |
| 2334 | FixedLabels: true, |
| 2335 | AlwaysReturns: true, |
| 2336 | KnownReturn: true, |
| 2337 | ReturnedNumber: 0, |
| 2338 | IsDead: true, |
| 2339 | IsDeadReason: "`vector(0) > vector(1)` always evaluates to `0 > 1` which is not possible, so it will never return anything", |
| 2340 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2341 | "": { |
| 2342 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2343 | }, |
| 2344 | }, |
| 2345 | Call: mustParse[*promParser.Call](t, "vector(0)", 0), |
| 2346 | IsConditional: true, |
| 2347 | Joins: []utils.Join{ |
| 2348 | { |
| 2349 | Src: utils.Source{ |
| 2350 | Type: utils.FuncSource, |
| 2351 | Returns: promParser.ValueTypeVector, |
| 2352 | Operation: "vector", |
| 2353 | FixedLabels: true, |
| 2354 | AlwaysReturns: true, |
| 2355 | KnownReturn: true, |
| 2356 | ReturnedNumber: 1, |
| 2357 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2358 | "": { |
| 2359 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2360 | }, |
| 2361 | }, |
| 2362 | Call: mustParse[*promParser.Call](t, "vector(1)", 12), |
| 2363 | }, |
| 2364 | }, |
| 2365 | }, |
| 2366 | }, |
| 2367 | }, |
| 2368 | }, |
| 2369 | { |
| 2370 | expr: `sum(foo or vector(0)) > 0`, |
| 2371 | output: []utils.Source{ |
| 2372 | { |
| 2373 | Type: utils.AggregateSource, |
| 2374 | Returns: promParser.ValueTypeVector, |
| 2375 | Operation: "sum", |
| 2376 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 4), |
| 2377 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo or vector(0))`, 0), |
| 2378 | FixedLabels: true, |
| 2379 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2380 | "": { |
| 2381 | Reason: "Query is using aggregation that removes all labels.", |
| 2382 | }, |
| 2383 | }, |
| 2384 | IsConditional: true, |
| 2385 | }, |
| 2386 | { |
| 2387 | Type: utils.AggregateSource, |
| 2388 | Returns: promParser.ValueTypeVector, |
| 2389 | Operation: "sum", |
| 2390 | Call: mustParse[*promParser.Call](t, `vector(0)`, 11), |
| 2391 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo or vector(0))`, 0), |
| 2392 | FixedLabels: true, |
| 2393 | AlwaysReturns: true, |
| 2394 | KnownReturn: true, |
| 2395 | ReturnedNumber: 0, |
| 2396 | IsDead: true, |
| 2397 | IsDeadReason: "this query always evaluates to `0 > 0` which is not possible, so it will never return anything", |
| 2398 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2399 | "": { |
| 2400 | Reason: "Query is using aggregation that removes all labels.", |
| 2401 | }, |
| 2402 | }, |
| 2403 | IsConditional: true, |
| 2404 | }, |
| 2405 | }, |
| 2406 | }, |
| 2407 | { |
| 2408 | expr: `(sum(foo or vector(1)) > 0) == 2`, |
| 2409 | output: []utils.Source{ |
| 2410 | { |
| 2411 | Type: utils.AggregateSource, |
| 2412 | Returns: promParser.ValueTypeVector, |
| 2413 | Operation: "sum", |
| 2414 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 5), |
| 2415 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo or vector(1))`, 1), |
| 2416 | FixedLabels: true, |
| 2417 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2418 | "": { |
| 2419 | Reason: "Query is using aggregation that removes all labels.", |
| 2420 | }, |
| 2421 | }, |
| 2422 | IsConditional: true, |
| 2423 | }, |
| 2424 | { |
| 2425 | Type: utils.AggregateSource, |
| 2426 | Returns: promParser.ValueTypeVector, |
| 2427 | Operation: "sum", |
| 2428 | Call: mustParse[*promParser.Call](t, `vector(1)`, 12), |
| 2429 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo or vector(1))`, 1), |
| 2430 | FixedLabels: true, |
| 2431 | AlwaysReturns: true, |
| 2432 | KnownReturn: true, |
| 2433 | ReturnedNumber: 1, |
| 2434 | IsDead: true, |
| 2435 | IsDeadReason: "this query always evaluates to `1 == 2` which is not possible, so it will never return anything", |
| 2436 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2437 | "": { |
| 2438 | Reason: "Query is using aggregation that removes all labels.", |
| 2439 | }, |
| 2440 | }, |
| 2441 | IsConditional: true, |
| 2442 | }, |
| 2443 | }, |
| 2444 | }, |
| 2445 | { |
| 2446 | expr: `(sum(foo or vector(1)) > 0) != 2`, |
| 2447 | output: []utils.Source{ |
| 2448 | { |
| 2449 | Type: utils.AggregateSource, |
| 2450 | Returns: promParser.ValueTypeVector, |
| 2451 | Operation: "sum", |
| 2452 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 5), |
| 2453 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo or vector(1))`, 1), |
| 2454 | FixedLabels: true, |
| 2455 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2456 | "": { |
| 2457 | Reason: "Query is using aggregation that removes all labels.", |
| 2458 | }, |
| 2459 | }, |
| 2460 | IsConditional: true, |
| 2461 | }, |
| 2462 | { |
| 2463 | Type: utils.AggregateSource, |
| 2464 | Returns: promParser.ValueTypeVector, |
| 2465 | Operation: "sum", |
| 2466 | Call: mustParse[*promParser.Call](t, `vector(1)`, 12), |
| 2467 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo or vector(1))`, 1), |
| 2468 | FixedLabels: true, |
| 2469 | AlwaysReturns: true, |
| 2470 | KnownReturn: true, |
| 2471 | ReturnedNumber: 1, |
| 2472 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2473 | "": { |
| 2474 | Reason: "Query is using aggregation that removes all labels.", |
| 2475 | }, |
| 2476 | }, |
| 2477 | IsConditional: true, |
| 2478 | }, |
| 2479 | }, |
| 2480 | }, |
| 2481 | { |
| 2482 | expr: `(sum(foo or vector(2)) > 0) != 2`, |
| 2483 | output: []utils.Source{ |
| 2484 | { |
| 2485 | Type: utils.AggregateSource, |
| 2486 | Returns: promParser.ValueTypeVector, |
| 2487 | Operation: "sum", |
| 2488 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 5), |
| 2489 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo or vector(2))`, 1), |
| 2490 | FixedLabels: true, |
| 2491 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2492 | "": { |
| 2493 | Reason: "Query is using aggregation that removes all labels.", |
| 2494 | }, |
| 2495 | }, |
| 2496 | IsConditional: true, |
| 2497 | }, |
| 2498 | { |
| 2499 | Type: utils.AggregateSource, |
| 2500 | Returns: promParser.ValueTypeVector, |
| 2501 | Operation: "sum", |
| 2502 | Call: mustParse[*promParser.Call](t, `vector(2)`, 12), |
| 2503 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo or vector(2))`, 1), |
| 2504 | FixedLabels: true, |
| 2505 | AlwaysReturns: true, |
| 2506 | KnownReturn: true, |
| 2507 | ReturnedNumber: 2, |
| 2508 | IsDead: true, |
| 2509 | IsDeadReason: "this query always evaluates to `2 != 2` which is not possible, so it will never return anything", |
| 2510 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2511 | "": { |
| 2512 | Reason: "Query is using aggregation that removes all labels.", |
| 2513 | }, |
| 2514 | }, |
| 2515 | IsConditional: true, |
| 2516 | }, |
| 2517 | }, |
| 2518 | }, |
| 2519 | { |
| 2520 | expr: `(sum(sometimes{foo!="bar"} or vector(0))) |
| 2521 | or |
| 2522 | ((bob > 10) or sum(foo) or vector(1))`, |
| 2523 | output: []utils.Source{ |
| 2524 | { |
| 2525 | Type: utils.AggregateSource, |
| 2526 | Returns: promParser.ValueTypeVector, |
| 2527 | Operation: "sum", |
| 2528 | Selector: mustParse[*promParser.VectorSelector](t, `sometimes{foo!="bar"}`, 5), |
| 2529 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(sometimes{foo!="bar"} or vector(0) )`, 1), // FIXME extra end |
| 2530 | FixedLabels: true, |
| 2531 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2532 | "": { |
| 2533 | Reason: "Query is using aggregation that removes all labels.", |
| 2534 | Fragment: posrange.PositionRange{Start: 1, End: 1}, // FIXME bogus ) |
| 2535 | }, |
| 2536 | }, |
| 2537 | }, |
| 2538 | { |
| 2539 | Type: utils.AggregateSource, |
| 2540 | Returns: promParser.ValueTypeVector, |
| 2541 | Operation: "sum", |
| 2542 | Call: mustParse[*promParser.Call](t, `vector(0)`, 30), |
| 2543 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(sometimes{foo!="bar"} or vector(0) )`, 1), // FIXME extra end |
| 2544 | AlwaysReturns: true, |
| 2545 | KnownReturn: true, |
| 2546 | ReturnedNumber: 0, |
| 2547 | FixedLabels: true, |
| 2548 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2549 | "": { |
| 2550 | Reason: "Query is using aggregation that removes all labels.", |
| 2551 | Fragment: posrange.PositionRange{Start: 1, End: 1}, // FIXME bogus ) |
| 2552 | }, |
| 2553 | }, |
| 2554 | }, |
| 2555 | { |
| 2556 | Type: utils.SelectorSource, |
| 2557 | Operation: promParser.CardManyToMany.String(), |
| 2558 | Returns: promParser.ValueTypeVector, |
| 2559 | Selector: mustParse[*promParser.VectorSelector](t, `bob`, 47), |
| 2560 | IsConditional: true, |
| 2561 | }, |
| 2562 | { |
| 2563 | Type: utils.AggregateSource, |
| 2564 | Returns: promParser.ValueTypeVector, |
| 2565 | Operation: "sum", |
| 2566 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 64), |
| 2567 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo)`, 60), |
| 2568 | FixedLabels: true, |
| 2569 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2570 | "": { |
| 2571 | Reason: "Query is using aggregation that removes all labels.", |
| 2572 | }, |
| 2573 | }, |
| 2574 | }, |
| 2575 | { |
| 2576 | Type: utils.FuncSource, |
| 2577 | Returns: promParser.ValueTypeVector, |
| 2578 | Operation: "vector", |
| 2579 | AlwaysReturns: true, |
| 2580 | KnownReturn: true, |
| 2581 | ReturnedNumber: 1, |
| 2582 | FixedLabels: true, |
| 2583 | Call: mustParse[*promParser.Call](t, "vector(1)", 72), |
| 2584 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2585 | "": { |
| 2586 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2587 | }, |
| 2588 | }, |
| 2589 | }, |
| 2590 | }, |
| 2591 | }, |
| 2592 | { |
| 2593 | expr: ` |
| 2594 | ( |
| 2595 | sum(sometimes{foo!="bar"}) |
| 2596 | or |
| 2597 | vector(1) |
| 2598 | ) and ( |
| 2599 | ((bob > 10) or sum(bar)) |
| 2600 | or |
| 2601 | notfound > 0 |
| 2602 | )`, |
| 2603 | output: []utils.Source{ |
| 2604 | { |
| 2605 | Type: utils.AggregateSource, |
| 2606 | Returns: promParser.ValueTypeVector, |
| 2607 | Operation: "sum", |
| 2608 | Selector: mustParse[*promParser.VectorSelector](t, `sometimes{foo!="bar"}`, 8), |
| 2609 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(sometimes{foo!="bar"})`, 4), |
| 2610 | FixedLabels: true, |
| 2611 | IsConditional: true, |
| 2612 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2613 | "": { |
| 2614 | Reason: "Query is using aggregation that removes all labels.", |
| 2615 | }, |
| 2616 | }, |
| 2617 | Joins: []utils.Join{ |
| 2618 | { |
| 2619 | Src: utils.Source{ |
| 2620 | Type: utils.SelectorSource, |
| 2621 | Operation: promParser.CardManyToMany.String(), |
| 2622 | Returns: promParser.ValueTypeVector, |
| 2623 | Selector: mustParse[*promParser.VectorSelector](t, `bob`, 57), |
| 2624 | IsConditional: true, |
| 2625 | }, |
| 2626 | }, |
| 2627 | { |
| 2628 | Src: utils.Source{ |
| 2629 | Type: utils.AggregateSource, |
| 2630 | Returns: promParser.ValueTypeVector, |
| 2631 | Operation: "sum", |
| 2632 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 74), |
| 2633 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(bar )`, 70), |
| 2634 | FixedLabels: true, |
| 2635 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2636 | "": { |
| 2637 | Reason: "Query is using aggregation that removes all labels.", |
| 2638 | Fragment: posrange.PositionRange{Start: 1, End: 1}, // FIXME bogus ) |
| 2639 | }, |
| 2640 | }, |
| 2641 | }, |
| 2642 | }, |
| 2643 | { |
| 2644 | Src: utils.Source{ |
| 2645 | Type: utils.SelectorSource, |
| 2646 | Operation: promParser.CardManyToMany.String(), |
| 2647 | Returns: promParser.ValueTypeVector, |
| 2648 | Selector: mustParse[*promParser.VectorSelector](t, `notfound`, 85), |
| 2649 | IsConditional: true, |
| 2650 | }, |
| 2651 | }, |
| 2652 | }, |
| 2653 | }, |
| 2654 | { |
| 2655 | Type: utils.FuncSource, |
| 2656 | Returns: promParser.ValueTypeVector, |
| 2657 | Operation: "vector", |
| 2658 | AlwaysReturns: true, |
| 2659 | KnownReturn: true, |
| 2660 | ReturnedNumber: 1, |
| 2661 | FixedLabels: true, |
| 2662 | IsConditional: true, |
| 2663 | Call: mustParse[*promParser.Call](t, "vector(1)", 36), |
| 2664 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2665 | "": { |
| 2666 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2667 | }, |
| 2668 | }, |
| 2669 | Joins: []utils.Join{ |
| 2670 | { |
| 2671 | Src: utils.Source{ |
| 2672 | Type: utils.SelectorSource, |
| 2673 | Operation: promParser.CardManyToMany.String(), |
| 2674 | Returns: promParser.ValueTypeVector, |
| 2675 | Selector: mustParse[*promParser.VectorSelector](t, `bob`, 57), |
| 2676 | IsConditional: true, |
| 2677 | }, |
| 2678 | }, |
| 2679 | { |
| 2680 | Src: utils.Source{ |
| 2681 | Type: utils.AggregateSource, |
| 2682 | Returns: promParser.ValueTypeVector, |
| 2683 | Operation: "sum", |
| 2684 | Selector: mustParse[*promParser.VectorSelector](t, `bar`, 74), |
| 2685 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(bar )`, 70), // FIXME extra end |
| 2686 | FixedLabels: true, |
| 2687 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2688 | "": { |
| 2689 | Reason: "Query is using aggregation that removes all labels.", |
| 2690 | Fragment: posrange.PositionRange{Start: 1, End: 1}, // FIXME bogus ) |
| 2691 | }, |
| 2692 | }, |
| 2693 | }, |
| 2694 | }, |
| 2695 | { |
| 2696 | Src: utils.Source{ |
| 2697 | Type: utils.SelectorSource, |
| 2698 | Operation: promParser.CardManyToMany.String(), |
| 2699 | Returns: promParser.ValueTypeVector, |
| 2700 | Selector: mustParse[*promParser.VectorSelector](t, `notfound`, 85), |
| 2701 | IsConditional: true, |
| 2702 | }, |
| 2703 | }, |
| 2704 | }, |
| 2705 | }, |
| 2706 | }, |
| 2707 | }, |
| 2708 | { |
| 2709 | expr: "foo offset 5m > 5", |
| 2710 | output: []utils.Source{ |
| 2711 | { |
| 2712 | Type: utils.SelectorSource, |
| 2713 | Returns: promParser.ValueTypeVector, |
| 2714 | Selector: mustParse[*promParser.VectorSelector](t, "foo offset 5m", 0), |
| 2715 | IsConditional: true, |
| 2716 | }, |
| 2717 | }, |
| 2718 | }, |
| 2719 | { |
| 2720 | expr: ` |
| 2721 | (rate(metric2[5m]) or vector(0)) + |
| 2722 | (rate(metric1[5m]) or vector(1)) + |
| 2723 | (rate(metric3{log_name="samplerd"}[5m]) or vector(2)) > 0 |
| 2724 | `, |
| 2725 | output: []utils.Source{ |
| 2726 | { |
| 2727 | Type: utils.FuncSource, |
| 2728 | Operation: "rate", |
| 2729 | Returns: promParser.ValueTypeVector, |
| 2730 | Selector: mustParse[*promParser.VectorSelector](t, "metric2", 7), |
| 2731 | Call: mustParse[*promParser.Call](t, "rate(metric2[5m])", 2), |
| 2732 | IsConditional: true, |
| 2733 | Joins: []utils.Join{ |
| 2734 | { |
| 2735 | Src: utils.Source{ |
| 2736 | Type: utils.FuncSource, |
| 2737 | Operation: "rate", |
| 2738 | Returns: promParser.ValueTypeVector, |
| 2739 | Selector: mustParse[*promParser.VectorSelector](t, "metric1", 42), |
| 2740 | Call: mustParse[*promParser.Call](t, "rate(metric1[5m])", 37), |
| 2741 | }, |
| 2742 | }, |
| 2743 | { |
| 2744 | Src: utils.Source{ |
| 2745 | Type: utils.FuncSource, |
| 2746 | Returns: promParser.ValueTypeVector, |
| 2747 | Operation: "vector", |
| 2748 | AlwaysReturns: true, |
| 2749 | KnownReturn: true, |
| 2750 | ReturnedNumber: 1, |
| 2751 | FixedLabels: true, |
| 2752 | Call: mustParse[*promParser.Call](t, "vector(1)", 58), |
| 2753 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2754 | "": { |
| 2755 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2756 | }, |
| 2757 | }, |
| 2758 | }, |
| 2759 | }, |
| 2760 | { |
| 2761 | Src: utils.Source{ |
| 2762 | Type: utils.FuncSource, |
| 2763 | Operation: "rate", |
| 2764 | Returns: promParser.ValueTypeVector, |
| 2765 | Selector: mustParse[*promParser.VectorSelector](t, `metric3{log_name="samplerd"}`, 77), |
| 2766 | Call: mustParse[*promParser.Call](t, `rate(metric3{log_name="samplerd"}[5m])`, 72), |
| 2767 | GuaranteedLabels: []string{"log_name"}, |
| 2768 | }, |
| 2769 | }, |
| 2770 | { |
| 2771 | Src: utils.Source{ |
| 2772 | Type: utils.FuncSource, |
| 2773 | Returns: promParser.ValueTypeVector, |
| 2774 | Operation: "vector", |
| 2775 | AlwaysReturns: true, |
| 2776 | KnownReturn: true, |
| 2777 | ReturnedNumber: 2, |
| 2778 | FixedLabels: true, |
| 2779 | Call: mustParse[*promParser.Call](t, "vector(2)", 114), |
| 2780 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2781 | "": { |
| 2782 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2783 | }, |
| 2784 | }, |
| 2785 | }, |
| 2786 | }, |
| 2787 | }, |
| 2788 | }, |
| 2789 | { |
| 2790 | Type: utils.FuncSource, |
| 2791 | Returns: promParser.ValueTypeVector, |
| 2792 | Operation: "vector", |
| 2793 | AlwaysReturns: true, |
| 2794 | KnownReturn: true, |
| 2795 | ReturnedNumber: 3, |
| 2796 | FixedLabels: true, |
| 2797 | Call: mustParse[*promParser.Call](t, "vector(0)", 23), |
| 2798 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2799 | "": { |
| 2800 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2801 | }, |
| 2802 | }, |
| 2803 | IsConditional: true, |
| 2804 | Joins: []utils.Join{ |
| 2805 | { |
| 2806 | Src: utils.Source{ |
| 2807 | Type: utils.FuncSource, |
| 2808 | Operation: "rate", |
| 2809 | Returns: promParser.ValueTypeVector, |
| 2810 | Selector: mustParse[*promParser.VectorSelector](t, "metric1", 42), |
| 2811 | Call: mustParse[*promParser.Call](t, "rate(metric1[5m])", 37), |
| 2812 | }, |
| 2813 | }, |
| 2814 | { |
| 2815 | Src: utils.Source{ |
| 2816 | Type: utils.FuncSource, |
| 2817 | Returns: promParser.ValueTypeVector, |
| 2818 | Operation: "vector", |
| 2819 | AlwaysReturns: true, |
| 2820 | KnownReturn: true, |
| 2821 | ReturnedNumber: 1, |
| 2822 | FixedLabels: true, |
| 2823 | Call: mustParse[*promParser.Call](t, "vector(1)", 58), |
| 2824 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2825 | "": { |
| 2826 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2827 | }, |
| 2828 | }, |
| 2829 | }, |
| 2830 | }, |
| 2831 | { |
| 2832 | Src: utils.Source{ |
| 2833 | Type: utils.FuncSource, |
| 2834 | Operation: "rate", |
| 2835 | Returns: promParser.ValueTypeVector, |
| 2836 | Selector: mustParse[*promParser.VectorSelector](t, `metric3{log_name="samplerd"}`, 77), |
| 2837 | Call: mustParse[*promParser.Call](t, `rate(metric3{log_name="samplerd"}[5m])`, 72), |
| 2838 | GuaranteedLabels: []string{"log_name"}, |
| 2839 | }, |
| 2840 | }, |
| 2841 | { |
| 2842 | Src: utils.Source{ |
| 2843 | Type: utils.FuncSource, |
| 2844 | Returns: promParser.ValueTypeVector, |
| 2845 | Operation: "vector", |
| 2846 | AlwaysReturns: true, |
| 2847 | KnownReturn: true, |
| 2848 | ReturnedNumber: 2, |
| 2849 | FixedLabels: true, |
| 2850 | Call: mustParse[*promParser.Call](t, "vector(2)", 114), |
| 2851 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2852 | "": { |
| 2853 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2854 | }, |
| 2855 | }, |
| 2856 | }, |
| 2857 | }, |
| 2858 | }, |
| 2859 | }, |
| 2860 | }, |
| 2861 | }, |
| 2862 | { |
| 2863 | expr: `label_replace(vector(1), "nexthop_tag", "$1", "nexthop", "(.+)")`, |
| 2864 | output: []utils.Source{ |
| 2865 | { |
| 2866 | Type: utils.FuncSource, |
| 2867 | Returns: promParser.ValueTypeVector, |
| 2868 | Operation: "label_replace", |
| 2869 | AlwaysReturns: true, |
| 2870 | KnownReturn: true, |
| 2871 | FixedLabels: true, |
| 2872 | ReturnedNumber: 1, |
| 2873 | GuaranteedLabels: []string{"nexthop_tag"}, |
| 2874 | Call: mustParse[*promParser.Call](t, `label_replace(vector(1), "nexthop_tag", "$1", "nexthop", "(.+)")`, 0), |
| 2875 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2876 | "": { |
| 2877 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2878 | }, |
| 2879 | }, |
| 2880 | }, |
| 2881 | }, |
| 2882 | }, |
| 2883 | { |
| 2884 | expr: `(sum(foo{job="myjob"}))`, |
| 2885 | output: []utils.Source{ |
| 2886 | { |
| 2887 | Type: utils.AggregateSource, |
| 2888 | Returns: promParser.ValueTypeVector, |
| 2889 | Operation: "sum", |
| 2890 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 5), |
| 2891 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{job="myjob"} )`, 1), |
| 2892 | FixedLabels: true, |
| 2893 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2894 | "": { |
| 2895 | Reason: "Query is using aggregation that removes all labels.", |
| 2896 | Fragment: posrange.PositionRange{Start: 1, End: 1}, // FIXME bogus ) |
| 2897 | }, |
| 2898 | }, |
| 2899 | }, |
| 2900 | }, |
| 2901 | }, |
| 2902 | { |
| 2903 | expr: `(-foo{job="myjob"})`, |
| 2904 | output: []utils.Source{ |
| 2905 | { |
| 2906 | Type: utils.SelectorSource, |
| 2907 | Returns: promParser.ValueTypeVector, |
| 2908 | Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 2), |
| 2909 | GuaranteedLabels: []string{"job"}, |
| 2910 | }, |
| 2911 | }, |
| 2912 | }, |
| 2913 | { |
| 2914 | expr: "\n((( group(vector(0)) ))) > 0", |
| 2915 | output: []utils.Source{ |
| 2916 | { |
| 2917 | Type: utils.AggregateSource, |
| 2918 | Operation: "group", |
| 2919 | Returns: promParser.ValueTypeVector, |
| 2920 | FixedLabels: true, |
| 2921 | AlwaysReturns: true, |
| 2922 | KnownReturn: true, |
| 2923 | IsConditional: true, |
| 2924 | IsDead: true, |
| 2925 | IsDeadReason: "this query always evaluates to `0 > 0` which is not possible, so it will never return anything", |
| 2926 | ReturnedNumber: 0, |
| 2927 | Call: mustParse[*promParser.Call](t, `vector(0)`, 11), |
| 2928 | Aggregation: mustParse[*promParser.AggregateExpr](t, "group(vector(0) )", 5), // FIXME |
| 2929 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2930 | "": { |
| 2931 | Reason: "Query is using aggregation that removes all labels.", |
| 2932 | Fragment: posrange.PositionRange{Start: 1, End: 1}, // FIXME bogus ) |
| 2933 | }, |
| 2934 | }, |
| 2935 | }, |
| 2936 | }, |
| 2937 | }, |
| 2938 | { |
| 2939 | expr: "1 > bool 5", |
| 2940 | output: []utils.Source{ |
| 2941 | { |
| 2942 | Type: utils.NumberSource, |
| 2943 | Returns: promParser.ValueTypeScalar, |
| 2944 | FixedLabels: true, |
| 2945 | AlwaysReturns: true, |
| 2946 | KnownReturn: true, |
| 2947 | IsConditional: true, |
| 2948 | IsDead: true, |
| 2949 | IsDeadReason: "this query always evaluates to `1 > 5` which is not possible, so it will never return anything", |
| 2950 | ReturnedNumber: 1, |
| 2951 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2952 | "": { |
| 2953 | Reason: "This query returns a number value with no labels.", |
| 2954 | }, |
| 2955 | }, |
| 2956 | }, |
| 2957 | }, |
| 2958 | }, |
| 2959 | { |
| 2960 | expr: `prometheus_ready{job="prometheus"} unless vector(0)`, |
| 2961 | output: []utils.Source{ |
| 2962 | { |
| 2963 | Type: utils.SelectorSource, |
| 2964 | Operation: promParser.CardManyToMany.String(), |
| 2965 | Returns: promParser.ValueTypeVector, |
| 2966 | Selector: mustParse[*promParser.VectorSelector](t, `prometheus_ready{job="prometheus"}`, 0), |
| 2967 | GuaranteedLabels: []string{"job"}, |
| 2968 | Unless: []utils.Join{ |
| 2969 | { |
| 2970 | Src: utils.Source{ |
| 2971 | Type: utils.FuncSource, |
| 2972 | Returns: promParser.ValueTypeVector, |
| 2973 | Operation: "vector", |
| 2974 | AlwaysReturns: true, |
| 2975 | KnownReturn: true, |
| 2976 | ReturnedNumber: 0, |
| 2977 | FixedLabels: true, |
| 2978 | Call: mustParse[*promParser.Call](t, "vector(0)", 42), |
| 2979 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 2980 | "": { |
| 2981 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 2982 | }, |
| 2983 | }, |
| 2984 | IsDead: true, |
| 2985 | IsDeadReason: "The right hand side will never be matched because it doesn't have the `job` label while the left hand side will. Calling `vector()` will return a vector value with no labels.", |
| 2986 | }, |
| 2987 | }, |
| 2988 | }, |
| 2989 | }, |
| 2990 | }, |
| 2991 | }, |
| 2992 | { |
| 2993 | expr: `prometheus_ready{job="prometheus"} unless on() vector(0)`, |
| 2994 | output: []utils.Source{ |
| 2995 | { |
| 2996 | Type: utils.SelectorSource, |
| 2997 | Operation: promParser.CardManyToMany.String(), |
| 2998 | Returns: promParser.ValueTypeVector, |
| 2999 | IsDead: true, |
| 3000 | IsDeadReason: "this query will never return anything because the `unless` query always returns something", |
| 3001 | Selector: mustParse[*promParser.VectorSelector](t, `prometheus_ready{job="prometheus"}`, 0), |
| 3002 | GuaranteedLabels: []string{"job"}, |
| 3003 | Unless: []utils.Join{ |
| 3004 | { |
| 3005 | Src: utils.Source{ |
| 3006 | Type: utils.FuncSource, |
| 3007 | Returns: promParser.ValueTypeVector, |
| 3008 | Operation: "vector", |
| 3009 | AlwaysReturns: true, |
| 3010 | KnownReturn: true, |
| 3011 | ReturnedNumber: 0, |
| 3012 | FixedLabels: true, |
| 3013 | Call: mustParse[*promParser.Call](t, "vector(0)", 47), |
| 3014 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3015 | "": { |
| 3016 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 3017 | }, |
| 3018 | }, |
| 3019 | }, |
| 3020 | }, |
| 3021 | }, |
| 3022 | }, |
| 3023 | }, |
| 3024 | }, |
| 3025 | { |
| 3026 | expr: `prometheus_ready{job="prometheus"} unless on(job) vector(0)`, |
| 3027 | output: []utils.Source{ |
| 3028 | { |
| 3029 | Type: utils.SelectorSource, |
| 3030 | Operation: promParser.CardManyToMany.String(), |
| 3031 | Returns: promParser.ValueTypeVector, |
| 3032 | Selector: mustParse[*promParser.VectorSelector](t, `prometheus_ready{job="prometheus"}`, 0), |
| 3033 | IncludedLabels: []string{"job"}, |
| 3034 | GuaranteedLabels: []string{"job"}, |
| 3035 | Unless: []utils.Join{ |
| 3036 | { |
| 3037 | Src: utils.Source{ |
| 3038 | Type: utils.FuncSource, |
| 3039 | Returns: promParser.ValueTypeVector, |
| 3040 | Operation: "vector", |
| 3041 | AlwaysReturns: true, |
| 3042 | KnownReturn: true, |
| 3043 | IsDead: true, |
| 3044 | IsDeadReason: "The right hand side will never be matched because it doesn't have the `job` label from `on(...)`. Calling `vector()` will return a vector value with no labels.", |
| 3045 | ReturnedNumber: 0, |
| 3046 | FixedLabels: true, |
| 3047 | Call: mustParse[*promParser.Call](t, "vector(0)", 50), |
| 3048 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3049 | "": { |
| 3050 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 3051 | }, |
| 3052 | }, |
| 3053 | }, |
| 3054 | }, |
| 3055 | }, |
| 3056 | }, |
| 3057 | }, |
| 3058 | }, |
| 3059 | { |
| 3060 | expr: ` |
| 3061 | max by (instance, cluster) (cf_node_role{kubernetes_role="master",role="kubernetes"}) |
| 3062 | unless |
| 3063 | sum by (instance, cluster) (time() - node_systemd_timer_last_trigger_seconds{name=~"etcd-defrag-.*.timer"}) |
| 3064 | * on (instance) group_left (cluster) |
| 3065 | cf_node_role{kubernetes_role="master",role="kubernetes"} |
| 3066 | `, |
| 3067 | output: []utils.Source{ |
| 3068 | { |
| 3069 | Type: utils.AggregateSource, |
| 3070 | Operation: "max", |
| 3071 | Returns: promParser.ValueTypeVector, |
| 3072 | Selector: mustParse[*promParser.VectorSelector](t, `cf_node_role{kubernetes_role="master",role="kubernetes"}`, 29), |
| 3073 | Aggregation: mustParse[*promParser.AggregateExpr](t, `max by (instance, cluster) (cf_node_role{kubernetes_role="master",role="kubernetes"})`, 1), |
| 3074 | FixedLabels: true, |
| 3075 | IncludedLabels: []string{"instance", "cluster"}, |
| 3076 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3077 | "": { |
| 3078 | Reason: "Query is using aggregation with `by(instance, cluster)`, only labels included inside `by(...)` will be present on the results.", |
| 3079 | }, |
| 3080 | }, |
| 3081 | Unless: []utils.Join{ |
| 3082 | { |
| 3083 | Src: utils.Source{ |
| 3084 | Type: utils.AggregateSource, |
| 3085 | Operation: "sum", |
| 3086 | Returns: promParser.ValueTypeVector, |
| 3087 | Selector: mustParse[*promParser.VectorSelector](t, `node_systemd_timer_last_trigger_seconds{name=~"etcd-defrag-.*.timer"}`, 132), |
| 3088 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum by (instance, cluster) (time() - node_systemd_timer_last_trigger_seconds{name=~"etcd-defrag-.*.timer"})`, 95), |
| 3089 | FixedLabels: true, |
| 3090 | IncludedLabels: []string{"instance", "cluster"}, |
| 3091 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3092 | "": { |
| 3093 | Reason: "Query is using aggregation with `by(instance, cluster)`, only labels included inside `by(...)` will be present on the results.", |
| 3094 | }, |
| 3095 | }, |
| 3096 | Joins: []utils.Join{ |
| 3097 | { |
| 3098 | Src: utils.Source{ |
| 3099 | Type: utils.SelectorSource, |
| 3100 | Returns: promParser.ValueTypeVector, |
| 3101 | Selector: mustParse[*promParser.VectorSelector](t, `cf_node_role{kubernetes_role="master",role="kubernetes"}`, 247), |
| 3102 | GuaranteedLabels: []string{"kubernetes_role", "role"}, |
| 3103 | }, |
| 3104 | }, |
| 3105 | }, |
| 3106 | }, |
| 3107 | }, |
| 3108 | }, |
| 3109 | }, |
| 3110 | }, |
| 3111 | }, |
| 3112 | { |
| 3113 | expr: `foo{a="1"} * on() bar{b="2"}`, |
| 3114 | output: []utils.Source{ |
| 3115 | { |
| 3116 | Type: utils.SelectorSource, |
| 3117 | Returns: promParser.ValueTypeVector, |
| 3118 | Operation: promParser.CardOneToOne.String(), |
| 3119 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="1"}`, 0), |
| 3120 | FixedLabels: true, |
| 3121 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3122 | "": { |
| 3123 | Reason: "Query is using one-to-one vector matching with `on()`, only labels included inside `on(...)` will be present on the results.", |
| 3124 | }, |
| 3125 | }, |
| 3126 | Joins: []utils.Join{ |
| 3127 | { |
| 3128 | Src: utils.Source{ |
| 3129 | Type: utils.SelectorSource, |
| 3130 | Returns: promParser.ValueTypeVector, |
| 3131 | GuaranteedLabels: []string{"b"}, |
| 3132 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="2"}`, 18), |
| 3133 | }, |
| 3134 | }, |
| 3135 | }, |
| 3136 | }, |
| 3137 | }, |
| 3138 | }, |
| 3139 | { |
| 3140 | expr: `foo{a="1"} * on(instance) group_left(c,d) bar{b="2"}`, |
| 3141 | output: []utils.Source{ |
| 3142 | { |
| 3143 | Type: utils.SelectorSource, |
| 3144 | Returns: promParser.ValueTypeVector, |
| 3145 | Operation: promParser.CardManyToOne.String(), |
| 3146 | IncludedLabels: []string{"c", "d", "instance"}, |
| 3147 | GuaranteedLabels: []string{"a"}, |
| 3148 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="1"}`, 0), |
| 3149 | Joins: []utils.Join{ |
| 3150 | { |
| 3151 | Src: utils.Source{ |
| 3152 | Type: utils.SelectorSource, |
| 3153 | Returns: promParser.ValueTypeVector, |
| 3154 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="2"}`, 42), |
| 3155 | GuaranteedLabels: []string{"b"}, |
| 3156 | }, |
| 3157 | }, |
| 3158 | }, |
| 3159 | }, |
| 3160 | }, |
| 3161 | }, |
| 3162 | { |
| 3163 | expr: `foo{a="1"} * on(instance) group_right(c,d) bar{b="2"}`, |
| 3164 | output: []utils.Source{ |
| 3165 | { |
| 3166 | Type: utils.SelectorSource, |
| 3167 | Returns: promParser.ValueTypeVector, |
| 3168 | Operation: promParser.CardOneToMany.String(), |
| 3169 | IncludedLabels: []string{"c", "d", "instance"}, |
| 3170 | GuaranteedLabels: []string{"b"}, |
| 3171 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="2"}`, 43), |
| 3172 | Joins: []utils.Join{ |
| 3173 | { |
| 3174 | Src: utils.Source{ |
| 3175 | Type: utils.SelectorSource, |
| 3176 | Returns: promParser.ValueTypeVector, |
| 3177 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="1"}`, 0), |
| 3178 | GuaranteedLabels: []string{"a"}, |
| 3179 | }, |
| 3180 | }, |
| 3181 | }, |
| 3182 | }, |
| 3183 | }, |
| 3184 | }, |
| 3185 | { |
| 3186 | expr: `foo{a="1"} * on(instance) sum(bar{b="2"})`, |
| 3187 | output: []utils.Source{ |
| 3188 | { |
| 3189 | Type: utils.SelectorSource, |
| 3190 | Returns: promParser.ValueTypeVector, |
| 3191 | Operation: promParser.CardOneToOne.String(), |
| 3192 | IncludedLabels: []string{"instance"}, |
| 3193 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="1"}`, 0), |
| 3194 | FixedLabels: true, |
| 3195 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3196 | "": { |
| 3197 | Reason: "Query is using one-to-one vector matching with `on(instance)`, only labels included inside `on(...)` will be present on the results.", |
| 3198 | }, |
| 3199 | }, |
| 3200 | Joins: []utils.Join{ |
| 3201 | { |
| 3202 | Src: utils.Source{ |
| 3203 | Type: utils.AggregateSource, |
| 3204 | Operation: "sum", |
| 3205 | Returns: promParser.ValueTypeVector, |
| 3206 | FixedLabels: true, |
| 3207 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="2"}`, 30), |
| 3208 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(bar{b="2"})`, 26), |
| 3209 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3210 | "": { |
| 3211 | Reason: "Query is using aggregation that removes all labels.", |
| 3212 | }, |
| 3213 | }, |
| 3214 | IsDead: true, |
| 3215 | IsDeadReason: "The right hand side will never be matched because it doesn't have the `instance` label from `on(...)`. Query is using aggregation that removes all labels.", |
| 3216 | }, |
| 3217 | }, |
| 3218 | }, |
| 3219 | }, |
| 3220 | }, |
| 3221 | }, |
| 3222 | { |
| 3223 | expr: `foo{a="1"} * on(instance) group_left(c,d) sum(bar{b="2"})`, |
| 3224 | output: []utils.Source{ |
| 3225 | { |
| 3226 | Type: utils.SelectorSource, |
| 3227 | Returns: promParser.ValueTypeVector, |
| 3228 | Operation: promParser.CardManyToOne.String(), |
| 3229 | IncludedLabels: []string{"c", "d", "instance"}, |
| 3230 | GuaranteedLabels: []string{"a"}, |
| 3231 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="1"}`, 0), |
| 3232 | Joins: []utils.Join{ |
| 3233 | { |
| 3234 | Src: utils.Source{ |
| 3235 | Type: utils.AggregateSource, |
| 3236 | Operation: "sum", |
| 3237 | Returns: promParser.ValueTypeVector, |
| 3238 | FixedLabels: true, |
| 3239 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="2"}`, 46), |
| 3240 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(bar{b="2"})`, 42), |
| 3241 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3242 | "": { |
| 3243 | Reason: "Query is using aggregation that removes all labels.", |
| 3244 | }, |
| 3245 | }, |
| 3246 | IsDead: true, |
| 3247 | IsDeadReason: "The right hand side will never be matched because it doesn't have the `instance` label from `on(...)`. Query is using aggregation that removes all labels.", |
| 3248 | }, |
| 3249 | }, |
| 3250 | }, |
| 3251 | }, |
| 3252 | }, |
| 3253 | }, |
| 3254 | { |
| 3255 | expr: `sum(foo{a="1"}) * on(instance) group_right(c,d) bar{b="2"}`, |
| 3256 | output: []utils.Source{ |
| 3257 | { |
| 3258 | Type: utils.SelectorSource, |
| 3259 | Returns: promParser.ValueTypeVector, |
| 3260 | Operation: promParser.CardOneToMany.String(), |
| 3261 | IncludedLabels: []string{"c", "d", "instance"}, |
| 3262 | GuaranteedLabels: []string{"b"}, |
| 3263 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="2"}`, 48), |
| 3264 | Joins: []utils.Join{ |
| 3265 | { |
| 3266 | Src: utils.Source{ |
| 3267 | Type: utils.AggregateSource, |
| 3268 | Operation: "sum", |
| 3269 | Returns: promParser.ValueTypeVector, |
| 3270 | FixedLabels: true, |
| 3271 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="1"}`, 4), |
| 3272 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{a="1"})`, 0), |
| 3273 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3274 | "": { |
| 3275 | Reason: "Query is using aggregation that removes all labels.", |
| 3276 | }, |
| 3277 | }, |
| 3278 | IsDead: true, |
| 3279 | IsDeadReason: "The left hand side will never be matched because it doesn't have the `instance` label from `on(...)`. Query is using aggregation that removes all labels.", |
| 3280 | }, |
| 3281 | }, |
| 3282 | }, |
| 3283 | }, |
| 3284 | }, |
| 3285 | }, |
| 3286 | { |
| 3287 | expr: `foo{a="1"} * on(instance) group_left(c,d) sum(bar{b="2"}) without(instance)`, |
| 3288 | output: []utils.Source{ |
| 3289 | { |
| 3290 | Type: utils.SelectorSource, |
| 3291 | Returns: promParser.ValueTypeVector, |
| 3292 | Operation: promParser.CardManyToOne.String(), |
| 3293 | IncludedLabels: []string{"c", "d", "instance"}, |
| 3294 | GuaranteedLabels: []string{"a"}, |
| 3295 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="1"}`, 0), |
| 3296 | Joins: []utils.Join{ |
| 3297 | { |
| 3298 | Src: utils.Source{ |
| 3299 | Type: utils.AggregateSource, |
| 3300 | Operation: "sum", |
| 3301 | Returns: promParser.ValueTypeVector, |
| 3302 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="2"}`, 46), |
| 3303 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(bar{b="2"}) without(instance)`, 42), |
| 3304 | GuaranteedLabels: []string{"b"}, |
| 3305 | ExcludedLabels: []string{"instance"}, |
| 3306 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3307 | "instance": { |
| 3308 | Reason: "Query is using aggregation with `without(instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 3309 | }, |
| 3310 | }, |
| 3311 | IsDead: true, |
| 3312 | IsDeadReason: "The right hand side will never be matched because it doesn't have the `instance` label from `on(...)`. Query is using aggregation with `without(instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 3313 | }, |
| 3314 | }, |
| 3315 | }, |
| 3316 | }, |
| 3317 | }, |
| 3318 | }, |
| 3319 | { |
| 3320 | expr: `sum(foo{a="1"}) without(instance) * on(instance) group_right(c,d) bar{b="2"}`, |
| 3321 | output: []utils.Source{ |
| 3322 | { |
| 3323 | Type: utils.SelectorSource, |
| 3324 | Returns: promParser.ValueTypeVector, |
| 3325 | Operation: promParser.CardOneToMany.String(), |
| 3326 | IncludedLabels: []string{"c", "d", "instance"}, |
| 3327 | GuaranteedLabels: []string{"b"}, |
| 3328 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="2"}`, 66), |
| 3329 | Joins: []utils.Join{ |
| 3330 | { |
| 3331 | Src: utils.Source{ |
| 3332 | Type: utils.AggregateSource, |
| 3333 | Operation: "sum", |
| 3334 | Returns: promParser.ValueTypeVector, |
| 3335 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="1"}`, 4), |
| 3336 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{a="1"}) without(instance)`, 0), |
| 3337 | GuaranteedLabels: []string{"a"}, |
| 3338 | ExcludedLabels: []string{"instance"}, |
| 3339 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3340 | "instance": { |
| 3341 | Reason: "Query is using aggregation with `without(instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 3342 | }, |
| 3343 | }, |
| 3344 | IsDead: true, |
| 3345 | IsDeadReason: "The left hand side will never be matched because it doesn't have the `instance` label from `on(...)`. Query is using aggregation with `without(instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 3346 | }, |
| 3347 | }, |
| 3348 | }, |
| 3349 | }, |
| 3350 | }, |
| 3351 | }, |
| 3352 | { |
| 3353 | expr: ` |
| 3354 | max without (source_instance) ( |
| 3355 | increase(kernel_device_io_errors_total{device!~"loop.+"}[120m]) > 3 unless on(instance, device) ( |
| 3356 | increase(kernel_device_io_soft_errors_total{device!~"loop.+"}[125m])*2 > increase(kernel_device_io_errors_total[120m]) |
| 3357 | ) |
| 3358 | and on(device, instance) absent(node_disk_info) |
| 3359 | ) * on(instance) group_left(group) label_replace(salt_highstate_runner_configured_minions, "instance", "$1", "minion", "(.+)") |
| 3360 | `, |
| 3361 | output: []utils.Source{ |
| 3362 | { |
| 3363 | Type: utils.AggregateSource, |
| 3364 | Returns: promParser.ValueTypeVector, |
| 3365 | Operation: "max", |
| 3366 | Selector: mustParse[*promParser.VectorSelector](t, `kernel_device_io_errors_total{device!~"loop.+"}`, 46), |
| 3367 | Call: mustParse[*promParser.Call](t, `increase(kernel_device_io_errors_total{device!~"loop.+"}[120m])`, 37), |
| 3368 | Aggregation: mustParse[*promParser.AggregateExpr](t, |
| 3369 | `max without (source_instance) ( |
| 3370 | increase(kernel_device_io_errors_total{device!~"loop.+"}[120m]) > 3 unless on(instance, device) ( |
| 3371 | increase(kernel_device_io_soft_errors_total{device!~"loop.+"}[125m])*2 > increase(kernel_device_io_errors_total[120m]) |
| 3372 | ) |
| 3373 | and on(device, instance) absent(node_disk_info) |
| 3374 | )`, 2), |
| 3375 | IsConditional: true, |
| 3376 | IncludedLabels: []string{"instance", "device", "group"}, |
| 3377 | ExcludedLabels: []string{"source_instance"}, |
| 3378 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3379 | "source_instance": { |
| 3380 | Reason: "Query is using aggregation with `without(source_instance)`, all labels included inside `without(...)` will be removed from the results.", |
| 3381 | }, |
| 3382 | }, |
| 3383 | Joins: []utils.Join{ |
| 3384 | { |
| 3385 | Src: utils.Source{ |
| 3386 | Type: utils.FuncSource, |
| 3387 | Returns: promParser.ValueTypeVector, |
| 3388 | Operation: "absent", |
| 3389 | FixedLabels: true, |
| 3390 | Selector: mustParse[*promParser.VectorSelector](t, `node_disk_info`, 299), |
| 3391 | Call: mustParse[*promParser.Call](t, `absent(node_disk_info)`, 292), |
| 3392 | IsDead: true, |
| 3393 | IsDeadReason: "The right hand side will never be matched because it doesn't have the `device` label from `on(...)`. The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 3394 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3395 | "": { |
| 3396 | Reason: "The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series.\nYou will only get any results back if the metric selector you pass doesn't match anything.\nSince there are no matching time series there are also no labels. If some time series is missing you cannot read its labels.\nThis means that the only labels you can get back from absent call are the ones you pass to it.\nIf you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the `up` metric instead.", |
| 3397 | }, |
| 3398 | }, |
| 3399 | }, |
| 3400 | }, |
| 3401 | { |
| 3402 | Src: utils.Source{ |
| 3403 | Type: utils.FuncSource, |
| 3404 | Returns: promParser.ValueTypeVector, |
| 3405 | Operation: "label_replace", |
| 3406 | GuaranteedLabels: []string{"instance"}, |
| 3407 | Selector: mustParse[*promParser.VectorSelector](t, `salt_highstate_runner_configured_minions`, 365), |
| 3408 | Call: mustParse[*promParser.Call](t, `label_replace(salt_highstate_runner_configured_minions, "instance", "$1", "minion", "(.+)")`, 351), |
| 3409 | }, |
| 3410 | }, |
| 3411 | }, |
| 3412 | Unless: []utils.Join{ |
| 3413 | { |
| 3414 | Src: utils.Source{ |
| 3415 | Type: utils.FuncSource, |
| 3416 | Returns: promParser.ValueTypeVector, |
| 3417 | Operation: "increase", |
| 3418 | IsConditional: true, |
| 3419 | Selector: mustParse[*promParser.VectorSelector](t, `kernel_device_io_soft_errors_total{device!~"loop.+"}`, 149), |
| 3420 | Call: mustParse[*promParser.Call](t, `increase(kernel_device_io_soft_errors_total{device!~"loop.+"}[125m])`, 140), |
| 3421 | Joins: []utils.Join{ |
| 3422 | { |
| 3423 | Src: utils.Source{ |
| 3424 | Type: utils.FuncSource, |
| 3425 | Returns: promParser.ValueTypeVector, |
| 3426 | Operation: "increase", |
| 3427 | Selector: mustParse[*promParser.VectorSelector](t, `kernel_device_io_errors_total`, 222), |
| 3428 | Call: mustParse[*promParser.Call](t, `increase(kernel_device_io_errors_total[120m])`, 213), |
| 3429 | }, |
| 3430 | }, |
| 3431 | }, |
| 3432 | }, |
| 3433 | }, |
| 3434 | }, |
| 3435 | }, |
| 3436 | }, |
| 3437 | }, |
| 3438 | { |
| 3439 | expr: `sum(foo{a="1"}) by(job) * on() bar{b="2"}`, |
| 3440 | output: []utils.Source{ |
| 3441 | { |
| 3442 | Type: utils.AggregateSource, |
| 3443 | Returns: promParser.ValueTypeVector, |
| 3444 | Operation: "sum", |
| 3445 | Selector: mustParse[*promParser.VectorSelector](t, `foo{a="1"}`, 4), |
| 3446 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(foo{a="1"}) by(job)`, 0), |
| 3447 | FixedLabels: true, |
| 3448 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3449 | "": { |
| 3450 | Reason: "Query is using one-to-one vector matching with `on()`, only labels included inside `on(...)` will be present on the results.", |
| 3451 | }, |
| 3452 | }, |
| 3453 | Joins: []utils.Join{ |
| 3454 | { |
| 3455 | Src: utils.Source{ |
| 3456 | Type: utils.SelectorSource, |
| 3457 | Returns: promParser.ValueTypeVector, |
| 3458 | GuaranteedLabels: []string{"b"}, |
| 3459 | Selector: mustParse[*promParser.VectorSelector](t, `bar{b="2"}`, 31), |
| 3460 | }, |
| 3461 | }, |
| 3462 | }, |
| 3463 | }, |
| 3464 | }, |
| 3465 | }, |
| 3466 | { |
| 3467 | expr: `sum(sum(foo) without(job)) by(job)`, |
| 3468 | output: []utils.Source{ |
| 3469 | { |
| 3470 | Type: utils.AggregateSource, |
| 3471 | Returns: promParser.ValueTypeVector, |
| 3472 | Operation: "sum", |
| 3473 | Selector: mustParse[*promParser.VectorSelector](t, `foo`, 8), |
| 3474 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum(sum(foo) without(job)) by(job)`, 0), |
| 3475 | FixedLabels: true, |
| 3476 | ExcludedLabels: []string{"job"}, |
| 3477 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3478 | "": { |
| 3479 | Reason: "Query is using aggregation with `by(job)`, only labels included inside `by(...)` will be present on the results.", |
| 3480 | }, |
| 3481 | "job": { |
| 3482 | Reason: "Query is using aggregation with `without(job)`, all labels included inside `without(...)` will be removed from the results.", |
| 3483 | }, |
| 3484 | }, |
| 3485 | }, |
| 3486 | }, |
| 3487 | }, |
| 3488 | { |
| 3489 | expr: ` |
| 3490 | prometheus:scrape_series_added:since_gc:sum |
| 3491 | * on(prometheus) group_left() |
| 3492 | label_replace( |
| 3493 | max(max_over_time(go_memstats_alloc_bytes{job="prometheus"}[2h])) by(instance) |
| 3494 | / |
| 3495 | max(max_over_time(prometheus_tsdb_head_series[2h])) by(instance), |
| 3496 | "prometheus", "$1", |
| 3497 | "instance", "(.+)" |
| 3498 | ) |
| 3499 | `, |
| 3500 | output: []utils.Source{ |
| 3501 | { |
| 3502 | Type: utils.SelectorSource, |
| 3503 | Returns: promParser.ValueTypeVector, |
| 3504 | Operation: promParser.CardManyToOne.String(), |
| 3505 | Selector: mustParse[*promParser.VectorSelector](t, `prometheus:scrape_series_added:since_gc:sum`, 1), |
| 3506 | IncludedLabels: []string{"prometheus"}, |
| 3507 | Joins: []utils.Join{ |
| 3508 | { |
| 3509 | Src: utils.Source{ |
| 3510 | Type: utils.FuncSource, |
| 3511 | Returns: promParser.ValueTypeVector, |
| 3512 | Operation: "label_replace", |
| 3513 | Selector: mustParse[*promParser.VectorSelector](t, `go_memstats_alloc_bytes{job="prometheus"}`, 110), |
| 3514 | Call: mustParse[*promParser.Call](t, `label_replace( |
| 3515 | max(max_over_time(go_memstats_alloc_bytes{job="prometheus"}[2h])) by(instance) |
| 3516 | / |
| 3517 | max(max_over_time(prometheus_tsdb_head_series[2h])) by(instance), |
| 3518 | "prometheus", "$1", |
| 3519 | "instance", "(.+)" |
| 3520 | )`, 75), |
| 3521 | Aggregation: mustParse[*promParser.AggregateExpr](t, `max(max_over_time(go_memstats_alloc_bytes{job="prometheus"}[2h])) by(instance)`, 92), |
| 3522 | GuaranteedLabels: []string{"prometheus"}, |
| 3523 | IncludedLabels: []string{"instance"}, |
| 3524 | FixedLabels: true, |
| 3525 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3526 | "": { |
| 3527 | Reason: "Query is using aggregation with `by(instance)`, only labels included inside `by(...)` will be present on the results.", |
| 3528 | }, |
| 3529 | }, |
| 3530 | Joins: []utils.Join{ |
| 3531 | { |
| 3532 | Src: utils.Source{ |
| 3533 | Type: utils.AggregateSource, |
| 3534 | Returns: promParser.ValueTypeVector, |
| 3535 | Operation: "max", |
| 3536 | Selector: mustParse[*promParser.VectorSelector](t, `prometheus_tsdb_head_series`, 195), |
| 3537 | Call: mustParse[*promParser.Call](t, `max_over_time(prometheus_tsdb_head_series[2h])`, 181), |
| 3538 | Aggregation: mustParse[*promParser.AggregateExpr](t, `max(max_over_time(prometheus_tsdb_head_series[2h])) by(instance)`, 177), |
| 3539 | IncludedLabels: []string{"instance"}, |
| 3540 | FixedLabels: true, |
| 3541 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3542 | "": { |
| 3543 | Reason: "Query is using aggregation with `by(instance)`, only labels included inside `by(...)` will be present on the results.", |
| 3544 | }, |
| 3545 | }, |
| 3546 | }, |
| 3547 | }, |
| 3548 | }, |
| 3549 | }, |
| 3550 | }, |
| 3551 | }, |
| 3552 | }, |
| 3553 | }, |
| 3554 | }, |
| 3555 | { |
| 3556 | expr: `(day_of_week() == 6 and hour() < 1) or vector(1)`, |
| 3557 | output: []utils.Source{ |
| 3558 | { |
| 3559 | Type: utils.FuncSource, |
| 3560 | Returns: promParser.ValueTypeVector, |
| 3561 | Operation: "day_of_week", |
| 3562 | Call: mustParse[*promParser.Call](t, `day_of_week()`, 1), |
| 3563 | FixedLabels: true, |
| 3564 | AlwaysReturns: true, |
| 3565 | IsConditional: true, |
| 3566 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3567 | "": { |
| 3568 | Reason: "Calling `day_of_week()` with no arguments will return an empty time series with no labels.", |
| 3569 | }, |
| 3570 | }, |
| 3571 | Joins: []utils.Join{ |
| 3572 | { |
| 3573 | Src: utils.Source{ |
| 3574 | Type: utils.FuncSource, |
| 3575 | Returns: promParser.ValueTypeVector, |
| 3576 | Operation: "hour", |
| 3577 | Call: mustParse[*promParser.Call](t, `hour()`, 24), |
| 3578 | FixedLabels: true, |
| 3579 | AlwaysReturns: true, |
| 3580 | IsConditional: true, |
| 3581 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3582 | "": { |
| 3583 | Reason: "Calling `hour()` with no arguments will return an empty time series with no labels.", |
| 3584 | }, |
| 3585 | }, |
| 3586 | }, |
| 3587 | }, |
| 3588 | }, |
| 3589 | }, |
| 3590 | { |
| 3591 | Type: utils.FuncSource, |
| 3592 | Returns: promParser.ValueTypeVector, |
| 3593 | Operation: "vector", |
| 3594 | AlwaysReturns: true, |
| 3595 | KnownReturn: true, |
| 3596 | ReturnedNumber: 1, |
| 3597 | FixedLabels: true, |
| 3598 | Call: mustParse[*promParser.Call](t, "vector(1)", 39), |
| 3599 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3600 | "": { |
| 3601 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 3602 | }, |
| 3603 | }, |
| 3604 | }, |
| 3605 | }, |
| 3606 | }, |
| 3607 | { |
| 3608 | expr: ` |
| 3609 | sum by (foo, bar) ( |
| 3610 | rate(errors_total[5m]) |
| 3611 | * on (instance) group_left (bob, alice) |
| 3612 | server_errors_total |
| 3613 | )`, |
| 3614 | output: []utils.Source{ |
| 3615 | { |
| 3616 | Type: utils.AggregateSource, |
| 3617 | Returns: promParser.ValueTypeVector, |
| 3618 | Operation: "sum", |
| 3619 | Aggregation: mustParse[*promParser.AggregateExpr](t, `sum by (foo, bar) ( |
| 3620 | rate(errors_total[5m]) |
| 3621 | * on (instance) group_left (bob, alice) |
| 3622 | server_errors_total |
| 3623 | )`, 1), |
| 3624 | Call: mustParse[*promParser.Call](t, "rate(errors_total[5m])", 25), |
| 3625 | Selector: mustParse[*promParser.VectorSelector](t, "errors_total", 30), |
| 3626 | FixedLabels: true, |
| 3627 | IncludedLabels: []string{"foo", "bar"}, |
| 3628 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3629 | "": { |
| 3630 | Reason: "Query is using aggregation with `by(foo, bar)`, only labels included inside `by(...)` will be present on the results.", |
| 3631 | }, |
| 3632 | }, |
| 3633 | Joins: []utils.Join{ |
| 3634 | { |
| 3635 | Src: utils.Source{ |
| 3636 | Type: utils.SelectorSource, |
| 3637 | Returns: promParser.ValueTypeVector, |
| 3638 | Selector: mustParse[*promParser.VectorSelector](t, "server_errors_total", 94), |
| 3639 | }, |
| 3640 | }, |
| 3641 | }, |
| 3642 | }, |
| 3643 | }, |
| 3644 | }, |
| 3645 | { |
| 3646 | expr: `1 - (foo or vector(0)) < 0.999`, |
| 3647 | output: []utils.Source{ |
| 3648 | { |
| 3649 | Type: utils.SelectorSource, |
| 3650 | Returns: promParser.ValueTypeVector, |
| 3651 | Operation: promParser.CardManyToMany.String(), |
| 3652 | IsConditional: true, |
| 3653 | Selector: mustParse[*promParser.VectorSelector](t, "foo", 5), |
| 3654 | }, |
| 3655 | { |
| 3656 | Type: utils.FuncSource, |
| 3657 | Returns: promParser.ValueTypeVector, |
| 3658 | Operation: "vector", |
| 3659 | AlwaysReturns: true, |
| 3660 | IsConditional: true, |
| 3661 | FixedLabels: true, |
| 3662 | IsDead: true, |
| 3663 | KnownReturn: true, |
| 3664 | ReturnedNumber: 1, |
| 3665 | IsDeadReason: "this query always evaluates to `1 < 0.999` which is not possible, so it will never return anything", |
| 3666 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3667 | "": { |
| 3668 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 3669 | }, |
| 3670 | }, |
| 3671 | Call: mustParse[*promParser.Call](t, "vector(0)", 12), |
| 3672 | }, |
| 3673 | }, |
| 3674 | }, |
| 3675 | { |
| 3676 | expr: ` |
| 3677 | ( |
| 3678 | vector(1) and month() == 2 |
| 3679 | ) or vector(0) |
| 3680 | `, |
| 3681 | output: []utils.Source{ |
| 3682 | { |
| 3683 | Type: utils.FuncSource, |
| 3684 | Returns: promParser.ValueTypeVector, |
| 3685 | Operation: "vector", |
| 3686 | AlwaysReturns: true, |
| 3687 | IsConditional: true, |
| 3688 | FixedLabels: true, |
| 3689 | KnownReturn: true, |
| 3690 | ReturnedNumber: 1, |
| 3691 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3692 | "": { |
| 3693 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 3694 | }, |
| 3695 | }, |
| 3696 | Call: mustParse[*promParser.Call](t, "vector(1)", 5), |
| 3697 | Joins: []utils.Join{ |
| 3698 | { |
| 3699 | Src: utils.Source{ |
| 3700 | Type: utils.FuncSource, |
| 3701 | Returns: promParser.ValueTypeVector, |
| 3702 | Operation: "month", |
| 3703 | AlwaysReturns: true, |
| 3704 | FixedLabels: true, |
| 3705 | IsConditional: true, |
| 3706 | Call: mustParse[*promParser.Call](t, "month()", 19), |
| 3707 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3708 | "": { |
| 3709 | Reason: "Calling `month()` with no arguments will return an empty time series with no labels.", |
| 3710 | }, |
| 3711 | }, |
| 3712 | }, |
| 3713 | }, |
| 3714 | }, |
| 3715 | }, |
| 3716 | { |
| 3717 | Type: utils.FuncSource, |
| 3718 | Returns: promParser.ValueTypeVector, |
| 3719 | Operation: "vector", |
| 3720 | AlwaysReturns: true, |
| 3721 | FixedLabels: true, |
| 3722 | KnownReturn: true, |
| 3723 | ReturnedNumber: 0, |
| 3724 | ExcludeReason: map[string]utils.ExcludedLabel{ |
| 3725 | "": { |
| 3726 | Reason: "Calling `vector()` will return a vector value with no labels.", |
| 3727 | }, |
| 3728 | }, |
| 3729 | Call: mustParse[*promParser.Call](t, "vector(0)", 37), |
| 3730 | }, |
| 3731 | }, |
| 3732 | }, |
| 3733 | } |
| 3734 | |
| 3735 | for _, tc := range testCases { |
| 3736 | t.Run(tc.expr, func(t *testing.T) { |
| 3737 | n, err := parser.DecodeExpr(tc.expr) |
| 3738 | if err != nil { |
| 3739 | t.Error(err) |
| 3740 | t.FailNow() |
| 3741 | } |
| 3742 | output := utils.LabelsSource(tc.expr, n.Expr) |
| 3743 | require.Len(t, output, len(tc.output)) |
| 3744 | if diff := cmp.Diff(tc.output, output, |
| 3745 | cmpopts.EquateNaNs(), |
| 3746 | cmpopts.IgnoreUnexported(labels.Matcher{}), |
| 3747 | cmpopts.IgnoreFields(utils.ExcludedLabel{}, "Fragment"), |
| 3748 | cmpopts.IgnoreFields(utils.Source{}, "Position"), |
| 3749 | ); diff != "" { |
| 3750 | t.Errorf("utils.LabelsSource() returned wrong output (-want +got):\n%s", diff) |
| 3751 | return |
| 3752 | } |
| 3753 | }) |
| 3754 | } |
| 3755 | } |
| 3756 | |
| 3757 | func TestLabelsSourceCallCoverage(t *testing.T) { |
| 3758 | for name, def := range promParser.Functions { |
| 3759 | t.Run(name, func(t *testing.T) { |
| 3760 | if def.Experimental { |
| 3761 | t.SkipNow() |
| 3762 | } |
| 3763 | |
| 3764 | var b strings.Builder |
| 3765 | b.WriteString(name) |
| 3766 | b.WriteRune('(') |
| 3767 | for i, at := range def.ArgTypes { |
| 3768 | if i > 0 { |
| 3769 | b.WriteString(", ") |
| 3770 | } |
| 3771 | switch at { |
| 3772 | case promParser.ValueTypeNone: |
| 3773 | case promParser.ValueTypeScalar: |
| 3774 | b.WriteRune('1') |
| 3775 | case promParser.ValueTypeVector: |
| 3776 | b.WriteString("http_requests_total") |
| 3777 | case promParser.ValueTypeMatrix: |
| 3778 | b.WriteString("http_requests_total[2m]") |
| 3779 | case promParser.ValueTypeString: |
| 3780 | b.WriteString(`"foo"`) |
| 3781 | } |
| 3782 | } |
| 3783 | b.WriteRune(')') |
| 3784 | |
| 3785 | n, err := parser.DecodeExpr(b.String()) |
| 3786 | if err != nil { |
| 3787 | t.Error(err) |
| 3788 | t.FailNow() |
| 3789 | } |
| 3790 | output := utils.LabelsSource(b.String(), n.Expr) |
| 3791 | require.Len(t, output, 1) |
| 3792 | require.NotNil(t, output[0].Call, "no call detected in: %q ~> %+v", b.String(), output) |
| 3793 | require.Equal(t, name, output[0].Operation) |
| 3794 | require.Equal(t, def.ReturnType, output[0].Returns, "incorrect return type on Source{}") |
| 3795 | }) |
| 3796 | } |
| 3797 | } |
| 3798 | |
| 3799 | func TestLabelsSourceCallCoverageFail(t *testing.T) { |
| 3800 | n := &parser.PromQLNode{ |
| 3801 | Expr: &promParser.Call{ |
| 3802 | Func: &promParser.Function{ |
| 3803 | Name: "fake_call", |
| 3804 | }, |
| 3805 | }, |
| 3806 | } |
| 3807 | output := utils.LabelsSource("fake_call()", n.Expr) |
| 3808 | require.Len(t, output, 1) |
| 3809 | require.Nil(t, output[0].Call, "no call should have been detected in fake function") |
| 3810 | } |
| 3811 | |
| 3812 | func TestSourceFragment(t *testing.T) { |
| 3813 | type testCaseT struct { |
| 3814 | expr string |
| 3815 | fragments []string |
| 3816 | } |
| 3817 | |
| 3818 | testCases := []testCaseT{ |
| 3819 | { |
| 3820 | expr: "1", |
| 3821 | fragments: []string{""}, |
| 3822 | }, |
| 3823 | { |
| 3824 | expr: `"foo"`, |
| 3825 | fragments: []string{""}, |
| 3826 | }, |
| 3827 | { |
| 3828 | expr: `foo`, |
| 3829 | fragments: []string{"foo"}, |
| 3830 | }, |
| 3831 | { |
| 3832 | expr: `foo{job="bar"}`, |
| 3833 | fragments: []string{`foo{job="bar"}`}, |
| 3834 | }, |
| 3835 | { |
| 3836 | expr: `rate(foo{job="bar"}[5m])`, |
| 3837 | fragments: []string{`rate(foo{job="bar"}[5m])`}, |
| 3838 | }, |
| 3839 | { |
| 3840 | expr: `sum(foo{job="bar"})`, |
| 3841 | fragments: []string{`sum(foo{job="bar"})`}, |
| 3842 | }, |
| 3843 | } |
| 3844 | |
| 3845 | for _, tc := range testCases { |
| 3846 | t.Run(tc.expr, func(t *testing.T) { |
| 3847 | n, err := parser.DecodeExpr(tc.expr) |
| 3848 | if err != nil { |
| 3849 | t.Error(err) |
| 3850 | t.FailNow() |
| 3851 | } |
| 3852 | var got []string |
| 3853 | for _, src := range utils.LabelsSource(tc.expr, n.Expr) { |
| 3854 | got = append(got, src.Fragment(tc.expr)) |
| 3855 | } |
| 3856 | require.Equal(t, tc.fragments, got) |
| 3857 | }) |
| 3858 | } |
| 3859 | } |
| 3860 | |