As requested at the bottom of this message is the backtrace from lldb
regarding the error I'm seeing. I think there might be a race condition
with the two hash tables being constructed. There are times that the
execution will proceed past the build stage to where I'm expecting it to
fail, and sometimes where it fails on key validation. Looking at the
HashTable code I'm seeing there might be an issue with me using a
defined type with force_key_copy set to FALSE. The work orders might be
swapping between constructing the two hash tables so would setting this
to TRUE fix the race condition? I'm thinking it might if I'm
interpreting it correctly.
* thread #2, stop reason = signal SIGABRT
* frame #0: 0x00007fffc1dccd42 libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x00007fffc1eba457 libsystem_pthread.dylib`pthread_kill + 90
frame #2: 0x00007fffc1d32420 libsystem_c.dylib`abort + 129
frame #3: 0x00007fffc1cf9893 libsystem_c.dylib`__assert_rtn + 320
frame #4: 0x000000010067cc2c
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`quickstep::SimpleScalarSeparateChainingHashTable<quickstep::TupleReference,
true, false, false, true>::putInternal(this=0x000000011e302e10,
key=0x000070000055ee30, variable_key_size=0, value=0x000070000055ee20,
prealloc_state=0x000070000055f018) at
SimpleScalarSeparateChainingHashTable.hpp:629
frame #5: 0x00000001002d5fdd
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`quickstep::HashTablePutResult
quickstep::HashTablePutResult
quickstep::HashTable<quickstep::TupleReference, true, false, false,
true>::putValueAccessor<quickstep::(anonymous
namespace)::TupleReferenceGenerator>(this=0x000070000055efd0,
accessor=0x000000011d703950)::TupleReferenceGenerator*)::'lambda'(quickstep::(anonymous
namespace)::TupleReferenceGenerator*)::operator()<quickstep::SplitRowStoreValueAccessor>(quickstep::(anonymous
namespace)::TupleReferenceGenerator*) const at HashTable.hpp:1424
frame #6: 0x00000001002d0472
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`auto
quickstep::InvokeOnValueAccessorNotAdapter<quickstep::HashTablePutResult
quickstep::HashTable<quickstep::TupleReference, true, false, false,
true>::putValueAccessor<quickstep::(anonymous
namespace)::TupleReferenceGenerator>(quickstep::ValueAccessor*, int,
bool, quickstep::(anonymous
namespace)::TupleReferenceGenerator*)::'lambda'(quickstep::(anonymous
namespace)::TupleReferenceGenerator*)>(accessor=0x000000011d703950,
functor=0x000070000055efd0)::TupleReferenceGenerator const&) at
ValueAccessorUtil.hpp:73
frame #7: 0x00000001002cfb43
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`auto
quickstep::InvokeOnAnyValueAccessor<quickstep::HashTablePutResult
quickstep::HashTable<quickstep::TupleReference, true, false, false,
true>::putValueAccessor<quickstep::(anonymous
namespace)::TupleReferenceGenerator>(quickstep::ValueAccessor*, int,
bool, quickstep::(anonymous
namespace)::TupleReferenceGenerator*)::'lambda'(quickstep::(anonymous
namespace)::TupleReferenceGenerator*)>(accessor=0x000000011d703950,
functor=0x000070000055efd0)::TupleReferenceGenerator const&) at
ValueAccessorUtil.hpp:256
frame #8: 0x00000001002cf54e
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`quickstep::HashTablePutResult
quickstep::HashTable<quickstep::TupleReference, true, false, false,
true>::putValueAccessor<quickstep::(anonymous
namespace)::TupleReferenceGenerator>(this=0x000000011e302e10,
accessor=0x000000011d703950, key_attr_id=0, check_for_null_keys=false,
functor=0x000070000055f1b0)::TupleReferenceGenerator*) at HashTable.hpp:1373
frame #9: 0x00000001002ceecc
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`quickstep::BuildGeneralizedHashWorkOrder::execute(this=0x000000011d703880)
at BuildGeneralizedHashOperator.cpp:283
frame #10: 0x00000001000c0c55
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`quickstep::Worker::executeWorkOrderHelper(this=0x000000011e0025d0,
tagged_message=0x000070000055fc50, proto=0x000070000055fbc0,
is_rebuild_work_order=false) at Worker.cpp:137
frame #11: 0x00000001000c066d
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`quickstep::Worker::run(this=0x000000011e0025d0)
at Worker.cpp:78
frame #12: 0x000000010023c0a4
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`quickstep::threading_internal::executeRunMethodForThreadReturnNothing(thread_ptr=0x000000011e0025d0)
at Thread.cpp:30
frame #13: 0x000000010000f15d
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`void*
std::__1::__thread_proxy<std::__1::tuple<void (*)(void*),
quickstep::ThreadImplCPP11*> >(void*) [inlined]
decltype(__f=0x000000011e0039f0,
__args=0x000000011e0039f8)(void*)>(fp)(std::__1::forward<quickstep::ThreadImplCPP11*>(fp0)))
std::__1::__invoke<void (*)(void*), quickstep::ThreadImplCPP11*>(void
(*&&)(void*), quickstep::ThreadImplCPP11*&&) at __functional_base:416
frame #14: 0x000000010000f145
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`void*
std::__1::__thread_proxy<std::__1::tuple<void (*)(void*),
quickstep::ThreadImplCPP11*> >(void*) [inlined] void
std::__1::__thread_execute<void (*)(void*), quickstep::ThreadImplCPP11*,
1ul>(__t=0x000000011e0039f0)(void*), quickstep::ThreadImplCPP11*>&,
std::__1::__tuple_indices<1ul>) at thread:347
frame #15: 0x000000010000f11d
quickstep_queryoptimizer_tests_ExecutionGeneratorTest`void*
std::__1::__thread_proxy<std::__1::tuple<void (*)(void*),
quickstep::ThreadImplCPP11*> >(__vp=0x000000011e0039f0) at thread:357
frame #16: 0x00007fffc1eb793b libsystem_pthread.dylib`_pthread_body
+ 180
frame #17: 0x00007fffc1eb7887
libsystem_pthread.dylib`_pthread_start + 286
frame #18: 0x00007fffc1eb708d libsystem_pthread.dylib`thread_start + 13
On 11/15/17 6:19 PM, Dylan Bacon wrote:
I'm working on getting the build functionality of two hash tables in a
single physical plan node to work. The code for this can be found at
my fork branch here
(https://github.com/dylanpbacon/incubator-quickstep/tree/Generalized-Hash)
or in the associated PR on the main tree. I've been running into a
key.isPlausibleInstanceOf error when the BuildGeneralizedHash attempts
to populate a hash table. The key types used are not plausible it
seems, though everything seems to be in order.
The code can be found starting at ExecutionGenerator.cpp:1124 and
following the classes and execution order for that function. Is there
anything fundamental to how a hash table in a given query context or
plan node works that would prohibit two being used at the same time or
would cause them to conflict in some way? Both hash tables should fit
within memory for this first implementation.