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

Use one implementation for finding path values #3087

Merged
merged 58 commits into from
Aug 4, 2023
Merged
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
bce806c
create initial common implementation
chilagrow Jul 20, 2023
c4073da
rename
chilagrow Jul 20, 2023
d0c0334
distinct uses new impl
chilagrow Jul 20, 2023
33936ff
use new function in filter
chilagrow Jul 20, 2023
aea192d
some cleaning
chilagrow Jul 20, 2023
4594b67
update doc
chilagrow Jul 20, 2023
3a693bd
re-organise filter pair code
chilagrow Jul 20, 2023
1ef1ef9
handle empty key for filter
chilagrow Jul 20, 2023
bee2816
add tests, comments and refactor
chilagrow Jul 21, 2023
d1b8ff0
tidy up
chilagrow Jul 21, 2023
2e0eff7
Merge branch 'main' into issue-2348-get-path-value
chilagrow Jul 21, 2023
9e188b5
fix merge
chilagrow Jul 21, 2023
5ce3f80
fix merge
chilagrow Jul 21, 2023
7b65633
reorganise
chilagrow Jul 21, 2023
876744d
Merge branch 'main' into issue-2348-get-path-value
mergify[bot] Jul 24, 2023
292d897
Merge branch 'main' into issue-2348-get-path-value
mergify[bot] Jul 24, 2023
d0be65d
Merge branch 'main' into issue-2348-get-path-value
mergify[bot] Jul 24, 2023
cc4af16
Merge branch 'main' into issue-2348-get-path-value
mergify[bot] Jul 24, 2023
15aaf03
Merge branch 'main' into issue-2348-get-path-value
mergify[bot] Jul 24, 2023
faf7daa
Merge branch 'main' into issue-2348-get-path-value
mergify[bot] Jul 24, 2023
ae4f67d
Refactor `types.Path` a bit
AlekSi Jul 24, 2023
fc446a3
Small tweaks
AlekSi Jul 24, 2023
0313d17
update test
chilagrow Jul 26, 2023
51c106b
merge
chilagrow Jul 26, 2023
1d5051f
checkpoint
chilagrow Jul 26, 2023
20c464a
Tweak documentation a little bit
AlekSi Jul 26, 2023
aa74542
another checkpoint
chilagrow Jul 26, 2023
7bf0bdd
Merge branch 'issue-2348-get-path-value' of github.com:chilagrow/Ferr…
chilagrow Jul 26, 2023
789bae3
some update
chilagrow Jul 26, 2023
2885c85
more comment
chilagrow Jul 27, 2023
76f0724
projection returns correct error code
chilagrow Jul 27, 2023
b31332f
fmt
chilagrow Jul 27, 2023
85f509d
Merge branch 'main' into issue-2348-get-path-value
chilagrow Jul 27, 2023
74d4fc1
path does not return error on $ prefix
chilagrow Jul 27, 2023
ca376f4
Revert "projection returns correct error code"
chilagrow Jul 27, 2023
8147dfe
add todo for fixing projection positional operator
chilagrow Jul 27, 2023
e2fc0ff
aggregation projection checks valid path
chilagrow Jul 27, 2023
bac5eeb
add todo
chilagrow Jul 27, 2023
9f19a76
fmt
chilagrow Jul 27, 2023
8a41dc4
Merge branch 'main' into issue-2348-get-path-value
chilagrow Jul 27, 2023
d7c16a0
Revert "aggregation projection checks valid path"
chilagrow Jul 28, 2023
7e49bd4
review comment
chilagrow Jul 28, 2023
3811585
renaming
chilagrow Jul 28, 2023
bc74089
test empty and space keys for insert and find
chilagrow Jul 28, 2023
1316e0c
Revert "test empty and space keys for insert and find"
chilagrow Jul 28, 2023
ea14b20
clean up
chilagrow Jul 28, 2023
b047e14
Merge branch 'main' into issue-2348-get-path-value
AlekSi Aug 1, 2023
e00bd95
update expression documentation
chilagrow Aug 1, 2023
9c4899c
Merge branch 'issue-2348-get-path-value' of github.com:chilagrow/Ferr…
chilagrow Aug 1, 2023
b706f91
update comment
chilagrow Aug 1, 2023
aa3fecd
Merge branch 'main' into issue-2348-get-path-value
chilagrow Aug 2, 2023
f2f0106
update expression comments
chilagrow Aug 2, 2023
b93ea91
more comments
chilagrow Aug 2, 2023
8b205c2
from pairing session
chilagrow Aug 2, 2023
7c0c76f
add more comments
chilagrow Aug 3, 2023
fd19a7a
more update of inline comments
chilagrow Aug 3, 2023
76a63cf
minor comment update
chilagrow Aug 3, 2023
307792e
resolve merge conflict
chilagrow Aug 4, 2023
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
Prev Previous commit
Next Next commit
another checkpoint
  • Loading branch information
