Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quickfix: bool column with terms aggr #1145

Merged
merged 6 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion quesma/model/bucket_aggregations/terms.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,25 @@ func (query Terms) TranslateSqlResponseToJson(rows []model.QueryResultRow) model
for _, row := range rows {
docCount := query.docCount(row)
bucket := model.JsonMap{
"key": query.key(row),
"doc_count": docCount,
}
if query.significant {
bucket["score"] = docCount
bucket["bg_count"] = docCount
}

// response for bool keys is different
key := query.key(row)
if boolPtr, isBoolPtr := key.(*bool); isBoolPtr {
key = *boolPtr
}
if keyAsBool, ok := key.(bool); ok {
bucket["key"] = util.BoolToInt(keyAsBool)
bucket["key_as_string"] = util.BoolToString(keyAsBool)
} else {
bucket["key"] = key
}

response = append(response, bucket)
}

Expand Down
7 changes: 3 additions & 4 deletions quesma/model/pipeline_aggregations/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ func calculateResultWhenMissingCommonForDiffAggregations(ctx context.Context, pa
if row.LastColValue() != nil {
firstNonNilIndex = i + rowsWithNilValueCnt
break
} else {
resultRow := row.Copy()
resultRow.Cols[len(resultRow.Cols)-1].Value = nil
resultRows = append(resultRows, resultRow)
}
resultRow := row.Copy()
resultRow.Cols[len(resultRow.Cols)-1].Value = nil
resultRows = append(resultRows, resultRow)
}
if firstNonNilIndex == -1 {
return resultRows
Expand Down
8 changes: 1 addition & 7 deletions quesma/model/pipeline_aggregations/max_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,7 @@ func (query MaxBucket) calculateSingleMaxBucket(parentRows []model.QueryResultRo
var resultValue any
var resultKeys []any

firstNonNilIndex := -1
for i, row := range parentRows {
if row.LastColValue() != nil {
firstNonNilIndex = i
break
}
}
firstNonNilIndex := model.FirstNonNilIndex(parentRows)
if firstNonNilIndex == -1 {
resultRow := parentRows[0].Copy()
resultRow.Cols[len(resultRow.Cols)-1].Value = model.JsonMap{
Expand Down
8 changes: 1 addition & 7 deletions quesma/model/pipeline_aggregations/sum_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,7 @@ func (query SumBucket) CalculateResultWhenMissing(parentRows []model.QueryResult
func (query SumBucket) calculateSingleSumBucket(parentRows []model.QueryResultRow) model.QueryResultRow {
var resultValue any

firstNonNilIndex := -1
for i, row := range parentRows {
if row.LastColValue() != nil {
firstNonNilIndex = i
break
}
}
firstNonNilIndex := model.FirstNonNilIndex(parentRows)
if firstNonNilIndex == -1 {
resultRow := parentRows[0].Copy()
resultRow.Cols[len(resultRow.Cols)-1].Value = model.JsonMap{
Expand Down
9 changes: 9 additions & 0 deletions quesma/model/query_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,12 @@ func (r *QueryResultRow) Copy() QueryResultRow {
func (r *QueryResultRow) LastColValue() any {
return r.Cols[len(r.Cols)-1].Value
}

func FirstNonNilIndex(rows []QueryResultRow) int {
for i, row := range rows {
if row.LastColValue() != nil {
return i
}
}
return -1
}
64 changes: 64 additions & 0 deletions quesma/testdata/aggregation_requests_2.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"time"
)

var randomTrueVariableUsedBelow = true

// Goland lags a lot when you edit aggregation_requests.go file, so let's add new tests to this one.

var AggregationTests2 = []AggregationTestCase{
Expand Down Expand Up @@ -5290,6 +5292,68 @@ var AggregationTests2 = []AggregationTestCase{
LIMIT 3`},
},
{ // [77]
TestName: "terms with bool field",
QueryRequestJson: `
{
"aggs": {
"terms": {
"terms": {
"field": "Cancelled",
"size": 2
}
}
},
"size": 0,
"track_total_hits": true
}`,
// I omit "took", "timed_out", "_shards", and "hits" from the response for brevity (they can also be easily unit-tested)
ExpectedResponse: `
{
"aggregations": {
"terms": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 38654,
"buckets": [
{
"key": 0,
"key_as_string": "false",
"doc_count": 11344
},
{
"key": 1,
"key_as_string": "true",
"doc_count": 2
}
]
}
}
}`,
ExpectedPancakeResults: []model.QueryResultRow{
{Cols: []model.QueryResultCol{
model.NewQueryResultCol("aggr__terms__parent_count", int64(50000)),
model.NewQueryResultCol("aggr__terms__key_0", nil),
model.NewQueryResultCol("aggr__terms__count", int64(12000)),
}},
{Cols: []model.QueryResultCol{
model.NewQueryResultCol("aggr__terms__parent_count", int64(50000)),
model.NewQueryResultCol("aggr__terms__key_0", false),
model.NewQueryResultCol("aggr__terms__count", int64(11344)),
}},
{Cols: []model.QueryResultCol{
model.NewQueryResultCol("aggr__terms__parent_count", int64(50000)),
model.NewQueryResultCol("aggr__terms__key_0", &randomTrueVariableUsedBelow), // used here
model.NewQueryResultCol("aggr__terms__count", int64(2)),
}},
},
ExpectedPancakeSQL: `
SELECT sum(count(*)) OVER () AS "aggr__terms__parent_count",
"Cancelled" AS "aggr__terms__key_0", count(*) AS "aggr__terms__count"
FROM __quesma_table_name
GROUP BY "Cancelled" AS "aggr__terms__key_0"
ORDER BY "aggr__terms__count" DESC, "aggr__terms__key_0" ASC
LIMIT 3`,
},
{ // [78]
TestName: `Escaping of ', \, \n, and \t in some example aggregations. No tests for other escape characters, e.g. \r or 'b. Add if needed.`,
QueryRequestJson: `
{
Expand Down
6 changes: 4 additions & 2 deletions quesma/testdata/kibana-visualize/aggregation_requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,8 @@ var AggregationTests = []testdata.AggregationTestCase{
"95.0": 15480.335426897316
}
},
"key": false,
"key": 0,
"key_as_string": "false",
"doc_count": 2974
},
{
Expand Down Expand Up @@ -991,7 +992,8 @@ var AggregationTests = []testdata.AggregationTestCase{
"95.0": 14463.254101562497
}
},
"key": true,
"key": 1,
"key_as_string": "true",
"doc_count": 419
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,7 @@ var PipelineAggregationTests = []testdata.AggregationTestCase{
"key": 1714871400000,
"key_as_string": "2024-05-05T01:10:00.000"
},
{
{
"1": {
"value": 0.0
},
Expand All @@ -999,7 +999,7 @@ var PipelineAggregationTests = []testdata.AggregationTestCase{
"key": 1714872000000,
"key_as_string": "2024-05-05T01:20:00.000"
},
{
{
"1": {
"value": 0.0
},
Expand All @@ -1010,7 +1010,7 @@ var PipelineAggregationTests = []testdata.AggregationTestCase{
"key": 1714872600000,
"key_as_string": "2024-05-05T01:30:00.000"
},
{
{
"1": {
"value": 0.0
},
Expand All @@ -1021,7 +1021,7 @@ var PipelineAggregationTests = []testdata.AggregationTestCase{
"key": 1714873200000,
"key_as_string": "2024-05-05T01:40:00.000"
},
{
{
"1": {
"value": 0.0
},
Expand All @@ -1032,7 +1032,7 @@ var PipelineAggregationTests = []testdata.AggregationTestCase{
"key": 1714873800000,
"key_as_string": "2024-05-05T01:50:00.000"
},
{
{
"1": {
"value": 0.0
},
Expand Down Expand Up @@ -3345,11 +3345,13 @@ var PipelineAggregationTests = []testdata.AggregationTestCase{
"buckets": [
{
"doc_count": 260,
"key": true
"key": 1,
"key_as_string": "true"
},
{
"doc_count": 1923,
"key": false
"key": 0,
"key_as_string": "false"
}
],
"doc_count_error_upper_bound": 0,
Expand Down
14 changes: 14 additions & 0 deletions quesma/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,20 @@ func ExtractNumeric64(value any) float64 {
return asFloat64
}

func BoolToInt(b bool) int {
if b {
return 1
}
return 0
}

func BoolToString(b bool) string {
if b {
return "true"
}
return "false"
}

// SingleQuote is a simple helper function: str -> 'str'
func SingleQuote(value string) string {
return "'" + value + "'"
Expand Down
Loading