dbms: fixed error with IN [#METR-15293].

This commit is contained in:
Alexey Milovidov 2015-03-03 23:00:39 +03:00
parent a21b2573c5
commit 9981a29365
2 changed files with 23 additions and 38 deletions

View File

@ -55,9 +55,8 @@ struct SetMethodOneNumber
Key getKey( Key getKey(
const ConstColumnPlainPtrs & key_columns, /// Ключевые столбцы. const ConstColumnPlainPtrs & key_columns, /// Ключевые столбцы.
size_t keys_size, /// Количество ключевых столбцов. size_t keys_size, /// Количество ключевых столбцов.
size_t i, /// Из какой строки блока достать ключ. size_t i, /// Из какой строки блока достать ключ.
const Sizes & key_sizes, /// Если ключи фиксированной длины - их длины. Не используется в методах по ключам переменной длины. const Sizes & key_sizes) const /// Если ключи фиксированной длины - их длины. Не используется в методах по ключам переменной длины.
StringRefs & keys) const /// Сюда могут быть записаны ссылки на данные ключей в столбцах. Они могут быть использованы в дальнейшем.
{ {
return unionCastToUInt64(vec[i]); return unionCastToUInt64(vec[i]);
} }
@ -65,7 +64,7 @@ struct SetMethodOneNumber
/** Разместить дополнительные данные, если это необходимо, в случае, когда в хэш-таблицу был вставлен новый ключ. /** Разместить дополнительные данные, если это необходимо, в случае, когда в хэш-таблицу был вставлен новый ключ.
*/ */
static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, StringRefs & keys, Arena & pool) {} static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, Arena & pool) {}
}; };
/// Для случая, когда есть один строковый ключ. /// Для случая, когда есть один строковый ключ.
@ -94,8 +93,7 @@ struct SetMethodString
const ConstColumnPlainPtrs & key_columns, const ConstColumnPlainPtrs & key_columns,
size_t keys_size, size_t keys_size,
size_t i, size_t i,
const Sizes & key_sizes, const Sizes & key_sizes) const
StringRefs & keys) const
{ {
return StringRef( return StringRef(
&(*chars)[i == 0 ? 0 : (*offsets)[i - 1]], &(*chars)[i == 0 ? 0 : (*offsets)[i - 1]],
@ -103,7 +101,7 @@ struct SetMethodString
} }
}; };
static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, StringRefs & keys, Arena & pool) static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, Arena & pool)
{ {
value.data = pool.insert(value.data, value.size); value.data = pool.insert(value.data, value.size);
} }
@ -135,14 +133,13 @@ struct SetMethodFixedString
const ConstColumnPlainPtrs & key_columns, const ConstColumnPlainPtrs & key_columns,
size_t keys_size, size_t keys_size,
size_t i, size_t i,
const Sizes & key_sizes, const Sizes & key_sizes) const
StringRefs & keys) const
{ {
return StringRef(&(*chars)[i * n], n); return StringRef(&(*chars)[i * n], n);
} }
}; };
static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, StringRefs & keys, Arena & pool) static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, Arena & pool)
{ {
value.data = pool.insert(value.data, value.size); value.data = pool.insert(value.data, value.size);
} }
@ -167,14 +164,13 @@ struct SetMethodKeysFixed
const ConstColumnPlainPtrs & key_columns, const ConstColumnPlainPtrs & key_columns,
size_t keys_size, size_t keys_size,
size_t i, size_t i,
const Sizes & key_sizes, const Sizes & key_sizes) const
StringRefs & keys) const
{ {
return packFixed<Key>(i, keys_size, key_columns, key_sizes); return packFixed<Key>(i, keys_size, key_columns, key_sizes);
} }
}; };
static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, StringRefs & keys, Arena & pool) {} static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, Arena & pool) {}
}; };
/// Для остальных случаев. По 128 битному хэшу от ключа. (При этом, строки, содержащие нули посередине, могут склеиться.) /// Для остальных случаев. По 128 битному хэшу от ключа. (При этом, строки, содержащие нули посередине, могут склеиться.)
@ -196,14 +192,13 @@ struct SetMethodHashed
const ConstColumnPlainPtrs & key_columns, const ConstColumnPlainPtrs & key_columns,
size_t keys_size, size_t keys_size,
size_t i, size_t i,
const Sizes & key_sizes, const Sizes & key_sizes) const
StringRefs & keys) const
{ {
return hash128(i, keys_size, key_columns, keys); return hash128(i, keys_size, key_columns);
} }
}; };
static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, StringRefs & keys, Arena & pool) {} static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, Arena & pool) {}
}; };
@ -367,7 +362,6 @@ private:
Method & method, Method & method,
const ConstColumnPlainPtrs & key_columns, const ConstColumnPlainPtrs & key_columns,
size_t rows, size_t rows,
StringRefs & keys,
SetVariants & variants); SetVariants & variants);
template <typename Method> template <typename Method>
@ -376,8 +370,7 @@ private:
const ConstColumnPlainPtrs & key_columns, const ConstColumnPlainPtrs & key_columns,
ColumnUInt8::Container_t & vec_res, ColumnUInt8::Container_t & vec_res,
bool negative, bool negative,
size_t rows, size_t rows) const;
StringRefs & keys) const;
template <typename Method> template <typename Method>
void executeArrayImpl( void executeArrayImpl(
@ -386,8 +379,7 @@ private:
const ColumnArray::Offsets_t & offsets, const ColumnArray::Offsets_t & offsets,
ColumnUInt8::Container_t & vec_res, ColumnUInt8::Container_t & vec_res,
bool negative, bool negative,
size_t rows, size_t rows) const;
StringRefs & keys) const;
}; };
typedef Poco::SharedPtr<Set> SetPtr; typedef Poco::SharedPtr<Set> SetPtr;

