Add all versions of CARDINALITY commands
parent
50d73497c5
commit
bda6de9817
|
@ -2102,7 +2102,7 @@ type ShowSeriesCardinalityStatement struct {
|
|||
// The database can also be specified per source in the Sources.
|
||||
Database string
|
||||
|
||||
// If exact is false then the cardinality estimation approach is used.
|
||||
// Specifies whether the user requires exact counting or not.
|
||||
Exact bool
|
||||
|
||||
// Measurement(s) the series are listed for.
|
||||
|
@ -2734,6 +2734,7 @@ func (s *ShowTagKeysStatement) DefaultDatabase() string {
|
|||
// ShowTagKeyCardinalityStatement represents a command for listing tag key cardinality.
|
||||
type ShowTagKeyCardinalityStatement struct {
|
||||
Database string
|
||||
Exact bool
|
||||
Sources Sources
|
||||
Condition Expr
|
||||
Dimensions Dimensions
|
||||
|
@ -2743,7 +2744,11 @@ type ShowTagKeyCardinalityStatement struct {
|
|||
// String returns a string representation of the statement.
|
||||
func (s *ShowTagKeyCardinalityStatement) String() string {
|
||||
var buf bytes.Buffer
|
||||
_, _ = buf.WriteString("SHOW TAG KEY EXACT CARDINALITY")
|
||||
_, _ = buf.WriteString("SHOW TAG KEY ")
|
||||
if s.Exact {
|
||||
_, _ = buf.WriteString("EXACT ")
|
||||
}
|
||||
_, _ = buf.WriteString("CARDINALITY")
|
||||
|
||||
if s.Database != "" {
|
||||
_, _ = buf.WriteString(" ON ")
|
||||
|
@ -2863,6 +2868,7 @@ func (s *ShowTagValuesStatement) DefaultDatabase() string {
|
|||
// ShowTagValuesCardinalityStatement represents a command for listing tag value cardinality.
|
||||
type ShowTagValuesCardinalityStatement struct {
|
||||
Database string
|
||||
Exact bool
|
||||
Sources Sources
|
||||
Op Token
|
||||
TagKeyExpr Literal
|
||||
|
@ -2874,7 +2880,11 @@ type ShowTagValuesCardinalityStatement struct {
|
|||
// String returns a string representation of the statement.
|
||||
func (s *ShowTagValuesCardinalityStatement) String() string {
|
||||
var buf bytes.Buffer
|
||||
_, _ = buf.WriteString("SHOW TAG VALUES EXACT CARDINALITY")
|
||||
_, _ = buf.WriteString("SHOW TAG VALUES ")
|
||||
if s.Exact {
|
||||
_, _ = buf.WriteString("EXACT ")
|
||||
}
|
||||
_, _ = buf.WriteString("CARDINALITY")
|
||||
|
||||
if s.Database != "" {
|
||||
_, _ = buf.WriteString(" ON ")
|
||||
|
@ -2936,6 +2946,7 @@ func (s *ShowUsersStatement) RequiredPrivileges() (ExecutionPrivileges, error) {
|
|||
// ShowFieldKeyCardinalityStatement represents a command for listing field key cardinality.
|
||||
type ShowFieldKeyCardinalityStatement struct {
|
||||
Database string
|
||||
Exact bool
|
||||
Sources Sources
|
||||
Condition Expr
|
||||
Dimensions Dimensions
|
||||
|
@ -2945,7 +2956,12 @@ type ShowFieldKeyCardinalityStatement struct {
|
|||
// String returns a string representation of the statement.
|
||||
func (s *ShowFieldKeyCardinalityStatement) String() string {
|
||||
var buf bytes.Buffer
|
||||
_, _ = buf.WriteString("SHOW FIELD KEY EXACT CARDINALITY")
|
||||
_, _ = buf.WriteString("SHOW FIELD KEY ")
|
||||
|
||||
if s.Exact {
|
||||
_, _ = buf.WriteString("EXACT ")
|
||||
}
|
||||
_, _ = buf.WriteString("CARDINALITY")
|
||||
|
||||
if s.Database != "" {
|
||||
_, _ = buf.WriteString(" ON ")
|
||||
|
|
|
@ -118,7 +118,7 @@ func init() {
|
|||
})
|
||||
show.Group(FIELD).With(func(field *ParseTree) {
|
||||
field.Handle(KEY, func(p *Parser) (Statement, error) {
|
||||
return p.parseShowFieldKeyStatement()
|
||||
return p.parseShowFieldKeyCardinalityStatement()
|
||||
})
|
||||
field.Handle(KEYS, func(p *Parser) (Statement, error) {
|
||||
return p.parseShowFieldKeysStatement()
|
||||
|
|
|
@ -974,11 +974,6 @@ func (p *Parser) parseShowSeriesCardinalityStatement(exact bool) (Statement, err
|
|||
p.Unscan()
|
||||
}
|
||||
|
||||
// Estimation command doesn't support any further versions of the command.
|
||||
if !exact {
|
||||
return stmt, nil
|
||||
}
|
||||
|
||||
// Parse optional FROM.
|
||||
if tok, _, _ := p.ScanIgnoreWhitespace(); tok == FROM {
|
||||
if stmt.Sources, err = p.parseSources(false); err != nil {
|
||||
|
@ -1008,8 +1003,7 @@ func (p *Parser) parseShowSeriesCardinalityStatement(exact bool) (Statement, err
|
|||
return stmt, nil
|
||||
}
|
||||
|
||||
// This function assumes the "SHOW MEASUREMENT EXACT" or "SHOW MEASUREMENT CARDINALITY"
|
||||
// tokens have already been consumed.
|
||||
// This function assumes the "SHOW MEASUREMENT" tokens have already been consumed.
|
||||
func (p *Parser) parseShowMeasurementCardinalityStatement(exact bool) (Statement, error) {
|
||||
stmt := &ShowMeasurementCardinalityStatement{Exact: exact}
|
||||
|
||||
|
@ -1030,11 +1024,6 @@ func (p *Parser) parseShowMeasurementCardinalityStatement(exact bool) (Statement
|
|||
p.Unscan()
|
||||
}
|
||||
|
||||
// Estimation command doesn't support any further versions of the command.
|
||||
if !stmt.Exact {
|
||||
return stmt, nil
|
||||
}
|
||||
|
||||
// Parse optional FROM.
|
||||
if tok, _, _ := p.ScanIgnoreWhitespace(); tok == FROM {
|
||||
if stmt.Sources, err = p.parseSources(false); err != nil {
|
||||
|
@ -1156,15 +1145,20 @@ func (p *Parser) parseShowRetentionPoliciesStatement() (*ShowRetentionPoliciesSt
|
|||
// This function assumes the "SHOW TAG KEY" tokens have already been consumed.
|
||||
func (p *Parser) parseShowTagKeyCardinalityStatement() (Statement, error) {
|
||||
var err error
|
||||
stmt := &ShowTagKeyCardinalityStatement{}
|
||||
|
||||
if tok, pos, lit := p.ScanIgnoreWhitespace(); tok != EXACT {
|
||||
return nil, newParseError(tokstr(tok, lit), []string{"EXACT"}, pos)
|
||||
var exactCardinality bool
|
||||
requiredTokens := []string{"EXACT", "CARDINALITY"}
|
||||
if tok, _, _ := p.ScanIgnoreWhitespace(); tok == EXACT {
|
||||
exactCardinality = true
|
||||
requiredTokens = requiredTokens[1:]
|
||||
} else {
|
||||
p.Unscan()
|
||||
}
|
||||
|
||||
stmt := &ShowTagKeyCardinalityStatement{Exact: exactCardinality}
|
||||
|
||||
// Parse remaining CARDINALITY token
|
||||
if tok, pos, lit := p.ScanIgnoreWhitespace(); tok != CARDINALITY {
|
||||
return nil, newParseError(tokstr(tok, lit), []string{"CARDINALITY"}, pos)
|
||||
return nil, newParseError(tokstr(tok, lit), requiredTokens, pos)
|
||||
}
|
||||
|
||||
// Parse optional ON clause.
|
||||
|
@ -1271,7 +1265,9 @@ func (p *Parser) parseShowTagValuesStatement() (Statement, error) {
|
|||
var err error
|
||||
|
||||
if tok, _, _ := p.ScanIgnoreWhitespace(); tok == EXACT {
|
||||
return p.parseShowTagValuesCardinalityStatement()
|
||||
return p.parseShowTagValuesCardinalityStatement(true)
|
||||
} else if tok == CARDINALITY {
|
||||
return p.parseShowTagValuesCardinalityStatement(false)
|
||||
}
|
||||
p.Unscan()
|
||||
|
||||
|
@ -1323,14 +1319,16 @@ func (p *Parser) parseShowTagValuesStatement() (Statement, error) {
|
|||
return stmt, nil
|
||||
}
|
||||
|
||||
// This function assumes the "SHOW TAG VALUES EXACT" tokens have already been consumed.
|
||||
func (p *Parser) parseShowTagValuesCardinalityStatement() (Statement, error) {
|
||||
// This function assumes the "SHOW TAG VALUES" tokens have already been consumed.
|
||||
func (p *Parser) parseShowTagValuesCardinalityStatement(exact bool) (Statement, error) {
|
||||
var err error
|
||||
stmt := &ShowTagValuesCardinalityStatement{}
|
||||
stmt := &ShowTagValuesCardinalityStatement{Exact: exact}
|
||||
|
||||
// Parse remaining CARDINALITY token
|
||||
if tok, pos, lit := p.ScanIgnoreWhitespace(); tok != CARDINALITY {
|
||||
return nil, newParseError(tokstr(tok, lit), []string{"CARDINALITY"}, pos)
|
||||
if stmt.Exact {
|
||||
// Parse remaining CARDINALITY token
|
||||
if tok, pos, lit := p.ScanIgnoreWhitespace(); tok != CARDINALITY {
|
||||
return nil, newParseError(tokstr(tok, lit), []string{"CARDINALITY"}, pos)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse optional ON clause.
|
||||
|
@ -1376,7 +1374,7 @@ func (p *Parser) parseShowTagValuesCardinalityStatement() (Statement, error) {
|
|||
return stmt, nil
|
||||
}
|
||||
|
||||
// parseTagKeys parses a string and returns a list of tag keys.
|
||||
// parseTagKeys pa³rses a string and returns a list of tag keys.
|
||||
func (p *Parser) parseTagKeyExpr() (Token, Literal, error) {
|
||||
var err error
|
||||
|
||||
|
@ -1438,23 +1436,23 @@ func (p *Parser) parseShowSubscriptionsStatement() (*ShowSubscriptionsStatement,
|
|||
return stmt, nil
|
||||
}
|
||||
|
||||
// parseShowFieldKeyStatement parses a string and returns a Statement.
|
||||
// This function assumes the "SHOW FIELD KEY" tokens have already been consumed.
|
||||
func (p *Parser) parseShowFieldKeyStatement() (Statement, error) {
|
||||
if tok, pos, lit := p.ScanIgnoreWhitespace(); tok != EXACT {
|
||||
return nil, newParseError(tokstr(tok, lit), []string{"EXACT"}, pos)
|
||||
}
|
||||
return p.parseShowFieldKeyCardinalityStatement()
|
||||
}
|
||||
|
||||
// This function assumes the "SHOW FIELD KEY EXACT" tokens have already been consumed.
|
||||
func (p *Parser) parseShowFieldKeyCardinalityStatement() (Statement, error) {
|
||||
var err error
|
||||
stmt := &ShowFieldKeyCardinalityStatement{}
|
||||
var exactCardinality bool
|
||||
requiredTokens := []string{"EXACT", "CARDINALITY"}
|
||||
if tok, _, _ := p.ScanIgnoreWhitespace(); tok == EXACT {
|
||||
exactCardinality = true
|
||||
requiredTokens = requiredTokens[1:]
|
||||
} else {
|
||||
p.Unscan()
|
||||
}
|
||||
|
||||
stmt := &ShowFieldKeyCardinalityStatement{Exact: exactCardinality}
|
||||
|
||||
// Parse remaining CARDINALITY token
|
||||
if tok, pos, lit := p.ScanIgnoreWhitespace(); tok != CARDINALITY {
|
||||
return nil, newParseError(tokstr(tok, lit), []string{"CARDINALITY"}, pos)
|
||||
return nil, newParseError(tokstr(tok, lit), requiredTokens, pos)
|
||||
}
|
||||
|
||||
// Parse optional ON clause.
|
||||
|
|
|
@ -1802,17 +1802,78 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
Database: "db0",
|
||||
},
|
||||
},
|
||||
// SHOW TAG KEY CARDINALITY statement
|
||||
{
|
||||
s: `SHOW TAG KEY CARDINALITY`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY CARDINALITY FROM cpu
|
||||
{
|
||||
s: `SHOW TAG KEY CARDINALITY FROM cpu`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{
|
||||
Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}},
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY CARDINALITY ON db0
|
||||
{
|
||||
s: `SHOW TAG KEY CARDINALITY ON db0`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{
|
||||
Database: "db0",
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY CARDINALITY FROM /<regex>/
|
||||
{
|
||||
s: `SHOW TAG KEY CARDINALITY FROM /[cg]pu/`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{
|
||||
Sources: []influxql.Source{
|
||||
&influxql.Measurement{
|
||||
Regex: &influxql.RegexLiteral{Val: regexp.MustCompile(`[cg]pu`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY CARDINALITY with OFFSET 0
|
||||
{
|
||||
s: `SHOW TAG KEY CARDINALITY OFFSET 0`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{Offset: 0},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY CARDINALITY with LIMIT 2 OFFSET 0
|
||||
{
|
||||
s: `SHOW TAG KEY CARDINALITY LIMIT 2 OFFSET 0`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{Offset: 0, Limit: 2},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY CARDINALITY WHERE with ORDER BY and LIMIT
|
||||
{
|
||||
s: `SHOW TAG KEY CARDINALITY WHERE region = 'order by desc' LIMIT 10`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{
|
||||
Condition: &influxql.BinaryExpr{
|
||||
Op: influxql.EQ,
|
||||
LHS: &influxql.VarRef{Val: "region"},
|
||||
RHS: &influxql.StringLiteral{Val: "order by desc"},
|
||||
},
|
||||
Limit: 10,
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY EXACT CARDINALITY statement
|
||||
{
|
||||
s: `SHOW TAG KEY EXACT CARDINALITY`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{},
|
||||
s: `SHOW TAG KEY EXACT CARDINALITY`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY EXACT CARDINALITY FROM cpu
|
||||
{
|
||||
s: `SHOW TAG KEY EXACT CARDINALITY FROM cpu`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}},
|
||||
},
|
||||
},
|
||||
|
@ -1821,6 +1882,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW TAG KEY EXACT CARDINALITY ON db0`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Database: "db0",
|
||||
},
|
||||
},
|
||||
|
@ -1829,6 +1891,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW TAG KEY EXACT CARDINALITY FROM /[cg]pu/`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Sources: []influxql.Source{
|
||||
&influxql.Measurement{
|
||||
Regex: &influxql.RegexLiteral{Val: regexp.MustCompile(`[cg]pu`)},
|
||||
|
@ -1840,19 +1903,20 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
// SHOW TAG KEY EXACT CARDINALITY with OFFSET 0
|
||||
{
|
||||
s: `SHOW TAG KEY EXACT CARDINALITY OFFSET 0`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{Offset: 0},
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{Exact: true, Offset: 0},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY EXACT CARDINALITY with LIMIT 2 OFFSET 0
|
||||
{
|
||||
s: `SHOW TAG KEY EXACT CARDINALITY LIMIT 2 OFFSET 0`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{Offset: 0, Limit: 2},
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{Exact: true, Offset: 0, Limit: 2},
|
||||
},
|
||||
|
||||
// SHOW TAG KEY EXACT CARDINALITY WHERE with ORDER BY and LIMIT
|
||||
{
|
||||
s: `SHOW TAG KEY EXACT CARDINALITY WHERE region = 'order by desc' LIMIT 10`,
|
||||
stmt: &influxql.ShowTagKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Condition: &influxql.BinaryExpr{
|
||||
Op: influxql.EQ,
|
||||
LHS: &influxql.VarRef{Val: "region"},
|
||||
|
@ -2091,10 +2155,90 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
},
|
||||
},
|
||||
|
||||
// SHOW TAG VALUES CARDINALITY statement
|
||||
{
|
||||
s: `SHOW TAG VALUES CARDINALITY WITH KEY = host`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG VALUES CARDINALITY FROM cpu
|
||||
{
|
||||
s: `SHOW TAG VALUES CARDINALITY FROM cpu WITH KEY = host`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}},
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG VALUES CARDINALITY ON db0
|
||||
{
|
||||
s: `SHOW TAG VALUES CARDINALITY ON db0 WITH KEY = host`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Database: "db0",
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG VALUES CARDINALITY FROM /<regex>/
|
||||
{
|
||||
s: `SHOW TAG VALUES CARDINALITY FROM /[cg]pu/ WITH KEY = host`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Sources: []influxql.Source{
|
||||
&influxql.Measurement{
|
||||
Regex: &influxql.RegexLiteral{Val: regexp.MustCompile(`[cg]pu`)},
|
||||
},
|
||||
},
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG VALUES CARDINALITY with OFFSET 0
|
||||
{
|
||||
s: `SHOW TAG VALUES CARDINALITY WITH KEY = host OFFSET 0`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
Offset: 0,
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG VALUES CARDINALITY with LIMIT 2 OFFSET 0
|
||||
{
|
||||
s: `SHOW TAG VALUES CARDINALITY WITH KEY = host LIMIT 2 OFFSET 0`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
Offset: 0,
|
||||
Limit: 2,
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG VALUES CARDINALITY WHERE with ORDER BY and LIMIT
|
||||
{
|
||||
s: `SHOW TAG VALUES CARDINALITY WITH KEY = host WHERE region = 'order by desc' LIMIT 10`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
Condition: &influxql.BinaryExpr{
|
||||
Op: influxql.EQ,
|
||||
LHS: &influxql.VarRef{Val: "region"},
|
||||
RHS: &influxql.StringLiteral{Val: "order by desc"},
|
||||
},
|
||||
Limit: 10,
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW TAG VALUES EXACT CARDINALITY statement
|
||||
{
|
||||
s: `SHOW TAG VALUES EXACT CARDINALITY WITH KEY = host`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Exact: true,
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
},
|
||||
|
@ -2104,6 +2248,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW TAG VALUES EXACT CARDINALITY FROM cpu WITH KEY = host`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Exact: true,
|
||||
Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}},
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
|
@ -2114,6 +2259,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW TAG VALUES EXACT CARDINALITY ON db0 WITH KEY = host`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Exact: true,
|
||||
Database: "db0",
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
|
@ -2124,6 +2270,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW TAG VALUES EXACT CARDINALITY FROM /[cg]pu/ WITH KEY = host`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Exact: true,
|
||||
Sources: []influxql.Source{
|
||||
&influxql.Measurement{
|
||||
Regex: &influxql.RegexLiteral{Val: regexp.MustCompile(`[cg]pu`)},
|
||||
|
@ -2138,6 +2285,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW TAG VALUES EXACT CARDINALITY WITH KEY = host OFFSET 0`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Exact: true,
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
Offset: 0,
|
||||
|
@ -2148,6 +2296,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW TAG VALUES EXACT CARDINALITY WITH KEY = host LIMIT 2 OFFSET 0`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Exact: true,
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
Offset: 0,
|
||||
|
@ -2159,6 +2308,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW TAG VALUES EXACT CARDINALITY WITH KEY = host WHERE region = 'order by desc' LIMIT 10`,
|
||||
stmt: &influxql.ShowTagValuesCardinalityStatement{
|
||||
Exact: true,
|
||||
Op: influxql.EQ,
|
||||
TagKeyExpr: &influxql.StringLiteral{Val: "host"},
|
||||
Condition: &influxql.BinaryExpr{
|
||||
|
@ -2207,16 +2357,83 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
},
|
||||
},
|
||||
|
||||
// SHOW FIELD KEY CARDINALITY statement
|
||||
{
|
||||
s: `SHOW FIELD KEY CARDINALITY`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{},
|
||||
},
|
||||
|
||||
// SHOW FIELD KEY CARDINALITY FROM cpu
|
||||
{
|
||||
s: `SHOW FIELD KEY CARDINALITY FROM cpu`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}},
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW FIELD KEY CARDINALITY ON db0
|
||||
{
|
||||
s: `SHOW FIELD KEY CARDINALITY ON db0`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Database: "db0",
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW FIELD KEY CARDINALITY FROM /<regex>/
|
||||
{
|
||||
s: `SHOW FIELD KEY CARDINALITY FROM /[cg]pu/`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Sources: []influxql.Source{
|
||||
&influxql.Measurement{
|
||||
Regex: &influxql.RegexLiteral{Val: regexp.MustCompile(`[cg]pu`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW FIELD KEY CARDINALITY with OFFSET 0
|
||||
{
|
||||
s: `SHOW FIELD KEY CARDINALITY OFFSET 0`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Offset: 0,
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW FIELD KEY CARDINALITY with LIMIT 2 OFFSET 0
|
||||
{
|
||||
s: `SHOW FIELD KEY CARDINALITY LIMIT 2 OFFSET 0`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Offset: 0,
|
||||
Limit: 2,
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW FIELD KEY CARDINALITY WHERE with ORDER BY and LIMIT
|
||||
{
|
||||
s: `SHOW FIELD KEY CARDINALITY WHERE region = 'order by desc' LIMIT 10`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Condition: &influxql.BinaryExpr{
|
||||
Op: influxql.EQ,
|
||||
LHS: &influxql.VarRef{Val: "region"},
|
||||
RHS: &influxql.StringLiteral{Val: "order by desc"},
|
||||
},
|
||||
Limit: 10,
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW FIELD KEY EXACT CARDINALITY statement
|
||||
{
|
||||
s: `SHOW FIELD KEY EXACT CARDINALITY`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{},
|
||||
s: `SHOW FIELD KEY EXACT CARDINALITY`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
},
|
||||
},
|
||||
|
||||
// SHOW FIELD KEY EXACT CARDINALITY FROM cpu
|
||||
{
|
||||
s: `SHOW FIELD KEY EXACT CARDINALITY FROM cpu`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}},
|
||||
},
|
||||
},
|
||||
|
@ -2225,6 +2442,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW FIELD KEY EXACT CARDINALITY ON db0`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Database: "db0",
|
||||
},
|
||||
},
|
||||
|
@ -2233,6 +2451,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW FIELD KEY EXACT CARDINALITY FROM /[cg]pu/`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Sources: []influxql.Source{
|
||||
&influxql.Measurement{
|
||||
Regex: &influxql.RegexLiteral{Val: regexp.MustCompile(`[cg]pu`)},
|
||||
|
@ -2245,6 +2464,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW FIELD KEY EXACT CARDINALITY OFFSET 0`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Offset: 0,
|
||||
},
|
||||
},
|
||||
|
@ -2253,6 +2473,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW FIELD KEY EXACT CARDINALITY LIMIT 2 OFFSET 0`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Offset: 0,
|
||||
Limit: 2,
|
||||
},
|
||||
|
@ -2262,6 +2483,7 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{
|
||||
s: `SHOW FIELD KEY EXACT CARDINALITY WHERE region = 'order by desc' LIMIT 10`,
|
||||
stmt: &influxql.ShowFieldKeyCardinalityStatement{
|
||||
Exact: true,
|
||||
Condition: &influxql.BinaryExpr{
|
||||
Op: influxql.EQ,
|
||||
LHS: &influxql.VarRef{Val: "region"},
|
||||
|
@ -2270,7 +2492,6 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
Limit: 10,
|
||||
},
|
||||
},
|
||||
|
||||
// DELETE statement
|
||||
{
|
||||
s: `DELETE FROM src`,
|
||||
|
|
|
@ -111,7 +111,10 @@ func rewriteShowMeasurementsStatement(stmt *ShowMeasurementsStatement) (Statemen
|
|||
}
|
||||
|
||||
func rewriteShowMeasurementCardinalityStatement(stmt *ShowMeasurementCardinalityStatement) (Statement, error) {
|
||||
if !stmt.Exact { // Use cardinality estimation and don't rewrite.
|
||||
// TODO(edd): currently we only support cardinality estimation for certain
|
||||
// types of query. As the estimation coverage is expanded, this condition
|
||||
// will become less strict.
|
||||
if !stmt.Exact && stmt.Sources == nil && stmt.Condition == nil && stmt.Dimensions == nil && stmt.Limit == 0 && stmt.Offset == 0 {
|
||||
return stmt, nil
|
||||
}
|
||||
|
||||
|
@ -170,7 +173,10 @@ func rewriteShowSeriesStatement(stmt *ShowSeriesStatement) (Statement, error) {
|
|||
}
|
||||
|
||||
func rewriteShowSeriesCardinalityStatement(stmt *ShowSeriesCardinalityStatement) (Statement, error) {
|
||||
if !stmt.Exact {
|
||||
// TODO(edd): currently we only support cardinality estimation for certain
|
||||
// types of query. As the estimation coverage is expanded, this condition
|
||||
// will become less strict.
|
||||
if !stmt.Exact && stmt.Sources == nil && stmt.Condition == nil && stmt.Dimensions == nil && stmt.Limit == 0 && stmt.Offset == 0 {
|
||||
return stmt, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -7217,6 +7218,76 @@ func TestServer_Query_ShowSeries(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestServer_Query_ShowSeriesCardinalityEstimation(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := OpenServer(NewConfig())
|
||||
defer s.Close()
|
||||
|
||||
if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicySpec("rp0", 1, 0), true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
test := NewTest("db0", "rp0")
|
||||
test.writes = make(Writes, 0, 10)
|
||||
// Add 1,000,000 series.
|
||||
for j := 0; j < cap(test.writes); j++ {
|
||||
writes := make([]string, 0, 50000)
|
||||
for i := 0; i < cap(writes); i++ {
|
||||
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()))
|
||||
}
|
||||
test.writes = append(test.writes, &Write{data: strings.Join(writes, "\n")})
|
||||
}
|
||||
|
||||
// These queries use index sketches to estimate cardinality.
|
||||
test.addQueries([]*Query{
|
||||
&Query{
|
||||
name: `show series cardinality`,
|
||||
command: "SHOW SERIES CARDINALITY",
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show series cardinality on db0`,
|
||||
command: "SHOW SERIES CARDINALITY ON db0",
|
||||
},
|
||||
}...)
|
||||
|
||||
for i, query := range test.queries {
|
||||
t.Run(query.name, func(t *testing.T) {
|
||||
if i == 0 {
|
||||
if err := test.init(s); err != nil {
|
||||
t.Fatalf("test init failed: %s", err)
|
||||
}
|
||||
}
|
||||
if query.skip {
|
||||
t.Skipf("SKIP:: %s", query.name)
|
||||
}
|
||||
if err := query.Execute(s); err != nil {
|
||||
t.Error(query.Error(err))
|
||||
}
|
||||
|
||||
// Manually parse result rather than comparing results string, as
|
||||
// results are not deterministic.
|
||||
got := struct {
|
||||
Results []struct {
|
||||
Series []struct {
|
||||
Values [][]int
|
||||
}
|
||||
}
|
||||
}{}
|
||||
|
||||
t.Log(query.act)
|
||||
if err := json.Unmarshal([]byte(query.act), &got); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
cardinality := got.Results[0].Series[0].Values[0][0]
|
||||
if cardinality < 450000 || cardinality > 550000 {
|
||||
t.Errorf("got cardinality %d, which is 10%% or more away from expected estimation of 500,000", cardinality)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_Query_ShowSeriesExactCardinality(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := OpenServer(NewConfig())
|
||||
|
@ -7242,6 +7313,48 @@ func TestServer_Query_ShowSeriesExactCardinality(t *testing.T) {
|
|||
}
|
||||
|
||||
test.addQueries([]*Query{
|
||||
&Query{
|
||||
name: `show series cardinality from measurement`,
|
||||
command: "SHOW SERIES CARDINALITY FROM cpu",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[4]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show series cardinality from regular expression`,
|
||||
command: "SHOW SERIES CARDINALITY FROM /[cg]pu/",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[4]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show series cardinality with where tag`,
|
||||
command: "SHOW SERIES CARDINALITY WHERE region = 'uswest'",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[1]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show series cardinality where tag matches regular expression`,
|
||||
command: "SHOW SERIES CARDINALITY WHERE region =~ /ca.*/",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show series cardinality`,
|
||||
command: "SHOW SERIES CARDINALITY WHERE host !~ /server0[12]/",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show series cardinality with from and where`,
|
||||
command: "SHOW SERIES CARDINALITY FROM cpu WHERE region = 'useast'",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show series cardinality with WHERE time should fail`,
|
||||
command: "SHOW SERIES CARDINALITY WHERE time > now() - 1h",
|
||||
exp: `{"results":[{"statement_id":0,"error":"SHOW SERIES EXACT CARDINALITY doesn't support time in WHERE clause"}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show series exact cardinality`,
|
||||
command: "SHOW SERIES EXACT CARDINALITY",
|
||||
|
@ -7434,7 +7547,81 @@ func TestServer_Query_ShowMeasurements(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestServer_Query_ShowMeasurementCardinality(t *testing.T) {
|
||||
func TestServer_Query_ShowMeasurementCardinalityEstimation(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping expensive test")
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
s := OpenServer(NewConfig())
|
||||
defer s.Close()
|
||||
|
||||
if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicySpec("rp0", 1, 0), true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
test := NewTest("db0", "rp0")
|
||||
test.writes = make(Writes, 0, 10)
|
||||
// Add 1,000,000 series.
|
||||
for j := 0; j < cap(test.writes); j++ {
|
||||
writes := make([]string, 0, 50000)
|
||||
for i := 0; i < cap(writes); i++ {
|
||||
writes = append(writes, fmt.Sprintf(`cpu-%d-s%d v=1 %d`, j, i, mustParseTime(time.RFC3339Nano, "2009-11-10T23:00:01Z").UnixNano()))
|
||||
}
|
||||
test.writes = append(test.writes, &Write{data: strings.Join(writes, "\n")})
|
||||
}
|
||||
|
||||
// These queries use index sketches to estimate cardinality.
|
||||
test.addQueries([]*Query{
|
||||
&Query{
|
||||
name: `show measurement cardinality`,
|
||||
command: "SHOW MEASUREMENT CARDINALITY",
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show measurement cardinality on db0`,
|
||||
command: "SHOW MEASUREMENT CARDINALITY ON db0",
|
||||
},
|
||||
}...)
|
||||
|
||||
for i, query := range test.queries {
|
||||
t.Run(query.name, func(t *testing.T) {
|
||||
if i == 0 {
|
||||
if err := test.init(s); err != nil {
|
||||
t.Fatalf("test init failed: %s", err)
|
||||
}
|
||||
}
|
||||
if query.skip {
|
||||
t.Skipf("SKIP:: %s", query.name)
|
||||
}
|
||||
if err := query.Execute(s); err != nil {
|
||||
t.Error(query.Error(err))
|
||||
}
|
||||
|
||||
// Manually parse result rather than comparing results string, as
|
||||
// results are not deterministic.
|
||||
got := struct {
|
||||
Results []struct {
|
||||
Series []struct {
|
||||
Values [][]int
|
||||
}
|
||||
}
|
||||
}{}
|
||||
|
||||
t.Log(query.act)
|
||||
if err := json.Unmarshal([]byte(query.act), &got); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
cardinality := got.Results[0].Series[0].Values[0][0]
|
||||
if cardinality < 450000 || cardinality > 550000 {
|
||||
t.Errorf("got cardinality %d, which is 10%% or more away from expected estimation of 500,000", cardinality)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_Query_ShowMeasurementExactCardinality(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := OpenServer(NewConfig())
|
||||
defer s.Close()
|
||||
|
@ -7460,15 +7647,34 @@ func TestServer_Query_ShowMeasurementCardinality(t *testing.T) {
|
|||
|
||||
test.addQueries([]*Query{
|
||||
&Query{
|
||||
name: `show measurement cardinality`,
|
||||
command: "SHOW MEASUREMENT CARDINALITY",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"columns":["cardinality"],"values":[[3]]}]}]}`,
|
||||
name: `show measurement cardinality using FROM and regex`,
|
||||
command: "SHOW MEASUREMENT CARDINALITY FROM /[cg]pu/",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show measurement cardinality on db0`,
|
||||
command: "SHOW MEASUREMENT CARDINALITY ON db0",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"columns":["cardinality"],"values":[[3]]}]}]}`,
|
||||
name: `show measurement cardinality using FROM and regex - no matches`,
|
||||
command: "SHOW MEASUREMENT CARDINALITY FROM /.*zzzzz.*/",
|
||||
exp: `{"results":[{"statement_id":0}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show measurement cardinality where tag matches regular expression`,
|
||||
command: "SHOW MEASUREMENT CARDINALITY WHERE region =~ /ca.*/",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show measurement cardinality where tag does not match a regular expression`,
|
||||
command: "SHOW MEASUREMENT CARDINALITY WHERE region !~ /ca.*/",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show measurement cardinality with time in WHERE clauses errors`,
|
||||
command: `SHOW MEASUREMENT CARDINALITY WHERE time > now() - 1h`,
|
||||
exp: `{"results":[{"statement_id":0,"error":"SHOW MEASUREMENT EXACT CARDINALITY doesn't support time in WHERE clause"}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show measurement exact cardinality`,
|
||||
|
@ -7700,6 +7906,41 @@ func TestServer_Query_ShowTagKeyCardinality(t *testing.T) {
|
|||
}
|
||||
|
||||
test.addQueries([]*Query{
|
||||
&Query{
|
||||
name: `show tag key cardinality`,
|
||||
command: "SHOW TAG KEY CARDINALITY",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"disk","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag key cardinality on db0`,
|
||||
command: "SHOW TAG KEY CARDINALITY ON db0",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"disk","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`,
|
||||
},
|
||||
&Query{
|
||||
name: "show tag key cardinality from",
|
||||
command: "SHOW TAG KEY CARDINALITY FROM cpu",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: "show tag key cardinality from regex",
|
||||
command: "SHOW TAG KEY CARDINALITY FROM /[cg]pu/",
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: "show tag key cardinality measurement not found",
|
||||
command: "SHOW TAG KEY CARDINALITY FROM doesntexist",
|
||||
exp: `{"results":[{"statement_id":0}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: "show tag key cardinality with time in WHERE clause errors",
|
||||
command: "SHOW TAG KEY CARDINALITY FROM cpu WHERE time > now() - 1h",
|
||||
exp: `{"results":[{"statement_id":0,"error":"SHOW TAG KEY EXACT CARDINALITY doesn't support time in WHERE clause"}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag key exact cardinality`,
|
||||
command: "SHOW TAG KEY EXACT CARDINALITY",
|
||||
|
@ -7735,6 +7976,48 @@ func TestServer_Query_ShowTagKeyCardinality(t *testing.T) {
|
|||
exp: `{"results":[{"statement_id":0,"error":"SHOW TAG KEY EXACT CARDINALITY doesn't support time in WHERE clause"}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag values cardinality with key and where matches the regular expression`,
|
||||
command: `SHOW TAG VALUES CARDINALITY WITH KEY = host WHERE region =~ /ca.*/`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag values cardinality with key and where does not match the regular expression`,
|
||||
command: `SHOW TAG VALUES CARDINALITY WITH KEY = region WHERE host !~ /server0[12]/`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag values cardinality with key and where partially matches the regular expression`,
|
||||
command: `SHOW TAG VALUES CARDINALITY WITH KEY = host WHERE region =~ /us/`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag values cardinality with key and where partially does not match the regular expression`,
|
||||
command: `SHOW TAG VALUES CARDINALITY WITH KEY = host WHERE region !~ /us/`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"disk","columns":["count"],"values":[[1]]},{"name":"gpu","columns":["count"],"values":[[1]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag values cardinality with key in and where does not match the regular expression`,
|
||||
command: `SHOW TAG VALUES CARDINALITY FROM cpu WITH KEY IN (host, region) WHERE region = 'uswest'`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag values cardinality with key regex and where does not match the regular expression`,
|
||||
command: `SHOW TAG VALUES CARDINALITY FROM cpu WITH KEY =~ /(host|region)/ WHERE region = 'uswest'`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag values cardinality with key and measurement matches regular expression`,
|
||||
command: `SHOW TAG VALUES CARDINALITY FROM /[cg]pu/ WITH KEY = host`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[2]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show tag values exact cardinality with key and where matches the regular expression`,
|
||||
command: `SHOW TAG VALUES EXACT CARDINALITY WITH KEY = host WHERE region =~ /ca.*/`,
|
||||
|
@ -7887,6 +8170,24 @@ func TestServer_Query_ShowFieldKeyCardinality(t *testing.T) {
|
|||
}
|
||||
|
||||
test.addQueries([]*Query{
|
||||
&Query{
|
||||
name: `show field key cardinality`,
|
||||
command: `SHOW FIELD KEY CARDINALITY`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[3]]},{"name":"disk","columns":["count"],"values":[[2]]},{"name":"gpu","columns":["count"],"values":[[4]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show field key cardinality from measurement`,
|
||||
command: `SHOW FIELD KEY CARDINALITY FROM cpu`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[3]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show field key cardinality measurement with regex`,
|
||||
command: `SHOW FIELD KEY CARDINALITY FROM /[cg]pu/`,
|
||||
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["count"],"values":[[3]]},{"name":"gpu","columns":["count"],"values":[[4]]}]}]}`,
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
},
|
||||
&Query{
|
||||
name: `show field key exact cardinality`,
|
||||
command: `SHOW FIELD KEY EXACT CARDINALITY`,
|
||||
|
|
Loading…
Reference in New Issue