chilagrow committed Jul 26, 2023
commit aa74542e57ae93bd38794865bbf9eb27d6cc059c
53 changes: 29 additions & 24 deletions internal/handlers/commonpath/commonpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,47 +26,51 @@ import (

// FindValuesOpts sets options for FindValues.
type FindValuesOpts struct {
// FindArrayElements searches by iterating through the whole array to find documents that contains path key.
// Using path `v.foo` and `v` is an array, it returns all document which has key `foo`.
// If FindArrayElements is true, it iterates the array to find document elements containing the key.
// If FindArrayElements is false, it does not find any element from the array.
// Using path `v.foo` and `v` is an array:
// - with FindArrayElements true, it returns documents' values of key `foo`;
// - with FindArrayElements false, it returns an empty array.
// If `v` is not an array, FindArrayElements has no impact.
FindArrayElements bool
// FindArrayIndex gets an element at the specified index of an array.
// Using path `v.0` and `v` is an array, it returns 0-th index element of the array.
// If FindArrayIndex is true, it uses indexes to find an element of the array.
// If FindArrayIndex is false, it does use indexes on the path.
// Using path `v.0` and `v` is an array:
// - with FindArrayIndex true, it returns 0-th index element of the array;
// - with FindArrayIndex false, it returns empty array.
// If `v` is not an array, FindArrayIndex has no impact.
FindArrayIndex bool
chilagrow marked this conversation as resolved.
Show resolved Hide resolved
}

// FindValues goes through each key of the path iteratively on doc to find values
// at the suffix of the path. At each key of the path, it checks:
// - if the document has the key;
// - if the array contains an element at an index where index equals to the key, and;
// - if the array contains one or more documents which have the key.
// FindValues iterates path elements, at each path element it checks:
// - if it is document and has the key, add it to next values to iterate;
// - if it is array and FindArrayIndex is true, it finds element by index and add it to next values to iterate;
// - if it is array and FindArrayElements is true, it finds elements and add it to next values to iterate;
//
// It returns a slice of values and an empty array is returned if no value was found.
// It returns a slice of values or an empty array is returned if no value was found.
func FindValues(doc *types.Document, path types.Path, opts *FindValuesOpts) ([]any, error) {
if opts == nil {
opts = new(FindValuesOpts)
}

keys := path.Slice()
inputs := []any{doc}
var values []any
var nextValues = []any{doc}

for _, key := range keys {
values = []any{}
for _, p := range path.Slice() {
values := []any{}

for _, input := range inputs {
switch input := input.(type) {
for _, next := range nextValues {
switch next := next.(type) {
case *types.Document:
v, err := input.Get(key)
v, err := next.Get(p)
if err != nil {
continue
}

values = append(values, v)

case *types.Array:
if opts.FindArrayIndex {
res, err := findArrayIndex(input, key)
res, err := findArrayIndex(next, p)
if err != nil {
return nil, lazyerrors.Error(err)
}
Expand All @@ -75,22 +79,23 @@ func FindValues(doc *types.Document, path types.Path, opts *FindValuesOpts) ([]a
}

if opts.FindArrayElements {
res, err := findArrayElements(input, key)
res, err := findArrayElements(next, p)
if err != nil {
return nil, lazyerrors.Error(err)
}

values = append(values, res...)
}

default:
// key does not exist in scalar values
// path does not exist in scalar values, nothing to do
}
}

inputs = values
nextValues = values
}

return values, nil
return nextValues, nil
}

// findArrayIndex checks if key can be used as an index of array and returns
Expand All @@ -112,7 +117,7 @@ func findArrayIndex(array *types.Array, key string) ([]any, error) {
return []any{}, nil
}

// findArrayElements finds document elements containing the key and returns the values.
// findArrayElements finds document elements containing the key and returns the values of the key.
// Empty array is returned if no document elements containing the key was found.
func findArrayElements(array *types.Array, key string) ([]any, error) {
iter := array.Iterator()
Expand Down