github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt_exec_factory.go (about) 1 // Copyright 2018 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 "bytes" 15 "compress/zlib" 16 "context" 17 "encoding/base64" 18 "fmt" 19 "net/url" 20 "strings" 21 22 "github.com/cockroachdb/cockroach/pkg/geo/geoindex" 23 "github.com/cockroachdb/cockroach/pkg/sql/execinfra" 24 "github.com/cockroachdb/cockroach/pkg/sql/opt" 25 "github.com/cockroachdb/cockroach/pkg/sql/opt/cat" 26 "github.com/cockroachdb/cockroach/pkg/sql/opt/constraint" 27 "github.com/cockroachdb/cockroach/pkg/sql/opt/exec" 28 "github.com/cockroachdb/cockroach/pkg/sql/row" 29 "github.com/cockroachdb/cockroach/pkg/sql/rowexec" 30 "github.com/cockroachdb/cockroach/pkg/sql/sem/builtins" 31 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 32 "github.com/cockroachdb/cockroach/pkg/sql/span" 33 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 34 "github.com/cockroachdb/cockroach/pkg/sql/types" 35 "github.com/cockroachdb/cockroach/pkg/util" 36 "github.com/cockroachdb/cockroach/pkg/util/encoding" 37 "github.com/cockroachdb/errors" 38 ) 39 40 type execFactory struct { 41 planner *planner 42 allowAutoCommit bool 43 } 44 45 var _ exec.Factory = &execFactory{} 46 47 func newExecFactory(p *planner) *execFactory { 48 return &execFactory{ 49 planner: p, 50 allowAutoCommit: p.autoCommit, 51 } 52 } 53 54 func (ef *execFactory) disableAutoCommit() { 55 ef.allowAutoCommit = false 56 } 57 58 // ConstructValues is part of the exec.Factory interface. 59 func (ef *execFactory) ConstructValues( 60 rows [][]tree.TypedExpr, cols sqlbase.ResultColumns, 61 ) (exec.Node, error) { 62 if len(cols) == 0 && len(rows) == 1 { 63 return &unaryNode{}, nil 64 } 65 if len(rows) == 0 { 66 return &zeroNode{columns: cols}, nil 67 } 68 return &valuesNode{ 69 columns: cols, 70 tuples: rows, 71 specifiedInQuery: true, 72 }, nil 73 } 74 75 // ConstructScan is part of the exec.Factory interface. 76 func (ef *execFactory) ConstructScan( 77 table cat.Table, 78 index cat.Index, 79 needed exec.TableColumnOrdinalSet, 80 indexConstraint *constraint.Constraint, 81 hardLimit int64, 82 softLimit int64, 83 reverse bool, 84 maxResults uint64, 85 reqOrdering exec.OutputOrdering, 86 rowCount float64, 87 locking *tree.LockingItem, 88 ) (exec.Node, error) { 89 if table.IsVirtualTable() { 90 return ef.constructVirtualScan( 91 table, index, needed, indexConstraint, hardLimit, softLimit, reverse, maxResults, 92 reqOrdering, rowCount, locking, 93 ) 94 } 95 96 tabDesc := table.(*optTable).desc 97 indexDesc := index.(*optIndex).desc 98 // Create a scanNode. 99 scan := ef.planner.Scan() 100 colCfg := makeScanColumnsConfig(table, needed) 101 102 sb := span.MakeBuilder(ef.planner.ExecCfg().Codec, tabDesc.TableDesc(), indexDesc) 103 104 // initTable checks that the current user has the correct privilege to access 105 // the table. However, the privilege has already been checked in optbuilder, 106 // and does not need to be rechecked. In fact, it's an error to check the 107 // privilege if the table was originally part of a view, since lower privilege 108 // users might be able to access a view that uses a higher privilege table. 109 ef.planner.skipSelectPrivilegeChecks = true 110 defer func() { ef.planner.skipSelectPrivilegeChecks = false }() 111 if err := scan.initTable(context.TODO(), ef.planner, tabDesc, nil, colCfg); err != nil { 112 return nil, err 113 } 114 115 if indexConstraint != nil && indexConstraint.IsContradiction() { 116 return newZeroNode(scan.resultColumns), nil 117 } 118 119 scan.index = indexDesc 120 scan.hardLimit = hardLimit 121 scan.softLimit = softLimit 122 123 scan.reverse = reverse 124 scan.maxResults = maxResults 125 scan.parallelScansEnabled = sqlbase.ParallelScans.Get(&ef.planner.extendedEvalCtx.Settings.SV) 126 var err error 127 scan.spans, err = sb.SpansFromConstraint(indexConstraint, needed, false /* forDelete */) 128 if err != nil { 129 return nil, err 130 } 131 scan.isFull = len(scan.spans) == 1 && scan.spans[0].EqualValue( 132 scan.desc.IndexSpan(ef.planner.ExecCfg().Codec, scan.index.ID), 133 ) 134 for i := range reqOrdering { 135 if reqOrdering[i].ColIdx >= len(colCfg.wantedColumns) { 136 return nil, errors.Errorf("invalid reqOrdering: %v", reqOrdering) 137 } 138 } 139 scan.reqOrdering = ReqOrdering(reqOrdering) 140 scan.estimatedRowCount = uint64(rowCount) 141 if locking != nil { 142 scan.lockingStrength = sqlbase.ToScanLockingStrength(locking.Strength) 143 scan.lockingWaitPolicy = sqlbase.ToScanLockingWaitPolicy(locking.WaitPolicy) 144 } 145 return scan, nil 146 } 147 148 func (ef *execFactory) constructVirtualScan( 149 table cat.Table, 150 index cat.Index, 151 needed exec.TableColumnOrdinalSet, 152 indexConstraint *constraint.Constraint, 153 hardLimit int64, 154 softLimit int64, 155 reverse bool, 156 maxResults uint64, 157 reqOrdering exec.OutputOrdering, 158 rowCount float64, 159 locking *tree.LockingItem, 160 ) (exec.Node, error) { 161 tn := &table.(*optVirtualTable).name 162 virtual, err := ef.planner.getVirtualTabler().getVirtualTableEntry(tn) 163 if err != nil { 164 return nil, err 165 } 166 indexDesc := index.(*optVirtualIndex).desc 167 columns, constructor := virtual.getPlanInfo( 168 table.(*optVirtualTable).desc.TableDesc(), 169 indexDesc, indexConstraint) 170 171 var n exec.Node 172 n = &delayedNode{ 173 name: fmt.Sprintf("%s@%s", table.Name(), index.Name()), 174 columns: columns, 175 indexConstraint: indexConstraint, 176 constructor: func(ctx context.Context, p *planner) (planNode, error) { 177 return constructor(ctx, p, tn.Catalog()) 178 }, 179 } 180 181 // Check for explicit use of the dummy column. 182 if needed.Contains(0) { 183 return nil, errors.Errorf("use of %s column not allowed.", table.Column(0).ColName()) 184 } 185 if locking != nil { 186 // We shouldn't have allowed SELECT FOR UPDATE for a virtual table. 187 return nil, errors.AssertionFailedf("locking cannot be used with virtual table") 188 } 189 if needed.Len() != len(columns) { 190 // We are selecting a subset of columns; we need a projection. 191 cols := make([]exec.NodeColumnOrdinal, 0, needed.Len()) 192 colNames := make([]string, len(cols)) 193 for ord, ok := needed.Next(0); ok; ord, ok = needed.Next(ord + 1) { 194 cols = append(cols, exec.NodeColumnOrdinal(ord-1)) 195 colNames = append(colNames, columns[ord-1].Name) 196 } 197 n, err = ef.ConstructSimpleProject(n, cols, colNames, nil /* reqOrdering */) 198 if err != nil { 199 return nil, err 200 } 201 } 202 if hardLimit != 0 { 203 n, err = ef.ConstructLimit(n, tree.NewDInt(tree.DInt(hardLimit)), nil /* offset */) 204 if err != nil { 205 return nil, err 206 } 207 } 208 // reqOrdering will be set if the optimizer expects that the output of the 209 // exec.Node that we're returning will actually have a legitimate ordering. 210 // Virtual indexes never provide a legitimate ordering, so we have to make 211 // sure to sort if we have a required ordering. 212 if len(reqOrdering) != 0 { 213 n, err = ef.ConstructSort(n, sqlbase.ColumnOrdering(reqOrdering), 0) 214 if err != nil { 215 return nil, err 216 } 217 } 218 return n, nil 219 } 220 221 func asDataSource(n exec.Node) planDataSource { 222 plan := n.(planNode) 223 return planDataSource{ 224 columns: planColumns(plan), 225 plan: plan, 226 } 227 } 228 229 // ConstructFilter is part of the exec.Factory interface. 230 func (ef *execFactory) ConstructFilter( 231 n exec.Node, filter tree.TypedExpr, reqOrdering exec.OutputOrdering, 232 ) (exec.Node, error) { 233 // Push the filter into the scanNode. We cannot do this if the scanNode has a 234 // limit (it would make the limit apply AFTER the filter). 235 if s, ok := n.(*scanNode); ok && s.filter == nil && s.hardLimit == 0 { 236 s.filter = s.filterVars.Rebind(filter, true /* alsoReset */, false /* normalizeToNonNil */) 237 // Note: if the filter statically evaluates to true, s.filter stays nil. 238 s.reqOrdering = ReqOrdering(reqOrdering) 239 return s, nil 240 } 241 // Create a filterNode. 242 src := asDataSource(n) 243 f := &filterNode{ 244 source: src, 245 } 246 f.ivarHelper = tree.MakeIndexedVarHelper(f, len(src.columns)) 247 f.filter = f.ivarHelper.Rebind(filter, true /* alsoReset */, false /* normalizeToNonNil */) 248 if f.filter == nil { 249 // Filter statically evaluates to true. Just return the input plan. 250 return n, nil 251 } 252 f.reqOrdering = ReqOrdering(reqOrdering) 253 254 // If there's a spool, pull it up. 255 if spool, ok := f.source.plan.(*spoolNode); ok { 256 f.source.plan = spool.source 257 spool.source = f 258 return spool, nil 259 } 260 return f, nil 261 } 262 263 // ConstructSimpleProject is part of the exec.Factory interface. 264 func (ef *execFactory) ConstructSimpleProject( 265 n exec.Node, cols []exec.NodeColumnOrdinal, colNames []string, reqOrdering exec.OutputOrdering, 266 ) (exec.Node, error) { 267 // If the top node is already a renderNode, just rearrange the columns. But 268 // we don't want to duplicate a rendering expression (in case it is expensive 269 // to compute or has side-effects); so if we have duplicates we avoid this 270 // optimization (and add a new renderNode). 271 if r, ok := n.(*renderNode); ok && !hasDuplicates(cols) { 272 oldCols, oldRenders := r.columns, r.render 273 r.columns = make(sqlbase.ResultColumns, len(cols)) 274 r.render = make([]tree.TypedExpr, len(cols)) 275 for i, ord := range cols { 276 r.columns[i] = oldCols[ord] 277 if colNames != nil { 278 r.columns[i].Name = colNames[i] 279 } 280 r.render[i] = oldRenders[ord] 281 } 282 r.reqOrdering = ReqOrdering(reqOrdering) 283 return r, nil 284 } 285 var inputCols sqlbase.ResultColumns 286 if colNames == nil { 287 // We will need the names of the input columns. 288 inputCols = planColumns(n.(planNode)) 289 } 290 291 var rb renderBuilder 292 rb.init(n, reqOrdering) 293 294 exprs := make(tree.TypedExprs, len(cols)) 295 resultCols := make(sqlbase.ResultColumns, len(cols)) 296 for i, col := range cols { 297 v := rb.r.ivarHelper.IndexedVar(int(col)) 298 if colNames == nil { 299 resultCols[i] = inputCols[col] 300 // If we have a SimpleProject, we should clear the hidden bit on any 301 // column since it indicates it's been explicitly selected. 302 resultCols[i].Hidden = false 303 } else { 304 resultCols[i] = sqlbase.ResultColumn{ 305 Name: colNames[i], 306 Typ: v.ResolvedType(), 307 } 308 } 309 exprs[i] = v 310 } 311 rb.setOutput(exprs, resultCols) 312 return rb.res, nil 313 } 314 315 func hasDuplicates(cols []exec.NodeColumnOrdinal) bool { 316 var set util.FastIntSet 317 for _, c := range cols { 318 if set.Contains(int(c)) { 319 return true 320 } 321 set.Add(int(c)) 322 } 323 return false 324 } 325 326 // ConstructRender is part of the exec.Factory interface. 327 // N.B.: The input exprs will be modified. 328 func (ef *execFactory) ConstructRender( 329 n exec.Node, 330 columns sqlbase.ResultColumns, 331 exprs tree.TypedExprs, 332 reqOrdering exec.OutputOrdering, 333 ) (exec.Node, error) { 334 var rb renderBuilder 335 rb.init(n, reqOrdering) 336 for i, expr := range exprs { 337 expr = rb.r.ivarHelper.Rebind(expr, false /* alsoReset */, true /* normalizeToNonNil */) 338 exprs[i] = expr 339 } 340 rb.setOutput(exprs, columns) 341 return rb.res, nil 342 } 343 344 // RenameColumns is part of the exec.Factory interface. 345 func (ef *execFactory) RenameColumns(n exec.Node, colNames []string) (exec.Node, error) { 346 inputCols := planMutableColumns(n.(planNode)) 347 for i := range inputCols { 348 inputCols[i].Name = colNames[i] 349 } 350 return n, nil 351 } 352 353 // ConstructHashJoin is part of the exec.Factory interface. 354 func (ef *execFactory) ConstructHashJoin( 355 joinType sqlbase.JoinType, 356 left, right exec.Node, 357 leftEqCols, rightEqCols []exec.NodeColumnOrdinal, 358 leftEqColsAreKey, rightEqColsAreKey bool, 359 extraOnCond tree.TypedExpr, 360 ) (exec.Node, error) { 361 p := ef.planner 362 leftSrc := asDataSource(left) 363 rightSrc := asDataSource(right) 364 pred, err := makePredicate(joinType, leftSrc.columns, rightSrc.columns) 365 if err != nil { 366 return nil, err 367 } 368 369 numEqCols := len(leftEqCols) 370 // Save some allocations by putting both sides in the same slice. 371 intBuf := make([]int, 2*numEqCols) 372 pred.leftEqualityIndices = intBuf[:numEqCols:numEqCols] 373 pred.rightEqualityIndices = intBuf[numEqCols:] 374 nameBuf := make(tree.NameList, 2*numEqCols) 375 pred.leftColNames = nameBuf[:numEqCols:numEqCols] 376 pred.rightColNames = nameBuf[numEqCols:] 377 378 for i := range leftEqCols { 379 pred.leftEqualityIndices[i] = int(leftEqCols[i]) 380 pred.rightEqualityIndices[i] = int(rightEqCols[i]) 381 pred.leftColNames[i] = tree.Name(leftSrc.columns[leftEqCols[i]].Name) 382 pred.rightColNames[i] = tree.Name(rightSrc.columns[rightEqCols[i]].Name) 383 } 384 pred.leftEqKey = leftEqColsAreKey 385 pred.rightEqKey = rightEqColsAreKey 386 387 pred.onCond = pred.iVarHelper.Rebind( 388 extraOnCond, false /* alsoReset */, false, /* normalizeToNonNil */ 389 ) 390 391 return p.makeJoinNode(leftSrc, rightSrc, pred), nil 392 } 393 394 // ConstructApplyJoin is part of the exec.Factory interface. 395 func (ef *execFactory) ConstructApplyJoin( 396 joinType sqlbase.JoinType, 397 left exec.Node, 398 rightColumns sqlbase.ResultColumns, 399 onCond tree.TypedExpr, 400 planRightSideFn exec.ApplyJoinPlanRightSideFn, 401 ) (exec.Node, error) { 402 leftSrc := asDataSource(left) 403 pred, err := makePredicate(joinType, leftSrc.columns, rightColumns) 404 if err != nil { 405 return nil, err 406 } 407 pred.onCond = pred.iVarHelper.Rebind( 408 onCond, false /* alsoReset */, false, /* normalizeToNonNil */ 409 ) 410 return newApplyJoinNode(joinType, leftSrc, rightColumns, pred, planRightSideFn) 411 } 412 413 // ConstructMergeJoin is part of the exec.Factory interface. 414 func (ef *execFactory) ConstructMergeJoin( 415 joinType sqlbase.JoinType, 416 left, right exec.Node, 417 onCond tree.TypedExpr, 418 leftOrdering, rightOrdering sqlbase.ColumnOrdering, 419 reqOrdering exec.OutputOrdering, 420 leftEqColsAreKey, rightEqColsAreKey bool, 421 ) (exec.Node, error) { 422 p := ef.planner 423 leftSrc := asDataSource(left) 424 rightSrc := asDataSource(right) 425 pred, err := makePredicate(joinType, leftSrc.columns, rightSrc.columns) 426 if err != nil { 427 return nil, err 428 } 429 pred.onCond = pred.iVarHelper.Rebind( 430 onCond, false /* alsoReset */, false, /* normalizeToNonNil */ 431 ) 432 pred.leftEqKey = leftEqColsAreKey 433 pred.rightEqKey = rightEqColsAreKey 434 435 n := len(leftOrdering) 436 if n == 0 || len(rightOrdering) != n { 437 return nil, errors.Errorf("orderings from the left and right side must be the same non-zero length") 438 } 439 pred.leftEqualityIndices = make([]int, n) 440 pred.rightEqualityIndices = make([]int, n) 441 pred.leftColNames = make(tree.NameList, n) 442 pred.rightColNames = make(tree.NameList, n) 443 for i := 0; i < n; i++ { 444 leftColIdx, rightColIdx := leftOrdering[i].ColIdx, rightOrdering[i].ColIdx 445 pred.leftEqualityIndices[i] = leftColIdx 446 pred.rightEqualityIndices[i] = rightColIdx 447 pred.leftColNames[i] = tree.Name(leftSrc.columns[leftColIdx].Name) 448 pred.rightColNames[i] = tree.Name(rightSrc.columns[rightColIdx].Name) 449 } 450 451 node := p.makeJoinNode(leftSrc, rightSrc, pred) 452 node.mergeJoinOrdering = make(sqlbase.ColumnOrdering, n) 453 for i := 0; i < n; i++ { 454 // The mergeJoinOrdering "columns" are equality column indices. Because of 455 // the way we constructed the equality indices, the ordering will always be 456 // 0,1,2,3.. 457 node.mergeJoinOrdering[i].ColIdx = i 458 node.mergeJoinOrdering[i].Direction = leftOrdering[i].Direction 459 } 460 461 // Set up node.props, which tells the distsql planner to maintain the 462 // resulting ordering (if needed). 463 node.reqOrdering = ReqOrdering(reqOrdering) 464 465 return node, nil 466 } 467 468 // ConstructScalarGroupBy is part of the exec.Factory interface. 469 func (ef *execFactory) ConstructScalarGroupBy( 470 input exec.Node, aggregations []exec.AggInfo, 471 ) (exec.Node, error) { 472 n := &groupNode{ 473 plan: input.(planNode), 474 funcs: make([]*aggregateFuncHolder, 0, len(aggregations)), 475 columns: make(sqlbase.ResultColumns, 0, len(aggregations)), 476 isScalar: true, 477 } 478 if err := ef.addAggregations(n, aggregations); err != nil { 479 return nil, err 480 } 481 return n, nil 482 } 483 484 // ConstructGroupBy is part of the exec.Factory interface. 485 func (ef *execFactory) ConstructGroupBy( 486 input exec.Node, 487 groupCols []exec.NodeColumnOrdinal, 488 groupColOrdering sqlbase.ColumnOrdering, 489 aggregations []exec.AggInfo, 490 reqOrdering exec.OutputOrdering, 491 ) (exec.Node, error) { 492 n := &groupNode{ 493 plan: input.(planNode), 494 funcs: make([]*aggregateFuncHolder, 0, len(groupCols)+len(aggregations)), 495 columns: make(sqlbase.ResultColumns, 0, len(groupCols)+len(aggregations)), 496 groupCols: make([]int, len(groupCols)), 497 groupColOrdering: groupColOrdering, 498 isScalar: false, 499 reqOrdering: ReqOrdering(reqOrdering), 500 } 501 inputCols := planColumns(n.plan) 502 for i := range groupCols { 503 col := int(groupCols[i]) 504 n.groupCols[i] = col 505 506 // TODO(radu): only generate the grouping columns we actually need. 507 f := n.newAggregateFuncHolder( 508 builtins.AnyNotNull, 509 inputCols[col].Typ, 510 []int{col}, 511 builtins.NewAnyNotNullAggregate, 512 nil, /* arguments */ 513 ef.planner.EvalContext().Mon.MakeBoundAccount(), 514 ) 515 n.funcs = append(n.funcs, f) 516 n.columns = append(n.columns, inputCols[col]) 517 } 518 if err := ef.addAggregations(n, aggregations); err != nil { 519 return nil, err 520 } 521 return n, nil 522 } 523 524 func (ef *execFactory) addAggregations(n *groupNode, aggregations []exec.AggInfo) error { 525 inputCols := planColumns(n.plan) 526 for i := range aggregations { 527 agg := &aggregations[i] 528 builtin := agg.Builtin 529 renderIdxs := make([]int, len(agg.ArgCols)) 530 params := make([]*types.T, len(agg.ArgCols)) 531 for j, col := range agg.ArgCols { 532 renderIdx := int(col) 533 renderIdxs[j] = renderIdx 534 params[j] = inputCols[renderIdx].Typ 535 } 536 aggFn := func(evalCtx *tree.EvalContext, arguments tree.Datums) tree.AggregateFunc { 537 return builtin.AggregateFunc(params, evalCtx, arguments) 538 } 539 540 f := n.newAggregateFuncHolder( 541 agg.FuncName, 542 agg.ResultType, 543 renderIdxs, 544 aggFn, 545 agg.ConstArgs, 546 ef.planner.EvalContext().Mon.MakeBoundAccount(), 547 ) 548 if agg.Distinct { 549 f.setDistinct() 550 } 551 552 if agg.Filter == -1 { 553 // A value of -1 means the aggregate had no filter. 554 f.filterRenderIdx = noRenderIdx 555 } else { 556 f.filterRenderIdx = int(agg.Filter) 557 } 558 559 n.funcs = append(n.funcs, f) 560 n.columns = append(n.columns, sqlbase.ResultColumn{ 561 Name: agg.FuncName, 562 Typ: agg.ResultType, 563 }) 564 } 565 return nil 566 } 567 568 // ConstructDistinct is part of the exec.Factory interface. 569 func (ef *execFactory) ConstructDistinct( 570 input exec.Node, 571 distinctCols, orderedCols exec.NodeColumnOrdinalSet, 572 reqOrdering exec.OutputOrdering, 573 nullsAreDistinct bool, 574 errorOnDup string, 575 ) (exec.Node, error) { 576 return &distinctNode{ 577 plan: input.(planNode), 578 distinctOnColIdxs: distinctCols, 579 columnsInOrder: orderedCols, 580 reqOrdering: ReqOrdering(reqOrdering), 581 nullsAreDistinct: nullsAreDistinct, 582 errorOnDup: errorOnDup, 583 }, nil 584 } 585 586 // ConstructSetOp is part of the exec.Factory interface. 587 func (ef *execFactory) ConstructSetOp( 588 typ tree.UnionType, all bool, left, right exec.Node, 589 ) (exec.Node, error) { 590 return ef.planner.newUnionNode(typ, all, left.(planNode), right.(planNode)) 591 } 592 593 // ConstructSort is part of the exec.Factory interface. 594 func (ef *execFactory) ConstructSort( 595 input exec.Node, ordering sqlbase.ColumnOrdering, alreadyOrderedPrefix int, 596 ) (exec.Node, error) { 597 return &sortNode{ 598 plan: input.(planNode), 599 ordering: ordering, 600 alreadyOrderedPrefix: alreadyOrderedPrefix, 601 }, nil 602 } 603 604 // ConstructOrdinality is part of the exec.Factory interface. 605 func (ef *execFactory) ConstructOrdinality(input exec.Node, colName string) (exec.Node, error) { 606 plan := input.(planNode) 607 inputColumns := planColumns(plan) 608 cols := make(sqlbase.ResultColumns, len(inputColumns)+1) 609 copy(cols, inputColumns) 610 cols[len(cols)-1] = sqlbase.ResultColumn{ 611 Name: colName, 612 Typ: types.Int, 613 } 614 return &ordinalityNode{ 615 source: plan, 616 columns: cols, 617 run: ordinalityRun{ 618 row: make(tree.Datums, len(cols)), 619 curCnt: 1, 620 }, 621 }, nil 622 } 623 624 // ConstructIndexJoin is part of the exec.Factory interface. 625 func (ef *execFactory) ConstructIndexJoin( 626 input exec.Node, 627 table cat.Table, 628 keyCols []exec.NodeColumnOrdinal, 629 tableCols exec.TableColumnOrdinalSet, 630 reqOrdering exec.OutputOrdering, 631 ) (exec.Node, error) { 632 tabDesc := table.(*optTable).desc 633 colCfg := makeScanColumnsConfig(table, tableCols) 634 colDescs := makeColDescList(table, tableCols) 635 636 tableScan := ef.planner.Scan() 637 638 if err := tableScan.initTable(context.TODO(), ef.planner, tabDesc, nil, colCfg); err != nil { 639 return nil, err 640 } 641 642 primaryIndex := tabDesc.GetPrimaryIndex() 643 tableScan.index = &primaryIndex 644 tableScan.disableBatchLimit() 645 646 n := &indexJoinNode{ 647 input: input.(planNode), 648 table: tableScan, 649 cols: colDescs, 650 resultColumns: sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), colDescs), 651 reqOrdering: ReqOrdering(reqOrdering), 652 } 653 654 n.keyCols = make([]int, len(keyCols)) 655 for i, c := range keyCols { 656 n.keyCols[i] = int(c) 657 } 658 659 return n, nil 660 } 661 662 // ConstructLookupJoin is part of the exec.Factory interface. 663 func (ef *execFactory) ConstructLookupJoin( 664 joinType sqlbase.JoinType, 665 input exec.Node, 666 table cat.Table, 667 index cat.Index, 668 eqCols []exec.NodeColumnOrdinal, 669 eqColsAreKey bool, 670 lookupCols exec.TableColumnOrdinalSet, 671 onCond tree.TypedExpr, 672 reqOrdering exec.OutputOrdering, 673 ) (exec.Node, error) { 674 if table.IsVirtualTable() { 675 return ef.constructVirtualTableLookupJoin(joinType, input, table, index, eqCols, lookupCols, onCond) 676 } 677 tabDesc := table.(*optTable).desc 678 indexDesc := index.(*optIndex).desc 679 colCfg := makeScanColumnsConfig(table, lookupCols) 680 tableScan := ef.planner.Scan() 681 682 if err := tableScan.initTable(context.TODO(), ef.planner, tabDesc, nil, colCfg); err != nil { 683 return nil, err 684 } 685 686 tableScan.index = indexDesc 687 688 n := &lookupJoinNode{ 689 input: input.(planNode), 690 table: tableScan, 691 joinType: joinType, 692 eqColsAreKey: eqColsAreKey, 693 reqOrdering: ReqOrdering(reqOrdering), 694 } 695 if onCond != nil && onCond != tree.DBoolTrue { 696 n.onCond = onCond 697 } 698 n.eqCols = make([]int, len(eqCols)) 699 for i, c := range eqCols { 700 n.eqCols[i] = int(c) 701 } 702 // Build the result columns. 703 inputCols := planColumns(input.(planNode)) 704 var scanCols sqlbase.ResultColumns 705 if joinType != sqlbase.LeftSemiJoin && joinType != sqlbase.LeftAntiJoin { 706 scanCols = planColumns(tableScan) 707 } 708 n.columns = make(sqlbase.ResultColumns, 0, len(inputCols)+len(scanCols)) 709 n.columns = append(n.columns, inputCols...) 710 n.columns = append(n.columns, scanCols...) 711 return n, nil 712 } 713 714 func (ef *execFactory) constructVirtualTableLookupJoin( 715 joinType sqlbase.JoinType, 716 input exec.Node, 717 table cat.Table, 718 index cat.Index, 719 eqCols []exec.NodeColumnOrdinal, 720 lookupCols exec.TableColumnOrdinalSet, 721 onCond tree.TypedExpr, 722 ) (exec.Node, error) { 723 tn := &table.(*optVirtualTable).name 724 virtual, err := ef.planner.getVirtualTabler().getVirtualTableEntry(tn) 725 if err != nil { 726 return nil, err 727 } 728 if len(eqCols) > 1 { 729 return nil, errors.AssertionFailedf("vtable indexes with more than one column aren't supported yet") 730 } 731 // Check for explicit use of the dummy column. 732 if lookupCols.Contains(0) { 733 return nil, errors.Errorf("use of %s column not allowed.", table.Column(0).ColName()) 734 } 735 indexDesc := index.(*optVirtualIndex).desc 736 tableDesc := table.(*optVirtualTable).desc 737 // Build the result columns. 738 inputCols := planColumns(input.(planNode)) 739 740 if onCond == tree.DBoolTrue { 741 onCond = nil 742 } 743 744 var tableScan scanNode 745 // Set up a scanNode that we won't actually use, just to get the needed 746 // column analysis. 747 colCfg := makeScanColumnsConfig(table, lookupCols) 748 if err := tableScan.initTable(context.TODO(), ef.planner, tableDesc, nil, colCfg); err != nil { 749 return nil, err 750 } 751 tableScan.index = indexDesc 752 vtableCols := sqlbase.ResultColumnsFromColDescs(tableDesc.ID, tableDesc.Columns) 753 projectedVtableCols := planColumns(&tableScan) 754 outputCols := make(sqlbase.ResultColumns, 0, len(inputCols)+len(projectedVtableCols)) 755 outputCols = append(outputCols, inputCols...) 756 outputCols = append(outputCols, projectedVtableCols...) 757 // joinType is either INNER or LEFT_OUTER. 758 pred, err := makePredicate(joinType, inputCols, projectedVtableCols) 759 if err != nil { 760 return nil, err 761 } 762 pred.onCond = pred.iVarHelper.Rebind( 763 onCond, false /* alsoReset */, false, /* normalizeToNonNil */ 764 ) 765 n := &vTableLookupJoinNode{ 766 input: input.(planNode), 767 joinType: joinType, 768 virtualTableEntry: virtual, 769 dbName: tn.Catalog(), 770 table: tableDesc.TableDesc(), 771 index: indexDesc, 772 eqCol: int(eqCols[0]), 773 inputCols: inputCols, 774 vtableCols: vtableCols, 775 lookupCols: lookupCols, 776 columns: outputCols, 777 pred: pred, 778 } 779 return n, nil 780 } 781 782 func (ef *execFactory) ConstructGeoLookupJoin( 783 joinType sqlbase.JoinType, 784 geoRelationshipType geoindex.RelationshipType, 785 input exec.Node, 786 table cat.Table, 787 index cat.Index, 788 geoCol exec.NodeColumnOrdinal, 789 lookupCols exec.TableColumnOrdinalSet, 790 onCond tree.TypedExpr, 791 reqOrdering exec.OutputOrdering, 792 ) (exec.Node, error) { 793 // TODO(rytaft, sumeerbhola): Fill this in. 794 return nil, errors.Errorf("Geospatial joins are not yet supported") 795 } 796 797 // Helper function to create a scanNode from just a table / index descriptor 798 // and requested cols. 799 func (ef *execFactory) constructScanForZigzag( 800 indexDesc *sqlbase.IndexDescriptor, 801 tableDesc *sqlbase.ImmutableTableDescriptor, 802 cols exec.NodeColumnOrdinalSet, 803 ) (*scanNode, error) { 804 805 colCfg := scanColumnsConfig{ 806 wantedColumns: make([]tree.ColumnID, 0, cols.Len()), 807 } 808 809 for c, ok := cols.Next(0); ok; c, ok = cols.Next(c + 1) { 810 colCfg.wantedColumns = append(colCfg.wantedColumns, tree.ColumnID(tableDesc.Columns[c].ID)) 811 } 812 813 scan := ef.planner.Scan() 814 if err := scan.initTable(context.TODO(), ef.planner, tableDesc, nil, colCfg); err != nil { 815 return nil, err 816 } 817 818 scan.index = indexDesc 819 820 return scan, nil 821 } 822 823 // ConstructZigzagJoin is part of the exec.Factory interface. 824 func (ef *execFactory) ConstructZigzagJoin( 825 leftTable cat.Table, 826 leftIndex cat.Index, 827 rightTable cat.Table, 828 rightIndex cat.Index, 829 leftEqCols []exec.NodeColumnOrdinal, 830 rightEqCols []exec.NodeColumnOrdinal, 831 leftCols exec.NodeColumnOrdinalSet, 832 rightCols exec.NodeColumnOrdinalSet, 833 onCond tree.TypedExpr, 834 fixedVals []exec.Node, 835 reqOrdering exec.OutputOrdering, 836 ) (exec.Node, error) { 837 leftIndexDesc := leftIndex.(*optIndex).desc 838 leftTabDesc := leftTable.(*optTable).desc 839 rightIndexDesc := rightIndex.(*optIndex).desc 840 rightTabDesc := rightTable.(*optTable).desc 841 842 leftScan, err := ef.constructScanForZigzag(leftIndexDesc, leftTabDesc, leftCols) 843 if err != nil { 844 return nil, err 845 } 846 rightScan, err := ef.constructScanForZigzag(rightIndexDesc, rightTabDesc, rightCols) 847 if err != nil { 848 return nil, err 849 } 850 851 n := &zigzagJoinNode{ 852 reqOrdering: ReqOrdering(reqOrdering), 853 } 854 if onCond != nil && onCond != tree.DBoolTrue { 855 n.onCond = onCond 856 } 857 n.sides = make([]zigzagJoinSide, 2) 858 n.sides[0].scan = leftScan 859 n.sides[1].scan = rightScan 860 n.sides[0].eqCols = make([]int, len(leftEqCols)) 861 n.sides[1].eqCols = make([]int, len(rightEqCols)) 862 863 if len(leftEqCols) != len(rightEqCols) { 864 panic("creating zigzag join with unequal number of equated cols") 865 } 866 867 for i, c := range leftEqCols { 868 n.sides[0].eqCols[i] = int(c) 869 n.sides[1].eqCols[i] = int(rightEqCols[i]) 870 } 871 // The resultant columns are identical to those from individual index scans; so 872 // reuse the resultColumns generated in the scanNodes. 873 n.columns = make( 874 sqlbase.ResultColumns, 875 0, 876 len(leftScan.resultColumns)+len(rightScan.resultColumns), 877 ) 878 n.columns = append(n.columns, leftScan.resultColumns...) 879 n.columns = append(n.columns, rightScan.resultColumns...) 880 881 // Fixed values are the values fixed for a prefix of each side's index columns. 882 // See the comment in pkg/sql/rowexec/zigzagjoiner.go for how they are used. 883 for i := range fixedVals { 884 valNode, ok := fixedVals[i].(*valuesNode) 885 if !ok { 886 panic("non-values node passed as fixed value to zigzag join") 887 } 888 if i >= len(n.sides) { 889 panic("more fixed values passed than zigzag join sides") 890 } 891 n.sides[i].fixedVals = valNode 892 } 893 return n, nil 894 } 895 896 // ConstructLimit is part of the exec.Factory interface. 897 func (ef *execFactory) ConstructLimit( 898 input exec.Node, limit, offset tree.TypedExpr, 899 ) (exec.Node, error) { 900 plan := input.(planNode) 901 // If the input plan is also a limitNode that has just an offset, and we are 902 // only applying a limit, update the existing node. This is useful because 903 // Limit and Offset are separate operators which result in separate calls to 904 // this function. 905 if l, ok := plan.(*limitNode); ok && l.countExpr == nil && offset == nil { 906 l.countExpr = limit 907 return l, nil 908 } 909 // If the input plan is a spoolNode, then propagate any constant limit to it. 910 if spool, ok := plan.(*spoolNode); ok { 911 if val, ok := limit.(*tree.DInt); ok { 912 spool.hardLimit = int64(*val) 913 } 914 } 915 return &limitNode{ 916 plan: plan, 917 countExpr: limit, 918 offsetExpr: offset, 919 }, nil 920 } 921 922 // ConstructMax1Row is part of the exec.Factory interface. 923 func (ef *execFactory) ConstructMax1Row(input exec.Node, errorText string) (exec.Node, error) { 924 plan := input.(planNode) 925 return &max1RowNode{ 926 plan: plan, 927 errorText: errorText, 928 }, nil 929 } 930 931 // ConstructBuffer is part of the exec.Factory interface. 932 func (ef *execFactory) ConstructBuffer(input exec.Node, label string) (exec.BufferNode, error) { 933 return &bufferNode{ 934 plan: input.(planNode), 935 label: label, 936 }, nil 937 } 938 939 // ConstructScanBuffer is part of the exec.Factory interface. 940 func (ef *execFactory) ConstructScanBuffer(ref exec.BufferNode, label string) (exec.Node, error) { 941 return &scanBufferNode{ 942 buffer: ref.(*bufferNode), 943 label: label, 944 }, nil 945 } 946 947 // ConstructRecursiveCTE is part of the exec.Factory interface. 948 func (ef *execFactory) ConstructRecursiveCTE( 949 initial exec.Node, fn exec.RecursiveCTEIterationFn, label string, 950 ) (exec.Node, error) { 951 return &recursiveCTENode{ 952 initial: initial.(planNode), 953 genIterationFn: fn, 954 label: label, 955 }, nil 956 } 957 958 // ConstructProjectSet is part of the exec.Factory interface. 959 func (ef *execFactory) ConstructProjectSet( 960 n exec.Node, exprs tree.TypedExprs, zipCols sqlbase.ResultColumns, numColsPerGen []int, 961 ) (exec.Node, error) { 962 src := asDataSource(n) 963 cols := append(src.columns, zipCols...) 964 p := &projectSetNode{ 965 source: src.plan, 966 sourceCols: src.columns, 967 columns: cols, 968 numColsInSource: len(src.columns), 969 exprs: exprs, 970 funcs: make([]*tree.FuncExpr, len(exprs)), 971 numColsPerGen: numColsPerGen, 972 run: projectSetRun{ 973 gens: make([]tree.ValueGenerator, len(exprs)), 974 done: make([]bool, len(exprs)), 975 rowBuffer: make(tree.Datums, len(cols)), 976 }, 977 } 978 979 for i, expr := range exprs { 980 if tFunc, ok := expr.(*tree.FuncExpr); ok && tFunc.IsGeneratorApplication() { 981 // Set-generating functions: generate_series() etc. 982 p.funcs[i] = tFunc 983 } 984 } 985 986 return p, nil 987 } 988 989 // ConstructWindow is part of the exec.Factory interface. 990 func (ef *execFactory) ConstructWindow(root exec.Node, wi exec.WindowInfo) (exec.Node, error) { 991 p := &windowNode{ 992 plan: root.(planNode), 993 columns: wi.Cols, 994 windowRender: make([]tree.TypedExpr, len(wi.Cols)), 995 } 996 997 partitionIdxs := make([]int, len(wi.Partition)) 998 for i, idx := range wi.Partition { 999 partitionIdxs[i] = int(idx) 1000 } 1001 1002 p.funcs = make([]*windowFuncHolder, len(wi.Exprs)) 1003 for i := range wi.Exprs { 1004 argsIdxs := make([]uint32, len(wi.ArgIdxs[i])) 1005 for j := range argsIdxs { 1006 argsIdxs[j] = uint32(wi.ArgIdxs[i][j]) 1007 } 1008 1009 p.funcs[i] = &windowFuncHolder{ 1010 expr: wi.Exprs[i], 1011 args: wi.Exprs[i].Exprs, 1012 argsIdxs: argsIdxs, 1013 window: p, 1014 filterColIdx: wi.FilterIdxs[i], 1015 outputColIdx: wi.OutputIdxs[i], 1016 partitionIdxs: partitionIdxs, 1017 columnOrdering: wi.Ordering, 1018 frame: wi.Exprs[i].WindowDef.Frame, 1019 } 1020 if len(wi.Ordering) == 0 { 1021 frame := p.funcs[i].frame 1022 if frame.Mode == tree.RANGE && frame.Bounds.HasOffset() { 1023 // We have an empty ordering, but RANGE mode when at least one bound 1024 // has 'offset' requires a single column in ORDER BY. We have optimized 1025 // it out, but the execution still needs information about which column 1026 // it was, so we reconstruct the "original" ordering (note that the 1027 // direction of the ordering doesn't actually matter, so we leave it 1028 // with the default value). 1029 p.funcs[i].columnOrdering = sqlbase.ColumnOrdering{ 1030 sqlbase.ColumnOrderInfo{ 1031 ColIdx: int(wi.RangeOffsetColumn), 1032 }, 1033 } 1034 } 1035 } 1036 1037 p.windowRender[wi.OutputIdxs[i]] = p.funcs[i] 1038 } 1039 1040 return p, nil 1041 } 1042 1043 // ConstructPlan is part of the exec.Factory interface. 1044 func (ef *execFactory) ConstructPlan( 1045 root exec.Node, subqueries []exec.Subquery, cascades []exec.Cascade, checks []exec.Node, 1046 ) (exec.Plan, error) { 1047 // No need to spool at the root. 1048 if spool, ok := root.(*spoolNode); ok { 1049 root = spool.source 1050 } 1051 res := &planTop{ 1052 // TODO(radu): these fields can be modified by planning various opaque 1053 // statements. We should have a cleaner way of plumbing these. 1054 avoidBuffering: ef.planner.curPlan.avoidBuffering, 1055 auditEvents: ef.planner.curPlan.auditEvents, 1056 instrumentation: ef.planner.curPlan.instrumentation, 1057 } 1058 res.main.planNode = root.(planNode) 1059 if len(subqueries) > 0 { 1060 res.subqueryPlans = make([]subquery, len(subqueries)) 1061 for i := range subqueries { 1062 in := &subqueries[i] 1063 out := &res.subqueryPlans[i] 1064 out.subquery = in.ExprNode 1065 switch in.Mode { 1066 case exec.SubqueryExists: 1067 out.execMode = rowexec.SubqueryExecModeExists 1068 case exec.SubqueryOneRow: 1069 out.execMode = rowexec.SubqueryExecModeOneRow 1070 case exec.SubqueryAnyRows: 1071 out.execMode = rowexec.SubqueryExecModeAllRowsNormalized 1072 case exec.SubqueryAllRows: 1073 out.execMode = rowexec.SubqueryExecModeAllRows 1074 default: 1075 return nil, errors.Errorf("invalid SubqueryMode %d", in.Mode) 1076 } 1077 out.expanded = true 1078 out.plan.planNode = in.Root.(planNode) 1079 } 1080 } 1081 if len(cascades) > 0 { 1082 res.cascades = make([]cascadeMetadata, len(cascades)) 1083 for i := range cascades { 1084 res.cascades[i].Cascade = cascades[i] 1085 } 1086 } 1087 if len(checks) > 0 { 1088 res.checkPlans = make([]checkPlan, len(checks)) 1089 for i := range checks { 1090 res.checkPlans[i].plan.planNode = checks[i].(planNode) 1091 } 1092 } 1093 1094 return res, nil 1095 } 1096 1097 // urlOutputter handles writing strings into an encoded URL for EXPLAIN (OPT, 1098 // ENV). It also ensures that (in the text that is encoded by the URL) each 1099 // entry gets its own line and there's exactly one blank line between entries. 1100 type urlOutputter struct { 1101 buf bytes.Buffer 1102 } 1103 1104 func (e *urlOutputter) writef(format string, args ...interface{}) { 1105 if e.buf.Len() > 0 { 1106 e.buf.WriteString("\n") 1107 } 1108 fmt.Fprintf(&e.buf, format, args...) 1109 } 1110 1111 func (e *urlOutputter) finish() (url.URL, error) { 1112 // Generate a URL that encodes all the text. 1113 var compressed bytes.Buffer 1114 encoder := base64.NewEncoder(base64.URLEncoding, &compressed) 1115 compressor := zlib.NewWriter(encoder) 1116 if _, err := e.buf.WriteTo(compressor); err != nil { 1117 return url.URL{}, err 1118 } 1119 if err := compressor.Close(); err != nil { 1120 return url.URL{}, err 1121 } 1122 if err := encoder.Close(); err != nil { 1123 return url.URL{}, err 1124 } 1125 return url.URL{ 1126 Scheme: "https", 1127 Host: "cockroachdb.github.io", 1128 Path: "text/decode.html", 1129 Fragment: compressed.String(), 1130 }, nil 1131 } 1132 1133 // showEnv implements EXPLAIN (opt, env). It returns a node which displays 1134 // the environment a query was run in. 1135 func (ef *execFactory) showEnv(plan string, envOpts exec.ExplainEnvData) (exec.Node, error) { 1136 var out urlOutputter 1137 1138 c := makeStmtEnvCollector( 1139 ef.planner.EvalContext().Context, 1140 ef.planner.extendedEvalCtx.InternalExecutor.(*InternalExecutor), 1141 ) 1142 1143 // Show the version of Cockroach running. 1144 if err := c.PrintVersion(&out.buf); err != nil { 1145 return nil, err 1146 } 1147 out.writef("") 1148 // Show the values of any non-default session variables that can impact 1149 // planning decisions. 1150 if err := c.PrintSettings(&out.buf); err != nil { 1151 return nil, err 1152 } 1153 1154 // Show the definition of each referenced catalog object. 1155 for i := range envOpts.Sequences { 1156 out.writef("") 1157 if err := c.PrintCreateSequence(&out.buf, &envOpts.Sequences[i]); err != nil { 1158 return nil, err 1159 } 1160 } 1161 1162 // TODO(justin): it might also be relevant in some cases to print the create 1163 // statements for tables referenced via FKs in these tables. 1164 for i := range envOpts.Tables { 1165 out.writef("") 1166 if err := c.PrintCreateTable(&out.buf, &envOpts.Tables[i]); err != nil { 1167 return nil, err 1168 } 1169 out.writef("") 1170 1171 // In addition to the schema, it's important to know what the table 1172 // statistics on each table are. 1173 1174 // NOTE: We don't include the histograms because they take up a ton of 1175 // vertical space. Unfortunately this means that in some cases we won't be 1176 // able to reproduce a particular plan. 1177 err := c.PrintTableStats(&out.buf, &envOpts.Tables[i], true /* hideHistograms */) 1178 if err != nil { 1179 return nil, err 1180 } 1181 } 1182 1183 for i := range envOpts.Views { 1184 out.writef("") 1185 if err := c.PrintCreateView(&out.buf, &envOpts.Views[i]); err != nil { 1186 return nil, err 1187 } 1188 } 1189 1190 // Show the query running. Note that this is the *entire* query, including 1191 // the "EXPLAIN (opt, env)" preamble. 1192 out.writef("%s;\n----\n%s", ef.planner.stmt.AST.String(), plan) 1193 1194 url, err := out.finish() 1195 if err != nil { 1196 return nil, err 1197 } 1198 return &valuesNode{ 1199 columns: sqlbase.ExplainOptColumns, 1200 tuples: [][]tree.TypedExpr{{tree.NewDString(url.String())}}, 1201 specifiedInQuery: true, 1202 }, nil 1203 } 1204 1205 // ConstructExplainOpt is part of the exec.Factory interface. 1206 func (ef *execFactory) ConstructExplainOpt( 1207 planText string, envOpts exec.ExplainEnvData, 1208 ) (exec.Node, error) { 1209 // If this was an EXPLAIN (opt, env), we need to run a bunch of auxiliary 1210 // queries to fetch the environment info. 1211 if envOpts.ShowEnv { 1212 return ef.showEnv(planText, envOpts) 1213 } 1214 1215 var rows [][]tree.TypedExpr 1216 ss := strings.Split(strings.Trim(planText, "\n"), "\n") 1217 for _, line := range ss { 1218 rows = append(rows, []tree.TypedExpr{tree.NewDString(line)}) 1219 } 1220 1221 return &valuesNode{ 1222 columns: sqlbase.ExplainOptColumns, 1223 tuples: rows, 1224 specifiedInQuery: true, 1225 }, nil 1226 } 1227 1228 // ConstructExplain is part of the exec.Factory interface. 1229 func (ef *execFactory) ConstructExplain( 1230 options *tree.ExplainOptions, stmtType tree.StatementType, plan exec.Plan, 1231 ) (exec.Node, error) { 1232 p := plan.(*planTop) 1233 1234 analyzeSet := options.Flags[tree.ExplainFlagAnalyze] 1235 1236 if options.Flags[tree.ExplainFlagEnv] { 1237 return nil, errors.New("ENV only supported with (OPT) option") 1238 } 1239 1240 switch options.Mode { 1241 case tree.ExplainDistSQL: 1242 return &explainDistSQLNode{ 1243 options: options, 1244 plan: p.planComponents, 1245 analyze: analyzeSet, 1246 stmtType: stmtType, 1247 }, nil 1248 1249 case tree.ExplainVec: 1250 return &explainVecNode{ 1251 options: options, 1252 plan: p.main, 1253 subqueryPlans: p.subqueryPlans, 1254 stmtType: stmtType, 1255 }, nil 1256 1257 case tree.ExplainPlan: 1258 if analyzeSet { 1259 return nil, errors.New("EXPLAIN ANALYZE only supported with (DISTSQL) option") 1260 } 1261 return ef.planner.makeExplainPlanNodeWithPlan( 1262 context.TODO(), 1263 options, 1264 &p.planComponents, 1265 stmtType, 1266 ) 1267 1268 default: 1269 panic(fmt.Sprintf("unsupported explain mode %v", options.Mode)) 1270 } 1271 } 1272 1273 // ConstructShowTrace is part of the exec.Factory interface. 1274 func (ef *execFactory) ConstructShowTrace(typ tree.ShowTraceType, compact bool) (exec.Node, error) { 1275 var node planNode = ef.planner.makeShowTraceNode(compact, typ == tree.ShowTraceKV) 1276 1277 // Ensure the messages are sorted in age order, so that the user 1278 // does not get confused. 1279 ageColIdx := sqlbase.GetTraceAgeColumnIdx(compact) 1280 node = &sortNode{ 1281 plan: node, 1282 ordering: sqlbase.ColumnOrdering{ 1283 sqlbase.ColumnOrderInfo{ColIdx: ageColIdx, Direction: encoding.Ascending}, 1284 }, 1285 } 1286 1287 if typ == tree.ShowTraceReplica { 1288 node = &showTraceReplicaNode{plan: node} 1289 } 1290 return node, nil 1291 } 1292 1293 func (ef *execFactory) ConstructInsert( 1294 input exec.Node, 1295 table cat.Table, 1296 insertColOrdSet exec.TableColumnOrdinalSet, 1297 returnColOrdSet exec.TableColumnOrdinalSet, 1298 checkOrdSet exec.CheckOrdinalSet, 1299 allowAutoCommit bool, 1300 skipFKChecks bool, 1301 ) (exec.Node, error) { 1302 ctx := ef.planner.extendedEvalCtx.Context 1303 1304 // Derive insert table and column descriptors. 1305 rowsNeeded := !returnColOrdSet.Empty() 1306 tabDesc := table.(*optTable).desc 1307 colDescs := makeColDescList(table, insertColOrdSet) 1308 1309 if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil { 1310 return nil, err 1311 } 1312 1313 var fkTables row.FkTableMetadata 1314 checkFKs := row.SkipFKs 1315 if !skipFKChecks { 1316 checkFKs = row.CheckFKs 1317 // Determine the foreign key tables involved in the update. 1318 var err error 1319 fkTables, err = ef.makeFkMetadata(tabDesc, row.CheckInserts) 1320 if err != nil { 1321 return nil, err 1322 } 1323 } 1324 // Create the table inserter, which does the bulk of the work. 1325 ri, err := row.MakeInserter( 1326 ctx, ef.planner.txn, ef.planner.ExecCfg().Codec, tabDesc, colDescs, checkFKs, fkTables, ef.planner.alloc, 1327 ) 1328 if err != nil { 1329 return nil, err 1330 } 1331 1332 // Regular path for INSERT. 1333 ins := insertNodePool.Get().(*insertNode) 1334 *ins = insertNode{ 1335 source: input.(planNode), 1336 run: insertRun{ 1337 ti: tableInserter{ri: ri}, 1338 checkOrds: checkOrdSet, 1339 insertCols: ri.InsertCols, 1340 }, 1341 } 1342 1343 // If rows are not needed, no columns are returned. 1344 if rowsNeeded { 1345 returnColDescs := makeColDescList(table, returnColOrdSet) 1346 ins.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs) 1347 1348 // Set the tabColIdxToRetIdx for the mutation. Insert always returns 1349 // non-mutation columns in the same order they are defined in the table. 1350 ins.run.tabColIdxToRetIdx = row.ColMapping(tabDesc.Columns, returnColDescs) 1351 ins.run.rowsNeeded = true 1352 } 1353 1354 if allowAutoCommit && ef.allowAutoCommit { 1355 ins.enableAutoCommit() 1356 } 1357 1358 // serialize the data-modifying plan to ensure that no data is 1359 // observed that hasn't been validated first. See the comments 1360 // on BatchedNext() in plan_batch.go. 1361 if rowsNeeded { 1362 return &spoolNode{source: &serializeNode{source: ins}}, nil 1363 } 1364 1365 // We could use serializeNode here, but using rowCountNode is an 1366 // optimization that saves on calls to Next() by the caller. 1367 return &rowCountNode{source: ins}, nil 1368 } 1369 1370 func (ef *execFactory) ConstructInsertFastPath( 1371 rows [][]tree.TypedExpr, 1372 table cat.Table, 1373 insertColOrdSet exec.TableColumnOrdinalSet, 1374 returnColOrdSet exec.TableColumnOrdinalSet, 1375 checkOrdSet exec.CheckOrdinalSet, 1376 fkChecks []exec.InsertFastPathFKCheck, 1377 ) (exec.Node, error) { 1378 ctx := ef.planner.extendedEvalCtx.Context 1379 1380 // Derive insert table and column descriptors. 1381 rowsNeeded := !returnColOrdSet.Empty() 1382 tabDesc := table.(*optTable).desc 1383 colDescs := makeColDescList(table, insertColOrdSet) 1384 1385 if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil { 1386 return nil, err 1387 } 1388 1389 // Create the table inserter, which does the bulk of the work. 1390 ri, err := row.MakeInserter( 1391 ctx, ef.planner.txn, ef.planner.ExecCfg().Codec, tabDesc, colDescs, row.SkipFKs, nil /* fkTables */, ef.planner.alloc, 1392 ) 1393 if err != nil { 1394 return nil, err 1395 } 1396 1397 // Regular path for INSERT. 1398 ins := insertFastPathNodePool.Get().(*insertFastPathNode) 1399 *ins = insertFastPathNode{ 1400 input: rows, 1401 run: insertFastPathRun{ 1402 insertRun: insertRun{ 1403 ti: tableInserter{ri: ri}, 1404 checkOrds: checkOrdSet, 1405 insertCols: ri.InsertCols, 1406 }, 1407 }, 1408 } 1409 1410 if len(fkChecks) > 0 { 1411 ins.run.fkChecks = make([]insertFastPathFKCheck, len(fkChecks)) 1412 for i := range fkChecks { 1413 ins.run.fkChecks[i].InsertFastPathFKCheck = fkChecks[i] 1414 } 1415 } 1416 1417 // If rows are not needed, no columns are returned. 1418 if rowsNeeded { 1419 returnColDescs := makeColDescList(table, returnColOrdSet) 1420 ins.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs) 1421 1422 // Set the tabColIdxToRetIdx for the mutation. Insert always returns 1423 // non-mutation columns in the same order they are defined in the table. 1424 ins.run.tabColIdxToRetIdx = row.ColMapping(tabDesc.Columns, returnColDescs) 1425 ins.run.rowsNeeded = true 1426 } 1427 1428 if len(rows) == 0 { 1429 return &zeroNode{columns: ins.columns}, nil 1430 } 1431 1432 if ef.allowAutoCommit { 1433 ins.enableAutoCommit() 1434 } 1435 1436 // serialize the data-modifying plan to ensure that no data is 1437 // observed that hasn't been validated first. See the comments 1438 // on BatchedNext() in plan_batch.go. 1439 if rowsNeeded { 1440 return &spoolNode{source: &serializeNode{source: ins}}, nil 1441 } 1442 1443 // We could use serializeNode here, but using rowCountNode is an 1444 // optimization that saves on calls to Next() by the caller. 1445 return &rowCountNode{source: ins}, nil 1446 } 1447 1448 func (ef *execFactory) ConstructUpdate( 1449 input exec.Node, 1450 table cat.Table, 1451 fetchColOrdSet exec.TableColumnOrdinalSet, 1452 updateColOrdSet exec.TableColumnOrdinalSet, 1453 returnColOrdSet exec.TableColumnOrdinalSet, 1454 checks exec.CheckOrdinalSet, 1455 passthrough sqlbase.ResultColumns, 1456 allowAutoCommit bool, 1457 skipFKChecks bool, 1458 ) (exec.Node, error) { 1459 ctx := ef.planner.extendedEvalCtx.Context 1460 1461 // Derive table and column descriptors. 1462 rowsNeeded := !returnColOrdSet.Empty() 1463 tabDesc := table.(*optTable).desc 1464 fetchColDescs := makeColDescList(table, fetchColOrdSet) 1465 1466 if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil { 1467 return nil, err 1468 } 1469 1470 // Add each column to update as a sourceSlot. The CBO only uses scalarSlot, 1471 // since it compiles tuples and subqueries into a simple sequence of target 1472 // columns. 1473 updateColDescs := makeColDescList(table, updateColOrdSet) 1474 sourceSlots := make([]sourceSlot, len(updateColDescs)) 1475 for i := range sourceSlots { 1476 sourceSlots[i] = scalarSlot{column: updateColDescs[i], sourceIndex: len(fetchColDescs) + i} 1477 } 1478 1479 var fkTables row.FkTableMetadata 1480 checkFKs := row.SkipFKs 1481 if !skipFKChecks { 1482 checkFKs = row.CheckFKs 1483 // Determine the foreign key tables involved in the update. 1484 var err error 1485 fkTables, err = ef.makeFkMetadata(tabDesc, row.CheckUpdates) 1486 if err != nil { 1487 return nil, err 1488 } 1489 } 1490 1491 // Create the table updater, which does the bulk of the work. 1492 ru, err := row.MakeUpdater( 1493 ctx, 1494 ef.planner.txn, 1495 ef.planner.ExecCfg().Codec, 1496 tabDesc, 1497 fkTables, 1498 updateColDescs, 1499 fetchColDescs, 1500 row.UpdaterDefault, 1501 checkFKs, 1502 ef.planner.EvalContext(), 1503 ef.planner.alloc, 1504 ) 1505 if err != nil { 1506 return nil, err 1507 } 1508 1509 // Truncate any FetchCols added by MakeUpdater. The optimizer has already 1510 // computed a correct set that can sometimes be smaller. 1511 ru.FetchCols = ru.FetchCols[:len(fetchColDescs)] 1512 1513 // updateColsIdx inverts the mapping of UpdateCols to FetchCols. See 1514 // the explanatory comments in updateRun. 1515 updateColsIdx := make(map[sqlbase.ColumnID]int, len(ru.UpdateCols)) 1516 for i := range ru.UpdateCols { 1517 id := ru.UpdateCols[i].ID 1518 updateColsIdx[id] = i 1519 } 1520 1521 upd := updateNodePool.Get().(*updateNode) 1522 *upd = updateNode{ 1523 source: input.(planNode), 1524 run: updateRun{ 1525 tu: tableUpdater{ru: ru}, 1526 checkOrds: checks, 1527 iVarContainerForComputedCols: sqlbase.RowIndexedVarContainer{ 1528 CurSourceRow: make(tree.Datums, len(ru.FetchCols)), 1529 Cols: ru.FetchCols, 1530 Mapping: ru.FetchColIDtoRowIndex, 1531 }, 1532 sourceSlots: sourceSlots, 1533 updateValues: make(tree.Datums, len(ru.UpdateCols)), 1534 updateColsIdx: updateColsIdx, 1535 numPassthrough: len(passthrough), 1536 }, 1537 } 1538 1539 // If rows are not needed, no columns are returned. 1540 if rowsNeeded { 1541 returnColDescs := makeColDescList(table, returnColOrdSet) 1542 1543 upd.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs) 1544 // Add the passthrough columns to the returning columns. 1545 upd.columns = append(upd.columns, passthrough...) 1546 1547 // Set the rowIdxToRetIdx for the mutation. Update returns the non-mutation 1548 // columns specified, in the same order they are defined in the table. 1549 // 1550 // The Updater derives/stores the fetch columns of the mutation and 1551 // since the return columns are always a subset of the fetch columns, 1552 // we can use use the fetch columns to generate the mapping for the 1553 // returned rows. 1554 upd.run.rowIdxToRetIdx = row.ColMapping(ru.FetchCols, returnColDescs) 1555 upd.run.rowsNeeded = true 1556 } 1557 1558 if allowAutoCommit && ef.allowAutoCommit { 1559 upd.enableAutoCommit() 1560 } 1561 1562 // Serialize the data-modifying plan to ensure that no data is observed that 1563 // hasn't been validated first. See the comments on BatchedNext() in 1564 // plan_batch.go. 1565 if rowsNeeded { 1566 return &spoolNode{source: &serializeNode{source: upd}}, nil 1567 } 1568 1569 // We could use serializeNode here, but using rowCountNode is an 1570 // optimization that saves on calls to Next() by the caller. 1571 return &rowCountNode{source: upd}, nil 1572 } 1573 1574 func (ef *execFactory) makeFkMetadata( 1575 tabDesc *sqlbase.ImmutableTableDescriptor, fkCheckType row.FKCheckType, 1576 ) (row.FkTableMetadata, error) { 1577 ctx := ef.planner.extendedEvalCtx.Context 1578 1579 // Create a CheckHelper, used in case of cascading actions that cause changes 1580 // in the original table. This is only possible with UPDATE (together with 1581 // cascade loops or self-references). 1582 var checkHelper *sqlbase.CheckHelper 1583 if fkCheckType == row.CheckUpdates { 1584 var err error 1585 checkHelper, err = sqlbase.NewEvalCheckHelper(ctx, ef.planner.analyzeExpr, tabDesc) 1586 if err != nil { 1587 return nil, err 1588 } 1589 } 1590 // Determine the foreign key tables involved in the upsert. 1591 return row.MakeFkMetadata( 1592 ef.planner.extendedEvalCtx.Context, 1593 tabDesc, 1594 fkCheckType, 1595 ef.planner.LookupTableByID, 1596 ef.planner.CheckPrivilege, 1597 ef.planner.analyzeExpr, 1598 checkHelper, 1599 ) 1600 } 1601 1602 func (ef *execFactory) ConstructUpsert( 1603 input exec.Node, 1604 table cat.Table, 1605 canaryCol exec.NodeColumnOrdinal, 1606 insertColOrdSet exec.TableColumnOrdinalSet, 1607 fetchColOrdSet exec.TableColumnOrdinalSet, 1608 updateColOrdSet exec.TableColumnOrdinalSet, 1609 returnColOrdSet exec.TableColumnOrdinalSet, 1610 checks exec.CheckOrdinalSet, 1611 allowAutoCommit bool, 1612 skipFKChecks bool, 1613 ) (exec.Node, error) { 1614 ctx := ef.planner.extendedEvalCtx.Context 1615 1616 // Derive table and column descriptors. 1617 rowsNeeded := !returnColOrdSet.Empty() 1618 tabDesc := table.(*optTable).desc 1619 insertColDescs := makeColDescList(table, insertColOrdSet) 1620 fetchColDescs := makeColDescList(table, fetchColOrdSet) 1621 updateColDescs := makeColDescList(table, updateColOrdSet) 1622 1623 if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil { 1624 return nil, err 1625 } 1626 1627 var fkTables row.FkTableMetadata 1628 checkFKs := row.SkipFKs 1629 if !skipFKChecks { 1630 checkFKs = row.CheckFKs 1631 1632 // Determine the foreign key tables involved in the upsert. 1633 var err error 1634 fkTables, err = ef.makeFkMetadata(tabDesc, row.CheckUpdates) 1635 if err != nil { 1636 return nil, err 1637 } 1638 } 1639 1640 // Create the table inserter, which does the bulk of the insert-related work. 1641 ri, err := row.MakeInserter( 1642 ctx, 1643 ef.planner.txn, 1644 ef.planner.ExecCfg().Codec, 1645 tabDesc, 1646 insertColDescs, 1647 checkFKs, 1648 fkTables, 1649 ef.planner.alloc, 1650 ) 1651 if err != nil { 1652 return nil, err 1653 } 1654 1655 // Create the table updater, which does the bulk of the update-related work. 1656 ru, err := row.MakeUpdater( 1657 ctx, 1658 ef.planner.txn, 1659 ef.planner.ExecCfg().Codec, 1660 tabDesc, 1661 fkTables, 1662 updateColDescs, 1663 fetchColDescs, 1664 row.UpdaterDefault, 1665 checkFKs, 1666 ef.planner.EvalContext(), 1667 ef.planner.alloc, 1668 ) 1669 if err != nil { 1670 return nil, err 1671 } 1672 1673 // Truncate any FetchCols added by MakeUpdater. The optimizer has already 1674 // computed a correct set that can sometimes be smaller. 1675 ru.FetchCols = ru.FetchCols[:len(fetchColDescs)] 1676 1677 // updateColsIdx inverts the mapping of UpdateCols to FetchCols. See 1678 // the explanatory comments in updateRun. 1679 updateColsIdx := make(map[sqlbase.ColumnID]int, len(ru.UpdateCols)) 1680 for i := range ru.UpdateCols { 1681 id := ru.UpdateCols[i].ID 1682 updateColsIdx[id] = i 1683 } 1684 1685 // Instantiate the upsert node. 1686 ups := upsertNodePool.Get().(*upsertNode) 1687 *ups = upsertNode{ 1688 source: input.(planNode), 1689 run: upsertRun{ 1690 checkOrds: checks, 1691 insertCols: ri.InsertCols, 1692 tw: optTableUpserter{ 1693 ri: ri, 1694 alloc: ef.planner.alloc, 1695 canaryOrdinal: int(canaryCol), 1696 fkTables: fkTables, 1697 fetchCols: fetchColDescs, 1698 updateCols: updateColDescs, 1699 ru: ru, 1700 }, 1701 }, 1702 } 1703 1704 // If rows are not needed, no columns are returned. 1705 if rowsNeeded { 1706 returnColDescs := makeColDescList(table, returnColOrdSet) 1707 ups.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs) 1708 1709 // Update the tabColIdxToRetIdx for the mutation. Upsert returns 1710 // non-mutation columns specified, in the same order they are defined 1711 // in the table. 1712 ups.run.tw.tabColIdxToRetIdx = row.ColMapping(tabDesc.Columns, returnColDescs) 1713 ups.run.tw.returnCols = returnColDescs 1714 ups.run.tw.collectRows = true 1715 } 1716 1717 if allowAutoCommit && ef.allowAutoCommit { 1718 ups.enableAutoCommit() 1719 } 1720 1721 // Serialize the data-modifying plan to ensure that no data is observed that 1722 // hasn't been validated first. See the comments on BatchedNext() in 1723 // plan_batch.go. 1724 if rowsNeeded { 1725 return &spoolNode{source: &serializeNode{source: ups}}, nil 1726 } 1727 1728 // We could use serializeNode here, but using rowCountNode is an 1729 // optimization that saves on calls to Next() by the caller. 1730 return &rowCountNode{source: ups}, nil 1731 } 1732 1733 func (ef *execFactory) ConstructDelete( 1734 input exec.Node, 1735 table cat.Table, 1736 fetchColOrdSet exec.TableColumnOrdinalSet, 1737 returnColOrdSet exec.TableColumnOrdinalSet, 1738 allowAutoCommit bool, 1739 skipFKChecks bool, 1740 ) (exec.Node, error) { 1741 ctx := ef.planner.extendedEvalCtx.Context 1742 1743 // Derive table and column descriptors. 1744 rowsNeeded := !returnColOrdSet.Empty() 1745 tabDesc := table.(*optTable).desc 1746 fetchColDescs := makeColDescList(table, fetchColOrdSet) 1747 1748 if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil { 1749 return nil, err 1750 } 1751 1752 var fkTables row.FkTableMetadata 1753 checkFKs := row.SkipFKs 1754 if !skipFKChecks { 1755 checkFKs = row.CheckFKs 1756 // Determine the foreign key tables involved in the update. 1757 var err error 1758 fkTables, err = ef.makeFkMetadata(tabDesc, row.CheckDeletes) 1759 if err != nil { 1760 return nil, err 1761 } 1762 } 1763 // Create the table deleter, which does the bulk of the work. In the HP, 1764 // the deleter derives the columns that need to be fetched. By contrast, the 1765 // CBO will have already determined the set of fetch columns, and passes 1766 // those sets into the deleter (which will basically be a no-op). 1767 rd, err := row.MakeDeleter( 1768 ctx, 1769 ef.planner.txn, 1770 ef.planner.ExecCfg().Codec, 1771 tabDesc, 1772 fkTables, 1773 fetchColDescs, 1774 checkFKs, 1775 ef.planner.EvalContext(), 1776 ef.planner.alloc, 1777 ) 1778 if err != nil { 1779 return nil, err 1780 } 1781 1782 // Truncate any FetchCols added by MakeUpdater. The optimizer has already 1783 // computed a correct set that can sometimes be smaller. 1784 rd.FetchCols = rd.FetchCols[:len(fetchColDescs)] 1785 1786 // Now make a delete node. We use a pool. 1787 del := deleteNodePool.Get().(*deleteNode) 1788 *del = deleteNode{ 1789 source: input.(planNode), 1790 run: deleteRun{ 1791 td: tableDeleter{rd: rd, alloc: ef.planner.alloc}, 1792 }, 1793 } 1794 1795 // If rows are not needed, no columns are returned. 1796 if rowsNeeded { 1797 returnColDescs := makeColDescList(table, returnColOrdSet) 1798 // Delete returns the non-mutation columns specified, in the same 1799 // order they are defined in the table. 1800 del.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs) 1801 1802 del.run.rowIdxToRetIdx = row.ColMapping(rd.FetchCols, returnColDescs) 1803 del.run.rowsNeeded = true 1804 } 1805 1806 if allowAutoCommit && ef.allowAutoCommit { 1807 del.enableAutoCommit() 1808 } 1809 1810 // Serialize the data-modifying plan to ensure that no data is observed that 1811 // hasn't been validated first. See the comments on BatchedNext() in 1812 // plan_batch.go. 1813 if rowsNeeded { 1814 return &spoolNode{source: &serializeNode{source: del}}, nil 1815 } 1816 1817 // We could use serializeNode here, but using rowCountNode is an 1818 // optimization that saves on calls to Next() by the caller. 1819 return &rowCountNode{source: del}, nil 1820 } 1821 1822 func (ef *execFactory) ConstructDeleteRange( 1823 table cat.Table, 1824 needed exec.TableColumnOrdinalSet, 1825 indexConstraint *constraint.Constraint, 1826 interleavedTables []cat.Table, 1827 maxReturnedKeys int, 1828 allowAutoCommit bool, 1829 ) (exec.Node, error) { 1830 tabDesc := table.(*optTable).desc 1831 indexDesc := &tabDesc.PrimaryIndex 1832 sb := span.MakeBuilder(ef.planner.ExecCfg().Codec, tabDesc.TableDesc(), indexDesc) 1833 1834 if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil { 1835 return nil, err 1836 } 1837 1838 // Setting the "forDelete" flag includes all column families in case where a 1839 // single record is deleted. 1840 spans, err := sb.SpansFromConstraint(indexConstraint, needed, true /* forDelete */) 1841 if err != nil { 1842 return nil, err 1843 } 1844 1845 // Permitting autocommit in DeleteRange is very important, because DeleteRange 1846 // is used for simple deletes from primary indexes like 1847 // DELETE FROM t WHERE key = 1000 1848 // When possible, we need to make this a 1pc transaction for performance 1849 // reasons. At the same time, we have to be careful, because DeleteRange 1850 // returns all of the keys that it deleted - so we have to set a limit on the 1851 // DeleteRange request. But, trying to set autocommit and a limit on the 1852 // request doesn't work properly if the limit is hit. So, we permit autocommit 1853 // here if we can guarantee that the number of returned keys is finite and 1854 // relatively small. 1855 autoCommitEnabled := allowAutoCommit && ef.allowAutoCommit 1856 // If maxReturnedKeys is 0, it indicates that we weren't able to determine 1857 // the maximum number of returned keys, so we'll give up and not permit 1858 // autocommit. 1859 if maxReturnedKeys == 0 || maxReturnedKeys > TableTruncateChunkSize { 1860 autoCommitEnabled = false 1861 } 1862 1863 dr := &deleteRangeNode{ 1864 interleavedFastPath: false, 1865 spans: spans, 1866 desc: tabDesc, 1867 autoCommitEnabled: autoCommitEnabled, 1868 } 1869 1870 if len(interleavedTables) > 0 { 1871 dr.interleavedFastPath = true 1872 dr.interleavedDesc = make([]*sqlbase.ImmutableTableDescriptor, len(interleavedTables)) 1873 for i := range dr.interleavedDesc { 1874 dr.interleavedDesc[i] = interleavedTables[i].(*optTable).desc 1875 } 1876 } 1877 return dr, nil 1878 } 1879 1880 // ConstructCreateTable is part of the exec.Factory interface. 1881 func (ef *execFactory) ConstructCreateTable( 1882 input exec.Node, schema cat.Schema, ct *tree.CreateTable, 1883 ) (exec.Node, error) { 1884 nd := &createTableNode{n: ct, dbDesc: schema.(*optSchema).desc} 1885 if input != nil { 1886 nd.sourcePlan = input.(planNode) 1887 } 1888 return nd, nil 1889 } 1890 1891 // ConstructCreateView is part of the exec.Factory interface. 1892 func (ef *execFactory) ConstructCreateView( 1893 schema cat.Schema, 1894 viewName string, 1895 ifNotExists bool, 1896 replace bool, 1897 temporary bool, 1898 viewQuery string, 1899 columns sqlbase.ResultColumns, 1900 deps opt.ViewDeps, 1901 ) (exec.Node, error) { 1902 1903 planDeps := make(planDependencies, len(deps)) 1904 for _, d := range deps { 1905 desc, err := getDescForDataSource(d.DataSource) 1906 if err != nil { 1907 return nil, err 1908 } 1909 var ref sqlbase.TableDescriptor_Reference 1910 if d.SpecificIndex { 1911 idx := d.DataSource.(cat.Table).Index(d.Index) 1912 ref.IndexID = idx.(*optIndex).desc.ID 1913 } 1914 if !d.ColumnOrdinals.Empty() { 1915 ref.ColumnIDs = make([]sqlbase.ColumnID, 0, d.ColumnOrdinals.Len()) 1916 d.ColumnOrdinals.ForEach(func(ord int) { 1917 ref.ColumnIDs = append(ref.ColumnIDs, desc.Columns[ord].ID) 1918 }) 1919 } 1920 entry := planDeps[desc.ID] 1921 entry.desc = desc 1922 entry.deps = append(entry.deps, ref) 1923 planDeps[desc.ID] = entry 1924 } 1925 1926 return &createViewNode{ 1927 viewName: tree.Name(viewName), 1928 ifNotExists: ifNotExists, 1929 replace: replace, 1930 temporary: temporary, 1931 viewQuery: viewQuery, 1932 dbDesc: schema.(*optSchema).desc, 1933 columns: columns, 1934 planDeps: planDeps, 1935 }, nil 1936 } 1937 1938 // ConstructSequenceSelect is part of the exec.Factory interface. 1939 func (ef *execFactory) ConstructSequenceSelect(sequence cat.Sequence) (exec.Node, error) { 1940 return ef.planner.SequenceSelectNode(sequence.(*optSequence).desc) 1941 } 1942 1943 // ConstructSaveTable is part of the exec.Factory interface. 1944 func (ef *execFactory) ConstructSaveTable( 1945 input exec.Node, table *cat.DataSourceName, colNames []string, 1946 ) (exec.Node, error) { 1947 return ef.planner.makeSaveTable(input.(planNode), table, colNames), nil 1948 } 1949 1950 // ConstructErrorIfRows is part of the exec.Factory interface. 1951 func (ef *execFactory) ConstructErrorIfRows( 1952 input exec.Node, mkErr func(tree.Datums) error, 1953 ) (exec.Node, error) { 1954 return &errorIfRowsNode{ 1955 plan: input.(planNode), 1956 mkErr: mkErr, 1957 }, nil 1958 } 1959 1960 // ConstructOpaque is part of the exec.Factory interface. 1961 func (ef *execFactory) ConstructOpaque(metadata opt.OpaqueMetadata) (exec.Node, error) { 1962 o, ok := metadata.(*opaqueMetadata) 1963 if !ok { 1964 return nil, errors.AssertionFailedf("unexpected OpaqueMetadata object type %T", metadata) 1965 } 1966 return o.plan, nil 1967 } 1968 1969 // ConstructAlterTableSplit is part of the exec.Factory interface. 1970 func (ef *execFactory) ConstructAlterTableSplit( 1971 index cat.Index, input exec.Node, expiration tree.TypedExpr, 1972 ) (exec.Node, error) { 1973 expirationTime, err := parseExpirationTime(ef.planner.EvalContext(), expiration) 1974 if err != nil { 1975 return nil, err 1976 } 1977 1978 return &splitNode{ 1979 tableDesc: &index.Table().(*optTable).desc.TableDescriptor, 1980 index: index.(*optIndex).desc, 1981 rows: input.(planNode), 1982 expirationTime: expirationTime, 1983 }, nil 1984 } 1985 1986 // ConstructAlterTableUnsplit is part of the exec.Factory interface. 1987 func (ef *execFactory) ConstructAlterTableUnsplit( 1988 index cat.Index, input exec.Node, 1989 ) (exec.Node, error) { 1990 return &unsplitNode{ 1991 tableDesc: &index.Table().(*optTable).desc.TableDescriptor, 1992 index: index.(*optIndex).desc, 1993 rows: input.(planNode), 1994 }, nil 1995 } 1996 1997 // ConstructAlterTableUnsplitAll is part of the exec.Factory interface. 1998 func (ef *execFactory) ConstructAlterTableUnsplitAll(index cat.Index) (exec.Node, error) { 1999 return &unsplitAllNode{ 2000 tableDesc: &index.Table().(*optTable).desc.TableDescriptor, 2001 index: index.(*optIndex).desc, 2002 }, nil 2003 } 2004 2005 // ConstructAlterTableRelocate is part of the exec.Factory interface. 2006 func (ef *execFactory) ConstructAlterTableRelocate( 2007 index cat.Index, input exec.Node, relocateLease bool, 2008 ) (exec.Node, error) { 2009 return &relocateNode{ 2010 relocateLease: relocateLease, 2011 tableDesc: &index.Table().(*optTable).desc.TableDescriptor, 2012 index: index.(*optIndex).desc, 2013 rows: input.(planNode), 2014 }, nil 2015 } 2016 2017 // ConstructControlJobs is part of the exec.Factory interface. 2018 func (ef *execFactory) ConstructControlJobs( 2019 command tree.JobCommand, input exec.Node, 2020 ) (exec.Node, error) { 2021 return &controlJobsNode{ 2022 rows: input.(planNode), 2023 desiredStatus: jobCommandToDesiredStatus[command], 2024 }, nil 2025 } 2026 2027 // ConstructCancelQueries is part of the exec.Factory interface. 2028 func (ef *execFactory) ConstructCancelQueries(input exec.Node, ifExists bool) (exec.Node, error) { 2029 return &cancelQueriesNode{ 2030 rows: input.(planNode), 2031 ifExists: ifExists, 2032 }, nil 2033 } 2034 2035 // ConstructCancelSessions is part of the exec.Factory interface. 2036 func (ef *execFactory) ConstructCancelSessions(input exec.Node, ifExists bool) (exec.Node, error) { 2037 return &cancelSessionsNode{ 2038 rows: input.(planNode), 2039 ifExists: ifExists, 2040 }, nil 2041 } 2042 2043 // renderBuilder encapsulates the code to build a renderNode. 2044 type renderBuilder struct { 2045 r *renderNode 2046 res planNode 2047 } 2048 2049 // init initializes the renderNode with render expressions. 2050 func (rb *renderBuilder) init(n exec.Node, reqOrdering exec.OutputOrdering) { 2051 src := asDataSource(n) 2052 rb.r = &renderNode{ 2053 source: src, 2054 } 2055 rb.r.ivarHelper = tree.MakeIndexedVarHelper(rb.r, len(src.columns)) 2056 rb.r.reqOrdering = ReqOrdering(reqOrdering) 2057 2058 // If there's a spool, pull it up. 2059 if spool, ok := rb.r.source.plan.(*spoolNode); ok { 2060 rb.r.source.plan = spool.source 2061 spool.source = rb.r 2062 rb.res = spool 2063 } else { 2064 rb.res = rb.r 2065 } 2066 } 2067 2068 // setOutput sets the output of the renderNode. exprs is the list of render 2069 // expressions, and columns is the list of information about the expressions, 2070 // including their names, types, and so on. They must be the same length. 2071 func (rb *renderBuilder) setOutput(exprs tree.TypedExprs, columns sqlbase.ResultColumns) { 2072 rb.r.render = exprs 2073 rb.r.columns = columns 2074 } 2075 2076 // makeColDescList returns a list of table column descriptors. Columns are 2077 // included if their ordinal position in the table schema is in the cols set. 2078 func makeColDescList(table cat.Table, cols exec.TableColumnOrdinalSet) []sqlbase.ColumnDescriptor { 2079 colDescs := make([]sqlbase.ColumnDescriptor, 0, cols.Len()) 2080 for i, n := 0, table.DeletableColumnCount(); i < n; i++ { 2081 if !cols.Contains(i) { 2082 continue 2083 } 2084 colDescs = append(colDescs, *table.Column(i).(*sqlbase.ColumnDescriptor)) 2085 } 2086 return colDescs 2087 } 2088 2089 // makeScanColumnsConfig builds a scanColumnsConfig struct by constructing a 2090 // list of descriptor IDs for columns in the given cols set. Columns are 2091 // identified by their ordinal position in the table schema. 2092 func makeScanColumnsConfig(table cat.Table, cols exec.TableColumnOrdinalSet) scanColumnsConfig { 2093 // Set visibility=execinfra.ScanVisibilityPublicAndNotPublic, since all 2094 // columns in the "cols" set should be projected, regardless of whether 2095 // they're public or non- public. The caller decides which columns to 2096 // include (or not include). Note that when wantedColumns is non-empty, 2097 // the visibility flag will never trigger the addition of more columns. 2098 colCfg := scanColumnsConfig{ 2099 wantedColumns: make([]tree.ColumnID, 0, cols.Len()), 2100 visibility: execinfra.ScanVisibilityPublicAndNotPublic, 2101 } 2102 for c, ok := cols.Next(0); ok; c, ok = cols.Next(c + 1) { 2103 desc := table.Column(c).(*sqlbase.ColumnDescriptor) 2104 colCfg.wantedColumns = append(colCfg.wantedColumns, tree.ColumnID(desc.ID)) 2105 } 2106 return colCfg 2107 }