github.com/mithrandie/csvq@v1.18.1/lib/query/view.go (about) 1 package query 2 3 import ( 4 "context" 5 "math" 6 "sort" 7 "strings" 8 "sync" 9 10 "github.com/mithrandie/csvq/lib/option" 11 "github.com/mithrandie/csvq/lib/parser" 12 "github.com/mithrandie/csvq/lib/value" 13 14 "github.com/mithrandie/ternary" 15 ) 16 17 type View struct { 18 Header Header 19 RecordSet RecordSet 20 FileInfo *FileInfo 21 22 selectFields []int 23 selectLabels []string 24 isGrouped bool 25 26 comparisonKeysInEachRecord []string 27 sortValuesInEachCell [][]*SortValue 28 sortValuesInEachRecord []SortValues 29 sortDirections []int 30 sortNullPositions []int 31 32 offset int 33 } 34 35 func NewView() *View { 36 return &View{} 37 } 38 39 func NewDualView() *View { 40 return &View{ 41 Header: NewEmptyHeader(1), 42 RecordSet: RecordSet{NewEmptyRecord(1)}, 43 } 44 } 45 46 func NewViewFromGroupedRecord(ctx context.Context, flags *option.Flags, referenceRecord ReferenceRecord) (*View, error) { 47 view := NewView() 48 view.Header = referenceRecord.view.Header 49 record := referenceRecord.view.RecordSet[referenceRecord.recordIndex] 50 51 view.RecordSet = make(RecordSet, record.GroupLen()) 52 53 if err := NewGoroutineTaskManager(record.GroupLen(), -1, flags.CPU).Run(ctx, func(index int) error { 54 view.RecordSet[index] = make(Record, view.FieldLen()) 55 for j := range record { 56 grpIdx := index 57 if len(record[j]) < 2 { 58 grpIdx = 0 59 } 60 view.RecordSet[index][j] = record[j][grpIdx : grpIdx+1] 61 } 62 return nil 63 }); err != nil { 64 return nil, err 65 } 66 return view, nil 67 } 68 69 func (view *View) IsUpdatable() bool { 70 return view.FileInfo != nil && view.FileInfo.IsUpdatable() 71 } 72 73 func (view *View) Where(ctx context.Context, scope *ReferenceScope, clause parser.WhereClause) error { 74 return view.filter(ctx, scope, clause.Filter) 75 } 76 77 func (view *View) filter(ctx context.Context, scope *ReferenceScope, condition parser.QueryExpression) error { 78 results := make([]bool, view.RecordLen()) 79 80 if err := EvaluateSequentially(ctx, scope, view, func(seqScope *ReferenceScope, rIdx int) error { 81 primary, e := Evaluate(ctx, seqScope, condition) 82 if e != nil { 83 return e 84 } 85 86 if primary.Ternary() == ternary.TRUE { 87 results[rIdx] = true 88 } 89 return nil 90 }); err != nil { 91 return err 92 } 93 94 newIdx := 0 95 for i, ok := range results { 96 if ok { 97 if i != newIdx { 98 view.RecordSet[newIdx] = view.RecordSet[i] 99 } 100 newIdx++ 101 } 102 } 103 104 view.RecordSet = view.RecordSet[:newIdx] 105 return nil 106 } 107 108 func (view *View) GroupBy(ctx context.Context, scope *ReferenceScope, clause parser.GroupByClause) error { 109 return view.group(ctx, scope, clause.Items) 110 } 111 112 func (view *View) group(ctx context.Context, scope *ReferenceScope, items []parser.QueryExpression) error { 113 if items == nil { 114 return view.groupAll(ctx, scope.Tx.Flags) 115 } 116 117 gm := NewGoroutineTaskManager(view.RecordLen(), -1, scope.Tx.Flags.CPU) 118 groupsList := make([]map[string][]int, gm.Number) 119 groupKeyCnt := make(map[string]int, 40) 120 groupKeys := make([]string, 0, 40) 121 mtx := &sync.Mutex{} 122 123 var grpFn = func(thIdx int) { 124 defer func() { 125 if !gm.HasError() { 126 if panicReport := recover(); panicReport != nil { 127 gm.SetError(NewFatalError(panicReport)) 128 } 129 } 130 131 if 1 < gm.Number { 132 gm.Done() 133 } 134 }() 135 136 start, end := gm.RecordRange(thIdx) 137 seqScope := scope.CreateScopeForSequentialEvaluation(view) 138 groups := make(map[string][]int, 20) 139 values := make([]value.Primary, len(items)) 140 141 GroupKeyLoop: 142 for i := start; i < end; i++ { 143 if gm.HasError() { 144 break GroupKeyLoop 145 } 146 if i&15 == 0 && ctx.Err() != nil { 147 break GroupKeyLoop 148 } 149 150 seqScope.Records[0].recordIndex = i 151 152 for i, item := range items { 153 p, e := Evaluate(ctx, seqScope, item) 154 if e != nil { 155 gm.SetError(e) 156 break GroupKeyLoop 157 } 158 values[i] = p 159 } 160 keyBuf := GetComparisonKeysBuf() 161 SerializeComparisonKeys(keyBuf, values, seqScope.Tx.Flags) 162 key := keyBuf.String() 163 PutComparisonkeysBuf(keyBuf) 164 165 if _, ok := groups[key]; ok { 166 groups[key] = append(groups[key], i) 167 } else { 168 groups[key] = make([]int, 0, int(math.Min(float64(view.RecordLen()/18), 1000))) 169 groups[key] = append(groups[key], i) 170 mtx.Lock() 171 if _, ok := groupKeyCnt[key]; !ok { 172 groupKeyCnt[key] = 0 173 groupKeys = append(groupKeys, key) 174 } 175 mtx.Unlock() 176 } 177 } 178 179 groupsList[thIdx] = groups 180 } 181 182 if 1 < gm.Number { 183 for i := 0; i < gm.Number; i++ { 184 gm.Add() 185 go grpFn(i) 186 } 187 gm.Wait() 188 } else { 189 grpFn(0) 190 } 191 192 if gm.HasError() { 193 return gm.Err() 194 } 195 if ctx.Err() != nil { 196 return ConvertContextError(ctx.Err()) 197 } 198 199 for i := range groupsList { 200 for k := range groupsList[i] { 201 groupKeyCnt[k] = groupKeyCnt[k] + len(groupsList[i][k]) 202 } 203 } 204 205 records := make(RecordSet, len(groupKeys)) 206 calcCnt := view.RecordLen() * len(groupKeys) 207 minReq := -1 208 if MinimumRequiredPerCPUCore < calcCnt { 209 minReq = int(math.Ceil(float64(len(groupKeys)) / (math.Floor(float64(calcCnt) / MinimumRequiredPerCPUCore)))) 210 } 211 if err := NewGoroutineTaskManager(len(groupKeys), minReq, scope.Tx.Flags.CPU).Run(ctx, func(gIdx int) error { 212 record := make(Record, view.FieldLen()) 213 214 for i := 0; i < view.FieldLen(); i++ { 215 primaries := make(Cell, groupKeyCnt[groupKeys[gIdx]]) 216 pos := 0 217 for j := range groupsList { 218 if indices, ok := groupsList[j][groupKeys[gIdx]]; ok { 219 for k := range indices { 220 primaries[pos+k] = view.RecordSet[indices[k]][i][0] 221 } 222 pos += len(indices) 223 } 224 } 225 record[i] = primaries 226 } 227 228 records[gIdx] = record 229 return nil 230 }); err != nil { 231 return err 232 } 233 234 view.RecordSet = records 235 view.isGrouped = true 236 for _, item := range items { 237 switch item.(type) { 238 case parser.FieldReference, parser.ColumnNumber: 239 idx, _ := view.Header.SearchIndex(item) 240 view.Header[idx].IsGroupKey = true 241 } 242 } 243 return nil 244 } 245 246 func (view *View) groupAll(ctx context.Context, flags *option.Flags) error { 247 if 0 < view.RecordLen() { 248 record := make(Record, view.FieldLen()) 249 250 calcCnt := view.RecordLen() * view.FieldLen() 251 minReq := -1 252 if MinimumRequiredPerCPUCore < calcCnt { 253 minReq = int(math.Ceil(float64(view.FieldLen()) / (math.Floor(float64(calcCnt) / MinimumRequiredPerCPUCore)))) 254 } 255 if err := NewGoroutineTaskManager(view.FieldLen(), minReq, flags.CPU).Run(ctx, func(fIdx int) error { 256 primaries := make(Cell, len(view.RecordSet)) 257 for j := range view.RecordSet { 258 primaries[j] = view.RecordSet[j][fIdx][0] 259 } 260 record[fIdx] = primaries 261 return nil 262 }); err != nil { 263 return err 264 } 265 266 view.RecordSet = view.RecordSet[:1] 267 view.RecordSet[0] = record 268 } 269 270 view.isGrouped = true 271 return nil 272 } 273 274 func (view *View) Having(ctx context.Context, scope *ReferenceScope, clause parser.HavingClause) error { 275 err := view.filter(ctx, scope, clause.Filter) 276 if err != nil { 277 if _, ok := err.(*NotGroupingRecordsError); ok { 278 if err = view.group(ctx, scope, nil); err != nil { 279 return err 280 } 281 if err = view.filter(ctx, scope, clause.Filter); err != nil { 282 return err 283 } 284 } else { 285 return err 286 } 287 } 288 return nil 289 } 290 291 func (view *View) Select(ctx context.Context, scope *ReferenceScope, clause parser.SelectClause) error { 292 var parseWildcard = func(fields []parser.QueryExpression) []parser.Field { 293 list := make([]parser.Field, 0, len(fields)) 294 295 columns := view.Header.TableColumns() 296 297 for _, v := range fields { 298 field := v.(parser.Field) 299 300 if _, ok := field.Object.(parser.AllColumns); ok { 301 for _, c := range columns { 302 list = append(list, parser.Field{ 303 Object: c, 304 }) 305 } 306 307 continue 308 } 309 310 if fieldReference, ok := field.Object.(parser.FieldReference); ok { 311 if _, ok := fieldReference.Column.(parser.AllColumns); ok { 312 viewName := fieldReference.View.Literal 313 314 for _, c := range columns { 315 cref := c.(parser.FieldReference) 316 if cref.View.Literal != viewName { 317 continue 318 } 319 320 list = append(list, parser.Field{ 321 Object: c, 322 }) 323 } 324 325 continue 326 } 327 } 328 329 list = append(list, field) 330 } 331 332 return list 333 } 334 335 var evalFields = func(fields []parser.Field) error { 336 view.selectFields = make([]int, len(fields)) 337 view.selectLabels = make([]string, len(fields)) 338 for i, field := range fields { 339 alias := "" 340 if field.Alias != nil { 341 alias = field.Alias.(parser.Identifier).Literal 342 } 343 idx, err := view.evalColumn(ctx, scope, field.Object, alias) 344 if err != nil { 345 return err 346 } 347 view.selectFields[i] = idx 348 view.selectLabels[i] = field.Name() 349 } 350 351 return nil 352 } 353 354 fields := parseWildcard(clause.Fields) 355 fieldObjects := make([]parser.QueryExpression, len(fields)) 356 for i := range fields { 357 fieldObjects[i] = fields[i].Object 358 } 359 360 if !view.isGrouped { 361 hasAggregateFunction, err := HasAggregateFunctionInList(fieldObjects, scope) 362 if err != nil { 363 return err 364 } 365 366 if hasAggregateFunction { 367 if err = view.group(ctx, scope, nil); err != nil { 368 return err 369 } 370 371 if view.RecordLen() < 1 { 372 record := make(Record, view.FieldLen()) 373 for i := range record { 374 record[i] = make(Cell, 0) 375 } 376 view.RecordSet = append(view.RecordSet, record) 377 } 378 } 379 } 380 381 analyticFunctions, err := SearchAnalyticFunctionsInList(fieldObjects) 382 if err != nil { 383 return err 384 } 385 386 if err := view.ExtendRecordCapacity(ctx, scope, fieldObjects, analyticFunctions); err != nil { 387 return err 388 } 389 390 for _, fn := range analyticFunctions { 391 err = view.evalAnalyticFunction(ctx, scope, fn) 392 if err != nil { 393 return err 394 } 395 } 396 397 err = evalFields(fields) 398 if err != nil { 399 return err 400 } 401 402 if clause.IsDistinct() { 403 if err = view.GenerateComparisonKeys(ctx, scope.Tx.Flags); err != nil { 404 return err 405 } 406 records := make(RecordSet, 0, 40) 407 values := make(map[string]bool, 40) 408 for i, v := range view.RecordSet { 409 if !values[view.comparisonKeysInEachRecord[i]] { 410 values[view.comparisonKeysInEachRecord[i]] = true 411 412 record := make(Record, len(view.selectFields)) 413 for j, idx := range view.selectFields { 414 record[j] = v[idx] 415 } 416 records = append(records, record) 417 } 418 } 419 420 hfields := NewEmptyHeader(len(view.selectFields)) 421 for i, idx := range view.selectFields { 422 hfields[i] = view.Header[idx] 423 view.selectFields[i] = i 424 } 425 426 view.Header = hfields 427 view.RecordSet = records 428 view.comparisonKeysInEachRecord = nil 429 view.sortValuesInEachCell = nil 430 } 431 432 return nil 433 } 434 435 func (view *View) GenerateComparisonKeys(ctx context.Context, flags *option.Flags) error { 436 view.comparisonKeysInEachRecord = make([]string, view.RecordLen()) 437 438 return NewGoroutineTaskManager(view.RecordLen(), -1, flags.CPU).Run(ctx, func(index int) error { 439 flags := flags 440 buf := GetComparisonKeysBuf() 441 var primaries []value.Primary = nil 442 443 if view.selectFields != nil { 444 primaries = make([]value.Primary, len(view.selectFields)) 445 for j, idx := range view.selectFields { 446 primaries[j] = view.RecordSet[index][idx][0] 447 } 448 } else { 449 primaries = make([]value.Primary, view.FieldLen()) 450 for j := range view.RecordSet[index] { 451 primaries[j] = view.RecordSet[index][j][0] 452 } 453 } 454 SerializeComparisonKeys(buf, primaries, flags) 455 456 view.comparisonKeysInEachRecord[index] = buf.String() 457 PutComparisonkeysBuf(buf) 458 return nil 459 }) 460 } 461 462 func (view *View) SelectAllColumns(ctx context.Context, scope *ReferenceScope) error { 463 selectClause := parser.SelectClause{ 464 Fields: []parser.QueryExpression{ 465 parser.Field{Object: parser.AllColumns{}}, 466 }, 467 } 468 return view.Select(ctx, scope, selectClause) 469 } 470 471 func (view *View) OrderBy(ctx context.Context, scope *ReferenceScope, clause parser.OrderByClause) error { 472 if view.RecordLen() < 2 { 473 return nil 474 } 475 476 orderValues := make([]parser.QueryExpression, len(clause.Items)) 477 for i, item := range clause.Items { 478 orderValues[i] = item.(parser.OrderItem).Value 479 } 480 481 analyticFunctions, err := SearchAnalyticFunctionsInList(orderValues) 482 if err != nil { 483 return err 484 } 485 486 if err := view.ExtendRecordCapacity(ctx, scope, orderValues, analyticFunctions); err != nil { 487 return err 488 } 489 490 for _, fn := range analyticFunctions { 491 err = view.evalAnalyticFunction(ctx, scope, fn) 492 if err != nil { 493 return err 494 } 495 } 496 497 sortIndices := make([]int, len(clause.Items)) 498 for i, v := range clause.Items { 499 oi := v.(parser.OrderItem) 500 idx, err := view.evalColumn(ctx, scope, oi.Value, "") 501 if err != nil { 502 return err 503 } 504 sortIndices[i] = idx 505 } 506 507 view.sortValuesInEachRecord = make([]SortValues, view.RecordLen()) 508 view.sortDirections = make([]int, len(clause.Items)) 509 view.sortNullPositions = make([]int, len(clause.Items)) 510 511 for i, v := range clause.Items { 512 oi := v.(parser.OrderItem) 513 if oi.Direction.IsEmpty() { 514 view.sortDirections[i] = parser.ASC 515 } else { 516 view.sortDirections[i] = oi.Direction.Token 517 } 518 519 if oi.NullsPosition.IsEmpty() { 520 switch view.sortDirections[i] { 521 case parser.ASC: 522 view.sortNullPositions[i] = parser.FIRST 523 default: //parser.DESC 524 view.sortNullPositions[i] = parser.LAST 525 } 526 } else { 527 view.sortNullPositions[i] = oi.NullsPosition.Token 528 } 529 } 530 531 if err := NewGoroutineTaskManager(view.RecordLen(), -1, scope.Tx.Flags.CPU).Run(ctx, func(index int) error { 532 if view.sortValuesInEachCell != nil && view.sortValuesInEachCell[index] == nil { 533 view.sortValuesInEachCell[index] = make([]*SortValue, cap(view.RecordSet[index])) 534 } 535 536 sortValues := make(SortValues, len(sortIndices)) 537 for j, idx := range sortIndices { 538 if view.sortValuesInEachCell != nil && idx < len(view.sortValuesInEachCell[index]) && view.sortValuesInEachCell[index][idx] != nil { 539 sortValues[j] = view.sortValuesInEachCell[index][idx] 540 } else { 541 sortValues[j] = NewSortValue(view.RecordSet[index][idx][0], scope.Tx.Flags) 542 if view.sortValuesInEachCell != nil && idx < len(view.sortValuesInEachCell[index]) { 543 view.sortValuesInEachCell[index][idx] = sortValues[j] 544 } 545 } 546 } 547 view.sortValuesInEachRecord[index] = sortValues 548 return nil 549 }); err != nil { 550 return err 551 } 552 553 sort.Sort(view) 554 return nil 555 } 556 557 func (view *View) numberOfColumnsToBeAdded(exprs []parser.QueryExpression, funcs []parser.AnalyticFunction) int { 558 n := 0 559 560 analyticFunctionIdentifiers := make(map[string]bool, len(funcs)) 561 562 numberInAnalyticFunction := func(fn parser.AnalyticFunction) int { 563 if _, ok := view.Header.ContainsObject(fn); ok { 564 return 0 565 } 566 567 identifier := FormatFieldIdentifier(fn) 568 569 if _, ok := analyticFunctionIdentifiers[identifier]; ok { 570 return 0 571 } 572 573 analyticFunctionIdentifiers[identifier] = true 574 partitionExprs := fn.AnalyticClause.PartitionValues() 575 numberInPartitionClause := view.numberOfColumnsToBeAdded(partitionExprs, nil) 576 577 numberInOrderByClause := 0 578 if fn.AnalyticClause.OrderByClause != nil { 579 orderByExprs := GetValuesInOrderByClause(fn.AnalyticClause.OrderByClause.(parser.OrderByClause)) 580 numberInOrderByClause = view.numberOfColumnsToBeAdded(orderByExprs, nil) 581 } 582 583 return 1 + numberInOrderByClause + numberInPartitionClause 584 } 585 586 for _, expr := range exprs { 587 switch expr.(type) { 588 case parser.FieldReference, parser.ColumnNumber: 589 continue 590 case parser.AnalyticFunction: 591 n = n + numberInAnalyticFunction(expr.(parser.AnalyticFunction)) 592 default: 593 n = n + 1 594 } 595 } 596 597 for _, expr := range funcs { 598 n = n + numberInAnalyticFunction(expr) 599 } 600 601 return n 602 } 603 604 func (view *View) ExtendRecordCapacity(ctx context.Context, scope *ReferenceScope, exprs []parser.QueryExpression, funcs []parser.AnalyticFunction) error { 605 fieldCap := view.FieldLen() + view.numberOfColumnsToBeAdded(exprs, funcs) 606 607 if 0 < view.RecordLen() && fieldCap <= cap(view.RecordSet[0]) { 608 return nil 609 } 610 611 return NewGoroutineTaskManager(view.RecordLen(), -1, scope.Tx.Flags.CPU).Run(ctx, func(index int) error { 612 record := make(Record, view.FieldLen(), fieldCap) 613 copy(record, view.RecordSet[index]) 614 view.RecordSet[index] = record 615 return nil 616 }) 617 } 618 619 func (view *View) evalColumn(ctx context.Context, scope *ReferenceScope, obj parser.QueryExpression, alias string) (int, error) { 620 var idx = -1 621 var ok = false 622 623 switch obj.(type) { 624 case parser.FieldReference, parser.ColumnNumber, parser.AnalyticFunction: 625 idx, ok = view.Header.ContainsObject(obj) 626 627 switch obj.(type) { 628 case parser.FieldReference, parser.ColumnNumber: 629 if ok && view.isGrouped && view.Header[idx].IsFromTable && !view.Header[idx].IsGroupKey { 630 return idx, NewFieldNotGroupKeyError(obj) 631 } 632 } 633 } 634 635 if !ok { 636 if err := EvaluateSequentially(ctx, scope, view, func(seqScope *ReferenceScope, rIdx int) error { 637 primary, e := Evaluate(ctx, seqScope, obj) 638 if e != nil { 639 return e 640 } 641 642 view.RecordSet[rIdx] = append(view.RecordSet[rIdx], NewCell(primary)) 643 return nil 644 }); err != nil { 645 return idx, err 646 } 647 view.Header, idx = AddHeaderField(view.Header, FormatFieldIdentifier(obj), FormatFieldLabel(obj), alias) 648 } 649 650 if 0 < len(alias) { 651 if !strings.EqualFold(view.Header[idx].Column, alias) && !InStrSliceWithCaseInsensitive(alias, view.Header[idx].Aliases) { 652 view.Header[idx].Aliases = append(view.Header[idx].Aliases, alias) 653 } 654 } 655 656 return idx, nil 657 } 658 659 func (view *View) evalAnalyticFunction(ctx context.Context, scope *ReferenceScope, expr parser.AnalyticFunction) error { 660 if _, ok := view.Header.ContainsObject(expr); ok { 661 return nil 662 } 663 664 name := strings.ToUpper(expr.Name) 665 if _, ok := AggregateFunctions[name]; !ok { 666 if _, ok := AnalyticFunctions[name]; !ok { 667 if udfn, err := scope.GetFunction(expr, expr.Name); err != nil || !udfn.IsAggregate { 668 return NewFunctionNotExistError(expr, expr.Name) 669 } 670 } 671 } 672 673 var partitionIndices []int 674 if expr.AnalyticClause.PartitionClause != nil { 675 partitionExprs := expr.AnalyticClause.PartitionValues() 676 677 partitionIndices = make([]int, len(partitionExprs)) 678 for i, pexpr := range partitionExprs { 679 idx, err := view.evalColumn(ctx, scope, pexpr, "") 680 if err != nil { 681 return err 682 } 683 partitionIndices[i] = idx 684 } 685 } 686 687 if view.sortValuesInEachCell == nil { 688 view.sortValuesInEachCell = make([][]*SortValue, view.RecordLen()) 689 } 690 691 if expr.AnalyticClause.OrderByClause != nil { 692 err := view.OrderBy(ctx, scope, expr.AnalyticClause.OrderByClause.(parser.OrderByClause)) 693 if err != nil { 694 return err 695 } 696 } 697 698 err := Analyze(ctx, scope, view, expr, partitionIndices) 699 700 view.sortValuesInEachRecord = nil 701 view.sortDirections = nil 702 view.sortNullPositions = nil 703 704 return err 705 } 706 707 func (view *View) Offset(ctx context.Context, scope *ReferenceScope, clause parser.OffsetClause) error { 708 val, err := Evaluate(ctx, scope, clause.Value) 709 if err != nil { 710 return err 711 } 712 number := value.ToInteger(val) 713 if value.IsNull(number) { 714 return NewInvalidOffsetNumberError(clause) 715 } 716 view.offset = int(number.(*value.Integer).Raw()) 717 value.Discard(number) 718 719 if view.offset < 0 { 720 view.offset = 0 721 } 722 723 if view.RecordLen() <= view.offset { 724 view.RecordSet = RecordSet{} 725 } else { 726 newSet := view.RecordSet[view.offset:] 727 view.RecordSet = view.RecordSet[:len(newSet)] 728 for i := range newSet { 729 view.RecordSet[i] = newSet[i] 730 } 731 } 732 return nil 733 } 734 735 func (view *View) Limit(ctx context.Context, scope *ReferenceScope, clause parser.LimitClause) error { 736 val, err := Evaluate(ctx, scope, clause.Value) 737 if err != nil { 738 return err 739 } 740 741 var limit int 742 if clause.Percentage() { 743 number := value.ToFloat(val) 744 if value.IsNull(number) { 745 return NewInvalidLimitPercentageError(clause) 746 } 747 percentage := number.(*value.Float).Raw() 748 value.Discard(number) 749 750 if 100 < percentage { 751 limit = 100 752 } else if percentage < 0 { 753 limit = 0 754 } else { 755 limit = int(math.Ceil(float64(view.RecordLen()+view.offset) * percentage / 100)) 756 } 757 } else { 758 number := value.ToInteger(val) 759 if value.IsNull(number) { 760 return NewInvalidLimitNumberError(clause) 761 } 762 limit = int(number.(*value.Integer).Raw()) 763 value.Discard(number) 764 765 if limit < 0 { 766 limit = 0 767 } 768 } 769 770 if view.RecordLen() <= limit { 771 return nil 772 } 773 774 if clause.WithTies() && view.sortValuesInEachRecord != nil { 775 bottomSortValues := view.sortValuesInEachRecord[limit-1] 776 for limit < view.RecordLen() { 777 if !bottomSortValues.EquivalentTo(view.sortValuesInEachRecord[limit]) { 778 break 779 } 780 limit++ 781 } 782 } 783 784 view.RecordSet = view.RecordSet[:limit] 785 return nil 786 } 787 788 func (view *View) InsertValues(ctx context.Context, scope *ReferenceScope, fields []parser.QueryExpression, list []parser.QueryExpression) (int, error) { 789 recordValues, err := view.convertListToRecordValues(ctx, scope, fields, list) 790 if err != nil { 791 return 0, err 792 } 793 return view.insert(ctx, fields, recordValues) 794 } 795 796 func (view *View) InsertFromQuery(ctx context.Context, scope *ReferenceScope, fields []parser.QueryExpression, query parser.SelectQuery) (int, error) { 797 recordValues, err := view.convertResultSetToRecordValues(ctx, scope, fields, query) 798 if err != nil { 799 return 0, err 800 } 801 return view.insert(ctx, fields, recordValues) 802 } 803 804 func (view *View) ReplaceValues(ctx context.Context, scope *ReferenceScope, fields []parser.QueryExpression, list []parser.QueryExpression, keys []parser.QueryExpression) (int, error) { 805 recordValues, err := view.convertListToRecordValues(ctx, scope, fields, list) 806 if err != nil { 807 return 0, err 808 } 809 return view.replace(ctx, scope.Tx.Flags, fields, recordValues, keys) 810 } 811 812 func (view *View) ReplaceFromQuery(ctx context.Context, scope *ReferenceScope, fields []parser.QueryExpression, query parser.SelectQuery, keys []parser.QueryExpression) (int, error) { 813 recordValues, err := view.convertResultSetToRecordValues(ctx, scope, fields, query) 814 if err != nil { 815 return 0, err 816 } 817 return view.replace(ctx, scope.Tx.Flags, fields, recordValues, keys) 818 } 819 820 func (view *View) convertListToRecordValues(ctx context.Context, scope *ReferenceScope, fields []parser.QueryExpression, list []parser.QueryExpression) ([][]value.Primary, error) { 821 recordValues := make([][]value.Primary, len(list)) 822 for i, item := range list { 823 if ctx.Err() != nil { 824 return nil, ConvertContextError(ctx.Err()) 825 } 826 827 rv := item.(parser.RowValue) 828 values, err := EvalRowValue(ctx, scope, rv) 829 if err != nil { 830 return recordValues, err 831 } 832 if len(fields) != len(values) { 833 return recordValues, NewInsertRowValueLengthError(rv, len(fields)) 834 } 835 836 recordValues[i] = values 837 } 838 return recordValues, nil 839 } 840 841 func (view *View) convertResultSetToRecordValues(ctx context.Context, scope *ReferenceScope, fields []parser.QueryExpression, query parser.SelectQuery) ([][]value.Primary, error) { 842 selectedView, err := Select(ctx, scope, query) 843 if err != nil { 844 return nil, err 845 } 846 if len(fields) != selectedView.FieldLen() { 847 return nil, NewInsertSelectFieldLengthError(query, len(fields)) 848 } 849 850 recordValues := make([][]value.Primary, selectedView.RecordLen()) 851 for i, record := range selectedView.RecordSet { 852 if ctx.Err() != nil { 853 return nil, ConvertContextError(ctx.Err()) 854 } 855 856 values := make([]value.Primary, selectedView.FieldLen()) 857 for j, cell := range record { 858 values[j] = cell[0] 859 } 860 recordValues[i] = values 861 } 862 return recordValues, nil 863 } 864 865 func (view *View) convertRecordValuesToRecordSet(ctx context.Context, fields []parser.QueryExpression, recordValues [][]value.Primary) (RecordSet, error) { 866 var valueIndex = func(i int, list []int) int { 867 for j, v := range list { 868 if i == v { 869 return j 870 } 871 } 872 return -1 873 } 874 875 fieldIndices, err := view.FieldIndices(fields) 876 if err != nil { 877 return nil, err 878 } 879 880 recordIndices := make([]int, view.FieldLen()) 881 for i := 0; i < view.FieldLen(); i++ { 882 recordIndices[i] = valueIndex(i, fieldIndices) 883 } 884 885 records := make(RecordSet, len(recordValues)) 886 for i, values := range recordValues { 887 if ctx.Err() != nil { 888 return nil, ConvertContextError(ctx.Err()) 889 } 890 891 record := make(Record, view.FieldLen()) 892 for j := 0; j < view.FieldLen(); j++ { 893 if recordIndices[j] < 0 { 894 record[j] = NewCell(value.NewNull()) 895 } else { 896 record[j] = NewCell(values[recordIndices[j]]) 897 } 898 } 899 records[i] = record 900 } 901 return records, nil 902 } 903 904 func (view *View) insert(ctx context.Context, fields []parser.QueryExpression, recordValues [][]value.Primary) (int, error) { 905 records, err := view.convertRecordValuesToRecordSet(ctx, fields, recordValues) 906 if err != nil { 907 return 0, err 908 } 909 910 view.RecordSet = view.RecordSet.Merge(records) 911 return len(recordValues), nil 912 } 913 914 func (view *View) replace(ctx context.Context, flags *option.Flags, fields []parser.QueryExpression, recordValues [][]value.Primary, keys []parser.QueryExpression) (int, error) { 915 fieldIndices, err := view.FieldIndices(fields) 916 if err != nil { 917 return 0, err 918 } 919 fieldIndicesMap := make(map[uint]bool, len(fieldIndices)) 920 for _, v := range fieldIndices { 921 fieldIndicesMap[uint(v)] = true 922 } 923 924 keyIndices, err := view.FieldIndices(keys) 925 if err != nil { 926 return 0, err 927 } 928 keyIndicesMap := make(map[uint]bool, len(keyIndices)) 929 for _, v := range keyIndices { 930 keyIndicesMap[uint(v)] = true 931 } 932 933 for idx, i := range keyIndices { 934 if _, ok := fieldIndicesMap[uint(i)]; !ok { 935 return 0, NewReplaceKeyNotSetError(keys[idx]) 936 } 937 } 938 updateIndices := make([]int, 0, len(fieldIndices)-len(keyIndices)) 939 for _, i := range fieldIndices { 940 if _, ok := keyIndicesMap[uint(i)]; !ok { 941 updateIndices = append(updateIndices, i) 942 } 943 } 944 945 records, err := view.convertRecordValuesToRecordSet(ctx, fields, recordValues) 946 if err != nil { 947 return 0, err 948 } 949 950 sortValuesInEachRecord := make([]SortValues, view.RecordLen()) 951 if err := NewGoroutineTaskManager(view.RecordLen(), -1, flags.CPU).Run(ctx, func(index int) error { 952 sortValues := make(SortValues, len(keyIndices)) 953 for j, idx := range keyIndices { 954 sortValues[j] = NewSortValue(view.RecordSet[index][idx][0], flags) 955 } 956 sortValuesInEachRecord[index] = sortValues 957 return nil 958 }); err != nil { 959 return 0, err 960 } 961 962 sortValuesInInsertRecords := make([]SortValues, len(records)) 963 if err := NewGoroutineTaskManager(len(records), -1, flags.CPU).Run(ctx, func(index int) error { 964 sortValues := make(SortValues, len(keyIndices)) 965 for j, idx := range keyIndices { 966 sortValues[j] = NewSortValue(records[index][idx][0], flags) 967 } 968 sortValuesInInsertRecords[index] = sortValues 969 return nil 970 }); err != nil { 971 return 0, err 972 } 973 974 replacedRecord := make(map[int]bool, len(records)) 975 replacedCount := 0 976 for i := range records { 977 replacedRecord[i] = false 978 } 979 replaceMtx := &sync.Mutex{} 980 var replaced = func(idx int) { 981 replaceMtx.Lock() 982 replacedRecord[idx] = true 983 replacedCount++ 984 replaceMtx.Unlock() 985 } 986 if err := NewGoroutineTaskManager(view.RecordLen(), -1, flags.CPU).Run(ctx, func(index int) error { 987 for j, rsv := range sortValuesInInsertRecords { 988 if sortValuesInEachRecord[index].EquivalentTo(rsv) { 989 for _, fidx := range updateIndices { 990 view.RecordSet[index][fidx] = records[j][fidx] 991 } 992 replaced(j) 993 break 994 } 995 } 996 return nil 997 }); err != nil { 998 return 0, err 999 } 1000 1001 insertRecords := make(RecordSet, 0, len(records)) 1002 for i, isReplaced := range replacedRecord { 1003 if !isReplaced { 1004 insertRecords = append(insertRecords, records[i]) 1005 } 1006 } 1007 view.RecordSet = view.RecordSet.Merge(insertRecords) 1008 return len(insertRecords) + replacedCount, nil 1009 } 1010 1011 func (view *View) Fix(ctx context.Context, flags *option.Flags) error { 1012 fieldLen := len(view.selectFields) 1013 resize := false 1014 if fieldLen != view.FieldLen() { 1015 resize = true 1016 } else { 1017 for i := 0; i < view.FieldLen(); i++ { 1018 if view.selectFields[i] != i { 1019 resize = true 1020 break 1021 } 1022 } 1023 } 1024 1025 if resize { 1026 if err := NewGoroutineTaskManager(view.RecordLen(), -1, flags.CPU).Run(ctx, func(index int) error { 1027 record := make(Record, fieldLen) 1028 for j, idx := range view.selectFields { 1029 record[j] = view.RecordSet[index][idx][:1] 1030 } 1031 1032 if len(view.RecordSet[index]) < fieldLen { 1033 view.RecordSet[index] = make(Record, fieldLen) 1034 } else if fieldLen < len(view.RecordSet[index]) { 1035 view.RecordSet[index] = view.RecordSet[index][:fieldLen] 1036 } 1037 for i := range record { 1038 view.RecordSet[index][i] = record[i] 1039 } 1040 return nil 1041 }); err != nil { 1042 return err 1043 } 1044 } 1045 1046 hfields := NewEmptyHeader(len(view.selectFields)) 1047 1048 colNumber := 0 1049 for i, idx := range view.selectFields { 1050 colNumber++ 1051 1052 hfields[i] = view.Header[idx] 1053 hfields[i].Identifier = "" 1054 hfields[i].Aliases = nil 1055 hfields[i].Number = colNumber 1056 hfields[i].IsFromTable = true 1057 hfields[i].IsJoinColumn = false 1058 hfields[i].IsGroupKey = false 1059 1060 if 0 < len(view.selectLabels) { 1061 hfields[i].Column = view.selectLabels[i] 1062 } 1063 } 1064 1065 view.Header = hfields 1066 view.selectFields = nil 1067 view.selectLabels = nil 1068 view.isGrouped = false 1069 view.comparisonKeysInEachRecord = nil 1070 view.sortValuesInEachCell = nil 1071 view.sortValuesInEachRecord = nil 1072 view.sortDirections = nil 1073 view.sortNullPositions = nil 1074 view.offset = 0 1075 return nil 1076 } 1077 1078 func (view *View) Union(ctx context.Context, flags *option.Flags, calcView *View, all bool) (err error) { 1079 view.RecordSet = view.RecordSet.Merge(calcView.RecordSet) 1080 view.FileInfo = nil 1081 1082 if !all { 1083 if err = view.GenerateComparisonKeys(ctx, flags); err != nil { 1084 return err 1085 } 1086 1087 records := make(RecordSet, 0, view.RecordLen()) 1088 values := make(map[string]bool) 1089 1090 for i, key := range view.comparisonKeysInEachRecord { 1091 if !values[key] { 1092 values[key] = true 1093 records = append(records, view.RecordSet[i]) 1094 } 1095 } 1096 1097 view.RecordSet = records 1098 view.comparisonKeysInEachRecord = nil 1099 } 1100 return 1101 } 1102 1103 func (view *View) Except(ctx context.Context, flags *option.Flags, calcView *View, all bool) (err error) { 1104 if err = view.GenerateComparisonKeys(ctx, flags); err != nil { 1105 return err 1106 } 1107 if err = calcView.GenerateComparisonKeys(ctx, flags); err != nil { 1108 return err 1109 } 1110 1111 keys := make(map[string]bool) 1112 for _, key := range calcView.comparisonKeysInEachRecord { 1113 if !keys[key] { 1114 keys[key] = true 1115 } 1116 } 1117 1118 distinctKeys := make(map[string]bool) 1119 records := make(RecordSet, 0, view.RecordLen()) 1120 for i, key := range view.comparisonKeysInEachRecord { 1121 if !keys[key] { 1122 if !all { 1123 if distinctKeys[key] { 1124 continue 1125 } 1126 distinctKeys[key] = true 1127 } 1128 records = append(records, view.RecordSet[i]) 1129 } 1130 } 1131 view.RecordSet = records 1132 view.FileInfo = nil 1133 view.comparisonKeysInEachRecord = nil 1134 return 1135 } 1136 1137 func (view *View) Intersect(ctx context.Context, flags *option.Flags, calcView *View, all bool) (err error) { 1138 if err = view.GenerateComparisonKeys(ctx, flags); err != nil { 1139 return err 1140 } 1141 if err = calcView.GenerateComparisonKeys(ctx, flags); err != nil { 1142 return err 1143 } 1144 1145 keys := make(map[string]bool) 1146 for _, key := range calcView.comparisonKeysInEachRecord { 1147 if !keys[key] { 1148 keys[key] = true 1149 } 1150 } 1151 1152 distinctKeys := make(map[string]bool) 1153 records := make(RecordSet, 0, view.RecordLen()) 1154 for i, key := range view.comparisonKeysInEachRecord { 1155 if _, ok := keys[key]; ok { 1156 if !all { 1157 if distinctKeys[key] { 1158 continue 1159 } 1160 distinctKeys[key] = true 1161 } 1162 records = append(records, view.RecordSet[i]) 1163 } 1164 } 1165 view.RecordSet = records 1166 view.FileInfo = nil 1167 view.comparisonKeysInEachRecord = nil 1168 return 1169 } 1170 1171 func (view *View) ListValuesForAggregateFunctions(ctx context.Context, scope *ReferenceScope, expr parser.QueryExpression, arg parser.QueryExpression, distinct bool) ([]value.Primary, error) { 1172 list := make([]value.Primary, view.RecordLen()) 1173 1174 if err := EvaluateSequentially(ctx, scope, view, func(sqlScope *ReferenceScope, rIdx int) error { 1175 p, e := Evaluate(ctx, sqlScope, arg) 1176 if e != nil { 1177 if _, ok := e.(*NotGroupingRecordsError); ok { 1178 e = NewNestedAggregateFunctionsError(expr) 1179 } 1180 return e 1181 } 1182 list[rIdx] = p 1183 return nil 1184 }); err != nil { 1185 return nil, err 1186 } 1187 1188 if distinct { 1189 list = Distinguish(list, scope.Tx.Flags) 1190 } 1191 1192 return list, nil 1193 } 1194 1195 func (view *View) RestoreHeaderReferences() error { 1196 return view.Header.Update(FormatTableName(view.FileInfo.Path), nil) 1197 } 1198 1199 func (view *View) FieldIndex(fieldRef parser.QueryExpression) (int, error) { 1200 idx, err := view.Header.SearchIndex(fieldRef) 1201 if err != nil { 1202 if err == errFieldAmbiguous { 1203 err = NewFieldAmbiguousError(fieldRef) 1204 } else { 1205 err = NewFieldNotExistError(fieldRef) 1206 } 1207 } 1208 return idx, err 1209 } 1210 1211 func (view *View) FieldIndices(fields []parser.QueryExpression) ([]int, error) { 1212 indices := make([]int, len(fields)) 1213 for i, v := range fields { 1214 idx, err := view.FieldIndex(v) 1215 if err != nil { 1216 return nil, err 1217 } 1218 indices[i] = idx 1219 } 1220 return indices, nil 1221 } 1222 1223 func (view *View) FieldViewName(fieldRef parser.QueryExpression) (string, error) { 1224 idx, err := view.FieldIndex(fieldRef) 1225 if err != nil { 1226 return "", err 1227 } 1228 return view.Header[idx].View, nil 1229 } 1230 1231 func (view *View) InternalRecordId(ref string, recordIndex int) (int, error) { 1232 idx, err := view.Header.ContainsInternalId(ref) 1233 if err != nil { 1234 return -1, NewInternalRecordIdNotExistError() 1235 } 1236 internalId, ok := view.RecordSet[recordIndex][idx][0].(*value.Integer) 1237 if !ok { 1238 return -1, NewInternalRecordIdEmptyError() 1239 } 1240 return int(internalId.Raw()), nil 1241 } 1242 1243 func (view *View) CreateRestorePoint() { 1244 view.FileInfo.restorePointRecordSet = view.RecordSet.Copy() 1245 view.FileInfo.restorePointHeader = view.Header.Copy() 1246 } 1247 1248 func (view *View) Restore() { 1249 view.RecordSet = view.FileInfo.restorePointRecordSet.Copy() 1250 view.Header = view.FileInfo.restorePointHeader.Copy() 1251 } 1252 1253 func (view *View) FieldLen() int { 1254 return view.Header.Len() 1255 } 1256 1257 func (view *View) RecordLen() int { 1258 return view.Len() 1259 } 1260 1261 func (view *View) Len() int { 1262 return len(view.RecordSet) 1263 } 1264 1265 func (view *View) Swap(i, j int) { 1266 view.RecordSet[i], view.RecordSet[j] = view.RecordSet[j], view.RecordSet[i] 1267 view.sortValuesInEachRecord[i], view.sortValuesInEachRecord[j] = view.sortValuesInEachRecord[j], view.sortValuesInEachRecord[i] 1268 if view.sortValuesInEachCell != nil { 1269 view.sortValuesInEachCell[i], view.sortValuesInEachCell[j] = view.sortValuesInEachCell[j], view.sortValuesInEachCell[i] 1270 } 1271 } 1272 1273 func (view *View) Less(i, j int) bool { 1274 return view.sortValuesInEachRecord[i].Less(view.sortValuesInEachRecord[j], view.sortDirections, view.sortNullPositions) 1275 } 1276 1277 func (view *View) Copy() *View { 1278 header := view.Header.Copy() 1279 records := view.RecordSet.Copy() 1280 1281 return &View{ 1282 Header: header, 1283 RecordSet: records, 1284 FileInfo: view.FileInfo, 1285 } 1286 }