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