Skip to content

Commit

Permalink
pr fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
nasdf committed Sep 30, 2024
1 parent 87ecfd4 commit e779d9f
Show file tree
Hide file tree
Showing 15 changed files with 277 additions and 96 deletions.
5 changes: 3 additions & 2 deletions internal/planner/aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ func lessO[T number](a immutable.Option[T], b immutable.Option[T]) bool {
return a.Value() < b.Value()
}

func reverse[T any](original func(T, T) bool) func(T, T) bool {
// inverse returns the logical inverse of the given sort func.
func inverse[T any](original func(T, T) bool) func(T, T) bool {
return func(t1, t2 T) bool {
return !original(t1, t2)
}
Expand Down Expand Up @@ -80,7 +81,7 @@ func reduceItems[T any, V any](
if aggregateTarget.OrderBy.Conditions[0].Direction == mapper.ASC {
items = enumerable.Sort(items, less, len(source))
} else {
items = enumerable.Sort(items, reverse(less), len(source))
items = enumerable.Sort(items, inverse(less), len(source))
}
}

Expand Down
86 changes: 57 additions & 29 deletions internal/planner/max.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ type maxNode struct {
p *Planner
plan planNode

isFloat bool
isFloat bool
// virtualFieldIndex is the index of the field
// that contains the result of the aggregate.
virtualFieldIndex int
aggregateMapping []mapper.AggregateTarget

Expand Down Expand Up @@ -139,40 +141,50 @@ func (n *maxNode) Next() (bool, error) {
}
n.currentValue = n.plan.Value()

max := -math.MaxFloat64
var max *float64
for _, source := range n.aggregateMapping {
child := n.currentValue.Fields[source.Index]
collectionMax := -math.MaxFloat64
var collectionMax *float64
var err error
switch childCollection := child.(type) {
case []core.Doc:
collectionMax = reduceDocs(
childCollection,
-math.MaxFloat64,
func(childItem core.Doc, value float64) float64 {
nil,
func(childItem core.Doc, value *float64) *float64 {
childProperty := childItem.Fields[source.ChildTarget.Index]
var res float64
switch v := childProperty.(type) {
case int:
return math.Max(value, float64(v))
res = float64(v)
case int64:
return math.Max(value, float64(v))
res = float64(v)
case uint64:
return math.Max(value, float64(v))
res = float64(v)
case float64:
return math.Max(value, float64(v))
res = float64(v)
default:
return value
return nil
}
if value != nil {
res = math.Max(*value, res)
}
return &res
},
)

case []int64:
collectionMax, err = reduceItems(
childCollection,
&source,
lessN[int64],
-math.MaxFloat64,
func(childItem int64, value float64) float64 {
return math.Max(value, float64(childItem))
nil,
func(childItem int64, value *float64) *float64 {
res := float64(childItem)
if value != nil {
res = math.Max(*value, res)
}
return &res
},
)

Expand All @@ -181,12 +193,16 @@ func (n *maxNode) Next() (bool, error) {
childCollection,
&source,
lessO[int64],
-math.MaxFloat64,
func(childItem immutable.Option[int64], value float64) float64 {
nil,
func(childItem immutable.Option[int64], value *float64) *float64 {
if !childItem.HasValue() {
return value
}
return math.Max(value, float64(childItem.Value()))
res := float64(childItem.Value())
if value != nil {
res = math.Max(*value, res)
}
return &res
},
)

Expand All @@ -195,9 +211,13 @@ func (n *maxNode) Next() (bool, error) {
childCollection,
&source,
lessN[float64],
-math.MaxFloat64,
func(childItem float64, value float64) float64 {
return math.Max(value, childItem)
nil,
func(childItem float64, value *float64) *float64 {
res := childItem
if value != nil {
res = math.Max(*value, res)
}
return &res
},
)

Expand All @@ -206,28 +226,36 @@ func (n *maxNode) Next() (bool, error) {
childCollection,
&source,
lessO[float64],
-math.MaxFloat64,
func(childItem immutable.Option[float64], value float64) float64 {
nil,
func(childItem immutable.Option[float64], value *float64) *float64 {
if !childItem.HasValue() {
return value
}
return math.Max(value, childItem.Value())
res := childItem.Value()
if value != nil {
res = math.Max(*value, res)
}
return &res
},
)
}
if err != nil {
return false, err
}
max = math.Max(max, collectionMax)
if max == nil {
max = collectionMax
} else {
res := math.Max(*max, *collectionMax)
max = &res
}
}

if n.isFloat {
n.currentValue.Fields[n.virtualFieldIndex] = float64(max)
} else if max <= math.MinInt64 {
n.currentValue.Fields[n.virtualFieldIndex] = int64(math.MinInt64)
if max == nil {
n.currentValue.Fields[n.virtualFieldIndex] = nil
} else if n.isFloat {
n.currentValue.Fields[n.virtualFieldIndex] = float64(*max)
} else {
n.currentValue.Fields[n.virtualFieldIndex] = int64(max)
n.currentValue.Fields[n.virtualFieldIndex] = int64(*max)
}

return true, nil
}
86 changes: 57 additions & 29 deletions internal/planner/min.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ type minNode struct {
p *Planner
plan planNode

isFloat bool
isFloat bool
// virtualFieldIndex is the index of the field
// that contains the result of the aggregate.
virtualFieldIndex int
aggregateMapping []mapper.AggregateTarget

Expand Down Expand Up @@ -139,40 +141,50 @@ func (n *minNode) Next() (bool, error) {
}
n.currentValue = n.plan.Value()

min := math.MaxFloat64
var min *float64
for _, source := range n.aggregateMapping {
child := n.currentValue.Fields[source.Index]
collectionMin := math.MaxFloat64
var collectionMin *float64
var err error
switch childCollection := child.(type) {
case []core.Doc:
collectionMin = reduceDocs(
childCollection,
math.MaxFloat64,
func(childItem core.Doc, value float64) float64 {
nil,
func(childItem core.Doc, value *float64) *float64 {
childProperty := childItem.Fields[source.ChildTarget.Index]
var res float64
switch v := childProperty.(type) {
case int:
return math.Min(value, float64(v))
res = float64(v)
case int64:
return math.Min(value, float64(v))
res = float64(v)
case uint64:
return math.Min(value, float64(v))
res = float64(v)
case float64:
return math.Min(value, float64(v))
res = float64(v)
default:
return value
return nil
}
if value != nil {
res = math.Min(*value, res)
}
return &res
},
)

case []int64:
collectionMin, err = reduceItems(
childCollection,
&source,
lessN[int64],
math.MaxFloat64,
func(childItem int64, value float64) float64 {
return math.Min(value, float64(childItem))
nil,
func(childItem int64, value *float64) *float64 {
res := float64(childItem)
if value != nil {
res = math.Min(*value, res)
}
return &res
},
)

Expand All @@ -181,12 +193,16 @@ func (n *minNode) Next() (bool, error) {
childCollection,
&source,
lessO[int64],
math.MaxFloat64,
func(childItem immutable.Option[int64], value float64) float64 {
nil,
func(childItem immutable.Option[int64], value *float64) *float64 {
if !childItem.HasValue() {
return value
}
return math.Min(value, float64(childItem.Value()))
res := float64(childItem.Value())
if value != nil {
res = math.Min(*value, res)
}
return &res
},
)

Expand All @@ -195,9 +211,13 @@ func (n *minNode) Next() (bool, error) {
childCollection,
&source,
lessN[float64],
math.MaxFloat64,
func(childItem float64, value float64) float64 {
return math.Min(value, childItem)
nil,
func(childItem float64, value *float64) *float64 {
res := childItem
if value != nil {
res = math.Min(*value, res)
}
return &res
},
)

Expand All @@ -206,28 +226,36 @@ func (n *minNode) Next() (bool, error) {
childCollection,
&source,
lessO[float64],
math.MaxFloat64,
func(childItem immutable.Option[float64], value float64) float64 {
nil,
func(childItem immutable.Option[float64], value *float64) *float64 {
if !childItem.HasValue() {
return value
}
return math.Min(value, childItem.Value())
res := childItem.Value()
if value != nil {
res = math.Min(*value, res)
}
return &res
},
)
}
if err != nil {
return false, err
}
min = math.Min(min, collectionMin)
if min == nil {
min = collectionMin
} else {
res := math.Min(*min, *collectionMin)
min = &res
}
}

if n.isFloat {
n.currentValue.Fields[n.virtualFieldIndex] = float64(min)
} else if min >= math.MaxInt64 {
n.currentValue.Fields[n.virtualFieldIndex] = int64(math.MaxInt64)
if min == nil {
n.currentValue.Fields[n.virtualFieldIndex] = nil
} else if n.isFloat {
n.currentValue.Fields[n.virtualFieldIndex] = float64(*min)
} else {
n.currentValue.Fields[n.virtualFieldIndex] = int64(min)
n.currentValue.Fields[n.virtualFieldIndex] = int64(*min)
}

return true, nil
}
51 changes: 51 additions & 0 deletions tests/integration/query/inline_array/with_max_doc_id_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2024 Democratized Data Foundation
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package inline_array

import (
"testing"

testUtils "github.com/sourcenetwork/defradb/tests/integration"
)

// This test is meant to provide coverage of the planNode.Spans
// func by targeting a specific docID in the parent select.
func TestQueryInlineNillableFloatArray_WithDocIDAndMax_Succeeds(t *testing.T) {
test := testUtils.TestCase{
Description: "Simple inline array with doc id, max of nillable float array",
Actions: []any{
testUtils.CreateDoc{
Doc: `{
"name": "Shahzad",
"pageRatings": [3.1425, 0.00000000001, 10, null]
}`,
},
testUtils.Request{
Request: `query {
Users(docID: "bae-3f7e0f22-e253-53dd-b31b-df8b081292d9") {
name
_max(pageRatings: {})
}
}`,
Results: map[string]any{
"Users": []map[string]any{
{
"name": "Shahzad",
"_max": float64(10),
},
},
},
},
},
}

executeTestCase(t, test)
}
Loading

0 comments on commit e779d9f

Please sign in to comment.