(joinCommand *ast.JoinCommand, leftTableName string)
| 548 | } |
| 549 | |
| 550 | func (engine *DbEngine) joinTables(joinCommand *ast.JoinCommand, leftTableName string) (*Table, error) { |
| 551 | leftTable, exist := engine.Tables[leftTableName] |
| 552 | leftTablePrefix := leftTableName + "." |
| 553 | if !exist { |
| 554 | return nil, &TableDoesNotExistError{leftTableName} |
| 555 | } |
| 556 | |
| 557 | rightTableName := joinCommand.Name.Token.Literal |
| 558 | rightTablePrefix := rightTableName + "." |
| 559 | rightTable, exist := engine.Tables[rightTableName] |
| 560 | if !exist { |
| 561 | return nil, &TableDoesNotExistError{rightTableName} |
| 562 | } |
| 563 | |
| 564 | joinedTable := &Table{Columns: []*Column{}} |
| 565 | |
| 566 | addColumnsWithPrefix(joinedTable, leftTable.Columns, leftTablePrefix) |
| 567 | addColumnsWithPrefix(joinedTable, rightTable.Columns, rightTablePrefix) |
| 568 | |
| 569 | leftTableWithAddedPrefix := leftTable.getTableCopyWithAddedPrefixToColumnNames(leftTablePrefix) |
| 570 | rightTableWithAddedPrefix := rightTable.getTableCopyWithAddedPrefixToColumnNames(rightTablePrefix) |
| 571 | var unmatchedRightRows = make(map[int]bool) |
| 572 | |
| 573 | for leftRowIndex := 0; leftRowIndex < len(leftTable.Columns[0].Values); leftRowIndex++ { |
| 574 | joinedRowLeft := getRow(leftTableWithAddedPrefix, leftRowIndex) |
| 575 | leftRowMatches := false |
| 576 | |
| 577 | for rightRowIndex := 0; rightRowIndex < len(rightTable.Columns[0].Values); rightRowIndex++ { |
| 578 | joinedRowRight := getRow(rightTableWithAddedPrefix, rightRowIndex) |
| 579 | maps.Copy(joinedRowRight, joinedRowLeft) |
| 580 | |
| 581 | fulfilledFilters, err := isFulfillingFilters(joinedRowRight, joinCommand.Expression, joinCommand.Token.Literal) |
| 582 | if err != nil { |
| 583 | return nil, err |
| 584 | } |
| 585 | |
| 586 | isLastLeftRow := leftRowIndex == len(leftTable.Columns[0].Values)-1 |
| 587 | |
| 588 | if fulfilledFilters { |
| 589 | for colIndex, column := range joinedTable.Columns { |
| 590 | joinedTable.Columns[colIndex].Values = append(joinedTable.Columns[colIndex].Values, joinedRowRight[column.Name]) |
| 591 | } |
| 592 | leftRowMatches, unmatchedRightRows[rightRowIndex] = true, true |
| 593 | } else if isLastLeftRow && joinCommand.ShouldTakeRightSide() && !unmatchedRightRows[rightRowIndex] { |
| 594 | joinedRowRight = getRow(rightTableWithAddedPrefix, rightRowIndex) |
| 595 | aggregateRowIntoJoinTable(leftTableWithAddedPrefix, joinedRowRight, joinedTable) |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | if joinCommand.ShouldTakeLeftSide() && !leftRowMatches { |
| 600 | aggregateRowIntoJoinTable(rightTableWithAddedPrefix, joinedRowLeft, joinedTable) |
| 601 | } |
| 602 | } |
| 603 | |
| 604 | return joinedTable, nil |
| 605 | } |
| 606 | |
| 607 | func aggregateRowIntoJoinTable(tableWithAddedPrefix *Table, joinedRow map[string]ValueInterface, joinedTable *Table) { |
no test coverage detected