mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
fb-1075 (#2221)
* handle multi field count correctly COUNT() should ignore null values. If the data type of the expression supports an existence bitmap for the underlying FeatureBase data type we will use it to eliminate nulls from the aggregate * simplify aggregate for existence test we can use a direct != null instead of an indirect not(=null), and avoid relying on the probably-broken behavior in the executor that tries to silently fix up Row(x=3) tests on BSI fields which wanted Row(x==3). Co-authored-by: Seebs <seebs@molecula.com>
This commit is contained in:
parent
98a7129464
commit
91e3b8457a
4 changed files with 48 additions and 6 deletions
|
|
@ -1379,7 +1379,7 @@ func (h *Handler) handlePostSQL(w http.ResponseWriter, r *http.Request) {
|
|||
// Write response back to client.
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
// the pandas data frame format in json per https://molecula.atlassian.net/wiki/spaces/MOLECULA/pages/540999700/Queries
|
||||
// the pandas data frame format in json
|
||||
|
||||
// Opening bracket.
|
||||
w.Write([]byte("{"))
|
||||
|
|
|
|||
|
|
@ -28,7 +28,11 @@ func coerceValue(sourceType parser.ExprDataType, targetType parser.ExprDataType,
|
|||
return value, nil
|
||||
|
||||
case *parser.DataTypeID:
|
||||
return value, nil
|
||||
val, ok := value.(int64)
|
||||
if !ok {
|
||||
return nil, sql3.NewErrInternalf("unexpected value type '%T'", value)
|
||||
}
|
||||
return val, nil
|
||||
|
||||
case *parser.DataTypeDecimal:
|
||||
val, ok := value.(int64)
|
||||
|
|
|
|||
|
|
@ -140,14 +140,39 @@ func (i *pqlAggregateRowIter) Next(ctx context.Context) (types.Row, error) {
|
|||
|
||||
case types.AGGREGATE_COUNT:
|
||||
if cond == nil {
|
||||
cond = &pql.Call{Name: "All"}
|
||||
// COUNT() should ignore null values
|
||||
// if the data type of the expression supports an existence bitmap for
|
||||
// the underlying FeatureBase data type use it to eliminate nulls from the aggregate
|
||||
switch expr.dataType.(type) {
|
||||
case *parser.DataTypeInt, *parser.DataTypeTimestamp, *parser.DataTypeDecimal:
|
||||
cond = &pql.Call{
|
||||
Name: "Row",
|
||||
Args: map[string]interface{}{
|
||||
expr.columnName: &pql.Condition{Op: pql.NEQ, Value: nil},
|
||||
},
|
||||
}
|
||||
default:
|
||||
cond = &pql.Call{Name: "All"}
|
||||
}
|
||||
}
|
||||
|
||||
call = &pql.Call{Name: "Count", Children: []*pql.Call{cond}}
|
||||
|
||||
case types.AGGREGATE_AVG:
|
||||
if cond == nil {
|
||||
cond = &pql.Call{Name: "All"}
|
||||
// COUNT() should ignore null values
|
||||
// if the data type of the expression supports an existence bitmap for
|
||||
// the underlying FeatureBase data type use it to eliminate nulls from the aggregate
|
||||
switch expr.dataType.(type) {
|
||||
case *parser.DataTypeInt, *parser.DataTypeTimestamp, *parser.DataTypeDecimal:
|
||||
cond = &pql.Call{
|
||||
Name: "Row",
|
||||
Args: map[string]interface{}{
|
||||
expr.columnName: &pql.Condition{Op: pql.NEQ, Value: nil},
|
||||
},
|
||||
}
|
||||
default:
|
||||
cond = &pql.Call{Name: "All"}
|
||||
}
|
||||
}
|
||||
|
||||
call = &pql.Call{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"github.com/molecula/featurebase/v3/sql3/parser"
|
||||
)
|
||||
|
||||
//aggregate function tests
|
||||
// aggregate function tests
|
||||
var countTests = tableTest{
|
||||
table: tbl(
|
||||
"count_test",
|
||||
|
|
@ -50,6 +50,19 @@ var countTests = tableTest{
|
|||
),
|
||||
compare: compareExactUnordered,
|
||||
},
|
||||
{
|
||||
sqls: sqls(
|
||||
"SELECT COUNT(i1) as a, COUNT(i2) as b FROM count_test",
|
||||
),
|
||||
expHdrs: hdrs(
|
||||
hdr("a", fldTypeInt),
|
||||
hdr("b", fldTypeInt),
|
||||
),
|
||||
expRows: rows(
|
||||
row(int64(6), int64(2)),
|
||||
),
|
||||
compare: compareExactUnordered,
|
||||
},
|
||||
{
|
||||
sqls: sqls(
|
||||
"SELECT COUNT(*) + 10 - 11 * 2 AS count_rows FROM count_test",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue