mirror of
https://github.com/apache/impala.git
synced 2025-12-19 18:12:08 -05:00
Fix crash in TopN node with null tuples.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -26,3 +26,4 @@ Testing/
|
||||
llvm-ir/
|
||||
shell/gen-py/
|
||||
shell/build/
|
||||
tests/results
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
====
|
||||
|
||||
Reference in New Issue
Block a user