forked from timescale/tsbs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
345 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package clickhouse | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/timescale/tsbs/cmd/tsbs_generate_queries/uses/dea" | ||
"github.com/timescale/tsbs/pkg/query" | ||
) | ||
|
||
// Devops produces ClickHouse-specific queries for all the devops query types. | ||
type DEA struct { | ||
*dea.Core | ||
*BaseGenerator | ||
} | ||
|
||
const ( | ||
Json string = "json" | ||
Map string = "map" | ||
) | ||
|
||
func Must[T any](v T, err error) T { | ||
if err != nil { | ||
panic(err) | ||
} | ||
return v | ||
} | ||
|
||
func (d *DEA) getJSONProperty(key string) string { | ||
return fmt.Sprintf("simpleJSONExtractRaw(propertiesJson, '%s')", key) | ||
} | ||
|
||
func (d *DEA) getMapProperty(key string) string { | ||
return fmt.Sprintf("propertiesMap['%s']", key) | ||
} | ||
|
||
func (d *DEA) getProperty(key string) string { | ||
switch d.PropertyAccessMode { | ||
case Json: | ||
return d.getJSONProperty(key) | ||
case Map: | ||
return d.getMapProperty(key) | ||
default: | ||
panic(fmt.Sprintf("unknown access mode %s", d.PropertyAccessMode)) | ||
} | ||
} | ||
|
||
func (d *DEA) getPropertyAlias(property string) string { | ||
return fmt.Sprintf("a_%s", property) | ||
} | ||
|
||
func (d *DEA) getAliasedProperties(keys []string) []string { | ||
aliasedProps := make([]string, len(keys)) | ||
|
||
for i := range keys { | ||
aliasedProps[i] = fmt.Sprintf("%s as %s", d.getProperty(keys[i]), d.getPropertyAlias(keys[i])) | ||
} | ||
|
||
return aliasedProps | ||
} | ||
|
||
func (d *DEA) NestedWhere(qi query.Query, nProperties int) { | ||
randomProperties, err := d.GetRandomProperties(4, dea.AvailableStrProperties) | ||
panicIfErr(err) | ||
|
||
selectClauses := strings.Join(d.getAliasedProperties(randomProperties), ", ") | ||
|
||
whereClauses := fmt.Sprintf("%s = '%s' AND %s != '' AND (%s LIKE '%%%s%%' OR %s LIKE '%%%s')", | ||
d.getPropertyAlias(randomProperties[0]), | ||
Must(d.GetRandomPropertyValue(randomProperties[0])), | ||
d.getPropertyAlias(randomProperties[1]), | ||
d.getPropertyAlias(randomProperties[2]), | ||
Must(d.GetRandomPropertyValue(randomProperties[2]))[2:6], | ||
d.getPropertyAlias(randomProperties[3]), | ||
Must(d.GetRandomPropertyValue(randomProperties[3]))[2:]) | ||
|
||
// GetRandomSubsetPerm - use this | ||
|
||
sql := fmt.Sprintf(` | ||
SELECT toStartOfHour(created_at) AS hour, %s FROM events WHERE %s | ||
`, selectClauses, whereClauses) | ||
|
||
humanLabel := "ClickHouse nested and dynamic" | ||
humanDesc := fmt.Sprintf("%s: nested where query with dynamic data access", humanLabel) | ||
d.fillInQuery(qi, humanLabel, humanDesc, dea.TableName, sql) | ||
} | ||
|
||
func (d *DEA) EventHistogram(qi query.Query) { | ||
sql := fmt.Sprintf(` | ||
SELECT | ||
toDate(timestamp, 'Europe/Prague') as day, | ||
uniq(user_id) as visitors, | ||
count() as cnt | ||
FROM events | ||
WHERE | ||
name LIKE 'package_changed_to%' | ||
AND tenant_id = '57e8dcb8673eec55468b4567' | ||
AND timestamp >= now() - INTERVAL 30 DAY | ||
GROUP BY | ||
day | ||
ORDER BY | ||
day WITH FILL | ||
FROM toDate(now() - INTERVAL 30 DAY, 'Europe/Prague') | ||
TO toDate(now(), 'Europe/Prague') | ||
`) | ||
|
||
d.fillInQuery(qi, "ClickHouse Event histogram", "Clickhouse Event histogram", dea.TableName, sql) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package dea | ||
|
||
import ( | ||
"fmt" | ||
"math/rand" | ||
"time" | ||
|
||
"github.com/timescale/tsbs/cmd/tsbs_generate_queries/uses/common" | ||
"github.com/timescale/tsbs/pkg/query" | ||
) | ||
|
||
const ( | ||
TableName = "events" | ||
|
||
LabelNestedWhere = "nested-where" | ||
) | ||
|
||
const ( | ||
UrlProperty = "url" | ||
EmailProperty = "email" | ||
NameProperty = "name" | ||
PhoneProperty = "phone" | ||
FavoriteNumberProperty = "age" | ||
) | ||
|
||
const ( | ||
NavigationEvent = "navigation" | ||
) | ||
|
||
var ( | ||
AvailableStrProperties = []string{UrlProperty, EmailProperty, NameProperty, PhoneProperty} | ||
AvailableStrPropertyValues = map[string][]string{ | ||
UrlProperty: {"https://www.seznam.cz"}, | ||
EmailProperty: {"[email protected]"}, | ||
NameProperty: {"john doe"}, | ||
PhoneProperty: {"+420602303222"}, | ||
} | ||
) | ||
|
||
// Core is the common component of all generators for all systems. | ||
type Core struct { | ||
*common.Core | ||
} | ||
|
||
// NewCore returns a new Core for the given time range and cardinality | ||
func NewCore(start, end time.Time, scale int) (*Core, error) { | ||
c, err := common.NewCore(start, end, scale) | ||
return &Core{Core: c}, err | ||
} | ||
|
||
type NestedWhereFiller interface { | ||
NestedWhere(query.Query, int) | ||
} | ||
|
||
func (d *Core) GetRandomProperties(n int, properties []string) ([]string, error) { | ||
if n < 1 { | ||
return nil, fmt.Errorf("number of properties cannot be < 1; got %d", n) | ||
} | ||
if n > len(properties) { | ||
return nil, fmt.Errorf("number of properties (%d) larger than total properties (%d)", n, len(properties)) | ||
} | ||
|
||
randomNumbers, err := common.GetRandomSubsetPerm(n, len(properties)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
selectedProperties := make([]string, n) | ||
for i, n := range randomNumbers { | ||
selectedProperties[i] = properties[n] | ||
} | ||
|
||
return selectedProperties, nil | ||
} | ||
|
||
func (d *Core) GetRandomPropertyValue(property string) (string, error) { | ||
if values, ok := AvailableStrPropertyValues[property]; ok { | ||
return values[rand.Intn(len(values))], nil | ||
} else { | ||
return "", fmt.Errorf("no values for %s", property) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package dea | ||
|
||
import ( | ||
"github.com/timescale/tsbs/cmd/tsbs_generate_queries/uses/common" | ||
"github.com/timescale/tsbs/cmd/tsbs_generate_queries/utils" | ||
"github.com/timescale/tsbs/pkg/query" | ||
) | ||
|
||
// NestedWhere contains info for filling in avg load queries. | ||
type NestedWhere struct { | ||
core utils.QueryGenerator | ||
} | ||
|
||
// NewNestedWhere creates a new avg load query filler. | ||
func NewNestedWhere(scale int) utils.QueryFillerMaker { | ||
return func(core utils.QueryGenerator) utils.QueryFiller { | ||
return &NestedWhere{ | ||
core: core, | ||
} | ||
} | ||
} | ||
|
||
// Fill fills in the query.Query with query details. | ||
func (i *NestedWhere) Fill(q query.Query) query.Query { | ||
fc, ok := i.core.(NestedWhereFiller) | ||
if !ok { | ||
common.PanicUnimplementedQuery(i.core) | ||
} | ||
fc.NestedWhere(q, 1) | ||
return q | ||
} |
Oops, something went wrong.