github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/delayed.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package sql 12 13 import ( 14 "context" 15 16 "github.com/cockroachdb/cockroach/pkg/sql/opt/constraint" 17 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 18 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 19 ) 20 21 // delayedNode wraps a planNode in cases where the planNode 22 // constructor must be delayed during query execution (as opposed to 23 // SQL prepare) for resource tracking purposes. 24 type delayedNode struct { 25 name string 26 columns sqlbase.ResultColumns 27 indexConstraint *constraint.Constraint 28 constructor nodeConstructor 29 plan planNode 30 } 31 32 type nodeConstructor func(context.Context, *planner) (planNode, error) 33 34 func (d *delayedNode) Next(params runParams) (bool, error) { return d.plan.Next(params) } 35 func (d *delayedNode) Values() tree.Datums { return d.plan.Values() } 36 37 func (d *delayedNode) Close(ctx context.Context) { 38 if d.plan != nil { 39 d.plan.Close(ctx) 40 d.plan = nil 41 } 42 } 43 44 // startExec constructs the wrapped planNode now that execution is underway. 45 func (d *delayedNode) startExec(params runParams) error { 46 if d.plan != nil { 47 panic("wrapped plan should not yet exist") 48 } 49 50 plan, err := d.constructor(params.ctx, params.p) 51 if err != nil { 52 return err 53 } 54 d.plan = plan 55 56 // Recursively invoke startExec on new plan. Normally, startExec doesn't 57 // recurse - calling children is handled by the planNode walker. The reason 58 // this won't suffice here is that the the child of this node doesn't exist 59 // until after startExec is invoked. 60 return startExec(params, plan) 61 }