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  }