handle precalls and cross-index queries better

There's two actual changes here, but they're closely related.

First, handle named parameters for precalls, not just indexed parameters.
Second, when doing translation for a call, check whether it specifies an
index, and if it does, use that index instead of the current index for
the translation.
This commit is contained in:
Seebs 2019-11-20 14:57:15 -06:00
parent 16c3cfa727
commit 6ad39a376e

View file

@ -366,6 +366,14 @@ func (e *executor) handlePreCallChildren(ctx context.Context, index string, c *p
return err
}
}
for _, val := range c.Args {
// Handle Call() operations which exist inside named arguments, too.
if call, ok := val.(*pql.Call); ok {
if err := e.handlePreCalls(ctx, index, call, shards, opt); err != nil {
return err
}
}
}
return nil
}
@ -3095,7 +3103,20 @@ func (e *executor) translateCalls(ctx context.Context, index string, idx *Index,
defer span.Finish()
for i := range calls {
if err := e.translateCall(index, idx, calls[i]); err != nil {
// Possibly change to another index for translation, if this
// call crosses index boundaries.
newIdxName := calls[i].CallIndex()
var newIdx *Index
if newIdxName == "" || newIdxName == index {
newIdxName = index
newIdx = idx
} else {
newIdx = idx.holder.indexes[newIdxName]
if newIdx == nil {
return fmt.Errorf("unknown index %q specified in cross-index call", newIdxName)
}
}
if err := e.translateCall(newIdxName, newIdx, calls[i]); err != nil {
return err
}
}
@ -3195,7 +3216,20 @@ func (e *executor) translateCall(index string, idx *Index, c *pql.Call) error {
// Translate child calls.
for _, child := range c.Children {
if err := e.translateCall(index, idx, child); err != nil {
// Possibly change to another index for translation, if this
// call crosses index boundaries.
newIdxName := child.CallIndex()
var newIdx *Index
if newIdxName == "" || newIdxName == index {
newIdxName = index
newIdx = idx
} else {
newIdx = idx.holder.indexes[newIdxName]
if newIdx == nil {
return fmt.Errorf("unknown index %q specified in cross-index call", newIdxName)
}
}
if err := e.translateCall(newIdxName, newIdx, child); err != nil {
return err
}
}