Fix crash in TopN node with null tuples.

This commit is contained in:
Nong Li
2012-11-29 14:14:42 -08:00
committed by Henry Robinson
parent b7c348edfa
commit fbfef4e22e
4 changed files with 46 additions and 13 deletions

1
.gitignore vendored
View File

@@ -26,3 +26,4 @@ Testing/
llvm-ir/
shell/gen-py/
shell/build/
tests/results

View File

@@ -151,13 +151,9 @@ void TopNNode::InsertTupleRow(TupleRow* input_row) {
} else {
TupleRow* top_tuple_row = priority_queue_.top();
if (tuple_row_less_than_(input_row, top_tuple_row)) {
for (int i = 0; i < tuple_descs_.size(); ++i) {
Tuple* dst_tuple = top_tuple_row->GetTuple(i);
Tuple* src_tuple = input_row->GetTuple(i);
// TODO: DeepCopy will allocate new buffers for the string data. This needs
// to be fixed to use a freelist
src_tuple->DeepCopy(dst_tuple, *(tuple_descs_[i]), tuple_pool_.get());
}
// TODO: DeepCopy will allocate new buffers for the string data. This needs
// to be fixed to use a freelist
input_row->DeepCopy(top_tuple_row, tuple_descs_, tuple_pool_.get(), true);
insert_tuple_row = top_tuple_row;
priority_queue_.pop();
}

View File

@@ -34,19 +34,34 @@ class TupleRow {
tuples_[tuple_idx] = tuple;
}
// Create a deep copy of this TupleRow. DeepCopy will allocate from the MemPool and copy
// the tuple pointers, the tuples and the string data in the tuples.
// Create a deep copy of this TupleRow. DeepCopy will allocate from the pool.
TupleRow* DeepCopy(const std::vector<TupleDescriptor*> descs, MemPool* pool) {
int size = descs.size() * sizeof(Tuple*);
TupleRow* result = reinterpret_cast<TupleRow*>(pool->Allocate(size));
DeepCopy(result, descs, pool, false);
return result;
}
// Create a deep copy of this TupleRow into 'dst'. DeepCopy will allocate from
// the MemPool and coyp the tuple pointers, the tuples and the string data in the tuples.
// If reuse_tuple_mem is true, it is assumed the dst TupleRow has already allocated
// tuple memory and that memory will be reused. Otherwise, new tuples will be allocated
// and stored in 'dst'.
void DeepCopy(TupleRow* dst, const std::vector<TupleDescriptor*> descs, MemPool* pool,
bool reuse_tuple_mem) {
for (int i = 0; i < descs.size(); ++i) {
if (this->GetTuple(i) != NULL) {
result->SetTuple(i, this->GetTuple(i)->DeepCopy(*descs[i], pool));
if (reuse_tuple_mem && dst->GetTuple(i) != NULL) {
this->GetTuple(i)->DeepCopy(dst->GetTuple(i), *descs[i], pool);
} else {
dst->SetTuple(i, this->GetTuple(i)->DeepCopy(*descs[i], pool));
}
} else {
result->SetTuple(i, NULL);
// TODO: this is wasteful. If we have 'reuse_tuple_mem', we should be able
// to save the tuple buffer and reuse it (i.e. freelist).
dst->SetTuple(i, NULL);
}
}
return result;
}
// TODO: make a macro for doing this

View File

@@ -648,4 +648,25 @@ from alltypessmall order by 1 limit 20
2008-12-20 00:23:00.930000000,2009-03-03 00:23:00.930000000,73
---- TYPES
TIMESTAMP, TIMESTAMP, INT
====
====
---- QUERY
# Test of order by with NULL tuple rows (from an outer join)
select t1.id, t1.int_col, t2.id, t2.int_col
from alltypesagg t1
left outer join alltypessmall t2
on (t1.int_col = t2.int_col)
order by t1.id,t2.id limit 10
---- TYPES
int,int,int,int
---- RESULTS
0,NULL,NULL,NULL
1,1,1,1
1,1,11,1
1,1,21,1
1,1,26,1
1,1,36,1
1,1,46,1
1,1,51,1
1,1,61,1
1,1,71,1
====