github.com/influxdata/influxdb/v2@v2.7.6/influxql/v1tests/server_test.go (about) 1 package v1tests 2 3 import ( 4 "context" 5 "fmt" 6 "net/url" 7 "strconv" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/influxdata/influxdb/v2" 13 "github.com/influxdata/influxdb/v2/cmd/influxd/launcher" 14 "github.com/influxdata/influxdb/v2/models" 15 "github.com/stretchr/testify/require" 16 ) 17 18 const ( 19 NeedsReview = "Needs review" // Test requires further review 20 NotSupported = "Not supported" // Test exercises features not supported in Cloud 2 21 SkippedOSS = "Skipped OSS" // Test was skipped in OSS 22 FixRequired = "Fix required: " // Test requires fix per linked issue 23 FlakyTest = "Flaky test" // Test was skipped in OSS as flakey 24 ) 25 26 // Ensure the server can query with default databases (via param) and default retention policy 27 func TestServer_Query_DefaultDBAndRP(t *testing.T) { 28 s := OpenServer(t) 29 defer s.Close() 30 31 test := NewTest("db0", "rp0") 32 test.writes = Writes{ 33 &Write{data: fmt.Sprintf(`cpu value=1.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano())}, 34 } 35 36 test.addQueries([]*Query{ 37 { 38 name: "default db and rp", 39 params: url.Values{"db": []string{"db0"}}, 40 command: `SELECT * FROM cpu GROUP BY *`, 41 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T01:00:00Z",1]]}]}]}`, 42 }, 43 { 44 name: "default rp exists", 45 command: `show retention policies ON db0`, 46 exp: `{"results":[{"statement_id":0,"series":[{"columns":["name","duration","shardGroupDuration","replicaN","default"],"values":[["autogen","0s","168h0m0s",1,false],["rp0","0s","168h0m0s",1,true]]}]}]}`, 47 skip: "not supported", 48 }, 49 { 50 name: "default rp", 51 command: `SELECT * FROM db0..cpu GROUP BY *`, 52 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T01:00:00Z",1]]}]}]}`, 53 }, 54 { 55 name: "default dp", 56 params: url.Values{"db": []string{"db0"}}, 57 command: `SELECT * FROM rp0.cpu GROUP BY *`, 58 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T01:00:00Z",1]]}]}]}`, 59 }, 60 }...) 61 62 ctx := context.Background() 63 test.Run(ctx, t, s) 64 } 65 66 // Ensure the server can have a database with multiple measurements. 67 func TestServer_Query_Multiple_Measurements(t *testing.T) { 68 s := OpenServer(t) 69 defer s.Close() 70 71 // Make sure we do writes for measurements that will span across shards 72 writes := []string{ 73 fmt.Sprintf("cpu,host=server01 value=100,core=4 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 74 fmt.Sprintf("cpu1,host=server02 value=50,core=2 %d", mustParseTime(time.RFC3339Nano, "2015-01-01T00:00:00Z").UnixNano()), 75 } 76 test := NewTest("db0", "rp0") 77 test.writes = Writes{ 78 &Write{data: strings.Join(writes, "\n")}, 79 } 80 81 test.addQueries([]*Query{ 82 { 83 name: "measurement in one shard but not another shouldn't panic server", 84 command: `SELECT host,value FROM db0.rp0.cpu`, 85 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","host","value"],"values":[["2000-01-01T00:00:00Z","server01",100]]}]}]}`, 86 }, 87 { 88 name: "measurement in one shard but not another shouldn't panic server", 89 command: `SELECT host,value FROM db0.rp0.cpu GROUP BY host`, 90 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","host","value"],"values":[["2000-01-01T00:00:00Z","server01",100]]}]}]}`, 91 }, 92 }...) 93 94 ctx := context.Background() 95 test.Run(ctx, t, s) 96 } 97 98 // Ensure the server can query with relative time. 99 func TestServer_Query_SelectRelativeTime(t *testing.T) { 100 s := OpenServer(t) 101 defer s.Close() 102 103 now := now() 104 yesterday := yesterday() 105 106 test := NewTest("db0", "rp0") 107 test.writes = Writes{ 108 &Write{data: fmt.Sprintf("cpu,host=server01 value=100 %s\ncpu,host=server01 value=200 %s", strconv.FormatInt(yesterday.UnixNano(), 10), strconv.FormatInt(now.UnixNano(), 10))}, 109 } 110 111 test.addQueries([]*Query{ 112 { 113 name: "single point with time pre-calculated for past time queries yesterday", 114 command: `SELECT * FROM db0.rp0.cpu where time >= '` + yesterday.Add(-1*time.Minute).Format(time.RFC3339Nano) + `' GROUP BY *`, 115 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[["%s",100],["%s",200]]}]}]}`, yesterday.Format(time.RFC3339Nano), now.Format(time.RFC3339Nano)), 116 }, 117 { 118 name: "single point with time pre-calculated for relative time queries now", 119 command: `SELECT * FROM db0.rp0.cpu where time >= now() - 1m GROUP BY *`, 120 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[["%s",200]]}]}]}`, now.Format(time.RFC3339Nano)), 121 }, 122 }...) 123 124 ctx := context.Background() 125 test.Run(ctx, t, s) 126 } 127 128 func TestServer_Query_Aggregates_IntMax(t *testing.T) { 129 s := OpenServer(t) 130 defer s.Close() 131 132 test := NewTest("db0", "rp0") 133 test.writes = Writes{ 134 &Write{data: strings.Join([]string{ 135 fmt.Sprintf(`intmax value=%s %d`, maxInt64(), mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 136 fmt.Sprintf(`intmax value=%s %d`, maxInt64(), mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano()), 137 }, "\n")}, 138 } 139 140 test.addQueries([]*Query{ 141 { 142 name: "large mean and stddev - int", 143 params: url.Values{"db": []string{"db0"}}, 144 command: `SELECT MEAN(value), STDDEV(value) FROM intmax`, 145 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmax","columns":["time","mean","stddev"],"values":[["1970-01-01T00:00:00Z",` + maxInt64() + `,0]]}]}]}`, 146 }, 147 }...) 148 149 ctx := context.Background() 150 test.Run(ctx, t, s) 151 } 152 153 func TestServer_Query_TimeZone(t *testing.T) { 154 s := OpenServer(t) 155 defer s.Close() 156 157 var writes []string 158 for _, start := range []time.Time{ 159 // One day before DST starts. 160 time.Date(2000, 4, 1, 0, 0, 0, 0, LosAngeles), 161 // Middle of DST. No change. 162 time.Date(2000, 6, 1, 0, 0, 0, 0, LosAngeles), 163 // One day before DST ends. 164 time.Date(2000, 10, 28, 0, 0, 0, 0, LosAngeles), 165 } { 166 ts := start 167 // Write every hour for 4 days. 168 for i := 0; i < 24*4; i++ { 169 writes = append(writes, fmt.Sprintf(`cpu,interval=daily value=0 %d`, ts.UnixNano())) 170 ts = ts.Add(time.Hour) 171 } 172 173 // Write every 5 minutes for 3 hours. Start at 1 on the day with DST. 174 ts = start.Add(25 * time.Hour) 175 for i := 0; i < 12*3; i++ { 176 writes = append(writes, fmt.Sprintf(`cpu,interval=hourly value=0 %d`, ts.UnixNano())) 177 ts = ts.Add(5 * time.Minute) 178 } 179 } 180 181 test := NewTest("db0", "rp0") 182 test.writes = Writes{ 183 &Write{data: strings.Join(writes, "\n")}, 184 } 185 186 test.addQueries([]*Query{ 187 { 188 name: "timezone offset - dst start - daily", 189 command: `SELECT count(value) FROM cpu WHERE time >= '2000-04-02T00:00:00-08:00' AND time < '2000-04-04T00:00:00-07:00' AND interval = 'daily' GROUP BY time(1d) TZ('America/Los_Angeles')`, 190 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["2000-04-02T00:00:00-08:00",23],["2000-04-03T00:00:00-07:00",24]]}]}]}`, 191 params: url.Values{"db": []string{"db0"}}, 192 }, 193 { 194 name: "timezone offset - no change - daily", 195 command: `SELECT count(value) FROM cpu WHERE time >= '2000-06-01T00:00:00-07:00' AND time < '2000-06-03T00:00:00-07:00' AND interval = 'daily' GROUP BY time(1d) TZ('America/Los_Angeles')`, 196 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["2000-06-01T00:00:00-07:00",24],["2000-06-02T00:00:00-07:00",24]]}]}]}`, 197 params: url.Values{"db": []string{"db0"}}, 198 }, 199 { 200 name: "timezone offset - dst end - daily", 201 command: `SELECT count(value) FROM cpu WHERE time >= '2000-10-29T00:00:00-07:00' AND time < '2000-10-31T00:00:00-08:00' AND interval = 'daily' GROUP BY time(1d) TZ('America/Los_Angeles')`, 202 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["2000-10-29T00:00:00-07:00",25],["2000-10-30T00:00:00-08:00",24]]}]}]}`, 203 params: url.Values{"db": []string{"db0"}}, 204 }, 205 { 206 name: "timezone offset - dst start - hourly", 207 command: `SELECT count(value) FROM cpu WHERE time >= '2000-04-02T01:00:00-08:00' AND time < '2000-04-02T04:00:00-07:00' AND interval = 'hourly' GROUP BY time(1h) TZ('America/Los_Angeles')`, 208 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["2000-04-02T01:00:00-08:00",12],["2000-04-02T03:00:00-07:00",12]]}]}]}`, 209 params: url.Values{"db": []string{"db0"}}, 210 }, 211 { 212 name: "timezone offset - no change - hourly", 213 command: `SELECT count(value) FROM cpu WHERE time >= '2000-06-02T01:00:00-07:00' AND time < '2000-06-02T03:00:00-07:00' AND interval = 'hourly' GROUP BY time(1h) TZ('America/Los_Angeles')`, 214 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["2000-06-02T01:00:00-07:00",12],["2000-06-02T02:00:00-07:00",12]]}]}]}`, 215 params: url.Values{"db": []string{"db0"}}, 216 }, 217 { 218 name: "timezone offset - dst end - hourly", 219 command: `SELECT count(value) FROM cpu WHERE time >= '2000-10-29T01:00:00-07:00' AND time < '2000-10-29T02:00:00-08:00' AND interval = 'hourly' GROUP BY time(1h) TZ('America/Los_Angeles')`, 220 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["2000-10-29T01:00:00-07:00",12],["2000-10-29T01:00:00-08:00",12]]}]}]}`, 221 params: url.Values{"db": []string{"db0"}}, 222 }, 223 }...) 224 225 ctx := context.Background() 226 test.Run(ctx, t, s) 227 } 228 229 // Ensure the server correctly supports data with identical tag values. 230 func TestServer_Query_IdenticalTagValues(t *testing.T) { 231 s := OpenServer(t) 232 defer s.Close() 233 234 writes := []string{ 235 fmt.Sprintf("cpu,t1=val1 value=1 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 236 fmt.Sprintf("cpu,t2=val2 value=2 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 237 fmt.Sprintf("cpu,t1=val2 value=3 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:02:00Z").UnixNano()), 238 } 239 test := NewTest("db0", "rp0") 240 test.writes = Writes{ 241 &Write{data: strings.Join(writes, "\n")}, 242 } 243 244 test.addQueries([]*Query{ 245 { 246 name: "measurements with identical tag values - SELECT *, no GROUP BY", 247 command: `SELECT * FROM db0.rp0.cpu GROUP BY *`, 248 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"t1":"","t2":"val2"},"columns":["time","value"],"values":[["2000-01-01T00:01:00Z",2]]},{"name":"cpu","tags":{"t1":"val1","t2":""},"columns":["time","value"],"values":[["2000-01-01T00:00:00Z",1]]},{"name":"cpu","tags":{"t1":"val2","t2":""},"columns":["time","value"],"values":[["2000-01-01T00:02:00Z",3]]}]}]}`, 249 }, 250 { 251 name: "measurements with identical tag values - SELECT *, with GROUP BY", 252 command: `SELECT value FROM db0.rp0.cpu GROUP BY t1,t2`, 253 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"t1":"","t2":"val2"},"columns":["time","value"],"values":[["2000-01-01T00:01:00Z",2]]},{"name":"cpu","tags":{"t1":"val1","t2":""},"columns":["time","value"],"values":[["2000-01-01T00:00:00Z",1]]},{"name":"cpu","tags":{"t1":"val2","t2":""},"columns":["time","value"],"values":[["2000-01-01T00:02:00Z",3]]}]}]}`, 254 }, 255 { 256 name: "measurements with identical tag values - SELECT value no GROUP BY", 257 command: `SELECT value FROM db0.rp0.cpu`, 258 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00Z",1],["2000-01-01T00:01:00Z",2],["2000-01-01T00:02:00Z",3]]}]}]}`, 259 }, 260 }...) 261 262 ctx := context.Background() 263 test.Run(ctx, t, s) 264 } 265 266 // Ensure the server can handle a query that involves accessing no shards. 267 func TestServer_Query_NoShards(t *testing.T) { 268 s := OpenServer(t) 269 defer s.Close() 270 271 now := now() 272 273 test := NewTest("db0", "rp0") 274 test.writes = Writes{ 275 &Write{data: `cpu,host=server01 value=1 ` + strconv.FormatInt(now.UnixNano(), 10)}, 276 } 277 278 test.addQueries([]*Query{ 279 { 280 name: "selecting value should succeed", 281 command: `SELECT value FROM db0.rp0.cpu WHERE time < now() - 1d`, 282 exp: `{"results":[{"statement_id":0}]}`, 283 }, 284 }...) 285 286 ctx := context.Background() 287 test.Run(ctx, t, s) 288 } 289 290 // Ensure the server can query a non-existent field 291 func TestServer_Query_NonExistent(t *testing.T) { 292 s := OpenServer(t) 293 defer s.Close() 294 295 now := now() 296 297 test := NewTest("db0", "rp0") 298 test.writes = Writes{ 299 &Write{data: `cpu,host=server01 value=1 ` + strconv.FormatInt(now.UnixNano(), 10)}, 300 } 301 302 test.addQueries([]*Query{ 303 { 304 name: "selecting value should succeed", 305 command: `SELECT value FROM db0.rp0.cpu`, 306 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["%s",1]]}]}]}`, now.Format(time.RFC3339Nano)), 307 }, 308 { 309 name: "selecting non-existent should succeed", 310 command: `SELECT foo FROM db0.rp0.cpu`, 311 exp: `{"results":[{"statement_id":0}]}`, 312 }, 313 }...) 314 315 ctx := context.Background() 316 test.Run(ctx, t, s) 317 } 318 319 // Ensure the server can perform basic math 320 func TestServer_Query_Math(t *testing.T) { 321 s := OpenServer(t) 322 defer s.Close() 323 324 now := now() 325 writes := []string{ 326 "float value=42 " + strconv.FormatInt(now.UnixNano(), 10), 327 "integer value=42i " + strconv.FormatInt(now.UnixNano(), 10), 328 } 329 330 test := NewTest("db", "rp") 331 test.writes = Writes{ 332 &Write{data: strings.Join(writes, "\n")}, 333 } 334 335 test.addQueries([]*Query{ 336 { 337 name: "SELECT multiple of float value", 338 command: `SELECT value * 2 from db.rp.float`, 339 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"float","columns":["time","value"],"values":[["%s",84]]}]}]}`, now.Format(time.RFC3339Nano)), 340 }, 341 { 342 name: "SELECT multiple of float value", 343 command: `SELECT 2 * value from db.rp.float`, 344 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"float","columns":["time","value"],"values":[["%s",84]]}]}]}`, now.Format(time.RFC3339Nano)), 345 }, 346 { 347 name: "SELECT multiple of integer value", 348 command: `SELECT value * 2 from db.rp.integer`, 349 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"integer","columns":["time","value"],"values":[["%s",84]]}]}]}`, now.Format(time.RFC3339Nano)), 350 }, 351 { 352 name: "SELECT float multiple of integer value", 353 command: `SELECT value * 2.0 from db.rp.integer`, 354 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"integer","columns":["time","value"],"values":[["%s",84]]}]}]}`, now.Format(time.RFC3339Nano)), 355 }, 356 { 357 name: "SELECT square of float value", 358 command: `SELECT value * value from db.rp.float`, 359 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"float","columns":["time","value_value"],"values":[["%s",1764]]}]}]}`, now.Format(time.RFC3339Nano)), 360 }, 361 { 362 name: "SELECT square of integer value", 363 command: `SELECT value * value from db.rp.integer`, 364 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"integer","columns":["time","value_value"],"values":[["%s",1764]]}]}]}`, now.Format(time.RFC3339Nano)), 365 }, 366 { 367 name: "SELECT square of integer, float value", 368 command: `SELECT value * value,float from db.rp.integer`, 369 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"integer","columns":["time","value_value","float"],"values":[["%s",1764,null]]}]}]}`, now.Format(time.RFC3339Nano)), 370 }, 371 { 372 name: "SELECT square of integer value with alias", 373 command: `SELECT value * value as square from db.rp.integer`, 374 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"integer","columns":["time","square"],"values":[["%s",1764]]}]}]}`, now.Format(time.RFC3339Nano)), 375 }, 376 { 377 name: "SELECT sum of aggregates", 378 command: `SELECT max(value) + min(value) from db.rp.integer`, 379 exp: `{"results":[{"statement_id":0,"series":[{"name":"integer","columns":["time","max_min"],"values":[["1970-01-01T00:00:00Z",84]]}]}]}`, 380 }, 381 { 382 name: "SELECT square of enclosed integer value", 383 command: `SELECT ((value) * (value)) from db.rp.integer`, 384 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"integer","columns":["time","value_value"],"values":[["%s",1764]]}]}]}`, now.Format(time.RFC3339Nano)), 385 }, 386 { 387 name: "SELECT square of enclosed integer value", 388 command: `SELECT (value * value) from db.rp.integer`, 389 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"integer","columns":["time","value_value"],"values":[["%s",1764]]}]}]}`, now.Format(time.RFC3339Nano)), 390 }, 391 }...) 392 393 ctx := context.Background() 394 test.Run(ctx, t, s) 395 } 396 397 // Ensure the server can handle various simple non_negative_derivative queries. 398 func TestServer_Query_SelectRawNonNegativeDerivative(t *testing.T) { 399 s := OpenServer(t) 400 defer s.Close() 401 402 test := NewTest("db0", "rp0") 403 test.writes = Writes{ 404 &Write{data: `cpu value=10 1278010021000000000 405 cpu value=15 1278010022000000000 406 cpu value=10 1278010023000000000 407 cpu value=20 1278010024000000000 408 `}, 409 } 410 411 test.addQueries([]*Query{ 412 { 413 name: "calculate single non_negative_derivative", 414 command: `SELECT non_negative_derivative(value) from db0.rp0.cpu`, 415 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","non_negative_derivative"],"values":[["2010-07-01T18:47:02Z",5],["2010-07-01T18:47:04Z",10]]}]}]}`, 416 }, 417 { 418 name: "calculate single non_negative_derivative", 419 command: `SELECT non_negative_derivative(value, 10s) from db0.rp0.cpu`, 420 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","non_negative_derivative"],"values":[["2010-07-01T18:47:02Z",50],["2010-07-01T18:47:04Z",100]]}]}]}`, 421 }, 422 }...) 423 424 ctx := context.Background() 425 test.Run(ctx, t, s) 426 } 427 428 // Ensure the server can handle various group by time derivative queries. 429 func TestServer_Query_SelectGroupByTimeDerivative(t *testing.T) { 430 s := OpenServer(t) 431 defer s.Close() 432 433 test := NewTest("db0", "rp0") 434 test.writes = Writes{ 435 &Write{data: `cpu value=10 1278010020000000000 436 cpu value=15 1278010021000000000 437 cpu value=20 1278010022000000000 438 cpu value=25 1278010023000000000 439 440 cpu0,host=server01 ticks=10,total=100 1278010020000000000 441 cpu0,host=server01 ticks=30,total=100 1278010021000000000 442 cpu0,host=server01 ticks=32,total=100 1278010022000000000 443 cpu0,host=server01 ticks=47,total=100 1278010023000000000 444 cpu0,host=server02 ticks=40,total=100 1278010020000000000 445 cpu0,host=server02 ticks=45,total=100 1278010021000000000 446 cpu0,host=server02 ticks=84,total=100 1278010022000000000 447 cpu0,host=server02 ticks=101,total=100 1278010023000000000 448 `}, 449 } 450 451 test.addQueries([]*Query{ 452 { 453 name: "calculate derivative of count with unit default (2s) group by time", 454 command: `SELECT derivative(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 455 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",2],["2010-07-01T18:47:02Z",0]]}]}]}`, 456 }, 457 { 458 name: "calculate derivative of count with unit 4s group by time", 459 command: `SELECT derivative(count(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 460 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",4],["2010-07-01T18:47:02Z",0]]}]}]}`, 461 }, 462 { 463 name: "calculate derivative of mean with unit default (2s) group by time", 464 command: `SELECT derivative(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 465 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 466 }, 467 { 468 name: "calculate derivative of mean with unit 4s group by time", 469 command: `SELECT derivative(mean(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 470 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 471 }, 472 { 473 name: "calculate derivative of median with unit default (2s) group by time", 474 command: `SELECT derivative(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 475 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 476 }, 477 { 478 name: "calculate derivative of median with unit 4s group by time", 479 command: `SELECT derivative(median(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 480 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 481 }, 482 { 483 name: "calculate derivative of mode with unit default (2s) group by time", 484 command: `SELECT derivative(mode(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 485 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 486 }, 487 { 488 name: "calculate derivative of mode with unit 4s group by time", 489 command: `SELECT derivative(mode(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 490 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 491 }, 492 493 { 494 name: "calculate derivative of sum with unit default (2s) group by time", 495 command: `SELECT derivative(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 496 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 497 }, 498 { 499 name: "calculate derivative of sum with unit 4s group by time", 500 command: `SELECT derivative(sum(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 501 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",40]]}]}]}`, 502 }, 503 { 504 name: "calculate derivative of first with unit default (2s) group by time", 505 command: `SELECT derivative(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 506 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 507 }, 508 { 509 name: "calculate derivative of first with unit 4s group by time", 510 command: `SELECT derivative(first(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 511 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 512 }, 513 { 514 name: "calculate derivative of last with unit default (2s) group by time", 515 command: `SELECT derivative(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 516 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 517 }, 518 { 519 name: "calculate derivative of last with unit 4s group by time", 520 command: `SELECT derivative(last(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 521 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 522 }, 523 { 524 name: "calculate derivative of min with unit default (2s) group by time", 525 command: `SELECT derivative(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 526 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 527 }, 528 { 529 name: "calculate derivative of min with unit 4s group by time", 530 command: `SELECT derivative(min(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 531 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 532 }, 533 { 534 name: "calculate derivative of max with unit default (2s) group by time", 535 command: `SELECT derivative(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 536 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 537 }, 538 { 539 name: "calculate derivative of max with unit 4s group by time", 540 command: `SELECT derivative(max(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 541 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 542 }, 543 { 544 name: "calculate derivative of percentile with unit default (2s) group by time", 545 command: `SELECT derivative(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 546 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 547 }, 548 { 549 name: "calculate derivative of percentile with unit 4s group by time", 550 command: `SELECT derivative(percentile(value, 50), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 551 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 552 }, 553 { 554 name: "calculate derivative of ticks divided by aggregate", 555 command: `SELECT non_negative_derivative(mean(ticks), 1s) / last(total) * 100 AS usage FROM db0.rp0.cpu0 WHERE time >= '2010-07-01 18:47:00' AND time <= '2010-07-01 18:47:03' GROUP BY host, time(1s)`, 556 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu0","tags":{"host":"server01"},"columns":["time","usage"],"values":[["2010-07-01T18:47:00Z",null],["2010-07-01T18:47:01Z",20],["2010-07-01T18:47:02Z",2],["2010-07-01T18:47:03Z",15]]},{"name":"cpu0","tags":{"host":"server02"},"columns":["time","usage"],"values":[["2010-07-01T18:47:00Z",null],["2010-07-01T18:47:01Z",5],["2010-07-01T18:47:02Z",39],["2010-07-01T18:47:03Z",17]]}]}]}`, 557 }, 558 }...) 559 560 ctx := context.Background() 561 test.Run(ctx, t, s) 562 } 563 564 // Ensure the server can query with the count aggregate function 565 func TestServer_Query_Count(t *testing.T) { 566 s := OpenServer(t) 567 defer s.Close() 568 569 now := now() 570 571 test := NewTest("db0", "rp0") 572 writes := []string{ 573 `cpu,host=server01 value=1.0 ` + strconv.FormatInt(now.UnixNano(), 10), 574 `ram value1=1.0,value2=2.0 ` + strconv.FormatInt(now.UnixNano(), 10), 575 } 576 577 test.writes = Writes{ 578 &Write{data: strings.Join(writes, "\n")}, 579 } 580 581 hourAgo := now.Add(-time.Hour).UTC() 582 583 test.addQueries([]*Query{ 584 { 585 name: "selecting count(value) should succeed", 586 command: `SELECT count(value) FROM db0.rp0.cpu`, 587 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",1]]}]}]}`, 588 }, 589 { 590 name: "selecting count(value) with where time should return result", 591 command: fmt.Sprintf(`SELECT count(value) FROM db0.rp0.cpu WHERE time >= '%s'`, hourAgo.Format(time.RFC3339Nano)), 592 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["%s",1]]}]}]}`, hourAgo.Format(time.RFC3339Nano)), 593 }, 594 { 595 name: "selecting count(value) with filter that excludes all results should return 0", 596 command: fmt.Sprintf(`SELECT count(value) FROM db0.rp0.cpu WHERE value=100 AND time >= '%s'`, hourAgo.Format(time.RFC3339Nano)), 597 exp: `{"results":[{"statement_id":0}]}`, 598 }, 599 { 600 name: "selecting count(value1) with matching filter against value2 should return correct result", 601 command: fmt.Sprintf(`SELECT count(value1) FROM db0.rp0.ram WHERE value2=2 AND time >= '%s'`, hourAgo.Format(time.RFC3339Nano)), 602 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"ram","columns":["time","count"],"values":[["%s",1]]}]}]}`, hourAgo.Format(time.RFC3339Nano)), 603 }, 604 { 605 name: "selecting count(value1) with non-matching filter against value2 should return correct result", 606 command: fmt.Sprintf(`SELECT count(value1) FROM db0.rp0.ram WHERE value2=3 AND time >= '%s'`, hourAgo.Format(time.RFC3339Nano)), 607 exp: `{"results":[{"statement_id":0}]}`, 608 }, 609 { 610 name: "selecting count(*) should expand the wildcard", 611 command: `SELECT count(*) FROM db0.rp0.cpu`, 612 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count_value"],"values":[["1970-01-01T00:00:00Z",1]]}]}]}`, 613 }, 614 { 615 name: "selecting count(2) should error", 616 command: `SELECT count(2) FROM db0.rp0.cpu`, 617 exp: `{"results":[{"statement_id":0,"error":"expected field argument in count()"}]}`, 618 }, 619 }...) 620 621 ctx := context.Background() 622 test.Run(ctx, t, s) 623 } 624 625 // Ensure the server can limit concurrent series. 626 func TestServer_Query_MaxSelectSeriesN(t *testing.T) { 627 s := OpenServer(t, func(o *launcher.InfluxdOpts) { 628 o.CoordinatorConfig.MaxSelectSeriesN = 3 629 }) 630 defer s.Close() 631 632 test := NewTest("db0", "rp0") 633 test.writes = Writes{ 634 &Write{data: `cpu,host=server01 value=1.0 0`}, 635 &Write{data: `cpu,host=server02 value=1.0 0`}, 636 &Write{data: `cpu,host=server03 value=1.0 0`}, 637 &Write{data: `cpu,host=server04 value=1.0 0`}, 638 } 639 640 test.addQueries([]*Query{ 641 { 642 name: "exceeed max series", 643 command: `SELECT COUNT(value) FROM db0.rp0.cpu`, 644 exp: `{"results":[{"statement_id":0,"error":"max-select-series limit exceeded: (4/3)"}]}`, 645 }, 646 }...) 647 648 ctx := context.Background() 649 test.Run(ctx, t, s) 650 } 651 652 // Ensure the server can query with Now(). 653 func TestServer_Query_Now(t *testing.T) { 654 s := OpenServer(t) 655 defer s.Close() 656 657 now := now() 658 659 test := NewTest("db0", "rp0") 660 test.writes = Writes{ 661 &Write{data: `cpu,host=server01 value=1.0 ` + strconv.FormatInt(now.UnixNano(), 10)}, 662 } 663 664 test.addQueries([]*Query{ 665 { 666 name: "where with time < now() should work", 667 command: `SELECT * FROM db0.rp0.cpu where time < now()`, 668 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","host","value"],"values":[["%s","server01",1]]}]}]}`, now.Format(time.RFC3339Nano)), 669 }, 670 { 671 name: "where with time < now() and GROUP BY * should work", 672 command: `SELECT * FROM db0.rp0.cpu where time < now() GROUP BY *`, 673 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[["%s",1]]}]}]}`, now.Format(time.RFC3339Nano)), 674 }, 675 { 676 name: "where with time > now() should return an empty result", 677 command: `SELECT * FROM db0.rp0.cpu where time > now()`, 678 exp: `{"results":[{"statement_id":0}]}`, 679 }, 680 { 681 name: "where with time > now() with GROUP BY * should return an empty result", 682 command: `SELECT * FROM db0.rp0.cpu where time > now() GROUP BY *`, 683 exp: `{"results":[{"statement_id":0}]}`, 684 }, 685 }...) 686 687 ctx := context.Background() 688 test.Run(ctx, t, s) 689 } 690 691 // Ensure the server can query with epoch precisions. 692 func TestServer_Query_EpochPrecision(t *testing.T) { 693 s := OpenServer(t) 694 defer s.Close() 695 696 now := now() 697 698 test := NewTest("db0", "rp0") 699 test.writes = Writes{ 700 &Write{data: `cpu,host=server01 value=1.0 ` + strconv.FormatInt(now.UnixNano(), 10)}, 701 } 702 703 test.addQueries([]*Query{ 704 { 705 name: "nanosecond precision", 706 command: `SELECT * FROM db0.rp0.cpu GROUP BY *`, 707 params: url.Values{"epoch": []string{"n"}}, 708 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[[%d,1]]}]}]}`, now.UnixNano()), 709 }, 710 { 711 name: "microsecond precision", 712 command: `SELECT * FROM db0.rp0.cpu GROUP BY *`, 713 params: url.Values{"epoch": []string{"u"}}, 714 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[[%d,1]]}]}]}`, now.UnixNano()/int64(time.Microsecond)), 715 }, 716 { 717 name: "millisecond precision", 718 command: `SELECT * FROM db0.rp0.cpu GROUP BY *`, 719 params: url.Values{"epoch": []string{"ms"}}, 720 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[[%d,1]]}]}]}`, now.UnixNano()/int64(time.Millisecond)), 721 }, 722 { 723 name: "second precision", 724 command: `SELECT * FROM db0.rp0.cpu GROUP BY *`, 725 params: url.Values{"epoch": []string{"s"}}, 726 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[[%d,1]]}]}]}`, now.UnixNano()/int64(time.Second)), 727 }, 728 { 729 name: "minute precision", 730 command: `SELECT * FROM db0.rp0.cpu GROUP BY *`, 731 params: url.Values{"epoch": []string{"m"}}, 732 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[[%d,1]]}]}]}`, now.UnixNano()/int64(time.Minute)), 733 }, 734 { 735 name: "hour precision", 736 command: `SELECT * FROM db0.rp0.cpu GROUP BY *`, 737 params: url.Values{"epoch": []string{"h"}}, 738 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[[%d,1]]}]}]}`, now.UnixNano()/int64(time.Hour)), 739 }, 740 }...) 741 742 ctx := context.Background() 743 test.Run(ctx, t, s) 744 } 745 746 // Ensure the server works with tag queries. 747 func TestServer_Query_Tags(t *testing.T) { 748 s := OpenServer(t) 749 defer s.Close() 750 751 now := now() 752 753 writes := []string{ 754 fmt.Sprintf("cpu,host=server01 value=100,core=4 %d", now.UnixNano()), 755 fmt.Sprintf("cpu,host=server02 value=50,core=2 %d", now.Add(1).UnixNano()), 756 757 fmt.Sprintf("cpu1,host=server01,region=us-west value=100 %d", mustParseTime(time.RFC3339Nano, "2015-02-28T01:03:36.703820946Z").UnixNano()), 758 fmt.Sprintf("cpu1,host=server02 value=200 %d", mustParseTime(time.RFC3339Nano, "2010-02-28T01:03:37.703820946Z").UnixNano()), 759 fmt.Sprintf("cpu1,host=server03 value=300 %d", mustParseTime(time.RFC3339Nano, "2012-02-28T01:03:38.703820946Z").UnixNano()), 760 761 fmt.Sprintf("cpu2,host=server01 value=100 %d", mustParseTime(time.RFC3339Nano, "2015-02-28T01:03:36.703820946Z").UnixNano()), 762 fmt.Sprintf("cpu2 value=200 %d", mustParseTime(time.RFC3339Nano, "2012-02-28T01:03:38.703820946Z").UnixNano()), 763 764 fmt.Sprintf("cpu3,company=acme01 value=100 %d", mustParseTime(time.RFC3339Nano, "2015-02-28T01:03:36.703820946Z").UnixNano()), 765 fmt.Sprintf("cpu3 value=200 %d", mustParseTime(time.RFC3339Nano, "2012-02-28T01:03:38.703820946Z").UnixNano()), 766 767 fmt.Sprintf("status_code,url=http://www.example.com value=404 %d", mustParseTime(time.RFC3339Nano, "2015-07-22T08:13:54.929026672Z").UnixNano()), 768 fmt.Sprintf("status_code,url=https://influxdb.com value=418 %d", mustParseTime(time.RFC3339Nano, "2015-07-22T09:52:24.914395083Z").UnixNano()), 769 } 770 771 test := NewTest("db0", "rp0") 772 test.writes = Writes{ 773 &Write{data: strings.Join(writes, "\n")}, 774 } 775 776 test.addQueries([]*Query{ 777 { 778 name: "tag without field should return error", 779 command: `SELECT host FROM db0.rp0.cpu`, 780 exp: `{"results":[{"statement_id":0,"error":"statement must have at least one field in select clause"}]}`, 781 skip: SkippedOSS, // FIXME(benbjohnson): tags should stream as values 782 }, 783 { 784 name: "field with tag should succeed", 785 command: `SELECT host, value FROM db0.rp0.cpu`, 786 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","host","value"],"values":[["%s","server01",100],["%s","server02",50]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 787 }, 788 { 789 name: "field with tag and GROUP BY should succeed", 790 command: `SELECT host, value FROM db0.rp0.cpu GROUP BY host`, 791 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","host","value"],"values":[["%s","server01",100]]},{"name":"cpu","tags":{"host":"server02"},"columns":["time","host","value"],"values":[["%s","server02",50]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 792 }, 793 { 794 name: "field with two tags should succeed", 795 command: `SELECT host, value, core FROM db0.rp0.cpu`, 796 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","host","value","core"],"values":[["%s","server01",100,4],["%s","server02",50,2]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 797 }, 798 { 799 name: "field with two tags and GROUP BY should succeed", 800 command: `SELECT host, value, core FROM db0.rp0.cpu GROUP BY host`, 801 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","host","value","core"],"values":[["%s","server01",100,4]]},{"name":"cpu","tags":{"host":"server02"},"columns":["time","host","value","core"],"values":[["%s","server02",50,2]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 802 }, 803 { 804 name: "select * with tags should succeed", 805 command: `SELECT * FROM db0.rp0.cpu`, 806 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core","host","value"],"values":[["%s",4,"server01",100],["%s",2,"server02",50]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 807 }, 808 { 809 name: "select * with tags with GROUP BY * should succeed", 810 command: `SELECT * FROM db0.rp0.cpu GROUP BY *`, 811 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","core","value"],"values":[["%s",4,100]]},{"name":"cpu","tags":{"host":"server02"},"columns":["time","core","value"],"values":[["%s",2,50]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 812 }, 813 { 814 name: "group by tag", 815 command: `SELECT value FROM db0.rp0.cpu GROUP by host`, 816 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[["%s",100]]},{"name":"cpu","tags":{"host":"server02"},"columns":["time","value"],"values":[["%s",50]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 817 }, 818 { 819 name: "single field (EQ tag value1)", 820 command: `SELECT value FROM db0.rp0.cpu1 WHERE host = 'server01'`, 821 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",100]]}]}]}`, 822 }, 823 { 824 name: "single field (2 EQ tags)", 825 command: `SELECT value FROM db0.rp0.cpu1 WHERE host = 'server01' AND region = 'us-west'`, 826 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",100]]}]}]}`, 827 }, 828 { 829 name: "single field (OR different tags)", 830 command: `SELECT value FROM db0.rp0.cpu1 WHERE host = 'server03' OR region = 'us-west'`, 831 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2012-02-28T01:03:38.703820946Z",300],["2015-02-28T01:03:36.703820946Z",100]]}]}]}`, 832 }, 833 { 834 name: "single field (OR with non-existent tag value)", 835 command: `SELECT value FROM db0.rp0.cpu1 WHERE host = 'server01' OR host = 'server66'`, 836 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",100]]}]}]}`, 837 }, 838 { 839 name: "single field (OR with all tag values)", 840 command: `SELECT value FROM db0.rp0.cpu1 WHERE host = 'server01' OR host = 'server02' OR host = 'server03'`, 841 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2010-02-28T01:03:37.703820946Z",200],["2012-02-28T01:03:38.703820946Z",300],["2015-02-28T01:03:36.703820946Z",100]]}]}]}`, 842 }, 843 { 844 name: "single field (1 EQ and 1 NEQ tag)", 845 command: `SELECT value FROM db0.rp0.cpu1 WHERE host = 'server01' AND region != 'us-west'`, 846 exp: `{"results":[{"statement_id":0}]}`, 847 }, 848 { 849 name: "single field (EQ tag value2)", 850 command: `SELECT value FROM db0.rp0.cpu1 WHERE host = 'server02'`, 851 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2010-02-28T01:03:37.703820946Z",200]]}]}]}`, 852 }, 853 { 854 name: "single field (NEQ tag value1)", 855 command: `SELECT value FROM db0.rp0.cpu1 WHERE host != 'server01'`, 856 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2010-02-28T01:03:37.703820946Z",200],["2012-02-28T01:03:38.703820946Z",300]]}]}]}`, 857 }, 858 { 859 name: "single field (NEQ tag value1 AND NEQ tag value2)", 860 command: `SELECT value FROM db0.rp0.cpu1 WHERE host != 'server01' AND host != 'server02'`, 861 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2012-02-28T01:03:38.703820946Z",300]]}]}]}`, 862 }, 863 { 864 name: "single field (NEQ tag value1 OR NEQ tag value2)", 865 command: `SELECT value FROM db0.rp0.cpu1 WHERE host != 'server01' OR host != 'server02'`, // Yes, this is always true, but that's the point. 866 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2010-02-28T01:03:37.703820946Z",200],["2012-02-28T01:03:38.703820946Z",300],["2015-02-28T01:03:36.703820946Z",100]]}]}]}`, 867 }, 868 { 869 name: "single field (NEQ tag value1 AND NEQ tag value2 AND NEQ tag value3)", 870 command: `SELECT value FROM db0.rp0.cpu1 WHERE host != 'server01' AND host != 'server02' AND host != 'server03'`, 871 exp: `{"results":[{"statement_id":0}]}`, 872 }, 873 { 874 name: "single field (NEQ tag value1, point without any tags)", 875 command: `SELECT value FROM db0.rp0.cpu2 WHERE host != 'server01'`, 876 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu2","columns":["time","value"],"values":[["2012-02-28T01:03:38.703820946Z",200]]}]}]}`, 877 }, 878 { 879 name: "single field (NEQ tag value1, point without any tags)", 880 command: `SELECT value FROM db0.rp0.cpu3 WHERE company !~ /acme01/`, 881 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu3","columns":["time","value"],"values":[["2012-02-28T01:03:38.703820946Z",200]]}]}]}`, 882 }, 883 { 884 name: "single field (regex tag match)", 885 command: `SELECT value FROM db0.rp0.cpu3 WHERE company =~ /acme01/`, 886 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu3","columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",100]]}]}]}`, 887 }, 888 { 889 name: "single field (regex tag match)", 890 command: `SELECT value FROM db0.rp0.cpu3 WHERE company !~ /acme[23]/`, 891 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu3","columns":["time","value"],"values":[["2012-02-28T01:03:38.703820946Z",200],["2015-02-28T01:03:36.703820946Z",100]]}]}]}`, 892 }, 893 { 894 name: "single field (regex tag match with escaping)", 895 command: `SELECT value FROM db0.rp0.status_code WHERE url !~ /https\:\/\/influxdb\.com/`, 896 exp: `{"results":[{"statement_id":0,"series":[{"name":"status_code","columns":["time","value"],"values":[["2015-07-22T08:13:54.929026672Z",404]]}]}]}`, 897 }, 898 { 899 name: "single field (regex tag match with escaping)", 900 command: `SELECT value FROM db0.rp0.status_code WHERE url =~ /https\:\/\/influxdb\.com/`, 901 exp: `{"results":[{"statement_id":0,"series":[{"name":"status_code","columns":["time","value"],"values":[["2015-07-22T09:52:24.914395083Z",418]]}]}]}`, 902 }, 903 }...) 904 905 ctx := context.Background() 906 test.Run(ctx, t, s) 907 } 908 909 // Ensure the server can handle various group by time moving average queries. 910 func TestServer_Query_SelectGroupByTimeMovingAverage(t *testing.T) { 911 s := OpenServer(t) 912 defer s.Close() 913 914 test := NewTest("db0", "rp0") 915 test.writes = Writes{ 916 &Write{data: `cpu value=10 1278010020000000000 917 cpu value=15 1278010021000000000 918 cpu value=20 1278010022000000000 919 cpu value=25 1278010023000000000 920 cpu value=30 1278010024000000000 921 cpu value=35 1278010025000000000 922 `}, 923 } 924 925 test.addQueries([]*Query{ 926 { 927 name: "calculate moving average of count", 928 command: `SELECT moving_average(count(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 929 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",1],["2010-07-01T18:47:02Z",2],["2010-07-01T18:47:04Z",2]]}]}]}`, 930 }, 931 { 932 name: "calculate moving average of mean", 933 command: `SELECT moving_average(mean(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 934 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",17.5],["2010-07-01T18:47:04Z",27.5]]}]}]}`, 935 }, 936 { 937 name: "calculate moving average of median", 938 command: `SELECT moving_average(median(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 939 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",17.5],["2010-07-01T18:47:04Z",27.5]]}]}]}`, 940 }, 941 { 942 name: "calculate moving average of mode", 943 command: `SELECT moving_average(mode(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 944 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",15],["2010-07-01T18:47:04Z",25]]}]}]}`, 945 }, 946 { 947 name: "calculate moving average of sum", 948 command: `SELECT moving_average(sum(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 949 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",35],["2010-07-01T18:47:04Z",55]]}]}]}`, 950 }, 951 { 952 name: "calculate moving average of first", 953 command: `SELECT moving_average(first(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 954 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",15],["2010-07-01T18:47:04Z",25]]}]}]}`, 955 }, 956 { 957 name: "calculate moving average of last", 958 command: `SELECT moving_average(last(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 959 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",20],["2010-07-01T18:47:04Z",30]]}]}]}`, 960 }, 961 { 962 name: "calculate moving average of min", 963 command: `SELECT moving_average(min(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 964 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",15],["2010-07-01T18:47:04Z",25]]}]}]}`, 965 }, 966 { 967 name: "calculate moving average of max", 968 command: `SELECT moving_average(max(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 969 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",20],["2010-07-01T18:47:04Z",30]]}]}]}`, 970 }, 971 { 972 name: "calculate moving average of percentile", 973 command: `SELECT moving_average(percentile(value, 50), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s)`, 974 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",15],["2010-07-01T18:47:04Z",25]]}]}]}`, 975 }, 976 }...) 977 978 ctx := context.Background() 979 test.Run(ctx, t, s) 980 } 981 982 // Ensure the server can handle various group by time moving average queries. 983 func TestServer_Query_SelectGroupByTimeMovingAverageWithFill(t *testing.T) { 984 s := OpenServer(t) 985 defer s.Close() 986 987 test := NewTest("db0", "rp0") 988 test.writes = Writes{ 989 &Write{data: `cpu value=10 1278010020000000000 990 cpu value=15 1278010021000000000 991 cpu value=30 1278010024000000000 992 cpu value=35 1278010025000000000 993 `}, 994 } 995 996 test.addQueries([]*Query{ 997 { 998 name: "calculate moving average of count with fill 0", 999 command: `SELECT moving_average(count(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1000 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",1],["2010-07-01T18:47:02Z",1],["2010-07-01T18:47:04Z",1]]}]}]}`, 1001 }, 1002 { 1003 name: "calculate moving average of count with fill previous", 1004 command: `SELECT moving_average(count(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1005 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",2],["2010-07-01T18:47:04Z",2]]}]}]}`, 1006 }, 1007 { 1008 name: "calculate moving average of mean with fill 0", 1009 command: `SELECT moving_average(mean(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1010 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",6.25],["2010-07-01T18:47:02Z",6.25],["2010-07-01T18:47:04Z",16.25]]}]}]}`, 1011 }, 1012 { 1013 name: "calculate moving average of mean with fill previous", 1014 command: `SELECT moving_average(mean(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1015 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",12.5],["2010-07-01T18:47:04Z",22.5]]}]}]}`, 1016 }, 1017 { 1018 name: "calculate moving average of median with fill 0", 1019 command: `SELECT moving_average(median(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1020 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",6.25],["2010-07-01T18:47:02Z",6.25],["2010-07-01T18:47:04Z",16.25]]}]}]}`, 1021 }, 1022 { 1023 name: "calculate moving average of median with fill previous", 1024 command: `SELECT moving_average(median(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1025 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",12.5],["2010-07-01T18:47:04Z",22.5]]}]}]}`, 1026 }, 1027 { 1028 name: "calculate moving average of mode with fill 0", 1029 command: `SELECT moving_average(mode(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1030 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",5],["2010-07-01T18:47:02Z",5],["2010-07-01T18:47:04Z",15]]}]}]}`, 1031 }, 1032 { 1033 name: "calculate moving average of mode with fill previous", 1034 command: `SELECT moving_average(mode(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1035 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",10],["2010-07-01T18:47:04Z",20]]}]}]}`, 1036 }, 1037 { 1038 name: "calculate moving average of sum with fill 0", 1039 command: `SELECT moving_average(sum(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1040 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",12.5],["2010-07-01T18:47:02Z",12.5],["2010-07-01T18:47:04Z",32.5]]}]}]}`, 1041 }, 1042 { 1043 name: "calculate moving average of sum with fill previous", 1044 command: `SELECT moving_average(sum(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1045 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",25],["2010-07-01T18:47:04Z",45]]}]}]}`, 1046 }, 1047 { 1048 name: "calculate moving average of first with fill 0", 1049 command: `SELECT moving_average(first(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1050 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",5],["2010-07-01T18:47:02Z",5],["2010-07-01T18:47:04Z",15]]}]}]}`, 1051 }, 1052 { 1053 name: "calculate moving average of first with fill previous", 1054 command: `SELECT moving_average(first(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1055 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",10],["2010-07-01T18:47:04Z",20]]}]}]}`, 1056 }, 1057 { 1058 name: "calculate moving average of last with fill 0", 1059 command: `SELECT moving_average(last(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1060 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",7.5],["2010-07-01T18:47:02Z",7.5],["2010-07-01T18:47:04Z",17.5]]}]}]}`, 1061 }, 1062 { 1063 name: "calculate moving average of last with fill previous", 1064 command: `SELECT moving_average(last(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1065 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",15],["2010-07-01T18:47:04Z",25]]}]}]}`, 1066 }, 1067 { 1068 name: "calculate moving average of min with fill 0", 1069 command: `SELECT moving_average(min(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1070 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",5],["2010-07-01T18:47:02Z",5],["2010-07-01T18:47:04Z",15]]}]}]}`, 1071 }, 1072 { 1073 name: "calculate moving average of min with fill previous", 1074 command: `SELECT moving_average(min(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1075 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",10],["2010-07-01T18:47:04Z",20]]}]}]}`, 1076 }, 1077 { 1078 name: "calculate moving average of max with fill 0", 1079 command: `SELECT moving_average(max(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1080 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",7.5],["2010-07-01T18:47:02Z",7.5],["2010-07-01T18:47:04Z",17.5]]}]}]}`, 1081 }, 1082 { 1083 name: "calculate moving average of max with fill previous", 1084 command: `SELECT moving_average(max(value), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1085 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",15],["2010-07-01T18:47:04Z",25]]}]}]}`, 1086 }, 1087 { 1088 name: "calculate moving average of percentile with fill 0", 1089 command: `SELECT moving_average(percentile(value, 50), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(0)`, 1090 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:00Z",5],["2010-07-01T18:47:02Z",5],["2010-07-01T18:47:04Z",15]]}]}]}`, 1091 }, 1092 { 1093 name: "calculate moving average of percentile with fill previous", 1094 command: `SELECT moving_average(percentile(value, 50), 2) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:05' group by time(2s) fill(previous)`, 1095 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","moving_average"],"values":[["2010-07-01T18:47:02Z",10],["2010-07-01T18:47:04Z",20]]}]}]}`, 1096 }, 1097 }...) 1098 1099 ctx := context.Background() 1100 test.Run(ctx, t, s) 1101 } // Ensure the server correctly queries with an alias. 1102 func TestServer_Query_Alias(t *testing.T) { 1103 s := OpenServer(t) 1104 defer s.Close() 1105 1106 writes := []string{ 1107 fmt.Sprintf("cpu value=1i,steps=3i %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 1108 fmt.Sprintf("cpu value=2i,steps=4i %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 1109 } 1110 test := NewTest("db0", "rp0") 1111 test.writes = Writes{ 1112 &Write{data: strings.Join(writes, "\n")}, 1113 } 1114 1115 test.addQueries([]*Query{ 1116 { 1117 name: "baseline query - SELECT * FROM db0.rp0.cpu", 1118 command: `SELECT * FROM db0.rp0.cpu`, 1119 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","steps","value"],"values":[["2000-01-01T00:00:00Z",3,1],["2000-01-01T00:01:00Z",4,2]]}]}]}`, 1120 }, 1121 { 1122 name: "basic query with alias - SELECT steps, value as v FROM db0.rp0.cpu", 1123 command: `SELECT steps, value as v FROM db0.rp0.cpu`, 1124 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","steps","v"],"values":[["2000-01-01T00:00:00Z",3,1],["2000-01-01T00:01:00Z",4,2]]}]}]}`, 1125 }, 1126 { 1127 name: "double aggregate sum - SELECT sum(value), sum(steps) FROM db0.rp0.cpu", 1128 command: `SELECT sum(value), sum(steps) FROM db0.rp0.cpu`, 1129 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum","sum_1"],"values":[["1970-01-01T00:00:00Z",3,7]]}]}]}`, 1130 }, 1131 { 1132 name: "double aggregate sum reverse order - SELECT sum(steps), sum(value) FROM db0.rp0.cpu", 1133 command: `SELECT sum(steps), sum(value) FROM db0.rp0.cpu`, 1134 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum","sum_1"],"values":[["1970-01-01T00:00:00Z",7,3]]}]}]}`, 1135 }, 1136 { 1137 name: "double aggregate sum with alias - SELECT sum(value) as sumv, sum(steps) as sums FROM db0.rp0.cpu", 1138 command: `SELECT sum(value) as sumv, sum(steps) as sums FROM db0.rp0.cpu`, 1139 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sumv","sums"],"values":[["1970-01-01T00:00:00Z",3,7]]}]}]}`, 1140 }, 1141 { 1142 name: "double aggregate with same value - SELECT sum(value), mean(value) FROM db0.rp0.cpu", 1143 command: `SELECT sum(value), mean(value) FROM db0.rp0.cpu`, 1144 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum","mean"],"values":[["1970-01-01T00:00:00Z",3,1.5]]}]}]}`, 1145 }, 1146 { 1147 name: "double aggregate with same value and same alias - SELECT mean(value) as mv, max(value) as mv FROM db0.rp0.cpu", 1148 command: `SELECT mean(value) as mv, max(value) as mv FROM db0.rp0.cpu`, 1149 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mv","mv"],"values":[["1970-01-01T00:00:00Z",1.5,2]]}]}]}`, 1150 }, 1151 { 1152 name: "double aggregate with non-existent field - SELECT mean(value), max(foo) FROM db0.rp0.cpu", 1153 command: `SELECT mean(value), max(foo) FROM db0.rp0.cpu`, 1154 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean","max"],"values":[["1970-01-01T00:00:00Z",1.5,null]]}]}]}`, 1155 }, 1156 }...) 1157 1158 ctx := context.Background() 1159 test.Run(ctx, t, s) 1160 } 1161 1162 // Ensure the server can handle various group by time cumulative sum queries. 1163 func TestServer_Query_SelectGroupByTimeCumulativeSum(t *testing.T) { 1164 s := OpenServer(t) 1165 defer s.Close() 1166 1167 test := NewTest("db0", "rp0") 1168 test.writes = Writes{ 1169 &Write{data: `cpu value=10 1278010020000000000 1170 cpu value=15 1278010021000000000 1171 cpu value=20 1278010022000000000 1172 cpu value=25 1278010023000000000 1173 `}, 1174 } 1175 1176 test.addQueries([]*Query{ 1177 { 1178 name: "calculate cumulative sum of count", 1179 command: `SELECT cumulative_sum(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1180 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",2],["2010-07-01T18:47:02Z",4]]}]}]}`, 1181 }, 1182 { 1183 name: "calculate cumulative sum of mean", 1184 command: `SELECT cumulative_sum(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1185 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",12.5],["2010-07-01T18:47:02Z",35]]}]}]}`, 1186 }, 1187 { 1188 name: "calculate cumulative sum of median", 1189 command: `SELECT cumulative_sum(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1190 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",12.5],["2010-07-01T18:47:02Z",35]]}]}]}`, 1191 }, 1192 { 1193 name: "calculate cumulative sum of mode", 1194 command: `SELECT cumulative_sum(mode(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1195 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",30]]}]}]}`, 1196 }, 1197 { 1198 name: "calculate cumulative sum of sum", 1199 command: `SELECT cumulative_sum(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1200 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",25],["2010-07-01T18:47:02Z",70]]}]}]}`, 1201 }, 1202 { 1203 name: "calculate cumulative sum of first", 1204 command: `SELECT cumulative_sum(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1205 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",30]]}]}]}`, 1206 }, 1207 { 1208 name: "calculate cumulative sum of last", 1209 command: `SELECT cumulative_sum(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1210 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",40]]}]}]}`, 1211 }, 1212 { 1213 name: "calculate cumulative sum of min", 1214 command: `SELECT cumulative_sum(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1215 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",30]]}]}]}`, 1216 }, 1217 { 1218 name: "calculate cumulative sum of max", 1219 command: `SELECT cumulative_sum(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1220 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",40]]}]}]}`, 1221 }, 1222 { 1223 name: "calculate cumulative sum of percentile", 1224 command: `SELECT cumulative_sum(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 1225 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",30]]}]}]}`, 1226 }, 1227 }...) 1228 1229 ctx := context.Background() 1230 test.Run(ctx, t, s) 1231 } 1232 1233 // Ensure the server can handle various group by time cumulative sum queries with fill. 1234 func TestServer_Query_SelectGroupByTimeCumulativeSumWithFill(t *testing.T) { 1235 s := OpenServer(t) 1236 defer s.Close() 1237 1238 test := NewTest("db0", "rp0") 1239 test.writes = Writes{ 1240 &Write{data: `cpu value=10 1278010020000000000 1241 cpu value=20 1278010021000000000 1242 `}, 1243 } 1244 1245 test.addQueries([]*Query{ 1246 { 1247 name: "calculate cumulative sum of count with fill 0", 1248 command: `SELECT cumulative_sum(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1249 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",2],["2010-07-01T18:47:02Z",2]]}]}]}`, 1250 }, 1251 { 1252 name: "calculate cumulative sum of count with fill previous", 1253 command: `SELECT cumulative_sum(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1254 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",2],["2010-07-01T18:47:02Z",4]]}]}]}`, 1255 }, 1256 { 1257 name: "calculate cumulative sum of mean with fill 0", 1258 command: `SELECT cumulative_sum(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1259 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",15]]}]}]}`, 1260 }, 1261 { 1262 name: "calculate cumulative sum of mean with fill previous", 1263 command: `SELECT cumulative_sum(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1264 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",30]]}]}]}`, 1265 }, 1266 { 1267 name: "calculate cumulative sum of median with fill 0", 1268 command: `SELECT cumulative_sum(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1269 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",15]]}]}]}`, 1270 }, 1271 { 1272 name: "calculate cumulative sum of median with fill previous", 1273 command: `SELECT cumulative_sum(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1274 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",30]]}]}]}`, 1275 }, 1276 { 1277 name: "calculate cumulative sum of mode with fill 0", 1278 command: `SELECT cumulative_sum(mode(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1279 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",10]]}]}]}`, 1280 }, 1281 { 1282 name: "calculate cumulative sum of mode with fill previous", 1283 command: `SELECT cumulative_sum(mode(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1284 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",20]]}]}]}`, 1285 }, 1286 { 1287 name: "calculate cumulative sum of sum with fill 0", 1288 command: `SELECT cumulative_sum(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1289 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",30],["2010-07-01T18:47:02Z",30]]}]}]}`, 1290 }, 1291 { 1292 name: "calculate cumulative sum of sum with fill previous", 1293 command: `SELECT cumulative_sum(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1294 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",30],["2010-07-01T18:47:02Z",60]]}]}]}`, 1295 }, 1296 { 1297 name: "calculate cumulative sum of first with fill 0", 1298 command: `SELECT cumulative_sum(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1299 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",10]]}]}]}`, 1300 }, 1301 { 1302 name: "calculate cumulative sum of first with fill previous", 1303 command: `SELECT cumulative_sum(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1304 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",20]]}]}]}`, 1305 }, 1306 { 1307 name: "calculate cumulative sum of last with fill 0", 1308 command: `SELECT cumulative_sum(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1309 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",20]]}]}]}`, 1310 }, 1311 { 1312 name: "calculate cumulative sum of last with fill previous", 1313 command: `SELECT cumulative_sum(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1314 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",40]]}]}]}`, 1315 }, 1316 { 1317 name: "calculate cumulative sum of min with fill 0", 1318 command: `SELECT cumulative_sum(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1319 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",10]]}]}]}`, 1320 }, 1321 { 1322 name: "calculate cumulative sum of min with fill previous", 1323 command: `SELECT cumulative_sum(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1324 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",20]]}]}]}`, 1325 }, 1326 { 1327 name: "calculate cumulative sum of max with fill 0", 1328 command: `SELECT cumulative_sum(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1329 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",20]]}]}]}`, 1330 }, 1331 { 1332 name: "calculate cumulative sum of max with fill previous", 1333 command: `SELECT cumulative_sum(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1334 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",40]]}]}]}`, 1335 }, 1336 { 1337 name: "calculate cumulative sum of percentile with fill 0", 1338 command: `SELECT cumulative_sum(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 1339 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",10]]}]}]}`, 1340 }, 1341 { 1342 name: "calculate cumulative sum of percentile with fill previous", 1343 command: `SELECT cumulative_sum(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 1344 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",20]]}]}]}`, 1345 }, 1346 }...) 1347 1348 ctx := context.Background() 1349 test.Run(ctx, t, s) 1350 } 1351 1352 func TestServer_Query_Aggregates_Int(t *testing.T) { 1353 s := OpenServer(t) 1354 defer s.Close() 1355 1356 test := NewTest("db0", "rp0") 1357 test.writes = Writes{ 1358 &Write{data: strings.Join([]string{ 1359 fmt.Sprintf(`int value=45 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 1360 }, "\n")}, 1361 } 1362 1363 test.addQueries([]*Query{ 1364 // int64 1365 { 1366 name: "stddev with just one point - int", 1367 params: url.Values{"db": []string{"db0"}}, 1368 command: `SELECT STDDEV(value) FROM int`, 1369 exp: `{"results":[{"statement_id":0,"series":[{"name":"int","columns":["time","stddev"],"values":[["1970-01-01T00:00:00Z",null]]}]}]}`, 1370 }, 1371 }...) 1372 1373 ctx := context.Background() 1374 test.Run(ctx, t, s) 1375 } 1376 1377 func TestServer_Query_MathWithFill(t *testing.T) { 1378 s := OpenServer(t) 1379 defer s.Close() 1380 1381 test := NewTest("db0", "rp0") 1382 test.writes = Writes{ 1383 &Write{data: `cpu value=15 1278010020000000000 1384 `}, 1385 } 1386 1387 test.addQueries([]*Query{ 1388 { 1389 name: "multiplication with fill previous", 1390 command: `SELECT 4*mean(value) FROM db0.rp0.cpu WHERE time >= '2010-07-01 18:47:00' AND time < '2010-07-01 18:48:30' GROUP BY time(30s) FILL(previous)`, 1391 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean"],"values":[["2010-07-01T18:47:00Z",60],["2010-07-01T18:47:30Z",60],["2010-07-01T18:48:00Z",60]]}]}]}`, 1392 }, 1393 { 1394 name: "multiplication of mode value with fill previous", 1395 command: `SELECT 4*mode(value) FROM db0.rp0.cpu WHERE time >= '2010-07-01 18:47:00' AND time < '2010-07-01 18:48:30' GROUP BY time(30s) FILL(previous)`, 1396 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mode"],"values":[["2010-07-01T18:47:00Z",60],["2010-07-01T18:47:30Z",60],["2010-07-01T18:48:00Z",60]]}]}]}`, 1397 }, 1398 }...) 1399 1400 ctx := context.Background() 1401 test.Run(ctx, t, s) 1402 } 1403 1404 // mergeMany ensures that when merging many series together and some of them have a different number 1405 // of points than others in a group by interval the results are correct 1406 func TestServer_Query_MergeMany(t *testing.T) { 1407 s := OpenServer(t) 1408 defer s.Close() 1409 1410 test := NewTest("db0", "rp0") 1411 1412 var writes []string 1413 for i := 1; i < 11; i++ { 1414 for j := 1; j < 5+i%3; j++ { 1415 data := fmt.Sprintf(`cpu,host=server_%d value=22 %d`, i, time.Unix(int64(j), int64(0)).UTC().UnixNano()) 1416 writes = append(writes, data) 1417 } 1418 } 1419 test.writes = Writes{ 1420 &Write{data: strings.Join(writes, "\n")}, 1421 } 1422 1423 test.addQueries([]*Query{ 1424 { 1425 name: "GROUP by time", 1426 command: `SELECT count(value) FROM db0.rp0.cpu WHERE time >= '1970-01-01T00:00:01Z' AND time <= '1970-01-01T00:00:06Z' GROUP BY time(1s)`, 1427 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["1970-01-01T00:00:01Z",10],["1970-01-01T00:00:02Z",10],["1970-01-01T00:00:03Z",10],["1970-01-01T00:00:04Z",10],["1970-01-01T00:00:05Z",7],["1970-01-01T00:00:06Z",3]]}]}]}`, 1428 }, 1429 { 1430 skip: "Skipped OSS", 1431 name: "GROUP by tag - FIXME issue #2875", 1432 command: `SELECT count(value) FROM db0.rp0.cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:00Z' group by host`, 1433 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","count"],"values":[["2000-01-01T00:00:00Z",1]]},{"name":"cpu","tags":{"host":"server02"},"columns":["time","count"],"values":[["2000-01-01T00:00:00Z",1]]},{"name":"cpu","tags":{"host":"server03"},"columns":["time","count"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, 1434 }, 1435 { 1436 name: "GROUP by field", 1437 command: `SELECT count(value) FROM db0.rp0.cpu group by value`, 1438 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"value":""},"columns":["time","count"],"values":[["1970-01-01T00:00:00Z",50]]}]}]}`, 1439 }, 1440 }...) 1441 1442 ctx := context.Background() 1443 test.Run(ctx, t, s) 1444 } 1445 1446 func TestServer_Query_SelectGroupByTime_MultipleAggregates(t *testing.T) { 1447 s := OpenServer(t) 1448 defer s.Close() 1449 1450 test := NewTest("db0", "rp0") 1451 test.writes = Writes{ 1452 &Write{data: `test,t=a x=1i 1000000000 1453 test,t=b y=1i 1000000000 1454 test,t=a x=2i 2000000000 1455 test,t=b y=2i 2000000000 1456 test,t=a x=3i 3000000000 1457 test,t=b y=3i 3000000000 1458 `}, 1459 } 1460 1461 test.addQueries([]*Query{ 1462 { 1463 name: "two aggregates with a group by host", 1464 command: `SELECT mean(x) as x, mean(y) as y from db0.rp0.test where time >= 1s and time < 4s group by t, time(1s)`, 1465 exp: `{"results":[{"statement_id":0,"series":[{"name":"test","tags":{"t":"a"},"columns":["time","x","y"],"values":[["1970-01-01T00:00:01Z",1,null],["1970-01-01T00:00:02Z",2,null],["1970-01-01T00:00:03Z",3,null]]},{"name":"test","tags":{"t":"b"},"columns":["time","x","y"],"values":[["1970-01-01T00:00:01Z",null,1],["1970-01-01T00:00:02Z",null,2],["1970-01-01T00:00:03Z",null,3]]}]}]}`, 1466 }, 1467 }...) 1468 1469 ctx := context.Background() 1470 test.Run(ctx, t, s) 1471 } 1472 1473 func TestServer_Query_Regex(t *testing.T) { 1474 s := OpenServer(t) 1475 defer s.Close() 1476 1477 writes := []string{ 1478 fmt.Sprintf(`cpu1,host=server01 value=10 %d`, mustParseTime(time.RFC3339Nano, "2015-02-28T01:03:36.703820946Z").UnixNano()), 1479 fmt.Sprintf(`cpu2,host=server01 value=20 %d`, mustParseTime(time.RFC3339Nano, "2015-02-28T01:03:36.703820946Z").UnixNano()), 1480 fmt.Sprintf(`cpu3,host=server01 value=30 %d`, mustParseTime(time.RFC3339Nano, "2015-02-28T01:03:36.703820946Z").UnixNano()), 1481 } 1482 1483 test := NewTest("db0", "rp0") 1484 test.writes = Writes{ 1485 &Write{data: strings.Join(writes, "\n")}, 1486 } 1487 1488 test.addQueries([]*Query{ 1489 { 1490 name: "default db and rp", 1491 command: `SELECT * FROM /cpu[13]/`, 1492 params: url.Values{"db": []string{"db0"}}, 1493 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","host","value"],"values":[["2015-02-28T01:03:36.703820946Z","server01",10]]},{"name":"cpu3","columns":["time","host","value"],"values":[["2015-02-28T01:03:36.703820946Z","server01",30]]}]}]}`, 1494 }, 1495 { 1496 name: "default db and rp with GROUP BY *", 1497 command: `SELECT * FROM /cpu[13]/ GROUP BY *`, 1498 params: url.Values{"db": []string{"db0"}}, 1499 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","tags":{"host":"server01"},"columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",10]]},{"name":"cpu3","tags":{"host":"server01"},"columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",30]]}]}]}`, 1500 }, 1501 { 1502 name: "specifying db and rp", 1503 command: `SELECT * FROM db0.rp0./cpu[13]/ GROUP BY *`, 1504 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","tags":{"host":"server01"},"columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",10]]},{"name":"cpu3","tags":{"host":"server01"},"columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",30]]}]}]}`, 1505 }, 1506 { 1507 name: "default db and specified rp", 1508 command: `SELECT * FROM rp0./cpu[13]/ GROUP BY *`, 1509 params: url.Values{"db": []string{"db0"}}, 1510 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","tags":{"host":"server01"},"columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",10]]},{"name":"cpu3","tags":{"host":"server01"},"columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",30]]}]}]}`, 1511 }, 1512 { 1513 name: "specified db and default rp", 1514 command: `SELECT * FROM db0../cpu[13]/ GROUP BY *`, 1515 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","tags":{"host":"server01"},"columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",10]]},{"name":"cpu3","tags":{"host":"server01"},"columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",30]]}]}]}`, 1516 }, 1517 { 1518 name: "map field type with a regex source", 1519 command: `SELECT value FROM /cpu[13]/`, 1520 params: url.Values{"db": []string{"db0"}}, 1521 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu1","columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",10]]},{"name":"cpu3","columns":["time","value"],"values":[["2015-02-28T01:03:36.703820946Z",30]]}]}]}`, 1522 }, 1523 }...) 1524 1525 ctx := context.Background() 1526 test.Run(ctx, t, s) 1527 } 1528 1529 func TestServer_Query_Aggregates_Load(t *testing.T) { 1530 s := OpenServer(t) 1531 defer s.Close() 1532 1533 test := NewTest("db0", "rp0") 1534 test.writes = Writes{ 1535 &Write{data: strings.Join([]string{ 1536 fmt.Sprintf(`load,region=us-east,host=serverA value=20.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 1537 fmt.Sprintf(`load,region=us-east,host=serverB value=30.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 1538 fmt.Sprintf(`load,region=us-west,host=serverC value=100.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 1539 }, "\n")}, 1540 } 1541 1542 test.addQueries([]*Query{ 1543 { 1544 name: "group by multiple dimensions", 1545 params: url.Values{"db": []string{"db0"}}, 1546 command: `SELECT sum(value) FROM load GROUP BY region, host`, 1547 exp: `{"results":[{"statement_id":0,"series":[{"name":"load","tags":{"host":"serverA","region":"us-east"},"columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",20]]},{"name":"load","tags":{"host":"serverB","region":"us-east"},"columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",30]]},{"name":"load","tags":{"host":"serverC","region":"us-west"},"columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",100]]}]}]}`, 1548 }, 1549 { 1550 name: "group by multiple dimensions", 1551 params: url.Values{"db": []string{"db0"}}, 1552 command: `SELECT sum(value)*2 FROM load`, 1553 exp: `{"results":[{"statement_id":0,"series":[{"name":"load","columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",300]]}]}]}`, 1554 }, 1555 { 1556 name: "group by multiple dimensions", 1557 params: url.Values{"db": []string{"db0"}}, 1558 command: `SELECT sum(value)/2 FROM load`, 1559 exp: `{"results":[{"statement_id":0,"series":[{"name":"load","columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",75]]}]}]}`, 1560 }, 1561 }...) 1562 1563 ctx := context.Background() 1564 test.Run(ctx, t, s) 1565 } 1566 1567 func TestServer_Query_SLimitAndSOffset(t *testing.T) { 1568 s := OpenServer(t) 1569 defer s.Close() 1570 1571 test := NewTest("db0", "rp0") 1572 1573 var writes []string 1574 for i := 1; i < 10; i++ { 1575 data := fmt.Sprintf(`cpu,region=us-east,host=server-%d value=%d %d`, i, i, time.Unix(int64(i), int64(0)).UnixNano()) 1576 writes = append(writes, data) 1577 } 1578 test.writes = Writes{ 1579 &Write{data: strings.Join(writes, "\n")}, 1580 } 1581 1582 test.addQueries([]*Query{ 1583 { 1584 name: "SLIMIT 2 SOFFSET 1", 1585 command: `SELECT count(value) FROM db0.rp0.cpu GROUP BY * SLIMIT 2 SOFFSET 1`, 1586 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server-2","region":"us-east"},"columns":["time","count"],"values":[["1970-01-01T00:00:00Z",1]]},{"name":"cpu","tags":{"host":"server-3","region":"us-east"},"columns":["time","count"],"values":[["1970-01-01T00:00:00Z",1]]}]}]}`, 1587 }, 1588 { 1589 name: "SLIMIT 2 SOFFSET 3", 1590 command: `SELECT count(value) FROM db0.rp0.cpu GROUP BY * SLIMIT 2 SOFFSET 3`, 1591 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server-4","region":"us-east"},"columns":["time","count"],"values":[["1970-01-01T00:00:00Z",1]]},{"name":"cpu","tags":{"host":"server-5","region":"us-east"},"columns":["time","count"],"values":[["1970-01-01T00:00:00Z",1]]}]}]}`, 1592 }, 1593 { 1594 name: "SLIMIT 3 SOFFSET 8", 1595 command: `SELECT count(value) FROM db0.rp0.cpu GROUP BY * SLIMIT 3 SOFFSET 8`, 1596 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server-9","region":"us-east"},"columns":["time","count"],"values":[["1970-01-01T00:00:00Z",1]]}]}]}`, 1597 }, 1598 }...) 1599 1600 ctx := context.Background() 1601 test.Run(ctx, t, s) 1602 } 1603 1604 func TestServer_Query_CumulativeCount(t *testing.T) { 1605 s := OpenServer(t) 1606 defer s.Close() 1607 1608 test := NewTest("db0", "rp0") 1609 test.writes = Writes{ 1610 &Write{data: `events signup=t 1005832000 1611 events signup=t 1048283000 1612 events signup=t 1784832000 1613 events signup=t 2000000000 1614 events signup=t 3084890000 1615 events signup=t 3838400000 1616 `}, 1617 } 1618 1619 test.addQueries([]*Query{ 1620 { 1621 name: "cumulative count", 1622 command: `SELECT cumulative_sum(count(signup)) from db0.rp0.events where time >= 1s and time < 4s group by time(1s)`, 1623 exp: `{"results":[{"statement_id":0,"series":[{"name":"events","columns":["time","cumulative_sum"],"values":[["1970-01-01T00:00:01Z",3],["1970-01-01T00:00:02Z",4],["1970-01-01T00:00:03Z",6]]}]}]}`, 1624 }, 1625 }...) 1626 1627 ctx := context.Background() 1628 test.Run(ctx, t, s) 1629 } 1630 1631 func TestServer_Query_Aggregates_String(t *testing.T) { 1632 s := OpenServer(t) 1633 defer s.Close() 1634 1635 test := NewTest("db0", "rp0") 1636 test.writes = Writes{ 1637 &Write{data: strings.Join([]string{ 1638 fmt.Sprintf(`stringdata value="first" %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 1639 fmt.Sprintf(`stringdata value="last" %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:04Z").UnixNano()), 1640 }, "\n")}, 1641 } 1642 1643 test.addQueries([]*Query{ 1644 // strings 1645 { 1646 name: "STDDEV on string data - string", 1647 params: url.Values{"db": []string{"db0"}}, 1648 command: `SELECT STDDEV(value) FROM stringdata`, 1649 exp: `{"results":[{"statement_id":0,"series":[{"name":"stringdata","columns":["time","stddev"],"values":[["1970-01-01T00:00:00Z",null]]}]}]}`, 1650 skip: "Skipped OSS", // FIXME(benbjohnson): allow non-float var ref expr in cursor iterator 1651 }, 1652 { 1653 name: "MEAN on string data - string", 1654 params: url.Values{"db": []string{"db0"}}, 1655 command: `SELECT MEAN(value) FROM stringdata`, 1656 exp: `{"results":[{"statement_id":0,"series":[{"name":"stringdata","columns":["time","mean"],"values":[["1970-01-01T00:00:00Z",0]]}]}]}`, 1657 skip: "Skipped OSS", // FIXME(benbjohnson): allow non-float var ref expr in cursor iterator 1658 }, 1659 { 1660 name: "MEDIAN on string data - string", 1661 params: url.Values{"db": []string{"db0"}}, 1662 command: `SELECT MEDIAN(value) FROM stringdata`, 1663 exp: `{"results":[{"statement_id":0,"series":[{"name":"stringdata","columns":["time","median"],"values":[["1970-01-01T00:00:00Z",null]]}]}]}`, 1664 skip: "Skipped OSS", // FIXME(benbjohnson): allow non-float var ref expr in cursor iterator 1665 }, 1666 { 1667 name: "COUNT on string data - string", 1668 params: url.Values{"db": []string{"db0"}}, 1669 command: `SELECT COUNT(value) FROM stringdata`, 1670 exp: `{"results":[{"statement_id":0,"series":[{"name":"stringdata","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",2]]}]}]}`, 1671 skip: "Skipped OSS", // FIXME(benbjohnson): allow non-float var ref expr in cursor iterator 1672 }, 1673 { 1674 name: "FIRST on string data - string", 1675 params: url.Values{"db": []string{"db0"}}, 1676 command: `SELECT FIRST(value) FROM stringdata`, 1677 exp: `{"results":[{"statement_id":0,"series":[{"name":"stringdata","columns":["time","first"],"values":[["2000-01-01T00:00:03Z","first"]]}]}]}`, 1678 skip: "Skipped OSS", // FIXME(benbjohnson): allow non-float var ref expr in cursor iterator 1679 }, 1680 { 1681 name: "LAST on string data - string", 1682 params: url.Values{"db": []string{"db0"}}, 1683 command: `SELECT LAST(value) FROM stringdata`, 1684 exp: `{"results":[{"statement_id":0,"series":[{"name":"stringdata","columns":["time","last"],"values":[["2000-01-01T00:00:04Z","last"]]}]}]}`, 1685 skip: "Skipped OSS", // FIXME(benbjohnson): allow non-float var ref expr in cursor iterator 1686 }, 1687 }...) 1688 1689 ctx := context.Background() 1690 test.Run(ctx, t, s) 1691 } 1692 1693 func TestServer_Query_AggregateSelectors(t *testing.T) { 1694 s := OpenServer(t) 1695 defer s.Close() 1696 1697 writes := []string{ 1698 fmt.Sprintf(`network,host=server01,region=west,core=1 rx=10i,tx=20i,core=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 1699 fmt.Sprintf(`network,host=server02,region=west,core=2 rx=40i,tx=50i,core=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 1700 fmt.Sprintf(`network,host=server03,region=east,core=3 rx=40i,tx=55i,core=4i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 1701 fmt.Sprintf(`network,host=server04,region=east,core=4 rx=40i,tx=60i,core=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()), 1702 fmt.Sprintf(`network,host=server05,region=west,core=1 rx=50i,tx=70i,core=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:40Z").UnixNano()), 1703 fmt.Sprintf(`network,host=server06,region=east,core=2 rx=50i,tx=40i,core=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:50Z").UnixNano()), 1704 fmt.Sprintf(`network,host=server07,region=west,core=3 rx=70i,tx=30i,core=4i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 1705 fmt.Sprintf(`network,host=server08,region=east,core=4 rx=90i,tx=10i,core=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:10Z").UnixNano()), 1706 fmt.Sprintf(`network,host=server09,region=east,core=1 rx=5i,tx=4i,core=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:20Z").UnixNano()), 1707 } 1708 1709 test := NewTest("db0", "rp0") 1710 test.writes = Writes{ 1711 &Write{data: strings.Join(writes, "\n")}, 1712 } 1713 1714 test.addQueries([]*Query{ 1715 { 1716 name: "baseline", 1717 params: url.Values{"db": []string{"db0"}}, 1718 command: `SELECT * FROM network`, 1719 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","core","core_1","host","region","rx","tx"],"values":[["2000-01-01T00:00:00Z",2,"1","server01","west",10,20],["2000-01-01T00:00:10Z",3,"2","server02","west",40,50],["2000-01-01T00:00:20Z",4,"3","server03","east",40,55],["2000-01-01T00:00:30Z",1,"4","server04","east",40,60],["2000-01-01T00:00:40Z",2,"1","server05","west",50,70],["2000-01-01T00:00:50Z",3,"2","server06","east",50,40],["2000-01-01T00:01:00Z",4,"3","server07","west",70,30],["2000-01-01T00:01:10Z",1,"4","server08","east",90,10],["2000-01-01T00:01:20Z",2,"1","server09","east",5,4]]}]}]}`, 1720 }, 1721 { 1722 name: "max - baseline 30s", 1723 params: url.Values{"db": []string{"db0"}}, 1724 command: `SELECT max(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1725 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","max"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",90]]}]}]}`, 1726 }, 1727 { 1728 name: "max - baseline 30s - epoch ms", 1729 params: url.Values{"db": []string{"db0"}, "epoch": []string{"ms"}}, 1730 command: `SELECT max(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1731 exp: fmt.Sprintf( 1732 `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","max"],"values":[[%d,40],[%d,50],[%d,90]]}]}]}`, 1733 mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()/int64(time.Millisecond), 1734 mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()/int64(time.Millisecond), 1735 mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()/int64(time.Millisecond), 1736 ), 1737 }, 1738 { 1739 name: "max - tx", 1740 params: url.Values{"db": []string{"db0"}}, 1741 command: `SELECT tx, max(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1742 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","tx","max"],"values":[["2000-01-01T00:00:00Z",50,40],["2000-01-01T00:00:30Z",70,50],["2000-01-01T00:01:00Z",10,90]]}]}]}`, 1743 }, 1744 { 1745 name: "max - time", 1746 params: url.Values{"db": []string{"db0"}}, 1747 command: `SELECT time, max(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1748 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","max"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",90]]}]}]}`, 1749 }, 1750 { 1751 name: "max - time and tx", 1752 params: url.Values{"db": []string{"db0"}}, 1753 command: `SELECT time, tx, max(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1754 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","tx","max"],"values":[["2000-01-01T00:00:00Z",50,40],["2000-01-01T00:00:30Z",70,50],["2000-01-01T00:01:00Z",10,90]]}]}]}`, 1755 }, 1756 { 1757 name: "min - baseline 30s", 1758 params: url.Values{"db": []string{"db0"}}, 1759 command: `SELECT min(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1760 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","min"],"values":[["2000-01-01T00:00:00Z",10],["2000-01-01T00:00:30Z",40],["2000-01-01T00:01:00Z",5]]}]}]}`, 1761 }, 1762 { 1763 name: "min - tx", 1764 params: url.Values{"db": []string{"db0"}}, 1765 command: `SELECT tx, min(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1766 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","tx","min"],"values":[["2000-01-01T00:00:00Z",20,10],["2000-01-01T00:00:30Z",60,40],["2000-01-01T00:01:00Z",4,5]]}]}]}`, 1767 }, 1768 { 1769 name: "min - time", 1770 params: url.Values{"db": []string{"db0"}}, 1771 command: `SELECT time, min(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1772 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","min"],"values":[["2000-01-01T00:00:00Z",10],["2000-01-01T00:00:30Z",40],["2000-01-01T00:01:00Z",5]]}]}]}`, 1773 }, 1774 { 1775 name: "min - time and tx", 1776 params: url.Values{"db": []string{"db0"}}, 1777 command: `SELECT time, tx, min(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1778 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","tx","min"],"values":[["2000-01-01T00:00:00Z",20,10],["2000-01-01T00:00:30Z",60,40],["2000-01-01T00:01:00Z",4,5]]}]}]}`, 1779 }, 1780 { 1781 name: "max,min - baseline 30s", 1782 params: url.Values{"db": []string{"db0"}}, 1783 command: `SELECT max(rx), min(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1784 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","max","min"],"values":[["2000-01-01T00:00:00Z",40,10],["2000-01-01T00:00:30Z",50,40],["2000-01-01T00:01:00Z",90,5]]}]}]}`, 1785 }, 1786 { 1787 name: "first - baseline 30s", 1788 params: url.Values{"db": []string{"db0"}}, 1789 command: `SELECT first(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1790 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",10],["2000-01-01T00:00:30Z",40],["2000-01-01T00:01:00Z",70]]}]}]}`, 1791 }, 1792 { 1793 name: "first - tx", 1794 params: url.Values{"db": []string{"db0"}}, 1795 command: `SELECT time, tx, first(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1796 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","tx","first"],"values":[["2000-01-01T00:00:00Z",20,10],["2000-01-01T00:00:30Z",60,40],["2000-01-01T00:01:00Z",30,70]]}]}]}`, 1797 }, 1798 { 1799 name: "first - time", 1800 params: url.Values{"db": []string{"db0"}}, 1801 command: `SELECT time, first(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1802 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",10],["2000-01-01T00:00:30Z",40],["2000-01-01T00:01:00Z",70]]}]}]}`, 1803 }, 1804 { 1805 name: "first - time and tx", 1806 params: url.Values{"db": []string{"db0"}}, 1807 command: `SELECT time, tx, first(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1808 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","tx","first"],"values":[["2000-01-01T00:00:00Z",20,10],["2000-01-01T00:00:30Z",60,40],["2000-01-01T00:01:00Z",30,70]]}]}]}`, 1809 }, 1810 { 1811 name: "last - baseline 30s", 1812 params: url.Values{"db": []string{"db0"}}, 1813 command: `SELECT last(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1814 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","last"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",5]]}]}]}`, 1815 }, 1816 { 1817 name: "last - tx", 1818 params: url.Values{"db": []string{"db0"}}, 1819 command: `SELECT tx, last(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1820 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","tx","last"],"values":[["2000-01-01T00:00:00Z",55,40],["2000-01-01T00:00:30Z",40,50],["2000-01-01T00:01:00Z",4,5]]}]}]}`, 1821 }, 1822 { 1823 name: "last - time", 1824 params: url.Values{"db": []string{"db0"}}, 1825 command: `SELECT time, last(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1826 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","last"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",5]]}]}]}`, 1827 }, 1828 { 1829 name: "last - time and tx", 1830 params: url.Values{"db": []string{"db0"}}, 1831 command: `SELECT time, tx, last(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1832 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","tx","last"],"values":[["2000-01-01T00:00:00Z",55,40],["2000-01-01T00:00:30Z",40,50],["2000-01-01T00:01:00Z",4,5]]}]}]}`, 1833 }, 1834 { 1835 name: "count - baseline 30s", 1836 params: url.Values{"db": []string{"db0"}}, 1837 command: `SELECT count(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1838 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","count"],"values":[["2000-01-01T00:00:00Z",3],["2000-01-01T00:00:30Z",3],["2000-01-01T00:01:00Z",3]]}]}]}`, 1839 }, 1840 { 1841 name: "count - time", 1842 params: url.Values{"db": []string{"db0"}}, 1843 command: `SELECT time, count(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1844 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","count"],"values":[["2000-01-01T00:00:00Z",3],["2000-01-01T00:00:30Z",3],["2000-01-01T00:01:00Z",3]]}]}]}`, 1845 }, 1846 { 1847 name: "count - tx", 1848 params: url.Values{"db": []string{"db0"}}, 1849 command: `SELECT tx, count(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1850 exp: `{"results":[{"statement_id":0,"error":"mixing aggregate and non-aggregate queries is not supported"}]}`, 1851 }, 1852 { 1853 name: "distinct - baseline 30s", 1854 params: url.Values{"db": []string{"db0"}}, 1855 command: `SELECT distinct(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1856 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","distinct"],"values":[["2000-01-01T00:00:00Z",10],["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",70],["2000-01-01T00:01:00Z",90],["2000-01-01T00:01:00Z",5]]}]}]}`, 1857 }, 1858 { 1859 name: "distinct - time", 1860 params: url.Values{"db": []string{"db0"}}, 1861 command: `SELECT time, distinct(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1862 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","distinct"],"values":[["2000-01-01T00:00:00Z",10],["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",70],["2000-01-01T00:01:00Z",90],["2000-01-01T00:01:00Z",5]]}]}]}`, 1863 }, 1864 { 1865 name: "distinct - tx", 1866 params: url.Values{"db": []string{"db0"}}, 1867 command: `SELECT tx, distinct(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1868 exp: `{"results":[{"statement_id":0,"error":"aggregate function distinct() cannot be combined with other functions or fields"}]}`, 1869 }, 1870 { 1871 name: "mean - baseline 30s", 1872 params: url.Values{"db": []string{"db0"}}, 1873 command: `SELECT mean(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1874 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",30],["2000-01-01T00:00:30Z",46.666666666666664],["2000-01-01T00:01:00Z",55]]}]}]}`, 1875 }, 1876 { 1877 name: "mean - time", 1878 params: url.Values{"db": []string{"db0"}}, 1879 command: `SELECT time, mean(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1880 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",30],["2000-01-01T00:00:30Z",46.666666666666664],["2000-01-01T00:01:00Z",55]]}]}]}`, 1881 }, 1882 { 1883 name: "mean - tx", 1884 params: url.Values{"db": []string{"db0"}}, 1885 command: `SELECT tx, mean(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1886 exp: `{"results":[{"statement_id":0,"error":"mixing aggregate and non-aggregate queries is not supported"}]}`, 1887 }, 1888 { 1889 name: "median - baseline 30s", 1890 params: url.Values{"db": []string{"db0"}}, 1891 command: `SELECT median(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1892 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","median"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",70]]}]}]}`, 1893 }, 1894 { 1895 name: "median - time", 1896 params: url.Values{"db": []string{"db0"}}, 1897 command: `SELECT time, median(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1898 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","median"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",70]]}]}]}`, 1899 }, 1900 { 1901 name: "median - tx", 1902 params: url.Values{"db": []string{"db0"}}, 1903 command: `SELECT tx, median(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1904 exp: `{"results":[{"statement_id":0,"error":"mixing aggregate and non-aggregate queries is not supported"}]}`, 1905 }, 1906 { 1907 name: "mode - baseline 30s", 1908 params: url.Values{"db": []string{"db0"}}, 1909 command: `SELECT mode(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1910 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","mode"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",5]]}]}]}`, 1911 }, 1912 { 1913 name: "mode - time", 1914 params: url.Values{"db": []string{"db0"}}, 1915 command: `SELECT time, mode(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1916 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","mode"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",5]]}]}]}`, 1917 }, 1918 { 1919 name: "mode - tx", 1920 params: url.Values{"db": []string{"db0"}}, 1921 command: `SELECT tx, mode(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1922 exp: `{"results":[{"statement_id":0,"error":"mixing aggregate and non-aggregate queries is not supported"}]}`, 1923 }, 1924 { 1925 name: "spread - baseline 30s", 1926 params: url.Values{"db": []string{"db0"}}, 1927 command: `SELECT spread(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1928 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","spread"],"values":[["2000-01-01T00:00:00Z",30],["2000-01-01T00:00:30Z",10],["2000-01-01T00:01:00Z",85]]}]}]}`, 1929 }, 1930 { 1931 name: "spread - time", 1932 params: url.Values{"db": []string{"db0"}}, 1933 command: `SELECT time, spread(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1934 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","spread"],"values":[["2000-01-01T00:00:00Z",30],["2000-01-01T00:00:30Z",10],["2000-01-01T00:01:00Z",85]]}]}]}`, 1935 }, 1936 { 1937 name: "spread - tx", 1938 params: url.Values{"db": []string{"db0"}}, 1939 command: `SELECT tx, spread(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1940 exp: `{"results":[{"statement_id":0,"error":"mixing aggregate and non-aggregate queries is not supported"}]}`, 1941 }, 1942 { 1943 name: "stddev - baseline 30s", 1944 params: url.Values{"db": []string{"db0"}}, 1945 command: `SELECT stddev(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1946 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","stddev"],"values":[["2000-01-01T00:00:00Z",17.320508075688775],["2000-01-01T00:00:30Z",5.773502691896258],["2000-01-01T00:01:00Z",44.44097208657794]]}]}]}`, 1947 }, 1948 { 1949 name: "stddev - time", 1950 params: url.Values{"db": []string{"db0"}}, 1951 command: `SELECT time, stddev(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1952 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","stddev"],"values":[["2000-01-01T00:00:00Z",17.320508075688775],["2000-01-01T00:00:30Z",5.773502691896258],["2000-01-01T00:01:00Z",44.44097208657794]]}]}]}`, 1953 }, 1954 { 1955 name: "stddev - tx", 1956 params: url.Values{"db": []string{"db0"}}, 1957 command: `SELECT tx, stddev(rx) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1958 exp: `{"results":[{"statement_id":0,"error":"mixing aggregate and non-aggregate queries is not supported"}]}`, 1959 }, 1960 { 1961 name: "percentile - baseline 30s", 1962 params: url.Values{"db": []string{"db0"}}, 1963 command: `SELECT percentile(rx, 75) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1964 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","percentile"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",70]]}]}]}`, 1965 }, 1966 { 1967 name: "percentile - time", 1968 params: url.Values{"db": []string{"db0"}}, 1969 command: `SELECT time, percentile(rx, 75) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1970 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","percentile"],"values":[["2000-01-01T00:00:00Z",40],["2000-01-01T00:00:30Z",50],["2000-01-01T00:01:00Z",70]]}]}]}`, 1971 }, 1972 { 1973 name: "percentile - tx", 1974 params: url.Values{"db": []string{"db0"}}, 1975 command: `SELECT tx, percentile(rx, 75) FROM network where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:29Z' group by time(30s)`, 1976 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","tx","percentile"],"values":[["2000-01-01T00:00:00Z",50,40],["2000-01-01T00:00:30Z",70,50],["2000-01-01T00:01:00Z",30,70]]}]}]}`, 1977 }, 1978 }...) 1979 1980 ctx := context.Background() 1981 test.Run(ctx, t, s) 1982 } 1983 1984 func TestServer_Query_Selectors(t *testing.T) { 1985 s := OpenServer(t) 1986 defer s.Close() 1987 1988 writes := []string{ 1989 fmt.Sprintf(`network,host=server01,region=west,core=1 rx=10i,tx=20i,core=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 1990 fmt.Sprintf(`network,host=server02,region=west,core=2 rx=40i,tx=50i,core=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 1991 fmt.Sprintf(`network,host=server03,region=east,core=3 rx=40i,tx=55i,core=4i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 1992 fmt.Sprintf(`network,host=server04,region=east,core=4 rx=40i,tx=60i,core=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()), 1993 fmt.Sprintf(`network,host=server05,region=west,core=1 rx=50i,tx=70i,core=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:40Z").UnixNano()), 1994 fmt.Sprintf(`network,host=server06,region=east,core=2 rx=50i,tx=40i,core=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:50Z").UnixNano()), 1995 fmt.Sprintf(`network,host=server07,region=west,core=3 rx=70i,tx=30i,core=4i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 1996 fmt.Sprintf(`network,host=server08,region=east,core=4 rx=90i,tx=10i,core=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:10Z").UnixNano()), 1997 fmt.Sprintf(`network,host=server09,region=east,core=1 rx=5i,tx=4i,core=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:20Z").UnixNano()), 1998 } 1999 2000 test := NewTest("db0", "rp0") 2001 test.writes = Writes{ 2002 &Write{data: strings.Join(writes, "\n")}, 2003 } 2004 2005 test.addQueries([]*Query{ 2006 { 2007 name: "max - tx", 2008 params: url.Values{"db": []string{"db0"}}, 2009 command: `SELECT max(tx) FROM network`, 2010 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","max"],"values":[["2000-01-01T00:00:40Z",70]]}]}]}`, 2011 }, 2012 { 2013 name: "min - tx", 2014 params: url.Values{"db": []string{"db0"}}, 2015 command: `SELECT min(tx) FROM network`, 2016 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","min"],"values":[["2000-01-01T00:01:20Z",4]]}]}]}`, 2017 }, 2018 { 2019 name: "first", 2020 params: url.Values{"db": []string{"db0"}}, 2021 command: `SELECT first(tx) FROM network`, 2022 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",20]]}]}]}`, 2023 }, 2024 { 2025 name: "last", 2026 params: url.Values{"db": []string{"db0"}}, 2027 command: `SELECT last(tx) FROM network`, 2028 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","last"],"values":[["2000-01-01T00:01:20Z",4]]}]}]}`, 2029 }, 2030 { 2031 name: "percentile", 2032 params: url.Values{"db": []string{"db0"}}, 2033 command: `SELECT percentile(tx, 50) FROM network`, 2034 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","percentile"],"values":[["2000-01-01T00:00:50Z",40]]}]}]}`, 2035 }, 2036 }...) 2037 2038 ctx := context.Background() 2039 test.Run(ctx, t, s) 2040 } 2041 2042 func TestServer_Query_TopBottomInt(t *testing.T) { 2043 s := OpenServer(t) 2044 defer s.Close() 2045 2046 writes := []string{ 2047 // cpu data with overlapping duplicate values 2048 // hour 0 2049 fmt.Sprintf(`cpu,host=server01 value=2.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2050 fmt.Sprintf(`cpu,host=server02 value=3.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 2051 fmt.Sprintf(`cpu,host=server03 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 2052 // hour 1 2053 fmt.Sprintf(`cpu,host=server04 value=3.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano()), 2054 fmt.Sprintf(`cpu,host=server05 value=7.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:10Z").UnixNano()), 2055 fmt.Sprintf(`cpu,host=server06 value=6.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:20Z").UnixNano()), 2056 // hour 2 2057 fmt.Sprintf(`cpu,host=server07 value=7.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:00Z").UnixNano()), 2058 fmt.Sprintf(`cpu,host=server08 value=9.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:10Z").UnixNano()), 2059 2060 // memory data 2061 // hour 0 2062 fmt.Sprintf(`memory,host=a,service=redis value=1000i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2063 fmt.Sprintf(`memory,host=b,service=mysql value=2000i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2064 fmt.Sprintf(`memory,host=b,service=redis value=1500i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2065 // hour 1 2066 fmt.Sprintf(`memory,host=a,service=redis value=1001i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano()), 2067 fmt.Sprintf(`memory,host=b,service=mysql value=2001i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano()), 2068 fmt.Sprintf(`memory,host=b,service=redis value=1501i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano()), 2069 // hour 2 2070 fmt.Sprintf(`memory,host=a,service=redis value=1002i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:00Z").UnixNano()), 2071 fmt.Sprintf(`memory,host=b,service=mysql value=2002i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:00Z").UnixNano()), 2072 fmt.Sprintf(`memory,host=b,service=redis value=1502i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:00Z").UnixNano()), 2073 } 2074 2075 test := NewTest("db0", "rp0") 2076 test.writes = Writes{ 2077 &Write{data: strings.Join(writes, "\n")}, 2078 } 2079 2080 test.addQueries([]*Query{ 2081 { 2082 name: "top - cpu", 2083 params: url.Values{"db": []string{"db0"}}, 2084 command: `SELECT TOP(value, 1) FROM cpu`, 2085 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T02:00:10Z",9]]}]}]}`, 2086 }, 2087 { 2088 name: "bottom - cpu", 2089 params: url.Values{"db": []string{"db0"}}, 2090 command: `SELECT BOTTOM(value, 1) FROM cpu`, 2091 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","bottom"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 2092 }, 2093 { 2094 name: "top - cpu - 2 values", 2095 params: url.Values{"db": []string{"db0"}}, 2096 command: `SELECT TOP(value, 2) FROM cpu`, 2097 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T01:00:10Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, 2098 }, 2099 { 2100 name: "bottom - cpu - 2 values", 2101 params: url.Values{"db": []string{"db0"}}, 2102 command: `SELECT BOTTOM(value, 2) FROM cpu`, 2103 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","bottom"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:10Z",3]]}]}]}`, 2104 }, 2105 { 2106 name: "top - cpu - 3 values - sorts on tie properly", 2107 params: url.Values{"db": []string{"db0"}}, 2108 command: `SELECT TOP(value, 3) FROM cpu`, 2109 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T01:00:10Z",7],["2000-01-01T02:00:00Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, 2110 }, 2111 { 2112 name: "bottom - cpu - 3 values - sorts on tie properly", 2113 params: url.Values{"db": []string{"db0"}}, 2114 command: `SELECT BOTTOM(value, 3) FROM cpu`, 2115 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","bottom"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:10Z",3],["2000-01-01T01:00:00Z",3]]}]}]}`, 2116 }, 2117 { 2118 name: "top - cpu - with tag", 2119 params: url.Values{"db": []string{"db0"}}, 2120 command: `SELECT TOP(value, host, 2) FROM cpu`, 2121 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","top","host"],"values":[["2000-01-01T01:00:10Z",7,"server05"],["2000-01-01T02:00:10Z",9,"server08"]]}]}]}`, 2122 }, 2123 { 2124 name: "bottom - cpu - with tag", 2125 params: url.Values{"db": []string{"db0"}}, 2126 command: `SELECT BOTTOM(value, host, 2) FROM cpu`, 2127 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","bottom","host"],"values":[["2000-01-01T00:00:00Z",2,"server01"],["2000-01-01T00:00:10Z",3,"server02"]]}]}]}`, 2128 }, 2129 { 2130 name: "top - cpu - 3 values with limit 2", 2131 params: url.Values{"db": []string{"db0"}}, 2132 command: `SELECT TOP(value, 3) FROM cpu limit 2`, 2133 exp: `{"results":[{"statement_id":0,"error":"limit (3) in top function can not be larger than the LIMIT (2) in the select statement"}]}`, 2134 }, 2135 { 2136 name: "bottom - cpu - 3 values with limit 2", 2137 params: url.Values{"db": []string{"db0"}}, 2138 command: `SELECT BOTTOM(value, 3) FROM cpu limit 2`, 2139 exp: `{"results":[{"statement_id":0,"error":"limit (3) in bottom function can not be larger than the LIMIT (2) in the select statement"}]}`, 2140 }, 2141 { 2142 name: "top - cpu - hourly", 2143 params: url.Values{"db": []string{"db0"}}, 2144 command: `SELECT TOP(value, 1) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, 2145 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:20Z",4],["2000-01-01T01:00:10Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, 2146 }, 2147 { 2148 name: "bottom - cpu - hourly", 2149 params: url.Values{"db": []string{"db0"}}, 2150 command: `SELECT BOTTOM(value, 1) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, 2151 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","bottom"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T01:00:00Z",3],["2000-01-01T02:00:00Z",7]]}]}]}`, 2152 }, 2153 { 2154 name: "top - cpu - 2 values hourly", 2155 params: url.Values{"db": []string{"db0"}}, 2156 command: `SELECT TOP(value, 2) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, 2157 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:10Z",3],["2000-01-01T00:00:20Z",4],["2000-01-01T01:00:10Z",7],["2000-01-01T01:00:20Z",6],["2000-01-01T02:00:00Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, 2158 }, 2159 { 2160 name: "bottom - cpu - 2 values hourly", 2161 params: url.Values{"db": []string{"db0"}}, 2162 command: `SELECT BOTTOM(value, 2) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, 2163 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","bottom"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:10Z",3],["2000-01-01T01:00:00Z",3],["2000-01-01T01:00:20Z",6],["2000-01-01T02:00:00Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, 2164 }, 2165 { 2166 name: "top - cpu - 3 values hourly - validates that a bucket can have less than limit if no values exist in that time bucket", 2167 params: url.Values{"db": []string{"db0"}}, 2168 command: `SELECT TOP(value, 3) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, 2169 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:10Z",3],["2000-01-01T00:00:20Z",4],["2000-01-01T01:00:00Z",3],["2000-01-01T01:00:10Z",7],["2000-01-01T01:00:20Z",6],["2000-01-01T02:00:00Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, 2170 }, 2171 { 2172 name: "bottom - cpu - 3 values hourly - validates that a bucket can have less than limit if no values exist in that time bucket", 2173 params: url.Values{"db": []string{"db0"}}, 2174 command: `SELECT BOTTOM(value, 3) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, 2175 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","bottom"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:10Z",3],["2000-01-01T00:00:20Z",4],["2000-01-01T01:00:00Z",3],["2000-01-01T01:00:10Z",7],["2000-01-01T01:00:20Z",6],["2000-01-01T02:00:00Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, 2176 }, 2177 { 2178 name: "top - memory - 2 values, two tags", 2179 params: url.Values{"db": []string{"db0"}}, 2180 command: `SELECT TOP(value, 2), host, service FROM memory`, 2181 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T01:00:00Z",2001,"b","mysql"],["2000-01-01T02:00:00Z",2002,"b","mysql"]]}]}]}`, 2182 }, 2183 { 2184 name: "bottom - memory - 2 values, two tags", 2185 params: url.Values{"db": []string{"db0"}}, 2186 command: `SELECT BOTTOM(value, 2), host, service FROM memory`, 2187 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","bottom","host","service"],"values":[["2000-01-01T00:00:00Z",1000,"a","redis"],["2000-01-01T01:00:00Z",1001,"a","redis"]]}]}]}`, 2188 }, 2189 { 2190 name: "top - memory - host tag with limit 2", 2191 params: url.Values{"db": []string{"db0"}}, 2192 command: `SELECT TOP(value, host, 2) FROM memory`, 2193 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","top","host"],"values":[["2000-01-01T02:00:00Z",2002,"b"],["2000-01-01T02:00:00Z",1002,"a"]]}]}]}`, 2194 }, 2195 { 2196 name: "bottom - memory - host tag with limit 2", 2197 params: url.Values{"db": []string{"db0"}}, 2198 command: `SELECT BOTTOM(value, host, 2) FROM memory`, 2199 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","bottom","host"],"values":[["2000-01-01T00:00:00Z",1000,"a"],["2000-01-01T00:00:00Z",1500,"b"]]}]}]}`, 2200 }, 2201 { 2202 name: "top - memory - host tag with limit 2, service tag in select", 2203 params: url.Values{"db": []string{"db0"}}, 2204 command: `SELECT TOP(value, host, 2), service FROM memory`, 2205 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T02:00:00Z",2002,"b","mysql"],["2000-01-01T02:00:00Z",1002,"a","redis"]]}]}]}`, 2206 }, 2207 { 2208 name: "bottom - memory - host tag with limit 2, service tag in select", 2209 params: url.Values{"db": []string{"db0"}}, 2210 command: `SELECT BOTTOM(value, host, 2), service FROM memory`, 2211 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","bottom","host","service"],"values":[["2000-01-01T00:00:00Z",1000,"a","redis"],["2000-01-01T00:00:00Z",1500,"b","redis"]]}]}]}`, 2212 }, 2213 { 2214 name: "top - memory - service tag with limit 2, host tag in select", 2215 params: url.Values{"db": []string{"db0"}}, 2216 command: `SELECT TOP(value, service, 2), host FROM memory`, 2217 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","top","service","host"],"values":[["2000-01-01T02:00:00Z",2002,"mysql","b"],["2000-01-01T02:00:00Z",1502,"redis","b"]]}]}]}`, 2218 }, 2219 { 2220 name: "bottom - memory - service tag with limit 2, host tag in select", 2221 params: url.Values{"db": []string{"db0"}}, 2222 command: `SELECT BOTTOM(value, service, 2), host FROM memory`, 2223 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","bottom","service","host"],"values":[["2000-01-01T00:00:00Z",1000,"redis","a"],["2000-01-01T00:00:00Z",2000,"mysql","b"]]}]}]}`, 2224 }, 2225 { 2226 name: "top - memory - host and service tag with limit 2", 2227 params: url.Values{"db": []string{"db0"}}, 2228 command: `SELECT TOP(value, host, service, 2) FROM memory`, 2229 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T02:00:00Z",2002,"b","mysql"],["2000-01-01T02:00:00Z",1502,"b","redis"]]}]}]}`, 2230 }, 2231 { 2232 name: "bottom - memory - host and service tag with limit 2", 2233 params: url.Values{"db": []string{"db0"}}, 2234 command: `SELECT BOTTOM(value, host, service, 2) FROM memory`, 2235 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","bottom","host","service"],"values":[["2000-01-01T00:00:00Z",1000,"a","redis"],["2000-01-01T00:00:00Z",1500,"b","redis"]]}]}]}`, 2236 }, 2237 { 2238 name: "top - memory - host tag with limit 2 with service tag in select", 2239 params: url.Values{"db": []string{"db0"}}, 2240 command: `SELECT TOP(value, host, 2), service FROM memory`, 2241 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T02:00:00Z",2002,"b","mysql"],["2000-01-01T02:00:00Z",1002,"a","redis"]]}]}]}`, 2242 }, 2243 { 2244 name: "bottom - memory - host tag with limit 2 with service tag in select", 2245 params: url.Values{"db": []string{"db0"}}, 2246 command: `SELECT BOTTOM(value, host, 2), service FROM memory`, 2247 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","bottom","host","service"],"values":[["2000-01-01T00:00:00Z",1000,"a","redis"],["2000-01-01T00:00:00Z",1500,"b","redis"]]}]}]}`, 2248 }, 2249 { 2250 name: "top - memory - host and service tag with limit 3", 2251 params: url.Values{"db": []string{"db0"}}, 2252 command: `SELECT TOP(value, host, service, 3) FROM memory`, 2253 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T02:00:00Z",2002,"b","mysql"],["2000-01-01T02:00:00Z",1502,"b","redis"],["2000-01-01T02:00:00Z",1002,"a","redis"]]}]}]}`, 2254 }, 2255 { 2256 name: "bottom - memory - host and service tag with limit 3", 2257 params: url.Values{"db": []string{"db0"}}, 2258 command: `SELECT BOTTOM(value, host, service, 3) FROM memory`, 2259 exp: `{"results":[{"statement_id":0,"series":[{"name":"memory","columns":["time","bottom","host","service"],"values":[["2000-01-01T00:00:00Z",1000,"a","redis"],["2000-01-01T00:00:00Z",1500,"b","redis"],["2000-01-01T00:00:00Z",2000,"b","mysql"]]}]}]}`, 2260 }, 2261 2262 // TODO 2263 // - Test that specifiying fields or tags in the function will rewrite the query to expand them to the fields 2264 // - Test that a field can be used in the top function 2265 // - Test that asking for a field will come back before a tag if they have the same name for a tag and a field 2266 // - Test that `select top(value, host, 2)` when there is only one value for `host` it will only bring back one value 2267 // - Test that `select top(value, host, 4) from foo where time > now() - 1d and time < now() group by time(1h)` and host is unique in some time buckets that it returns only the unique ones, and not always 4 values 2268 2269 }...) 2270 2271 ctx := context.Background() 2272 test.Run(ctx, t, s) 2273 } 2274 2275 func TestServer_Query_ExactTimeRange(t *testing.T) { 2276 s := OpenServer(t) 2277 defer s.Close() 2278 2279 writes := []string{ 2280 fmt.Sprintf(`cpu value=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00.000000000Z").UnixNano()), 2281 fmt.Sprintf(`cpu value=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00.000000001Z").UnixNano()), 2282 fmt.Sprintf(`cpu value=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00.000000002Z").UnixNano()), 2283 } 2284 2285 test := NewTest("db0", "rp0") 2286 test.writes = Writes{ 2287 &Write{data: strings.Join(writes, "\n")}, 2288 } 2289 2290 test.addQueries([]*Query{ 2291 { 2292 name: "query point at exactly one time - rfc3339nano", 2293 params: url.Values{"db": []string{"db0"}}, 2294 command: `SELECT * FROM cpu WHERE time = '2000-01-01T00:00:00.000000001Z'`, 2295 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00.000000001Z",2]]}]}]}`, 2296 }, 2297 { 2298 name: "query point at exactly one time - timestamp", 2299 params: url.Values{"db": []string{"db0"}}, 2300 command: `SELECT * FROM cpu WHERE time = 946684800000000001`, 2301 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00.000000001Z",2]]}]}]}`, 2302 }, 2303 }...) 2304 2305 ctx := context.Background() 2306 test.Run(ctx, t, s) 2307 } 2308 2309 func TestServer_Query_Aggregates_Math(t *testing.T) { 2310 s := OpenServer(t) 2311 defer s.Close() 2312 2313 writes := []string{ 2314 fmt.Sprintf(`network,host=server01,region=west,core=1 rx=10i,tx=20i,core=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2315 fmt.Sprintf(`network,host=server02,region=west,core=2 rx=40i,tx=50i,core=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 2316 fmt.Sprintf(`network,host=server03,region=east,core=3 rx=40i,tx=55i,core=4i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 2317 fmt.Sprintf(`network,host=server04,region=east,core=4 rx=40i,tx=60i,core=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()), 2318 fmt.Sprintf(`network,host=server05,region=west,core=1 rx=50i,tx=70i,core=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:40Z").UnixNano()), 2319 fmt.Sprintf(`network,host=server06,region=east,core=2 rx=50i,tx=40i,core=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:50Z").UnixNano()), 2320 fmt.Sprintf(`network,host=server07,region=west,core=3 rx=70i,tx=30i,core=4i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 2321 fmt.Sprintf(`network,host=server08,region=east,core=4 rx=90i,tx=10i,core=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:10Z").UnixNano()), 2322 fmt.Sprintf(`network,host=server09,region=east,core=1 rx=5i,tx=4i,core=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:20Z").UnixNano()), 2323 } 2324 2325 test := NewTest("db0", "rp0") 2326 test.writes = Writes{ 2327 &Write{data: strings.Join(writes, "\n")}, 2328 } 2329 2330 test.addQueries([]*Query{ 2331 { 2332 name: "add two selectors", 2333 params: url.Values{"db": []string{"db0"}}, 2334 command: `SELECT max(rx) + min(rx) FROM network WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:01:30Z'`, 2335 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","max_min"],"values":[["2000-01-01T00:00:00Z",95]]}]}]}`, 2336 }, 2337 { 2338 name: "use math one two selectors separately", 2339 params: url.Values{"db": []string{"db0"}}, 2340 command: `SELECT max(rx) * 1, min(rx) * 1 FROM network WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:01:30Z'`, 2341 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","max","min"],"values":[["2000-01-01T00:00:00Z",90,5]]}]}]}`, 2342 }, 2343 { 2344 name: "math with a single selector", 2345 params: url.Values{"db": []string{"db0"}}, 2346 command: `SELECT max(rx) * 1 FROM network WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:01:30Z'`, 2347 exp: `{"results":[{"statement_id":0,"series":[{"name":"network","columns":["time","max"],"values":[["2000-01-01T00:01:10Z",90]]}]}]}`, 2348 }, 2349 }...) 2350 2351 ctx := context.Background() 2352 test.Run(ctx, t, s) 2353 } 2354 2355 func TestServer_Query_Aggregates_CPU(t *testing.T) { 2356 s := OpenServer(t) 2357 defer s.Close() 2358 2359 test := NewTest("db0", "rp0") 2360 test.writes = Writes{ 2361 &Write{data: strings.Join([]string{ 2362 fmt.Sprintf(`cpu,region=uk,host=serverZ,service=redis value=20.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 2363 fmt.Sprintf(`cpu,region=uk,host=serverZ,service=mysql value=30.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 2364 }, "\n")}, 2365 } 2366 2367 test.addQueries([]*Query{ 2368 { 2369 name: "aggregation with WHERE and AND", 2370 params: url.Values{"db": []string{"db0"}}, 2371 command: `SELECT sum(value) FROM cpu WHERE region='uk' AND host='serverZ'`, 2372 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",50]]}]}]}`, 2373 }, 2374 }...) 2375 2376 ctx := context.Background() 2377 test.Run(ctx, t, s) 2378 } 2379 2380 func TestServer_Query_Aggregates_IntMany(t *testing.T) { 2381 s := OpenServer(t) 2382 defer s.Close() 2383 2384 test := NewTest("db0", "rp0") 2385 test.writes = Writes{ 2386 &Write{data: strings.Join([]string{ 2387 fmt.Sprintf(`intmany,host=server01 value=2.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2388 fmt.Sprintf(`intmany,host=server02 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 2389 fmt.Sprintf(`intmany,host=server03 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 2390 fmt.Sprintf(`intmany,host=server04 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()), 2391 fmt.Sprintf(`intmany,host=server05 value=5.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:40Z").UnixNano()), 2392 fmt.Sprintf(`intmany,host=server06 value=5.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:50Z").UnixNano()), 2393 fmt.Sprintf(`intmany,host=server07 value=7.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 2394 fmt.Sprintf(`intmany,host=server08 value=9.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:10Z").UnixNano()), 2395 }, "\n")}, 2396 } 2397 2398 test.addQueries([]*Query{ 2399 { 2400 name: "mean and stddev - int", 2401 params: url.Values{"db": []string{"db0"}}, 2402 command: `SELECT MEAN(value), STDDEV(value) FROM intmany WHERE time >= '2000-01-01' AND time < '2000-01-01T00:02:00Z' GROUP BY time(10m)`, 2403 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","mean","stddev"],"values":[["2000-01-01T00:00:00Z",5,2.138089935299395]]}]}]}`, 2404 }, 2405 { 2406 name: "first - int", 2407 params: url.Values{"db": []string{"db0"}}, 2408 command: `SELECT FIRST(value) FROM intmany`, 2409 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 2410 }, 2411 { 2412 name: "first - int - epoch ms", 2413 params: url.Values{"db": []string{"db0"}, "epoch": []string{"ms"}}, 2414 command: `SELECT FIRST(value) FROM intmany`, 2415 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","first"],"values":[[%d,2]]}]}]}`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()/int64(time.Millisecond)), 2416 }, 2417 { 2418 name: "last - int", 2419 params: url.Values{"db": []string{"db0"}}, 2420 command: `SELECT LAST(value) FROM intmany`, 2421 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","last"],"values":[["2000-01-01T00:01:10Z",9]]}]}]}`, 2422 }, 2423 { 2424 name: "spread - int", 2425 params: url.Values{"db": []string{"db0"}}, 2426 command: `SELECT SPREAD(value) FROM intmany`, 2427 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","spread"],"values":[["1970-01-01T00:00:00Z",7]]}]}]}`, 2428 }, 2429 { 2430 name: "median - even count - int", 2431 params: url.Values{"db": []string{"db0"}}, 2432 command: `SELECT MEDIAN(value) FROM intmany`, 2433 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","median"],"values":[["1970-01-01T00:00:00Z",4.5]]}]}]}`, 2434 }, 2435 { 2436 name: "median - odd count - int", 2437 params: url.Values{"db": []string{"db0"}}, 2438 command: `SELECT MEDIAN(value) FROM intmany where time < '2000-01-01T00:01:10Z'`, 2439 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","median"],"values":[["1970-01-01T00:00:00Z",4]]}]}]}`, 2440 }, 2441 { 2442 name: "mode - single - int", 2443 params: url.Values{"db": []string{"db0"}}, 2444 command: `SELECT MODE(value) FROM intmany`, 2445 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","mode"],"values":[["1970-01-01T00:00:00Z",4]]}]}]}`, 2446 }, 2447 { 2448 name: "mode - multiple - int", 2449 params: url.Values{"db": []string{"db0"}}, 2450 command: `SELECT MODE(value) FROM intmany where time < '2000-01-01T00:01:10Z'`, 2451 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","mode"],"values":[["1970-01-01T00:00:00Z",4]]}]}]}`, 2452 }, 2453 { 2454 name: "distinct as call - int", 2455 params: url.Values{"db": []string{"db0"}}, 2456 command: `SELECT DISTINCT(value) FROM intmany`, 2457 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","distinct"],"values":[["1970-01-01T00:00:00Z",2],["1970-01-01T00:00:00Z",4],["1970-01-01T00:00:00Z",5],["1970-01-01T00:00:00Z",7],["1970-01-01T00:00:00Z",9]]}]}]}`, 2458 }, 2459 { 2460 name: "distinct alt syntax - int", 2461 params: url.Values{"db": []string{"db0"}}, 2462 command: `SELECT DISTINCT value FROM intmany`, 2463 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","distinct"],"values":[["1970-01-01T00:00:00Z",2],["1970-01-01T00:00:00Z",4],["1970-01-01T00:00:00Z",5],["1970-01-01T00:00:00Z",7],["1970-01-01T00:00:00Z",9]]}]}]}`, 2464 }, 2465 { 2466 name: "distinct select tag - int", 2467 params: url.Values{"db": []string{"db0"}}, 2468 command: `SELECT DISTINCT(host) FROM intmany`, 2469 exp: `{"results":[{"statement_id":0,"error":"statement must have at least one field in select clause"}]}`, 2470 skip: SkippedOSS, // FIXME(benbjohnson): should be allowed, need to stream tag values 2471 }, 2472 { 2473 name: "distinct alt select tag - int", 2474 params: url.Values{"db": []string{"db0"}}, 2475 command: `SELECT DISTINCT host FROM intmany`, 2476 exp: `{"results":[{"statement_id":0,"error":"statement must have at least one field in select clause"}]}`, 2477 skip: SkippedOSS, // FIXME(benbjohnson): should be allowed, need to stream tag values 2478 }, 2479 { 2480 name: "count distinct - int", 2481 params: url.Values{"db": []string{"db0"}}, 2482 command: `SELECT COUNT(DISTINCT value) FROM intmany`, 2483 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",5]]}]}]}`, 2484 }, 2485 { 2486 name: "count distinct as call - int", 2487 params: url.Values{"db": []string{"db0"}}, 2488 command: `SELECT COUNT(DISTINCT(value)) FROM intmany`, 2489 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",5]]}]}]}`, 2490 }, 2491 { 2492 name: "count distinct select tag - int", 2493 params: url.Values{"db": []string{"db0"}}, 2494 command: `SELECT COUNT(DISTINCT host) FROM intmany`, 2495 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",0]]}]}]}`, 2496 skip: SkippedOSS, // FIXME(benbjohnson): stream tag values 2497 }, 2498 { 2499 name: "count distinct as call select tag - int", 2500 params: url.Values{"db": []string{"db0"}}, 2501 command: `SELECT COUNT(DISTINCT host) FROM intmany`, 2502 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",0]]}]}]}`, 2503 skip: SkippedOSS, // FIXME(benbjohnson): stream tag values 2504 }, 2505 }...) 2506 2507 ctx := context.Background() 2508 test.Run(ctx, t, s) 2509 } 2510 2511 func TestServer_Query_Where_Fields(t *testing.T) { 2512 s := OpenServer(t) 2513 defer s.Close() 2514 2515 writes := []string{ 2516 fmt.Sprintf(`cpu alert_id="alert",tenant_id="tenant",_cust="johnson brothers" %d`, mustParseTime(time.RFC3339Nano, "2015-02-28T01:03:36.703820946Z").UnixNano()), 2517 fmt.Sprintf(`cpu alert_id="alert",tenant_id="tenant",_cust="johnson brothers" %d`, mustParseTime(time.RFC3339Nano, "2015-02-28T01:03:36.703820946Z").UnixNano()), 2518 2519 fmt.Sprintf(`cpu load=100.0,core=4 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:02Z").UnixNano()), 2520 fmt.Sprintf(`cpu load=80.0,core=2 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:01:02Z").UnixNano()), 2521 2522 fmt.Sprintf(`clicks local=true %d`, mustParseTime(time.RFC3339Nano, "2014-11-10T23:00:01Z").UnixNano()), 2523 fmt.Sprintf(`clicks local=false %d`, mustParseTime(time.RFC3339Nano, "2014-11-10T23:00:02Z").UnixNano()), 2524 } 2525 2526 test := NewTest("db0", "rp0") 2527 test.writes = Writes{ 2528 &Write{data: strings.Join(writes, "\n")}, 2529 } 2530 2531 test.addQueries([]*Query{ 2532 // non type specific 2533 { 2534 name: "missing measurement with group by", 2535 params: url.Values{"db": []string{"db0"}}, 2536 command: `SELECT load from missing group by *`, 2537 exp: `{"results":[{"statement_id":0}]}`, 2538 }, 2539 2540 // string 2541 { 2542 name: "single string field", 2543 params: url.Values{"db": []string{"db0"}}, 2544 command: `SELECT alert_id FROM cpu WHERE alert_id='alert'`, 2545 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","alert_id"],"values":[["2015-02-28T01:03:36.703820946Z","alert"]]}]}]}`, 2546 }, 2547 { 2548 name: "string AND query, all fields in SELECT", 2549 params: url.Values{"db": []string{"db0"}}, 2550 command: `SELECT alert_id,tenant_id,_cust FROM cpu WHERE alert_id='alert' AND tenant_id='tenant'`, 2551 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","alert_id","tenant_id","_cust"],"values":[["2015-02-28T01:03:36.703820946Z","alert","tenant","johnson brothers"]]}]}]}`, 2552 }, 2553 { 2554 name: "string AND query, all fields in SELECT, one in parenthesis", 2555 params: url.Values{"db": []string{"db0"}}, 2556 command: `SELECT alert_id,tenant_id FROM cpu WHERE alert_id='alert' AND (tenant_id='tenant')`, 2557 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","alert_id","tenant_id"],"values":[["2015-02-28T01:03:36.703820946Z","alert","tenant"]]}]}]}`, 2558 }, 2559 { 2560 name: "string underscored field", 2561 params: url.Values{"db": []string{"db0"}}, 2562 command: `SELECT alert_id FROM cpu WHERE _cust='johnson brothers'`, 2563 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","alert_id"],"values":[["2015-02-28T01:03:36.703820946Z","alert"]]}]}]}`, 2564 }, 2565 { 2566 name: "string no match", 2567 params: url.Values{"db": []string{"db0"}}, 2568 command: `SELECT alert_id FROM cpu WHERE _cust='acme'`, 2569 exp: `{"results":[{"statement_id":0}]}`, 2570 }, 2571 2572 // float64 2573 { 2574 name: "float64 GT no match", 2575 params: url.Values{"db": []string{"db0"}}, 2576 command: `select load from cpu where load > 100`, 2577 exp: `{"results":[{"statement_id":0}]}`, 2578 }, 2579 { 2580 name: "float64 GTE match one", 2581 params: url.Values{"db": []string{"db0"}}, 2582 command: `select load from cpu where load >= 100`, 2583 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","load"],"values":[["2009-11-10T23:00:02Z",100]]}]}]}`, 2584 }, 2585 { 2586 name: "float64 EQ match upper bound", 2587 params: url.Values{"db": []string{"db0"}}, 2588 command: `select load from cpu where load = 100`, 2589 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","load"],"values":[["2009-11-10T23:00:02Z",100]]}]}]}`, 2590 }, 2591 { 2592 name: "float64 LTE match two", 2593 params: url.Values{"db": []string{"db0"}}, 2594 command: `select load from cpu where load <= 100`, 2595 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","load"],"values":[["2009-11-10T23:00:02Z",100],["2009-11-10T23:01:02Z",80]]}]}]}`, 2596 }, 2597 { 2598 name: "float64 GT match one", 2599 params: url.Values{"db": []string{"db0"}}, 2600 command: `select load from cpu where load > 99`, 2601 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","load"],"values":[["2009-11-10T23:00:02Z",100]]}]}]}`, 2602 }, 2603 { 2604 name: "float64 EQ no match", 2605 params: url.Values{"db": []string{"db0"}}, 2606 command: `select load from cpu where load = 99`, 2607 exp: `{"results":[{"statement_id":0}]}`, 2608 }, 2609 { 2610 name: "float64 LT match one", 2611 params: url.Values{"db": []string{"db0"}}, 2612 command: `select load from cpu where load < 99`, 2613 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","load"],"values":[["2009-11-10T23:01:02Z",80]]}]}]}`, 2614 }, 2615 { 2616 name: "float64 LT no match", 2617 params: url.Values{"db": []string{"db0"}}, 2618 command: `select load from cpu where load < 80`, 2619 exp: `{"results":[{"statement_id":0}]}`, 2620 }, 2621 { 2622 name: "float64 NE match one", 2623 params: url.Values{"db": []string{"db0"}}, 2624 command: `select load from cpu where load != 100`, 2625 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","load"],"values":[["2009-11-10T23:01:02Z",80]]}]}]}`, 2626 }, 2627 2628 // int64 2629 { 2630 name: "int64 GT no match", 2631 params: url.Values{"db": []string{"db0"}}, 2632 command: `select core from cpu where core > 4`, 2633 exp: `{"results":[{"statement_id":0}]}`, 2634 }, 2635 { 2636 name: "int64 GTE match one", 2637 params: url.Values{"db": []string{"db0"}}, 2638 command: `select core from cpu where core >= 4`, 2639 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core"],"values":[["2009-11-10T23:00:02Z",4]]}]}]}`, 2640 }, 2641 { 2642 name: "int64 EQ match upper bound", 2643 params: url.Values{"db": []string{"db0"}}, 2644 command: `select core from cpu where core = 4`, 2645 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core"],"values":[["2009-11-10T23:00:02Z",4]]}]}]}`, 2646 }, 2647 { 2648 name: "int64 LTE match two ", 2649 params: url.Values{"db": []string{"db0"}}, 2650 command: `select core from cpu where core <= 4`, 2651 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core"],"values":[["2009-11-10T23:00:02Z",4],["2009-11-10T23:01:02Z",2]]}]}]}`, 2652 }, 2653 { 2654 name: "int64 GT match one", 2655 params: url.Values{"db": []string{"db0"}}, 2656 command: `select core from cpu where core > 3`, 2657 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core"],"values":[["2009-11-10T23:00:02Z",4]]}]}]}`, 2658 }, 2659 { 2660 name: "int64 EQ no match", 2661 params: url.Values{"db": []string{"db0"}}, 2662 command: `select core from cpu where core = 3`, 2663 exp: `{"results":[{"statement_id":0}]}`, 2664 }, 2665 { 2666 name: "int64 LT match one", 2667 params: url.Values{"db": []string{"db0"}}, 2668 command: `select core from cpu where core < 3`, 2669 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core"],"values":[["2009-11-10T23:01:02Z",2]]}]}]}`, 2670 }, 2671 { 2672 name: "int64 LT no match", 2673 params: url.Values{"db": []string{"db0"}}, 2674 command: `select core from cpu where core < 2`, 2675 exp: `{"results":[{"statement_id":0}]}`, 2676 }, 2677 { 2678 name: "int64 NE match one", 2679 params: url.Values{"db": []string{"db0"}}, 2680 command: `select core from cpu where core != 4`, 2681 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core"],"values":[["2009-11-10T23:01:02Z",2]]}]}]}`, 2682 }, 2683 2684 // bool 2685 { 2686 name: "bool EQ match true", 2687 params: url.Values{"db": []string{"db0"}}, 2688 command: `select local from clicks where local = true`, 2689 exp: `{"results":[{"statement_id":0,"series":[{"name":"clicks","columns":["time","local"],"values":[["2014-11-10T23:00:01Z",true]]}]}]}`, 2690 }, 2691 { 2692 name: "bool EQ match false", 2693 params: url.Values{"db": []string{"db0"}}, 2694 command: `select local from clicks where local = false`, 2695 exp: `{"results":[{"statement_id":0,"series":[{"name":"clicks","columns":["time","local"],"values":[["2014-11-10T23:00:02Z",false]]}]}]}`, 2696 }, 2697 2698 { 2699 name: "bool NE match one", 2700 params: url.Values{"db": []string{"db0"}}, 2701 command: `select local from clicks where local != true`, 2702 exp: `{"results":[{"statement_id":0,"series":[{"name":"clicks","columns":["time","local"],"values":[["2014-11-10T23:00:02Z",false]]}]}]}`, 2703 }, 2704 }...) 2705 2706 ctx := context.Background() 2707 test.Run(ctx, t, s) 2708 } 2709 2710 func TestServer_Query_Aggregates_IntMany_GroupBy(t *testing.T) { 2711 s := OpenServer(t) 2712 defer s.Close() 2713 2714 test := NewTest("db0", "rp0") 2715 test.writes = Writes{ 2716 &Write{data: strings.Join([]string{ 2717 fmt.Sprintf(`intmany,host=server01 value=2.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2718 fmt.Sprintf(`intmany,host=server02 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 2719 fmt.Sprintf(`intmany,host=server03 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 2720 fmt.Sprintf(`intmany,host=server04 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()), 2721 fmt.Sprintf(`intmany,host=server05 value=5.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:40Z").UnixNano()), 2722 fmt.Sprintf(`intmany,host=server06 value=5.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:50Z").UnixNano()), 2723 fmt.Sprintf(`intmany,host=server07 value=7.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 2724 fmt.Sprintf(`intmany,host=server08 value=9.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:10Z").UnixNano()), 2725 }, "\n")}, 2726 } 2727 2728 test.addQueries([]*Query{ 2729 { 2730 name: "max order by time with time specified group by 10s", 2731 params: url.Values{"db": []string{"db0"}}, 2732 command: `SELECT time, max(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:14Z' group by time(10s)`, 2733 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","max"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:10Z",4],["2000-01-01T00:00:20Z",4],["2000-01-01T00:00:30Z",4],["2000-01-01T00:00:40Z",5],["2000-01-01T00:00:50Z",5],["2000-01-01T00:01:00Z",7],["2000-01-01T00:01:10Z",9]]}]}]}`, 2734 }, 2735 { 2736 name: "max order by time without time specified group by 30s", 2737 params: url.Values{"db": []string{"db0"}}, 2738 command: `SELECT max(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:14Z' group by time(30s)`, 2739 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","max"],"values":[["2000-01-01T00:00:00Z",4],["2000-01-01T00:00:30Z",5],["2000-01-01T00:01:00Z",9]]}]}]}`, 2740 }, 2741 { 2742 name: "max order by time with time specified group by 30s", 2743 params: url.Values{"db": []string{"db0"}}, 2744 command: `SELECT time, max(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:14Z' group by time(30s)`, 2745 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","max"],"values":[["2000-01-01T00:00:00Z",4],["2000-01-01T00:00:30Z",5],["2000-01-01T00:01:00Z",9]]}]}]}`, 2746 }, 2747 { 2748 name: "min order by time without time specified group by 15s", 2749 params: url.Values{"db": []string{"db0"}}, 2750 command: `SELECT min(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:14Z' group by time(15s)`, 2751 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","min"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:15Z",4],["2000-01-01T00:00:30Z",4],["2000-01-01T00:00:45Z",5],["2000-01-01T00:01:00Z",7]]}]}]}`, 2752 }, 2753 { 2754 name: "min order by time with time specified group by 15s", 2755 params: url.Values{"db": []string{"db0"}}, 2756 command: `SELECT time, min(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:14Z' group by time(15s)`, 2757 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","min"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:15Z",4],["2000-01-01T00:00:30Z",4],["2000-01-01T00:00:45Z",5],["2000-01-01T00:01:00Z",7]]}]}]}`, 2758 }, 2759 { 2760 name: "first order by time without time specified group by 15s", 2761 params: url.Values{"db": []string{"db0"}}, 2762 command: `SELECT first(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:14Z' group by time(15s)`, 2763 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:15Z",4],["2000-01-01T00:00:30Z",4],["2000-01-01T00:00:45Z",5],["2000-01-01T00:01:00Z",7]]}]}]}`, 2764 }, 2765 { 2766 name: "first order by time with time specified group by 15s", 2767 params: url.Values{"db": []string{"db0"}}, 2768 command: `SELECT time, first(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:14Z' group by time(15s)`, 2769 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:15Z",4],["2000-01-01T00:00:30Z",4],["2000-01-01T00:00:45Z",5],["2000-01-01T00:01:00Z",7]]}]}]}`, 2770 }, 2771 { 2772 name: "last order by time without time specified group by 15s", 2773 params: url.Values{"db": []string{"db0"}}, 2774 command: `SELECT last(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:14Z' group by time(15s)`, 2775 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","last"],"values":[["2000-01-01T00:00:00Z",4],["2000-01-01T00:00:15Z",4],["2000-01-01T00:00:30Z",5],["2000-01-01T00:00:45Z",5],["2000-01-01T00:01:00Z",9]]}]}]}`, 2776 }, 2777 { 2778 name: "last order by time with time specified group by 15s", 2779 params: url.Values{"db": []string{"db0"}}, 2780 command: `SELECT time, last(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:14Z' group by time(15s)`, 2781 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","last"],"values":[["2000-01-01T00:00:00Z",4],["2000-01-01T00:00:15Z",4],["2000-01-01T00:00:30Z",5],["2000-01-01T00:00:45Z",5],["2000-01-01T00:01:00Z",9]]}]}]}`, 2782 }, 2783 }...) 2784 2785 ctx := context.Background() 2786 test.Run(ctx, t, s) 2787 } 2788 2789 func TestServer_Query_Aggregates_IntMany_OrderByDesc(t *testing.T) { 2790 s := OpenServer(t) 2791 defer s.Close() 2792 2793 test := NewTest("db0", "rp0") 2794 test.writes = Writes{ 2795 &Write{data: strings.Join([]string{ 2796 fmt.Sprintf(`intmany,host=server01 value=2.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2797 fmt.Sprintf(`intmany,host=server02 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 2798 fmt.Sprintf(`intmany,host=server03 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 2799 fmt.Sprintf(`intmany,host=server04 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()), 2800 fmt.Sprintf(`intmany,host=server05 value=5.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:40Z").UnixNano()), 2801 fmt.Sprintf(`intmany,host=server06 value=5.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:50Z").UnixNano()), 2802 fmt.Sprintf(`intmany,host=server07 value=7.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 2803 fmt.Sprintf(`intmany,host=server08 value=9.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:10Z").UnixNano()), 2804 }, "\n")}, 2805 } 2806 2807 test.addQueries([]*Query{ 2808 { 2809 name: "aggregate order by time desc", 2810 params: url.Values{"db": []string{"db0"}}, 2811 command: `SELECT max(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:00Z' group by time(10s) order by time desc`, 2812 exp: `{"results":[{"statement_id":0,"series":[{"name":"intmany","columns":["time","max"],"values":[["2000-01-01T00:01:00Z",7],["2000-01-01T00:00:50Z",5],["2000-01-01T00:00:40Z",5],["2000-01-01T00:00:30Z",4],["2000-01-01T00:00:20Z",4],["2000-01-01T00:00:10Z",4],["2000-01-01T00:00:00Z",2]]}]}]}`, 2813 }, 2814 }...) 2815 2816 ctx := context.Background() 2817 test.Run(ctx, t, s) 2818 } 2819 2820 func TestServer_Query_Aggregates_IntOverlap(t *testing.T) { 2821 s := OpenServer(t) 2822 defer s.Close() 2823 2824 test := NewTest("db0", "rp0") 2825 test.writes = Writes{ 2826 &Write{data: strings.Join([]string{ 2827 fmt.Sprintf(`intoverlap,region=us-east value=20 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2828 fmt.Sprintf(`intoverlap,region=us-east value=30 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 2829 fmt.Sprintf(`intoverlap,region=us-west value=100 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2830 fmt.Sprintf(`intoverlap,region=us-east otherVal=20 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 2831 }, "\n")}, 2832 } 2833 2834 test.addQueries([]*Query{ 2835 /* { 2836 name: "aggregation with no interval - int", 2837 params: url.Values{"db": []string{"db0"}}, 2838 command: `SELECT count(value) FROM intoverlap WHERE time = '2000-01-01 00:00:00'`, 2839 exp: `{"results":[{"statement_id":0,"series":[{"name":"intoverlap","columns":["time","count"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 2840 }, 2841 { 2842 name: "sum - int", 2843 params: url.Values{"db": []string{"db0"}}, 2844 command: `SELECT SUM(value) FROM intoverlap WHERE time >= '2000-01-01 00:00:05' AND time <= '2000-01-01T00:00:10Z' GROUP BY time(10s), region`, 2845 exp: `{"results":[{"statement_id":0,"series":[{"name":"intoverlap","tags":{"region":"us-east"},"columns":["time","sum"],"values":[["2000-01-01T00:00:10Z",30]]}]}]}`, 2846 }, 2847 */{ 2848 name: "aggregation with a null field value - int", 2849 params: url.Values{"db": []string{"db0"}}, 2850 command: `SELECT SUM(value) FROM intoverlap GROUP BY region`, 2851 exp: `{"results":[{"statement_id":0,"series":[{"name":"intoverlap","tags":{"region":"us-east"},"columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",50]]},{"name":"intoverlap","tags":{"region":"us-west"},"columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",100]]}]}]}`, 2852 }, 2853 { 2854 name: "multiple aggregations - int", 2855 params: url.Values{"db": []string{"db0"}}, 2856 command: `SELECT SUM(value), MEAN(value) FROM intoverlap GROUP BY region`, 2857 exp: `{"results":[{"statement_id":0,"series":[{"name":"intoverlap","tags":{"region":"us-east"},"columns":["time","sum","mean"],"values":[["1970-01-01T00:00:00Z",50,25]]},{"name":"intoverlap","tags":{"region":"us-west"},"columns":["time","sum","mean"],"values":[["1970-01-01T00:00:00Z",100,100]]}]}]}`, 2858 }, 2859 { 2860 skip: SkippedOSS, 2861 name: "multiple aggregations with division - int FIXME issue #2879", 2862 params: url.Values{"db": []string{"db0"}}, 2863 command: `SELECT sum(value), mean(value), sum(value) / mean(value) as div FROM intoverlap GROUP BY region`, 2864 exp: `{"results":[{"statement_id":0,"series":[{"name":"intoverlap","tags":{"region":"us-east"},"columns":["time","sum","mean","div"],"values":[["1970-01-01T00:00:00Z",50,25,2]]},{"name":"intoverlap","tags":{"region":"us-west"},"columns":["time","div"],"values":[["1970-01-01T00:00:00Z",100,100,1]]}]}]}`, 2865 }, 2866 }...) 2867 2868 ctx := context.Background() 2869 test.Run(ctx, t, s) 2870 } 2871 2872 func TestServer_Query_Aggregates_FloatSingle(t *testing.T) { 2873 s := OpenServer(t) 2874 defer s.Close() 2875 2876 test := NewTest("db0", "rp0") 2877 test.writes = Writes{ 2878 &Write{data: strings.Join([]string{ 2879 fmt.Sprintf(`floatsingle value=45.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 2880 }, "\n")}, 2881 } 2882 2883 test.addQueries([]*Query{ 2884 { 2885 name: "stddev with just one point - float", 2886 params: url.Values{"db": []string{"db0"}}, 2887 command: `SELECT STDDEV(value) FROM floatsingle`, 2888 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatsingle","columns":["time","stddev"],"values":[["1970-01-01T00:00:00Z",null]]}]}]}`, 2889 }, 2890 }...) 2891 2892 ctx := context.Background() 2893 test.Run(ctx, t, s) 2894 } 2895 2896 func TestServer_Query_LimitAndOffset(t *testing.T) { 2897 s := OpenServer(t) 2898 defer s.Close() 2899 2900 writes := []string{ 2901 fmt.Sprintf(`limited,tennant=paul foo=2 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:02Z").UnixNano()), 2902 fmt.Sprintf(`limited,tennant=paul foo=3 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:03Z").UnixNano()), 2903 fmt.Sprintf(`limited,tennant=paul foo=4 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:04Z").UnixNano()), 2904 fmt.Sprintf(`limited,tennant=todd foo=5 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:05Z").UnixNano()), 2905 } 2906 2907 test := NewTest("db0", "rp0") 2908 test.writes = Writes{ 2909 &Write{data: strings.Join(writes, "\n")}, 2910 } 2911 2912 test.addQueries([]*Query{ 2913 { 2914 name: "limit on points", 2915 params: url.Values{"db": []string{"db0"}}, 2916 command: `select foo from "limited" LIMIT 2`, 2917 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","columns":["time","foo"],"values":[["2009-11-10T23:00:02Z",2],["2009-11-10T23:00:03Z",3]]}]}]}`, 2918 }, 2919 { 2920 name: "limit higher than the number of data points", 2921 params: url.Values{"db": []string{"db0"}}, 2922 command: `select foo from "limited" LIMIT 20`, 2923 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","columns":["time","foo"],"values":[["2009-11-10T23:00:02Z",2],["2009-11-10T23:00:03Z",3],["2009-11-10T23:00:04Z",4],["2009-11-10T23:00:05Z",5]]}]}]}`, 2924 }, 2925 { 2926 name: "limit and offset", 2927 params: url.Values{"db": []string{"db0"}}, 2928 command: `select foo from "limited" LIMIT 2 OFFSET 1`, 2929 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","columns":["time","foo"],"values":[["2009-11-10T23:00:03Z",3],["2009-11-10T23:00:04Z",4]]}]}]}`, 2930 }, 2931 { 2932 name: "limit + offset equal to total number of points", 2933 params: url.Values{"db": []string{"db0"}}, 2934 command: `select foo from "limited" LIMIT 3 OFFSET 3`, 2935 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","columns":["time","foo"],"values":[["2009-11-10T23:00:05Z",5]]}]}]}`, 2936 }, 2937 { 2938 name: "limit - offset higher than number of points", 2939 command: `select foo from "limited" LIMIT 2 OFFSET 20`, 2940 exp: `{"results":[{"statement_id":0}]}`, 2941 params: url.Values{"db": []string{"db0"}}, 2942 }, 2943 { 2944 name: "limit on points with group by time", 2945 command: `select mean(foo) from "limited" WHERE time >= '2009-11-10T23:00:02Z' AND time < '2009-11-10T23:00:06Z' GROUP BY TIME(1s) LIMIT 2`, 2946 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","columns":["time","mean"],"values":[["2009-11-10T23:00:02Z",2],["2009-11-10T23:00:03Z",3]]}]}]}`, 2947 params: url.Values{"db": []string{"db0"}}, 2948 }, 2949 { 2950 name: "limit higher than the number of data points with group by time", 2951 command: `select mean(foo) from "limited" WHERE time >= '2009-11-10T23:00:02Z' AND time < '2009-11-10T23:00:06Z' GROUP BY TIME(1s) LIMIT 20`, 2952 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","columns":["time","mean"],"values":[["2009-11-10T23:00:02Z",2],["2009-11-10T23:00:03Z",3],["2009-11-10T23:00:04Z",4],["2009-11-10T23:00:05Z",5]]}]}]}`, 2953 params: url.Values{"db": []string{"db0"}}, 2954 }, 2955 { 2956 name: "limit and offset with group by time", 2957 command: `select mean(foo) from "limited" WHERE time >= '2009-11-10T23:00:02Z' AND time < '2009-11-10T23:00:06Z' GROUP BY TIME(1s) LIMIT 2 OFFSET 1`, 2958 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","columns":["time","mean"],"values":[["2009-11-10T23:00:03Z",3],["2009-11-10T23:00:04Z",4]]}]}]}`, 2959 params: url.Values{"db": []string{"db0"}}, 2960 }, 2961 { 2962 name: "limit + offset equal to the number of points with group by time", 2963 command: `select mean(foo) from "limited" WHERE time >= '2009-11-10T23:00:02Z' AND time < '2009-11-10T23:00:06Z' GROUP BY TIME(1s) LIMIT 3 OFFSET 3`, 2964 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","columns":["time","mean"],"values":[["2009-11-10T23:00:05Z",5]]}]}]}`, 2965 params: url.Values{"db": []string{"db0"}}, 2966 }, 2967 { 2968 name: "limit - offset higher than number of points with group by time", 2969 command: `select mean(foo) from "limited" WHERE time >= '2009-11-10T23:00:02Z' AND time < '2009-11-10T23:00:06Z' GROUP BY TIME(1s) LIMIT 2 OFFSET 20`, 2970 exp: `{"results":[{"statement_id":0}]}`, 2971 params: url.Values{"db": []string{"db0"}}, 2972 }, 2973 { 2974 name: "limit - group by tennant", 2975 command: `select foo from "limited" group by tennant limit 1`, 2976 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","tags":{"tennant":"paul"},"columns":["time","foo"],"values":[["2009-11-10T23:00:02Z",2]]},{"name":"limited","tags":{"tennant":"todd"},"columns":["time","foo"],"values":[["2009-11-10T23:00:05Z",5]]}]}]}`, 2977 params: url.Values{"db": []string{"db0"}}, 2978 }, 2979 { 2980 name: "limit and offset - group by tennant", 2981 command: `select foo from "limited" group by tennant limit 1 offset 1`, 2982 exp: `{"results":[{"statement_id":0,"series":[{"name":"limited","tags":{"tennant":"paul"},"columns":["time","foo"],"values":[["2009-11-10T23:00:03Z",3]]}]}]}`, 2983 params: url.Values{"db": []string{"db0"}}, 2984 }, 2985 }...) 2986 2987 ctx := context.Background() 2988 test.Run(ctx, t, s) 2989 } 2990 2991 func TestServer_Query_Fill(t *testing.T) { 2992 s := OpenServer(t) 2993 defer s.Close() 2994 2995 writes := []string{ 2996 fmt.Sprintf(`fills val=3 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:02Z").UnixNano()), 2997 fmt.Sprintf(`fills val=5 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:03Z").UnixNano()), 2998 fmt.Sprintf(`fills val=4 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:06Z").UnixNano()), 2999 fmt.Sprintf(`fills val=10 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:16Z").UnixNano()), 3000 } 3001 3002 test := NewTest("db0", "rp0") 3003 test.writes = Writes{ 3004 &Write{data: strings.Join(writes, "\n")}, 3005 } 3006 3007 test.addQueries([]*Query{ 3008 { 3009 name: "fill with value", 3010 command: `select mean(val) from fills where time >= '2009-11-10T23:00:00Z' and time < '2009-11-10T23:00:20Z' group by time(5s) FILL(1)`, 3011 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","mean"],"values":[["2009-11-10T23:00:00Z",4],["2009-11-10T23:00:05Z",4],["2009-11-10T23:00:10Z",1],["2009-11-10T23:00:15Z",10]]}]}]}`, 3012 params: url.Values{"db": []string{"db0"}}, 3013 }, 3014 { 3015 name: "fill with value, WHERE all values match condition", 3016 command: `select mean(val) from fills where time >= '2009-11-10T23:00:00Z' and time < '2009-11-10T23:00:20Z' and val < 50 group by time(5s) FILL(1)`, 3017 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","mean"],"values":[["2009-11-10T23:00:00Z",4],["2009-11-10T23:00:05Z",4],["2009-11-10T23:00:10Z",1],["2009-11-10T23:00:15Z",10]]}]}]}`, 3018 params: url.Values{"db": []string{"db0"}}, 3019 }, 3020 { 3021 name: "fill with value, WHERE no values match condition", 3022 command: `select mean(val) from fills where time >= '2009-11-10T23:00:00Z' and time < '2009-11-10T23:00:20Z' and val > 50 group by time(5s) FILL(1)`, 3023 exp: `{"results":[{"statement_id":0}]}`, 3024 params: url.Values{"db": []string{"db0"}}, 3025 }, 3026 { 3027 name: "fill with previous", 3028 command: `select mean(val) from fills where time >= '2009-11-10T23:00:00Z' and time < '2009-11-10T23:00:20Z' group by time(5s) FILL(previous)`, 3029 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","mean"],"values":[["2009-11-10T23:00:00Z",4],["2009-11-10T23:00:05Z",4],["2009-11-10T23:00:10Z",4],["2009-11-10T23:00:15Z",10]]}]}]}`, 3030 params: url.Values{"db": []string{"db0"}}, 3031 }, 3032 { 3033 name: "fill with none, i.e. clear out nulls", 3034 command: `select mean(val) from fills where time >= '2009-11-10T23:00:00Z' and time < '2009-11-10T23:00:20Z' group by time(5s) FILL(none)`, 3035 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","mean"],"values":[["2009-11-10T23:00:00Z",4],["2009-11-10T23:00:05Z",4],["2009-11-10T23:00:15Z",10]]}]}]}`, 3036 params: url.Values{"db": []string{"db0"}}, 3037 }, 3038 { 3039 name: "fill defaults to null", 3040 command: `select mean(val) from fills where time >= '2009-11-10T23:00:00Z' and time < '2009-11-10T23:00:20Z' group by time(5s)`, 3041 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","mean"],"values":[["2009-11-10T23:00:00Z",4],["2009-11-10T23:00:05Z",4],["2009-11-10T23:00:10Z",null],["2009-11-10T23:00:15Z",10]]}]}]}`, 3042 params: url.Values{"db": []string{"db0"}}, 3043 }, 3044 { 3045 name: "fill defaults to 0 for count", 3046 command: `select count(val) from fills where time >= '2009-11-10T23:00:00Z' and time < '2009-11-10T23:00:20Z' group by time(5s)`, 3047 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","count"],"values":[["2009-11-10T23:00:00Z",2],["2009-11-10T23:00:05Z",1],["2009-11-10T23:00:10Z",0],["2009-11-10T23:00:15Z",1]]}]}]}`, 3048 params: url.Values{"db": []string{"db0"}}, 3049 }, 3050 { 3051 name: "fill none drops 0s for count", 3052 command: `select count(val) from fills where time >= '2009-11-10T23:00:00Z' and time < '2009-11-10T23:00:20Z' group by time(5s) fill(none)`, 3053 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","count"],"values":[["2009-11-10T23:00:00Z",2],["2009-11-10T23:00:05Z",1],["2009-11-10T23:00:15Z",1]]}]}]}`, 3054 params: url.Values{"db": []string{"db0"}}, 3055 }, 3056 { 3057 name: "fill previous overwrites 0s for count", 3058 command: `select count(val) from fills where time >= '2009-11-10T23:00:00Z' and time < '2009-11-10T23:00:20Z' group by time(5s) fill(previous)`, 3059 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","count"],"values":[["2009-11-10T23:00:00Z",2],["2009-11-10T23:00:05Z",1],["2009-11-10T23:00:10Z",1],["2009-11-10T23:00:15Z",1]]}]}]}`, 3060 params: url.Values{"db": []string{"db0"}}, 3061 }, 3062 { 3063 name: "fill with implicit start time", 3064 command: `select mean(val) from fills where time < '2009-11-10T23:00:20Z' group by time(5s)`, 3065 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","mean"],"values":[["2009-11-10T23:00:00Z",4],["2009-11-10T23:00:05Z",4],["2009-11-10T23:00:10Z",null],["2009-11-10T23:00:15Z",10]]}]}]}`, 3066 params: url.Values{"db": []string{"db0"}}, 3067 }, 3068 }...) 3069 3070 ctx := context.Background() 3071 test.Run(ctx, t, s) 3072 } 3073 3074 func TestServer_Query_Aggregates_FloatMany(t *testing.T) { 3075 s := OpenServer(t) 3076 defer s.Close() 3077 3078 test := NewTest("db0", "rp0") 3079 test.writes = Writes{ 3080 &Write{data: strings.Join([]string{ 3081 fmt.Sprintf(`floatmany,host=server01 value=2.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3082 fmt.Sprintf(`floatmany,host=server02 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 3083 fmt.Sprintf(`floatmany,host=server03 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 3084 fmt.Sprintf(`floatmany,host=server04 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()), 3085 fmt.Sprintf(`floatmany,host=server05 value=5.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:40Z").UnixNano()), 3086 fmt.Sprintf(`floatmany,host=server06 value=5.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:50Z").UnixNano()), 3087 fmt.Sprintf(`floatmany,host=server07 value=7.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 3088 fmt.Sprintf(`floatmany,host=server08 value=9.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:10Z").UnixNano()), 3089 }, "\n")}, 3090 } 3091 3092 test.addQueries([]*Query{ 3093 { 3094 name: "mean and stddev - float", 3095 params: url.Values{"db": []string{"db0"}}, 3096 command: `SELECT MEAN(value), STDDEV(value) FROM floatmany WHERE time >= '2000-01-01' AND time < '2000-01-01T00:02:00Z' GROUP BY time(10m)`, 3097 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","mean","stddev"],"values":[["2000-01-01T00:00:00Z",5,2.138089935299395]]}]}]}`, 3098 }, 3099 { 3100 name: "first - float", 3101 params: url.Values{"db": []string{"db0"}}, 3102 command: `SELECT FIRST(value) FROM floatmany`, 3103 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 3104 }, 3105 { 3106 name: "last - float", 3107 params: url.Values{"db": []string{"db0"}}, 3108 command: `SELECT LAST(value) FROM floatmany`, 3109 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","last"],"values":[["2000-01-01T00:01:10Z",9]]}]}]}`, 3110 }, 3111 { 3112 name: "spread - float", 3113 params: url.Values{"db": []string{"db0"}}, 3114 command: `SELECT SPREAD(value) FROM floatmany`, 3115 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","spread"],"values":[["1970-01-01T00:00:00Z",7]]}]}]}`, 3116 }, 3117 { 3118 name: "median - even count - float", 3119 params: url.Values{"db": []string{"db0"}}, 3120 command: `SELECT MEDIAN(value) FROM floatmany`, 3121 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","median"],"values":[["1970-01-01T00:00:00Z",4.5]]}]}]}`, 3122 }, 3123 { 3124 name: "median - odd count - float", 3125 params: url.Values{"db": []string{"db0"}}, 3126 command: `SELECT MEDIAN(value) FROM floatmany where time < '2000-01-01T00:01:10Z'`, 3127 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","median"],"values":[["1970-01-01T00:00:00Z",4]]}]}]}`, 3128 }, 3129 { 3130 name: "mode - single - float", 3131 params: url.Values{"db": []string{"db0"}}, 3132 command: `SELECT MODE(value) FROM floatmany`, 3133 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","mode"],"values":[["1970-01-01T00:00:00Z",4]]}]}]}`, 3134 }, 3135 { 3136 name: "mode - multiple - float", 3137 params: url.Values{"db": []string{"db0"}}, 3138 command: `SELECT MODE(value) FROM floatmany where time < '2000-01-01T00:00:10Z'`, 3139 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","mode"],"values":[["1970-01-01T00:00:00Z",2]]}]}]}`, 3140 }, 3141 { 3142 name: "distinct as call - float", 3143 params: url.Values{"db": []string{"db0"}}, 3144 command: `SELECT DISTINCT(value) FROM floatmany`, 3145 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","distinct"],"values":[["1970-01-01T00:00:00Z",2],["1970-01-01T00:00:00Z",4],["1970-01-01T00:00:00Z",5],["1970-01-01T00:00:00Z",7],["1970-01-01T00:00:00Z",9]]}]}]}`, 3146 }, 3147 { 3148 name: "distinct alt syntax - float", 3149 params: url.Values{"db": []string{"db0"}}, 3150 command: `SELECT DISTINCT value FROM floatmany`, 3151 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","distinct"],"values":[["1970-01-01T00:00:00Z",2],["1970-01-01T00:00:00Z",4],["1970-01-01T00:00:00Z",5],["1970-01-01T00:00:00Z",7],["1970-01-01T00:00:00Z",9]]}]}]}`, 3152 }, 3153 { 3154 name: "distinct select tag - float", 3155 params: url.Values{"db": []string{"db0"}}, 3156 command: `SELECT DISTINCT(host) FROM floatmany`, 3157 exp: `{"results":[{"statement_id":0,"error":"statement must have at least one field in select clause"}]}`, 3158 skip: SkippedOSS, // FIXME(benbjohnson): show be allowed, stream tag values 3159 }, 3160 { 3161 name: "distinct alt select tag - float", 3162 params: url.Values{"db": []string{"db0"}}, 3163 command: `SELECT DISTINCT host FROM floatmany`, 3164 exp: `{"results":[{"statement_id":0,"error":"statement must have at least one field in select clause"}]}`, 3165 skip: SkippedOSS, // FIXME(benbjohnson): show be allowed, stream tag values 3166 }, 3167 { 3168 name: "count distinct - float", 3169 params: url.Values{"db": []string{"db0"}}, 3170 command: `SELECT COUNT(DISTINCT value) FROM floatmany`, 3171 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",5]]}]}]}`, 3172 }, 3173 { 3174 name: "count distinct as call - float", 3175 params: url.Values{"db": []string{"db0"}}, 3176 command: `SELECT COUNT(DISTINCT(value)) FROM floatmany`, 3177 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",5]]}]}]}`, 3178 }, 3179 { 3180 name: "count distinct select tag - float", 3181 params: url.Values{"db": []string{"db0"}}, 3182 command: `SELECT COUNT(DISTINCT host) FROM floatmany`, 3183 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",0]]}]}]}`, 3184 skip: SkippedOSS, // FIXME(benbjohnson): stream tag values 3185 }, 3186 { 3187 name: "count distinct as call select tag - float", 3188 params: url.Values{"db": []string{"db0"}}, 3189 command: `SELECT COUNT(DISTINCT host) FROM floatmany`, 3190 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatmany","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",0]]}]}]}`, 3191 skip: SkippedOSS, // FIXME(benbjohnson): stream tag values 3192 }, 3193 }...) 3194 3195 ctx := context.Background() 3196 test.Run(ctx, t, s) 3197 } 3198 3199 func TestServer_Query_ShowTagValues(t *testing.T) { 3200 s := OpenServer(t) 3201 defer s.Close() 3202 3203 writes := []string{ 3204 fmt.Sprintf(`cpu,host=server01 value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3205 fmt.Sprintf(`cpu,host=server01,region=uswest value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3206 fmt.Sprintf(`cpu,host=server01,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3207 fmt.Sprintf(`cpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3208 fmt.Sprintf(`gpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3209 fmt.Sprintf(`gpu,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3210 fmt.Sprintf(`disk,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3211 fmt.Sprintf(`_,__name__=metric1 value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3212 fmt.Sprintf(`_,__name__=metric2 value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3213 } 3214 3215 test := NewTest("db0", "rp0") 3216 test.writes = Writes{ 3217 &Write{data: strings.Join(writes, "\n")}, 3218 } 3219 3220 test.addQueries([]*Query{ 3221 { 3222 name: "show tag values with key", 3223 command: "SHOW TAG VALUES WITH KEY = host", 3224 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["host","server02"]]},{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server02"],["host","server03"]]}]}]}`, 3225 params: url.Values{"db": []string{"db0"}}, 3226 }, 3227 { 3228 name: "show tag values with key regex", 3229 command: "SHOW TAG VALUES WITH KEY =~ /ho/", 3230 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["host","server02"]]},{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server02"],["host","server03"]]}]}]}`, 3231 params: url.Values{"db": []string{"db0"}}, 3232 }, 3233 { 3234 name: `show tag values with key and where`, 3235 command: `SHOW TAG VALUES FROM cpu WITH KEY = host WHERE region = 'uswest'`, 3236 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"]]}]}]}`, 3237 params: url.Values{"db": []string{"db0"}}, 3238 }, 3239 { 3240 name: `show tag values with key regex and where`, 3241 command: `SHOW TAG VALUES FROM cpu WITH KEY =~ /ho/ WHERE region = 'uswest'`, 3242 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"]]}]}]}`, 3243 params: url.Values{"db": []string{"db0"}}, 3244 }, 3245 { 3246 name: `show tag values with key and where matches the regular expression`, 3247 command: `SHOW TAG VALUES WITH KEY = host WHERE region =~ /ca.*/`, 3248 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server03"]]}]}]}`, 3249 params: url.Values{"db": []string{"db0"}}, 3250 }, 3251 { 3252 name: `show tag values with key and where does not match the regular expression`, 3253 command: `SHOW TAG VALUES WITH KEY = region WHERE host !~ /server0[12]/`, 3254 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["key","value"],"values":[["region","caeast"]]},{"name":"gpu","columns":["key","value"],"values":[["region","caeast"]]}]}]}`, 3255 params: url.Values{"db": []string{"db0"}}, 3256 }, 3257 { 3258 name: `show tag values with key and where partially matches the regular expression`, 3259 command: `SHOW TAG VALUES WITH KEY = host WHERE region =~ /us/`, 3260 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["host","server02"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server02"]]}]}]}`, 3261 params: url.Values{"db": []string{"db0"}}, 3262 }, 3263 { 3264 name: `show tag values with key and where partially does not match the regular expression`, 3265 command: `SHOW TAG VALUES WITH KEY = host WHERE region !~ /us/`, 3266 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"]]},{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server03"]]}]}]}`, 3267 params: url.Values{"db": []string{"db0"}}, 3268 }, 3269 { 3270 name: `show tag values with key in and where does not match the regular expression`, 3271 command: `SHOW TAG VALUES FROM cpu WITH KEY IN (host, region) WHERE region = 'uswest'`, 3272 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["region","uswest"]]}]}]}`, 3273 params: url.Values{"db": []string{"db0"}}, 3274 }, 3275 { 3276 name: `show tag values with key regex and where does not match the regular expression`, 3277 command: `SHOW TAG VALUES FROM cpu WITH KEY =~ /(host|region)/ WHERE region = 'uswest'`, 3278 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["region","uswest"]]}]}]}`, 3279 params: url.Values{"db": []string{"db0"}}, 3280 }, 3281 { 3282 name: `show tag values with key and measurement matches regular expression`, 3283 command: `SHOW TAG VALUES FROM /[cg]pu/ WITH KEY = host`, 3284 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["host","server02"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server02"],["host","server03"]]}]}]}`, 3285 params: url.Values{"db": []string{"db0"}}, 3286 }, 3287 { 3288 name: "show tag values with key where time", 3289 command: "SHOW TAG VALUES WITH KEY = host WHERE time > 0", 3290 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["host","server02"]]},{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server02"],["host","server03"]]}]}]}`, 3291 params: url.Values{"db": []string{"db0"}}, 3292 }, 3293 { 3294 name: "show tag values with key regex where time", 3295 command: "SHOW TAG VALUES WITH KEY =~ /ho/ WHERE time > 0", 3296 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["host","server02"]]},{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server02"],["host","server03"]]}]}]}`, 3297 params: url.Values{"db": []string{"db0"}}, 3298 }, 3299 { 3300 name: `show tag values with key and where time`, 3301 command: `SHOW TAG VALUES FROM cpu WITH KEY = host WHERE region = 'uswest' AND time > 0`, 3302 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"]]}]}]}`, 3303 params: url.Values{"db": []string{"db0"}}, 3304 }, 3305 { 3306 name: `show tag values with key regex and where time`, 3307 command: `SHOW TAG VALUES FROM cpu WITH KEY =~ /ho/ WHERE region = 'uswest' AND time > 0`, 3308 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"]]}]}]}`, 3309 params: url.Values{"db": []string{"db0"}}, 3310 }, 3311 { 3312 name: `show tag values with key and where matches the regular expression where time`, 3313 command: `SHOW TAG VALUES WITH KEY = host WHERE region =~ /ca.*/ AND time > 0`, 3314 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server03"]]}]}]}`, 3315 params: url.Values{"db": []string{"db0"}}, 3316 }, 3317 { 3318 name: `show tag values with key and where does not match the regular expression where time`, 3319 command: `SHOW TAG VALUES WITH KEY = region WHERE host !~ /server0[12]/ AND time > 0`, 3320 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["key","value"],"values":[["region","caeast"]]},{"name":"gpu","columns":["key","value"],"values":[["region","caeast"]]}]}]}`, 3321 params: url.Values{"db": []string{"db0"}}, 3322 }, 3323 { 3324 name: `show tag values with key and where partially matches the regular expression where time`, 3325 command: `SHOW TAG VALUES WITH KEY = host WHERE region =~ /us/ AND time > 0`, 3326 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["host","server02"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server02"]]}]}]}`, 3327 params: url.Values{"db": []string{"db0"}}, 3328 }, 3329 { 3330 name: `show tag values with key and where partially does not match the regular expression where time`, 3331 command: `SHOW TAG VALUES WITH KEY = host WHERE region !~ /us/ AND time > 0`, 3332 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"]]},{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server03"]]}]}]}`, 3333 params: url.Values{"db": []string{"db0"}}, 3334 }, 3335 { 3336 name: `show tag values with key in and where does not match the regular expression where time`, 3337 command: `SHOW TAG VALUES FROM cpu WITH KEY IN (host, region) WHERE region = 'uswest' AND time > 0`, 3338 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["region","uswest"]]}]}]}`, 3339 params: url.Values{"db": []string{"db0"}}, 3340 }, 3341 { 3342 name: `show tag values with key regex and where does not match the regular expression where time`, 3343 command: `SHOW TAG VALUES FROM cpu WITH KEY =~ /(host|region)/ WHERE region = 'uswest' AND time > 0`, 3344 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["region","uswest"]]}]}]}`, 3345 params: url.Values{"db": []string{"db0"}}, 3346 }, 3347 { 3348 name: `show tag values with key and measurement matches regular expression where time`, 3349 command: `SHOW TAG VALUES FROM /[cg]pu/ WITH KEY = host WHERE time > 0`, 3350 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"],["host","server02"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server02"],["host","server03"]]}]}]}`, 3351 params: url.Values{"db": []string{"db0"}}, 3352 }, 3353 { 3354 name: `show tag values with key where label starts with underscore`, 3355 command: `SHOW TAG VALUES FROM "_" WITH KEY = "__name__" WHERE "__name__" = 'metric1'`, 3356 exp: `{"results":[{"statement_id":0,"series":[{"name":"_","columns":["key","value"],"values":[["__name__","metric1"]]}]}]}`, 3357 params: url.Values{"db": []string{"db0"}}, 3358 }, 3359 { 3360 name: "show tag values with value filter", 3361 skip: FixRequired + "https://github.com/influxdata/idpe/issues/7592", 3362 command: "SHOW TAG VALUES WITH KEY = host WHERE value = 'server03'", 3363 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["key","value"],"values":[["host","server03"]]},{"name":"gpu","columns":["key","value"],"values":[["host","server03"]]}]}]}`, 3364 params: url.Values{"db": []string{"db0"}}, 3365 }, 3366 { 3367 name: "show tag values with no matching value filter", 3368 command: "SHOW TAG VALUES WITH KEY = host WHERE value = 'no_such_value'", 3369 exp: `{"results":[{"statement_id":0}]}`, 3370 params: url.Values{"db": []string{"db0"}}, 3371 }, 3372 { 3373 name: "show tag values with non-string value filter", 3374 command: "SHOW TAG VALUES WITH KEY = host WHERE value = 5000", 3375 exp: `{"results":[{"statement_id":0}]}`, 3376 params: url.Values{"db": []string{"db0"}}, 3377 }, 3378 }...) 3379 3380 ctx := context.Background() 3381 test.Run(ctx, t, s) 3382 } 3383 3384 func TestServer_Query_ShowTagKeyCardinality(t *testing.T) { 3385 t.Skip(NotSupported) 3386 s := OpenServer(t) 3387 defer s.Close() 3388 3389 writes := []string{ 3390 fmt.Sprintf(`cpu,host=server01 value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3391 fmt.Sprintf(`cpu,host=server01,region=uswest value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3392 fmt.Sprintf(`cpu,host=server01,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3393 fmt.Sprintf(`cpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3394 fmt.Sprintf(`gpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3395 fmt.Sprintf(`gpu,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3396 fmt.Sprintf(`disk,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3397 } 3398 3399 test := NewTest("db0", "rp0") 3400 test.writes = Writes{ 3401 &Write{data: strings.Join(writes, "\n")}, 3402 } 3403 3404 test.addQueries([]*Query{ 3405 { 3406 name: `show tag key cardinality`, 3407 command: "SHOW TAG KEY CARDINALITY", 3408 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"disk","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 3409 params: url.Values{"db": []string{"db0"}}, 3410 }, 3411 { 3412 name: `show tag key cardinality on db0`, 3413 command: "SHOW TAG KEY CARDINALITY ON db0", 3414 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"disk","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 3415 }, 3416 { 3417 name: "show tag key cardinality from", 3418 command: "SHOW TAG KEY CARDINALITY FROM cpu", 3419 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`, 3420 params: url.Values{"db": []string{"db0"}}, 3421 }, 3422 { 3423 name: "show tag key cardinality from regex", 3424 command: "SHOW TAG KEY CARDINALITY FROM /[cg]pu/", 3425 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 3426 params: url.Values{"db": []string{"db0"}}, 3427 }, 3428 { 3429 name: "show tag key cardinality measurement not found", 3430 command: "SHOW TAG KEY CARDINALITY FROM doesntexist", 3431 exp: `{"results":[{"statement_id":0}]}`, 3432 params: url.Values{"db": []string{"db0"}}, 3433 }, 3434 { 3435 name: "show tag key cardinality with time in WHERE clause errors", 3436 command: "SHOW TAG KEY CARDINALITY FROM cpu WHERE time > now() - 1h", 3437 exp: `{"results":[{"statement_id":0,"error":"SHOW TAG KEY EXACT CARDINALITY doesn't support time in WHERE clause"}]}`, 3438 params: url.Values{"db": []string{"db0"}}, 3439 }, 3440 { 3441 name: `show tag key exact cardinality`, 3442 command: "SHOW TAG KEY EXACT CARDINALITY", 3443 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"disk","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 3444 params: url.Values{"db": []string{"db0"}}, 3445 }, 3446 { 3447 name: `show tag key exact cardinality on db0`, 3448 command: "SHOW TAG KEY EXACT CARDINALITY ON db0", 3449 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"disk","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 3450 }, 3451 { 3452 name: "show tag key exact cardinality from", 3453 command: "SHOW TAG KEY EXACT CARDINALITY FROM cpu", 3454 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`, 3455 params: url.Values{"db": []string{"db0"}}, 3456 }, 3457 { 3458 name: "show tag key exact cardinality from regex", 3459 command: "SHOW TAG KEY EXACT CARDINALITY FROM /[cg]pu/", 3460 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 3461 params: url.Values{"db": []string{"db0"}}, 3462 }, 3463 { 3464 name: "show tag key exact cardinality measurement not found", 3465 command: "SHOW TAG KEY EXACT CARDINALITY FROM doesntexist", 3466 exp: `{"results":[{"statement_id":0}]}`, 3467 params: url.Values{"db": []string{"db0"}}, 3468 }, 3469 { 3470 name: "show tag key exact cardinality with time in WHERE clause errors", 3471 command: "SHOW TAG KEY EXACT CARDINALITY FROM cpu WHERE time > now() - 1h", 3472 exp: `{"results":[{"statement_id":0,"error":"SHOW TAG KEY EXACT CARDINALITY doesn't support time in WHERE clause"}]}`, 3473 params: url.Values{"db": []string{"db0"}}, 3474 }, 3475 { 3476 name: `show tag values cardinality with key and where matches the regular expression`, 3477 command: `SHOW TAG VALUES CARDINALITY WITH KEY = host WHERE region =~ /ca.*/`, 3478 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 3479 params: url.Values{"db": []string{"db0"}}, 3480 }, 3481 { 3482 name: `show tag values cardinality with key and where does not match the regular expression`, 3483 command: `SHOW TAG VALUES CARDINALITY WITH KEY = region WHERE host !~ /server0[12]/`, 3484 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 3485 params: url.Values{"db": []string{"db0"}}, 3486 }, 3487 { 3488 name: `show tag values cardinality with key and where partially matches the regular expression`, 3489 command: `SHOW TAG VALUES CARDINALITY WITH KEY = host WHERE region =~ /us/`, 3490 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 3491 params: url.Values{"db": []string{"db0"}}, 3492 }, 3493 { 3494 name: `show tag values cardinality with key and where partially does not match the regular expression`, 3495 command: `SHOW TAG VALUES CARDINALITY WITH KEY = host WHERE region !~ /us/`, 3496 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 3497 params: url.Values{"db": []string{"db0"}}, 3498 }, 3499 { 3500 name: `show tag values cardinality with key in and where does not match the regular expression`, 3501 command: `SHOW TAG VALUES CARDINALITY FROM cpu WITH KEY IN (host, region) WHERE region = 'uswest'`, 3502 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`, 3503 params: url.Values{"db": []string{"db0"}}, 3504 }, 3505 { 3506 name: `show tag values cardinality with key regex and where does not match the regular expression`, 3507 command: `SHOW TAG VALUES CARDINALITY FROM cpu WITH KEY =~ /(host|region)/ WHERE region = 'uswest'`, 3508 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`, 3509 params: url.Values{"db": []string{"db0"}}, 3510 }, 3511 { 3512 name: `show tag values cardinality with key and measurement matches regular expression`, 3513 command: `SHOW TAG VALUES CARDINALITY FROM /[cg]pu/ WITH KEY = host`, 3514 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 3515 params: url.Values{"db": []string{"db0"}}, 3516 }, 3517 { 3518 name: `show tag values exact cardinality with key and where matches the regular expression`, 3519 command: `SHOW TAG VALUES EXACT CARDINALITY WITH KEY = host WHERE region =~ /ca.*/`, 3520 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 3521 params: url.Values{"db": []string{"db0"}}, 3522 }, 3523 { 3524 name: `show tag values exact cardinality with key and where does not match the regular expression`, 3525 command: `SHOW TAG VALUES EXACT CARDINALITY WITH KEY = region WHERE host !~ /server0[12]/`, 3526 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 3527 params: url.Values{"db": []string{"db0"}}, 3528 }, 3529 { 3530 name: `show tag values exact cardinality with key and where partially matches the regular expression`, 3531 command: `SHOW TAG VALUES EXACT CARDINALITY WITH KEY = host WHERE region =~ /us/`, 3532 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 3533 params: url.Values{"db": []string{"db0"}}, 3534 }, 3535 { 3536 name: `show tag values exact cardinality with key and where partially does not match the regular expression`, 3537 command: `SHOW TAG VALUES EXACT CARDINALITY WITH KEY = host WHERE region !~ /us/`, 3538 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 3539 params: url.Values{"db": []string{"db0"}}, 3540 }, 3541 { 3542 name: `show tag values exact cardinality with key in and where does not match the regular expression`, 3543 command: `SHOW TAG VALUES EXACT CARDINALITY FROM cpu WITH KEY IN (host, region) WHERE region = 'uswest'`, 3544 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`, 3545 params: url.Values{"db": []string{"db0"}}, 3546 }, 3547 { 3548 name: `show tag values exact cardinality with key regex and where does not match the regular expression`, 3549 command: `SHOW TAG VALUES EXACT CARDINALITY FROM cpu WITH KEY =~ /(host|region)/ WHERE region = 'uswest'`, 3550 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`, 3551 params: url.Values{"db": []string{"db0"}}, 3552 }, 3553 { 3554 name: `show tag values exact cardinality with key and measurement matches regular expression`, 3555 command: `SHOW TAG VALUES EXACT CARDINALITY FROM /[cg]pu/ WITH KEY = host`, 3556 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 3557 params: url.Values{"db": []string{"db0"}}, 3558 }, 3559 }...) 3560 3561 ctx := context.Background() 3562 test.Run(ctx, t, s) 3563 } 3564 3565 func TestServer_Query_Aggregates_FloatOverlap(t *testing.T) { 3566 s := OpenServer(t) 3567 defer s.Close() 3568 3569 test := NewTest("db0", "rp0") 3570 test.writes = Writes{ 3571 &Write{data: strings.Join([]string{ 3572 fmt.Sprintf(`floatoverlap,region=us-east value=20.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3573 fmt.Sprintf(`floatoverlap,region=us-east value=30.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 3574 fmt.Sprintf(`floatoverlap,region=us-west value=100.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3575 fmt.Sprintf(`floatoverlap,region=us-east otherVal=20.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 3576 }, "\n")}, 3577 } 3578 3579 test.addQueries([]*Query{ 3580 { 3581 name: "aggregation with no interval - float", 3582 params: url.Values{"db": []string{"db0"}}, 3583 command: `SELECT count(value) FROM floatoverlap WHERE time = '2000-01-01 00:00:00'`, 3584 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatoverlap","columns":["time","count"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 3585 }, 3586 { 3587 name: "sum - float", 3588 params: url.Values{"db": []string{"db0"}}, 3589 command: `SELECT SUM(value) FROM floatoverlap WHERE time >= '2000-01-01 00:00:05' AND time <= '2000-01-01T00:00:10Z' GROUP BY time(10s), region`, 3590 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatoverlap","tags":{"region":"us-east"},"columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",null],["2000-01-01T00:00:10Z",30]]}]}]}`, 3591 }, 3592 { 3593 name: "aggregation with a null field value - float", 3594 params: url.Values{"db": []string{"db0"}}, 3595 command: `SELECT SUM(value) FROM floatoverlap GROUP BY region`, 3596 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatoverlap","tags":{"region":"us-east"},"columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",50]]},{"name":"floatoverlap","tags":{"region":"us-west"},"columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",100]]}]}]}`, 3597 }, 3598 { 3599 name: "multiple aggregations - float", 3600 params: url.Values{"db": []string{"db0"}}, 3601 command: `SELECT SUM(value), MEAN(value) FROM floatoverlap GROUP BY region`, 3602 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatoverlap","tags":{"region":"us-east"},"columns":["time","sum","mean"],"values":[["1970-01-01T00:00:00Z",50,25]]},{"name":"floatoverlap","tags":{"region":"us-west"},"columns":["time","sum","mean"],"values":[["1970-01-01T00:00:00Z",100,100]]}]}]}`, 3603 }, 3604 { 3605 name: "multiple aggregations with division - float", 3606 params: url.Values{"db": []string{"db0"}}, 3607 command: `SELECT sum(value) / mean(value) as div FROM floatoverlap GROUP BY region`, 3608 exp: `{"results":[{"statement_id":0,"series":[{"name":"floatoverlap","tags":{"region":"us-east"},"columns":["time","div"],"values":[["1970-01-01T00:00:00Z",2]]},{"name":"floatoverlap","tags":{"region":"us-west"},"columns":["time","div"],"values":[["1970-01-01T00:00:00Z",1]]}]}]}`, 3609 }, 3610 }...) 3611 3612 ctx := context.Background() 3613 test.Run(ctx, t, s) 3614 } 3615 3616 func TestServer_Query_ShowFieldKeyCardinality(t *testing.T) { 3617 t.Skip(NotSupported) 3618 s := OpenServer(t) 3619 defer s.Close() 3620 3621 writes := []string{ 3622 fmt.Sprintf(`cpu,host=server01 field1=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3623 fmt.Sprintf(`cpu,host=server01,region=uswest field1=200,field2=300,field3=400 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3624 fmt.Sprintf(`cpu,host=server01,region=useast field1=200,field2=300,field3=400 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3625 fmt.Sprintf(`cpu,host=server02,region=useast field1=200,field2=300,field3=400 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3626 fmt.Sprintf(`gpu,host=server01,region=useast field4=200,field5=300 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3627 fmt.Sprintf(`gpu,host=server03,region=caeast field6=200,field7=300 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3628 fmt.Sprintf(`disk,host=server03,region=caeast field8=200,field9=300 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3629 } 3630 3631 test := NewTest("db0", "rp0") 3632 test.writes = Writes{ 3633 &Write{data: strings.Join(writes, "\n")}, 3634 } 3635 3636 test.addQueries([]*Query{ 3637 { 3638 name: `show field key cardinality`, 3639 command: `SHOW FIELD KEY CARDINALITY`, 3640 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[3]]},{"name":"disk","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[4]]}]}]}`, 3641 params: url.Values{"db": []string{"db0"}}, 3642 }, 3643 { 3644 name: `show field key cardinality from measurement`, 3645 command: `SHOW FIELD KEY CARDINALITY FROM cpu`, 3646 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[3]]}]}]}`, 3647 params: url.Values{"db": []string{"db0"}}, 3648 }, 3649 { 3650 name: `show field key cardinality measurement with regex`, 3651 command: `SHOW FIELD KEY CARDINALITY FROM /[cg]pu/`, 3652 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[3]]},{"name":"gpu","columns":["count"],"values":[[4]]}]}]}`, 3653 params: url.Values{"db": []string{"db0"}}, 3654 }, 3655 { 3656 name: `show field key exact cardinality`, 3657 command: `SHOW FIELD KEY EXACT CARDINALITY`, 3658 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[3]]},{"name":"disk","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[4]]}]}]}`, 3659 params: url.Values{"db": []string{"db0"}}, 3660 }, 3661 { 3662 name: `show field key exact cardinality from measurement`, 3663 command: `SHOW FIELD KEY EXACT CARDINALITY FROM cpu`, 3664 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[3]]}]}]}`, 3665 params: url.Values{"db": []string{"db0"}}, 3666 }, 3667 { 3668 name: `show field key exact cardinality measurement with regex`, 3669 command: `SHOW FIELD KEY EXACT CARDINALITY FROM /[cg]pu/`, 3670 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[3]]},{"name":"gpu","columns":["count"],"values":[[4]]}]}]}`, 3671 params: url.Values{"db": []string{"db0"}}, 3672 }, 3673 }...) 3674 3675 ctx := context.Background() 3676 test.Run(ctx, t, s) 3677 } 3678 3679 func TestServer_Query_ShowFieldKeys(t *testing.T) { 3680 s := OpenServer(t) 3681 defer s.Close() 3682 3683 writes := []string{ 3684 fmt.Sprintf(`cpu,host=server01 field1=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3685 fmt.Sprintf(`cpu,host=server01,region=uswest field1=200,field2=300,field3=400 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3686 fmt.Sprintf(`cpu,host=server01,region=useast field1=200,field2=300,field3=400 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3687 fmt.Sprintf(`cpu,host=server02,region=useast field1=200,field2=300,field3=400 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3688 fmt.Sprintf(`gpu,host=server01,region=useast field4=200,field5=300 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3689 fmt.Sprintf(`gpu,host=server03,region=caeast field6=200,field7=300 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3690 fmt.Sprintf(`disk,host=server03,region=caeast field8=200,field9=300 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 3691 } 3692 3693 test := NewTest("db0", "rp0") 3694 test.writes = Writes{ 3695 &Write{data: strings.Join(writes, "\n")}, 3696 } 3697 3698 test.addQueries([]*Query{ 3699 { 3700 name: `show field keys`, 3701 command: `SHOW FIELD KEYS`, 3702 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["fieldKey","fieldType"],"values":[["field1","float"],["field2","float"],["field3","float"]]},{"name":"disk","columns":["fieldKey","fieldType"],"values":[["field8","float"],["field9","float"]]},{"name":"gpu","columns":["fieldKey","fieldType"],"values":[["field4","float"],["field5","float"],["field6","float"],["field7","float"]]}]}]}`, 3703 params: url.Values{"db": []string{"db0"}}, 3704 }, 3705 { 3706 name: `show field keys from measurement`, 3707 command: `SHOW FIELD KEYS FROM cpu`, 3708 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["fieldKey","fieldType"],"values":[["field1","float"],["field2","float"],["field3","float"]]}]}]}`, 3709 params: url.Values{"db": []string{"db0"}}, 3710 }, 3711 { 3712 name: `show field keys measurement with regex`, 3713 command: `SHOW FIELD KEYS FROM /[cg]pu/`, 3714 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["fieldKey","fieldType"],"values":[["field1","float"],["field2","float"],["field3","float"]]},{"name":"gpu","columns":["fieldKey","fieldType"],"values":[["field4","float"],["field5","float"],["field6","float"],["field7","float"]]}]}]}`, 3715 params: url.Values{"db": []string{"db0"}}, 3716 }, 3717 }...) 3718 3719 ctx := context.Background() 3720 test.Run(ctx, t, s) 3721 } 3722 3723 func TestServer_Query_FieldWithMultiplePeriodsMeasurementPrefixMatch(t *testing.T) { 3724 s := OpenServer(t) 3725 defer s.Close() 3726 3727 writes := []string{ 3728 fmt.Sprintf(`foo foo.bar.baz=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3729 } 3730 3731 test := NewTest("db0", "rp0") 3732 test.writes = Writes{ 3733 &Write{data: strings.Join(writes, "\n")}, 3734 } 3735 3736 test.addQueries([]*Query{ 3737 { 3738 name: "baseline", 3739 params: url.Values{"db": []string{"db0"}}, 3740 command: `select * from foo`, 3741 exp: `{"results":[{"statement_id":0,"series":[{"name":"foo","columns":["time","foo.bar.baz"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, 3742 }, 3743 { 3744 name: "select field with periods", 3745 params: url.Values{"db": []string{"db0"}}, 3746 command: `select "foo.bar.baz" from foo`, 3747 exp: `{"results":[{"statement_id":0,"series":[{"name":"foo","columns":["time","foo.bar.baz"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, 3748 }, 3749 }...) 3750 3751 ctx := context.Background() 3752 test.Run(ctx, t, s) 3753 } 3754 3755 func TestServer_Query_FieldWithMultiplePeriods(t *testing.T) { 3756 s := OpenServer(t) 3757 defer s.Close() 3758 3759 writes := []string{ 3760 fmt.Sprintf(`cpu foo.bar.baz=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3761 } 3762 3763 test := NewTest("db0", "rp0") 3764 test.writes = Writes{ 3765 &Write{data: strings.Join(writes, "\n")}, 3766 } 3767 3768 test.addQueries([]*Query{ 3769 { 3770 name: "baseline", 3771 params: url.Values{"db": []string{"db0"}}, 3772 command: `select * from cpu`, 3773 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","foo.bar.baz"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, 3774 }, 3775 { 3776 name: "select field with periods", 3777 params: url.Values{"db": []string{"db0"}}, 3778 command: `select "foo.bar.baz" from cpu`, 3779 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","foo.bar.baz"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, 3780 }, 3781 }...) 3782 3783 ctx := context.Background() 3784 test.Run(ctx, t, s) 3785 } 3786 3787 func TestServer_Query_Aggregates_GroupByOffset(t *testing.T) { 3788 s := OpenServer(t) 3789 defer s.Close() 3790 3791 test := NewTest("db0", "rp0") 3792 test.writes = Writes{ 3793 &Write{data: strings.Join([]string{ 3794 fmt.Sprintf(`offset,region=us-east,host=serverA value=20.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3795 fmt.Sprintf(`offset,region=us-east,host=serverB value=30.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 3796 fmt.Sprintf(`offset,region=us-west,host=serverC value=100.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3797 }, "\n")}, 3798 } 3799 3800 test.addQueries([]*Query{ 3801 { 3802 name: "group by offset - standard", 3803 params: url.Values{"db": []string{"db0"}}, 3804 command: `SELECT sum(value) FROM "offset" WHERE time >= '1999-12-31T23:59:55Z' AND time < '2000-01-01T00:00:15Z' GROUP BY time(10s, 5s) FILL(0)`, 3805 exp: `{"results":[{"statement_id":0,"series":[{"name":"offset","columns":["time","sum"],"values":[["1999-12-31T23:59:55Z",120],["2000-01-01T00:00:05Z",30]]}]}]}`, 3806 }, 3807 { 3808 name: "group by offset - misaligned time", 3809 params: url.Values{"db": []string{"db0"}}, 3810 command: `SELECT sum(value) FROM "offset" WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:20Z' GROUP BY time(10s, 5s) FILL(0)`, 3811 exp: `{"results":[{"statement_id":0,"series":[{"name":"offset","columns":["time","sum"],"values":[["1999-12-31T23:59:55Z",120],["2000-01-01T00:00:05Z",30],["2000-01-01T00:00:15Z",0]]}]}]}`, 3812 }, 3813 { 3814 name: "group by offset - negative time", 3815 params: url.Values{"db": []string{"db0"}}, 3816 command: `SELECT sum(value) FROM "offset" WHERE time >= '1999-12-31T23:59:55Z' AND time < '2000-01-01T00:00:15Z' GROUP BY time(10s, -5s) FILL(0)`, 3817 exp: `{"results":[{"statement_id":0,"series":[{"name":"offset","columns":["time","sum"],"values":[["1999-12-31T23:59:55Z",120],["2000-01-01T00:00:05Z",30]]}]}]}`, 3818 }, 3819 { 3820 name: "group by offset - modulo", 3821 params: url.Values{"db": []string{"db0"}}, 3822 command: `SELECT sum(value) FROM "offset" WHERE time >= '1999-12-31T23:59:55Z' AND time < '2000-01-01T00:00:15Z' GROUP BY time(10s, 35s) FILL(0)`, 3823 exp: `{"results":[{"statement_id":0,"series":[{"name":"offset","columns":["time","sum"],"values":[["1999-12-31T23:59:55Z",120],["2000-01-01T00:00:05Z",30]]}]}]}`, 3824 }, 3825 }...) 3826 3827 ctx := context.Background() 3828 test.Run(ctx, t, s) 3829 } 3830 3831 // This will test that when using a group by, that it observes the time you asked for 3832 // but will only put the values in the bucket that match the time range 3833 func TestServer_Query_GroupByTimeCutoffs(t *testing.T) { 3834 s := OpenServer(t) 3835 defer s.Close() 3836 3837 writes := []string{ 3838 fmt.Sprintf(`cpu value=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3839 fmt.Sprintf(`cpu value=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 3840 fmt.Sprintf(`cpu value=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:05Z").UnixNano()), 3841 fmt.Sprintf(`cpu value=4i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:08Z").UnixNano()), 3842 fmt.Sprintf(`cpu value=5i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:09Z").UnixNano()), 3843 fmt.Sprintf(`cpu value=6i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 3844 } 3845 test := NewTest("db0", "rp0") 3846 test.writes = Writes{ 3847 &Write{data: strings.Join(writes, "\n")}, 3848 } 3849 3850 test.addQueries([]*Query{ 3851 { 3852 name: "sum all time", 3853 params: url.Values{"db": []string{"db0"}}, 3854 command: `SELECT SUM(value) FROM cpu`, 3855 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",21]]}]}]}`, 3856 }, 3857 { 3858 name: "sum all time grouped by time 5s", 3859 params: url.Values{"db": []string{"db0"}}, 3860 command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T00:00:10Z' group by time(5s)`, 3861 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",3],["2000-01-01T00:00:05Z",12],["2000-01-01T00:00:10Z",6]]}]}]}`, 3862 }, 3863 { 3864 name: "sum all time grouped by time 5s missing first point", 3865 params: url.Values{"db": []string{"db0"}}, 3866 command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:01Z' and time <= '2000-01-01T00:00:10Z' group by time(5s)`, 3867 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:05Z",12],["2000-01-01T00:00:10Z",6]]}]}]}`, 3868 }, 3869 { 3870 name: "sum all time grouped by time 5s missing first points (null for bucket)", 3871 params: url.Values{"db": []string{"db0"}}, 3872 command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:02Z' and time <= '2000-01-01T00:00:10Z' group by time(5s)`, 3873 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",null],["2000-01-01T00:00:05Z",12],["2000-01-01T00:00:10Z",6]]}]}]}`, 3874 }, 3875 { 3876 name: "sum all time grouped by time 5s missing last point - 2 time intervals", 3877 params: url.Values{"db": []string{"db0"}}, 3878 command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T00:00:09Z' group by time(5s)`, 3879 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",3],["2000-01-01T00:00:05Z",12]]}]}]}`, 3880 }, 3881 { 3882 name: "sum all time grouped by time 5s missing last 2 points - 2 time intervals", 3883 params: url.Values{"db": []string{"db0"}}, 3884 command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T00:00:08Z' group by time(5s)`, 3885 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",3],["2000-01-01T00:00:05Z",7]]}]}]}`, 3886 }, 3887 }...) 3888 3889 ctx := context.Background() 3890 test.Run(ctx, t, s) 3891 } 3892 3893 func TestServer_Query_MapType(t *testing.T) { 3894 s := OpenServer(t) 3895 defer s.Close() 3896 3897 writes := []string{ 3898 fmt.Sprintf(`cpu value=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3899 fmt.Sprintf(`gpu speed=25 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3900 } 3901 test := NewTest("db0", "rp0") 3902 test.writes = Writes{ 3903 &Write{data: strings.Join(writes, "\n")}, 3904 } 3905 3906 test.addQueries([]*Query{ 3907 { 3908 name: "query value with a single measurement", 3909 params: url.Values{"db": []string{"db0"}}, 3910 command: `SELECT value FROM cpu`, 3911 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 3912 }, 3913 { 3914 name: "query wildcard with a single measurement", 3915 params: url.Values{"db": []string{"db0"}}, 3916 command: `SELECT * FROM cpu`, 3917 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 3918 }, 3919 { 3920 name: "query value with multiple measurements", 3921 params: url.Values{"db": []string{"db0"}}, 3922 command: `SELECT value FROM cpu, gpu`, 3923 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 3924 }, 3925 { 3926 name: "query wildcard with multiple measurements", 3927 params: url.Values{"db": []string{"db0"}}, 3928 command: `SELECT * FROM cpu, gpu`, 3929 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","speed","value"],"values":[["2000-01-01T00:00:00Z",null,2]]},{"name":"gpu","columns":["time","speed","value"],"values":[["2000-01-01T00:00:00Z",25,null]]}]}]}`, 3930 }, 3931 { 3932 name: "query value with a regex measurement", 3933 params: url.Values{"db": []string{"db0"}}, 3934 command: `SELECT value FROM /[cg]pu/`, 3935 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 3936 }, 3937 { 3938 name: "query wildcard with a regex measurement", 3939 params: url.Values{"db": []string{"db0"}}, 3940 command: `SELECT * FROM /[cg]pu/`, 3941 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","speed","value"],"values":[["2000-01-01T00:00:00Z",null,2]]},{"name":"gpu","columns":["time","speed","value"],"values":[["2000-01-01T00:00:00Z",25,null]]}]}]}`, 3942 }, 3943 }...) 3944 3945 ctx := context.Background() 3946 test.Run(ctx, t, s) 3947 } 3948 3949 func TestServer_Query_Subqueries(t *testing.T) { 3950 s := OpenServer(t) 3951 defer s.Close() 3952 3953 writes := []string{ 3954 fmt.Sprintf(`cpu,host=server01 usage_user=70i,usage_system=30i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3955 fmt.Sprintf(`cpu,host=server01 usage_user=45i,usage_system=55i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 3956 fmt.Sprintf(`cpu,host=server01 usage_user=23i,usage_system=77i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 3957 fmt.Sprintf(`cpu,host=server02 usage_user=11i,usage_system=89i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 3958 fmt.Sprintf(`cpu,host=server02 usage_user=28i,usage_system=72i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 3959 fmt.Sprintf(`cpu,host=server02 usage_user=12i,usage_system=53i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 3960 } 3961 test := NewTest("db0", "rp0") 3962 test.writes = Writes{ 3963 &Write{data: strings.Join(writes, "\n")}, 3964 } 3965 3966 test.addQueries([]*Query{ 3967 { 3968 params: url.Values{"db": []string{"db0"}}, 3969 command: `SELECT mean FROM (SELECT mean(usage_user) FROM cpu) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 3970 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",31.5]]}]}]}`, 3971 }, 3972 { 3973 params: url.Values{"db": []string{"db0"}}, 3974 command: `SELECT value FROM (SELECT mean(usage_user) AS value FROM cpu) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 3975 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00Z",31.5]]}]}]}`, 3976 }, 3977 { 3978 params: url.Values{"db": []string{"db0"}}, 3979 command: `SELECT mean(usage) FROM (SELECT 100 - usage_user AS usage FROM cpu) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 3980 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",68.5]]}]}]}`, 3981 }, 3982 { 3983 params: url.Values{"db": []string{"db0"}}, 3984 command: `SELECT host FROM (SELECT min(usage_user), host FROM cpu) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 3985 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","host"],"values":[["2000-01-01T00:00:00Z","server02"]]}]}]}`, 3986 }, 3987 { 3988 params: url.Values{"db": []string{"db0"}}, 3989 command: `SELECT host FROM (SELECT min(usage_user) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 3990 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","host"],"values":[["2000-01-01T00:00:00Z","server02"],["2000-01-01T00:00:20Z","server01"]]}]}]}`, 3991 }, 3992 { 3993 params: url.Values{"db": []string{"db0"}}, 3994 command: `SELECT host FROM (SELECT min(usage_user) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z' GROUP BY host`, 3995 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","host"],"values":[["2000-01-01T00:00:20Z","server01"]]},{"name":"cpu","tags":{"host":"server02"},"columns":["time","host"],"values":[["2000-01-01T00:00:00Z","server02"]]}]}]}`, 3996 }, 3997 { 3998 params: url.Values{"db": []string{"db0"}}, 3999 command: `SELECT mean(min) FROM (SELECT min(usage_user) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4000 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",17]]}]}]}`, 4001 }, 4002 { 4003 params: url.Values{"db": []string{"db0"}}, 4004 command: `SELECT mean(min) FROM (SELECT (min(usage_user)) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4005 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",17]]}]}]}`, 4006 }, 4007 { 4008 params: url.Values{"db": []string{"db0"}}, 4009 command: `SELECT max(min), host FROM (SELECT min(usage_user) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4010 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","max","host"],"values":[["2000-01-01T00:00:20Z",23,"server01"]]}]}]}`, 4011 }, 4012 { 4013 params: url.Values{"db": []string{"db0"}}, 4014 command: `SELECT mean, host FROM (SELECT mean(usage_user) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4015 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean","host"],"values":[["2000-01-01T00:00:00Z",46,"server01"],["2000-01-01T00:00:00Z",17,"server02"]]}]}]}`, 4016 }, 4017 { 4018 params: url.Values{"db": []string{"db0"}}, 4019 command: `SELECT host FROM (SELECT mean(usage_user) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4020 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","host"],"values":[["2000-01-01T00:00:00Z","server01"],["2000-01-01T00:00:00Z","server02"]]}]}]}`, 4021 }, 4022 { 4023 params: url.Values{"db": []string{"db0"}}, 4024 command: `SELECT max(usage_system) FROM (SELECT min(usage_user), usage_system FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4025 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","max"],"values":[["2000-01-01T00:00:00Z",89]]}]}]}`, 4026 }, 4027 { 4028 params: url.Values{"db": []string{"db0"}}, 4029 command: `SELECT min(top), host FROM (SELECT top(usage_user, host, 2) FROM cpu) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4030 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","min","host"],"values":[["2000-01-01T00:00:10Z",28,"server02"]]}]}]}`, 4031 }, 4032 { 4033 params: url.Values{"db": []string{"db0"}}, 4034 command: `SELECT min(top), host FROM (SELECT top(usage_user, 2), host FROM cpu) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4035 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","min","host"],"values":[["2000-01-01T00:00:10Z",45,"server01"]]}]}]}`, 4036 }, 4037 { 4038 params: url.Values{"db": []string{"db0"}}, 4039 command: `SELECT count(host) FROM (SELECT top(usage_user, host, 2) FROM cpu) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4040 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","count"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`, 4041 }, 4042 { 4043 params: url.Values{"db": []string{"db0"}}, 4044 command: `SELECT sum(derivative) FROM (SELECT derivative(usage_user) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4045 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",-4.6]]}]}]}`, 4046 }, 4047 { 4048 params: url.Values{"db": []string{"db0"}}, 4049 command: `SELECT min(max) FROM (SELECT 100 - max(usage_user) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4050 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","min"],"values":[["2000-01-01T00:00:00Z",30]]}]}]}`, 4051 }, 4052 { 4053 params: url.Values{"db": []string{"db0"}}, 4054 command: `SELECT min(usage_system) FROM (SELECT max(usage_user), 100 - usage_system FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4055 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","min"],"values":[["2000-01-01T00:00:10Z",28]]}]}]}`, 4056 }, 4057 { 4058 params: url.Values{"db": []string{"db0"}}, 4059 command: `SELECT min(value) FROM (SELECT max(usage_user), usage_user - usage_system AS value FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4060 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","min"],"values":[["2000-01-01T00:00:10Z",-44]]}]}]}`, 4061 }, 4062 { 4063 params: url.Values{"db": []string{"db0"}}, 4064 command: `SELECT min(value) FROM (SELECT top(usage_user, 2), usage_user - usage_system AS value FROM cpu) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z' GROUP BY host`, 4065 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","min"],"values":[["2000-01-01T00:00:10Z",-10]]},{"name":"cpu","tags":{"host":"server02"},"columns":["time","min"],"values":[["2000-01-01T00:00:10Z",-44]]}]}]}`, 4066 }, 4067 { 4068 params: url.Values{"db": []string{"db0"}}, 4069 command: `SELECT min(value) FROM (SELECT max(usage_user), usage_user - usage_system AS value FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z' AND host = 'server01'`, 4070 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","min"],"values":[["2000-01-01T00:00:00Z",40]]}]}]}`, 4071 }, 4072 { 4073 params: url.Values{"db": []string{"db0"}}, 4074 command: `SELECT value FROM (SELECT max(usage_user), usage_user - usage_system AS value FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z' AND value > 0`, 4075 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00Z",40]]}]}]}`, 4076 }, 4077 { 4078 params: url.Values{"db": []string{"db0"}}, 4079 command: `SELECT max FROM (SELECT max(usage_user) FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z' AND host = 'server01'`, 4080 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","max"],"values":[["2000-01-01T00:00:00Z",70]]}]}]}`, 4081 }, 4082 { 4083 params: url.Values{"db": []string{"db0"}}, 4084 command: `SELECT mean(value) FROM (SELECT max(usage_user), usage_user - usage_system AS value FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z' AND value > 0`, 4085 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",40]]}]}]}`, 4086 }, 4087 { 4088 params: url.Values{"db": []string{"db0"}}, 4089 command: `SELECT mean(value) FROM (SELECT max(usage_user), usage_user - usage_system AS value FROM cpu GROUP BY host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z' AND host =~ /server/`, 4090 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",-2]]}]}]}`, 4091 }, 4092 { 4093 params: url.Values{"db": []string{"db0"}}, 4094 command: `SELECT top(usage_system, host, 2) FROM (SELECT min(usage_user), usage_system FROM cpu GROUP BY time(20s), host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4095 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","top","host"],"values":[["2000-01-01T00:00:00Z",89,"server02"],["2000-01-01T00:00:20Z",77,"server01"]]}]}]}`, 4096 }, 4097 { 4098 params: url.Values{"db": []string{"db0"}}, 4099 command: `SELECT bottom(usage_system, host, 2) FROM (SELECT max(usage_user), usage_system FROM cpu GROUP BY time(20s), host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 4100 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","bottom","host"],"values":[["2000-01-01T00:00:00Z",30,"server01"],["2000-01-01T00:00:20Z",53,"server02"]]}]}]}`, 4101 }, 4102 }...) 4103 4104 ctx := context.Background() 4105 test.Run(ctx, t, s) 4106 } 4107 4108 func TestServer_Query_SubqueryWithGroupBy(t *testing.T) { 4109 s := OpenServer(t) 4110 defer s.Close() 4111 4112 writes := []string{ 4113 fmt.Sprintf(`cpu,host=server01,region=uswest value=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4114 fmt.Sprintf(`cpu,host=server01,region=uswest value=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 4115 fmt.Sprintf(`cpu,host=server01,region=uswest value=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), 4116 fmt.Sprintf(`cpu,host=server01,region=uswest value=4i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 4117 fmt.Sprintf(`cpu,host=server02,region=uswest value=5i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4118 fmt.Sprintf(`cpu,host=server02,region=uswest value=6i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 4119 fmt.Sprintf(`cpu,host=server02,region=uswest value=7i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), 4120 fmt.Sprintf(`cpu,host=server02,region=uswest value=8i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 4121 fmt.Sprintf(`cpu,host=server01,region=useast value=9i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4122 fmt.Sprintf(`cpu,host=server01,region=useast value=10i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 4123 fmt.Sprintf(`cpu,host=server01,region=useast value=11i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), 4124 fmt.Sprintf(`cpu,host=server01,region=useast value=12i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 4125 fmt.Sprintf(`cpu,host=server02,region=useast value=13i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4126 fmt.Sprintf(`cpu,host=server02,region=useast value=14i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 4127 fmt.Sprintf(`cpu,host=server02,region=useast value=15i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), 4128 fmt.Sprintf(`cpu,host=server02,region=useast value=16i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 4129 } 4130 test := NewTest("db0", "rp0") 4131 test.writes = Writes{ 4132 &Write{data: strings.Join(writes, "\n")}, 4133 } 4134 4135 test.addQueries([]*Query{ 4136 { 4137 name: "group by time(2s) - time(2s), host", 4138 params: url.Values{"db": []string{"db0"}}, 4139 command: `SELECT mean(mean) FROM (SELECT mean(value) FROM cpu GROUP BY time(2s), host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:04Z' GROUP BY time(2s)`, 4140 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",7.5],["2000-01-01T00:00:02Z",9.5]]}]}]}`, 4141 }, 4142 { 4143 name: "group by time(4s), host - time(2s), host", 4144 params: url.Values{"db": []string{"db0"}}, 4145 command: `SELECT mean(mean) FROM (SELECT mean(value) FROM cpu GROUP BY time(2s), host) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:04Z' GROUP BY time(4s), host`, 4146 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",6.5]]},{"name":"cpu","tags":{"host":"server02"},"columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",10.5]]}]}]}`, 4147 }, 4148 { 4149 name: "group by time(2s), host - time(2s), host, region", 4150 params: url.Values{"db": []string{"db0"}}, 4151 command: `SELECT mean(mean) FROM (SELECT mean(value) FROM cpu GROUP BY time(2s), host, region) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:04Z' GROUP BY time(2s), host`, 4152 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":"server01"},"columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",5.5],["2000-01-01T00:00:02Z",7.5]]},{"name":"cpu","tags":{"host":"server02"},"columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",9.5],["2000-01-01T00:00:02Z",11.5]]}]}]}`, 4153 }, 4154 }...) 4155 4156 ctx := context.Background() 4157 test.Run(ctx, t, s) 4158 } 4159 4160 func TestServer_Query_SubqueryMath(t *testing.T) { 4161 s := OpenServer(t) 4162 defer s.Close() 4163 4164 writes := []string{ 4165 fmt.Sprintf("m0 f2=4,f3=2 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4166 fmt.Sprintf("m0 f1=5,f3=8 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 4167 fmt.Sprintf("m0 f1=5,f2=3,f3=6 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 4168 } 4169 test := NewTest("db0", "rp0") 4170 test.writes = Writes{ 4171 &Write{data: strings.Join(writes, "\n")}, 4172 } 4173 4174 test.addQueries([]*Query{ 4175 { 4176 name: "SumThreeValues", 4177 params: url.Values{"db": []string{"db0"}}, 4178 command: `SELECT sum FROM (SELECT f1 + f2 + f3 AS sum FROM m0)`, 4179 exp: `{"results":[{"statement_id":0,"series":[{"name":"m0","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",null],["2000-01-01T00:00:10Z",null],["2000-01-01T00:00:20Z",14]]}]}]}`, 4180 }, 4181 }...) 4182 4183 ctx := context.Background() 4184 test.Run(ctx, t, s) 4185 } 4186 4187 func TestServer_Query_PercentileDerivative(t *testing.T) { 4188 s := OpenServer(t) 4189 defer s.Close() 4190 4191 writes := []string{ 4192 fmt.Sprintf(`counter value=12 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4193 fmt.Sprintf(`counter value=34 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 4194 fmt.Sprintf(`counter value=78 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 4195 fmt.Sprintf(`counter value=89 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()), 4196 fmt.Sprintf(`counter value=101 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:40Z").UnixNano()), 4197 } 4198 test := NewTest("db0", "rp0") 4199 test.writes = Writes{ 4200 &Write{data: strings.Join(writes, "\n")}, 4201 } 4202 4203 test.addQueries([]*Query{ 4204 { 4205 name: "nth percentile of derivative", 4206 params: url.Values{"db": []string{"db0"}}, 4207 command: `SELECT percentile(derivative, 95) FROM (SELECT derivative(value, 1s) FROM counter) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:50Z'`, 4208 exp: `{"results":[{"statement_id":0,"series":[{"name":"counter","columns":["time","percentile"],"values":[["2000-01-01T00:00:20Z",4.4]]}]}]}`, 4209 }, 4210 }...) 4211 4212 ctx := context.Background() 4213 test.Run(ctx, t, s) 4214 } 4215 4216 func TestServer_Query_UnderscoreMeasurement(t *testing.T) { 4217 s := OpenServer(t) 4218 defer s.Close() 4219 4220 writes := []string{ 4221 fmt.Sprintf(`_cpu value=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4222 } 4223 test := NewTest("db0", "rp0") 4224 test.writes = Writes{ 4225 &Write{data: strings.Join(writes, "\n")}, 4226 } 4227 4228 test.addQueries([]*Query{ 4229 { 4230 name: "select underscore with underscore prefix", 4231 params: url.Values{"db": []string{"db0"}}, 4232 command: `SELECT * FROM _cpu`, 4233 exp: `{"results":[{"statement_id":0,"series":[{"name":"_cpu","columns":["time","value"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, 4234 }, 4235 }...) 4236 4237 ctx := context.Background() 4238 test.Run(ctx, t, s) 4239 } 4240 4241 func TestServer_Query_Wildcards(t *testing.T) { 4242 s := OpenServer(t) 4243 defer s.Close() 4244 4245 writes := []string{ 4246 fmt.Sprintf(`wildcard,region=us-east value=10 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4247 fmt.Sprintf(`wildcard,region=us-east valx=20 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 4248 fmt.Sprintf(`wildcard,region=us-east value=30,valx=40 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 4249 4250 fmt.Sprintf(`wgroup,region=us-east value=10.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4251 fmt.Sprintf(`wgroup,region=us-east value=20.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 4252 fmt.Sprintf(`wgroup,region=us-west value=30.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 4253 4254 fmt.Sprintf(`m1,region=us-east value=10.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4255 fmt.Sprintf(`m2,host=server01 field=20.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 4256 } 4257 4258 test := NewTest("db0", "rp0") 4259 test.writes = Writes{ 4260 &Write{data: strings.Join(writes, "\n")}, 4261 } 4262 4263 test.addQueries([]*Query{ 4264 { 4265 name: "wildcard", 4266 params: url.Values{"db": []string{"db0"}}, 4267 command: `SELECT * FROM wildcard`, 4268 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","columns":["time","region","value","valx"],"values":[["2000-01-01T00:00:00Z","us-east",10,null],["2000-01-01T00:00:10Z","us-east",null,20],["2000-01-01T00:00:20Z","us-east",30,40]]}]}]}`, 4269 }, 4270 { 4271 name: "wildcard with group by", 4272 params: url.Values{"db": []string{"db0"}}, 4273 command: `SELECT * FROM wildcard GROUP BY *`, 4274 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","tags":{"region":"us-east"},"columns":["time","value","valx"],"values":[["2000-01-01T00:00:00Z",10,null],["2000-01-01T00:00:10Z",null,20],["2000-01-01T00:00:20Z",30,40]]}]}]}`, 4275 }, 4276 { 4277 name: "GROUP BY queries", 4278 params: url.Values{"db": []string{"db0"}}, 4279 command: `SELECT mean(value) FROM wgroup GROUP BY *`, 4280 exp: `{"results":[{"statement_id":0,"series":[{"name":"wgroup","tags":{"region":"us-east"},"columns":["time","mean"],"values":[["1970-01-01T00:00:00Z",15]]},{"name":"wgroup","tags":{"region":"us-west"},"columns":["time","mean"],"values":[["1970-01-01T00:00:00Z",30]]}]}]}`, 4281 }, 4282 { 4283 name: "GROUP BY queries with time", 4284 params: url.Values{"db": []string{"db0"}}, 4285 command: `SELECT mean(value) FROM wgroup WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:01:00Z' GROUP BY *,TIME(1m)`, 4286 exp: `{"results":[{"statement_id":0,"series":[{"name":"wgroup","tags":{"region":"us-east"},"columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",15]]},{"name":"wgroup","tags":{"region":"us-west"},"columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",30]]}]}]}`, 4287 }, 4288 { 4289 name: "wildcard and field in select", 4290 params: url.Values{"db": []string{"db0"}}, 4291 command: `SELECT value, * FROM wildcard`, 4292 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","columns":["time","value","region","value_1","valx"],"values":[["2000-01-01T00:00:00Z",10,"us-east",10,null],["2000-01-01T00:00:10Z",null,"us-east",null,20],["2000-01-01T00:00:20Z",30,"us-east",30,40]]}]}]}`, 4293 }, 4294 { 4295 name: "field and wildcard in select", 4296 params: url.Values{"db": []string{"db0"}}, 4297 command: `SELECT value, * FROM wildcard`, 4298 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","columns":["time","value","region","value_1","valx"],"values":[["2000-01-01T00:00:00Z",10,"us-east",10,null],["2000-01-01T00:00:10Z",null,"us-east",null,20],["2000-01-01T00:00:20Z",30,"us-east",30,40]]}]}]}`, 4299 }, 4300 { 4301 name: "field and wildcard in group by", 4302 params: url.Values{"db": []string{"db0"}}, 4303 command: `SELECT * FROM wildcard GROUP BY region, *`, 4304 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","tags":{"region":"us-east"},"columns":["time","value","valx"],"values":[["2000-01-01T00:00:00Z",10,null],["2000-01-01T00:00:10Z",null,20],["2000-01-01T00:00:20Z",30,40]]}]}]}`, 4305 }, 4306 { 4307 name: "wildcard and field in group by", 4308 params: url.Values{"db": []string{"db0"}}, 4309 command: `SELECT * FROM wildcard GROUP BY *, region`, 4310 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","tags":{"region":"us-east"},"columns":["time","value","valx"],"values":[["2000-01-01T00:00:00Z",10,null],["2000-01-01T00:00:10Z",null,20],["2000-01-01T00:00:20Z",30,40]]}]}]}`, 4311 }, 4312 { 4313 name: "wildcard with multiple measurements", 4314 params: url.Values{"db": []string{"db0"}}, 4315 command: `SELECT * FROM m1, m2`, 4316 exp: `{"results":[{"statement_id":0,"series":[{"name":"m1","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:00Z",null,null,"us-east",10]]},{"name":"m2","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:01Z",20,"server01",null,null]]}]}]}`, 4317 }, 4318 { 4319 name: "wildcard with multiple measurements via regex", 4320 params: url.Values{"db": []string{"db0"}}, 4321 command: `SELECT * FROM /^m.*/`, 4322 exp: `{"results":[{"statement_id":0,"series":[{"name":"m1","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:00Z",null,null,"us-east",10]]},{"name":"m2","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:01Z",20,"server01",null,null]]}]}]}`, 4323 }, 4324 { 4325 name: "wildcard with multiple measurements via regex and limit", 4326 params: url.Values{"db": []string{"db0"}}, 4327 command: `SELECT * FROM db0../^m.*/ LIMIT 2`, 4328 exp: `{"results":[{"statement_id":0,"series":[{"name":"m1","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:00Z",null,null,"us-east",10]]},{"name":"m2","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:01Z",20,"server01",null,null]]}]}]}`, 4329 }, 4330 }...) 4331 4332 ctx := context.Background() 4333 test.Run(ctx, t, s) 4334 } 4335 4336 func TestServer_Query_WildcardExpansion(t *testing.T) { 4337 s := OpenServer(t) 4338 defer s.Close() 4339 4340 writes := []string{ 4341 fmt.Sprintf(`wildcard,region=us-east,host=A value=10,cpu=80 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4342 fmt.Sprintf(`wildcard,region=us-east,host=B value=20,cpu=90 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 4343 fmt.Sprintf(`wildcard,region=us-west,host=B value=30,cpu=70 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 4344 fmt.Sprintf(`wildcard,region=us-east,host=A value=40,cpu=60 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:30Z").UnixNano()), 4345 4346 fmt.Sprintf(`dupnames,region=us-east,day=1 value=10,day=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 4347 fmt.Sprintf(`dupnames,region=us-east,day=2 value=20,day=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 4348 fmt.Sprintf(`dupnames,region=us-west,day=3 value=30,day=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 4349 } 4350 4351 test := NewTest("db0", "rp0") 4352 test.writes = Writes{ 4353 &Write{data: strings.Join(writes, "\n")}, 4354 } 4355 4356 test.addQueries([]*Query{ 4357 { 4358 name: "wildcard", 4359 params: url.Values{"db": []string{"db0"}}, 4360 command: `SELECT * FROM wildcard`, 4361 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","columns":["time","cpu","host","region","value"],"values":[["2000-01-01T00:00:00Z",80,"A","us-east",10],["2000-01-01T00:00:10Z",90,"B","us-east",20],["2000-01-01T00:00:20Z",70,"B","us-west",30],["2000-01-01T00:00:30Z",60,"A","us-east",40]]}]}]}`, 4362 }, 4363 { 4364 name: "no wildcard in select", 4365 params: url.Values{"db": []string{"db0"}}, 4366 command: `SELECT cpu, host, region, value FROM wildcard`, 4367 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","columns":["time","cpu","host","region","value"],"values":[["2000-01-01T00:00:00Z",80,"A","us-east",10],["2000-01-01T00:00:10Z",90,"B","us-east",20],["2000-01-01T00:00:20Z",70,"B","us-west",30],["2000-01-01T00:00:30Z",60,"A","us-east",40]]}]}]}`, 4368 }, 4369 { 4370 name: "no wildcard in select, preserve column order", 4371 params: url.Values{"db": []string{"db0"}}, 4372 command: `SELECT host, cpu, region, value FROM wildcard`, 4373 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","columns":["time","host","cpu","region","value"],"values":[["2000-01-01T00:00:00Z","A",80,"us-east",10],["2000-01-01T00:00:10Z","B",90,"us-east",20],["2000-01-01T00:00:20Z","B",70,"us-west",30],["2000-01-01T00:00:30Z","A",60,"us-east",40]]}]}]}`, 4374 }, 4375 4376 { 4377 name: "no wildcard with alias", 4378 params: url.Values{"db": []string{"db0"}}, 4379 command: `SELECT cpu as c, host as h, region, value FROM wildcard`, 4380 exp: `{"results":[{"statement_id":0,"series":[{"name":"wildcard","columns":["time","c","h","region","value"],"values":[["2000-01-01T00:00:00Z",80,"A","us-east",10],["2000-01-01T00:00:10Z",90,"B","us-east",20],["2000-01-01T00:00:20Z",70,"B","us-west",30],["2000-01-01T00:00:30Z",60,"A","us-east",40]]}]}]}`, 4381 }, 4382 { 4383 name: "duplicate tag and field key", 4384 command: `SELECT * FROM dupnames`, 4385 params: url.Values{"db": []string{"db0"}}, 4386 exp: `{"results":[{"statement_id":0,"series":[{"name":"dupnames","columns":["time","day","day_1","region","value"],"values":[["2000-01-01T00:00:00Z",3,"1","us-east",10],["2000-01-01T00:00:10Z",2,"2","us-east",20],["2000-01-01T00:00:20Z",1,"3","us-west",30]]}]}]}`, 4387 }, 4388 }...) 4389 4390 ctx := context.Background() 4391 test.Run(ctx, t, s) 4392 } 4393 4394 func TestServer_Query_ShowQueries_Future(t *testing.T) { 4395 s := OpenServer(t) 4396 defer s.Close() 4397 4398 writes := []string{ 4399 fmt.Sprintf(`cpu,host=server01 value=100 %d`, models.MaxNanoTime), 4400 } 4401 4402 test := NewTest("db0", "rp0") 4403 test.writes = Writes{ 4404 &Write{data: strings.Join(writes, "\n")}, 4405 } 4406 4407 test.addQueries([]*Query{ 4408 { 4409 name: `show measurements`, 4410 command: "SHOW MEASUREMENTS", 4411 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["cpu"]]}]}]}`, 4412 params: url.Values{"db": []string{"db0"}}, 4413 }, 4414 { 4415 name: `show series`, 4416 skip: NotSupported, 4417 command: "SHOW SERIES", 4418 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01"]]}]}]}`, 4419 params: url.Values{"db": []string{"db0"}}, 4420 }, 4421 { 4422 name: `show tag keys`, 4423 command: "SHOW TAG KEYS FROM cpu", 4424 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["tagKey"],"values":[["host"]]}]}]}`, 4425 params: url.Values{"db": []string{"db0"}}, 4426 }, 4427 { 4428 name: `show tag values`, 4429 command: "SHOW TAG VALUES WITH KEY = \"host\"", 4430 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["key","value"],"values":[["host","server01"]]}]}]}`, 4431 params: url.Values{"db": []string{"db0"}}, 4432 }, 4433 { 4434 name: `show field keys`, 4435 command: "SHOW FIELD KEYS", 4436 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["fieldKey","fieldType"],"values":[["value","float"]]}]}]}`, 4437 params: url.Values{"db": []string{"db0"}}, 4438 }, 4439 }...) 4440 4441 ctx := context.Background() 4442 test.Run(ctx, t, s) 4443 } 4444 4445 func TestServer_Query_ShowSeries(t *testing.T) { 4446 t.Skip(NotSupported) 4447 s := OpenServer(t) 4448 defer s.Close() 4449 4450 writes := []string{ 4451 fmt.Sprintf(`cpu,host=server01 value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:01Z").UnixNano()), 4452 fmt.Sprintf(`cpu,host=server01,region=uswest value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:02Z").UnixNano()), 4453 fmt.Sprintf(`cpu,host=server01,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:03Z").UnixNano()), 4454 fmt.Sprintf(`cpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2020-11-10T23:00:04Z").UnixNano()), 4455 fmt.Sprintf(`gpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2020-11-10T23:00:05Z").UnixNano()), 4456 fmt.Sprintf(`gpu,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:06Z").UnixNano()), 4457 fmt.Sprintf(`disk,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:07Z").UnixNano()), 4458 } 4459 4460 test := NewTest("db0", "rp0") 4461 test.writes = Writes{ 4462 &Write{data: strings.Join(writes, "\n")}, 4463 } 4464 4465 test.addQueries([]*Query{ 4466 { 4467 name: `show series`, 4468 command: "SHOW SERIES", 4469 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01"],["cpu,host=server01,region=useast"],["cpu,host=server01,region=uswest"],["cpu,host=server02,region=useast"],["disk,host=server03,region=caeast"],["gpu,host=server02,region=useast"],["gpu,host=server03,region=caeast"]]}]}]}`, 4470 params: url.Values{"db": []string{"db0"}}, 4471 }, 4472 { 4473 name: `show series from measurement`, 4474 command: "SHOW SERIES FROM cpu", 4475 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01"],["cpu,host=server01,region=useast"],["cpu,host=server01,region=uswest"],["cpu,host=server02,region=useast"]]}]}]}`, 4476 params: url.Values{"db": []string{"db0"}}, 4477 }, 4478 { 4479 name: `show series from regular expression`, 4480 command: "SHOW SERIES FROM /[cg]pu/", 4481 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01"],["cpu,host=server01,region=useast"],["cpu,host=server01,region=uswest"],["cpu,host=server02,region=useast"],["gpu,host=server02,region=useast"],["gpu,host=server03,region=caeast"]]}]}]}`, 4482 params: url.Values{"db": []string{"db0"}}, 4483 }, 4484 { 4485 name: `show series with where tag`, 4486 command: "SHOW SERIES WHERE region = 'uswest'", 4487 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01,region=uswest"]]}]}]}`, 4488 params: url.Values{"db": []string{"db0"}}, 4489 }, 4490 { 4491 name: `show series where tag matches regular expression`, 4492 command: "SHOW SERIES WHERE region =~ /ca.*/", 4493 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["disk,host=server03,region=caeast"],["gpu,host=server03,region=caeast"]]}]}]}`, 4494 params: url.Values{"db": []string{"db0"}}, 4495 }, 4496 { 4497 name: `show series`, 4498 command: "SHOW SERIES WHERE host !~ /server0[12]/", 4499 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["disk,host=server03,region=caeast"],["gpu,host=server03,region=caeast"]]}]}]}`, 4500 params: url.Values{"db": []string{"db0"}}, 4501 }, 4502 { 4503 name: `show series with from and where`, 4504 command: "SHOW SERIES FROM cpu WHERE region = 'useast'", 4505 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01,region=useast"],["cpu,host=server02,region=useast"]]}]}]}`, 4506 params: url.Values{"db": []string{"db0"}}, 4507 }, 4508 { 4509 name: `show series with time`, 4510 command: "SHOW SERIES WHERE time > 0", 4511 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01"],["cpu,host=server01,region=useast"],["cpu,host=server01,region=uswest"],["cpu,host=server02,region=useast"],["disk,host=server03,region=caeast"],["gpu,host=server02,region=useast"],["gpu,host=server03,region=caeast"]]}]}]}`, 4512 params: url.Values{"db": []string{"db0"}}, 4513 }, 4514 { 4515 name: `show series from measurement with time`, 4516 command: "SHOW SERIES FROM cpu WHERE time > 0", 4517 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01"],["cpu,host=server01,region=useast"],["cpu,host=server01,region=uswest"],["cpu,host=server02,region=useast"]]}]}]}`, 4518 params: url.Values{"db": []string{"db0"}}, 4519 }, 4520 { 4521 name: `show series from regular expression with time`, 4522 command: "SHOW SERIES FROM /[cg]pu/ WHERE time > 0", 4523 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01"],["cpu,host=server01,region=useast"],["cpu,host=server01,region=uswest"],["cpu,host=server02,region=useast"],["gpu,host=server02,region=useast"],["gpu,host=server03,region=caeast"]]}]}]}`, 4524 params: url.Values{"db": []string{"db0"}}, 4525 }, 4526 { 4527 name: `show series with where tag with time`, 4528 command: "SHOW SERIES WHERE region = 'uswest' AND time > 0", 4529 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01,region=uswest"]]}]}]}`, 4530 params: url.Values{"db": []string{"db0"}}, 4531 }, 4532 { 4533 name: `show series where tag matches regular expression with time`, 4534 command: "SHOW SERIES WHERE region =~ /ca.*/ AND time > 0", 4535 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["disk,host=server03,region=caeast"],["gpu,host=server03,region=caeast"]]}]}]}`, 4536 params: url.Values{"db": []string{"db0"}}, 4537 }, 4538 { 4539 name: `show series with != regex and time`, 4540 command: "SHOW SERIES WHERE host !~ /server0[12]/ AND time > 0", 4541 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["disk,host=server03,region=caeast"],["gpu,host=server03,region=caeast"]]}]}]}`, 4542 params: url.Values{"db": []string{"db0"}}, 4543 }, 4544 { 4545 name: `show series with from and where with time`, 4546 command: "SHOW SERIES FROM cpu WHERE region = 'useast' AND time > 0", 4547 exp: `{"results":[{"statement_id":0,"series":[{"columns":["key"],"values":[["cpu,host=server01,region=useast"],["cpu,host=server02,region=useast"]]}]}]}`, 4548 params: url.Values{"db": []string{"db0"}}, 4549 }, 4550 }...) 4551 4552 ctx := context.Background() 4553 test.Run(ctx, t, s) 4554 } 4555 4556 func TestServer_Query_ShowSeriesCardinalityEstimation(t *testing.T) { 4557 t.Skip(NotSupported) 4558 // if testing.Short() || os.Getenv("GORACE") != "" || os.Getenv("APPVEYOR") != "" { 4559 // t.Skip("Skipping test in short, race and appveyor mode.") 4560 // } 4561 s := OpenServer(t) 4562 defer s.Close() 4563 4564 test := NewTest("db0", "rp0") 4565 test.writes = make(Writes, 0, 10) 4566 // Add 1,000,000 series. 4567 for j := 0; j < cap(test.writes); j++ { 4568 writes := make([]string, 0, 50000) 4569 for i := 0; i < cap(writes); i++ { 4570 writes = append(writes, fmt.Sprintf(`cpu,l=%d,h=s%d v=1 %d`, j, i, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:01Z").UnixNano())) 4571 } 4572 test.writes = append(test.writes, &Write{data: strings.Join(writes, "\n")}) 4573 } 4574 4575 // These queries use index sketches to estimate cardinality. 4576 test.addQueries([]*Query{ 4577 { 4578 name: `show series cardinality`, 4579 command: "SHOW SERIES CARDINALITY", 4580 params: url.Values{"db": []string{"db0"}}, 4581 }, 4582 { 4583 name: `show series cardinality on db0`, 4584 command: "SHOW SERIES CARDINALITY ON db0", 4585 }, 4586 }...) 4587 4588 ctx := context.Background() 4589 test.Run(ctx, t, s) 4590 } 4591 4592 func TestServer_Query_ShowSeriesExactCardinality(t *testing.T) { 4593 t.Skip(NotSupported) 4594 s := OpenServer(t) 4595 defer s.Close() 4596 4597 writes := []string{ 4598 fmt.Sprintf(`cpu,host=server01 value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:01Z").UnixNano()), 4599 fmt.Sprintf(`cpu,host=server01,region=uswest value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:02Z").UnixNano()), 4600 fmt.Sprintf(`cpu,host=server01,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:03Z").UnixNano()), 4601 fmt.Sprintf(`cpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:04Z").UnixNano()), 4602 fmt.Sprintf(`gpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:05Z").UnixNano()), 4603 fmt.Sprintf(`gpu,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:06Z").UnixNano()), 4604 fmt.Sprintf(`disk,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:07Z").UnixNano()), 4605 } 4606 4607 test := NewTest("db0", "rp0") 4608 test.writes = Writes{ 4609 &Write{data: strings.Join(writes, "\n")}, 4610 } 4611 4612 test.addQueries([]*Query{ 4613 { 4614 name: `show series cardinality from measurement`, 4615 command: "SHOW SERIES CARDINALITY FROM cpu", 4616 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[4]]}]}]}`, 4617 params: url.Values{"db": []string{"db0"}}, 4618 }, 4619 { 4620 name: `show series cardinality from regular expression`, 4621 command: "SHOW SERIES CARDINALITY FROM /[cg]pu/", 4622 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[4]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 4623 params: url.Values{"db": []string{"db0"}}, 4624 }, 4625 { 4626 name: `show series cardinality with where tag`, 4627 command: "SHOW SERIES CARDINALITY WHERE region = 'uswest'", 4628 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[1]]}]}]}`, 4629 params: url.Values{"db": []string{"db0"}}, 4630 }, 4631 { 4632 name: `show series cardinality where tag matches regular expression`, 4633 command: "SHOW SERIES CARDINALITY WHERE region =~ /ca.*/", 4634 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 4635 params: url.Values{"db": []string{"db0"}}, 4636 }, 4637 { 4638 name: `show series cardinality`, 4639 command: "SHOW SERIES CARDINALITY WHERE host !~ /server0[12]/", 4640 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 4641 params: url.Values{"db": []string{"db0"}}, 4642 }, 4643 { 4644 name: `show series cardinality with from and where`, 4645 command: "SHOW SERIES CARDINALITY FROM cpu WHERE region = 'useast'", 4646 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`, 4647 params: url.Values{"db": []string{"db0"}}, 4648 }, 4649 { 4650 name: `show series cardinality with WHERE time should fail`, 4651 command: "SHOW SERIES CARDINALITY WHERE time > now() - 1h", 4652 exp: `{"results":[{"statement_id":0,"error":"SHOW SERIES EXACT CARDINALITY doesn't support time in WHERE clause"}]}`, 4653 params: url.Values{"db": []string{"db0"}}, 4654 }, 4655 { 4656 name: `show series exact cardinality`, 4657 command: "SHOW SERIES EXACT CARDINALITY", 4658 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[4]]},{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 4659 params: url.Values{"db": []string{"db0"}}, 4660 }, 4661 { 4662 name: `show series exact cardinality from measurement`, 4663 command: "SHOW SERIES EXACT CARDINALITY FROM cpu", 4664 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[4]]}]}]}`, 4665 params: url.Values{"db": []string{"db0"}}, 4666 }, 4667 { 4668 name: `show series exact cardinality from regular expression`, 4669 command: "SHOW SERIES EXACT CARDINALITY FROM /[cg]pu/", 4670 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[4]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`, 4671 params: url.Values{"db": []string{"db0"}}, 4672 }, 4673 { 4674 name: `show series exact cardinality with where tag`, 4675 command: "SHOW SERIES EXACT CARDINALITY WHERE region = 'uswest'", 4676 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[1]]}]}]}`, 4677 params: url.Values{"db": []string{"db0"}}, 4678 }, 4679 { 4680 name: `show series exact cardinality where tag matches regular expression`, 4681 command: "SHOW SERIES EXACT CARDINALITY WHERE region =~ /ca.*/", 4682 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 4683 params: url.Values{"db": []string{"db0"}}, 4684 }, 4685 { 4686 name: `show series exact cardinality`, 4687 command: "SHOW SERIES EXACT CARDINALITY WHERE host !~ /server0[12]/", 4688 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`, 4689 params: url.Values{"db": []string{"db0"}}, 4690 }, 4691 { 4692 name: `show series exact cardinality with from and where`, 4693 command: "SHOW SERIES EXACT CARDINALITY FROM cpu WHERE region = 'useast'", 4694 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`, 4695 params: url.Values{"db": []string{"db0"}}, 4696 }, 4697 { 4698 name: `show series exact cardinality with WHERE time should fail`, 4699 command: "SHOW SERIES EXACT CARDINALITY WHERE time > now() - 1h", 4700 exp: `{"results":[{"statement_id":0,"error":"SHOW SERIES EXACT CARDINALITY doesn't support time in WHERE clause"}]}`, 4701 params: url.Values{"db": []string{"db0"}}, 4702 }, 4703 }...) 4704 4705 ctx := context.Background() 4706 test.Run(ctx, t, s) 4707 } 4708 4709 func TestServer_Query_ShowMeasurements(t *testing.T) { 4710 s := OpenServer(t) 4711 defer s.Close() 4712 4713 writes := []string{ 4714 fmt.Sprintf(`cpu,host=server01 value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4715 fmt.Sprintf(`cpu,host=server01,region=uswest value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4716 fmt.Sprintf(`cpu,host=server01,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4717 fmt.Sprintf(`cpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4718 fmt.Sprintf(`gpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4719 fmt.Sprintf(`gpu,host=server02,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4720 fmt.Sprintf(`other,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4721 } 4722 4723 ctx := context.Background() 4724 4725 client := s.MustNewAdminClient() 4726 bucket2 := influxdb.Bucket{ 4727 OrgID: s.DefaultOrgID, 4728 Name: "b2", 4729 } 4730 bucket3 := influxdb.Bucket{ 4731 OrgID: s.DefaultOrgID, 4732 Name: "b3", 4733 } 4734 bucket4 := influxdb.Bucket{ 4735 OrgID: s.DefaultOrgID, 4736 Name: "b4", 4737 } 4738 require.NoError(t, client.CreateBucket(ctx, &bucket2)) 4739 require.NoError(t, client.CreateBucket(ctx, &bucket3)) 4740 require.NoError(t, client.CreateBucket(ctx, &bucket4)) 4741 4742 require.NoError(t, client.DBRPMappingService.Create(ctx, &influxdb.DBRPMapping{ 4743 Database: "databaseEmpty", 4744 RetentionPolicy: "rp0", 4745 Default: false, 4746 OrganizationID: s.DefaultOrgID, 4747 BucketID: bucket4.ID, 4748 })) 4749 4750 require.NoError(t, client.DBRPMappingService.Create(ctx, &influxdb.DBRPMapping{ 4751 Database: "db0", 4752 RetentionPolicy: "rp1", 4753 Default: false, 4754 OrganizationID: s.DefaultOrgID, 4755 BucketID: bucket2.ID, 4756 })) 4757 4758 require.NoError(t, client.DBRPMappingService.Create(ctx, &influxdb.DBRPMapping{ 4759 Database: "db1", 4760 RetentionPolicy: "rp0", 4761 Default: false, 4762 OrganizationID: s.DefaultOrgID, 4763 BucketID: bucket3.ID, 4764 })) 4765 4766 rp1Writes := []string{ 4767 fmt.Sprintf(`other2,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4768 } 4769 4770 db1Writes := []string{ 4771 fmt.Sprintf(`cpu,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4772 fmt.Sprintf(`disk,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4773 } 4774 4775 test := NewTest("db0", "rp0") 4776 test.writes = Writes{ 4777 &Write{data: strings.Join(writes, "\n")}, 4778 &Write{bucketID: bucket2.ID, data: strings.Join(rp1Writes, "\n")}, 4779 &Write{bucketID: bucket3.ID, data: strings.Join(db1Writes, "\n")}, 4780 } 4781 4782 test.addQueries([]*Query{ 4783 { 4784 name: `show measurements`, 4785 command: "SHOW MEASUREMENTS", 4786 // *unlike* 1.x, InfluxDB 2 shows measurements from the default retention policy when the rp is not specified, not all retention policies 4787 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["cpu"],["gpu"],["other"]]}]}]}`, 4788 params: url.Values{"db": []string{"db0"}}, 4789 }, 4790 { 4791 name: `show measurements with rp parameter`, 4792 command: "SHOW MEASUREMENTS", 4793 // we ignore the rp parameter for show measurements 4794 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["cpu"],["gpu"],["other"]]}]}]}`, 4795 params: url.Values{"db": []string{"db0"}, "rp": []string{"rp1"}}, 4796 }, 4797 { 4798 name: `show measurements with on`, 4799 command: "SHOW MEASUREMENTS on db0", 4800 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["cpu"],["gpu"],["other"]]}]}]}`, 4801 params: url.Values{"db": []string{"db0"}, "rp": []string{"rp0"}}, 4802 }, 4803 { 4804 name: `show measurements with limit 2`, 4805 command: "SHOW MEASUREMENTS LIMIT 2", 4806 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["cpu"],["gpu"]]}]}]}`, 4807 params: url.Values{"db": []string{"db0"}}, 4808 }, 4809 { 4810 name: `show measurements using WITH`, 4811 command: "SHOW MEASUREMENTS WITH MEASUREMENT = cpu", 4812 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["cpu"]]}]}]}`, 4813 params: url.Values{"db": []string{"db0"}}, 4814 }, 4815 { 4816 name: `show measurements using WITH and regex`, 4817 command: "SHOW MEASUREMENTS WITH MEASUREMENT =~ /[cg]pu/", 4818 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["cpu"],["gpu"]]}]}]}`, 4819 params: url.Values{"db": []string{"db0"}}, 4820 }, 4821 { 4822 name: `show measurements using WITH and regex - no matches`, 4823 command: "SHOW MEASUREMENTS WITH MEASUREMENT =~ /.*zzzzz.*/", 4824 exp: `{"results":[{"statement_id":0}]}`, 4825 params: url.Values{"db": []string{"db0"}}, 4826 }, 4827 { 4828 name: `show measurements where tag matches regular expression`, 4829 command: "SHOW MEASUREMENTS WHERE region =~ /ca.*/", 4830 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["gpu"],["other"]]}]}]}`, 4831 params: url.Values{"db": []string{"db0"}}, 4832 }, 4833 { 4834 name: `show measurements where tag does not match a regular expression`, 4835 command: "SHOW MEASUREMENTS WHERE region !~ /ca.*/", 4836 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["cpu"]]}]}]}`, 4837 params: url.Values{"db": []string{"db0"}}, 4838 }, 4839 { 4840 name: `show measurements with limit 2 and time`, 4841 command: "SHOW MEASUREMENTS WHERE time > 0 LIMIT 2", 4842 exp: `{"results":[{"statement_id":0,"error":"SHOW MEASUREMENTS doesn't support time in WHERE clause"}]}`, 4843 params: url.Values{"db": []string{"db0"}}, 4844 }, 4845 { 4846 name: `show measurements using WITH and time`, 4847 command: "SHOW MEASUREMENTS WITH MEASUREMENT = cpu WHERE time > 0", 4848 exp: `{"results":[{"statement_id":0,"error":"SHOW MEASUREMENTS doesn't support time in WHERE clause"}]}`, 4849 params: url.Values{"db": []string{"db0"}}, 4850 }, 4851 { 4852 name: `show measurements using WITH and regex and time`, 4853 command: "SHOW MEASUREMENTS WITH MEASUREMENT =~ /[cg]pu/ WHERE time > 0 ", 4854 exp: `{"results":[{"statement_id":0,"error":"SHOW MEASUREMENTS doesn't support time in WHERE clause"}]}`, 4855 params: url.Values{"db": []string{"db0"}}, 4856 }, 4857 { 4858 name: `show measurements using WITH and regex and time - no matches`, 4859 command: "SHOW MEASUREMENTS WITH MEASUREMENT =~ /.*zzzzz.*/ WHERE time > 0 ", 4860 exp: `{"results":[{"statement_id":0,"error":"SHOW MEASUREMENTS doesn't support time in WHERE clause"}]}`, 4861 params: url.Values{"db": []string{"db0"}}, 4862 }, 4863 { 4864 name: `show measurements and time where tag matches regular expression `, 4865 command: "SHOW MEASUREMENTS WHERE region =~ /ca.*/ AND time > 0", 4866 exp: `{"results":[{"statement_id":0,"error":"SHOW MEASUREMENTS doesn't support time in WHERE clause"}]}`, 4867 params: url.Values{"db": []string{"db0"}}, 4868 }, 4869 { 4870 name: `show measurements and time where tag does not match a regular expression`, 4871 command: "SHOW MEASUREMENTS WHERE region !~ /ca.*/ AND time > 0", 4872 exp: `{"results":[{"statement_id":0,"error":"SHOW MEASUREMENTS doesn't support time in WHERE clause"}]}`, 4873 params: url.Values{"db": []string{"db0"}}, 4874 }, 4875 { 4876 name: `show measurements bad wildcard`, 4877 command: "SHOW MEASUREMENTS on *", 4878 exp: `{"results":[{"statement_id":0,"error":"query 'SHOW MEASUREMENTS ON *' not supported. use 'ON *.*' or specify a database"}]}`, 4879 params: url.Values{"db": []string{"db0"}, "rp": []string{"rp0"}}, 4880 }, 4881 { 4882 name: `show measurements bad rp wildcard`, 4883 command: "SHOW MEASUREMENTS on *.rp0", 4884 exp: `{"results":[{"statement_id":0,"error":"query 'SHOW MEASUREMENTS ON *.rp' not supported. use 'ON *.*' or specify a database"}]}`, 4885 params: url.Values{"db": []string{"db0"}, "rp": []string{"rp0"}}, 4886 }, 4887 { 4888 name: `show measurements on specific rp`, 4889 command: "SHOW MEASUREMENTS on db0.rp0", 4890 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name","database","retention policy"],"values":[["cpu","db0","rp0"],["gpu","db0","rp0"],["other","db0","rp0"]]}]}]}`, 4891 params: url.Values{"db": []string{"db0"}, "rp": []string{"rp0"}}, 4892 }, 4893 { 4894 name: `show measurements on all rps`, 4895 command: "SHOW MEASUREMENTS on db0.*", 4896 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name","database","retention policy"],"values":[["cpu","db0","rp0"],["gpu","db0","rp0"],["other","db0","rp0"],["other2","db0","rp1"]]}]}]}`, 4897 params: url.Values{"db": []string{"db0"}, "rp": []string{"rp0"}}, 4898 }, 4899 { 4900 name: `show measurements on all dbs and rps`, 4901 command: "SHOW MEASUREMENTS on *.*", 4902 exp: `{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name","database","retention policy"],"values":[["other2","b2","autogen"],["cpu","b3","autogen"],["disk","b3","autogen"],["cpu","db","rp"],["gpu","db","rp"],["other","db","rp"],["cpu","db0","rp0"],["gpu","db0","rp0"],["other","db0","rp0"],["other2","db0","rp1"],["cpu","db1","rp0"],["disk","db1","rp0"]]}]}]}`, 4903 params: url.Values{"db": []string{"db0"}, "rp": []string{"rp0"}}, 4904 }, 4905 }...) 4906 4907 test.Run(ctx, t, s) 4908 } 4909 4910 func TestServer_Query_ShowMeasurementCardinalityEstimation(t *testing.T) { 4911 // This test fails to build. The offending portions have been commented out 4912 t.Skip(NotSupported) 4913 // if testing.Short() || os.Getenv("GORACE") != "" || os.Getenv("APPVEYOR") != "" { 4914 // t.Skip("Skipping test in short, race and appveyor mode.") 4915 // } 4916 4917 s := OpenServer(t) 4918 defer s.Close() 4919 4920 test := NewTest("db0", "rp0") 4921 test.writes = make(Writes, 0, 10) 4922 for j := 0; j < cap(test.writes); j++ { 4923 writes := make([]string, 0, 10000) 4924 for i := 0; i < cap(writes); i++ { 4925 writes = append(writes, fmt.Sprintf(`cpu-%d-s%d v=1 %d`, j, i, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:01Z").UnixNano())) 4926 } 4927 test.writes = append(test.writes, &Write{data: strings.Join(writes, "\n")}) 4928 } 4929 4930 // These queries use index sketches to estimate cardinality. 4931 test.addQueries([]*Query{ 4932 { 4933 name: `show measurement cardinality`, 4934 command: "SHOW MEASUREMENT CARDINALITY", 4935 params: url.Values{"db": []string{"db0"}}, 4936 }, 4937 { 4938 name: `show measurement cardinality on db0`, 4939 command: "SHOW MEASUREMENT CARDINALITY ON db0", 4940 }, 4941 }...) 4942 4943 ctx := context.Background() 4944 test.Run(ctx, t, s) 4945 } 4946 4947 func TestServer_Query_ShowMeasurementExactCardinality(t *testing.T) { 4948 t.Skip(NotSupported) 4949 s := OpenServer(t) 4950 defer s.Close() 4951 4952 writes := []string{ 4953 fmt.Sprintf(`cpu,host=server01 value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4954 fmt.Sprintf(`cpu,host=server01,region=uswest value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4955 fmt.Sprintf(`cpu,host=server01,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4956 fmt.Sprintf(`cpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4957 fmt.Sprintf(`gpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4958 fmt.Sprintf(`gpu,host=server02,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4959 fmt.Sprintf(`other,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 4960 } 4961 4962 test := NewTest("db0", "rp0") 4963 test.writes = Writes{ 4964 &Write{data: strings.Join(writes, "\n")}, 4965 } 4966 4967 test.addQueries([]*Query{ 4968 { 4969 name: `show measurement cardinality using FROM and regex`, 4970 command: "SHOW MEASUREMENT CARDINALITY FROM /[cg]pu/", 4971 exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[2]]}]}]}`, 4972 params: url.Values{"db": []string{"db0"}}, 4973 }, 4974 { 4975 name: `show measurement cardinality using FROM and regex - no matches`, 4976 command: "SHOW MEASUREMENT CARDINALITY FROM /.*zzzzz.*/", 4977 exp: `{"results":[{"statement_id":0}]}`, 4978 params: url.Values{"db": []string{"db0"}}, 4979 }, 4980 { 4981 name: `show measurement cardinality where tag matches regular expression`, 4982 command: "SHOW MEASUREMENT CARDINALITY WHERE region =~ /ca.*/", 4983 exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[2]]}]}]}`, 4984 params: url.Values{"db": []string{"db0"}}, 4985 }, 4986 { 4987 name: `show measurement cardinality where tag does not match a regular expression`, 4988 command: "SHOW MEASUREMENT CARDINALITY WHERE region !~ /ca.*/", 4989 exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[2]]}]}]}`, 4990 params: url.Values{"db": []string{"db0"}}, 4991 }, 4992 { 4993 name: `show measurement cardinality with time in WHERE clauses errors`, 4994 command: `SHOW MEASUREMENT CARDINALITY WHERE time > now() - 1h`, 4995 exp: `{"results":[{"statement_id":0,"error":"SHOW MEASUREMENT EXACT CARDINALITY doesn't support time in WHERE clause"}]}`, 4996 params: url.Values{"db": []string{"db0"}}, 4997 }, 4998 { 4999 name: `show measurement exact cardinality`, 5000 command: "SHOW MEASUREMENT EXACT CARDINALITY", 5001 exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[3]]}]}]}`, 5002 params: url.Values{"db": []string{"db0"}}, 5003 }, 5004 { 5005 name: `show measurement exact cardinality using FROM`, 5006 command: "SHOW MEASUREMENT EXACT CARDINALITY FROM cpu", 5007 exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[1]]}]}]}`, 5008 params: url.Values{"db": []string{"db0"}}, 5009 }, 5010 { 5011 name: `show measurement exact cardinality using FROM and regex`, 5012 command: "SHOW MEASUREMENT EXACT CARDINALITY FROM /[cg]pu/", 5013 exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[2]]}]}]}`, 5014 params: url.Values{"db": []string{"db0"}}, 5015 }, 5016 { 5017 name: `show measurement exact cardinality using FROM and regex - no matches`, 5018 command: "SHOW MEASUREMENT EXACT CARDINALITY FROM /.*zzzzz.*/", 5019 exp: `{"results":[{"statement_id":0}]}`, 5020 params: url.Values{"db": []string{"db0"}}, 5021 }, 5022 { 5023 name: `show measurement exact cardinality where tag matches regular expression`, 5024 command: "SHOW MEASUREMENT EXACT CARDINALITY WHERE region =~ /ca.*/", 5025 exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[2]]}]}]}`, 5026 params: url.Values{"db": []string{"db0"}}, 5027 }, 5028 { 5029 name: `show measurement exact cardinality where tag does not match a regular expression`, 5030 command: "SHOW MEASUREMENT EXACT CARDINALITY WHERE region !~ /ca.*/", 5031 exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[2]]}]}]}`, 5032 params: url.Values{"db": []string{"db0"}}, 5033 }, 5034 { 5035 name: `show measurement exact cardinality with time in WHERE clauses errors`, 5036 command: `SHOW MEASUREMENT EXACT CARDINALITY WHERE time > now() - 1h`, 5037 exp: `{"results":[{"statement_id":0,"error":"SHOW MEASUREMENT EXACT CARDINALITY doesn't support time in WHERE clause"}]}`, 5038 params: url.Values{"db": []string{"db0"}}, 5039 }, 5040 }...) 5041 5042 ctx := context.Background() 5043 test.Run(ctx, t, s) 5044 } 5045 5046 func TestServer_Query_ShowTagKeys(t *testing.T) { 5047 s := OpenServer(t) 5048 defer s.Close() 5049 5050 writes := []string{ 5051 fmt.Sprintf(`cpu,host=server01 value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 5052 fmt.Sprintf(`cpu,host=server01,region=uswest value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 5053 fmt.Sprintf(`cpu,host=server01,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 5054 fmt.Sprintf(`cpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 5055 fmt.Sprintf(`gpu,host=server02,region=useast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 5056 fmt.Sprintf(`gpu,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 5057 fmt.Sprintf(`disk,host=server03,region=caeast value=100 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:00Z").UnixNano()), 5058 } 5059 5060 test := NewTest("db0", "rp0") 5061 test.writes = Writes{ 5062 &Write{data: strings.Join(writes, "\n")}, 5063 } 5064 5065 test.addQueries([]*Query{ 5066 { 5067 name: `show tag keys`, 5068 command: "SHOW TAG KEYS", 5069 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"disk","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"gpu","columns":["tagKey"],"values":[["host"],["region"]]}]}]}`, 5070 params: url.Values{"db": []string{"db0"}}, 5071 }, 5072 { 5073 name: `show tag keys on db0`, 5074 command: "SHOW TAG KEYS ON db0", 5075 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"disk","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"gpu","columns":["tagKey"],"values":[["host"],["region"]]}]}]}`, 5076 }, 5077 { 5078 name: "show tag keys from", 5079 command: "SHOW TAG KEYS FROM cpu", 5080 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["tagKey"],"values":[["host"],["region"]]}]}]}`, 5081 params: url.Values{"db": []string{"db0"}}, 5082 }, 5083 { 5084 name: "show tag keys from regex", 5085 command: "SHOW TAG KEYS FROM /[cg]pu/", 5086 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"gpu","columns":["tagKey"],"values":[["host"],["region"]]}]}]}`, 5087 params: url.Values{"db": []string{"db0"}}, 5088 }, 5089 { 5090 name: "show tag keys measurement not found", 5091 command: "SHOW TAG KEYS FROM doesntexist", 5092 exp: `{"results":[{"statement_id":0}]}`, 5093 params: url.Values{"db": []string{"db0"}}, 5094 }, 5095 { 5096 name: `show tag keys with time`, 5097 command: "SHOW TAG KEYS WHERE time > 0", 5098 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"disk","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"gpu","columns":["tagKey"],"values":[["host"],["region"]]}]}]}`, 5099 params: url.Values{"db": []string{"db0"}}, 5100 }, 5101 { 5102 name: `show tag keys on db0 with time`, 5103 command: "SHOW TAG KEYS ON db0 WHERE time > 0", 5104 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"disk","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"gpu","columns":["tagKey"],"values":[["host"],["region"]]}]}]}`, 5105 }, 5106 { 5107 name: "show tag keys with time from", 5108 command: "SHOW TAG KEYS FROM cpu WHERE time > 0", 5109 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["tagKey"],"values":[["host"],["region"]]}]}]}`, 5110 params: url.Values{"db": []string{"db0"}}, 5111 }, 5112 { 5113 name: "show tag keys with time from regex", 5114 command: "SHOW TAG KEYS FROM /[cg]pu/ WHERE time > 0", 5115 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"gpu","columns":["tagKey"],"values":[["host"],["region"]]}]}]}`, 5116 params: url.Values{"db": []string{"db0"}}, 5117 }, 5118 { 5119 name: "show tag keys with time where", 5120 command: "SHOW TAG KEYS WHERE host = 'server03' AND time > 0", 5121 exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["tagKey"],"values":[["host"],["region"]]},{"name":"gpu","columns":["tagKey"],"values":[["host"],["region"]]}]}]}`, 5122 params: url.Values{"db": []string{"db0"}}, 5123 }, 5124 { 5125 name: "show tag keys with time measurement not found", 5126 command: "SHOW TAG KEYS FROM doesntexist WHERE time > 0", 5127 exp: `{"results":[{"statement_id":0}]}`, 5128 params: url.Values{"db": []string{"db0"}}, 5129 }, 5130 }...) 5131 5132 ctx := context.Background() 5133 test.Run(ctx, t, s) 5134 } 5135 5136 func TestServer_Query_LargeTimestamp(t *testing.T) { 5137 // This test fails to build. The offending portions have been commented out. 5138 t.Skip(NeedsReview) 5139 s := OpenServer(t) 5140 defer s.Close() 5141 5142 // if _, ok := s.(*RemoteServer); ok { 5143 // t.Skip("Skipping. Cannot restart remote server") 5144 // } 5145 // 5146 writes := []string{ 5147 fmt.Sprintf(`cpu value=100 %d`, models.MaxNanoTime), 5148 } 5149 5150 test := NewTest("db0", "rp0") 5151 test.writes = Writes{ 5152 &Write{data: strings.Join(writes, "\n")}, 5153 } 5154 5155 test.addQueries([]*Query{ 5156 { 5157 name: `select value at max nano time`, 5158 params: url.Values{"db": []string{"db0"}}, 5159 command: fmt.Sprintf(`SELECT value FROM cpu WHERE time <= %d`, models.MaxNanoTime), 5160 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["` + time.Unix(0, models.MaxNanoTime).UTC().Format(time.RFC3339Nano) + `",100]]}]}]}`, 5161 }, 5162 }...) 5163 5164 // if err := test.init(s); err != nil { 5165 // t.Fatalf("test init failed: %s", err) 5166 // } 5167 5168 // Open a new server with the same configuration file. 5169 // This is to ensure the meta data was marshaled correctly. 5170 // s2 := OpenServer((s.(*LocalServer)).Config) 5171 // defer s2.(*LocalServer).Server.Close() 5172 5173 ctx := context.Background() 5174 test.Run(ctx, t, s) 5175 } 5176 5177 func TestServer_Query_DotProduct(t *testing.T) { 5178 s := OpenServer(t) 5179 defer s.Close() 5180 5181 writes := []string{ 5182 fmt.Sprintf(`cpu a=2,b=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5183 fmt.Sprintf(`cpu a=-5,b=8 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), 5184 fmt.Sprintf(`cpu a=9,b=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), 5185 } 5186 5187 test := NewTest("db0", "rp0") 5188 test.writes = Writes{ 5189 &Write{data: strings.Join(writes, "\n")}, 5190 } 5191 5192 test.addQueries([]*Query{ 5193 { 5194 name: "select dot product", 5195 params: url.Values{"db": []string{"db0"}}, 5196 command: `SELECT sum(a_b) FROM (SELECT a * b FROM cpu) WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:00:30Z'`, 5197 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",-7]]}]}]}`, 5198 }, 5199 }...) 5200 5201 ctx := context.Background() 5202 test.Run(ctx, t, s) 5203 } 5204 5205 // Ensure time in where clause is inclusive 5206 func TestServer_WhereTimeInclusive(t *testing.T) { 5207 s := OpenServer(t) 5208 defer s.Close() 5209 5210 writes := []string{ 5211 fmt.Sprintf(`cpu value=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 5212 fmt.Sprintf(`cpu value=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), 5213 fmt.Sprintf(`cpu value=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 5214 } 5215 5216 test := NewTest("db0", "rp0") 5217 test.writes = Writes{ 5218 &Write{data: strings.Join(writes, "\n")}, 5219 } 5220 5221 test.addQueries([]*Query{ 5222 { 5223 name: "all GTE/LTE", 5224 params: url.Values{"db": []string{"db0"}}, 5225 command: `SELECT * from cpu where time >= '2000-01-01T00:00:01Z' and time <= '2000-01-01T00:00:03Z'`, 5226 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:01Z",1],["2000-01-01T00:00:02Z",2],["2000-01-01T00:00:03Z",3]]}]}]}`, 5227 }, 5228 { 5229 name: "all GTE", 5230 params: url.Values{"db": []string{"db0"}}, 5231 command: `SELECT * from cpu where time >= '2000-01-01T00:00:01Z'`, 5232 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:01Z",1],["2000-01-01T00:00:02Z",2],["2000-01-01T00:00:03Z",3]]}]}]}`, 5233 }, 5234 { 5235 name: "all LTE", 5236 params: url.Values{"db": []string{"db0"}}, 5237 command: `SELECT * from cpu where time <= '2000-01-01T00:00:03Z'`, 5238 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:01Z",1],["2000-01-01T00:00:02Z",2],["2000-01-01T00:00:03Z",3]]}]}]}`, 5239 }, 5240 { 5241 name: "first GTE/LTE", 5242 params: url.Values{"db": []string{"db0"}}, 5243 command: `SELECT * from cpu where time >= '2000-01-01T00:00:01Z' and time <= '2000-01-01T00:00:01Z'`, 5244 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:01Z",1]]}]}]}`, 5245 }, 5246 { 5247 name: "last GTE/LTE", 5248 params: url.Values{"db": []string{"db0"}}, 5249 command: `SELECT * from cpu where time >= '2000-01-01T00:00:03Z' and time <= '2000-01-01T00:00:03Z'`, 5250 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:03Z",3]]}]}]}`, 5251 }, 5252 { 5253 name: "before GTE/LTE", 5254 params: url.Values{"db": []string{"db0"}}, 5255 command: `SELECT * from cpu where time <= '2000-01-01T00:00:00Z'`, 5256 exp: `{"results":[{"statement_id":0}]}`, 5257 }, 5258 { 5259 name: "all GT/LT", 5260 params: url.Values{"db": []string{"db0"}}, 5261 command: `SELECT * from cpu where time > '2000-01-01T00:00:00Z' and time < '2000-01-01T00:00:04Z'`, 5262 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:01Z",1],["2000-01-01T00:00:02Z",2],["2000-01-01T00:00:03Z",3]]}]}]}`, 5263 }, 5264 { 5265 name: "first GT/LT", 5266 params: url.Values{"db": []string{"db0"}}, 5267 command: `SELECT * from cpu where time > '2000-01-01T00:00:00Z' and time < '2000-01-01T00:00:02Z'`, 5268 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:01Z",1]]}]}]}`, 5269 }, 5270 { 5271 name: "last GT/LT", 5272 params: url.Values{"db": []string{"db0"}}, 5273 command: `SELECT * from cpu where time > '2000-01-01T00:00:02Z' and time < '2000-01-01T00:00:04Z'`, 5274 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:03Z",3]]}]}]}`, 5275 }, 5276 { 5277 name: "all GT", 5278 params: url.Values{"db": []string{"db0"}}, 5279 command: `SELECT * from cpu where time > '2000-01-01T00:00:00Z'`, 5280 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:01Z",1],["2000-01-01T00:00:02Z",2],["2000-01-01T00:00:03Z",3]]}]}]}`, 5281 }, 5282 { 5283 name: "all LT", 5284 params: url.Values{"db": []string{"db0"}}, 5285 command: `SELECT * from cpu where time < '2000-01-01T00:00:04Z'`, 5286 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:01Z",1],["2000-01-01T00:00:02Z",2],["2000-01-01T00:00:03Z",3]]}]}]}`, 5287 }, 5288 }...) 5289 5290 ctx := context.Background() 5291 test.Run(ctx, t, s) 5292 } 5293 5294 func TestServer_Query_ImplicitEndTime(t *testing.T) { 5295 t.Skip(FlakyTest) 5296 s := OpenServer(t) 5297 defer s.Close() 5298 5299 now := time.Now().UTC().Truncate(time.Second) 5300 past := now.Add(-10 * time.Second) 5301 future := now.Add(10 * time.Minute) 5302 writes := []string{ 5303 fmt.Sprintf(`cpu value=1 %d`, past.UnixNano()), 5304 fmt.Sprintf(`cpu value=2 %d`, future.UnixNano()), 5305 } 5306 5307 test := NewTest("db0", "rp0") 5308 test.writes = Writes{ 5309 &Write{data: strings.Join(writes, "\n")}, 5310 } 5311 5312 test.addQueries([]*Query{ 5313 { 5314 name: "raw query", 5315 params: url.Values{"db": []string{"db0"}}, 5316 command: `SELECT * FROM cpu`, 5317 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["%s",1],["%s",2]]}]}]}`, past.Format(time.RFC3339Nano), future.Format(time.RFC3339Nano)), 5318 }, 5319 { 5320 name: "aggregate query", 5321 params: url.Values{"db": []string{"db0"}}, 5322 command: fmt.Sprintf(`SELECT mean(value) FROM cpu WHERE time > '%s' - 1m GROUP BY time(1m) FILL(none)`, now.Truncate(time.Minute).Format(time.RFC3339Nano)), 5323 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","mean"],"values":[["%s",1]]}]}]}`, now.Truncate(time.Minute).Format(time.RFC3339Nano)), 5324 }, 5325 }...) 5326 5327 ctx := context.Background() 5328 test.Run(ctx, t, s) 5329 } 5330 5331 func TestServer_Query_Sample_Wildcard(t *testing.T) { 5332 s := OpenServer(t) 5333 defer s.Close() 5334 5335 writes := []string{ 5336 fmt.Sprintf(`cpu float=1,int=1i,string="hello, world",bool=true %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5337 } 5338 5339 test := NewTest("db0", "rp0") 5340 test.writes = Writes{ 5341 &Write{data: strings.Join(writes, "\n")}, 5342 } 5343 5344 test.addQueries([]*Query{ 5345 { 5346 name: "sample() with wildcard", 5347 params: url.Values{"db": []string{"db0"}}, 5348 command: `SELECT sample(*, 1) FROM cpu`, 5349 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sample_bool","sample_float","sample_int","sample_string"],"values":[["2000-01-01T00:00:00Z",true,1,1,"hello, world"]]}]}]}`, 5350 }, 5351 }...) 5352 5353 ctx := context.Background() 5354 test.Run(ctx, t, s) 5355 } 5356 5357 func TestServer_Query_Sample_LimitOffset(t *testing.T) { 5358 s := OpenServer(t) 5359 defer s.Close() 5360 5361 writes := []string{ 5362 fmt.Sprintf(`cpu float=1,int=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5363 fmt.Sprintf(`cpu float=2,int=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:01:00Z").UnixNano()), 5364 fmt.Sprintf(`cpu float=3,int=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:02:00Z").UnixNano()), 5365 } 5366 5367 test := NewTest("db0", "rp0") 5368 test.writes = Writes{ 5369 &Write{data: strings.Join(writes, "\n")}, 5370 } 5371 5372 test.addQueries([]*Query{ 5373 { 5374 name: "sample() with limit 1", 5375 params: url.Values{"db": []string{"db0"}}, 5376 command: `SELECT sample(float, 3), int FROM cpu LIMIT 1`, 5377 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sample","int"],"values":[["2000-01-01T00:00:00Z",1,1]]}]}]}`, 5378 }, 5379 { 5380 name: "sample() with offset 1", 5381 params: url.Values{"db": []string{"db0"}}, 5382 command: `SELECT sample(float, 3), int FROM cpu OFFSET 1`, 5383 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sample","int"],"values":[["2000-01-01T00:01:00Z",2,2],["2000-01-01T00:02:00Z",3,3]]}]}]}`, 5384 }, 5385 { 5386 name: "sample() with limit 1 offset 1", 5387 params: url.Values{"db": []string{"db0"}}, 5388 command: `SELECT sample(float, 3), int FROM cpu LIMIT 1 OFFSET 1`, 5389 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sample","int"],"values":[["2000-01-01T00:01:00Z",2,2]]}]}]}`, 5390 }, 5391 }...) 5392 5393 ctx := context.Background() 5394 test.Run(ctx, t, s) 5395 } 5396 5397 // Validate that nested aggregates don't panic 5398 func TestServer_NestedAggregateWithMathPanics(t *testing.T) { 5399 s := OpenServer(t) 5400 defer s.Close() 5401 5402 writes := []string{ 5403 `cpu value=2i 120000000000`, 5404 } 5405 5406 test := NewTest("db0", "rp0") 5407 test.writes = Writes{ 5408 &Write{data: strings.Join(writes, "\n")}, 5409 } 5410 5411 test.addQueries([]*Query{ 5412 { 5413 name: "dividing by elapsed count should not panic", 5414 params: url.Values{"db": []string{"db0"}}, 5415 command: `SELECT sum(value) / elapsed(sum(value), 1m) FROM cpu WHERE time > 0 AND time < 10m GROUP BY time(1m)`, 5416 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum_elapsed"],"values":[["1970-01-01T00:00:00Z",null],["1970-01-01T00:01:00Z",null],["1970-01-01T00:02:00Z",null],["1970-01-01T00:03:00Z",null],["1970-01-01T00:04:00Z",null],["1970-01-01T00:05:00Z",null],["1970-01-01T00:06:00Z",null],["1970-01-01T00:07:00Z",null],["1970-01-01T00:08:00Z",null],["1970-01-01T00:09:00Z",null]]}]}]}`, 5417 }, 5418 { 5419 name: "dividing by elapsed count with fill previous should not panic", 5420 params: url.Values{"db": []string{"db0"}}, 5421 command: `SELECT sum(value) / elapsed(sum(value), 1m) FROM cpu WHERE time > 0 AND time < 10m GROUP BY time(1m) FILL(previous)`, 5422 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","sum_elapsed"],"values":[["1970-01-01T00:00:00Z",null],["1970-01-01T00:01:00Z",null],["1970-01-01T00:02:00Z",null],["1970-01-01T00:03:00Z",2],["1970-01-01T00:04:00Z",2],["1970-01-01T00:05:00Z",2],["1970-01-01T00:06:00Z",2],["1970-01-01T00:07:00Z",2],["1970-01-01T00:08:00Z",2],["1970-01-01T00:09:00Z",2]]}]}]}`, 5423 }, 5424 }...) 5425 5426 ctx := context.Background() 5427 test.Run(ctx, t, s) 5428 } 5429 5430 // Ensure the server will succeed and error for common scenarios. 5431 func TestServer_Query_Common(t *testing.T) { 5432 s := OpenServer(t) 5433 defer s.Close() 5434 5435 now := now() 5436 5437 test := NewTest("db0", "rp0") 5438 test.writes = Writes{ 5439 &Write{data: fmt.Sprintf("cpu,host=server01 value=1 %s", strconv.FormatInt(now.UnixNano(), 10))}, 5440 } 5441 5442 test.addQueries([]*Query{ 5443 { 5444 name: "selecting a from a non-existent database should error", 5445 command: `SELECT value FROM db1.rp0.cpu`, 5446 exp: `{"results":[{"statement_id":0,"error":"database not found: db1"}]}`, 5447 }, 5448 { 5449 name: "selecting a from a non-existent retention policy should error", 5450 command: `SELECT value FROM db0.rp1.cpu`, 5451 exp: `{"results":[{"statement_id":0,"error":"retention policy not found: rp1"}]}`, 5452 }, 5453 { 5454 name: "selecting a valid measurement and field should succeed", 5455 command: `SELECT value FROM db0.rp0.cpu`, 5456 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["%s",1]]}]}]}`, now.Format(time.RFC3339Nano)), 5457 }, 5458 { 5459 name: "explicitly selecting time and a valid measurement and field should succeed", 5460 command: `SELECT time,value FROM db0.rp0.cpu`, 5461 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["%s",1]]}]}]}`, now.Format(time.RFC3339Nano)), 5462 }, 5463 { 5464 name: "selecting a measurement that doesn't exist should result in empty set", 5465 command: `SELECT value FROM db0.rp0.idontexist`, 5466 exp: `{"results":[{"statement_id":0}]}`, 5467 }, 5468 { 5469 name: "selecting a field that doesn't exist should result in empty set", 5470 command: `SELECT idontexist FROM db0.rp0.cpu`, 5471 exp: `{"results":[{"statement_id":0}]}`, 5472 }, 5473 { 5474 name: "selecting wildcard without specifying a database should error", 5475 command: `SELECT * FROM cpu`, 5476 exp: `{"results":[{"statement_id":0,"error":"database name required"}]}`, 5477 }, 5478 { 5479 name: "selecting explicit field without specifying a database should error", 5480 command: `SELECT value FROM cpu`, 5481 exp: `{"results":[{"statement_id":0,"error":"database name required"}]}`, 5482 }, 5483 }...) 5484 5485 ctx := context.Background() 5486 test.Run(ctx, t, s) 5487 } 5488 5489 // Ensure the server can query two points. 5490 func TestServer_Query_SelectTwoPoints(t *testing.T) { 5491 s := OpenServer(t) 5492 defer s.Close() 5493 5494 now := now() 5495 5496 test := NewTest("db0", "rp0") 5497 test.writes = Writes{ 5498 &Write{data: fmt.Sprintf("cpu value=100 %s\ncpu value=200 %s", strconv.FormatInt(now.UnixNano(), 10), strconv.FormatInt(now.Add(1).UnixNano(), 10))}, 5499 } 5500 5501 test.addQueries( 5502 &Query{ 5503 name: "selecting two points should result in two points", 5504 command: `SELECT * FROM db0.rp0.cpu`, 5505 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["%s",100],["%s",200]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 5506 }, 5507 &Query{ 5508 name: "selecting two points with GROUP BY * should result in two points", 5509 command: `SELECT * FROM db0.rp0.cpu GROUP BY *`, 5510 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["%s",100],["%s",200]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 5511 }, 5512 ) 5513 5514 ctx := context.Background() 5515 test.Run(ctx, t, s) 5516 } 5517 5518 // Ensure the server can query two negative points. 5519 func TestServer_Query_SelectTwoNegativePoints(t *testing.T) { 5520 s := OpenServer(t) 5521 defer s.Close() 5522 5523 now := now() 5524 5525 test := NewTest("db0", "rp0") 5526 test.writes = Writes{ 5527 &Write{data: fmt.Sprintf("cpu value=-100 %s\ncpu value=-200 %s", strconv.FormatInt(now.UnixNano(), 10), strconv.FormatInt(now.Add(1).UnixNano(), 10))}, 5528 } 5529 5530 test.addQueries(&Query{ 5531 name: "selecting two negative points should succeed", 5532 command: `SELECT * FROM db0.rp0.cpu`, 5533 exp: fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["%s",-100],["%s",-200]]}]}]}`, now.Format(time.RFC3339Nano), now.Add(1).Format(time.RFC3339Nano)), 5534 }) 5535 5536 ctx := context.Background() 5537 test.Run(ctx, t, s) 5538 } 5539 5540 // Ensure the server can handle various simple derivative queries. 5541 func TestServer_Query_SelectRawDerivative(t *testing.T) { 5542 s := OpenServer(t) 5543 defer s.Close() 5544 5545 test := NewTest("db0", "rp0") 5546 test.writes = Writes{ 5547 &Write{data: "cpu value=210 1278010021000000000\ncpu value=10 1278010022000000000"}, 5548 } 5549 5550 test.addQueries([]*Query{ 5551 { 5552 name: "calculate single derivate", 5553 command: `SELECT derivative(value) from db0.rp0.cpu`, 5554 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-200]]}]}]}`, 5555 }, 5556 { 5557 name: "calculate derivate with unit", 5558 command: `SELECT derivative(value, 10s) from db0.rp0.cpu`, 5559 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-2000]]}]}]}`, 5560 }, 5561 }...) 5562 5563 ctx := context.Background() 5564 test.Run(ctx, t, s) 5565 } 5566 5567 // Ensure the server can handle various group by time derivative queries. 5568 func TestServer_Query_SelectGroupByTimeDerivativeWithFill(t *testing.T) { 5569 s := OpenServer(t) 5570 defer s.Close() 5571 5572 test := NewTest("db0", "rp0") 5573 test.writes = Writes{ 5574 &Write{data: `cpu value=10 1278010020000000000 5575 cpu value=20 1278010021000000000 5576 `}, 5577 } 5578 5579 test.addQueries([]*Query{ 5580 { 5581 name: "calculate derivative of count with unit default (2s) group by time with fill 0", 5582 command: `SELECT derivative(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5583 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",2],["2010-07-01T18:47:02Z",-2]]}]}]}`, 5584 }, 5585 { 5586 name: "calculate derivative of count with unit 4s group by time with fill 0", 5587 command: `SELECT derivative(count(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5588 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",4],["2010-07-01T18:47:02Z",-4]]}]}]}`, 5589 }, 5590 { 5591 name: "calculate derivative of count with unit default (2s) group by time with fill previous", 5592 command: `SELECT derivative(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5593 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5594 }, 5595 { 5596 name: "calculate derivative of count with unit 4s group by time with fill previous", 5597 command: `SELECT derivative(count(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5598 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5599 }, 5600 { 5601 name: "calculate derivative of mean with unit default (2s) group by time with fill 0", 5602 command: `SELECT derivative(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5603 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",-15]]}]}]}`, 5604 }, 5605 { 5606 name: "calculate derivative of mean with unit 4s group by time with fill 0", 5607 command: `SELECT derivative(mean(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5608 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",30],["2010-07-01T18:47:02Z",-30]]}]}]}`, 5609 }, 5610 { 5611 name: "calculate derivative of mean with unit default (2s) group by time with fill previous", 5612 command: `SELECT derivative(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5613 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5614 }, 5615 { 5616 name: "calculate derivative of mean with unit 4s group by time with fill previous", 5617 command: `SELECT derivative(mean(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5618 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5619 }, 5620 { 5621 name: "calculate derivative of median with unit default (2s) group by time with fill 0", 5622 command: `SELECT derivative(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5623 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",-15]]}]}]}`, 5624 }, 5625 { 5626 name: "calculate derivative of median with unit 4s group by time with fill 0", 5627 command: `SELECT derivative(median(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5628 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",30],["2010-07-01T18:47:02Z",-30]]}]}]}`, 5629 }, 5630 { 5631 name: "calculate derivative of median with unit default (2s) group by time with fill previous", 5632 command: `SELECT derivative(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5633 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5634 }, 5635 { 5636 name: "calculate derivative of median with unit 4s group by time with fill previous", 5637 command: `SELECT derivative(median(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5638 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5639 }, 5640 { 5641 name: "calculate derivative of mode with unit default (2s) group by time with fill 0", 5642 command: `SELECT derivative(mode(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5643 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",-10]]}]}]}`, 5644 }, 5645 { 5646 name: "calculate derivative of mode with unit 4s group by time with fill 0", 5647 command: `SELECT derivative(mode(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5648 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",-20]]}]}]}`, 5649 }, 5650 { 5651 name: "calculate derivative of mode with unit default (2s) group by time with fill previous", 5652 command: `SELECT derivative(mode(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5653 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5654 }, 5655 { 5656 name: "calculate derivative of mode with unit 4s group by time with fill previous", 5657 command: `SELECT derivative(mode(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5658 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5659 }, 5660 { 5661 name: "calculate derivative of sum with unit default (2s) group by time with fill 0", 5662 command: `SELECT derivative(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5663 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",30],["2010-07-01T18:47:02Z",-30]]}]}]}`, 5664 }, 5665 { 5666 name: "calculate derivative of sum with unit 4s group by time with fill 0", 5667 command: `SELECT derivative(sum(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5668 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",60],["2010-07-01T18:47:02Z",-60]]}]}]}`, 5669 }, 5670 { 5671 name: "calculate derivative of sum with unit default (2s) group by time with fill previous", 5672 command: `SELECT derivative(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5673 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5674 }, 5675 { 5676 name: "calculate derivative of sum with unit 4s group by time with fill previous", 5677 command: `SELECT derivative(sum(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5678 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5679 }, 5680 { 5681 name: "calculate derivative of first with unit default (2s) group by time with fill 0", 5682 command: `SELECT derivative(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5683 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",-10]]}]}]}`, 5684 }, 5685 { 5686 name: "calculate derivative of first with unit 4s group by time with fill 0", 5687 command: `SELECT derivative(first(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5688 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",-20]]}]}]}`, 5689 }, 5690 { 5691 name: "calculate derivative of first with unit default (2s) group by time with fill previous", 5692 command: `SELECT derivative(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5693 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5694 }, 5695 { 5696 name: "calculate derivative of first with unit 4s group by time with fill previous", 5697 command: `SELECT derivative(first(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5698 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5699 }, 5700 { 5701 name: "calculate derivative of last with unit default (2s) group by time with fill 0", 5702 command: `SELECT derivative(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5703 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",-20]]}]}]}`, 5704 }, 5705 { 5706 name: "calculate derivative of last with unit 4s group by time with fill 0", 5707 command: `SELECT derivative(last(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5708 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",40],["2010-07-01T18:47:02Z",-40]]}]}]}`, 5709 }, 5710 { 5711 name: "calculate derivative of last with unit default (2s) group by time with fill previous", 5712 command: `SELECT derivative(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5713 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5714 }, 5715 { 5716 name: "calculate derivative of last with unit 4s group by time with fill previous", 5717 command: `SELECT derivative(last(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5718 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5719 }, 5720 { 5721 name: "calculate derivative of min with unit default (2s) group by time with fill 0", 5722 command: `SELECT derivative(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5723 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",-10]]}]}]}`, 5724 }, 5725 { 5726 name: "calculate derivative of min with unit 4s group by time with fill 0", 5727 command: `SELECT derivative(min(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5728 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",-20]]}]}]}`, 5729 }, 5730 { 5731 name: "calculate derivative of min with unit default (2s) group by time with fill previous", 5732 command: `SELECT derivative(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5733 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5734 }, 5735 { 5736 name: "calculate derivative of min with unit 4s group by time with fill previous", 5737 command: `SELECT derivative(min(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5738 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5739 }, 5740 { 5741 name: "calculate derivative of max with unit default (2s) group by time with fill 0", 5742 command: `SELECT derivative(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5743 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",-20]]}]}]}`, 5744 }, 5745 { 5746 name: "calculate derivative of max with unit 4s group by time with fill 0", 5747 command: `SELECT derivative(max(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5748 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",40],["2010-07-01T18:47:02Z",-40]]}]}]}`, 5749 }, 5750 { 5751 name: "calculate derivative of max with unit default (2s) group by time with fill previous", 5752 command: `SELECT derivative(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5753 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5754 }, 5755 { 5756 name: "calculate derivative of max with unit 4s group by time with fill previous", 5757 command: `SELECT derivative(max(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5758 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5759 }, 5760 { 5761 name: "calculate derivative of percentile with unit default (2s) group by time with fill 0", 5762 command: `SELECT derivative(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5763 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",-10]]}]}]}`, 5764 }, 5765 { 5766 name: "calculate derivative of percentile with unit 4s group by time with fill 0", 5767 command: `SELECT derivative(percentile(value, 50), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5768 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",-20]]}]}]}`, 5769 }, 5770 { 5771 name: "calculate derivative of percentile with unit default (2s) group by time with fill previous", 5772 command: `SELECT derivative(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5773 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5774 }, 5775 { 5776 name: "calculate derivative of percentile with unit 4s group by time with fill previous", 5777 command: `SELECT derivative(percentile(value, 50), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5778 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5779 }, 5780 }...) 5781 5782 ctx := context.Background() 5783 test.Run(ctx, t, s) 5784 } 5785 5786 // Ensure the server can handle various group by time difference queries. 5787 func TestServer_Query_SelectGroupByTimeDifference(t *testing.T) { 5788 s := OpenServer(t) 5789 defer s.Close() 5790 5791 test := NewTest("db0", "rp0") 5792 test.writes = Writes{ 5793 &Write{data: `cpu value=10 1278010020000000000 5794 cpu value=15 1278010021000000000 5795 cpu value=20 1278010022000000000 5796 cpu value=25 1278010023000000000 5797 `}, 5798 } 5799 5800 test.addQueries([]*Query{ 5801 { 5802 name: "calculate difference of count", 5803 command: `SELECT difference(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5804 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",2],["2010-07-01T18:47:02Z",0]]}]}]}`, 5805 }, 5806 { 5807 name: "calculate difference of mean", 5808 command: `SELECT difference(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5809 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 5810 }, 5811 { 5812 name: "calculate difference of median", 5813 command: `SELECT difference(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5814 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 5815 }, 5816 { 5817 name: "calculate difference of mode", 5818 command: `SELECT difference(mode(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5819 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 5820 }, 5821 { 5822 name: "calculate difference of sum", 5823 command: `SELECT difference(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5824 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, 5825 }, 5826 { 5827 name: "calculate difference of first", 5828 command: `SELECT difference(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5829 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 5830 }, 5831 { 5832 name: "calculate difference of last", 5833 command: `SELECT difference(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5834 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 5835 }, 5836 { 5837 name: "calculate difference of min", 5838 command: `SELECT difference(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5839 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 5840 }, 5841 { 5842 name: "calculate difference of max", 5843 command: `SELECT difference(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5844 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 5845 }, 5846 { 5847 name: "calculate difference of percentile", 5848 command: `SELECT difference(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, 5849 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, 5850 }, 5851 }...) 5852 5853 ctx := context.Background() 5854 test.Run(ctx, t, s) 5855 } 5856 5857 // Ensure the server can handle various group by time difference queries with fill. 5858 func TestServer_Query_SelectGroupByTimeDifferenceWithFill(t *testing.T) { 5859 s := OpenServer(t) 5860 defer s.Close() 5861 5862 test := NewTest("db0", "rp0") 5863 test.writes = Writes{ 5864 &Write{data: `cpu value=10 1278010020000000000 5865 cpu value=20 1278010021000000000 5866 `}, 5867 } 5868 5869 test.addQueries([]*Query{ 5870 { 5871 name: "calculate difference of count with fill 0", 5872 command: `SELECT difference(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5873 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",2],["2010-07-01T18:47:02Z",-2]]}]}]}`, 5874 }, 5875 { 5876 name: "calculate difference of count with fill previous", 5877 command: `SELECT difference(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5878 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5879 }, 5880 { 5881 name: "calculate difference of mean with fill 0", 5882 command: `SELECT difference(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5883 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",-15]]}]}]}`, 5884 }, 5885 { 5886 name: "calculate difference of mean with fill previous", 5887 command: `SELECT difference(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5888 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5889 }, 5890 { 5891 name: "calculate difference of median with fill 0", 5892 command: `SELECT difference(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5893 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",15],["2010-07-01T18:47:02Z",-15]]}]}]}`, 5894 }, 5895 { 5896 name: "calculate difference of median with fill previous", 5897 command: `SELECT difference(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5898 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5899 }, 5900 { 5901 name: "calculate difference of mode with fill 0", 5902 command: `SELECT difference(mode(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5903 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",-10]]}]}]}`, 5904 }, 5905 { 5906 name: "calculate difference of mode with fill previous", 5907 command: `SELECT difference(mode(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5908 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5909 }, 5910 { 5911 name: "calculate difference of sum with fill 0", 5912 command: `SELECT difference(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5913 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",30],["2010-07-01T18:47:02Z",-30]]}]}]}`, 5914 }, 5915 { 5916 name: "calculate difference of sum with fill previous", 5917 command: `SELECT difference(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5918 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5919 }, 5920 { 5921 name: "calculate difference of first with fill 0", 5922 command: `SELECT difference(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5923 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",-10]]}]}]}`, 5924 }, 5925 { 5926 name: "calculate difference of first with fill previous", 5927 command: `SELECT difference(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5928 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5929 }, 5930 { 5931 name: "calculate difference of last with fill 0", 5932 command: `SELECT difference(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5933 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",-20]]}]}]}`, 5934 }, 5935 { 5936 name: "calculate difference of last with fill previous", 5937 command: `SELECT difference(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5938 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5939 }, 5940 { 5941 name: "calculate difference of min with fill 0", 5942 command: `SELECT difference(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5943 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",-10]]}]}]}`, 5944 }, 5945 { 5946 name: "calculate difference of min with fill previous", 5947 command: `SELECT difference(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5948 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5949 }, 5950 { 5951 name: "calculate difference of max with fill 0", 5952 command: `SELECT difference(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5953 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",20],["2010-07-01T18:47:02Z",-20]]}]}]}`, 5954 }, 5955 { 5956 name: "calculate difference of max with fill previous", 5957 command: `SELECT difference(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5958 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5959 }, 5960 { 5961 name: "calculate difference of percentile with fill 0", 5962 command: `SELECT difference(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, 5963 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:00Z",10],["2010-07-01T18:47:02Z",-10]]}]}]}`, 5964 }, 5965 { 5966 name: "calculate difference of percentile with fill previous", 5967 command: `SELECT difference(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, 5968 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, 5969 }, 5970 }...) 5971 5972 ctx := context.Background() 5973 test.Run(ctx, t, s) 5974 } 5975 5976 // Test various aggregates when different series only have data for the same timestamp. 5977 func TestServer_Query_Aggregates_IdenticalTime(t *testing.T) { 5978 s := OpenServer(t) 5979 defer s.Close() 5980 5981 writes := []string{ 5982 fmt.Sprintf(`series,host=a value=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5983 fmt.Sprintf(`series,host=b value=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5984 fmt.Sprintf(`series,host=c value=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5985 fmt.Sprintf(`series,host=d value=4 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5986 fmt.Sprintf(`series,host=e value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5987 fmt.Sprintf(`series,host=f value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5988 fmt.Sprintf(`series,host=g value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5989 fmt.Sprintf(`series,host=h value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5990 fmt.Sprintf(`series,host=i value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 5991 } 5992 5993 test := NewTest("db0", "rp0") 5994 test.writes = Writes{ 5995 &Write{data: strings.Join(writes, "\n")}, 5996 } 5997 5998 test.addQueries([]*Query{ 5999 { 6000 name: "last from multiple series with identical timestamp", 6001 params: url.Values{"db": []string{"db0"}}, 6002 command: `SELECT last(value) FROM "series"`, 6003 exp: `{"results":[{"statement_id":0,"series":[{"name":"series","columns":["time","last"],"values":[["2000-01-01T00:00:00Z",5]]}]}]}`, 6004 repeat: 100, 6005 }, 6006 { 6007 name: "first from multiple series with identical timestamp", 6008 params: url.Values{"db": []string{"db0"}}, 6009 command: `SELECT first(value) FROM "series"`, 6010 exp: `{"results":[{"statement_id":0,"series":[{"name":"series","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",5]]}]}]}`, 6011 repeat: 100, 6012 }, 6013 }...) 6014 6015 ctx := context.Background() 6016 test.Run(ctx, t, s) 6017 } 6018 6019 func TestServer_Query_AcrossShardsAndFields(t *testing.T) { 6020 s := OpenServer(t) 6021 defer s.Close() 6022 6023 writes := []string{ 6024 fmt.Sprintf(`cpu load=100 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), 6025 fmt.Sprintf(`cpu load=200 %d`, mustParseTime(time.RFC3339Nano, "2010-01-01T00:00:00Z").UnixNano()), 6026 fmt.Sprintf(`cpu core=4 %d`, mustParseTime(time.RFC3339Nano, "2015-01-01T00:00:00Z").UnixNano()), 6027 } 6028 6029 test := NewTest("db0", "rp0") 6030 test.writes = Writes{ 6031 &Write{data: strings.Join(writes, "\n")}, 6032 } 6033 6034 test.addQueries([]*Query{ 6035 { 6036 name: "two results for cpu", 6037 params: url.Values{"db": []string{"db0"}}, 6038 command: `SELECT load FROM cpu`, 6039 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","load"],"values":[["2000-01-01T00:00:00Z",100],["2010-01-01T00:00:00Z",200]]}]}]}`, 6040 }, 6041 { 6042 name: "two results for cpu, multi-select", 6043 params: url.Values{"db": []string{"db0"}}, 6044 command: `SELECT core,load FROM cpu`, 6045 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core","load"],"values":[["2000-01-01T00:00:00Z",null,100],["2010-01-01T00:00:00Z",null,200],["2015-01-01T00:00:00Z",4,null]]}]}]}`, 6046 }, 6047 { 6048 name: "two results for cpu, wildcard select", 6049 params: url.Values{"db": []string{"db0"}}, 6050 command: `SELECT * FROM cpu`, 6051 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core","load"],"values":[["2000-01-01T00:00:00Z",null,100],["2010-01-01T00:00:00Z",null,200],["2015-01-01T00:00:00Z",4,null]]}]}]}`, 6052 }, 6053 { 6054 name: "one result for core", 6055 params: url.Values{"db": []string{"db0"}}, 6056 command: `SELECT core FROM cpu`, 6057 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","core"],"values":[["2015-01-01T00:00:00Z",4]]}]}]}`, 6058 }, 6059 { 6060 name: "empty result set from non-existent field", 6061 params: url.Values{"db": []string{"db0"}}, 6062 command: `SELECT foo FROM cpu`, 6063 exp: `{"results":[{"statement_id":0}]}`, 6064 }, 6065 }...) 6066 6067 ctx := context.Background() 6068 test.Run(ctx, t, s) 6069 } 6070 6071 func TestServer_Query_OrderedAcrossShards(t *testing.T) { 6072 s := OpenServer(t) 6073 defer s.Close() 6074 6075 writes := []string{ 6076 fmt.Sprintf(`cpu value=7 %d`, mustParseTime(time.RFC3339Nano, "2010-01-01T00:00:00Z").UnixNano()), 6077 fmt.Sprintf(`cpu value=14 %d`, mustParseTime(time.RFC3339Nano, "2010-01-08T00:00:00Z").UnixNano()), 6078 fmt.Sprintf(`cpu value=28 %d`, mustParseTime(time.RFC3339Nano, "2010-01-15T00:00:00Z").UnixNano()), 6079 fmt.Sprintf(`cpu value=56 %d`, mustParseTime(time.RFC3339Nano, "2010-01-22T00:00:00Z").UnixNano()), 6080 fmt.Sprintf(`cpu value=112 %d`, mustParseTime(time.RFC3339Nano, "2010-01-29T00:00:00Z").UnixNano()), 6081 } 6082 6083 test := NewTest("db0", "rp0") 6084 test.writes = Writes{ 6085 &Write{data: strings.Join(writes, "\n")}, 6086 } 6087 6088 test.addQueries([]*Query{ 6089 { 6090 name: "derivative", 6091 params: url.Values{"db": []string{"db0"}}, 6092 command: `SELECT derivative(value, 24h) FROM cpu`, 6093 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-01-08T00:00:00Z",1],["2010-01-15T00:00:00Z",2],["2010-01-22T00:00:00Z",4],["2010-01-29T00:00:00Z",8]]}]}]}`, 6094 }, 6095 { 6096 name: "non_negative_derivative", 6097 params: url.Values{"db": []string{"db0"}}, 6098 command: `SELECT non_negative_derivative(value, 24h) FROM cpu`, 6099 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","non_negative_derivative"],"values":[["2010-01-08T00:00:00Z",1],["2010-01-15T00:00:00Z",2],["2010-01-22T00:00:00Z",4],["2010-01-29T00:00:00Z",8]]}]}]}`, 6100 }, 6101 { 6102 name: "difference", 6103 params: url.Values{"db": []string{"db0"}}, 6104 command: `SELECT difference(value) FROM cpu`, 6105 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","difference"],"values":[["2010-01-08T00:00:00Z",7],["2010-01-15T00:00:00Z",14],["2010-01-22T00:00:00Z",28],["2010-01-29T00:00:00Z",56]]}]}]}`, 6106 }, 6107 { 6108 name: "cumulative_sum", 6109 params: url.Values{"db": []string{"db0"}}, 6110 command: `SELECT cumulative_sum(value) FROM cpu`, 6111 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","cumulative_sum"],"values":[["2010-01-01T00:00:00Z",7],["2010-01-08T00:00:00Z",21],["2010-01-15T00:00:00Z",49],["2010-01-22T00:00:00Z",105],["2010-01-29T00:00:00Z",217]]}]}]}`, 6112 }, 6113 }...) 6114 6115 ctx := context.Background() 6116 test.Run(ctx, t, s) 6117 } 6118 6119 func TestServer_Query_Where_With_Tags(t *testing.T) { 6120 s := OpenServer(t) 6121 defer s.Close() 6122 6123 writes := []string{ 6124 fmt.Sprintf(`where_events,tennant=paul foo="bar" %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:02Z").UnixNano()), 6125 fmt.Sprintf(`where_events,tennant=paul foo="baz" %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:03Z").UnixNano()), 6126 fmt.Sprintf(`where_events,tennant=paul foo="bat" %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:04Z").UnixNano()), 6127 fmt.Sprintf(`where_events,tennant=todd foo="bar" %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:05Z").UnixNano()), 6128 fmt.Sprintf(`where_events,tennant=david foo="bap" %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:06Z").UnixNano()), 6129 } 6130 6131 test := NewTest("db0", "rp0") 6132 test.writes = Writes{ 6133 &Write{data: strings.Join(writes, "\n")}, 6134 } 6135 6136 test.addQueries([]*Query{ 6137 { 6138 name: "tag field and time", 6139 params: url.Values{"db": []string{"db0"}}, 6140 command: `select foo from where_events where (tennant = 'paul' OR tennant = 'david') AND time > 1s AND (foo = 'bar' OR foo = 'baz' OR foo = 'bap')`, 6141 exp: `{"results":[{"statement_id":0,"series":[{"name":"where_events","columns":["time","foo"],"values":[["2009-11-10T23:00:02Z","bar"],["2009-11-10T23:00:03Z","baz"],["2009-11-10T23:00:06Z","bap"]]}]}]}`, 6142 }, 6143 { 6144 name: "tag or field", 6145 params: url.Values{"db": []string{"db0"}}, 6146 command: `select foo from where_events where tennant = 'paul' OR foo = 'bar'`, 6147 exp: `{"results":[{"statement_id":0,"series":[{"name":"where_events","columns":["time","foo"],"values":[["2009-11-10T23:00:02Z","bar"],["2009-11-10T23:00:03Z","baz"],["2009-11-10T23:00:04Z","bat"],["2009-11-10T23:00:05Z","bar"]]}]}]}`, 6148 }, 6149 { 6150 name: "non-existent tag and field", 6151 params: url.Values{"db": []string{"db0"}}, 6152 command: `select foo from where_events where tenant != 'paul' AND foo = 'bar'`, 6153 exp: `{"results":[{"statement_id":0,"series":[{"name":"where_events","columns":["time","foo"],"values":[["2009-11-10T23:00:02Z","bar"],["2009-11-10T23:00:05Z","bar"]]}]}]}`, 6154 }, 6155 { 6156 name: "non-existent tag or field", 6157 params: url.Values{"db": []string{"db0"}}, 6158 command: `select foo from where_events where tenant != 'paul' OR foo = 'bar'`, 6159 exp: `{"results":[{"statement_id":0,"series":[{"name":"where_events","columns":["time","foo"],"values":[["2009-11-10T23:00:02Z","bar"],["2009-11-10T23:00:03Z","baz"],["2009-11-10T23:00:04Z","bat"],["2009-11-10T23:00:05Z","bar"],["2009-11-10T23:00:06Z","bap"]]}]}]}`, 6160 }, 6161 { 6162 name: "where comparing tag and field", 6163 params: url.Values{"db": []string{"db0"}}, 6164 command: `select foo from where_events where tennant != foo`, 6165 exp: `{"results":[{"statement_id":0,"series":[{"name":"where_events","columns":["time","foo"],"values":[["2009-11-10T23:00:02Z","bar"],["2009-11-10T23:00:03Z","baz"],["2009-11-10T23:00:04Z","bat"],["2009-11-10T23:00:05Z","bar"],["2009-11-10T23:00:06Z","bap"]]}]}]}`, 6166 }, 6167 { 6168 name: "where comparing tag and tag", 6169 params: url.Values{"db": []string{"db0"}}, 6170 command: `select foo from where_events where tennant = tennant`, 6171 exp: `{"results":[{"statement_id":0,"series":[{"name":"where_events","columns":["time","foo"],"values":[["2009-11-10T23:00:02Z","bar"],["2009-11-10T23:00:03Z","baz"],["2009-11-10T23:00:04Z","bat"],["2009-11-10T23:00:05Z","bar"],["2009-11-10T23:00:06Z","bap"]]}]}]}`, 6172 }, 6173 }...) 6174 6175 ctx := context.Background() 6176 test.Run(ctx, t, s) 6177 } 6178 6179 func TestServer_Query_With_EmptyTags(t *testing.T) { 6180 s := OpenServer(t) 6181 defer s.Close() 6182 6183 writes := []string{ 6184 fmt.Sprintf(`cpu value=1 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:02Z").UnixNano()), 6185 fmt.Sprintf(`cpu,host=server01 value=2 %d`, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:03Z").UnixNano()), 6186 } 6187 6188 test := NewTest("db0", "rp0") 6189 test.writes = Writes{ 6190 &Write{data: strings.Join(writes, "\n")}, 6191 } 6192 6193 test.addQueries([]*Query{ 6194 { 6195 name: "where empty tag", 6196 params: url.Values{"db": []string{"db0"}}, 6197 command: `select value from cpu where host = ''`, 6198 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2009-11-10T23:00:02Z",1]]}]}]}`, 6199 }, 6200 { 6201 name: "where not empty tag", 6202 params: url.Values{"db": []string{"db0"}}, 6203 command: `select value from cpu where host != ''`, 6204 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2009-11-10T23:00:03Z",2]]}]}]}`, 6205 }, 6206 { 6207 name: "where regex none", 6208 params: url.Values{"db": []string{"db0"}}, 6209 command: `select value from cpu where host !~ /.*/`, 6210 exp: `{"results":[{"statement_id":0}]}`, 6211 }, 6212 { 6213 name: "where regex exact", 6214 params: url.Values{"db": []string{"db0"}}, 6215 command: `select value from cpu where host =~ /^server01$/`, 6216 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2009-11-10T23:00:03Z",2]]}]}]}`, 6217 }, 6218 { 6219 name: "where regex exact (case insensitive)", 6220 params: url.Values{"db": []string{"db0"}}, 6221 command: `select value from cpu where host =~ /(?i)^SeRvEr01$/`, 6222 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2009-11-10T23:00:03Z",2]]}]}]}`, 6223 }, 6224 { 6225 name: "where regex exact (not)", 6226 params: url.Values{"db": []string{"db0"}}, 6227 command: `select value from cpu where host !~ /^server01$/`, 6228 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2009-11-10T23:00:02Z",1]]}]}]}`, 6229 }, 6230 { 6231 name: "where regex at least one char", 6232 params: url.Values{"db": []string{"db0"}}, 6233 command: `select value from cpu where host =~ /.+/`, 6234 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2009-11-10T23:00:03Z",2]]}]}]}`, 6235 }, 6236 { 6237 name: "where regex not at least one char", 6238 params: url.Values{"db": []string{"db0"}}, 6239 command: `select value from cpu where host !~ /.+/`, 6240 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2009-11-10T23:00:02Z",1]]}]}]}`, 6241 }, 6242 { 6243 name: "group by empty tag", 6244 params: url.Values{"db": []string{"db0"}}, 6245 command: `select value from cpu group by host`, 6246 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"host":""},"columns":["time","value"],"values":[["2009-11-10T23:00:02Z",1]]},{"name":"cpu","tags":{"host":"server01"},"columns":["time","value"],"values":[["2009-11-10T23:00:03Z",2]]}]}]}`, 6247 }, 6248 { 6249 name: "group by missing tag", 6250 params: url.Values{"db": []string{"db0"}}, 6251 command: `select value from cpu group by region`, 6252 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","tags":{"region":""},"columns":["time","value"],"values":[["2009-11-10T23:00:02Z",1],["2009-11-10T23:00:03Z",2]]}]}]}`, 6253 }, 6254 }...) 6255 6256 ctx := context.Background() 6257 test.Run(ctx, t, s) 6258 } 6259 6260 func TestServer_Query_ImplicitFill(t *testing.T) { 6261 s := OpenServer(t, func(o *launcher.InfluxdOpts) { 6262 o.CoordinatorConfig.MaxSelectBucketsN = 5 6263 }) 6264 defer s.Close() 6265 6266 writes := []string{ 6267 fmt.Sprintf(`fills val=1 %d`, mustParseTime(time.RFC3339Nano, "2010-01-01T11:30:00Z").UnixNano()), 6268 fmt.Sprintf(`fills val=3 %d`, mustParseTime(time.RFC3339Nano, "2010-01-01T12:00:00Z").UnixNano()), 6269 fmt.Sprintf(`fills val=5 %d`, mustParseTime(time.RFC3339Nano, "2010-01-01T16:30:00Z").UnixNano()), 6270 } 6271 6272 test := NewTest("db0", "rp0") 6273 test.writes = Writes{ 6274 &Write{data: strings.Join(writes, "\n")}, 6275 } 6276 6277 test.addQueries([]*Query{ 6278 { 6279 name: "fill with implicit start", 6280 command: `select mean(val) from fills where time < '2010-01-01T18:00:00Z' group by time(1h)`, 6281 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","mean"],"values":[["2010-01-01T16:00:00Z",5],["2010-01-01T17:00:00Z",null]]}]}]}`, 6282 params: url.Values{"db": []string{"db0"}}, 6283 }, 6284 { 6285 name: "fill with implicit start - max select buckets", 6286 command: `select mean(val) from fills where time < '2010-01-01T17:00:00Z' group by time(1h)`, 6287 exp: `{"results":[{"statement_id":0,"series":[{"name":"fills","columns":["time","mean"],"values":[["2010-01-01T12:00:00Z",3],["2010-01-01T13:00:00Z",null],["2010-01-01T14:00:00Z",null],["2010-01-01T15:00:00Z",null],["2010-01-01T16:00:00Z",5]]}]}]}`, 6288 params: url.Values{"db": []string{"db0"}}, 6289 }, 6290 }...) 6291 6292 ctx := context.Background() 6293 test.Run(ctx, t, s) 6294 } 6295 6296 func TestServer_Query_MaxRowLimit(t *testing.T) { 6297 t.Skip(NotSupported) 6298 // config := NewConfig() 6299 // config.HTTPD.MaxRowLimit = 10 6300 6301 s := OpenServer(t) 6302 defer s.Close() 6303 6304 writes := make([]string, 11) // write one extra value beyond the max row limit 6305 expectedValues := make([]string, 10) 6306 for i := 0; i < len(writes); i++ { 6307 writes[i] = fmt.Sprintf(`cpu value=%d %d`, i, time.Unix(0, int64(i)).UnixNano()) 6308 if i < len(expectedValues) { 6309 expectedValues[i] = fmt.Sprintf(`["%s",%d]`, time.Unix(0, int64(i)).UTC().Format(time.RFC3339Nano), i) 6310 } 6311 } 6312 expected := fmt.Sprintf(`{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[%s],"partial":true}]}]}`, strings.Join(expectedValues, ",")) 6313 6314 test := NewTest("db0", "rp0") 6315 test.writes = Writes{ 6316 &Write{data: strings.Join(writes, "\n")}, 6317 } 6318 6319 test.addQueries([]*Query{ 6320 { 6321 name: "SELECT all values, no chunking", 6322 command: `SELECT value FROM cpu`, 6323 exp: expected, 6324 params: url.Values{"db": []string{"db0"}}, 6325 }, 6326 }...) 6327 6328 ctx := context.Background() 6329 test.Run(ctx, t, s) 6330 } 6331 6332 func TestServer_Query_EvilIdentifiers(t *testing.T) { 6333 s := OpenServer(t) 6334 defer s.Close() 6335 6336 test := NewTest("db0", "rp0") 6337 test.writes = Writes{ 6338 &Write{data: fmt.Sprintf("cpu select=1,in-bytes=2 %d", mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano())}, 6339 } 6340 6341 test.addQueries([]*Query{ 6342 { 6343 name: `query evil identifiers`, 6344 command: `SELECT "select", "in-bytes" FROM cpu`, 6345 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","select","in-bytes"],"values":[["2000-01-01T00:00:00Z",1,2]]}]}]}`, 6346 params: url.Values{"db": []string{"db0"}}, 6347 }, 6348 }...) 6349 6350 ctx := context.Background() 6351 test.Run(ctx, t, s) 6352 } 6353 6354 func TestServer_Query_OrderByTime(t *testing.T) { 6355 s := OpenServer(t) 6356 defer s.Close() 6357 6358 writes := []string{ 6359 fmt.Sprintf(`cpu,host=server1 value=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 6360 fmt.Sprintf(`cpu,host=server1 value=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), 6361 fmt.Sprintf(`cpu,host=server1 value=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 6362 6363 fmt.Sprintf(`power,presence=true value=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 6364 fmt.Sprintf(`power,presence=true value=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), 6365 fmt.Sprintf(`power,presence=true value=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), 6366 fmt.Sprintf(`power,presence=false value=4 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:04Z").UnixNano()), 6367 6368 fmt.Sprintf(`mem,host=server1 free=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 6369 fmt.Sprintf(`mem,host=server1 free=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), 6370 fmt.Sprintf(`mem,host=server2 used=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), 6371 fmt.Sprintf(`mem,host=server2 used=4 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), 6372 } 6373 6374 test := NewTest("db0", "rp0") 6375 test.writes = Writes{ 6376 &Write{data: strings.Join(writes, "\n")}, 6377 } 6378 6379 test.addQueries([]*Query{ 6380 { 6381 name: "order on points", 6382 params: url.Values{"db": []string{"db0"}}, 6383 command: `select value from "cpu" ORDER BY time DESC`, 6384 exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:03Z",3],["2000-01-01T00:00:02Z",2],["2000-01-01T00:00:01Z",1]]}]}]}`, 6385 }, 6386 6387 { 6388 name: "order desc with tags", 6389 params: url.Values{"db": []string{"db0"}}, 6390 command: `select value from "power" ORDER BY time DESC`, 6391 exp: `{"results":[{"statement_id":0,"series":[{"name":"power","columns":["time","value"],"values":[["2000-01-01T00:00:04Z",4],["2000-01-01T00:00:03Z",3],["2000-01-01T00:00:02Z",2],["2000-01-01T00:00:01Z",1]]}]}]}`, 6392 }, 6393 6394 { 6395 name: "order desc with sparse data", 6396 params: url.Values{"db": []string{"db0"}}, 6397 command: `select used, free from "mem" ORDER BY time DESC`, 6398 exp: `{"results":[{"statement_id":0,"series":[{"name":"mem","columns":["time","used","free"],"values":[["2000-01-01T00:00:02Z",4,null],["2000-01-01T00:00:02Z",null,2],["2000-01-01T00:00:01Z",3,null],["2000-01-01T00:00:01Z",null,1]]}]}]}`, 6399 }, 6400 6401 { 6402 name: "order desc with an aggregate and sparse data", 6403 params: url.Values{"db": []string{"db0"}}, 6404 command: `select first("used") AS "used", first("free") AS "free" from "mem" WHERE time >= '2000-01-01T00:00:01Z' AND time <= '2000-01-01T00:00:02Z' GROUP BY host, time(1s) FILL(none) ORDER BY time DESC`, 6405 exp: `{"results":[{"statement_id":0,"series":[{"name":"mem","tags":{"host":"server2"},"columns":["time","used","free"],"values":[["2000-01-01T00:00:02Z",4,null],["2000-01-01T00:00:01Z",3,null]]},{"name":"mem","tags":{"host":"server1"},"columns":["time","used","free"],"values":[["2000-01-01T00:00:02Z",null,2],["2000-01-01T00:00:01Z",null,1]]}]}]}`, 6406 }, 6407 }...) 6408 6409 ctx := context.Background() 6410 test.Run(ctx, t, s) 6411 }