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

feat: Add support to explain countNode attributes. #504

Merged
merged 2 commits into from
Jun 9, 2022
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 query/graphql/planner/count.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,19 @@ func (n *countNode) Source() planNode { return n.plan }
// Explain method returns a map containing all attributes of this node that
// are to be explained, subscribes / opts-in this node to be an explainablePlanNode.
func (n *countNode) Explain() (map[string]interface{}, error) {
return map[string]interface{}{}, nil
explainerMap := map[string]interface{}{}

// Add the filter attribute if it exists.
if n.filter == nil || n.filter.Conditions == nil {
explainerMap[filterLabel] = nil
} else {
explainerMap[filterLabel] = n.filter.Conditions
shahzadlone marked this conversation as resolved.
Show resolved Hide resolved
}

// Add the source property.
explainerMap["sourceProperty"] = n.sourceProperty

return explainerMap, nil
}

func (n *countNode) Next() (bool, error) {
Expand Down
6 changes: 3 additions & 3 deletions query/graphql/planner/planner.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,12 @@ func (p *Planner) expandPlan(plan planNode, parentPlan *selectTopNode) error {
}

func (p *Planner) expandSelectTopNodePlan(plan *selectTopNode, parentPlan *selectTopNode) error {
if err := p.expandPlan(plan.source, plan); err != nil {
if err := p.expandPlan(plan.selectnode, plan); err != nil {
return err
}

// wire up source to plan
plan.plan = plan.source
plan.plan = plan.selectnode

// if group
if plan.group != nil {
Expand Down Expand Up @@ -300,7 +300,7 @@ func (p *Planner) expandGroupNodePlan(plan *selectTopNode) error {
childSelect,
pipe,
false,
&plan.source.(*selectNode).sourceInfo,
&plan.selectnode.sourceInfo,
)
if err != nil {
return err
Expand Down
15 changes: 7 additions & 8 deletions query/graphql/planner/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,17 @@ SELECT * From TableA as A JOIN TableB as B ON a.id = b.friend_id
// Wraps a selectNode and all the logic of a plan graph into a single struct for proper plan expansion.
// Executes the top level plan node.
type selectTopNode struct {
source planNode
group *groupNode
sort *sortNode
limit planNode
render *renderNode
aggregates []aggregateNode

// top of the plan graph
plan planNode
// selectnode is used pre-wiring of the plan (before expansion and all).
selectnode *selectNode

// plan -> limit -> sort -> sort.plan = (values -> container | SORT_STRATEGY) -> render -> source
// ... source -> MultiNode -> TypeJoinNode.plan = (typeJoinOne | typeJoinMany) -> scanNode
// plan is the top of the plan graph (the wired and finalized plan graph).
plan planNode
}

func (n *selectTopNode) Kind() string { return "selectTopNode" }
Expand All @@ -76,7 +75,7 @@ func (n *selectTopNode) Spans(spans core.Spans) { n.plan.Spans(spans) }

func (n *selectTopNode) Value() map[string]interface{} { return n.plan.Value() }

func (n *selectTopNode) Source() planNode { return n.source }
func (n *selectTopNode) Source() planNode { return n.plan.Source() }

// Explain method for selectTopNode returns no attributes but is used to
// subscribe / opt-into being an explainablePlanNode.
Expand Down Expand Up @@ -572,7 +571,7 @@ func (p *Planner) SelectFromSource(
}

top := &selectTopNode{
source: s,
selectnode: s,
render: p.render(parsed),
limit: limitPlan,
sort: sortPlan,
Expand Down Expand Up @@ -613,7 +612,7 @@ func (p *Planner) Select(parsed *parser.Select) (planNode, error) {
}

top := &selectTopNode{
source: s,
selectnode: s,
render: p.render(parsed),
limit: limitPlan,
sort: sortPlan,
Expand Down
2 changes: 1 addition & 1 deletion query/graphql/planner/type_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func (n *typeJoinOne) valuesPrimary(doc map[string]interface{}) map[string]inter
doc[subDocField] = map[string]interface{}{}

// create the collection key for the sub doc
slct := n.subType.(*selectTopNode).source.(*selectNode)
slct := n.subType.(*selectTopNode).selectnode
desc := slct.sourceInfo.collectionDescription
subKeyIndexKey := base.MakeDocKey(desc, subDocKeyStr)

Expand Down
133 changes: 80 additions & 53 deletions tests/integration/query/explain/with_count_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,26 +74,31 @@ func TestExplainQueryOneToManyWithACount(t *testing.T) {
},
},

// ----> selectTopNode (explainable but no-attributes)
// ----> selectNode (explainable)
// ----> typeIndexJoin (explainable)
// ----> typeJoinMany (non-explainable)
// ----> scanNode (explainable)
// ----> selectTopNode (explainable but no-attributes)
// ----> countNode (explainable)
// ----> selectNode (explainable)
// ----> typeIndexJoin (explainable)
// ----> typeJoinMany (non-explainable)
// ----> scanNode (explainable)
Results: []dataMap{
{
"explain": dataMap{
"selectTopNode": dataMap{
"selectNode": dataMap{
"filter": nil,
"typeIndexJoin": dataMap{
"scanNode": dataMap{
"collectionID": "3",
"collectionName": "author",
"filter": nil,
"spans": []dataMap{
{
"start": "/3",
"end": "/4",
"countNode": dataMap{
"filter": nil,
"sourceProperty": "books",
"selectNode": dataMap{
"filter": nil,
"typeIndexJoin": dataMap{
"scanNode": dataMap{
"collectionID": "3",
"collectionName": "author",
"filter": nil,
"spans": []dataMap{
{
"start": "/3",
"end": "/4",
},
},
},
},
Expand All @@ -117,7 +122,15 @@ func TestExplainQueryOneToManyMultipleWithCounts(t *testing.T) {
author {
name
numberOfBooks: _count(books: {})
numberOfArticles: _count(articles: {})
numberOfArticles: _count(
articles: {
filter: {
name: {
_eq: "After Guantánamo, Another Injustice"
}
}
}
)
}
}`,

Expand Down Expand Up @@ -169,55 +182,69 @@ func TestExplainQueryOneToManyMultipleWithCounts(t *testing.T) {
},
},

// ----> selectTopNode (explainable but no attributes)
// ----> selectNode (explainable)
// ----> parallelNode (non-explainable but wraps children)
// ----> typeIndexJoin (explainable)
// ----> typeJoinMany (non-explainable)
// ----> scanNode (explainable)
// ----> scanNode (explainable)
// ----> typeIndexJoin (explainable)
// ----> typeJoinMany (non-explainable)
// ----> scanNode (explainable)
// ----> scanNode (explainable)
// ----> selectTopNode (explainable but no attributes)
// ----> countNode (explainable)
// ----> countNode (explainable)
// ----> selectNode (explainable)
// ----> parallelNode (non-explainable but wraps children)
// ----> typeIndexJoin (explainable)
// ----> typeJoinMany (non-explainable)
// ----> multiscanNode (non-explainable)
// ----> scanNode (explainable)
// ----> typeIndexJoin (explainable)
// ----> typeJoinMany (non-explainable)
// ----> multiscanNode (non-explainable)
// ----> scanNode (explainable)
Results: []dataMap{
{
"explain": dataMap{
"selectTopNode": dataMap{
"selectNode": dataMap{
"parallelNode": []dataMap{
{
"typeIndexJoin": dataMap{
"scanNode": dataMap{
"collectionID": "3",
"collectionName": "author",
"filter": nil,
"spans": []dataMap{
{
"start": "/3",
"end": "/4",
"countNode": dataMap{
"filter": nil,
"sourceProperty": "books",
"countNode": dataMap{
"filter": dataMap{
"name": dataMap{
"$eq": "After Guantánamo, Another Injustice",
},
},
"sourceProperty": "articles",
"selectNode": dataMap{
"filter": nil,
"parallelNode": []dataMap{
{
"typeIndexJoin": dataMap{
"scanNode": dataMap{
"collectionID": "3",
"collectionName": "author",
"filter": nil,
"spans": []dataMap{
{
"end": "/4",
"start": "/3",
},
},
},
},
},
},
},
{
"typeIndexJoin": dataMap{
"scanNode": dataMap{
"collectionID": "3",
"collectionName": "author",
"filter": nil,
"spans": []dataMap{
{
"start": "/3",
"end": "/4",
{
"typeIndexJoin": dataMap{
"scanNode": dataMap{
"collectionID": "3",
"collectionName": "author",
"filter": nil,
"spans": []dataMap{
{
"end": "/4",
"start": "/3",
},
},
},
},
},
},
},
},
"filter": nil,
},
},
},
Expand Down