dbms: fixed error [#METR-12412].

This commit is contained in:
Alexey Milovidov 2014-08-20 08:57:03 +04:00
parent d76bfae57b
commit 0019c0ef57
9 changed files with 55 additions and 33 deletions

View File

@ -386,6 +386,10 @@ private:
throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
ColumnPtr res = cloneEmpty();
if (0 == col_size)
return res;
ColumnArray & res_ = typeid_cast<ColumnArray &>(*res);
const typename ColumnVector<T>::Container_t & cur_data = typeid_cast<const ColumnVector<T> &>(*data).getData();
@ -430,6 +434,10 @@ private:
throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
ColumnPtr res = cloneEmpty();
if (0 == col_size)
return res;
ColumnArray & res_ = typeid_cast<ColumnArray &>(*res);
const ColumnString & cur_string = typeid_cast<const ColumnString &>(*data);

View File

@ -87,7 +87,8 @@ public:
if (s != offsets.size())
throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
return new ColumnConst<T>(offsets.back(), data, data_type);
size_t replicated_size = 0 == s ? 0 : offsets.back();
return new ColumnConst<T>(replicated_size, data, data_type);
}
size_t byteSize() const { return sizeof(data) + sizeof(s); }

View File

@ -48,12 +48,12 @@ public:
{
return true;
}
size_t byteSize() const
{
return chars.size() + sizeof(n);
}
Field operator[](size_t index) const
{
return String(reinterpret_cast<const char *>(&chars[n * index]), n);
@ -75,7 +75,7 @@ public:
if (s.size() > n)
throw Exception("Too large string '" + s + "' for FixedString column", ErrorCodes::TOO_LARGE_STRING_SIZE);
size_t old_size = chars.size();
chars.resize_fill(old_size + n);
memcpy(&chars[old_size], s.data(), s.size());
@ -222,7 +222,10 @@ public:
ColumnFixedString * res_ = new ColumnFixedString(n);
ColumnPtr res = res_;
if (0 == col_size)
return res;
Chars_t & res_chars = res_->chars;
res_chars.reserve(n * offsets.back());

View File

@ -31,8 +31,8 @@ private:
/// Размер, включая завершающий нулевой байт.
size_t __attribute__((__always_inline__)) sizeAt(size_t i) const { return i == 0 ? offsets[0] : (offsets[i] - offsets[i - 1]); }
public:
public:
/** Создать пустой столбец строк */
ColumnString() {}
@ -78,7 +78,7 @@ public:
const String & s = DB::get<const String &>(x);
size_t old_size = chars.size();
size_t size_to_append = s.size() + 1;
chars.resize(old_size + size_to_append);
memcpy(&chars[old_size], s.c_str(), size_to_append);
offsets.push_back((offsets.size() == 0 ? 0 : offsets.back()) + size_to_append);
@ -90,7 +90,7 @@ public:
size_t old_size = chars.size();
size_t size_to_append = src.sizeAt(n);
size_t offset = src.offsetAt(n);
chars.resize(old_size + size_to_append);
memcpy(&chars[old_size], &src.chars[offset], size_to_append);
offsets.push_back((offsets.size() == 0 ? 0 : offsets.back()) + size_to_append);
@ -132,7 +132,7 @@ public:
res_->chars.resize(nested_length);
memcpy(&res_->chars[0], &chars[nested_offset], nested_length);
Offsets_t & res_offsets = res_->offsets;
if (start == 0)
@ -173,7 +173,7 @@ public:
{
if (!filt[i])
continue;
size_t string_offset = i == 0 ? 0 : offsets[i - 1];
size_t string_size = offsets[i] - string_offset;
@ -248,12 +248,12 @@ public:
reinterpret_cast<const char *>(&chars[offsetAt(n)]),
reinterpret_cast<const char *>(&rhs.chars[rhs.offsetAt(m)]));
}
/// Версия compareAt для locale-sensitive сравнения строк
int compareAtWithCollation(size_t n, size_t m, const IColumn & rhs_, const Collator & collator) const
{
const ColumnString & rhs = static_cast<const ColumnString &>(rhs_);
return collator.compare(
reinterpret_cast<const char *>(&chars[offsetAt(n)]), sizeAt(n),
reinterpret_cast<const char *>(&rhs.chars[rhs.offsetAt(m)]), rhs.sizeAt(m));
@ -305,9 +305,9 @@ public:
{
const ColumnString & parent;
const Collator & collator;
lessWithCollation(const ColumnString & parent_, const Collator & collator_) : parent(parent_), collator(collator_) {}
bool operator()(size_t lhs, size_t rhs) const
{
int res = collator.compare(
@ -354,6 +354,9 @@ public:
ColumnString * res_ = new ColumnString;
ColumnPtr res = res_;
if (0 == col_size)
return res;
Chars_t & res_chars = res_->chars;
Offsets_t & res_offsets = res_->offsets;
res_chars.reserve(chars.size() / col_size * replicate_offsets.back());

View File

@ -296,6 +296,9 @@ public:
if (size != offsets.size())
throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
if (0 == size)
return new Self;
Self * res_ = new Self;
ColumnPtr res = res_;
typename Self::Container_t & res_data = res_->getData();

View File

@ -6,7 +6,7 @@
namespace DB
{
/** Базовый класс для столбцов-констант, содержащих значение, не входящее в Field.
* Не является полноценым столбцом и используется особым образом.
*/
@ -14,16 +14,16 @@ class IColumnDummy : public IColumn
{
public:
IColumnDummy(size_t s_) : s(s_) {}
virtual ColumnPtr cloneDummy(size_t s_) const = 0;
ColumnPtr cloneResized(size_t s_) const { return cloneDummy(s_); }
bool isConst() const { return true; }
size_t size() const { return s; }
void insertDefault() { ++s; }
size_t byteSize() const { return 0; }
int compareAt(size_t n, size_t m, const IColumn & rhs_, int nan_direction_hint) const { return 0; }
Field operator[](size_t n) const { throw Exception("Cannot get value from " + getName(), ErrorCodes::NOT_IMPLEMENTED); }
void get(size_t n, Field & res) const { throw Exception("Cannot get value from " + getName(), ErrorCodes::NOT_IMPLEMENTED); };
void insert(const Field & x) { throw Exception("Cannot insert element into " + getName(), ErrorCodes::NOT_IMPLEMENTED); }
@ -39,42 +39,42 @@ public:
{
return cloneDummy(length);
}
ColumnPtr filter(const Filter & filt) const
{
size_t new_size = 0;
for (Filter::const_iterator it = filt.begin(); it != filt.end(); ++it)
if (*it)
++new_size;
return cloneDummy(new_size);
}
ColumnPtr permute(const Permutation & perm, size_t limit) const
{
if (s != perm.size())
throw Exception("Size of permutation doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
return cloneDummy(limit ? std::min(s, limit) : s);
}
void getPermutation(bool reverse, size_t limit, Permutation & res) const
{
res.resize(s);
for (size_t i = 0; i < s; ++i)
res[i] = i;
}
ColumnPtr replicate(const Offsets_t & offsets) const
{
if (s != offsets.size())
throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
return cloneDummy(offsets.back());
return cloneDummy(s == 0 ? 0 : offsets.back());
}
private:
size_t s;
};
}

View File

@ -375,7 +375,7 @@ public:
prev_offset = new_offset;
}
if (out_offsets.back() != out_vec.size())
if (!out_offsets.empty() && out_offsets.back() != out_vec.size())
throw Exception("Column size mismatch (internal logical error)", ErrorCodes::LOGICAL_ERROR);
return true;
@ -436,7 +436,7 @@ public:
prev_offset = new_offset;
}
if (out_offsets.back() != out_vec.size())
if (!out_offsets.empty() && out_offsets.back() != out_vec.size())
throw Exception("Column size mismatch (internal logical error)", ErrorCodes::LOGICAL_ERROR);
return true;
@ -742,7 +742,7 @@ public:
}
out_vec.resize(pos - begin);
if (out_offsets.back() != out_vec.size())
if (!out_offsets.empty() && out_offsets.back() != out_vec.size())
throw Exception("Column size mismatch (internal logical error)", ErrorCodes::LOGICAL_ERROR);
return true;
@ -797,7 +797,7 @@ public:
}
out_vec.resize(pos - begin);
if (out_offsets.back() != out_vec.size())
if (!out_offsets.empty() && out_offsets.back() != out_vec.size())
throw Exception("Column size mismatch (internal logical error)", ErrorCodes::LOGICAL_ERROR);
return true;

View File

@ -0,0 +1,2 @@
[] 1
[] 1

View File

@ -0,0 +1,2 @@
SELECT arrayFilter(x -> materialize(0), materialize([0])) AS p, arrayAll(y -> arrayExists(x -> y != x, p), p) AS test;
SELECT arrayFilter(x -> materialize(0), materialize([''])) AS p, arrayAll(y -> arrayExists(x -> y != x, p), p) AS test;