Skip to content

Commit

Permalink
Add Condition of Hash Join as a supported predicate (#88)
Browse files Browse the repository at this point in the history
* Fix comment to add Condition of Hash Join as known predicates

* Add a test case of Hash Join

* Do gofmt
  • Loading branch information
apstndb authored Sep 25, 2020
1 parent 6af0238 commit 65daf9f
Show file tree
Hide file tree
Showing 4 changed files with 342 additions and 3 deletions.
2 changes: 1 addition & 1 deletion query_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ type QueryPlanRow struct {
}

func isPredicate(planNodes []*pb.PlanNode, childLink *pb.PlanNode_ChildLink) bool {
// Known predicates are Condition(Filter) or Seek Condition/Residual Condition(FilterScan) or Split Range(Distributed Union).
// Known predicates are Condition(Filter/Hash Join) or Seek Condition/Residual Condition(FilterScan) or Split Range(Distributed Union).
// Agg is a Function but not a predicate.
child := planNodes[childLink.ChildIndex]
if child.DisplayName != "Function" {
Expand Down
40 changes: 40 additions & 0 deletions query_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,46 @@ func TestRenderTreeUsingTestdataPlans(t *testing.T) {
Text: " +- Index Scan (Index: SingersByFirstLastName)",
},
}},
{
/*
Original Query:
SELECT a.AlbumTitle, s.SongName
FROM Albums AS a HASH JOIN Songs AS s
ON a.SingerId = s.SingerId AND a.AlbumId = s.AlbumId;
*/
title: "Hash Join",
file: "testdata/plans/hash_join.input.json",
want: []QueryPlanRow{
{
ID: 0,
Text: "Distributed Union",
},
{
ID: 1,
Text: "+- Serialize Result",
},
{
ID: 2,
Text: " +- Hash Join (join_type: INNER)",
Predicates: []string{"Condition: (($SingerId = $SingerId_1) AND ($AlbumId = $AlbumId_1))"},
},
{
ID: 3,
Text: " +- [Build] Local Distributed Union",
},
{
ID: 4,
Text: " | +- Table Scan (Full scan: true, Table: Albums)",
},
{
ID: 8,
Text: " +- [Probe] Local Distributed Union",
},
{
ID: 9,
Text: " +- Index Scan (Full scan: true, Index: SongsBySingerAlbumSongNameDesc)",
},
}},
} {
t.Run(test.title, func(t *testing.T) {
b, err := ioutil.ReadFile(test.file)
Expand Down
4 changes: 2 additions & 2 deletions statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ var (
)

var (
explainColumnNames = []string{"ID", "Query_Execution_Plan (EXPERIMENTAL)"}
explainColumnNames = []string{"ID", "Query_Execution_Plan (EXPERIMENTAL)"}
explainAnalyzeColumnNames = []string{"ID", "Query_Execution_Plan", "Rows_Returned", "Executions", "Total_Latency"}
)

Expand Down Expand Up @@ -747,7 +747,7 @@ func (s *ExplainDmlStatement) Execute(session *Session) (*Result, error) {
_, timestamp, queryPlan, err := runInNewOrExistRwTxForExplain(session, func() (int64, *pb.QueryPlan, error) {
plan, err := session.rwTxn.AnalyzeQuery(session.ctx, spanner.NewStatement(s.Dml))
return 0, plan, err
} )
})
if err != nil {
return nil, err
}
Expand Down
299 changes: 299 additions & 0 deletions testdata/plans/hash_join.input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
{
"planNodes": [
{
"childLinks": [
{
"childIndex": 1
},
{
"childIndex": 23,
"type": "Split Range"
}
],
"displayName": "Distributed Union",
"kind": "RELATIONAL",
"metadata": {
"subquery_cluster_node": "1"
}
},
{
"childLinks": [
{
"childIndex": 2
},
{
"childIndex": 21
},
{
"childIndex": 22
}
],
"displayName": "Serialize Result",
"index": 1,
"kind": "RELATIONAL"
},
{
"childLinks": [
{
"childIndex": 3,
"type": "Build"
},
{
"childIndex": 8,
"type": "Probe"
},
{
"childIndex": 13,
"type": "Condition"
},
{
"childIndex": 20,
"type": "Build",
"variable": "AlbumTitle'"
}
],
"displayName": "Hash Join",
"index": 2,
"kind": "RELATIONAL",
"metadata": {
"join_type": "INNER"
}
},
{
"childLinks": [
{
"childIndex": 4
}
],
"displayName": "Distributed Union",
"index": 3,
"kind": "RELATIONAL",
"metadata": {
"call_type": "Local",
"subquery_cluster_node": "4"
}
},
{
"childLinks": [
{
"childIndex": 5,
"variable": "SingerId"
},
{
"childIndex": 6,
"variable": "AlbumId"
},
{
"childIndex": 7,
"variable": "AlbumTitle"
}
],
"displayName": "Scan",
"index": 4,
"kind": "RELATIONAL",
"metadata": {
"Full scan": "true",
"scan_target": "Albums",
"scan_type": "TableScan"
}
},
{
"displayName": "Reference",
"index": 5,
"kind": "SCALAR",
"shortRepresentation": {
"description": "SingerId"
}
},
{
"displayName": "Reference",
"index": 6,
"kind": "SCALAR",
"shortRepresentation": {
"description": "AlbumId"
}
},
{
"displayName": "Reference",
"index": 7,
"kind": "SCALAR",
"shortRepresentation": {
"description": "AlbumTitle"
}
},
{
"childLinks": [
{
"childIndex": 9
}
],
"displayName": "Distributed Union",
"index": 8,
"kind": "RELATIONAL",
"metadata": {
"call_type": "Local",
"subquery_cluster_node": "9"
}
},
{
"childLinks": [
{
"childIndex": 10,
"variable": "AlbumId_1"
},
{
"childIndex": 11,
"variable": "SingerId_1"
},
{
"childIndex": 12,
"variable": "SongName"
}
],
"displayName": "Scan",
"index": 9,
"kind": "RELATIONAL",
"metadata": {
"Full scan": "true",
"scan_target": "SongsBySingerAlbumSongNameDesc",
"scan_type": "IndexScan"
}
},
{
"displayName": "Reference",
"index": 10,
"kind": "SCALAR",
"shortRepresentation": {
"description": "AlbumId"
}
},
{
"displayName": "Reference",
"index": 11,
"kind": "SCALAR",
"shortRepresentation": {
"description": "SingerId"
}
},
{
"displayName": "Reference",
"index": 12,
"kind": "SCALAR",
"shortRepresentation": {
"description": "SongName"
}
},
{
"childLinks": [
{
"childIndex": 14
},
{
"childIndex": 17
}
],
"displayName": "Function",
"index": 13,
"kind": "SCALAR",
"shortRepresentation": {
"description": "(($SingerId = $SingerId_1) AND ($AlbumId = $AlbumId_1))"
}
},
{
"childLinks": [
{
"childIndex": 15
},
{
"childIndex": 16
}
],
"displayName": "Function",
"index": 14,
"kind": "SCALAR",
"shortRepresentation": {
"description": "($SingerId = $SingerId_1)"
}
},
{
"displayName": "Reference",
"index": 15,
"kind": "SCALAR",
"shortRepresentation": {
"description": "$SingerId"
}
},
{
"displayName": "Reference",
"index": 16,
"kind": "SCALAR",
"shortRepresentation": {
"description": "$SingerId_1"
}
},
{
"childLinks": [
{
"childIndex": 18
},
{
"childIndex": 19
}
],
"displayName": "Function",
"index": 17,
"kind": "SCALAR",
"shortRepresentation": {
"description": "($AlbumId = $AlbumId_1)"
}
},
{
"displayName": "Reference",
"index": 18,
"kind": "SCALAR",
"shortRepresentation": {
"description": "$AlbumId"
}
},
{
"displayName": "Reference",
"index": 19,
"kind": "SCALAR",
"shortRepresentation": {
"description": "$AlbumId_1"
}
},
{
"displayName": "Reference",
"index": 20,
"kind": "SCALAR",
"shortRepresentation": {
"description": "$AlbumTitle"
}
},
{
"displayName": "Reference",
"index": 21,
"kind": "SCALAR",
"shortRepresentation": {
"description": "$AlbumTitle'"
}
},
{
"displayName": "Reference",
"index": 22,
"kind": "SCALAR",
"shortRepresentation": {
"description": "$SongName"
}
},
{
"displayName": "Constant",
"index": 23,
"kind": "SCALAR",
"shortRepresentation": {
"description": "true"
}
}
]
}

0 comments on commit 65daf9f

Please sign in to comment.