mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Merge pull request #831 from f1yegor/docs/translate-comments
translate comments: parsers
This commit is contained in:
commit
046c5aa0f4
@ -216,7 +216,7 @@ struct StdDevPopImpl
|
||||
|
||||
}
|
||||
|
||||
/** If `compute_marginal_moments` flag is set this class provides the heir
|
||||
/** If `compute_marginal_moments` flag is set this class provides the successor
|
||||
* CovarianceData support of marginal moments for calculating the correlation.
|
||||
*/
|
||||
template<bool compute_marginal_moments>
|
||||
|
@ -195,7 +195,7 @@ protected:
|
||||
QuotaForIntervals * quota = nullptr; /// If nullptr - the quota is not used.
|
||||
double prev_elapsed = 0;
|
||||
|
||||
/// The heirs must implement this function.
|
||||
/// The successors must implement this function.
|
||||
virtual Block readImpl() = 0;
|
||||
|
||||
/// Here you can do a preliminary initialization.
|
||||
|
@ -24,29 +24,29 @@ namespace ErrorCodes
|
||||
struct ExpressionAction;
|
||||
|
||||
|
||||
/** Интерфейс для обычных функций.
|
||||
* Обычные функции - это функции, которые не меняют количество строк в таблице,
|
||||
* и результат работы которых для каждой строчки не зависит от других строк.
|
||||
/** Interface for normal functions.
|
||||
* Normal functions are functions that do not change the number of rows in the table,
|
||||
* and the result of which for each row does not depend on other rows.
|
||||
*
|
||||
* Функция может принимать произвольное количество аргументов; возвращает ровно одно значение.
|
||||
* Тип результата зависит от типов и количества аргументов.
|
||||
* A function can take an arbitrary number of arguments; returns exactly one value.
|
||||
* The type of the result depends on the type and number of arguments.
|
||||
*
|
||||
* Функция диспетчеризуется для целого блока. Это позволяет производить всевозможные проверки редко,
|
||||
* и делать основную работу в виде эффективного цикла.
|
||||
* The function is dispatched for the whole block. This allows you to perform all kinds of checks rarely,
|
||||
* and do the main job as an efficient loop.
|
||||
*
|
||||
* Функция применяется к одному или нескольким столбцам блока, и записывает свой результат,
|
||||
* добавляя новый столбец к блоку. Функция не модифицирует свои агрументы.
|
||||
* The function is applied to one or more columns of the block, and writes its result,
|
||||
* adding a new column to the block. The function does not modify its arguments.
|
||||
*/
|
||||
class IFunction
|
||||
{
|
||||
public:
|
||||
/** Наследник IFunction должен реализовать:
|
||||
/** The successor of IFunction must implement:
|
||||
* - getName
|
||||
* - либо getReturnType, либо getReturnTypeAndPrerequisites
|
||||
* - одну из перегрузок execute.
|
||||
* - either getReturnType, or getReturnTypeAndPrerequisites
|
||||
* - one of the overloads of `execute`.
|
||||
*/
|
||||
|
||||
/// Получить основное имя функции.
|
||||
/// Get the main function name.
|
||||
virtual String getName() const = 0;
|
||||
|
||||
/// Override and return true if function could take different number of arguments.
|
||||
@ -97,8 +97,8 @@ public:
|
||||
*/
|
||||
virtual bool isDeterministicInScopeOfQuery() { return true; }
|
||||
|
||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||
/// Перегрузка для тех, кому не нужны prerequisites и значения константных аргументов. Снаружи не вызывается.
|
||||
/// Get the result type by argument type. If the function does not apply to these arguments, throw an exception.
|
||||
/// Overloading for those who do not need prerequisites and values of constant arguments. Not called from outside.
|
||||
DataTypePtr getReturnType(const DataTypes & arguments) const;
|
||||
|
||||
virtual DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const
|
||||
@ -106,11 +106,11 @@ public:
|
||||
throw Exception("getReturnType is not implemented for " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/** Получить тип результата по типам аргументов и значениям константных аргументов.
|
||||
* Если функция неприменима для данных аргументов - кинуть исключение.
|
||||
* Еще можно вернуть описание дополнительных столбцов, которые требуются для выполнения функции.
|
||||
* Для неконстантных столбцов arguments[i].column = nullptr.
|
||||
* Осмысленные типы элементов в out_prerequisites: APPLY_FUNCTION, ADD_COLUMN.
|
||||
/** Get the result type by argument types and constant argument values.
|
||||
* If the function does not apply to these arguments, throw an exception.
|
||||
* You can also return a description of the additional columns that are required to perform the function.
|
||||
* For non-constant columns `arguments[i].column = nullptr`.
|
||||
* Meaningful element types in out_prerequisites: APPLY_FUNCTION, ADD_COLUMN.
|
||||
*/
|
||||
void getReturnTypeAndPrerequisites(
|
||||
const ColumnsWithTypeAndName & arguments,
|
||||
@ -138,12 +138,12 @@ public:
|
||||
throw Exception("Function " + getName() + " can't have lambda-expressions as arguments", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
}
|
||||
|
||||
/// Выполнить функцию над блоком. Замечание: может вызываться одновременно из нескольких потоков, для одного объекта.
|
||||
/// Перегрузка для тех, кому не нужны prerequisites. Снаружи не вызывается.
|
||||
/// Execute the function on the block. Note: can be called simultaneously from several threads, for one object.
|
||||
/// Overloading for those who do not need `prerequisites`. Not called from outside.
|
||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result);
|
||||
|
||||
/// Выполнить функцию над блоком. Замечание: может вызываться одновременно из нескольких потоков, для одного объекта.
|
||||
/// prerequisites идут в том же порядке, что и out_prerequisites, полученные из getReturnTypeAndPrerequisites.
|
||||
/// Execute the function above the block. Note: can be called simultaneously from several threads, for one object.
|
||||
/// `prerequisites` go in the same order as `out_prerequisites` obtained from getReturnTypeAndPrerequisites.
|
||||
void execute(Block & block, const ColumnNumbers & arguments, const ColumnNumbers & prerequisites, size_t result);
|
||||
|
||||
virtual void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result)
|
||||
@ -160,25 +160,25 @@ public:
|
||||
/// that correspond to nullable columns and null columns.
|
||||
virtual bool hasSpecialSupportForNulls() const { return false; }
|
||||
|
||||
/** Позволяет узнать, является ли функция монотонной в некотором диапазоне значений.
|
||||
* Это используется для работы с индексом в сортированном куске данных.
|
||||
* И позволяет использовать индекс не только, когда написано, например date >= const, но и, например, toMonth(date) >= 11.
|
||||
* Всё это рассматривается только для функций одного аргумента.
|
||||
/** Lets you know if the function is monotonic in a range of values.
|
||||
* This is used to work with the index in a sorted chunk of data.
|
||||
* And allows to use the index not only when it is written, for example `date >= const`, but also, for example, `toMonth(date) >= 11`.
|
||||
* All this is considered only for functions of one argument.
|
||||
*/
|
||||
virtual bool hasInformationAboutMonotonicity() const { return false; }
|
||||
|
||||
/// Свойство монотонности на некотором диапазоне.
|
||||
/// The property of monotonicity for a certain range.
|
||||
struct Monotonicity
|
||||
{
|
||||
bool is_monotonic = false; /// Является ли функция монотонной (неубывающей или невозрастающей).
|
||||
bool is_positive = true; /// true, если функция неубывающая, false, если невозрастающая. Если is_monotonic = false, то не важно.
|
||||
bool is_monotonic = false; /// Is the function monotonous (nondecreasing or nonincreasing).
|
||||
bool is_positive = true; /// true if the function is nondecreasing, false, if notincreasing. If is_monotonic = false, then it does not matter.
|
||||
|
||||
Monotonicity(bool is_monotonic_ = false, bool is_positive_ = true)
|
||||
: is_monotonic(is_monotonic_), is_positive(is_positive_) {}
|
||||
};
|
||||
|
||||
/** Получить информацию о монотонности на отрезке значений. Вызывайте только если hasInformationAboutMonotonicity.
|
||||
* В качестве одного из аргументов может быть передан NULL. Это значит, что соответствующий диапазон неограничен слева или справа.
|
||||
/** Get information about monotonicity on a range of values. Call only if hasInformationAboutMonotonicity.
|
||||
* NULL can be passed as one of the arguments. This means that the corresponding range is unlimited on the left or on the right.
|
||||
*/
|
||||
virtual Monotonicity getMonotonicityForRange(const IDataType & type, const Field & left, const Field & right) const
|
||||
{
|
||||
|
@ -18,8 +18,8 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Позволяет получить тип результата применения функций +, -, *, /, %, div (целочисленное деление).
|
||||
* Правила отличаются от используемых в C++.
|
||||
/** Allows get the result type of the functions +, -, *, /, %, div (integer division).
|
||||
* The rules are different from those used in C++.
|
||||
*/
|
||||
|
||||
namespace NumberTraits
|
||||
@ -162,11 +162,11 @@ struct UpdateNullity
|
||||
>::Type;
|
||||
};
|
||||
|
||||
/** Результат сложения или умножения вычисляется по следующим правилам:
|
||||
* - если один из аргументов с плавающей запятой, то результат - с плавающей запятой, иначе - целый;
|
||||
* - если одно из аргументов со знаком, то результат - со знаком, иначе - без знака;
|
||||
* - результат содержит больше бит (не только значащих), чем максимум в аргументах
|
||||
* (например, UInt8 + Int32 = Int64).
|
||||
/** The result of addition or multiplication is calculated according to the following rules:
|
||||
* - if one of the arguments is floating-point, the result is a floating point, otherwise - the whole;
|
||||
* - if one of the arguments is signed, the result is signed, otherwise it is unsigned;
|
||||
* - the result contains more bits (not only meaningful) than the maximum in the arguments
|
||||
* (for example, UInt8 + Int32 = Int64).
|
||||
*/
|
||||
template <typename A, typename B> struct ResultOfAdditionMultiplication
|
||||
{
|
||||
@ -186,14 +186,14 @@ template <typename A, typename B> struct ResultOfSubtraction
|
||||
typename boost::mpl::or_<typename Traits<A>::Nullity, typename Traits<B>::Nullity>::type>::Type Type;
|
||||
};
|
||||
|
||||
/** При делении всегда получается число с плавающей запятой.
|
||||
/** When dividing, you always get a floating-point number.
|
||||
*/
|
||||
template <typename A, typename B> struct ResultOfFloatingPointDivision
|
||||
{
|
||||
using Type = Float64;
|
||||
};
|
||||
|
||||
/** При целочисленном делении получается число, битность которого равна делимому.
|
||||
/** For integer division, we get a number with the same number of bits as in divisible.
|
||||
*/
|
||||
template <typename A, typename B> struct ResultOfIntegerDivision
|
||||
{
|
||||
@ -204,7 +204,7 @@ template <typename A, typename B> struct ResultOfIntegerDivision
|
||||
typename boost::mpl::or_<typename Traits<A>::Nullity, typename Traits<B>::Nullity>::type>::Type Type;
|
||||
};
|
||||
|
||||
/** При взятии остатка получается число, битность которого равна делителю.
|
||||
/** Division with remainder you get a number with the same number of bits as in divisor.
|
||||
*/
|
||||
template <typename A, typename B> struct ResultOfModulo
|
||||
{
|
||||
@ -236,7 +236,7 @@ template <typename A> struct ResultOfAbs
|
||||
typename Traits<A>::Nullity>::Type Type;
|
||||
};
|
||||
|
||||
/** При побитовых операциях получается целое число, битность которого равна максимальной из битностей аргументов.
|
||||
/** For bitwise operations, an integer is obtained with number of bits is equal to the maximum of the arguments.
|
||||
*/
|
||||
template <typename A, typename B> struct ResultOfBit
|
||||
{
|
||||
@ -265,7 +265,7 @@ template <typename A> struct ResultOfBitNot
|
||||
};
|
||||
|
||||
|
||||
/** Приведение типов для функции if:
|
||||
/** Type casting for `if` function:
|
||||
* 1) void, Type -> Type
|
||||
* 2) UInt<x>, UInt<y> -> UInt<max(x,y)>
|
||||
* 3) Int<x>, Int<y> -> Int<max(x,y)>
|
||||
@ -294,7 +294,7 @@ struct ResultOfIf
|
||||
typename Construct<
|
||||
Signed,
|
||||
Floating,
|
||||
typename boost::mpl::max< /// Этот максимум нужен только потому что if_ всегда вычисляет все аргументы.
|
||||
typename boost::mpl::max< /// This maximum is needed only because `if_` always evaluates all arguments.
|
||||
typename boost::mpl::max<
|
||||
typename boost::mpl::if_<
|
||||
typename Traits<A>::Floatness,
|
||||
@ -334,7 +334,7 @@ struct ResultOfIf
|
||||
>::Type>::type>::type>::type>::type Type;
|
||||
};
|
||||
|
||||
/** Перед применением оператора % и побитовых операций, операнды приводятся к целым числам. */
|
||||
/** Before applying operator `%` and bitwise operations, operands are casted to whole numbers. */
|
||||
template <typename A> struct ToInteger
|
||||
{
|
||||
typedef typename Construct<
|
||||
|
@ -12,17 +12,17 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** Записывает данные асинхронно с помощью двойной буферизации.
|
||||
/** Writes data asynchronously using double buffering.
|
||||
*/
|
||||
class AsynchronousWriteBuffer : public WriteBuffer
|
||||
{
|
||||
private:
|
||||
WriteBuffer & out; /// Основной буфер, отвечает за запись данных.
|
||||
std::vector<char> memory; /// Кусок памяти для дублирования буфера.
|
||||
ThreadPool pool; /// Для асинхронной записи данных.
|
||||
bool started; /// Была ли запущена асинхронная запись данных.
|
||||
WriteBuffer & out; /// The main buffer, responsible for writing data.
|
||||
std::vector <char> memory; /// A piece of memory for duplicating the buffer.
|
||||
ThreadPool pool; /// For asynchronous data writing.
|
||||
bool started; /// Has an asynchronous data write started?
|
||||
|
||||
/// Менять местами основной и дублирующий буферы.
|
||||
/// Swap the main and duplicate buffers.
|
||||
void swapBuffers()
|
||||
{
|
||||
buffer().swap(out.buffer());
|
||||
@ -41,14 +41,14 @@ private:
|
||||
|
||||
swapBuffers();
|
||||
|
||||
/// Данные будут записываться в отельном потоке.
|
||||
/// The data will be written in separate stream.
|
||||
pool.schedule([this] { thread(); });
|
||||
}
|
||||
|
||||
public:
|
||||
AsynchronousWriteBuffer(WriteBuffer & out_) : WriteBuffer(nullptr, 0), out(out_), memory(out.buffer().size()), pool(1), started(false)
|
||||
{
|
||||
/// Данные пишутся в дублирующий буфер.
|
||||
/// Data is written to the duplicate buffer.
|
||||
set(memory.data(), memory.size());
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/// То, что выполняется в отдельном потоке
|
||||
/// That is executed in a separate thread
|
||||
void thread()
|
||||
{
|
||||
out.next();
|
||||
|
@ -8,30 +8,30 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** Базовый класс для ReadBuffer и WriteBuffer.
|
||||
* Содержит общие типы, переменные и функции.
|
||||
/** Base class for ReadBuffer and WriteBuffer.
|
||||
* Contains mutual types, variables, and functions.
|
||||
*
|
||||
* ReadBuffer и WriteBuffer похожи на istream и ostream, соответственно.
|
||||
* Их приходится использовать, так как с использованием iostream-ов невозможно эффективно реализовать некоторые операции.
|
||||
* Например, используя istream, невозможно быстро читать строковые значения из tab-separated файла,
|
||||
* чтобы после чтения, позиция осталась сразу после считанного значения.
|
||||
* (Единственный вариант - вызывать функцию std::istream::get() на каждый байт, но это тормозит из-за нескольких виртуальных вызовов.)
|
||||
* ReadBuffer and WriteBuffer are similar to istream and ostream, respectively.
|
||||
* They have to be used, because using iostreams it is impossible to effectively implement some operations.
|
||||
* For example, using istream, you can not quickly read string values from a tab-separated file,
|
||||
* so that after reading, the position remains immediately after the read value.
|
||||
* (The only option is to call the std::istream::get() function on each byte, but this slows down due to several virtual calls.)
|
||||
*
|
||||
* Read/WriteBuffer-ы предоставляют прямой доступ к внутреннему буферу, поэтому, необходимые операции реализуются эффективнее.
|
||||
* Используется только одна виртуальная функция nextImpl(), которая вызывается редко:
|
||||
* - в случае ReadBuffer - заполнить буфер новыми данными из источика;
|
||||
* - в случае WriteBuffer - записать данные из буфера в приёмник.
|
||||
* Read/WriteBuffers provide direct access to the internal buffer, so the necessary operations are implemented more efficiently.
|
||||
* Only one virtual function nextImpl() is used, which is rarely called:
|
||||
* - in the case of ReadBuffer - fill in the buffer with new data from the source;
|
||||
* - in the case of WriteBuffer - write data from the buffer into the receiver.
|
||||
*
|
||||
* Read/WriteBuffer-ы могут владеть или не владеть своим куском памяти.
|
||||
* Во втором случае, можно эффективно читать из уже существующего куска памяти / std::string, не копируя его.
|
||||
* Read/WriteBuffer can own or not own an own piece of memory.
|
||||
* In the second case, you can effectively read from an already existing piece of memory / std::string without copying it.
|
||||
*/
|
||||
class BufferBase
|
||||
{
|
||||
public:
|
||||
/** Курсор в буфере. Позиция записи или чтения. */
|
||||
/** Cursor in the buffer. The position of write or read. */
|
||||
using Position = char *;
|
||||
|
||||
/** Ссылка на диапазон памяти. */
|
||||
/** A reference to the range of memory. */
|
||||
struct Buffer
|
||||
{
|
||||
Buffer(Position begin_pos_, Position end_pos_) : begin_pos(begin_pos_), end_pos(end_pos_) {}
|
||||
@ -49,11 +49,11 @@ public:
|
||||
|
||||
private:
|
||||
Position begin_pos;
|
||||
Position end_pos; /// на 1 байт после конца буфера
|
||||
Position end_pos; /// 1 byte after the end of the buffer
|
||||
};
|
||||
|
||||
/** Конструктор принимает диапазон памяти, который следует использовать под буфер.
|
||||
* offset - начальное место курсора. ReadBuffer должен установить его в конец диапазона, а WriteBuffer - в начало.
|
||||
/** The constructor takes a range of memory to use for the buffer.
|
||||
* offset - the starting point of the cursor. ReadBuffer must set it to the end of the range, and WriteBuffer - to the beginning.
|
||||
*/
|
||||
BufferBase(Position ptr, size_t size, size_t offset)
|
||||
: internal_buffer(ptr, ptr + size), working_buffer(ptr, ptr + size), pos(ptr + offset) {}
|
||||
@ -65,19 +65,19 @@ public:
|
||||
pos = ptr + offset;
|
||||
}
|
||||
|
||||
/// получить буфер
|
||||
/// get buffer
|
||||
inline Buffer & internalBuffer() { return internal_buffer; }
|
||||
|
||||
/// получить часть буфера, из которого можно читать / в который можно писать данные
|
||||
/// get the part of the buffer from which you can read / write data
|
||||
inline Buffer & buffer() { return working_buffer; }
|
||||
|
||||
/// получить (для чтения и изменения) позицию в буфере
|
||||
/// get (for reading and modifying) the position in the buffer
|
||||
inline Position & position() { return pos; };
|
||||
|
||||
/// смещение в байтах курсора от начала буфера
|
||||
/// offset in bytes of the cursor from the beginning of the buffer
|
||||
inline size_t offset() const { return pos - working_buffer.begin(); }
|
||||
|
||||
/** Сколько байт было прочитано/записано, считая те, что ещё в буфере. */
|
||||
/** How many bytes have been read/written, counting those that are still in the buffer. */
|
||||
size_t count() const
|
||||
{
|
||||
return bytes + offset();
|
||||
@ -90,21 +90,21 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Ссылка на кусок памяти для буфера.
|
||||
/// A reference to a piece of memory for the buffer.
|
||||
Buffer internal_buffer;
|
||||
|
||||
/** Часть куска памяти, которую можно использовать.
|
||||
* Например, если internal_buffer - 1MB, а из файла для чтения было загружено в буфер
|
||||
* только 10 байт, то working_buffer будет иметь размер 10 байт
|
||||
* (working_buffer.end() будет указывать на позицию сразу после тех 10 байт, которых можно прочитать).
|
||||
/** A piece of memory that you can use.
|
||||
* For example, if internal_buffer is 1MB, and from a file for reading it was loaded into the buffer
|
||||
* only 10 bytes, then working_buffer will be 10 bytes in size
|
||||
* (working_buffer.end() will point to the position immediately after the 10 bytes that can be read).
|
||||
*/
|
||||
Buffer working_buffer;
|
||||
|
||||
/// Позиция чтения/записи.
|
||||
/// Read/write position.
|
||||
Position pos;
|
||||
|
||||
/** Сколько байт было прочитано/записано, не считая тех, что сейчас в буфере.
|
||||
* (считая те, что были уже использованы и "удалены" из буфера)
|
||||
/** How many bytes have been read/written, not counting those that are now in the buffer.
|
||||
* (counting those that were already used and "removed" from the buffer)
|
||||
*/
|
||||
size_t bytes = 0;
|
||||
};
|
||||
|
@ -12,11 +12,11 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** Буфер для чтения из сжатого файла с использованием кэша разжатых блоков.
|
||||
* Кэш внешний - передаётся в качестве аргумента в конструктор.
|
||||
* Позволяет увеличить производительность в случае, когда часто читаются одни и те же блоки.
|
||||
* Недостатки:
|
||||
* - в случае, если нужно читать много данных подряд, но из них только часть закэширована, приходится делать seek-и.
|
||||
/** A buffer for reading from a compressed file using the cache of decompressed blocks.
|
||||
* The external cache is passed as an argument to the constructor.
|
||||
* Allows you to increase performance in cases where the same blocks are often read.
|
||||
* Disadvantages:
|
||||
* - in case you need to read a lot of data in a row, but of them only a part is cached, you have to do seek-and.
|
||||
*/
|
||||
class CachedCompressedReadBuffer : public CompressedReadBufferBase, public ReadBuffer
|
||||
{
|
||||
@ -30,13 +30,13 @@ private:
|
||||
std::unique_ptr<ReadBufferFromFileBase> file_in;
|
||||
size_t file_pos;
|
||||
|
||||
/// Кусок данных из кэша, или кусок считанных данных, который мы положим в кэш.
|
||||
/// A piece of data from the cache, or a piece of read data that we put into the cache.
|
||||
UncompressedCache::MappedPtr owned_cell;
|
||||
|
||||
void initInput();
|
||||
bool nextImpl() override;
|
||||
|
||||
/// Передаётся в file_in.
|
||||
/// Passed into file_in.
|
||||
ReadBufferFromFileBase::ProfileCallback profile_callback;
|
||||
clockid_t clock_type;
|
||||
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
|
||||
size_t readBig(char * to, size_t n) override;
|
||||
|
||||
/// Сжатый размер текущего блока.
|
||||
/// The compressed size of the current block.
|
||||
size_t getSizeCompressed() const
|
||||
{
|
||||
return size_compressed;
|
||||
|
@ -11,16 +11,16 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/// В отличие от CompressedReadBuffer, умеет делать seek.
|
||||
/// Unlike CompressedReadBuffer, it can do seek.
|
||||
class CompressedReadBufferFromFile : public CompressedReadBufferBase, public BufferWithOwnMemory<ReadBuffer>
|
||||
{
|
||||
private:
|
||||
/** В любой момент выполняется одно из двух:
|
||||
` /** At any time, one of two things is true:
|
||||
* a) size_compressed = 0
|
||||
* b)
|
||||
* - working_buffer содержит целиком один блок.
|
||||
* - file_in смотрит в конец этого блока.
|
||||
* - size_compressed содержит сжатый размер этого блока.
|
||||
* - `working_buffer` contains the entire block.
|
||||
* - `file_in` points to the end of this block.
|
||||
* - `size_compressed` contains the compressed size of this block.
|
||||
*/
|
||||
std::unique_ptr<ReadBufferFromFileBase> p_file_in;
|
||||
ReadBufferFromFileBase & file_in;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/** Общие дефайны */
|
||||
/** Common Defines */
|
||||
|
||||
#define DBMS_MAX_COMPRESSED_SIZE 0x40000000ULL /// 1GB
|
||||
|
||||
@ -13,42 +13,42 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Метод сжатия */
|
||||
/** Compression method */
|
||||
enum class CompressionMethod
|
||||
{
|
||||
QuickLZ = 0,
|
||||
LZ4 = 1,
|
||||
LZ4HC = 2, /// Формат такой же, как у LZ4. Разница только при сжатии.
|
||||
ZSTD = 3, /// Экспериментальный алгоритм: https://github.com/Cyan4973/zstd
|
||||
LZ4HC = 2, /// The format is the same as for LZ4. The difference is only in compression.
|
||||
ZSTD = 3, /// Experimental algorithm: https://github.com/Cyan4973/zstd
|
||||
};
|
||||
|
||||
/** Формат сжатого блока следующий:
|
||||
/** The compressed block format is as follows:
|
||||
*
|
||||
* Первые 16 байт - чексумма от всех остальных байт блока. Сейчас используется только CityHash128.
|
||||
* В дальнейшем можно предусмотреть другие чексуммы, хотя сделать их другого размера не получится.
|
||||
* The first 16 bytes are the checksum from all other bytes of the block. Now only CityHash128 is used.
|
||||
* In the future, you can provide other checksums, although it will not be possible to make them different in size.
|
||||
*
|
||||
* Следующий байт определяет алгоритм сжатия. Далее всё зависит от алгоритма.
|
||||
* The next byte specifies the compression algorithm. Then everything depends on the algorithm.
|
||||
*
|
||||
* Первые 4 варианта совместимы с QuickLZ level 1.
|
||||
* То есть, если значение первого байта < 4, для разжатия достаточно использовать функцию qlz_level1_decompress.
|
||||
* The first 4 options are compatible with QuickLZ level 1.
|
||||
* That is, if the value of the first byte is < 4, it is enough to use qlz_level1_decompress function to decompress.
|
||||
*
|
||||
* 0x00 - несжатые данные, маленький блок. Далее один байт - размер сжатых данных, с учётом заголовка; один байт - размер несжатых данных.
|
||||
* 0x01 - сжатые данные, QuickLZ level 1, маленький блок. Далее два байта аналогично.
|
||||
* 0x02 - несжатые данные, большой блок. Далее 4 байта - размер сжатых данных, с учётом заголовка; 4 байта - размер несжатых данных.
|
||||
* 0x03 - сжатые данные, QuickLZ level 1, большой блок. Далее 8 байт аналогично.
|
||||
* 0x00 - uncompressed data, small block. Next, one byte - compressed data size, including header; one byte - uncompressed data size.
|
||||
* 0x01 - compressed data, QuickLZ level 1, small block. Then two bytes are similar.
|
||||
* 0x02 - uncompressed data, large block. Then 4 bytes - compressed data size, including header; 4 bytes uncompressed data size.
|
||||
* 0x03 - compressed data, QuickLZ level 1, large block. Then 8 bytes are similar.
|
||||
*
|
||||
* 0x82 - LZ4 или LZ4HC (они имеют одинаковый формат).
|
||||
* Далее 4 байта - размер сжатых данных, с учётом заголовка; 4 байта - размер несжатых данных.
|
||||
* 0x82 - LZ4 or LZ4HC (they have the same format).
|
||||
* Next 4 bytes - the size of the compressed data, taking into account the header; 4 bytes is the size of the uncompressed data.
|
||||
*
|
||||
* NOTE: Почему 0x82?
|
||||
* Изначально использовался только QuickLZ. Потом был добавлен LZ4.
|
||||
* Старший бит выставлен, чтобы отличить от QuickLZ, а второй бит выставлен для совместимости,
|
||||
* чтобы работали функции qlz_size_compressed, qlz_size_decompressed.
|
||||
* Хотя сейчас такая совместимость уже не актуальна.
|
||||
* NOTE: Why is 0x82?
|
||||
* Originally only QuickLZ was used. Then LZ4 was added.
|
||||
* The high bit is set to distinguish from QuickLZ, and the second bit is set for compatibility,
|
||||
* for the functions qlz_size_compressed, qlz_size_decompressed to work.
|
||||
* Although now such compatibility is no longer relevant.
|
||||
*
|
||||
* 0x90 - ZSTD
|
||||
*
|
||||
* Все размеры - little endian.
|
||||
* All sizes are little endian.
|
||||
*/
|
||||
|
||||
enum class CompressionMethodByte : uint8_t
|
||||
|
@ -29,7 +29,7 @@ private:
|
||||
#else
|
||||
/// ABI compatibility for USE_QUICKLZ
|
||||
void * fixed_size_padding = nullptr;
|
||||
/// Отменяет warning unused-private-field.
|
||||
/// Undoes warning unused-private-field.
|
||||
void * fixed_size_padding_used() const { return fixed_size_padding; }
|
||||
#endif
|
||||
|
||||
@ -41,20 +41,20 @@ public:
|
||||
CompressionMethod method_ = CompressionMethod::LZ4,
|
||||
size_t buf_size = DBMS_DEFAULT_BUFFER_SIZE);
|
||||
|
||||
/// Объём сжатых данных
|
||||
/// The amount of compressed data
|
||||
size_t getCompressedBytes()
|
||||
{
|
||||
nextIfAtEnd();
|
||||
return out.count();
|
||||
}
|
||||
|
||||
/// Сколько несжатых байт было записано в буфер
|
||||
/// How many uncompressed bytes were written to the buffer
|
||||
size_t getUncompressedBytes()
|
||||
{
|
||||
return count();
|
||||
}
|
||||
|
||||
/// Сколько байт находится в буфере (ещё не сжато)
|
||||
/// How many bytes are in the buffer (not yet compressed)
|
||||
size_t getRemainingBytes()
|
||||
{
|
||||
nextIfAtEnd();
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Читает из конкатенации нескольких ReadBuffer-ов
|
||||
/** Reads from the concatenation of multiple ReadBuffers
|
||||
*/
|
||||
class ConcatReadBuffer : public ReadBuffer
|
||||
{
|
||||
@ -24,7 +24,7 @@ protected:
|
||||
if (buffers.end() == current)
|
||||
return false;
|
||||
|
||||
/// Первое чтение
|
||||
/// First reading
|
||||
if (working_buffer.size() == 0 && (*current)->hasPendingData())
|
||||
{
|
||||
working_buffer = Buffer((*current)->position(), (*current)->buffer().end());
|
||||
@ -37,7 +37,7 @@ protected:
|
||||
if (buffers.end() == current)
|
||||
return false;
|
||||
|
||||
/// Пропускаем закончившиеся буферы; если буфер не закончился, но курсор на конце, то прочитаем следующую порцию данных.
|
||||
/// We skip the filled up buffers; if the buffer is not filled in, but the cursor is at the end, then read the next piece of data.
|
||||
while ((*current)->eof())
|
||||
{
|
||||
++current;
|
||||
|
@ -6,8 +6,8 @@
|
||||
namespace DB
|
||||
{
|
||||
/*
|
||||
* Считает хэш от прочитанных данных. При чтении данные читаются из вложенного ReadBuffer.
|
||||
* Мелкие кусочки копируются в собственную память.
|
||||
* Calculates the hash from the read data. When reading, the data is read from the nested ReadBuffer.
|
||||
* Small pieces are copied into its own memory.
|
||||
*/
|
||||
class HashingReadBuffer : public IHashingBuffer<ReadBuffer>
|
||||
{
|
||||
@ -18,7 +18,7 @@ public:
|
||||
working_buffer = in.buffer();
|
||||
pos = in.position();
|
||||
|
||||
/// считаем хэш от уже прочитанных данных
|
||||
/// calculate hash from the data already read
|
||||
if (working_buffer.size())
|
||||
{
|
||||
calculateHash(pos, working_buffer.end() - pos);
|
||||
|
@ -32,8 +32,8 @@ public:
|
||||
state = CityHash128WithSeed(data, block_size, state);
|
||||
}
|
||||
|
||||
/// вычисление хэша зависит от разбиения по блокам
|
||||
/// поэтому нужно вычислить хэш от n полных кусочков и одного неполного
|
||||
/// computation of the hash depends on the partitioning of blocks
|
||||
/// so you need to compute a hash of n complete pieces and one incomplete
|
||||
void calculateHash(DB::BufferBase::Position data, size_t len);
|
||||
|
||||
protected:
|
||||
@ -42,8 +42,8 @@ protected:
|
||||
uint128 state;
|
||||
};
|
||||
|
||||
/** Вычисляет хеш от записываемых данных и передает их в указанный WriteBuffer.
|
||||
* В качестве основного буфера используется буфер вложенного WriteBuffer.
|
||||
/** Computes the hash from the data to write and passes it to the specified WriteBuffer.
|
||||
* The buffer of the nested WriteBuffer is used as the main buffer.
|
||||
*/
|
||||
class HashingWriteBuffer : public IHashingBuffer<WriteBuffer>
|
||||
{
|
||||
@ -68,7 +68,7 @@ public:
|
||||
size_t block_size_ = DBMS_DEFAULT_HASHING_BLOCK_SIZE)
|
||||
: IHashingBuffer<DB::WriteBuffer>(block_size_), out(out_)
|
||||
{
|
||||
out.next(); /// Если до нас в out что-то уже писали, не дадим остаткам этих данных повлиять на хеш.
|
||||
out.next(); /// If something has already been written to `out` before us, we will not let the remains of this data affect the hash.
|
||||
working_buffer = out.buffer();
|
||||
pos = working_buffer.begin();
|
||||
state = uint128(0, 0);
|
||||
|
@ -4,14 +4,14 @@
|
||||
#include <IO/WriteBuffer.h>
|
||||
|
||||
|
||||
/// Так как HexWriteBuffer часто создаётся во внутреннем цикле, сделаем у него размер буфера маленьким.
|
||||
/// Since HexWriteBuffer is often created in the inner loop, we'll make its buffer size small.
|
||||
#define DBMS_HEX_WRITE_BUFFER_SIZE 32
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Всё что в него пишут, переводит в HEX (большими буквами) и пишет в другой WriteBuffer.
|
||||
/** Everything that is written into it, translates to HEX (in capital letters) and writes to another WriteBuffer.
|
||||
*/
|
||||
class HexWriteBuffer : public WriteBuffer
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ constexpr auto DEFAULT_REMOTE_WRITE_BUFFER_SEND_TIMEOUT = 1800;
|
||||
|
||||
}
|
||||
|
||||
/** Позволяет писать файл на удалённый сервер.
|
||||
/** Allows you to write a file to a remote server.
|
||||
*/
|
||||
class InterserverWriteBuffer final : public WriteBuffer
|
||||
{
|
||||
@ -44,10 +44,10 @@ private:
|
||||
std::string path;
|
||||
|
||||
Poco::Net::HTTPClientSession session;
|
||||
std::ostream * ostr; /// этим владеет session
|
||||
std::ostream * ostr; /// this is owned by session
|
||||
std::unique_ptr<WriteBuffer> impl;
|
||||
|
||||
/// Отправили все данные и переименовали файл
|
||||
/// Sent all the data and renamed the file
|
||||
bool finalized = false;
|
||||
};
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Позволяет считать из другого ReadBuffer не более указанного количества байт.
|
||||
/** Lets read from another ReadBuffer no more than the specified number of bytes.
|
||||
*/
|
||||
class LimitReadBuffer : public ReadBuffer
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ namespace mysqlxx
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// Вывести mysqlxx::Row в tab-separated виде
|
||||
/// Output mysqlxx::Row in tab-separated form
|
||||
inline void writeEscapedRow(const mysqlxx::Row & row, WriteBuffer & buf)
|
||||
{
|
||||
for (size_t i = 0; i < row.size(); ++i)
|
||||
|
@ -9,25 +9,25 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Реализует возможность записывать и считывать данные в WriteBuffer/ReadBuffer
|
||||
* с помощью операторов << и >> а также манипуляторов,
|
||||
* предоставляя способ использования, похожий на iostream-ы.
|
||||
/** Implements the ability to write and read data in/from WriteBuffer/ReadBuffer
|
||||
* with the help of << and >> operators and also manipulators,
|
||||
* providing a way of using, similar to iostreams.
|
||||
*
|
||||
* Не является ни подмножеством, ни расширением iostream-ов.
|
||||
* It is neither a subset nor an extension of iostreams.
|
||||
*
|
||||
* Пример использования:
|
||||
* Example usage:
|
||||
*
|
||||
* DB::WriteBufferFromFileDescriptor buf(STDOUT_FILENO);
|
||||
* buf << DB::double_quote << "Hello, world!" << '\n' << DB::flush;
|
||||
*
|
||||
* Выводит тип char (как правило, он же Int8) как символ, а не как число.
|
||||
* Outputs `char` type (usually it's Int8) as a symbol, not as a number.
|
||||
*/
|
||||
|
||||
/// Манипуляторы.
|
||||
enum EscapeManip { escape }; /// Для строк - экранировать спец-символы. В остальном, как обычно.
|
||||
enum QuoteManip { quote }; /// Для строк, дат, дат-с-временем - заключить в одинарные кавычки с экранированием. В остальном, как обычно.
|
||||
enum DoubleQuoteManip { double_quote }; /// Для строк, дат, дат-с-временем - заключить в двойные кавычки с экранированием. В остальном, как обычно.
|
||||
enum BinaryManip { binary }; /// Выводить в бинарном формате.
|
||||
/// Manipulators.
|
||||
enum EscapeManip { escape }; /// For strings - escape special characters. In the rest, as usual.
|
||||
enum QuoteManip { quote }; /// For strings, dates, datetimes - enclose in single quotes with escaping. In the rest, as usual.
|
||||
enum DoubleQuoteManip { double_quote }; /// For strings, dates, datetimes - enclose in double quotes with escaping. In the rest, as usual.
|
||||
enum BinaryManip { binary }; /// Output in binary format.
|
||||
|
||||
struct EscapeManipWriteBuffer : WriteBuffer {};
|
||||
struct QuoteManipWriteBuffer : WriteBuffer {};
|
||||
@ -41,7 +41,7 @@ struct BinaryManipReadBuffer : ReadBuffer {};
|
||||
|
||||
|
||||
template <typename T> WriteBuffer & operator<< (WriteBuffer & buf, const T & x) { writeText(x, buf); return buf; }
|
||||
/// Если не использовать манипуляторы, строка выводится без экранирования, как есть.
|
||||
/// If you do not use the manipulators, the string is displayed without an escape, as is.
|
||||
template <> inline WriteBuffer & operator<< (WriteBuffer & buf, const String & x) { writeString(x, buf); return buf; }
|
||||
template <> inline WriteBuffer & operator<< (WriteBuffer & buf, const char & x) { writeChar(x, buf); return buf; }
|
||||
|
||||
@ -62,7 +62,7 @@ inline WriteBuffer & operator<< (QuoteManipWriteBuffer & buf, const char *
|
||||
inline WriteBuffer & operator<< (DoubleQuoteManipWriteBuffer & buf, const char * x) { writeAnyQuotedString<'"'>(x, x + strlen(x), buf); return buf; }
|
||||
inline WriteBuffer & operator<< (BinaryManipWriteBuffer & buf, const char * x) { writeStringBinary(x, buf); return buf; }
|
||||
|
||||
/// Манипулятор вызывает у WriteBuffer метод next - это делает сброс буфера. Для вложенных буферов, сброс не рекурсивный.
|
||||
/// The manipulator calls the WriteBuffer method `next` - this makes the buffer reset. For nested buffers, the reset is not recursive.
|
||||
enum FlushManip { flush };
|
||||
|
||||
inline WriteBuffer & operator<< (WriteBuffer & buf, FlushManip x) { buf.next(); return buf; }
|
||||
@ -72,7 +72,7 @@ template <typename T> ReadBuffer & operator>> (ReadBuffer & buf, T & x)
|
||||
template <> inline ReadBuffer & operator>> (ReadBuffer & buf, String & x) { readString(x, buf); return buf; }
|
||||
template <> inline ReadBuffer & operator>> (ReadBuffer & buf, char & x) { readChar(x, buf); return buf; }
|
||||
|
||||
/// Если указать для чтения строковый литерал, то это будет обозначать - убедиться в наличии последовательности байт и пропустить её.
|
||||
/// If you specify a string literal for reading, this will mean - make sure there is a sequence of bytes and skip it.
|
||||
inline ReadBuffer & operator>> (ReadBuffer & buf, const char * x) { assertString(x, buf); return buf; }
|
||||
|
||||
inline EscapeManipReadBuffer & operator>> (ReadBuffer & buf, EscapeManip x) { return static_cast<EscapeManipReadBuffer &>(buf); }
|
||||
|
@ -17,34 +17,34 @@ namespace ErrorCodes
|
||||
extern const int CANNOT_READ_ALL_DATA;
|
||||
}
|
||||
|
||||
/** Простой абстрактный класс для буферизованного чтения данных (последовательности char) откуда-нибудь.
|
||||
* В отличие от std::istream, предоставляет доступ к внутреннему буферу,
|
||||
* а также позволяет вручную управлять позицией внутри буфера.
|
||||
/** A simple abstract class for buffered data reading (char sequences) from somewhere.
|
||||
* Unlike std::istream, it provides access to the internal buffer,
|
||||
* and also allows you to manually manage the position inside the buffer.
|
||||
*
|
||||
* Замечание! Используется char *, а не const char *
|
||||
* (для того, чтобы можно было вынести общий код в BufferBase, а также для того, чтобы можно было заполнять буфер новыми данными).
|
||||
* Это вызывает неудобства - например, при использовании ReadBuffer для чтения из куска памяти const char *,
|
||||
* приходится использовать const_cast.
|
||||
* Note! `char *`, not `const char *` is used
|
||||
* (so that you can take out the common code into BufferBase, and also so that you can fill the buffer in with new data).
|
||||
* This causes inconveniences - for example, when using ReadBuffer to read from a chunk of memory const char *,
|
||||
* you have to use const_cast.
|
||||
*
|
||||
* Наследники должны реализовать метод nextImpl().
|
||||
* successors must implement the nextImpl() method.
|
||||
*/
|
||||
class ReadBuffer : public BufferBase
|
||||
{
|
||||
public:
|
||||
/** Создаёт буфер и устанавливает кусок доступных данных для чтения нулевого размера,
|
||||
* чтобы при первой попытке чтения вызвалась функция next() для загрузки в буфер новой порции данных.
|
||||
/** Creates a buffer and sets a piece of available data to read to zero size,
|
||||
* so that the next() function is called to load the new data portion into the buffer at the first try.
|
||||
*/
|
||||
ReadBuffer(Position ptr, size_t size) : BufferBase(ptr, size, 0) { working_buffer.resize(0); }
|
||||
|
||||
/** Используется, если буфер уже заполнен данными, которые можно читать.
|
||||
* (в этом случае, передайте 0 в качестве offset)
|
||||
/** Used when the buffer is already full of data that can be read.
|
||||
* (in this case, pass 0 as an offset)
|
||||
*/
|
||||
ReadBuffer(Position ptr, size_t size, size_t offset) : BufferBase(ptr, size, offset) {}
|
||||
|
||||
void set(Position ptr, size_t size) { BufferBase::set(ptr, size, 0); working_buffer.resize(0); }
|
||||
|
||||
/** прочитать следующие данные и заполнить ими буфер; переместить позицию в начало;
|
||||
* вернуть false в случае конца, true иначе; кинуть исключение, если что-то не так
|
||||
/** read next data and fill a buffer with it; set position to the beginning;
|
||||
* return `false` in case of end, `true` otherwise; throw an exception, if something is wrong
|
||||
*/
|
||||
bool next()
|
||||
{
|
||||
@ -68,12 +68,12 @@ public:
|
||||
virtual ~ReadBuffer() {}
|
||||
|
||||
|
||||
/** В отличие от std::istream, возвращает true, если все данные были прочитаны
|
||||
* (а не в случае, если была попытка чтения после конца).
|
||||
* Если на данный момент позиция находится на конце буфера, то вызывает метод next().
|
||||
* То есть, имеет побочный эффект - если буфер закончился, то обновляет его и переносит позицию в начало.
|
||||
/** Unlike std::istream, it returns true if all data was read
|
||||
* (and not in case there was an attempt to read after the end).
|
||||
* If at the moment the position is at the end of the buffer, it calls the next() method.
|
||||
* That is, it has a side effect - if the buffer is over, then it updates it and set the position to the beginning.
|
||||
*
|
||||
* При попытке чтения после конца, следует кидать исключение.
|
||||
* Try to read after the end should throw an exception.
|
||||
*/
|
||||
bool ALWAYS_INLINE eof()
|
||||
{
|
||||
@ -101,7 +101,7 @@ public:
|
||||
throw Exception("Attempt to read after eof", ErrorCodes::ATTEMPT_TO_READ_AFTER_EOF);
|
||||
}
|
||||
|
||||
/// Можно было бы назвать этот метод ignore, а ignore назвать ignoreStrict.
|
||||
/// You could call this method `ignore`, and `ignore` call `ignoreStrict`.
|
||||
size_t tryIgnore(size_t n)
|
||||
{
|
||||
size_t bytes_ignored = 0;
|
||||
@ -116,7 +116,7 @@ public:
|
||||
return bytes_ignored;
|
||||
}
|
||||
|
||||
/** Читает столько, сколько есть, не больше n байт. */
|
||||
/** Reads as many as there are, no more than n bytes. */
|
||||
size_t read(char * to, size_t n)
|
||||
{
|
||||
size_t bytes_copied = 0;
|
||||
@ -132,18 +132,18 @@ public:
|
||||
return bytes_copied;
|
||||
}
|
||||
|
||||
/** Читает n байт, если есть меньше - кидает исключение. */
|
||||
/** Reads n bytes, if there are less - throws an exception. */
|
||||
void readStrict(char * to, size_t n)
|
||||
{
|
||||
if (n != read(to, n))
|
||||
throw Exception("Cannot read all data", ErrorCodes::CANNOT_READ_ALL_DATA);
|
||||
}
|
||||
|
||||
/** Метод, который может быть более эффективно реализован в наследниках, в случае чтения достаточно больших блоков.
|
||||
* Реализация может читать данные сразу в to, без лишнего копирования, если в to есть достаточно места для работы.
|
||||
* Например, CompressedReadBuffer может разжимать данные сразу в to, если весь разжатый блок туда помещается.
|
||||
* По-умолчанию - то же, что и read.
|
||||
* Для маленьких чтений использовать не нужно.
|
||||
/** A method that can be more efficiently implemented in successors, in the case of reading large enough blocks.
|
||||
* The implementation can read data directly into `to`, without superfluous copying, if in `to` there is enough space for work.
|
||||
* For example, a CompressedReadBuffer can decompress the data directly into `to`, if the entire decompressed block fits there.
|
||||
* By default - the same as read.
|
||||
* Don't use for small reads.
|
||||
*/
|
||||
virtual size_t readBig(char * to, size_t n)
|
||||
{
|
||||
@ -151,13 +151,13 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Количество игнорируемых байт с начальной позиции буфера working_buffer.
|
||||
/// The number of bytes to ignore from the initial position of `working_buffer` buffer.
|
||||
size_t working_buffer_offset = 0;
|
||||
|
||||
private:
|
||||
/** Прочитать следующие данные и заполнить ими буфер.
|
||||
* Вернуть false в случае конца, true иначе.
|
||||
* Кинуть исключение, если что-то не так.
|
||||
/** Read the next data and fill a buffer with it.
|
||||
* Return `false` in case of the end, `true` otherwise.
|
||||
* Throw an exception if something is wrong.
|
||||
*/
|
||||
virtual bool nextImpl() { return false; };
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ namespace CurrentMetrics
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Класс для асинхронного чтения данных.
|
||||
/** Class for asynchronous data reading.
|
||||
*/
|
||||
class ReadBufferAIO : public ReadBufferFromFileBase
|
||||
{
|
||||
@ -43,64 +43,64 @@ private:
|
||||
bool nextImpl() override;
|
||||
///
|
||||
off_t doSeek(off_t off, int whence) override;
|
||||
/// Синхронно читать данные.
|
||||
/// Synchronously read the data.
|
||||
void synchronousRead();
|
||||
/// Получить данные от асинхронного запроса.
|
||||
/// Get data from an asynchronous request.
|
||||
void receive();
|
||||
/// Игнорировать данные от асинхронного запроса.
|
||||
/// Ignore data from an asynchronous request.
|
||||
void skip();
|
||||
/// Ждать окончания текущей асинхронной задачи.
|
||||
/// Wait for the end of the current asynchronous task.
|
||||
bool waitForAIOCompletion();
|
||||
/// Подготовить запрос.
|
||||
/// Prepare the request.
|
||||
void prepare();
|
||||
/// Подготовить к чтению дублирующий буфер содержащий данные от
|
||||
/// последнего запроса.
|
||||
/// Prepare for reading a duplicate buffer containing data from
|
||||
/// of the last request.
|
||||
void finalize();
|
||||
|
||||
private:
|
||||
/// Буфер для асинхронных операций чтения данных.
|
||||
/// Buffer for asynchronous data read operations.
|
||||
BufferWithOwnMemory<ReadBuffer> fill_buffer;
|
||||
|
||||
/// Описание асинхронного запроса на чтение.
|
||||
/// Description of the asynchronous read request.
|
||||
iocb request{};
|
||||
std::future<ssize_t> future_bytes_read;
|
||||
|
||||
const std::string filename;
|
||||
|
||||
/// Максимальное количество байтов, которое можно прочитать.
|
||||
/// The maximum number of bytes that can be read.
|
||||
size_t max_bytes_read = std::numeric_limits<size_t>::max();
|
||||
/// Количество запрашиваемых байтов.
|
||||
/// Number of bytes requested.
|
||||
size_t requested_byte_count = 0;
|
||||
/// Количество прочитанных байт при последнем запросе.
|
||||
/// The number of bytes read at the last request.
|
||||
ssize_t bytes_read = 0;
|
||||
/// Итоговое количество прочитанных байтов.
|
||||
/// The total number of bytes read.
|
||||
size_t total_bytes_read = 0;
|
||||
|
||||
/// Позиция первого непрочитанного байта в файле.
|
||||
/// The position of the first unread byte in the file.
|
||||
off_t first_unread_pos_in_file = 0;
|
||||
|
||||
/// Начальная позиция выровненного региона диска, из которого читаются данные.
|
||||
/// The starting position of the aligned region of the disk from which the data is read.
|
||||
off_t region_aligned_begin = 0;
|
||||
/// Левое смещение для выравнения региона диска.
|
||||
/// Left offset to align the region of the disk.
|
||||
size_t region_left_padding = 0;
|
||||
/// Размер выровненного региона диска.
|
||||
/// The size of the aligned region of the disk.
|
||||
size_t region_aligned_size = 0;
|
||||
|
||||
/// Файловый дескриптор для чтения.
|
||||
/// The file descriptor for read.
|
||||
int fd = -1;
|
||||
|
||||
/// Буфер, в который пишутся полученные данные.
|
||||
/// The buffer to which the received data is written.
|
||||
Position buffer_begin = nullptr;
|
||||
|
||||
/// Асинхронная операция чтения ещё не завершилась.
|
||||
/// The asynchronous read operation is not yet completed.
|
||||
bool is_pending_read = false;
|
||||
/// Конец файла достигнут.
|
||||
/// The end of the file is reached.
|
||||
bool is_eof = false;
|
||||
/// Был отправлен хоть один запрос на чтение.
|
||||
/// At least one read request was sent.
|
||||
bool is_started = false;
|
||||
/// Является ли операция асинхронной?
|
||||
/// Is the operation asynchronous?
|
||||
bool is_aio = false;
|
||||
/// Асинхронная операция завершилась неудачно?
|
||||
/// Did the asynchronous operation fail?
|
||||
bool aio_failed = false;
|
||||
|
||||
CurrentMetrics::Increment metric_increment{CurrentMetrics::OpenFileForRead};
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
virtual std::string getFileName() const = 0;
|
||||
virtual int getFD() const = 0;
|
||||
|
||||
/// Есть возможность получать информацию о времени каждого чтения.
|
||||
/// It is possible to get information about the time of each reading.
|
||||
struct ProfileInfo
|
||||
{
|
||||
size_t bytes_requested;
|
||||
@ -34,7 +34,7 @@ public:
|
||||
|
||||
using ProfileCallback = std::function<void(ProfileInfo)>;
|
||||
|
||||
/// CLOCK_MONOTONIC_COARSE более чем достаточно для отслеживания долгих чтений - например, залипаний на секунды.
|
||||
/// CLOCK_MONOTONIC_COARSE is more than enough to track long reads - for example, hanging for a second.
|
||||
void setProfileCallback(const ProfileCallback & profile_callback_, clockid_t clock_type_ = CLOCK_MONOTONIC_COARSE)
|
||||
{
|
||||
profile_callback = profile_callback_;
|
||||
|
@ -9,16 +9,16 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Работает с готовым Poco::Net::Socket. Операции блокирующие.
|
||||
/** Works with the ready Poco::Net::Socket. Blocking operations.
|
||||
*/
|
||||
class ReadBufferFromPocoSocket : public BufferWithOwnMemory<ReadBuffer>
|
||||
{
|
||||
protected:
|
||||
Poco::Net::Socket & socket;
|
||||
|
||||
/** Для сообщений об ошибках. Нужно получать этот адрес заранее, так как,
|
||||
* например, если соединение разорвано, то адрес уже будет получить нельзя
|
||||
* (getpeername вернёт ошибку).
|
||||
/** For error messages. It is necessary to receive this address in advance, because,
|
||||
* for example, if the connection is broken, the address will not be received anymore
|
||||
* (getpeername will return an error).
|
||||
*/
|
||||
Poco::Net::SocketAddress peer_address;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Позволяет читать файл с удалённого сервера через riod.
|
||||
/** Allows you to read a file from a remote server via riod.
|
||||
*/
|
||||
class RemoteReadBuffer : public ReadBuffer
|
||||
{
|
||||
@ -51,7 +51,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Вернуть список имен файлов в директории.
|
||||
/// Return the list of file names in the directory.
|
||||
static std::vector<std::string> listFiles(
|
||||
const std::string & host,
|
||||
int port,
|
||||
|
@ -27,7 +27,7 @@ namespace ErrorCodes
|
||||
extern const int RECEIVED_ERROR_FROM_REMOTE_IO_SERVER;
|
||||
}
|
||||
|
||||
/** Позволяет писать файл на удалённый сервер.
|
||||
/** Allows you to write a file to a remote server.
|
||||
*/
|
||||
class RemoteWriteBuffer : public WriteBuffer
|
||||
{
|
||||
@ -45,15 +45,15 @@ private:
|
||||
std::string uri_str;
|
||||
|
||||
Poco::Net::HTTPClientSession session;
|
||||
std::ostream * ostr; /// этим владеет session
|
||||
std::ostream * ostr; /// this is owned by session
|
||||
std::unique_ptr<WriteBuffer> impl;
|
||||
|
||||
/// Отправили все данные и переименовали файл
|
||||
/// Have sent all the data and renamed the file
|
||||
bool finalized;
|
||||
public:
|
||||
/** Если tmp_path не пустой, то записывает сначала временный файл, а затем переименовывает,
|
||||
* удаляя существующие файлы, если есть.
|
||||
* Иначе используется параметр if_exists.
|
||||
/** If tmp_path is not empty, it writes first the temporary file, and then renames it,
|
||||
* deleting existing files, if any.
|
||||
* Otherwise, if_exists parameter is used.
|
||||
*/
|
||||
RemoteWriteBuffer(const std::string & host_, int port_, const std::string & path_,
|
||||
const std::string & tmp_path_ = "", const std::string & if_exists_ = "remove",
|
||||
@ -83,7 +83,7 @@ public:
|
||||
session.setPort(port);
|
||||
session.setKeepAlive(true);
|
||||
|
||||
/// устанавливаем таймаут
|
||||
/// set the timeout
|
||||
#if POCO_CLICKHOUSE_PATCH || POCO_VERSION >= 0x02000000
|
||||
session.setTimeout(connection_timeout, send_timeout, receive_timeout);
|
||||
#else
|
||||
@ -134,7 +134,7 @@ public:
|
||||
if (!offset() || finalized)
|
||||
return;
|
||||
|
||||
/// Для корректной работы с AsynchronousWriteBuffer, который подменяет буферы.
|
||||
/// For correct work with AsynchronousWriteBuffer, which replaces buffers.
|
||||
impl->set(buffer().begin(), buffer().size());
|
||||
|
||||
impl->position() = pos;
|
||||
@ -146,7 +146,7 @@ public:
|
||||
catch (const Exception & e)
|
||||
{
|
||||
if (e.code() == ErrorCodes::CANNOT_WRITE_TO_OSTREAM)
|
||||
checkStatus(); /// Меняем сообщение об ошибке на более ясное.
|
||||
checkStatus(); /// Change the error message to a clearer one.
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@ -159,7 +159,7 @@ public:
|
||||
next();
|
||||
checkStatus();
|
||||
|
||||
/// Переименовываем файл, если нужно.
|
||||
/// Rename the file if necessary.
|
||||
if (!tmp_path.empty())
|
||||
rename();
|
||||
|
||||
@ -246,7 +246,7 @@ private:
|
||||
}
|
||||
catch (const Exception & e)
|
||||
{
|
||||
/// Если в прошлую попытку от сервера не пришло ответа, но файл всё же был переименован.
|
||||
/// If in the last attempt we did not receive a response from the server, but the file was renamed already.
|
||||
if (i != 0 && e.code() == ErrorCodes::RECEIVED_ERROR_FROM_REMOTE_IO_SERVER
|
||||
&& nullptr != strstr(e.displayText().data(), "File not found"))
|
||||
{
|
||||
|
@ -10,26 +10,26 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** Записать UInt64 в формате переменной длины (base128) NOTE Only up to 2^63 - 1 are supported.*/
|
||||
/** Write UInt64 in variable length format (base128) NOTE Only up to 2^63 - 1 are supported. */
|
||||
void writeVarUInt(UInt64 x, std::ostream & ostr);
|
||||
void writeVarUInt(UInt64 x, WriteBuffer & ostr);
|
||||
char * writeVarUInt(UInt64 x, char * ostr);
|
||||
|
||||
|
||||
/** Прочитать UInt64, записанный в формате переменной длины (base128) */
|
||||
/** Read UInt64, written in variable length format (base128) */
|
||||
void readVarUInt(UInt64 & x, std::istream & istr);
|
||||
void readVarUInt(UInt64 & x, ReadBuffer & istr);
|
||||
const char * readVarUInt(UInt64 & x, const char * istr, size_t size);
|
||||
|
||||
|
||||
/** Получить длину UInt64 в формате VarUInt */
|
||||
/** Get the length of UInt64 in VarUInt format */
|
||||
size_t getLengthOfVarUInt(UInt64 x);
|
||||
|
||||
/** Получить длину Int64 в формате VarInt */
|
||||
/** Get the Int64 length in VarInt format */
|
||||
size_t getLengthOfVarInt(Int64 x);
|
||||
|
||||
|
||||
/** Записать Int64 в формате переменной длины (base128) */
|
||||
/** Write Int64 in variable length format (base128) */
|
||||
template <typename OUT>
|
||||
inline void writeVarInt(Int64 x, OUT & ostr)
|
||||
{
|
||||
@ -42,7 +42,7 @@ inline char * writeVarInt(Int64 x, char * ostr)
|
||||
}
|
||||
|
||||
|
||||
/** Прочитать Int64, записанный в формате переменной длины (base128) */
|
||||
/** Read Int64, written in variable length format (base128) */
|
||||
template <typename IN>
|
||||
inline void readVarInt(Int64 & x, IN & istr)
|
||||
{
|
||||
@ -73,7 +73,7 @@ inline const char * readVarT(UInt64 & x, const char * istr, size_t size) { retur
|
||||
inline const char * readVarT(Int64 & x, const char * istr, size_t size) { return readVarInt(x, istr, size); }
|
||||
|
||||
|
||||
/// Для [U]Int32, [U]Int16.
|
||||
/// For [U]Int32, [U]Int16.
|
||||
|
||||
inline void readVarUInt(UInt32 & x, ReadBuffer & istr)
|
||||
{
|
||||
|
@ -18,11 +18,11 @@ namespace ErrorCodes
|
||||
}
|
||||
|
||||
|
||||
/** Простой абстрактный класс для буферизованной записи данных (последовательности char) куда-нибудь.
|
||||
* В отличие от std::ostream, предоставляет доступ к внутреннему буферу,
|
||||
* а также позволяет вручную управлять позицией внутри буфера.
|
||||
/** A simple abstract class for buffered data writing (char sequences) somewhere.
|
||||
* Unlike std::ostream, it provides access to the internal buffer,
|
||||
* and also allows you to manually manage the position inside the buffer.
|
||||
*
|
||||
* Наследники должны реализовать метод nextImpl().
|
||||
* The successors must implement the nextImpl() method.
|
||||
*/
|
||||
class WriteBuffer : public BufferBase
|
||||
{
|
||||
@ -30,8 +30,8 @@ public:
|
||||
WriteBuffer(Position ptr, size_t size) : BufferBase(ptr, size, 0) {}
|
||||
void set(Position ptr, size_t size) { BufferBase::set(ptr, size, 0); }
|
||||
|
||||
/** записать данные, находящиеся в буфере (от начала буфера до текущей позиции);
|
||||
* переместить позицию в начало; кинуть исключение, если что-то не так
|
||||
/** write the data in the buffer (from the beginning of the buffer to the current position);
|
||||
* set the position to the beginning; throw an exception, if something is wrong
|
||||
*/
|
||||
inline void next()
|
||||
{
|
||||
@ -45,8 +45,8 @@ public:
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
/** Если вызов nextImpl() был неудачным, то переместим курсор в начало,
|
||||
* чтобы потом (например, при развёртке стека) не было второй попытки записать данные.
|
||||
/** If the nextImpl() call was unsuccessful, move the cursor to the beginning,
|
||||
* so that later (for example, when the stack was expanded) there was no second attempt to write data.
|
||||
*/
|
||||
pos = working_buffer.begin();
|
||||
throw;
|
||||
@ -55,8 +55,8 @@ public:
|
||||
pos = working_buffer.begin();
|
||||
}
|
||||
|
||||
/** желательно в наследниках поместить в деструктор вызов next(),
|
||||
* чтобы последние данные записались
|
||||
/** it is desirable in the successors to place the next() call in the destructor,
|
||||
* so that the last data is written
|
||||
*/
|
||||
virtual ~WriteBuffer() {}
|
||||
|
||||
@ -91,8 +91,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
/** Записать данные, находящиеся в буфере (от начала буфера до текущей позиции).
|
||||
* Кинуть исключение, если что-то не так.
|
||||
/** Write the data in the buffer (from the beginning of the buffer to the current position).
|
||||
* Throw an exception if something is wrong.
|
||||
*/
|
||||
virtual void nextImpl() { throw Exception("Cannot write after end of buffer.", ErrorCodes::CANNOT_WRITE_AFTER_END_OF_BUFFER); };
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ namespace CurrentMetrics
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Класс для асинхронной записи данных.
|
||||
/** Class for asynchronous data writing.
|
||||
*/
|
||||
class WriteBufferAIO : public WriteBufferFromFileBase
|
||||
{
|
||||
@ -42,20 +42,20 @@ private:
|
||||
off_t doSeek(off_t off, int whence) override;
|
||||
void doTruncate(off_t length) override;
|
||||
|
||||
/// Если в буфере ещё остались данные - запишем их.
|
||||
/// If there's still data in the buffer, we'll write them.
|
||||
void flush();
|
||||
/// Ждать окончания текущей асинхронной задачи.
|
||||
/// Wait for the end of the current asynchronous task.
|
||||
bool waitForAIOCompletion();
|
||||
/// Подготовить асинхронный запрос.
|
||||
/// Prepare an asynchronous request.
|
||||
void prepare();
|
||||
///
|
||||
void finalize();
|
||||
|
||||
private:
|
||||
/// Буфер для асинхронных операций записи данных.
|
||||
/// Buffer for asynchronous data writes.
|
||||
BufferWithOwnMemory<WriteBuffer> flush_buffer;
|
||||
|
||||
/// Описание асинхронного запроса на запись.
|
||||
/// Description of the asynchronous write request.
|
||||
iocb request = { 0 };
|
||||
std::vector<iocb *> request_ptrs{&request};
|
||||
std::vector<io_event> events{1};
|
||||
@ -64,33 +64,33 @@ private:
|
||||
|
||||
const std::string filename;
|
||||
|
||||
/// Количество байтов, которые будут записаны на диск.
|
||||
/// The number of bytes to be written to the disk.
|
||||
off_t bytes_to_write = 0;
|
||||
/// Количество записанных байт при последнем запросе.
|
||||
/// Number of bytes written with the last request.
|
||||
off_t bytes_written = 0;
|
||||
/// Количество нулевых байтов, которые надо отрезать c конца файла
|
||||
/// после завершения операции записи данных.
|
||||
/// The number of zero bytes to be cut from the end of the file
|
||||
/// after the data write operation completes.
|
||||
off_t truncation_count = 0;
|
||||
|
||||
/// Текущая позиция в файле.
|
||||
/// The current position in the file.
|
||||
off_t pos_in_file = 0;
|
||||
/// Максимальная достигнутая позиция в файле.
|
||||
/// The maximum position reached in the file.
|
||||
off_t max_pos_in_file = 0;
|
||||
|
||||
/// Начальная позиция выровненного региона диска, в который записываются данные.
|
||||
/// The starting position of the aligned region of the disk to which the data is written.
|
||||
off_t region_aligned_begin = 0;
|
||||
/// Размер выровненного региона диска.
|
||||
/// The size of the aligned region of the disk.
|
||||
size_t region_aligned_size = 0;
|
||||
|
||||
/// Файловый дескриптор для записи.
|
||||
/// The file descriptor for writing.
|
||||
int fd = -1;
|
||||
|
||||
/// Буфер данных, которые хотим записать на диск.
|
||||
/// The data buffer that we want to write to the disk.
|
||||
Position buffer_begin = nullptr;
|
||||
|
||||
/// Асинхронная операция записи ещё не завершилась?
|
||||
/// Is the asynchronous write operation still in progress?
|
||||
bool is_pending_write = false;
|
||||
/// Асинхронная операция завершилась неудачно?
|
||||
/// Did the asynchronous operation fail?
|
||||
bool aio_failed = false;
|
||||
|
||||
CurrentMetrics::Increment metric_increment{CurrentMetrics::OpenFileForWrite};
|
||||
|
@ -9,16 +9,16 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Работает с готовым Poco::Net::Socket. Операции блокирующие.
|
||||
/** Works with the ready Poco::Net::Socket. Blocking operations.
|
||||
*/
|
||||
class WriteBufferFromPocoSocket : public BufferWithOwnMemory<WriteBuffer>
|
||||
{
|
||||
protected:
|
||||
Poco::Net::Socket & socket;
|
||||
|
||||
/** Для сообщений об ошибках. Нужно получать этот адрес заранее, так как,
|
||||
* например, если соединение разорвано, то адрес уже будет получить нельзя
|
||||
* (getpeername вернёт ошибку).
|
||||
/** For error messages. It is necessary to receive this address in advance, because,
|
||||
* for example, if the connection is broken, the address will not be received anymore
|
||||
* (getpeername will return an error).
|
||||
*/
|
||||
Poco::Net::SocketAddress peer_address;
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Пишет данные в строку.
|
||||
* Замечение: перед использованием полученной строки, уничтожте этот объект.
|
||||
/** Writes the data to a string.
|
||||
* Note: before using the resulting string, destroy this object.
|
||||
*/
|
||||
class WriteBufferFromString : public WriteBuffer
|
||||
{
|
||||
|
@ -11,8 +11,8 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Инициализируется вектором. Пишет данные в него. Когда вектор закончится - увеличивает его размер в два раза.
|
||||
* CharType - char или unsigned char.
|
||||
/** Initialized by vector. Writes data to it. When the vector is finished, it doubles its size.
|
||||
* CharType - char or unsigned char.
|
||||
*/
|
||||
template <typename VectorType = std::vector<char> >
|
||||
class WriteBufferFromVector : public WriteBuffer
|
||||
|
@ -7,16 +7,16 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Пишет данные в другой буфер, заменяя невалидные UTF-8 последовательности на указанную последовательность.
|
||||
* Если записывается уже валидный UTF-8, работает быстрее.
|
||||
* Замечение: перед использованием полученной строки, уничтожте этот объект.
|
||||
/** Writes the data to another buffer, replacing the invalid UTF-8 sequences with the specified sequence.
|
||||
* If the valid UTF-8 is already written, it works faster.
|
||||
* Note: before using the resulting string, destroy this object.
|
||||
*/
|
||||
class WriteBufferValidUTF8 : public BufferWithOwnMemory<WriteBuffer>
|
||||
{
|
||||
private:
|
||||
WriteBuffer & output_buffer;
|
||||
bool group_replacements;
|
||||
/// Последний записанный символ был replacement.
|
||||
/// The last recorded character was `replacement`.
|
||||
bool just_put_replacement = false;
|
||||
std::string replacement;
|
||||
|
||||
|
@ -139,19 +139,19 @@ inline void writeString(const StringRef & ref, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
/** Пишет С-строку без создания временного объекта. Если строка - литерал, то strlen выполняется на этапе компиляции.
|
||||
* Используйте, когда строка - литерал.
|
||||
/** Writes a C-string without creating a temporary object. If the string is a literal, then `strlen` is executed at the compilation stage.
|
||||
* Use when the string is a literal.
|
||||
*/
|
||||
#define writeCString(s, buf) \
|
||||
(buf).write((s), strlen(s))
|
||||
|
||||
/** Пишет строку для использования в формате JSON:
|
||||
* - строка выводится в двойных кавычках
|
||||
* - эскейпится символ прямого слеша '/'
|
||||
* - байты из диапазона 0x00-0x1F кроме '\b', '\f', '\n', '\r', '\t' эскейпятся как \u00XX
|
||||
* - кодовые точки U+2028 и U+2029 (последовательности байт в UTF-8: e2 80 a8, e2 80 a9) эскейпятся как \u2028 и \u2029
|
||||
* - предполагается, что строка в кодировке UTF-8, невалидный UTF-8 не обрабатывается
|
||||
* - не-ASCII символы остаются как есть
|
||||
/** Writes a string for use in the JSON format:
|
||||
* - the string is outputted in double quotes
|
||||
* - forward slash character '/' is escaped
|
||||
* - bytes from the range 0x00-0x1F except `\b', '\f', '\n', '\r', '\t' are escaped as \u00XX
|
||||
* - code points U+2028 and U+2029 (byte sequences in UTF-8: e2 80 a8, e2 80 a9) are escaped as \u2028 and \u2029
|
||||
* - it is assumed that string is the UTF-8 encoded, the invalid UTF-8 is not processed
|
||||
* - non-ASCII characters remain as is
|
||||
*/
|
||||
inline void writeJSONString(const char * begin, const char * end, WriteBuffer & buf)
|
||||
{
|
||||
@ -227,7 +227,7 @@ void writeAnyEscapedString(const char * begin, const char * end, WriteBuffer & b
|
||||
const char * pos = begin;
|
||||
while (true)
|
||||
{
|
||||
/// Специально будем эскейпить больше символов, чем минимально необходимо.
|
||||
/// On purpose we will escape more characters than minimally necessary.
|
||||
const char * next_pos = find_first_symbols<'\b', '\f', '\n', '\r', '\t', '\0', '\\', c>(pos, end);
|
||||
|
||||
if (next_pos == end)
|
||||
@ -359,13 +359,13 @@ inline void writeDoubleQuotedString(const String & s, WriteBuffer & buf)
|
||||
writeAnyQuotedString<'"'>(s, buf);
|
||||
}
|
||||
|
||||
/// Выводит строку в обратных кавычках, как идентификатор в MySQL.
|
||||
/// Outputs a string in backquotes, as an identifier in MySQL.
|
||||
inline void writeBackQuotedString(const String & s, WriteBuffer & buf)
|
||||
{
|
||||
writeAnyQuotedString<'`'>(s, buf);
|
||||
}
|
||||
|
||||
/// То же самое, но обратные кавычки применяются только при наличии символов, не подходящих для идентификатора без обратных кавычек.
|
||||
/// The same, but backquotes apply only if there are characters that do not match the identifier without backquotes.
|
||||
inline void writeProbablyBackQuotedString(const String & s, WriteBuffer & buf)
|
||||
{
|
||||
if (s.empty() || !isValidIdentifierBegin(s[0]))
|
||||
@ -385,10 +385,10 @@ inline void writeProbablyBackQuotedString(const String & s, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
/** Выводит строку в для формата CSV.
|
||||
* Правила:
|
||||
* - строка выводится в кавычках;
|
||||
* - кавычка внутри строки выводится как две кавычки подряд.
|
||||
/** Outputs the string in for the CSV format.
|
||||
* Rules:
|
||||
* - the string is outputted in quotation marks;
|
||||
* - the quotation mark inside the string is outputted as two quotation marks in sequence.
|
||||
*/
|
||||
template <char quote = '"'>
|
||||
void writeCSVString(const char * begin, const char * end, WriteBuffer & buf)
|
||||
@ -405,7 +405,7 @@ void writeCSVString(const char * begin, const char * end, WriteBuffer & buf)
|
||||
buf.write(pos, end - pos);
|
||||
break;
|
||||
}
|
||||
else /// Кавычка.
|
||||
else /// Quotation.
|
||||
{
|
||||
++next_pos;
|
||||
buf.write(pos, next_pos - pos);
|
||||
@ -431,13 +431,13 @@ void writeCSVString(const StringRef & s, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
/// Запись строки в текстовый узел в XML (не в атрибут - иначе нужно больше эскейпинга).
|
||||
/// Writing a string to a text node in XML (not into an attribute - otherwise you need more escaping).
|
||||
inline void writeXMLString(const char * begin, const char * end, WriteBuffer & buf)
|
||||
{
|
||||
const char * pos = begin;
|
||||
while (true)
|
||||
{
|
||||
/// NOTE Возможно, для некоторых парсеров XML нужно ещё эскейпить нулевой байт и некоторые control characters.
|
||||
/// NOTE Perhaps for some XML parsers, you need to escape the zero byte and some control characters.
|
||||
const char * next_pos = find_first_symbols<'<', '&'>(pos, end);
|
||||
|
||||
if (next_pos == end)
|
||||
@ -473,7 +473,7 @@ inline void writeXMLString(const StringRef & s, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
/// в формате YYYY-MM-DD
|
||||
/// in YYYY-MM-DD format
|
||||
inline void writeDateText(DayNum_t date, WriteBuffer & buf)
|
||||
{
|
||||
char s[10] = {'0', '0', '0', '0', '-', '0', '0', '-', '0', '0'};
|
||||
@ -515,7 +515,7 @@ inline void writeDateText(LocalDate date, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
/// в формате YYYY-MM-DD HH:MM:SS, согласно текущему часовому поясу
|
||||
/// in the format YYYY-MM-DD HH:MM:SS, according to the current time zone
|
||||
template <char date_delimeter = '-', char time_delimeter = ':'>
|
||||
inline void writeDateTimeText(time_t datetime, WriteBuffer & buf, const DateLUTImpl & date_lut = DateLUT::instance())
|
||||
{
|
||||
@ -577,7 +577,7 @@ inline void writeDateTimeText(LocalDateTime datetime, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
/// Методы вывода в бинарном виде
|
||||
/// Methods of output in binary form
|
||||
template <typename T>
|
||||
inline typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
writeBinary(const T & x, WriteBuffer & buf) { writePODBinary(x, buf); }
|
||||
@ -589,7 +589,7 @@ inline void writeBinary(const LocalDate & x, WriteBuffer & buf) { writePO
|
||||
inline void writeBinary(const LocalDateTime & x, WriteBuffer & buf) { writePODBinary(x, buf); }
|
||||
|
||||
|
||||
/// Методы для вывода значения в текстовом виде для tab-separated формата.
|
||||
/// Methods for outputting the value in text form for a tab-separated format.
|
||||
template <typename T>
|
||||
inline typename std::enable_if<std::is_integral<T>::value, void>::type
|
||||
writeText(const T & x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
@ -603,15 +603,15 @@ inline void writeText(const String & x, WriteBuffer & buf) { writeEscaped
|
||||
/// Implemented as template specialization (not function overload) to avoid preference over templates on arithmetic types above.
|
||||
template <> inline void writeText<bool>(const bool & x, WriteBuffer & buf) { writeBoolText(x, buf); }
|
||||
|
||||
/// в отличие от метода для std::string
|
||||
/// здесь предполагается, что x null-terminated строка.
|
||||
/// unlike the method for std::string
|
||||
/// assumes here that `x` is a null-terminated string.
|
||||
inline void writeText(const char * x, WriteBuffer & buf) { writeEscapedString(x, strlen(x), buf); }
|
||||
inline void writeText(const char * x, size_t size, WriteBuffer & buf) { writeEscapedString(x, size, buf); }
|
||||
|
||||
inline void writeText(const LocalDate & x, WriteBuffer & buf) { writeDateText(x, buf); }
|
||||
inline void writeText(const LocalDateTime & x, WriteBuffer & buf) { writeDateTimeText(x, buf); }
|
||||
|
||||
/// Строки, даты, даты-с-временем - в одинарных кавычках с C-style эскейпингом. Числа - без.
|
||||
/// String, date, datetime are in single quotes with C-style escaping. Numbers - without.
|
||||
template <typename T>
|
||||
inline typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
writeQuoted(const T & x, WriteBuffer & buf) { writeText(x, buf); }
|
||||
@ -633,7 +633,7 @@ inline void writeQuoted(const LocalDateTime & x, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
/// Строки, даты, даты-с-временем - в двойных кавычках с C-style эскейпингом. Числа - без.
|
||||
/// String, date, datetime are in double quotes with C-style escaping. Numbers - without.
|
||||
template <typename T>
|
||||
inline typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
writeDoubleQuoted(const T & x, WriteBuffer & buf) { writeText(x, buf); }
|
||||
@ -655,7 +655,7 @@ inline void writeDoubleQuoted(const LocalDateTime & x, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
/// Строки - в двойных кавычках и с CSV-эскейпингом; даты, даты-с-временем - в двойных кавычках. Числа - без.
|
||||
/// String - in double quotes and with CSV-escaping; date, datetime - in double quotes. Numbers - without.
|
||||
template <typename T>
|
||||
inline typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
writeCSV(const T & x, WriteBuffer & buf) { writeText(x, buf); }
|
||||
@ -708,11 +708,11 @@ void writeText(const std::vector<T> & x, WriteBuffer & buf)
|
||||
|
||||
|
||||
|
||||
/// Сериализация эксепшена (чтобы его можно было передать по сети)
|
||||
/// Serialize exception (so that it can be transferred over the network)
|
||||
void writeException(const Exception & e, WriteBuffer & buf);
|
||||
|
||||
|
||||
/// Простой для использования метод преобразования чего-либо в строку в текстовом виде.
|
||||
/// An easy-to-use method for converting something to a string in text form.
|
||||
template <typename T>
|
||||
inline String toString(const T & x)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <Core/Types.h>
|
||||
#include <IO/WriteBuffer.h>
|
||||
|
||||
/// 20 цифр или 19 цифр и знак
|
||||
/// 20 digits or 19 digits and a sign
|
||||
#define WRITE_HELPERS_MAX_INT_WIDTH 20U
|
||||
|
||||
|
||||
@ -17,14 +17,14 @@ namespace DB
|
||||
|
||||
namespace detail
|
||||
{
|
||||
/** Смотрите:
|
||||
/** See:
|
||||
* https://github.com/localvoid/cxx-benchmark-itoa
|
||||
* http://www.slideshare.net/andreialexandrescu1/three-optimization-tips-for-c-15708507
|
||||
* http://vimeo.com/55639112
|
||||
*/
|
||||
|
||||
|
||||
/// Обычный способ, если в буфере не хватает места, чтобы там поместилось любое число.
|
||||
/// The usual way, if there is not enough space in the buffer for any number to fit there.
|
||||
template <typename T>
|
||||
void writeUIntTextFallback(T x, WriteBuffer & buf)
|
||||
{
|
||||
@ -52,9 +52,9 @@ namespace detail
|
||||
}
|
||||
|
||||
|
||||
/** Подсчёт количества десятичных цифр в числе.
|
||||
* Хорошо работает для неравномерного распределения чисел, которое обычно бывает.
|
||||
* Если большинство чисел длинные, то лучше работал бы branchless код с инструкцией bsr и хитрым преобразованием.
|
||||
/** Count the number of decimal digits in the number.
|
||||
* Works well for nonuniform distribution of numbers, which usually happens.
|
||||
* If most of the numbers are long, then a "branchless" code with a `bsr` instruction and a smart conversion would work better.
|
||||
*/
|
||||
template <typename T>
|
||||
UInt32 digits10(T x)
|
||||
@ -91,10 +91,10 @@ namespace detail
|
||||
}
|
||||
|
||||
|
||||
/** Преобразует по две цифры за итерацию.
|
||||
* Хорошо работает для неравномерного распределения чисел, которое обычно бывает.
|
||||
* Если большинство чисел длинные, и если не жалко кэш, то лучше работал бы вариант
|
||||
* с большой таблицей и четырьмя цифрами за итерацию.
|
||||
/** Converts two digits per iteration.
|
||||
* Works well for the nonuniform distribution of numbers, which usually happens.
|
||||
* If most of the numbers are long, and if you do care about the cache, then the variant
|
||||
* with a large table and four digits per iteration.
|
||||
*/
|
||||
template <typename T>
|
||||
UInt32 writeUIntText(T x, char * dst)
|
||||
@ -138,7 +138,7 @@ namespace detail
|
||||
}
|
||||
|
||||
|
||||
/** Если в буфере есть достаточно места - вызывает оптимизированный вариант, иначе - обычный вариант.
|
||||
/** If there is enough space in the buffer - calls an optimized version, otherwise - the normal version.
|
||||
*/
|
||||
template <typename T>
|
||||
void writeUIntText(T x, WriteBuffer & buf)
|
||||
@ -150,12 +150,12 @@ namespace detail
|
||||
}
|
||||
|
||||
|
||||
/** Обёртка для знаковых чисел.
|
||||
/** Wrapper for signed numbers.
|
||||
*/
|
||||
template <typename T>
|
||||
void writeSIntText(T x, WriteBuffer & buf)
|
||||
{
|
||||
/// Особый случай для самого маленького отрицательного числа
|
||||
/// A special case for the smallest negative number
|
||||
if (unlikely(x == std::numeric_limits<T>::min()))
|
||||
{
|
||||
if (sizeof(x) == 1)
|
||||
|
@ -11,15 +11,15 @@ class ReadBuffer;
|
||||
class WriteBuffer;
|
||||
|
||||
|
||||
/** Копирует данные из ReadBuffer в WriteBuffer, все что есть.
|
||||
/** Copies data from ReadBuffer to WriteBuffer, all that is.
|
||||
*/
|
||||
void copyData(ReadBuffer & from, WriteBuffer & to);
|
||||
|
||||
/** Копирует bytes байт из ReadBuffer в WriteBuffer. Если нет bytes байт, то кидает исключение.
|
||||
/** Copies `bytes` bytes from ReadBuffer to WriteBuffer. If there are no `bytes` bytes, then throws an exception.
|
||||
*/
|
||||
void copyData(ReadBuffer & from, WriteBuffer & to, size_t bytes);
|
||||
|
||||
/** То же самое, с условием на остановку.
|
||||
/** The same, with the condition to cancel.
|
||||
*/
|
||||
void copyData(ReadBuffer & from, WriteBuffer & to, std::atomic<bool> & is_cancelled);
|
||||
void copyData(ReadBuffer & from, WriteBuffer & to, size_t bytes, std::atomic<bool> & is_cancelled);
|
||||
|
@ -8,12 +8,12 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Создать объект для чтения данных из файла.
|
||||
* estimated_size - количество байтов, которые надо читать
|
||||
* aio_threshold - минимальное количество байт для асинхронных операций чтения
|
||||
/** Create an object to read data from a file.
|
||||
* estimated_size - the number of bytes to read
|
||||
* aio_threshold - the minimum number of bytes for asynchronous reads
|
||||
*
|
||||
* Если aio_threshold = 0 или estimated_size < aio_threshold, операции чтения выполняются синхронно.
|
||||
* В противном случае операции чтения выполняются асинхронно.
|
||||
* If aio_threshold = 0 or estimated_size < aio_threshold, read operations are executed synchronously.
|
||||
* Otherwise, the read operations are performed asynchronously.
|
||||
*/
|
||||
std::unique_ptr<ReadBufferFromFileBase> createReadBufferFromFileBase(const std::string & filename_,
|
||||
size_t estimated_size,
|
||||
|
@ -6,12 +6,12 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Создать объект для записи данных в файл.
|
||||
* estimated_size - количество байтов, которые надо записать
|
||||
* aio_threshold - минимальное количество байт для асинхронных операций записи
|
||||
/** Create an object to write data to a file.
|
||||
* estimated_size - number of bytes to write
|
||||
* aio_threshold - the minimum number of bytes for asynchronous writes
|
||||
*
|
||||
* Если aio_threshold = 0 или estimated_size < aio_threshold, операции записи выполняются синхронно.
|
||||
* В противном случае операции записи выполняются асинхронно.
|
||||
* If aio_threshold = 0 or estimated_size < aio_threshold, the write operations are executed synchronously.
|
||||
* Otherwise, write operations are performed asynchronously.
|
||||
*/
|
||||
WriteBufferFromFileBase * createWriteBufferFromFileBase(const std::string & filename_,
|
||||
size_t estimated_size,
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** ALTER запрос
|
||||
/** ALTER query
|
||||
* ALTER TABLE [db.]name_type
|
||||
* ADD COLUMN col_name type [AFTER col_after],
|
||||
* DROP COLUMN col_drop [FROM PARTITION partition],
|
||||
@ -43,35 +43,35 @@ public:
|
||||
|
||||
int type = NO_TYPE;
|
||||
|
||||
/** В запросе ADD COLUMN здесь хранится имя и тип добавляемого столбца
|
||||
* В запросе DROP это поле не используется
|
||||
* В запросе MODIFY здесь хранится имя столбца и новый тип
|
||||
/** The ADD COLUMN query stores the name and type of the column to add
|
||||
* This field is not used in the DROP query
|
||||
* In MODIFY query, the column name and the new type are stored here
|
||||
*/
|
||||
ASTPtr col_decl;
|
||||
|
||||
/** В запросе ADD COLUMN здесь опционально хранится имя столбца, следующее после AFTER
|
||||
* В запросе DROP здесь хранится имя столбца для удаления
|
||||
/** The ADD COLUMN query here optionally stores the name of the column following AFTER
|
||||
* The DROP query stores the column name for deletion here
|
||||
*/
|
||||
ASTPtr column;
|
||||
|
||||
/** Для MODIFY PRIMARY KEY
|
||||
/** For MODIFY PRIMARY KEY
|
||||
*/
|
||||
ASTPtr primary_key;
|
||||
|
||||
/** В запросах DROP PARTITION и RESHARD PARTITION здесь хранится имя partition'а.
|
||||
/** In DROP PARTITION and RESHARD PARTITION queries, the name of the partition is stored here.
|
||||
*/
|
||||
ASTPtr partition;
|
||||
bool detach = false; /// true для DETACH PARTITION.
|
||||
bool detach = false; /// true for DETACH PARTITION.
|
||||
|
||||
bool part = false; /// true для ATTACH PART
|
||||
bool part = false; /// true for ATTACH PART
|
||||
|
||||
bool do_copy = false; /// для RESHARD PARTITION.
|
||||
bool do_copy = false; /// for RESHARD PARTITION.
|
||||
|
||||
/** Для FETCH PARTITION - путь в ZK к шарду, с которого скачивать партицию.
|
||||
/** For FETCH PARTITION - the path in ZK to the shard, from which to download the partition.
|
||||
*/
|
||||
String from;
|
||||
|
||||
/** Для RESHARD PARTITION.
|
||||
/** For RESHARD PARTITION.
|
||||
*/
|
||||
ASTPtr last_partition;
|
||||
ASTPtr weighted_zookeeper_paths;
|
||||
@ -96,7 +96,7 @@ public:
|
||||
|
||||
ASTAlterQuery(StringRange range_ = StringRange());
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override;
|
||||
|
||||
ASTPtr clone() const override;
|
||||
|
@ -9,7 +9,7 @@ struct ASTCheckQuery : public ASTQueryWithOutput
|
||||
{
|
||||
ASTCheckQuery(StringRange range_ = StringRange()) : ASTQueryWithOutput(range_) {};
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return ("CheckQuery_" + database + "_" + table); };
|
||||
|
||||
ASTPtr clone() const override
|
||||
|
@ -8,12 +8,12 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** CREATE TABLE или ATTACH TABLE запрос
|
||||
/** CREATE TABLE or ATTACH TABLE query
|
||||
*/
|
||||
class ASTCreateQuery : public IAST
|
||||
{
|
||||
public:
|
||||
bool attach{false}; /// Запрос ATTACH TABLE, а не CREATE TABLE.
|
||||
bool attach{false}; /// Query ATTACH TABLE, not CREATE TABLE.
|
||||
bool if_not_exists{false};
|
||||
bool is_view{false};
|
||||
bool is_materialized_view{false};
|
||||
@ -23,7 +23,7 @@ public:
|
||||
String table;
|
||||
ASTPtr columns;
|
||||
ASTPtr storage;
|
||||
ASTPtr inner_storage; /// Внутренний engine для запроса CREATE MATERIALIZED VIEW
|
||||
ASTPtr inner_storage; /// Internal engine for the CREATE MATERIALIZED VIEW query
|
||||
String as_database;
|
||||
String as_table;
|
||||
ASTPtr select;
|
||||
@ -31,7 +31,7 @@ public:
|
||||
ASTCreateQuery() = default;
|
||||
ASTCreateQuery(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return (attach ? "AttachQuery_" : "CreateQuery_") + database + "_" + table; };
|
||||
|
||||
ASTPtr clone() const override
|
||||
|
@ -7,12 +7,12 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** DROP запрос
|
||||
/** DROP query
|
||||
*/
|
||||
class ASTDropQuery : public IAST
|
||||
{
|
||||
public:
|
||||
bool detach{false}; /// Запрос DETACH, а не DROP.
|
||||
bool detach{false}; /// DETACH query, not DROP.
|
||||
bool if_exists{false};
|
||||
String database;
|
||||
String table;
|
||||
@ -20,7 +20,7 @@ public:
|
||||
ASTDropQuery() = default;
|
||||
ASTDropQuery(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return (detach ? "DetachQuery_" : "DropQuery_") + database + "_" + table; };
|
||||
|
||||
ASTPtr clone() const override { return std::make_shared<ASTDropQuery>(*this); }
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/** Вывести список выражений в секциях запроса SELECT - по одному выражению на строку.
|
||||
/** Output a list of expressions in the SELECT query sections - one expression per line.
|
||||
*/
|
||||
void formatImplMultiline(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Идентификатор (столбца или алиас)
|
||||
/** Identifier (column or alias)
|
||||
*/
|
||||
class ASTIdentifier : public ASTWithAlias
|
||||
{
|
||||
@ -19,10 +19,10 @@ public:
|
||||
Format,
|
||||
};
|
||||
|
||||
/// имя. У составного идентификатора здесь будет конкатенированное имя (вида a.b.c), а отдельные составляюшие будут доступны внутри children.
|
||||
/// name. The composite identifier here will have a concatenated name (of the form a.b.c), and individual components will be available inside the children.
|
||||
String name;
|
||||
|
||||
/// чего идентифицирует этот идентификатор
|
||||
/// what this identifier identifies
|
||||
Kind kind;
|
||||
|
||||
ASTIdentifier() = default;
|
||||
@ -31,7 +31,7 @@ public:
|
||||
|
||||
String getColumnName() const override { return name; }
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "Identifier_" + name; }
|
||||
|
||||
ASTPtr clone() const override { return std::make_shared<ASTIdentifier>(*this); }
|
||||
|
@ -7,7 +7,7 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** INSERT запрос
|
||||
/** INSERT query
|
||||
*/
|
||||
class ASTInsertQuery : public IAST
|
||||
{
|
||||
@ -17,16 +17,16 @@ public:
|
||||
ASTPtr columns;
|
||||
String format;
|
||||
ASTPtr select;
|
||||
/// Идентификатор запроса INSERT. Используется при репликации.
|
||||
/// INSERT query identifier. Used for replication.
|
||||
String insert_id;
|
||||
/// Данные для вставки
|
||||
/// Data to insert
|
||||
const char * data = nullptr;
|
||||
const char * end = nullptr;
|
||||
|
||||
ASTInsertQuery() = default;
|
||||
ASTInsertQuery(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "InsertQuery_" + database + "_" + table; };
|
||||
|
||||
ASTPtr clone() const override
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Литерал (атомарный) - число, строка, NULL
|
||||
/** Literal (atomic) - number, string, NULL
|
||||
*/
|
||||
class ASTLiteral : public ASTWithAlias
|
||||
{
|
||||
@ -20,7 +20,7 @@ public:
|
||||
|
||||
String getColumnName() const override;
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "Literal_" + applyVisitor(FieldVisitorDump(), value); }
|
||||
|
||||
ASTPtr clone() const override { return std::make_shared<ASTLiteral>(*this); }
|
||||
|
@ -6,20 +6,20 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Пара из имени и типа. Например, browser FixedString(2).
|
||||
/** A pair of the name and type. For example, browser FixedString(2).
|
||||
*/
|
||||
class ASTNameTypePair : public IAST
|
||||
{
|
||||
public:
|
||||
/// имя
|
||||
/// name
|
||||
String name;
|
||||
/// тип
|
||||
/// type
|
||||
ASTPtr type;
|
||||
|
||||
ASTNameTypePair() = default;
|
||||
ASTNameTypePair(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "NameTypePair_" + name; }
|
||||
|
||||
ASTPtr clone() const override
|
||||
|
@ -7,7 +7,7 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** OPTIMIZE запрос
|
||||
/** OPTIMIZE query
|
||||
*/
|
||||
class ASTOptimizeQuery : public IAST
|
||||
{
|
||||
@ -15,9 +15,9 @@ public:
|
||||
String database;
|
||||
String table;
|
||||
|
||||
/// Может быть указана партиция, в которой производить оптимизацию.
|
||||
/// The partition to optimize can be specified.
|
||||
String partition;
|
||||
/// Может быть указан флаг - производить оптимизацию "до конца" вместо одного шага.
|
||||
/// A flag can be specified - perform optimization "to the end" instead of one step.
|
||||
bool final;
|
||||
/// Do deduplicate (default: false)
|
||||
bool deduplicate;
|
||||
@ -25,7 +25,7 @@ public:
|
||||
ASTOptimizeQuery() = default;
|
||||
ASTOptimizeQuery(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "OptimizeQuery_" + database + "_" + table + "_" + partition + (final ? "_final" : "") + (deduplicate ? "_deduplicate" : ""); };
|
||||
|
||||
ASTPtr clone() const override { return std::make_shared<ASTOptimizeQuery>(*this); }
|
||||
|
@ -28,7 +28,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/// Объявляет класс-наследник ASTQueryWithOutput с реализованными методами getID и clone.
|
||||
/// Declares the class-successor of ASTQueryWithOutput with implemented methods getID and clone.
|
||||
#define DEFINE_AST_QUERY_WITH_OUTPUT(Name, ID, Query) \
|
||||
class Name : public ASTQueryWithOutput \
|
||||
{ \
|
||||
|
@ -8,7 +8,7 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** Запрос с указанием названия таблицы и, возможно, БД и секцией FORMAT.
|
||||
/** Query specifying table name and, possibly, the database and the FORMAT section.
|
||||
*/
|
||||
class ASTQueryWithTableAndOutput : public ASTQueryWithOutput
|
||||
{
|
||||
@ -28,7 +28,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/// Объявляет класс-наследник ASTQueryWithTableAndOutput с реализованными методами getID и clone.
|
||||
/// Declares the inheritance class of ASTQueryWithTableAndOutput with the implementation of methods getID and clone.
|
||||
#define DEFINE_AST_QUERY_WITH_TABLE_AND_OUTPUT(Name, ID, Query) \
|
||||
class Name : public ASTQueryWithTableAndOutput \
|
||||
{ \
|
||||
|
@ -7,7 +7,7 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** RENAME запрос
|
||||
/** RENAME query
|
||||
*/
|
||||
class ASTRenameQuery : public IAST
|
||||
{
|
||||
@ -30,7 +30,7 @@ public:
|
||||
ASTRenameQuery() = default;
|
||||
ASTRenameQuery(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "Rename"; };
|
||||
|
||||
ASTPtr clone() const override { return std::make_shared<ASTRenameQuery>(*this); }
|
||||
|
@ -6,13 +6,13 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Коэффициент сэмплирования вида 0.1 или 1/10.
|
||||
* Важно сохранять его как рациональное число без преобразования в IEEE-754.
|
||||
/** Sampling factor in the form 0.1 or 1/10.
|
||||
* It's important to save it as a rational number without converting it to IEEE-754.
|
||||
*/
|
||||
class ASTSampleRatio : public IAST
|
||||
{
|
||||
public:
|
||||
using BigNum = __uint128_t; /// Должен вмещать в себя результат перемножения двух UInt64.
|
||||
using BigNum = __uint128_t; /// Must contain the result of multiplying two UInt64.
|
||||
|
||||
struct Rational
|
||||
{
|
||||
|
@ -19,26 +19,26 @@ public:
|
||||
ASTSelectQuery() = default;
|
||||
ASTSelectQuery(const StringRange range_);
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "SelectQuery"; };
|
||||
|
||||
/// Проверить наличие функции arrayJoin. (Не большого ARRAY JOIN.)
|
||||
/// Check for the presence of the `arrayJoin` function. (Not capital `ARRAY JOIN`.)
|
||||
static bool hasArrayJoin(const ASTPtr & ast);
|
||||
|
||||
/// Содержит ли запрос астериск?
|
||||
/// Does the query contain an asterisk?
|
||||
bool hasAsterisk() const;
|
||||
|
||||
/// Переименовать столбцы запроса в такие же имена, как в исходном запросе.
|
||||
/// Rename the query columns to the same names as in the original query.
|
||||
void renameColumns(const ASTSelectQuery & source);
|
||||
|
||||
/// Переписывает select_expression_list, чтобы вернуть только необходимые столбцы в правильном порядке.
|
||||
/// Rewrites select_expression_list to return only the required columns in the correct order.
|
||||
void rewriteSelectExpressionList(const Names & required_column_names);
|
||||
|
||||
bool isUnionAllHead() const { return (prev_union_all == nullptr) && next_union_all != nullptr; }
|
||||
|
||||
ASTPtr clone() const override;
|
||||
|
||||
/// Получить глубокую копию дерева первого запроса SELECT.
|
||||
/// Get a deep copy of the first SELECT query tree.
|
||||
ASTPtr cloneFirstSelect() const;
|
||||
|
||||
private:
|
||||
@ -72,13 +72,13 @@ public:
|
||||
void setDatabaseIfNeeded(const String & database_name);
|
||||
void replaceDatabaseAndTable(const String & database_name, const String & table_name);
|
||||
|
||||
/// Двусвязный список запросов SELECT внутри запроса UNION ALL.
|
||||
/// A double-linked list of SELECT queries inside a UNION ALL query.
|
||||
|
||||
/// Следующий запрос SELECT в цепочке UNION ALL, если такой есть
|
||||
/// The next SELECT query in the UNION ALL chain, if there is one
|
||||
ASTPtr next_union_all;
|
||||
/// Предыдущий запрос SELECT в цепочке UNION ALL (не вставляется в children и не клонируется)
|
||||
/// Указатель голый по следующим причинам:
|
||||
/// 1. чтобы предотвратить появление циклических зависимостей и, значит, утечки памяти;
|
||||
/// Previous SELECT query in the UNION ALL chain (not inserted into children and not cloned)
|
||||
/// The pointer is null for the following reasons:
|
||||
/// 1. to prevent the occurrence of cyclic dependencies and, hence, memory leaks;
|
||||
IAST * prev_union_all = nullptr;
|
||||
|
||||
protected:
|
||||
|
@ -8,8 +8,8 @@ namespace DB
|
||||
|
||||
class Set;
|
||||
|
||||
/** Множество. В процессе вычисления, на множество заменяется выражение в секции IN
|
||||
* - подзапрос или явное перечисление значений.
|
||||
/** The set. During the calculation, the expression in the IN section is replaced by the set
|
||||
* - a subquery or an explicit enumeration of values.
|
||||
*/
|
||||
class ASTSet : public IAST
|
||||
{
|
||||
@ -27,8 +27,8 @@ public:
|
||||
protected:
|
||||
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override
|
||||
{
|
||||
/** Подготовленное множество. В пользовательских запросах такого не бывает, но такое бывает после промежуточных преобразований запроса.
|
||||
* Выведем его не по-настоящему (это не будет корректным запросом, но покажет, что здесь было множество).
|
||||
/** Prepared set. In user requests, this does not happen, but this happens after the intermediate query transformation.
|
||||
* Output it for not real (this will not be a valid query, but it will show that there was a set).
|
||||
*/
|
||||
settings.ostr << (settings.hilite ? hilite_keyword : "")
|
||||
<< "(...)"
|
||||
|
@ -9,7 +9,7 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** SET запрос
|
||||
/** SET query
|
||||
*/
|
||||
class ASTSetQuery : public IAST
|
||||
{
|
||||
@ -23,12 +23,12 @@ public:
|
||||
using Changes = std::vector<Change>;
|
||||
Changes changes;
|
||||
|
||||
bool global; /// Если запрос SET GLOBAL.
|
||||
bool global; /// If the query is SET GLOBAL.
|
||||
|
||||
ASTSetQuery() = default;
|
||||
ASTSetQuery(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "Set"; };
|
||||
|
||||
ASTPtr clone() const override { return std::make_shared<ASTSetQuery>(*this); }
|
||||
|
@ -9,7 +9,7 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** Запрос SHOW TABLES или SHOW DATABASES
|
||||
/** Query SHOW TABLES or SHOW DATABASES
|
||||
*/
|
||||
class ASTShowTablesQuery : public ASTQueryWithOutput
|
||||
{
|
||||
@ -22,7 +22,7 @@ public:
|
||||
ASTShowTablesQuery() = default;
|
||||
ASTShowTablesQuery(const StringRange range_) : ASTQueryWithOutput(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "ShowTables"; };
|
||||
|
||||
ASTPtr clone() const override
|
||||
|
@ -7,7 +7,7 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** Подзарос SELECT
|
||||
/** SELECT subquery
|
||||
*/
|
||||
class ASTSubquery : public ASTWithAlias
|
||||
{
|
||||
@ -15,7 +15,7 @@ public:
|
||||
ASTSubquery() = default;
|
||||
ASTSubquery(const StringRange range_) : ASTWithAlias(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "Subquery"; }
|
||||
|
||||
ASTPtr clone() const override
|
||||
|
@ -7,7 +7,7 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** USE запрос
|
||||
/** USE query
|
||||
*/
|
||||
class ASTUseQuery : public IAST
|
||||
{
|
||||
@ -17,7 +17,7 @@ public:
|
||||
ASTUseQuery() = default;
|
||||
ASTUseQuery(const StringRange range_) : IAST(range_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
String getID() const override { return "UseQuery_" + database; };
|
||||
|
||||
ASTPtr clone() const override { return std::make_shared<ASTUseQuery>(*this); }
|
||||
|
@ -7,12 +7,12 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** Базовый класс для AST, которые могут содержать алиас (идентификаторы, литералы, функции).
|
||||
/** Base class for AST, which can contain an alias (identifiers, literals, functions).
|
||||
*/
|
||||
class ASTWithAlias : public IAST
|
||||
{
|
||||
public:
|
||||
/// Алиас, если есть, или пустая строка.
|
||||
/// The alias, if any, or an empty string.
|
||||
String alias;
|
||||
|
||||
using IAST::IAST;
|
||||
@ -21,7 +21,7 @@ public:
|
||||
String tryGetAlias() const override { return alias; }
|
||||
void setAlias(const String & to) override { alias = to; }
|
||||
|
||||
/// Вызывает formatImplWithoutAlias, а также выводит алиас. Если надо - заключает всё выражение в скобки.
|
||||
/// Calls formatImplWithoutAlias, and also outputs an alias. If necessary, encloses the entire expression in brackets.
|
||||
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override final;
|
||||
|
||||
virtual void formatImplWithoutAlias(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const = 0;
|
||||
|
@ -5,9 +5,9 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Если прямо сейчас не s, то ошибка.
|
||||
* Если word_boundary установлен в true, и последний символ строки - словарный (\w),
|
||||
* то проверяется, что последующий символ строки не словарный.
|
||||
/** If right now is not `s`, then an error.
|
||||
* If word_boundary is set to true, and the last character of the string - word (\w),
|
||||
* then it is checked that the next character in the string is not a word character.
|
||||
*/
|
||||
class ParserString : public IParserBase
|
||||
{
|
||||
@ -27,7 +27,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** пробельные символы
|
||||
/** whitespace characters
|
||||
*/
|
||||
class ParserWhiteSpace : public IParserBase
|
||||
{
|
||||
@ -61,7 +61,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** комментарии '--' или c-style
|
||||
/** comments '--' or c-style
|
||||
*/
|
||||
class ParserComment : public IParserBase
|
||||
{
|
||||
|
@ -15,9 +15,9 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Если в скобках выражение из одного элемента - возвращает в node этот элемент;
|
||||
* или если в скобках - подзапрос SELECT - то возвращает в node этот подзапрос;
|
||||
* иначе возвращает функцию tuple от содержимого скобок.
|
||||
/** If in parenthesis an expression from one element - returns this element in `node`;
|
||||
* or if there is a SELECT subquery in parenthesis, then this subquery returned in `node`;
|
||||
* otherwise returns `tuple` function from the contents of brackets.
|
||||
*/
|
||||
class ParserParenthesisExpression : public IParserBase
|
||||
{
|
||||
@ -27,7 +27,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Подзапрос SELECT в скобках.
|
||||
/** The SELECT subquery is in parenthesis.
|
||||
*/
|
||||
class ParserSubquery : public IParserBase
|
||||
{
|
||||
@ -37,7 +37,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Идентификатор, например, x_yz123 или `something special`
|
||||
/** An identifier, for example, x_yz123 or `something special`
|
||||
*/
|
||||
class ParserIdentifier : public IParserBase
|
||||
{
|
||||
@ -47,7 +47,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Идентификатор, возможно, содержащий точку, например, x_yz123 или `something special` или Hits.EventTime
|
||||
/** An identifier, possibly containing a dot, for example, x_yz123 or `something special` or Hits.EventTime
|
||||
*/
|
||||
class ParserCompoundIdentifier : public IParserBase
|
||||
{
|
||||
@ -76,11 +76,11 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Функция, например, f(x, y + 1, g(z)).
|
||||
* Или агрегатная функция: sum(x + f(y)), corr(x, y). По синтаксису - такая же, как обычная функция.
|
||||
* Или параметрическая агрегатная функция: quantile(0.9)(x + y).
|
||||
* Синтаксис - две пары круглых скобок вместо одной. Первая - для параметров, вторая - для аргументов.
|
||||
* Для функций может быть указан модификатор DISTINCT, например count(DISTINCT x, y).
|
||||
/** A function, for example, f(x, y + 1, g(z)).
|
||||
* Or an aggregate function: sum(x + f(y)), corr(x, y). The syntax is the same as the usual function.
|
||||
* Or a parametric aggregate function: quantile(0.9)(x + y).
|
||||
* Syntax - two pairs of parentheses instead of one. The first is for parameters, the second for arguments.
|
||||
* For functions, the DISTINCT modifier can be specified, for example, count(DISTINCT x, y).
|
||||
*/
|
||||
class ParserFunction : public IParserBase
|
||||
{
|
||||
@ -139,11 +139,11 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Массив литералов.
|
||||
* Массивы могут распарситься и как применение оператора [].
|
||||
* Но парсинг всего массива как целой константы серьёзно ускоряет анализ выражений в случае очень больших массивов.
|
||||
* Мы пробуем распарсить массив как массив литералов сначала (fast path),
|
||||
* а если не получилось (когда массив состоит из сложных выражений) - парсим как применение оператора [] (slow path).
|
||||
/** An array of literals.
|
||||
* Arrays can also be parsed as an application of [] operator.
|
||||
* But parsing the whole array as a whole constant seriously speeds up the analysis of expressions in the case of very large arrays.
|
||||
* We try to parse the array as an array of literals first (fast path),
|
||||
* and if it did not work out (when the array consists of complex expressions) - parse as an application of [] operator (slow path).
|
||||
*/
|
||||
class ParserArrayOfLiterals : public IParserBase
|
||||
{
|
||||
@ -153,7 +153,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Литерал - одно из: NULL, UInt64, Int64, Float64, String.
|
||||
/** The literal is one of: NULL, UInt64, Int64, Float64, String.
|
||||
*/
|
||||
class ParserLiteral : public IParserBase
|
||||
{
|
||||
@ -163,7 +163,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Алиас - идентификатор, перед которым идёт AS. Например: AS x_yz123.
|
||||
/** The alias is the identifier before which `AS` comes. For example: AS x_yz123.
|
||||
*/
|
||||
struct ParserAliasBase
|
||||
{
|
||||
@ -193,7 +193,7 @@ using ParserAlias = ParserAliasImpl<ParserIdentifier>;
|
||||
using ParserCastExpressionAlias = ParserAliasImpl<ParserTypeInCastExpression>;
|
||||
|
||||
|
||||
/** Элемент выражения - одно из: выражение в круглых скобках, массив, литерал, функция, идентификатор, звёздочка.
|
||||
/** The expression element is one of: an expression in parentheses, an array, a literal, a function, an identifier, an asterisk.
|
||||
*/
|
||||
class ParserExpressionElement : public IParserBase
|
||||
{
|
||||
@ -203,7 +203,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Элемент выражения, возможно, с алиасом, если уместно.
|
||||
/** An expression element, possibly with an alias, if appropriate.
|
||||
*/
|
||||
template <typename ParserAlias>
|
||||
class ParserWithOptionalAliasImpl : public IParserBase
|
||||
@ -237,7 +237,7 @@ protected:
|
||||
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
||||
};
|
||||
|
||||
/** Путь шарда в ZooKeeper вместе с весом.
|
||||
/** The path of the shard in ZooKeeper along with the weight.
|
||||
*/
|
||||
class ParserWeightedZooKeeperPath : public IParserBase
|
||||
{
|
||||
|
@ -9,13 +9,13 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Идущие подряд пары строк: оператор и соответствующая ему функция. Например, "+" -> "plus".
|
||||
* Порядок парсинга операторов имеет значение.
|
||||
/** Consequent pairs of rows: the operator and the corresponding function. For example, "+" -> "plus".
|
||||
* The parsing order of the operators is significant.
|
||||
*/
|
||||
using Operators_t = const char **;
|
||||
|
||||
|
||||
/** Список элементов, разделённых чем-либо. */
|
||||
/** List of elements separated by something. */
|
||||
class ParserList : public IParserBase
|
||||
{
|
||||
public:
|
||||
@ -33,8 +33,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/** Выражение с инфиксным бинарным лево-ассоциативным оператором.
|
||||
* Например, a + b - c + d.
|
||||
/** An expression with an infix binary left-associative operator.
|
||||
* For example, a + b - c + d.
|
||||
*/
|
||||
class ParserLeftAssociativeBinaryOperatorList : public IParserBase
|
||||
{
|
||||
@ -44,7 +44,7 @@ private:
|
||||
ParserPtr remaining_elem_parser;
|
||||
|
||||
public:
|
||||
/** operators_ - допустимые операторы и соответствующие им функции
|
||||
/** `operators_` - allowed operators and their corresponding functions
|
||||
*/
|
||||
ParserLeftAssociativeBinaryOperatorList(Operators_t operators_, ParserPtr && first_elem_parser_)
|
||||
: operators(operators_), first_elem_parser(std::move(first_elem_parser_))
|
||||
@ -65,8 +65,8 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Выражение с инфиксным оператором произвольной арности.
|
||||
* Например, a AND b AND c AND d.
|
||||
/** Expression with an infix operator of arbitrary arity.
|
||||
* For example, a AND b AND c AND d.
|
||||
*/
|
||||
class ParserVariableArityOperatorList : public IParserBase
|
||||
{
|
||||
@ -88,8 +88,8 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Выражение с префиксным унарным оператором.
|
||||
* Например, NOT x.
|
||||
/** An expression with a prefix unary operator.
|
||||
* Example, NOT x.
|
||||
*/
|
||||
class ParserPrefixUnaryOperatorExpression : public IParserBase
|
||||
{
|
||||
@ -98,7 +98,7 @@ private:
|
||||
ParserPtr elem_parser;
|
||||
|
||||
public:
|
||||
/** operators_ - допустимые операторы и соответствующие им функции
|
||||
/** `operators_` - allowed operators and their corresponding functions
|
||||
*/
|
||||
ParserPrefixUnaryOperatorExpression(Operators_t operators_, ParserPtr && elem_parser_)
|
||||
: operators(operators_), elem_parser(std::move(elem_parser_))
|
||||
@ -336,7 +336,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Список выражений, разделённых запятыми, возможно пустой. */
|
||||
/** A comma-separated list of expressions, probably empty. */
|
||||
class ParserExpressionList : public IParserBase
|
||||
{
|
||||
public:
|
||||
|
@ -31,7 +31,7 @@ using ASTs = std::vector<ASTPtr>;
|
||||
class WriteBuffer;
|
||||
|
||||
|
||||
/** Элемент синтаксического дерева (в дальнейшем - направленного ациклического графа с элементами семантики)
|
||||
/** Element of the syntax tree (hereinafter - directed acyclic graph with elements of semantics)
|
||||
*/
|
||||
class IAST
|
||||
{
|
||||
@ -39,8 +39,8 @@ public:
|
||||
ASTs children;
|
||||
StringRange range;
|
||||
|
||||
/** Строка с полным запросом.
|
||||
* Этот указатель не дает ее удалить, пока range в нее ссылается.
|
||||
/** A string with a full query.
|
||||
* This pointer does not allow it to be deleted while the range refers to it.
|
||||
*/
|
||||
StringPtr query_string;
|
||||
|
||||
@ -48,25 +48,25 @@ public:
|
||||
IAST(const StringRange range_) : range(range_) {}
|
||||
virtual ~IAST() = default;
|
||||
|
||||
/** Получить каноническое имя столбца, если элемент является столбцом */
|
||||
/** Get the canonical name of the column if the element is a column */
|
||||
virtual String getColumnName() const { throw Exception("Trying to get name of not a column: " + getID(), ErrorCodes::NOT_A_COLUMN); }
|
||||
|
||||
/** Получить алиас, если он есть, или каноническое имя столбца, если его нет. */
|
||||
/** Get the alias, if any, or the canonical name of the column, if it is not. */
|
||||
virtual String getAliasOrColumnName() const { return getColumnName(); }
|
||||
|
||||
/** Получить алиас, если он есть, или пустую строку, если его нет, или если элемент не поддерживает алиасы. */
|
||||
/** Get the alias, if any, or an empty string if it does not exist, or if the element does not support aliases. */
|
||||
virtual String tryGetAlias() const { return String(); }
|
||||
|
||||
/** Установить алиас. */
|
||||
/** Set the alias. */
|
||||
virtual void setAlias(const String & to)
|
||||
{
|
||||
throw Exception("Can't set alias of " + getColumnName(), ErrorCodes::UNKNOWN_TYPE_OF_AST_NODE);
|
||||
}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
/** Get the text that identifies this element. */
|
||||
virtual String getID() const = 0;
|
||||
|
||||
/** Получить глубокую копию дерева. */
|
||||
/** Get a deep copy of the tree. */
|
||||
virtual ASTPtr clone() const = 0;
|
||||
|
||||
/** Get text, describing and identifying this element and its subtree.
|
||||
@ -89,20 +89,20 @@ public:
|
||||
child->dumpTree(ostr, indent + 1);
|
||||
}
|
||||
|
||||
/** Проверить глубину дерева.
|
||||
* Если задано max_depth и глубина больше - кинуть исключение.
|
||||
* Возвращает глубину дерева.
|
||||
/** Check the depth of the tree.
|
||||
* If max_depth is specified and the depth is greater - throw an exception.
|
||||
* Returns the depth of the tree.
|
||||
*/
|
||||
size_t checkDepth(size_t max_depth) const
|
||||
{
|
||||
return checkDepthImpl(max_depth, 0);
|
||||
}
|
||||
|
||||
/** То же самое для общего количества элементов дерева.
|
||||
/** Same for the total number of tree elements.
|
||||
*/
|
||||
size_t checkSize(size_t max_size) const;
|
||||
|
||||
/** Получить set из имен индентификаторов
|
||||
/** Get `set` from the names of the identifiers
|
||||
*/
|
||||
virtual void collectIdentifierNames(IdentifierNameSet & set) const
|
||||
{
|
||||
@ -111,9 +111,9 @@ public:
|
||||
}
|
||||
|
||||
|
||||
/// Преобразовать в строку.
|
||||
/// Convert to a string.
|
||||
|
||||
/// Настройки формата.
|
||||
/// Format settings.
|
||||
struct FormatSettings
|
||||
{
|
||||
std::ostream & ostr;
|
||||
@ -129,16 +129,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Состояние. Например, может запоминаться множество узлов, которых мы уже обошли.
|
||||
/// State. For example, a set of nodes can be remembered, which we already walk through.
|
||||
struct FormatState
|
||||
{
|
||||
/** Запрос SELECT, в котором найден алиас; идентификатор узла с таким алиасом.
|
||||
* Нужно, чтобы когда узел встретился повторно, выводить только алиас.
|
||||
/** The SELECT query in which the alias was found; identifier of a node with such an alias.
|
||||
* It is necessary that when the node has met again, output only the alias.
|
||||
*/
|
||||
std::set<std::pair<const IAST *, std::string>> printed_asts_with_alias;
|
||||
};
|
||||
|
||||
/// Состояние, которое копируется при форматировании каждого узла. Например, уровень вложенности.
|
||||
/// The state that is copied when each node is formatted. For example, nesting level.
|
||||
struct FormatStateStacked
|
||||
{
|
||||
UInt8 indent = 0;
|
||||
@ -164,7 +164,7 @@ public:
|
||||
void writeAlias(const String & name, std::ostream & s, bool hilite) const;
|
||||
|
||||
protected:
|
||||
/// Для подсветки синтаксиса.
|
||||
/// For syntax highlighting.
|
||||
static const char * hilite_keyword;
|
||||
static const char * hilite_identifier;
|
||||
static const char * hilite_function;
|
||||
@ -177,7 +177,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/// Квотировать идентификатор обратными кавычками, если это требуется.
|
||||
/// Quota the identifier with backquotes, if required.
|
||||
String backQuoteIfNeed(const String & x);
|
||||
|
||||
|
||||
|
@ -14,23 +14,23 @@ namespace DB
|
||||
using Expected = const char *;
|
||||
|
||||
|
||||
/** Интерфейс для классов-парсеров
|
||||
/** Interface for parser classes
|
||||
*/
|
||||
class IParser
|
||||
{
|
||||
public:
|
||||
using Pos = const char *;
|
||||
|
||||
/** Получить текст о том, что парсит этот парсер. */
|
||||
/** Get the text of this parser parses. */
|
||||
virtual const char * getName() const = 0;
|
||||
|
||||
/** Распарсить кусок текста с позиции pos, но не дальше конца строки (end - позиция после конца строки),
|
||||
* переместить указатель pos на максимальное место, до которого удалось распарсить,
|
||||
* вернуть в случае успеха true и результат в node, если он нужен, иначе false,
|
||||
* в expected записать, что ожидалось в максимальной позиции,
|
||||
* до которой удалось распарсить, если парсинг был неуспешным,
|
||||
* или что парсит этот парсер, если парсинг был успешным.
|
||||
* Строка, в которую входит диапазон [begin, end) может быть не 0-terminated.
|
||||
/** Parse piece of text from position `pos`, but not beyond end of line (`end` - position after end of line),
|
||||
* move pointer `pos` to the maximum position to which it was possible to parse,
|
||||
* in case of success return `true` and the result in `node` if it is needed, otherwise false,
|
||||
* in `expected` write what was expected in the maximum position,
|
||||
* to which it was possible to parse if parsing was unsuccessful,
|
||||
* or what this parser parse if parsing was successful.
|
||||
* The string to which the [begin, end) range is included may be not 0-terminated.
|
||||
*/
|
||||
virtual bool parse(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) = 0;
|
||||
|
||||
@ -47,7 +47,7 @@ public:
|
||||
return ignore(pos, end, max_parsed_pos, expected);
|
||||
}
|
||||
|
||||
/** То же самое, но не двигать позицию и не записывать результат в node.
|
||||
/** The same, but do not move the position and do not write the result to node.
|
||||
*/
|
||||
bool check(Pos & pos, Pos end, Pos & max_parsed_pos, Expected & expected)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Базовый класс для большинства парсеров
|
||||
/** Base class for most parsers
|
||||
*/
|
||||
class IParserBase : public IParser
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Запрос типа такого:
|
||||
/** Query like this:
|
||||
* ALTER TABLE [db.]name
|
||||
* [ADD COLUMN col_name type [AFTER col_after],]
|
||||
* [DROP COLUMN col_drop, ...]
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
namespace DB
|
||||
{
|
||||
/** Запрос вида
|
||||
/** Query of form
|
||||
* CHECK [TABLE] [database.]table
|
||||
*/
|
||||
class ParserCheckQuery : public IParserBase
|
||||
|
@ -14,7 +14,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Вложенная таблица. Например, Nested(UInt32 CounterID, FixedString(2) UserAgentMajor)
|
||||
/** A nested table. For example, Nested(UInt32 CounterID, FixedString(2) UserAgentMajor)
|
||||
*/
|
||||
class ParserNestedTable : public IParserBase
|
||||
{
|
||||
@ -24,11 +24,11 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Параметрический тип или Storage. Например:
|
||||
* FixedString(10) или
|
||||
* Partitioned(Log, ChunkID) или
|
||||
/** Parametric type or Storage. For example:
|
||||
* FixedString(10) or
|
||||
* Partitioned(Log, ChunkID) or
|
||||
* Nested(UInt32 CounterID, FixedString(2) UserAgentMajor)
|
||||
* Результат парсинга - ASTFunction с параметрами или без.
|
||||
* Result of parsing - ASTFunction with or without parameters.
|
||||
*/
|
||||
class ParserIdentifierWithParameters : public IParserBase
|
||||
{
|
||||
@ -64,9 +64,9 @@ protected:
|
||||
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
||||
};
|
||||
|
||||
/** Имя и тип через пробел. Например, URL String. */
|
||||
/** The name and type are separated by a space. For example, URL String. */
|
||||
using ParserNameTypePair = IParserNameTypePair<ParserIdentifier>;
|
||||
/** Имя и тип через пробел. Имя может содержать точку. Например, Hits.URL String. */
|
||||
/** Name and type separated by a space. The name can contain a dot. For example, Hits.URL String. */
|
||||
using ParserCompoundNameTypePair = IParserNameTypePair<ParserCompoundIdentifier>;
|
||||
|
||||
template <class NameParser>
|
||||
@ -94,7 +94,7 @@ bool IParserNameTypePair<NameParser>::parseImpl(Pos & pos, Pos end, ASTPtr & nod
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Список столбцов. */
|
||||
/** List of columns. */
|
||||
class ParserNameTypePairList : public IParserBase
|
||||
{
|
||||
protected:
|
||||
@ -204,7 +204,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** Запрос типа такого:
|
||||
/** Query like this:
|
||||
* CREATE|ATTACH TABLE [IF NOT EXISTS] [db.]name
|
||||
* (
|
||||
* name1 type1,
|
||||
@ -212,16 +212,16 @@ protected:
|
||||
* ...
|
||||
* ) ENGINE = engine
|
||||
*
|
||||
* Или:
|
||||
* Or:
|
||||
* CREATE|ATTACH TABLE [IF NOT EXISTS] [db.]name AS [db2.]name2 [ENGINE = engine]
|
||||
*
|
||||
* Или:
|
||||
* Or:
|
||||
* CREATE|ATTACH TABLE [IF NOT EXISTS] [db.]name AS ENGINE = engine SELECT ...
|
||||
*
|
||||
* Или:
|
||||
* Or:
|
||||
* CREATE|ATTACH DATABASE db [ENGINE = engine]
|
||||
*
|
||||
* Или:
|
||||
* Or:
|
||||
* CREATE|ATTACH [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]name [ENGINE = engine] [POPULATE] AS SELECT ...
|
||||
*/
|
||||
class ParserCreateQuery : public IParserBase
|
||||
|
@ -7,10 +7,10 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Запрос типа такого:
|
||||
/** Query like this:
|
||||
* DROP|DETACH TABLE [IF EXISTS] [db.]name
|
||||
*
|
||||
* Или:
|
||||
* Or:
|
||||
* DROP DATABASE [IF EXISTS] db
|
||||
*/
|
||||
class ParserDropQuery : public IParserBase
|
||||
|
@ -7,18 +7,18 @@ namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** Варианты:
|
||||
/** Cases:
|
||||
*
|
||||
* Обычный вариант:
|
||||
* Normal case:
|
||||
* INSERT INTO [db.]table (c1, c2, c3) VALUES (v11, v12, v13), (v21, v22, v23), ...
|
||||
* INSERT INTO [db.]table VALUES (v11, v12, v13), (v21, v22, v23), ...
|
||||
*
|
||||
* Вставка данных в произвольном формате.
|
||||
* Сами данные идут после перевода строки, если он есть, или после всех пробельных символов, иначе.
|
||||
* Insert of data in an arbitrary format.
|
||||
* The data itself comes after LF(line feed), if it exists, or after all the whitespace characters, otherwise.
|
||||
* INSERT INTO [db.]table (c1, c2, c3) FORMAT format \n ...
|
||||
* INSERT INTO [db.]table FORMAT format \n ...
|
||||
*
|
||||
* Вставка результата выполнения SELECT запроса.
|
||||
* Insert the result of the SELECT query.
|
||||
* INSERT INTO [db.]table (c1, c2, c3) SELECT ...
|
||||
* INSERT INTO [db.]table SELECT ...
|
||||
*/
|
||||
|
@ -7,7 +7,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Запрос OPTIMIZE TABLE [db.]name [PARTITION partition] [FINAL] [DEDUPLICATE]
|
||||
/** Query OPTIMIZE TABLE [db.]name [PARTITION partition] [FINAL] [DEDUPLICATE]
|
||||
*/
|
||||
class ParserOptimizeQuery : public IParserBase
|
||||
{
|
||||
|
@ -7,9 +7,9 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Запрос типа такого:
|
||||
/** Query like this:
|
||||
* RENAME TABLE [db.]name TO [db.]name, [db.]name TO [db.]name, ...
|
||||
* (Переименовываться может произвольное количество таблиц.)
|
||||
* (An arbitrary number of tables can be renamed.)
|
||||
*/
|
||||
class ParserRenameQuery : public IParserBase
|
||||
{
|
||||
|
@ -6,8 +6,8 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Коэффициент сэмплирования вида 0.1 или 1/10.
|
||||
* Парсится как рациональное число без преобразования в IEEE-754.
|
||||
/** Sampling factor of the form 0.1 or 1/10.
|
||||
* It is parsed as a rational number without conversion to IEEE-754.
|
||||
*/
|
||||
class ParserSampleRatio : public IParserBase
|
||||
{
|
||||
|
@ -7,7 +7,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Запрос типа такого:
|
||||
/** Query like this:
|
||||
* SET [GLOBAL] name1 = value1, name2 = value2, ...
|
||||
*/
|
||||
class ParserSetQuery : public IParserBase
|
||||
@ -19,7 +19,7 @@ protected:
|
||||
const char * getName() const { return "SET query"; }
|
||||
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
||||
|
||||
/// Парсить список name = value пар, без SET [GLOBAL].
|
||||
/// Parse the list `name = value` pairs, without SET [GLOBAL].
|
||||
bool parse_only_internals;
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Запрос SHOW PROCESSLIST
|
||||
/** Query SHOW PROCESSLIST
|
||||
*/
|
||||
class ParserShowProcesslistQuery : public IParserBase
|
||||
{
|
||||
|
@ -6,9 +6,9 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Запрос типа такого:
|
||||
/** Query like this:
|
||||
* SHOW TABLES [FROM db] [[NOT] LIKE 'str']
|
||||
* или
|
||||
* or
|
||||
* SHOW DATABASES.
|
||||
*/
|
||||
class ParserShowTablesQuery : public IParserBase
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Запрос (EXISTS | SHOW CREATE | (DESCRIBE | DESC) ) [TABLE] [db.]name [FORMAT format]
|
||||
/** Query (EXISTS | SHOW CREATE | (DESCRIBE | DESC)) [TABLE] [db.]name [FORMAT format]
|
||||
*/
|
||||
class ParserTablePropertiesQuery : public IParserBase
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Запрос USE db
|
||||
/** Query USE db
|
||||
*/
|
||||
class ParserUseQuery : public IParserBase
|
||||
{
|
||||
|
@ -9,8 +9,8 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Берёт синтаксическое дерево и превращает его обратно в текст.
|
||||
* В случае запроса INSERT, данные будут отсутствовать.
|
||||
/** Takes a syntax tree and turns it back into text.
|
||||
* In case of INSERT query, the data will be missing.
|
||||
*/
|
||||
inline void formatAST(const IAST & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user