Hi, I’m trying to finish the Proj5 part2 tinysql. I followed instructions step by step but always fail in some test.
Here is my first function fetchAndBuildHashTable:
概要
func (e *HashJoinExec) fetchAndBuildHashTable(ctx context.Context) error {
// TODO: Implementing the building hash table stage.
// In this stage, you'll read the data from the inner side executor of the join operator and
// then use its data to build hash table.
// You'll need to store the hash table in `e.rowContainer`
// and you can call `newHashRowContainer` in `executor/hash_table.go` to build it.
// In this stage you can only assign value for `e.rowContainer` without changing any value of the `HashJoinExec`.
// init a new list for chunk
innerResult := chunk.NewList(e.innerSideExec.base().retFieldTypes, e.ctx.GetSessionVars().InitChunkSize, e.maxChunkSize)
for {
chk := chunk.New(e.innerSideExec.base().retFieldTypes, e.ctx.GetSessionVars().InitChunkSize, e.ctx.GetSessionVars().MaxChunkSize)
err := e.innerSideExec.Next(ctx, chk)
if err != nil {
return errors.Trace(err)
}
if chk.NumRows() == 0 {
break
}
innerResult.Add(chk)
}
buildKeyColIdx := make([]int, len(e.innerKeys))
for i := range e.innerKeys {
buildKeyColIdx[i] = e.innerKeys[i].Index
}
hCtx := &hashContext{
allTypes: e.innerSideExec.base().retFieldTypes,
keyColIdx: buildKeyColIdx,
}
e.rowContainer= newHashRowContainer(e.innerSideExec.base().ctx, int(e.innerSideEstCount), hCtx, innerResult)
return nil
}
My another function runJoinWorkers
概要
func (e *HashJoinExec) runJoinWorker(workerID uint, outerKeyColIdx []int) {
// TODO: Implement the worker of probing stage.
// In this method, you read the data from the channel e.outerResultChs[workerID].
// Then use `e.join2Chunk` method get the joined result `joinResult`,
// and put the `joinResult` into the channel `e.joinResultCh`.
// You may pay attention to:
// - e.closeCh, this is a channel tells that the join can be terminated as soon as possible.
// Read and filter outerResult, and join the outerResult with the inner rows.
emptyOuterResult := &outerChkResource{
dest: e.outerResultChs[workerID],
}
hCtx := &hashContext{
allTypes: e.outerSideExec.base().retFieldTypes,
keyColIdx: outerKeyColIdx,
}
var (
outerChunk *chunk.Chunk
selected = make([]bool, 0, chunk.InitialCapacity)
)
// reuse JoinResult Chk from main goroutine
ok, joinResult := e.getNewJoinResult(workerID)
if !ok {
return
}
for ok = true; ok;{
select{
case <-e.closeCh:
return
// get outerChunk from Outer Fetcher Goroutine
case outerChunk, ok = <-e.outerResultChs[workerID]:
}
if !ok{
break
}
// look up in hash table and compare different rows
ok, joinResult = e.join2Chunk(workerID, outerChunk, hCtx, joinResult, selected)
if !ok{
break
}
// send back info to outerChkResou
outerChunk.Reset()
emptyOuterResult.chk = outerChunk
e.outerChkResourceCh <- emptyOuterResult
}
// send result to joinResultCh
if joinResult == nil {
return
} else if joinResult.err != nil || (joinResult.chk != nil && joinResult.chk.NumRows() > 0) {
e.joinResultCh <- joinResult
} else if joinResult.chk != nil && joinResult.chk.NumRows() == 0 {
e.joinChkResourceCh[workerID] <- joinResult.chk
}
}
Can you give me some advice on debugging/ Am I misunderstanding the instructions somewhere? I also tried to follow source code and master branch code, but also fail, which made me doubt at the correctness of program itself.
The test failed at join result. For example, TestJoin case:
... obtained string = ""
... expected string = "[1]\
"
... sql:select 1 from t as a join t as b on 1
One more thing, seems that the function name NextChunk
is no longer used but github tutorial is still using it. I can only find Next
.