github.com/dolthub/go-mysql-server@v0.18.0/sql/rowexec/rel.go (about) 1 // Copyright 2023 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package rowexec 16 17 import ( 18 "encoding/json" 19 "errors" 20 "fmt" 21 "io" 22 "os" 23 "path/filepath" 24 "reflect" 25 "strings" 26 27 "github.com/dolthub/jsonpath" 28 "github.com/shopspring/decimal" 29 "go.opentelemetry.io/otel/attribute" 30 "go.opentelemetry.io/otel/trace" 31 32 "github.com/dolthub/go-mysql-server/sql" 33 "github.com/dolthub/go-mysql-server/sql/expression" 34 "github.com/dolthub/go-mysql-server/sql/expression/function/aggregation" 35 "github.com/dolthub/go-mysql-server/sql/plan" 36 "github.com/dolthub/go-mysql-server/sql/types" 37 ) 38 39 func (b *BaseBuilder) buildTopN(ctx *sql.Context, n *plan.TopN, row sql.Row) (sql.RowIter, error) { 40 span, ctx := ctx.Span("plan.TopN") 41 i, err := b.buildNodeExec(ctx, n.Child, row) 42 if err != nil { 43 span.End() 44 return nil, err 45 } 46 47 limit, err := getInt64Value(ctx, n.Limit) 48 if err != nil { 49 return nil, err 50 } 51 return sql.NewSpanIter(span, newTopRowsIter(n.Fields, limit, n.CalcFoundRows, i, len(n.Child.Schema()))), nil 52 } 53 54 func (b *BaseBuilder) buildValueDerivedTable(ctx *sql.Context, n *plan.ValueDerivedTable, row sql.Row) (sql.RowIter, error) { 55 rows := make([]sql.Row, len(n.ExpressionTuples)) 56 for i, et := range n.ExpressionTuples { 57 vals := make([]interface{}, len(et)) 58 for j, e := range et { 59 var err error 60 p, err := e.Eval(ctx, row) 61 if err != nil { 62 return nil, err 63 } 64 // cast all row values to the most permissive type 65 vals[j], _, err = n.Schema()[j].Type.Convert(p) 66 if err != nil { 67 return nil, err 68 } 69 // decimalType.Convert() does not use the given type precision and scale information 70 if t, ok := n.Schema()[j].Type.(sql.DecimalType); ok { 71 vals[j] = vals[j].(decimal.Decimal).Round(int32(t.Scale())) 72 } 73 } 74 75 rows[i] = sql.NewRow(vals...) 76 } 77 78 return sql.RowsToRowIter(rows...), nil 79 } 80 81 func (b *BaseBuilder) buildValues(ctx *sql.Context, n *plan.Values, row sql.Row) (sql.RowIter, error) { 82 rows := make([]sql.Row, len(n.ExpressionTuples)) 83 for i, et := range n.ExpressionTuples { 84 vals := make(sql.Row, len(et)) 85 86 // A non-zero row means that we're executing in a trigger context, so we evaluate against the row provided 87 // TODO: this probably won't work with triggers that define explicit DEFAULT values 88 if len(row) > 0 { 89 for j, e := range et { 90 var err error 91 vals[j], err = e.Eval(ctx, row) 92 if err != nil { 93 return nil, err 94 } 95 } 96 } else { 97 // For the values node, the relevant values to evaluate are the tuple itself. We may need to project 98 // DEFAULT values onto them, which ProjectRow handles correctly (could require multiple passes) 99 var err error 100 vals, err = ProjectRow(ctx, et, vals) 101 if err != nil { 102 return nil, err 103 } 104 } 105 106 rows[i] = sql.NewRow(vals...) 107 } 108 109 return sql.RowsToRowIter(rows...), nil 110 } 111 112 func (b *BaseBuilder) buildWindow(ctx *sql.Context, n *plan.Window, row sql.Row) (sql.RowIter, error) { 113 childIter, err := b.buildNodeExec(ctx, n.Child, row) 114 if err != nil { 115 return nil, err 116 } 117 blockIters, outputOrdinals, err := windowToIter(n) 118 if err != nil { 119 return nil, err 120 } 121 return aggregation.NewWindowIter(blockIters, outputOrdinals, childIter), nil 122 } 123 124 func (b *BaseBuilder) buildOffset(ctx *sql.Context, n *plan.Offset, row sql.Row) (sql.RowIter, error) { 125 span, ctx := ctx.Span("plan.Offset", trace.WithAttributes(attribute.Stringer("offset", n.Offset))) 126 127 offset, err := getInt64Value(ctx, n.Offset) 128 if err != nil { 129 span.End() 130 return nil, err 131 } 132 133 it, err := b.buildNodeExec(ctx, n.Child, row) 134 if err != nil { 135 span.End() 136 return nil, err 137 } 138 return sql.NewSpanIter(span, &offsetIter{offset, it}), nil 139 } 140 141 func (b *BaseBuilder) buildJSONTableCols(ctx *sql.Context, jtCols []plan.JSONTableCol, row sql.Row) ([]*jsonTableCol, error) { 142 var cols []*jsonTableCol 143 for _, col := range jtCols { 144 if col.Opts == nil { 145 innerCols, err := b.buildJSONTableCols(ctx, col.NestedCols, row) 146 if err != nil { 147 return nil, err 148 } 149 cols = append(cols, &jsonTableCol{ 150 path: col.Path, 151 cols: innerCols, 152 }) 153 continue 154 } 155 156 defErrVal, err := col.Opts.DefErrorVal.Eval(ctx, row) 157 if err != nil { 158 return nil, err 159 } 160 defEmpVal, err := col.Opts.DefEmptyVal.Eval(ctx, row) 161 if err != nil { 162 return nil, err 163 } 164 cols = append(cols, &jsonTableCol{ 165 path: col.Path, 166 opts: &jsonTableColOpts{ 167 name: col.Opts.Name, 168 typ: col.Opts.Type, 169 forOrd: col.Opts.ForOrd, 170 exists: col.Opts.Exists, 171 defErrVal: defErrVal, 172 defEmpVal: defEmpVal, 173 errOnErr: col.Opts.ErrorOnError, 174 errOnEmp: col.Opts.ErrorOnEmpty, 175 }, 176 }) 177 } 178 return cols, nil 179 } 180 181 func (b *BaseBuilder) buildJSONTable(ctx *sql.Context, n *plan.JSONTable, row sql.Row) (sql.RowIter, error) { 182 // data must evaluate to JSON string 183 data, err := n.DataExpr.Eval(ctx, row) 184 if err != nil { 185 return nil, err 186 } 187 188 if jd, ok := data.(types.JSONDocument); ok { 189 data, err = jd.JSONString() 190 if err != nil { 191 return nil, err 192 } 193 } 194 195 strData, _, err := types.LongBlob.Convert(data) 196 if err != nil { 197 return nil, fmt.Errorf("invalid data type for JSON data in argument 1 to function json_table; a JSON string or JSON type is required") 198 } 199 if strData == nil { 200 return &jsonTableRowIter{}, nil 201 } 202 203 var jsonData interface{} 204 if err = json.Unmarshal(strData.([]byte), &jsonData); err != nil { 205 return nil, err 206 } 207 jsonPathData, err := jsonpath.JsonPathLookup(jsonData, n.RootPath) 208 if err != nil { 209 jsonPathData = []interface{}{} 210 } 211 if _, ok := jsonPathData.([]interface{}); !ok { 212 jsonPathData = []interface{}{jsonPathData} 213 } 214 215 cols, err := b.buildJSONTableCols(ctx, n.Cols, row) 216 217 rowIter := &jsonTableRowIter{ 218 data: jsonPathData.([]interface{}), 219 cols: cols, 220 } 221 rowIter.NextSibling() // set to first sibling 222 223 return rowIter, nil 224 } 225 226 func (b *BaseBuilder) buildHashLookup(ctx *sql.Context, n *plan.HashLookup, row sql.Row) (sql.RowIter, error) { 227 n.Mutex.Lock() 228 defer n.Mutex.Unlock() 229 if n.Lookup == nil { 230 childIter, err := b.buildNodeExec(ctx, n.Child, row) 231 if err != nil { 232 return nil, err 233 } 234 return newHashLookupGeneratingIter(n, childIter), nil 235 } 236 key, err := n.GetHashKey(ctx, n.LeftProbeKey, row) 237 if err != nil { 238 return nil, err 239 } 240 if n.JoinType.IsExcludeNulls() { 241 // Some joins care if any of their filter comparisons have a NULL result. 242 // For these joins, we need to distinguish between an empty and non-empty secondary table. 243 // Thus, if there are any rows in the lookup, we must return at least one. 244 if len((*n.Lookup)[key]) > 0 { 245 return sql.RowsToRowIter((*n.Lookup)[key]...), nil 246 } 247 for k := range *n.Lookup { 248 if len((*n.Lookup)[k]) > 0 { 249 return sql.RowsToRowIter((*n.Lookup)[k]...), nil 250 } 251 } 252 } 253 return sql.RowsToRowIter((*n.Lookup)[key]...), nil 254 } 255 256 func (b *BaseBuilder) buildTableAlias(ctx *sql.Context, n *plan.TableAlias, row sql.Row) (sql.RowIter, error) { 257 var table string 258 if tbl, ok := n.Child.(sql.Nameable); ok { 259 table = tbl.Name() 260 } else { 261 table = reflect.TypeOf(n.Child).String() 262 } 263 264 span, ctx := ctx.Span("sql.TableAlias", trace.WithAttributes(attribute.String("table", table))) 265 266 iter, err := b.Build(ctx, n.Child, row) 267 if err != nil { 268 span.End() 269 return nil, err 270 } 271 272 return sql.NewSpanIter(span, iter), nil 273 } 274 275 func (b *BaseBuilder) buildJoinNode(ctx *sql.Context, n *plan.JoinNode, row sql.Row) (sql.RowIter, error) { 276 switch { 277 case n.Op.IsFullOuter(): 278 return newFullJoinIter(ctx, b, n, row) 279 case n.Op.IsPartial(): 280 return newExistsIter(ctx, b, n, row) 281 case n.Op.IsCross(): 282 return newCrossJoinIter(ctx, b, n, row) 283 case n.Op.IsPlaceholder(): 284 panic(fmt.Sprintf("%s is a placeholder, RowIter called", n.Op)) 285 case n.Op.IsMerge(): 286 return newMergeJoinIter(ctx, b, n, row) 287 case n.Op.IsLateral(): 288 return newLateralJoinIter(ctx, b, n, row) 289 case n.Op.IsRange(): 290 return newRangeHeapJoinIter(ctx, b, n, row) 291 default: 292 return newJoinIter(ctx, b, n, row) 293 } 294 } 295 296 func (b *BaseBuilder) buildOrderedDistinct(ctx *sql.Context, n *plan.OrderedDistinct, row sql.Row) (sql.RowIter, error) { 297 span, ctx := ctx.Span("plan.OrderedDistinct") 298 299 it, err := b.buildNodeExec(ctx, n.Child, row) 300 if err != nil { 301 span.End() 302 return nil, err 303 } 304 305 return sql.NewSpanIter(span, newOrderedDistinctIter(it, n.Child.Schema())), nil 306 } 307 308 func (b *BaseBuilder) buildWith(ctx *sql.Context, n *plan.With, row sql.Row) (sql.RowIter, error) { 309 return nil, fmt.Errorf("*plan.With has no execution iterator") 310 } 311 312 func (b *BaseBuilder) buildProject(ctx *sql.Context, n *plan.Project, row sql.Row) (sql.RowIter, error) { 313 span, ctx := ctx.Span("plan.Project", trace.WithAttributes( 314 attribute.Int("projections", len(n.Projections)), 315 )) 316 317 i, err := b.buildNodeExec(ctx, n.Child, row) 318 if err != nil { 319 span.End() 320 return nil, err 321 } 322 323 return sql.NewSpanIter(span, &projectIter{ 324 p: n.Projections, 325 childIter: i, 326 }), nil 327 } 328 329 func (b *BaseBuilder) buildVirtualColumnTable(ctx *sql.Context, n *plan.VirtualColumnTable, tableIter sql.RowIter, row sql.Row) (sql.RowIter, error) { 330 span, ctx := ctx.Span("plan.VirtualColumnTable", trace.WithAttributes( 331 attribute.Int("projections", len(n.Projections)), 332 )) 333 334 return sql.NewSpanIter(span, &projectIter{ 335 p: n.Projections, 336 childIter: tableIter, 337 }), nil 338 } 339 340 func (b *BaseBuilder) buildProcedure(ctx *sql.Context, n *plan.Procedure, row sql.Row) (sql.RowIter, error) { 341 return b.buildNodeExec(ctx, n.Body, row) 342 } 343 344 func (b *BaseBuilder) buildRecursiveTable(ctx *sql.Context, n *plan.RecursiveTable, row sql.Row) (sql.RowIter, error) { 345 return &recursiveTableIter{buf: n.Buf}, nil 346 } 347 348 func (b *BaseBuilder) buildSet(ctx *sql.Context, n *plan.Set, row sql.Row) (sql.RowIter, error) { 349 span, ctx := ctx.Span("plan.Set") 350 defer span.End() 351 352 var updateExprs []sql.Expression 353 for _, v := range n.Exprs { 354 setField, ok := v.(*expression.SetField) 355 if !ok { 356 return nil, fmt.Errorf("unsupported type for set: %T", v) 357 } 358 359 switch left := setField.LeftChild.(type) { 360 case *expression.SystemVar: 361 err := setSystemVar(ctx, left, setField.RightChild, row) 362 if err != nil { 363 return nil, err 364 } 365 case *expression.UserVar: 366 err := setUserVar(ctx, left, setField.RightChild, row) 367 if err != nil { 368 return nil, err 369 } 370 case *expression.ProcedureParam: 371 value, err := setField.RightChild.Eval(ctx, row) 372 if err != nil { 373 return nil, err 374 } 375 err = left.Set(value, setField.RightChild.Type()) 376 if err != nil { 377 return nil, err 378 } 379 case *expression.GetField: 380 updateExprs = append(updateExprs, setField) 381 default: 382 return nil, fmt.Errorf("unsupported type for set: %T", left) 383 } 384 } 385 386 var resultRow sql.Row 387 if len(updateExprs) > 0 { 388 newRow, err := applyUpdateExpressions(ctx, updateExprs, row) 389 if err != nil { 390 return nil, err 391 } 392 copy(resultRow, row) 393 resultRow = row.Append(newRow) 394 } 395 396 return sql.RowsToRowIter(resultRow), nil 397 } 398 399 func (b *BaseBuilder) buildGroupBy(ctx *sql.Context, n *plan.GroupBy, row sql.Row) (sql.RowIter, error) { 400 span, ctx := ctx.Span("plan.GroupBy", trace.WithAttributes( 401 attribute.Int("groupings", len(n.GroupByExprs)), 402 attribute.Int("aggregates", len(n.SelectedExprs)), 403 )) 404 405 i, err := b.buildNodeExec(ctx, n.Child, row) 406 if err != nil { 407 span.End() 408 return nil, err 409 } 410 411 var iter sql.RowIter 412 if len(n.GroupByExprs) == 0 { 413 iter = newGroupByIter(n.SelectedExprs, i) 414 } else { 415 iter = newGroupByGroupingIter(ctx, n.SelectedExprs, n.GroupByExprs, i) 416 } 417 418 return sql.NewSpanIter(span, iter), nil 419 } 420 421 func (b *BaseBuilder) buildFilter(ctx *sql.Context, n *plan.Filter, row sql.Row) (sql.RowIter, error) { 422 span, ctx := ctx.Span("plan.Filter") 423 424 i, err := b.buildNodeExec(ctx, n.Child, row) 425 if err != nil { 426 span.End() 427 return nil, err 428 } 429 430 return sql.NewSpanIter(span, plan.NewFilterIter(n.Expression, i)), nil 431 } 432 433 func (b *BaseBuilder) buildDeclareVariables(ctx *sql.Context, n *plan.DeclareVariables, row sql.Row) (sql.RowIter, error) { 434 return &declareVariablesIter{n, row}, nil 435 } 436 437 func (b *BaseBuilder) buildDeclareHandler(ctx *sql.Context, n *plan.DeclareHandler, row sql.Row) (sql.RowIter, error) { 438 return &declareHandlerIter{n}, nil 439 } 440 441 func (b *BaseBuilder) buildRecursiveCte(ctx *sql.Context, n *plan.RecursiveCte, row sql.Row) (sql.RowIter, error) { 442 var iter sql.RowIter = &recursiveCteIter{ 443 init: n.Left(), 444 rec: n.Right(), 445 row: row, 446 working: n.Working, 447 temp: make([]sql.Row, 0), 448 deduplicate: n.Union().Distinct, 449 b: b, 450 } 451 if n.Union().Limit != nil && len(n.Union().SortFields) > 0 { 452 limit, err := getInt64Value(ctx, n.Union().Limit) 453 if err != nil { 454 return nil, err 455 } 456 iter = newTopRowsIter(n.Union().SortFields, limit, false, iter, len(n.Union().Schema())) 457 } else if n.Union().Limit != nil { 458 limit, err := getInt64Value(ctx, n.Union().Limit) 459 if err != nil { 460 return nil, err 461 } 462 iter = &limitIter{limit: limit, childIter: iter} 463 } else if len(n.Union().SortFields) > 0 { 464 iter = newSortIter(n.Union().SortFields, iter) 465 } 466 return iter, nil 467 } 468 469 func (b *BaseBuilder) buildLimit(ctx *sql.Context, n *plan.Limit, row sql.Row) (sql.RowIter, error) { 470 span, ctx := ctx.Span("plan.Limit", trace.WithAttributes(attribute.Stringer("limit", n.Limit))) 471 472 limit, err := getInt64Value(ctx, n.Limit) 473 if err != nil { 474 span.End() 475 return nil, err 476 } 477 478 childIter, err := b.buildNodeExec(ctx, n.Child, row) 479 if err != nil { 480 span.End() 481 return nil, err 482 } 483 return sql.NewSpanIter(span, &limitIter{ 484 calcFoundRows: n.CalcFoundRows, 485 limit: limit, 486 childIter: childIter, 487 }), nil 488 } 489 490 func (b *BaseBuilder) buildMax1Row(ctx *sql.Context, n *plan.Max1Row, row sql.Row) (sql.RowIter, error) { 491 n.Mu.Lock() 492 defer n.Mu.Unlock() 493 494 if !n.HasResults() { 495 err := b.populateMax1Results(ctx, n, row) 496 if err != nil { 497 return nil, err 498 } 499 } 500 501 switch { 502 case n.EmptyResult: 503 return plan.EmptyIter, nil 504 case n.Result != nil: 505 return sql.RowsToRowIter(n.Result), nil 506 default: 507 return nil, fmt.Errorf("Max1Row failed to load results") 508 } 509 } 510 511 // PopulateResults loads and stores the state of its child iter: 512 // 1) no rows returned, 2) 1 row returned, or 3) more than 1 row 513 // returned 514 func (b *BaseBuilder) populateMax1Results(ctx *sql.Context, n *plan.Max1Row, row sql.Row) error { 515 i, err := b.buildNodeExec(ctx, n.Child, row) 516 if err != nil { 517 return err 518 } 519 defer i.Close(ctx) 520 r1, err := i.Next(ctx) 521 if errors.Is(err, io.EOF) { 522 n.EmptyResult = true 523 return nil 524 } else if err != nil { 525 return err 526 } 527 528 _, err = i.Next(ctx) 529 if err == nil { 530 return sql.ErrExpectedSingleRow.New() 531 } else if !errors.Is(err, io.EOF) { 532 return err 533 } 534 n.Result = r1 535 return nil 536 } 537 538 // isUnderSecureFileDir ensures that fileStr is under secureFileDir or a subdirectory of secureFileDir, errors otherwise 539 func isUnderSecureFileDir(secureFileDir interface{}, fileStr string) error { 540 if secureFileDir == nil || secureFileDir == "" { 541 return nil 542 } 543 sStat, err := os.Stat(secureFileDir.(string)) 544 if err != nil { 545 return err 546 } 547 fStat, err := os.Stat(filepath.Dir(fileStr)) 548 if err != nil { 549 return err 550 } 551 if os.SameFile(sStat, fStat) { 552 return nil 553 } 554 555 fileAbsPath, filePathErr := filepath.Abs(fileStr) 556 if filePathErr != nil { 557 return filePathErr 558 } 559 secureFileDirAbsPath, _ := filepath.Abs(secureFileDir.(string)) 560 if strings.HasPrefix(fileAbsPath, secureFileDirAbsPath) { 561 return nil 562 } 563 return sql.ErrSecureFilePriv.New() 564 } 565 566 // createIfNotExists creates a file if it does not exist, errors otherwise 567 func createIfNotExists(fileStr string) (*os.File, error) { 568 if _, fErr := os.Stat(fileStr); fErr == nil { 569 return nil, sql.ErrFileExists.New(fileStr) 570 } 571 file, fileErr := os.OpenFile(fileStr, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0640) 572 if fileErr != nil { 573 return nil, fileErr 574 } 575 return file, nil 576 } 577 578 func (b *BaseBuilder) buildInto(ctx *sql.Context, n *plan.Into, row sql.Row) (sql.RowIter, error) { 579 span, ctx := ctx.Span("plan.Into") 580 defer span.End() 581 582 rowIter, err := b.buildNodeExec(ctx, n.Child, row) 583 if err != nil { 584 return nil, err 585 } 586 rows, err := sql.RowIterToRows(ctx, rowIter) 587 if err != nil { 588 return nil, err 589 } 590 591 var secureFileDir interface{} 592 if n.Outfile != "" || n.Dumpfile != "" { 593 var ok bool 594 _, secureFileDir, ok = sql.SystemVariables.GetGlobal("secure_file_priv") 595 if !ok { 596 return nil, fmt.Errorf("error: secure_file_priv variable was not found") 597 } 598 } 599 600 if n.Outfile != "" { 601 // TODO: MySQL has relative paths from the "data dir" 602 if err = isUnderSecureFileDir(secureFileDir, n.Outfile); err != nil { 603 return nil, err 604 } 605 file, fileErr := createIfNotExists(n.Outfile) 606 if fileErr != nil { 607 return nil, fileErr 608 } 609 defer file.Close() 610 611 sch := n.Child.Schema() 612 for _, r := range rows { 613 file.WriteString(n.LinesStartingBy) 614 for i, val := range r { 615 if i != 0 { 616 file.WriteString(n.FieldsTerminatedBy) 617 } 618 if val == nil { 619 if len(n.FieldsEscapedBy) == 0 { 620 file.WriteString("NULL") 621 } else { 622 file.WriteString(fmt.Sprintf("%sN", n.FieldsEscapedBy)) 623 } 624 continue 625 } 626 if !n.FieldsEnclosedByOpt || types.IsText(sch[i].Type) { 627 if strVal, ok := val.(string); ok { 628 if len(n.LinesTerminatedBy) != 0 { 629 strVal = strings.Replace(strVal, n.LinesTerminatedBy, n.FieldsEscapedBy+n.LinesTerminatedBy, -1) 630 } 631 file.WriteString(fmt.Sprintf("%s%v%s", n.FieldsEnclosedBy, strVal, n.FieldsEnclosedBy)) 632 } else { 633 file.WriteString(fmt.Sprintf("%s%v%s", n.FieldsEnclosedBy, val, n.FieldsEnclosedBy)) 634 } 635 } else { 636 file.WriteString(fmt.Sprintf("%v", val)) 637 } 638 } 639 file.WriteString(n.LinesTerminatedBy) 640 } 641 return sql.RowsToRowIter(sql.Row{}), nil 642 } 643 644 rowNum := len(rows) 645 if rowNum > 1 { 646 return nil, sql.ErrMoreThanOneRow.New() 647 } 648 649 if n.Dumpfile != "" { 650 if err = isUnderSecureFileDir(secureFileDir, n.Dumpfile); err != nil { 651 return nil, err 652 } 653 file, fileErr := createIfNotExists(n.Dumpfile) 654 if fileErr != nil { 655 return nil, fileErr 656 } 657 defer file.Close() 658 if rowNum == 1 { 659 for _, val := range rows[0] { 660 file.WriteString(fmt.Sprintf("%v", val)) 661 } 662 } 663 return sql.RowsToRowIter(sql.Row{}), nil 664 } 665 666 if rowNum == 0 { 667 // a warning with error code 1329 occurs (No data), and make no change to variables 668 return sql.RowsToRowIter(sql.Row{}), nil 669 } 670 if len(rows[0]) != len(n.IntoVars) { 671 return nil, sql.ErrColumnNumberDoesNotMatch.New() 672 } 673 674 var rowValues = make([]interface{}, len(rows[0])) 675 copy(rowValues, rows[0]) 676 677 for j, v := range n.IntoVars { 678 switch variable := v.(type) { 679 case *expression.UserVar: 680 varType := types.ApproximateTypeFromValue(rowValues[j]) 681 err = ctx.SetUserVariable(ctx, variable.Name, rowValues[j], varType) 682 if err != nil { 683 return nil, err 684 } 685 case *expression.ProcedureParam: 686 err = variable.Set(rowValues[j], types.ApproximateTypeFromValue(rowValues[j])) 687 if err != nil { 688 return nil, err 689 } 690 default: 691 return nil, fmt.Errorf("unsupported type for into: %T", variable) 692 } 693 } 694 695 return sql.RowsToRowIter(sql.Row{}), nil 696 } 697 698 func (b *BaseBuilder) buildExternalProcedure(ctx *sql.Context, n *plan.ExternalProcedure, row sql.Row) (sql.RowIter, error) { 699 // The function's structure has been verified by the analyzer, so no need to double-check any of it here 700 funcVal := reflect.ValueOf(n.Function) 701 funcType := funcVal.Type() 702 // The first parameter is always the context, but it doesn't exist as far as the stored procedures are concerned, so 703 // we prepend it here 704 funcParams := make([]reflect.Value, len(n.Params)+1) 705 funcParams[0] = reflect.ValueOf(ctx) 706 707 for i := range n.Params { 708 paramDefinition := n.ParamDefinitions[i] 709 var funcParamType reflect.Type 710 if paramDefinition.Variadic { 711 funcParamType = funcType.In(funcType.NumIn() - 1).Elem() 712 } else { 713 funcParamType = funcType.In(i + 1) 714 } 715 // Grab the passed-in variable and convert it to the type we expect 716 exprParamVal, err := n.Params[i].Eval(ctx, nil) 717 if err != nil { 718 return nil, err 719 } 720 exprParamVal, _, err = paramDefinition.Type.Convert(exprParamVal) 721 if err != nil { 722 return nil, err 723 } 724 725 funcParams[i+1], err = n.ProcessParam(ctx, funcParamType, exprParamVal) 726 if err != nil { 727 return nil, err 728 } 729 } 730 out := funcVal.Call(funcParams) 731 732 // Again, these types are enforced in the analyzer, so it's safe to assume their types here 733 if err, ok := out[1].Interface().(error); ok { // Only evaluates to true when error is not nil 734 return nil, err 735 } 736 for i, paramDefinition := range n.ParamDefinitions { 737 if paramDefinition.Direction == plan.ProcedureParamDirection_Inout || paramDefinition.Direction == plan.ProcedureParamDirection_Out { 738 exprParam := n.Params[i] 739 funcParamVal := funcParams[i+1].Elem().Interface() 740 err := exprParam.Set(funcParamVal, exprParam.Type()) 741 if err != nil { 742 return nil, err 743 } 744 } 745 } 746 // It's not invalid to return a nil RowIter, as having no rows to return is expected of many stored procedures. 747 if rowIter, ok := out[0].Interface().(sql.RowIter); ok { 748 return rowIter, nil 749 } 750 return sql.RowsToRowIter(), nil 751 } 752 753 func (b *BaseBuilder) buildHaving(ctx *sql.Context, n *plan.Having, row sql.Row) (sql.RowIter, error) { 754 span, ctx := ctx.Span("plan.Having") 755 iter, err := b.buildNodeExec(ctx, n.Child, row) 756 if err != nil { 757 span.End() 758 return nil, err 759 } 760 761 return sql.NewSpanIter(span, plan.NewFilterIter(n.Cond, iter)), nil 762 } 763 764 func (b *BaseBuilder) buildDistinct(ctx *sql.Context, n *plan.Distinct, row sql.Row) (sql.RowIter, error) { 765 span, ctx := ctx.Span("plan.Distinct") 766 767 it, err := b.buildNodeExec(ctx, n.Child, row) 768 if err != nil { 769 span.End() 770 return nil, err 771 } 772 773 return sql.NewSpanIter(span, newDistinctIter(ctx, it)), nil 774 } 775 776 func (b *BaseBuilder) buildIndexedTableAccess(ctx *sql.Context, n *plan.IndexedTableAccess, row sql.Row) (sql.RowIter, error) { 777 span, ctx := ctx.Span("plan.IndexedTableAccess") 778 779 lookup, err := n.GetLookup(ctx, row) 780 if err != nil { 781 return nil, err 782 } 783 784 partIter, err := n.Table.LookupPartitions(ctx, lookup) 785 if err != nil { 786 return nil, err 787 } 788 789 var tableIter sql.RowIter 790 tableIter = sql.NewTableRowIter(ctx, n.Table, partIter) 791 792 if vct, ok := plan.FindVirtualColumnTable(n.Table); ok { 793 tableIter, err = b.buildVirtualColumnTable(ctx, vct, tableIter, row) 794 if err != nil { 795 return nil, err 796 } 797 } 798 799 return sql.NewSpanIter(span, tableIter), nil 800 } 801 802 func (b *BaseBuilder) buildSetOp(ctx *sql.Context, s *plan.SetOp, row sql.Row) (sql.RowIter, error) { 803 span, ctx := ctx.Span("plan.SetOp") 804 var iter sql.RowIter 805 var err error 806 iter, err = b.buildNodeExec(ctx, s.Left(), row) 807 if err != nil { 808 span.End() 809 return nil, err 810 } 811 switch s.SetOpType { 812 case plan.UnionType: 813 iter = &unionIter{ 814 cur: iter, 815 nextIter: func(ctx *sql.Context) (sql.RowIter, error) { 816 return b.buildNodeExec(ctx, s.Right(), row) 817 }, 818 } 819 case plan.IntersectType: 820 var iter2 sql.RowIter 821 iter2, err = b.buildNodeExec(ctx, s.Right(), row) 822 if err != nil { 823 span.End() 824 return nil, err 825 } 826 iter = &intersectIter{ 827 lIter: iter, 828 rIter: iter2, 829 } 830 case plan.ExceptType: 831 var iter2 sql.RowIter 832 iter2, err = b.buildNodeExec(ctx, s.Right(), row) 833 if err != nil { 834 span.End() 835 return nil, err 836 } 837 if s.Distinct { 838 dIter := newDistinctIter(ctx, iter) 839 s.AddDispose(dIter.dispose) 840 iter = dIter 841 842 dIter2 := newDistinctIter(ctx, iter2) 843 s.AddDispose(dIter2.dispose) 844 iter2 = dIter2 845 } 846 iter = &exceptIter{ 847 lIter: iter, 848 rIter: iter2, 849 } 850 } 851 852 if s.Distinct && s.SetOpType != plan.ExceptType { 853 dIter := newDistinctIter(ctx, iter) 854 s.AddDispose(dIter.dispose) 855 iter = dIter 856 } 857 // Limit must wrap offset, and not vice-versa, so that 858 // skipped rows don't count toward the returned row count. 859 if s.Offset != nil { 860 offset, err := getInt64Value(ctx, s.Offset) 861 if err != nil { 862 return nil, err 863 } 864 iter = &offsetIter{skip: offset, childIter: iter} 865 } 866 if s.Limit != nil && len(s.SortFields) > 0 { 867 limit, err := getInt64Value(ctx, s.Limit) 868 if err != nil { 869 return nil, err 870 } 871 iter = newTopRowsIter(s.SortFields, limit, false, iter, len(s.Schema())) 872 } else if s.Limit != nil { 873 limit, err := getInt64Value(ctx, s.Limit) 874 if err != nil { 875 return nil, err 876 } 877 iter = &limitIter{limit: limit, childIter: iter} 878 } else if len(s.SortFields) > 0 { 879 iter = newSortIter(s.SortFields, iter) 880 } 881 return sql.NewSpanIter(span, iter), nil 882 } 883 884 func (b *BaseBuilder) buildSubqueryAlias(ctx *sql.Context, n *plan.SubqueryAlias, row sql.Row) (sql.RowIter, error) { 885 span, ctx := ctx.Span("plan.SubqueryAlias") 886 887 if !n.OuterScopeVisibility && !n.IsLateral { 888 row = nil 889 } 890 iter, err := b.buildNodeExec(ctx, n.Child, row) 891 if err != nil { 892 span.End() 893 return nil, err 894 } 895 896 return sql.NewSpanIter(span, iter), nil 897 } 898 899 func (b *BaseBuilder) buildSort(ctx *sql.Context, n *plan.Sort, row sql.Row) (sql.RowIter, error) { 900 span, ctx := ctx.Span("plan.Sort") 901 i, err := b.buildNodeExec(ctx, n.Child, row) 902 if err != nil { 903 span.End() 904 return nil, err 905 } 906 return sql.NewSpanIter(span, newSortIter(n.SortFields, i)), nil 907 } 908 909 func (b *BaseBuilder) buildPrepareQuery(ctx *sql.Context, n *plan.PrepareQuery, row sql.Row) (sql.RowIter, error) { 910 return sql.RowsToRowIter(sql.NewRow(types.OkResult{RowsAffected: 0, Info: plan.PrepareInfo{}})), nil 911 } 912 913 func (b *BaseBuilder) buildResolvedTable(ctx *sql.Context, n *plan.ResolvedTable, row sql.Row) (sql.RowIter, error) { 914 span, ctx := ctx.Span("plan.TableNode") 915 916 partitions, err := n.Table.Partitions(ctx) 917 if err != nil { 918 span.End() 919 return nil, err 920 } 921 922 var iter sql.RowIter 923 iter = sql.NewTableRowIter(ctx, n.Table, partitions) 924 925 if vct, ok := plan.FindVirtualColumnTable(n.Table); ok { 926 iter, err = b.buildVirtualColumnTable(ctx, vct, iter, row) 927 if err != nil { 928 return nil, err 929 } 930 } 931 932 return sql.NewSpanIter(span, iter), nil 933 } 934 935 func (b *BaseBuilder) buildTableCount(_ *sql.Context, n *plan.TableCountLookup, _ sql.Row) (sql.RowIter, error) { 936 return sql.RowsToRowIter(sql.Row{int64(n.Count())}), nil 937 }