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