View File

@ -140,7 +140,6 @@ void NO_INLINE Set::insertFromBlockImpl(
Method & method, Method & method,
const ConstColumnPlainPtrs & key_columns, const ConstColumnPlainPtrs & key_columns,
size_t rows, size_t rows,
StringRefs & keys,
SetVariants & variants) SetVariants & variants)
{ {
typename Method::State state; typename Method::State state;
@ -151,14 +150,14 @@ void NO_INLINE Set::insertFromBlockImpl(
for (size_t i = 0; i < rows; ++i) for (size_t i = 0; i < rows; ++i)
{ {
/// Строим ключ /// Строим ключ
typename Method::Key key = state.getKey(key_columns, keys_size, i, key_sizes, keys); typename Method::Key key = state.getKey(key_columns, keys_size, i, key_sizes);
typename Method::Data::iterator it = method.data.find(key); typename Method::Data::iterator it = method.data.find(key);
bool inserted; bool inserted;
method.data.emplace(key, it, inserted); method.data.emplace(key, it, inserted);
if (inserted) if (inserted)
method.onNewKey(*it, keys_size, i, keys, variants.string_pool); method.onNewKey(*it, keys_size, i, variants.string_pool);
} }
} }
@ -184,12 +183,10 @@ bool Set::insertFromBlock(const Block & block, bool create_ordered_set)
if (empty()) if (empty())
data.init(data.chooseMethod(key_columns, key_sizes)); data.init(data.chooseMethod(key_columns, key_sizes));
StringRefs keys;
if (false) {} if (false) {}
#define M(NAME) \ #define M(NAME) \
else if (data.type == SetVariants::Type::NAME) \ else if (data.type == SetVariants::Type::NAME) \
insertFromBlockImpl(*data.NAME, key_columns, rows, keys, data); insertFromBlockImpl(*data.NAME, key_columns, rows, data);
APPLY_FOR_SET_VARIANTS(M) APPLY_FOR_SET_VARIANTS(M)
#undef M #undef M
else else
@ -471,8 +468,7 @@ void NO_INLINE Set::executeImpl(
const ConstColumnPlainPtrs & key_columns, const ConstColumnPlainPtrs & key_columns,
ColumnUInt8::Container_t & vec_res, ColumnUInt8::Container_t & vec_res,
bool negative, bool negative,
size_t rows, size_t rows) const
StringRefs & keys) const
{ {
typename Method::State state; typename Method::State state;
state.init(key_columns); state.init(key_columns);
@ -484,7 +480,7 @@ void NO_INLINE Set::executeImpl(
for (size_t i = 0; i < rows; ++i) for (size_t i = 0; i < rows; ++i)
{ {
/// Строим ключ /// Строим ключ
typename Method::Key key = state.getKey(key_columns, keys_size, i, key_sizes, keys); typename Method::Key key = state.getKey(key_columns, keys_size, i, key_sizes);
vec_res[i] = negative ^ (method.data.end() != method.data.find(key)); vec_res[i] = negative ^ (method.data.end() != method.data.find(key));
} }
} }
@ -496,8 +492,7 @@ void NO_INLINE Set::executeArrayImpl(
const ColumnArray::Offsets_t & offsets, const ColumnArray::Offsets_t & offsets,
ColumnUInt8::Container_t & vec_res, ColumnUInt8::Container_t & vec_res,
bool negative, bool negative,
size_t rows, size_t rows) const
StringRefs & keys) const
{ {
typename Method::State state; typename Method::State state;
state.init(key_columns); state.init(key_columns);
@ -512,7 +507,7 @@ void NO_INLINE Set::executeArrayImpl(
for (size_t j = prev_offset; j < offsets[i]; ++j) for (size_t j = prev_offset; j < offsets[i]; ++j)
{ {
/// Строим ключ /// Строим ключ
typename Method::Key key = state.getKey(key_columns, keys_size, i, key_sizes, keys); typename Method::Key key = state.getKey(key_columns, keys_size, i, key_sizes);
res |= negative ^ (method.data.end() != method.data.find(key)); res |= negative ^ (method.data.end() != method.data.find(key));
if (res) if (res)
break; break;
@ -526,12 +521,11 @@ void NO_INLINE Set::executeArrayImpl(
void Set::executeOrdinary(const ConstColumnPlainPtrs & key_columns, ColumnUInt8::Container_t & vec_res, bool negative) const void Set::executeOrdinary(const ConstColumnPlainPtrs & key_columns, ColumnUInt8::Container_t & vec_res, bool negative) const
{ {
size_t rows = key_columns[0]->size(); size_t rows = key_columns[0]->size();
StringRefs keys;
if (false) {} if (false) {}
#define M(NAME) \ #define M(NAME) \
else if (data.type == SetVariants::Type::NAME) \ else if (data.type == SetVariants::Type::NAME) \
executeImpl(*data.NAME, key_columns, vec_res, negative, rows, keys); executeImpl(*data.NAME, key_columns, vec_res, negative, rows);
APPLY_FOR_SET_VARIANTS(M) APPLY_FOR_SET_VARIANTS(M)
#undef M #undef M
else else
@ -543,12 +537,11 @@ void Set::executeArray(const ColumnArray * key_column, ColumnUInt8::Container_t
size_t rows = key_column->size(); size_t rows = key_column->size();
const ColumnArray::Offsets_t & offsets = key_column->getOffsets(); const ColumnArray::Offsets_t & offsets = key_column->getOffsets();
const IColumn & nested_column = key_column->getData(); const IColumn & nested_column = key_column->getData();
StringRefs keys;
if (false) {} if (false) {}
#define M(NAME) \ #define M(NAME) \
else if (data.type == SetVariants::Type::NAME) \ else if (data.type == SetVariants::Type::NAME) \
executeArrayImpl(*data.NAME, ConstColumnPlainPtrs{key_column}, offsets, vec_res, negative, rows, keys); executeArrayImpl(*data.NAME, ConstColumnPlainPtrs{key_column}, offsets, vec_res, negative, rows);
APPLY_FOR_SET_VARIANTS(M) APPLY_FOR_SET_VARIANTS(M)
#undef M #undef M
else else