mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-19 16:20:50 +00:00
dbms: development.
This commit is contained in:
parent
308942f9b2
commit
b2db328d0a
@ -71,6 +71,21 @@ public:
|
||||
data->cut(nested_offset, nested_length);
|
||||
}
|
||||
|
||||
void insert(const Field & x)
|
||||
{
|
||||
Array & array = boost::get<Array &>(x);
|
||||
size_t size = array.size();
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
data->insert(array[i]);
|
||||
offsets.push_back((offsets.size() == 0 ? 0 : offsets.back()) + size);
|
||||
}
|
||||
|
||||
void insertDefault()
|
||||
{
|
||||
data->insertDefault();
|
||||
offsets.push_back(offsets.size() == 0 ? 1 : (offsets.back() + 1));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data->clear();
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <Poco/SharedPtr.h>
|
||||
|
||||
#include <DB/Core/Exception.h>
|
||||
#include <DB/Core/ErrorCodes.h>
|
||||
#include <DB/Columns/IColumn.h>
|
||||
|
||||
|
||||
@ -23,6 +25,11 @@ public:
|
||||
Field operator[](size_t n) const { return data; }
|
||||
void cut(size_t start, size_t length) { s = length; }
|
||||
void clear() { s = 0; }
|
||||
void insert(const Field & x)
|
||||
{
|
||||
throw Exception("Cannot insert element into constant column", ErrorCodes::CANNOT_INSERT_ELEMENT_INTO_CONSTANT_COLUMN);
|
||||
}
|
||||
void insertDefault() { ++s; }
|
||||
|
||||
/** Более эффективные методы манипуляции */
|
||||
T & getData() { return data; }
|
||||
|
@ -44,6 +44,23 @@ public:
|
||||
data->cut(n * start, n * length);
|
||||
}
|
||||
|
||||
void insert(const Field & x)
|
||||
{
|
||||
const Array & array = boost::get<Array &>(x);
|
||||
if (n != array.size())
|
||||
throw Exception("Size of array doesn't match size of FixedArray column",
|
||||
ErrorCodes::SIZE_OF_ARRAY_DOESNT_MATCH_SIZE_OF_FIXEDARRAY_COLUMN);
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
data->insert(array[i]);
|
||||
}
|
||||
|
||||
void insertDefault()
|
||||
{
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
data->insertDefault();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data.clear();
|
||||
|
@ -59,6 +59,25 @@ public:
|
||||
data->cut(start, length);
|
||||
}
|
||||
|
||||
void insert(const Field & x)
|
||||
{
|
||||
if (x == boost::none)
|
||||
{
|
||||
data->insertDefault();
|
||||
nulls.push_back(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->insert(x);
|
||||
nulls.push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
void insertDefault()
|
||||
{
|
||||
insert(Null());
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data.clear();
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef DBMS_CORE_COLUMN_STRING_H
|
||||
#define DBMS_CORE_COLUMN_STRING_H
|
||||
|
||||
#include <string.h> // memcpy
|
||||
|
||||
#include <DB/Columns/ColumnArray.h>
|
||||
#include <DB/Columns/ColumnsNumber.h>
|
||||
|
||||
@ -13,20 +15,40 @@ namespace DB
|
||||
*/
|
||||
class ColumnString : public ColumnArray
|
||||
{
|
||||
private:
|
||||
ColumnUInt8::Container_t & char_data;
|
||||
|
||||
public:
|
||||
/** Создать пустой столбец строк, с типом значений */
|
||||
ColumnString()
|
||||
: ColumnArray(new ColumnUInt8())
|
||||
: ColumnArray(new ColumnUInt8()),
|
||||
char_data(dynamic_cast<ColumnUInt8 &>(*data).getData())
|
||||
{
|
||||
}
|
||||
|
||||
Field operator[](size_t n) const
|
||||
{
|
||||
size_t offset = n == 0 ? 0 : offsets[n - 1];
|
||||
size_t size = offsets[n] - offset;
|
||||
size_t size = offsets[n] - offset - 1;
|
||||
const char * s = reinterpret_cast<const char *>(&dynamic_cast<const ColumnUInt8 &>(*data).getData()[offset]);
|
||||
return String(s, size);
|
||||
}
|
||||
|
||||
void insert(const Field & x)
|
||||
{
|
||||
String & s = boost::get<String &>(x);
|
||||
size_t old_size = char_data.size();
|
||||
size_t size_to_append = s.size() + 1;
|
||||
char_data.resize(old_size + size_to_append);
|
||||
memcpy(&char_data[old_size], s.c_str(), size_to_append);
|
||||
offsets.push_back((offsets.size() == 0 ? 0 : offsets.back()) + size_to_append);
|
||||
}
|
||||
|
||||
void insertDefault()
|
||||
{
|
||||
char_data.push_back(0);
|
||||
offsets.push_back(offsets.size() == 0 ? 1 : (offsets.back() + 1));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -62,6 +62,22 @@ public:
|
||||
data[i]->cut(start, length);
|
||||
}
|
||||
|
||||
void insert(const Field & x)
|
||||
{
|
||||
Array & arr = boost::get<Array &>(x);
|
||||
if (arr.size() != data.size())
|
||||
throw Exception("Sizes of columns in tuple doesn't match", ErrorCodes::SIZES_OF_COLUMNS_IN_TUPLE_DOESNT_MATCH);
|
||||
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
data[i]->insert(arr[i]);
|
||||
}
|
||||
|
||||
void insertDefault()
|
||||
{
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
data[i]->insertDefault();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data.clear();
|
||||
|
@ -50,6 +50,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void insert(const Field & x)
|
||||
{
|
||||
data.push_back(boost::get<typename NearestFieldType<T>::Type>(x));
|
||||
}
|
||||
|
||||
void insertDefault()
|
||||
{
|
||||
data.push_back(T());
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data.clear();
|
||||
|
@ -11,15 +11,30 @@ namespace DB
|
||||
class IColumn
|
||||
{
|
||||
public:
|
||||
/** Количество значений в столбце */
|
||||
/** Количество значений в столбце. */
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
/** Получить значение n-го элемента */
|
||||
/** Получить значение n-го элемента.
|
||||
* Используется для преобразования из блоков в строки (например, при выводе значений в текстовый дамп)
|
||||
*/
|
||||
virtual Field operator[](size_t n) const = 0;
|
||||
|
||||
/** Удалить всё кроме диапазона элементов */
|
||||
/** Удалить всё кроме диапазона элементов.
|
||||
* Используется, например, для операции LIMIT.
|
||||
*/
|
||||
virtual void cut(size_t start, size_t length) = 0;
|
||||
|
||||
/** Вставить значение в конец столбца (количество значений увеличится на 1).
|
||||
* Используется для преобразования из строк в блоки (например, при чтении значений из текстового дампа)
|
||||
*/
|
||||
virtual void insert(const Field & x) = 0;
|
||||
|
||||
/** Вставить значение "по умолчанию".
|
||||
* Используется, когда нужно увеличить размер столбца, но значение не имеет смысла.
|
||||
* Например, для ColumnNullable, если взведён флаг null, то соответствующее значение во вложенном столбце игнорируется.
|
||||
*/
|
||||
virtual void insertDefault() = 0;
|
||||
|
||||
/** Очистить */
|
||||
virtual void clear() = 0;
|
||||
|
||||
|
12
dbms/include/DB/Common/DateLUT.h
Normal file
12
dbms/include/DB/Common/DateLUT.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef DBMS_COMMON_DATE_LUT_H
|
||||
#define DBMS_COMMON_DATE_LUT_H
|
||||
|
||||
#include <Yandex/DateLUT.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
typedef Yandex::DateLUT DateLUT;
|
||||
typedef Yandex::DateLUTSingleton DateLUTSingleton;
|
||||
}
|
||||
|
||||
#endif
|
@ -25,6 +25,9 @@ namespace ErrorCodes
|
||||
EMPTY_TUPLE,
|
||||
DUPLICATE_COLUMN,
|
||||
NO_SUCH_COLUMN_IN_TABLE,
|
||||
DELIMITER_IN_STRING_LITERAL_DOESNT_MATCH,
|
||||
CANNOT_INSERT_ELEMENT_INTO_CONSTANT_COLUMN,
|
||||
SIZE_OF_ARRAY_DOESNT_MATCH_SIZE_OF_FIXEDARRAY_COLUMN,
|
||||
};
|
||||
}
|
||||
|
||||
|
74
dbms/include/DB/DataTypes/DataTypeDate.h
Normal file
74
dbms/include/DB/DataTypes/DataTypeDate.h
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef DBMS_DATA_TYPES_NUMBER_FIXED_H
|
||||
#define DBMS_DATA_TYPES_NUMBER_FIXED_H
|
||||
|
||||
#include <Poco/DateTimeParser.h>
|
||||
|
||||
#include <DB/Core/Exception.h>
|
||||
#include <DB/Core/ErrorCodes.h>
|
||||
#include <DB/Columns/ColumnsNumber.h>
|
||||
#include <DB/DataTypes/IDataTypeNumberFixed.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
class DataTypeDate : public IDataTypeNumberFixed<UInt16, ColumnUInt64>
|
||||
{
|
||||
private:
|
||||
DateLUTSingleton & date_lut;
|
||||
|
||||
public:
|
||||
DataTypeDate() : date_lut(DateLUTSingleton::instance()) {}
|
||||
|
||||
std::string getName() const { return "Date"; }
|
||||
|
||||
void serializeText(const Field & field, std::ostream & ostr) const
|
||||
{
|
||||
DateLUT::Values & values = date_lut.getValues(boost::get<UInt16>(field));
|
||||
ostr << values.year << '-' << values.month << '-' << values.day_of_month;
|
||||
}
|
||||
|
||||
void deserializeText(Field & field, std::istream & istr) const
|
||||
{
|
||||
std::string s;
|
||||
istr >> s;
|
||||
|
||||
int time_zone_diff = 0;
|
||||
field = date_lut.toDayNum(Poco::DateTimeParser::parse(
|
||||
s, time_zone_diff).timestamp().epochTime());
|
||||
}
|
||||
|
||||
void serializeTextEscaped(const Field & field, std::ostream & ostr) const
|
||||
{
|
||||
serializeText(field, ostr);
|
||||
}
|
||||
|
||||
void deserializeTextEscaped(Field & field, std::istream & istr) const
|
||||
{
|
||||
deserializeText(field, istr);
|
||||
}
|
||||
|
||||
void serializeTextQuoted(const Field & field, std::ostream & ostr, bool compatible = false) const
|
||||
{
|
||||
ostr << '\'';
|
||||
serializeText(field, ostr);
|
||||
ostr << '\'';
|
||||
}
|
||||
|
||||
void deserializeTextQuoted(Field & field, std::istream & istr, bool compatible = false) const
|
||||
{
|
||||
char delim = istr.peek();
|
||||
if (delim == '\'' || delim == '"')
|
||||
istr.ignore();
|
||||
|
||||
deserializeText(field, istr);
|
||||
|
||||
if (istr.get() != delim)
|
||||
throw Exception("Delimiter in string literal doesn't match",
|
||||
ErrorCodes::DELIMITER_IN_STRING_LITERAL_DOESNT_MATCH);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user