From 66f9bfca61df264d78557c390d43c50ca71035d2 Mon Sep 17 00:00:00 2001 From: Vladimir Chebotaryov Date: Tue, 26 Jul 2022 09:05:31 +0300 Subject: [PATCH 1/6] Fixed point of origin for exponential decay window functions to the last value in window. --- src/Processors/Transforms/WindowTransform.cpp | 244 +++++++++--------- src/Processors/Transforms/WindowTransform.h | 14 + .../02020_exponential_smoothing.reference | 34 +-- 3 files changed, 160 insertions(+), 132 deletions(-) diff --git a/src/Processors/Transforms/WindowTransform.cpp b/src/Processors/Transforms/WindowTransform.cpp index 5e0d896599c..4155ab7c7f1 100644 --- a/src/Processors/Transforms/WindowTransform.cpp +++ b/src/Processors/Transforms/WindowTransform.cpp @@ -968,9 +968,6 @@ void WindowTransform::updateAggregationState() } } } - - prev_frame_start = frame_start; - prev_frame_end = frame_end; } void WindowTransform::writeOutCurrentRow() @@ -1212,6 +1209,9 @@ void WindowTransform::appendChunk(Chunk & chunk) return; } + prev_frame_start = frame_start; + prev_frame_end = frame_end; + // Move to the next row. The frame will have to be recalculated. // The peer group start is updated at the beginning of the loop, // because current_row might now be past-the-end. @@ -1617,16 +1617,12 @@ struct StatefulWindowFunction : public WindowFunction struct ExponentialTimeDecayedSumState { - RowNumber previous_frame_start; - RowNumber previous_frame_end; Float64 previous_time; Float64 previous_sum; }; struct ExponentialTimeDecayedAvgState { - RowNumber previous_frame_start; - RowNumber previous_frame_end; Float64 previous_time; Float64 previous_sum; Float64 previous_count; @@ -1685,40 +1681,43 @@ struct WindowFunctionExponentialTimeDecayedSum final : public StatefulWindowFunc auto & state = getState(workspace); Float64 result = 0; - Float64 curr_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, transform->current_row); - if (state.previous_frame_start <= transform->frame_start - && transform->frame_start < state.previous_frame_end - && state.previous_frame_end <= transform->frame_end) + if (transform->frame_start < transform->frame_end) { - for (RowNumber i = state.previous_frame_start; i < transform->frame_start; transform->advanceRowNumber(i)) - { - Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); - Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); - result -= std::exp((prev_t - curr_t) / decay_length) * prev_val; - } - result += std::exp((state.previous_time - curr_t) / decay_length) * state.previous_sum; - for (RowNumber i = state.previous_frame_end; i < transform->frame_end; transform->advanceRowNumber(i)) - { - Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); - Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); - result += std::exp((prev_t - curr_t) / decay_length) * prev_val; - } - } - else - { - for (RowNumber i = transform->frame_start; i < transform->frame_end; transform->advanceRowNumber(i)) - { - Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); - Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); - result += std::exp((prev_t - curr_t) / decay_length) * prev_val; - } - } + RowNumber frame_back = transform->prevRowNumber(transform->frame_end); + Float64 back_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, frame_back); - state.previous_sum = result; - state.previous_time = curr_t; - state.previous_frame_start = transform->frame_start; - state.previous_frame_end = transform->frame_end; + if (transform->prev_frame_start <= transform->frame_start + && transform->frame_start < transform->prev_frame_end + && transform->prev_frame_end <= transform->frame_end) + { + for (RowNumber i = transform->prev_frame_start; i < transform->frame_start; transform->advanceRowNumber(i)) + { + Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); + Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + result -= std::exp((prev_t - back_t) / decay_length) * prev_val; + } + result += std::exp((state.previous_time - back_t) / decay_length) * state.previous_sum; + for (RowNumber i = transform->prev_frame_end; i < transform->frame_end; transform->advanceRowNumber(i)) + { + Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); + Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + result += std::exp((prev_t - back_t) / decay_length) * prev_val; + } + } + else + { + for (RowNumber i = transform->frame_start; i < transform->frame_end; transform->advanceRowNumber(i)) + { + Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); + Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + result += std::exp((prev_t - back_t) / decay_length) * prev_val; + } + } + + state.previous_sum = result; + state.previous_time = back_t; + } WindowFunctionHelpers::setValueToOutputColumn(transform, function_index, result); } @@ -1776,18 +1775,24 @@ struct WindowFunctionExponentialTimeDecayedMax final : public WindowFunction void windowInsertResultInto(const WindowTransform * transform, size_t function_index) override { - Float64 result = std::numeric_limits::lowest(); - Float64 curr_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, transform->current_row); + Float64 result = std::numeric_limits::quiet_NaN(); - for (RowNumber i = transform->frame_start; i < transform->frame_end; transform->advanceRowNumber(i)) + if (transform->frame_start < transform->frame_end) { - Float64 value = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); - Float64 t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + result = std::numeric_limits::lowest(); + RowNumber frame_back = transform->prevRowNumber(transform->frame_end); + Float64 back_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, frame_back); - /// Avoiding extra calls to `exp` and multiplications. - if (value > result || t > curr_t || result < 0) + for (RowNumber i = transform->frame_start; i < transform->frame_end; transform->advanceRowNumber(i)) { - result = std::max(std::exp((t - curr_t) / decay_length) * value, result); + Float64 value = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); + Float64 t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + + /// Avoiding extra calls to `exp` and multiplications. + if (value > result || t > back_t || result < 0) + { + result = std::max(std::exp((t - back_t) / decay_length) * value, result); + } } } @@ -1842,37 +1847,40 @@ struct WindowFunctionExponentialTimeDecayedCount final : public StatefulWindowFu auto & state = getState(workspace); Float64 result = 0; - Float64 curr_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, transform->current_row); - if (state.previous_frame_start <= transform->frame_start - && transform->frame_start < state.previous_frame_end - && state.previous_frame_end <= transform->frame_end) + if (transform->frame_start < transform->frame_end) { - for (RowNumber i = state.previous_frame_start; i < transform->frame_start; transform->advanceRowNumber(i)) - { - Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); - result -= std::exp((prev_t - curr_t) / decay_length); - } - result += std::exp((state.previous_time - curr_t) / decay_length) * state.previous_sum; - for (RowNumber i = state.previous_frame_end; i < transform->frame_end; transform->advanceRowNumber(i)) - { - Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); - result += std::exp((prev_t - curr_t) / decay_length); - } - } - else - { - for (RowNumber i = transform->frame_start; i < transform->frame_end; transform->advanceRowNumber(i)) - { - Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); - result += std::exp((prev_t - curr_t) / decay_length); - } - } + RowNumber frame_back = transform->prevRowNumber(transform->frame_end); + Float64 back_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, frame_back); - state.previous_sum = result; - state.previous_time = curr_t; - state.previous_frame_start = transform->frame_start; - state.previous_frame_end = transform->frame_end; + if (transform->prev_frame_start <= transform->frame_start + && transform->frame_start < transform->prev_frame_end + && transform->prev_frame_end <= transform->frame_end) + { + for (RowNumber i = transform->prev_frame_start; i < transform->frame_start; transform->advanceRowNumber(i)) + { + Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + result -= std::exp((prev_t - back_t) / decay_length); + } + result += std::exp((state.previous_time - back_t) / decay_length) * state.previous_sum; + for (RowNumber i = transform->prev_frame_end; i < transform->frame_end; transform->advanceRowNumber(i)) + { + Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + result += std::exp((prev_t - back_t) / decay_length); + } + } + else + { + for (RowNumber i = transform->frame_start; i < transform->frame_end; transform->advanceRowNumber(i)) + { + Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + result += std::exp((prev_t - back_t) / decay_length); + } + } + + state.previous_sum = result; + state.previous_time = back_t; + } WindowFunctionHelpers::setValueToOutputColumn(transform, function_index, result); } @@ -1935,55 +1943,61 @@ struct WindowFunctionExponentialTimeDecayedAvg final : public StatefulWindowFunc Float64 count = 0; Float64 sum = 0; - Float64 curr_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, transform->current_row); + Float64 result = std::numeric_limits::quiet_NaN(); - if (state.previous_frame_start <= transform->frame_start - && transform->frame_start < state.previous_frame_end - && state.previous_frame_end <= transform->frame_end) + if (transform->frame_start < transform->frame_end) { - for (RowNumber i = state.previous_frame_start; i < transform->frame_start; transform->advanceRowNumber(i)) + RowNumber frame_back = transform->prevRowNumber(transform->frame_end); + Float64 back_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, frame_back); + + if (transform->prev_frame_start <= transform->frame_start + && transform->frame_start < transform->prev_frame_end + && transform->prev_frame_end <= transform->frame_end) { - Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); - Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); - Float64 decay = std::exp((prev_t - curr_t) / decay_length); - sum -= decay * prev_val; - count -= decay; + for (RowNumber i = transform->prev_frame_start; i < transform->frame_start; transform->advanceRowNumber(i)) + { + Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); + Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + Float64 decay = std::exp((prev_t - back_t) / decay_length); + sum -= decay * prev_val; + count -= decay; + } + + { + Float64 decay = std::exp((state.previous_time - back_t) / decay_length); + sum += decay * state.previous_sum; + count += decay * state.previous_count; + } + + for (RowNumber i = transform->prev_frame_end; i < transform->frame_end; transform->advanceRowNumber(i)) + { + Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); + Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + Float64 decay = std::exp((prev_t - back_t) / decay_length); + sum += decay * prev_val; + count += decay; + } + } + else + { + for (RowNumber i = transform->frame_start; i < transform->frame_end; transform->advanceRowNumber(i)) + { + Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); + Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); + Float64 decay = std::exp((prev_t - back_t) / decay_length); + sum += decay * prev_val; + count += decay; + } } - { - Float64 decay = std::exp((state.previous_time - curr_t) / decay_length); - sum += decay * state.previous_sum; - count += decay * state.previous_count; - } + state.previous_sum = sum; + state.previous_count = count; + state.previous_time = back_t; - for (RowNumber i = state.previous_frame_end; i < transform->frame_end; transform->advanceRowNumber(i)) - { - Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); - Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); - Float64 decay = std::exp((prev_t - curr_t) / decay_length); - sum += decay * prev_val; - count += decay; - } - } - else - { - for (RowNumber i = transform->frame_start; i < transform->frame_end; transform->advanceRowNumber(i)) - { - Float64 prev_val = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_VALUE, i); - Float64 prev_t = WindowFunctionHelpers::getValue(transform, function_index, ARGUMENT_TIME, i); - Float64 decay = std::exp((prev_t - curr_t) / decay_length); - sum += decay * prev_val; - count += decay; - } + result = sum/count; } - state.previous_sum = sum; - state.previous_count = count; - state.previous_time = curr_t; - state.previous_frame_start = transform->frame_start; - state.previous_frame_end = transform->frame_end; - - WindowFunctionHelpers::setValueToOutputColumn(transform, function_index, sum/count); + WindowFunctionHelpers::setValueToOutputColumn(transform, function_index, result); } private: diff --git a/src/Processors/Transforms/WindowTransform.h b/src/Processors/Transforms/WindowTransform.h index e6db8402c5f..840711fc4a2 100644 --- a/src/Processors/Transforms/WindowTransform.h +++ b/src/Processors/Transforms/WindowTransform.h @@ -198,6 +198,13 @@ public: ++x.block; } + RowNumber nextRowNumber(const RowNumber & x) const + { + RowNumber result = x; + advanceRowNumber(result); + return result; + } + void retreatRowNumber(RowNumber & x) const { if (x.row > 0) @@ -219,6 +226,13 @@ public: #endif } + RowNumber prevRowNumber(const RowNumber & x) const + { + RowNumber result = x; + retreatRowNumber(result); + return result; + } + auto moveRowNumber(const RowNumber & _x, int64_t offset) const; auto moveRowNumberNoCheck(const RowNumber & _x, int64_t offset) const; diff --git a/tests/queries/0_stateless/02020_exponential_smoothing.reference b/tests/queries/0_stateless/02020_exponential_smoothing.reference index bc6d0920705..95f5cb0c310 100644 --- a/tests/queries/0_stateless/02020_exponential_smoothing.reference +++ b/tests/queries/0_stateless/02020_exponential_smoothing.reference @@ -654,23 +654,23 @@ exponentialTimeDecayedAvg 0 48 0.201 ████████████████████ 0 49 0.196 ███████████████████▌ Check `exponentialTimeDecayed.*` supports sliding windows -2 1 3.010050167084 2 3.030251507111 0.993333444442 -1 2 7.060905027605 4.080805360107 4.02030134086 1.756312382816 -0 3 12.091654548833 5.101006700134 5.000500014167 2.418089094006 -4 4 11.050650848754 5.050250835421 5.000500014167 2.209909172572 -5 5 9.970249502081 5 5.000500014167 1.993850509716 -1 6 20.07305726224 10.202013400268 5.000500014167 4.014210020072 -0 7 15.991544871125 10.100501670842 3.98029867414 4.017674596889 +2 1 2.950447180363 1.960397346614 2.970248507056 0.993333444442 +1 2 6.921089740404 4 3.940694040604 1.756312382816 +0 3 11.85222374685 5 4.901483479757 2.418089094006 +4 4 10.831833301125 4.950249168746 4.901483479757 2.209909172572 +5 5 9.772825334477 4.900993366534 4.901483479757 1.993850509716 +1 6 19.675584097659 10 4.901483479757 4.014210020072 +0 7 15.832426341049 10 3.940694040604 4.017674596889 10 8 10.980198673307 10 2.970248507056 3.696727276261 Check `exponentialTimeDecayedMax` works with negative values -2 1 -1.010050167084 -1 2 -1 -10 3 -0.990049833749 -4 4 -0.980198673307 -5 5 -1.010050167084 -1 6 -1 -10 7 -0.990049833749 -10 8 -0.980198673307 -10 9 -9.801986733068 -9.81 10 -9.801986733068 +2 1 -0.990049833749 +1 2 -0.980198673307 +10 3 -0.970445533549 +4 4 -0.960789439152 +5 5 -0.990049833749 +1 6 -0.980198673307 +10 7 -0.970445533549 +10 8 -0.960789439152 +10 9 -9.607894391523 +9.81 10 -9.704455335485 9.9 11 -9.712388869079 From 3cc03b141e50799340f9be9af007982ed004a4cc Mon Sep 17 00:00:00 2001 From: Vladimir Chebotaryov Date: Thu, 4 Aug 2022 18:08:32 +0300 Subject: [PATCH 2/6] Fixed tests on Debug build type. --- src/Processors/Transforms/WindowTransform.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Processors/Transforms/WindowTransform.h b/src/Processors/Transforms/WindowTransform.h index 840711fc4a2..424466bca8a 100644 --- a/src/Processors/Transforms/WindowTransform.h +++ b/src/Processors/Transforms/WindowTransform.h @@ -207,6 +207,10 @@ public: void retreatRowNumber(RowNumber & x) const { +#ifndef NDEBUG + auto original_x = x; +#endif + if (x.row > 0) { --x.row; @@ -220,9 +224,9 @@ public: x.row = blockAt(x).rows - 1; #ifndef NDEBUG - auto xx = x; - advanceRowNumber(xx); - assert(xx == x); + auto advanced_retreated_x = x; + advanceRowNumber(advanced_retreated_x); + assert(advanced_retreated_x == original_x); #endif } From 5252d41fdb2fd529c17e1fb4f11fa793f3adf435 Mon Sep 17 00:00:00 2001 From: Stephan <79573800+cyber-moon@users.noreply.github.com> Date: Wed, 17 Aug 2022 13:21:03 +0200 Subject: [PATCH 3/6] Provide missing documentation for `arrayWithConstant` Documentation of `arrayWithConstant(l, const)`-function, as this was not part of the documentation so far. --- docs/en/sql-reference/functions/array-functions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/sql-reference/functions/array-functions.md b/docs/en/sql-reference/functions/array-functions.md index 50a394e45fd..e76317b9e47 100644 --- a/docs/en/sql-reference/functions/array-functions.md +++ b/docs/en/sql-reference/functions/array-functions.md @@ -162,6 +162,10 @@ Creates an array from the function arguments. The arguments must be constants and have types that have the smallest common type. At least one argument must be passed, because otherwise it isn’t clear which type of array to create. That is, you can’t use this function to create an empty array (to do that, use the ‘emptyArray\*’ function described above). Returns an ‘Array(T)’ type result, where ‘T’ is the smallest common type out of the passed arguments. +## arrayWithConstant(length, elem) + +Creates an array of length `length` filled with the constant `elem`. + ## arrayConcat Combines arrays passed as arguments. From 5a1ac130727989200714c80f2b5d6bab57ea5359 Mon Sep 17 00:00:00 2001 From: Ramazan Polat Date: Wed, 17 Aug 2022 15:12:19 +0300 Subject: [PATCH 4/6] By default, enable_positional_arguments=1 --- docs/en/operations/settings/settings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index ae0d2eeb595..78db3720ac1 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -3102,7 +3102,7 @@ Possible values: - 0 — Positional arguments aren't supported. - 1 — Positional arguments are supported: column numbers can use instead of column names. -Default value: `0`. +Default value: `1`. **Example** From d5465d32e12c2181853bf03fd0cd5f21d36ad145 Mon Sep 17 00:00:00 2001 From: Denny Crane Date: Wed, 17 Aug 2022 09:38:06 -0300 Subject: [PATCH 5/6] Update settings.md --- docs/en/operations/settings/settings.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index ae0d2eeb595..5a0263a1247 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -3095,14 +3095,14 @@ Exception: Total regexp lengths too large. ## enable_positional_arguments {#enable-positional-arguments} -Enables or disables supporting positional arguments for [GROUP BY](../../sql-reference/statements/select/group-by.md), [LIMIT BY](../../sql-reference/statements/select/limit-by.md), [ORDER BY](../../sql-reference/statements/select/order-by.md) statements. When you want to use column numbers instead of column names in these clauses, set `enable_positional_arguments = 1`. +Enables or disables supporting positional arguments for [GROUP BY](../../sql-reference/statements/select/group-by.md), [LIMIT BY](../../sql-reference/statements/select/limit-by.md), [ORDER BY](../../sql-reference/statements/select/order-by.md) statements. Possible values: - 0 — Positional arguments aren't supported. - 1 — Positional arguments are supported: column numbers can use instead of column names. -Default value: `0`. +Default value: `1`. **Example** @@ -3113,8 +3113,6 @@ CREATE TABLE positional_arguments(one Int, two Int, three Int) ENGINE=Memory(); INSERT INTO positional_arguments VALUES (10, 20, 30), (20, 20, 10), (30, 10, 20); -SET enable_positional_arguments = 1; - SELECT * FROM positional_arguments ORDER BY 2,3; ``` From fa718ffc6e478da2bc86492ecd6e35f2e41553fe Mon Sep 17 00:00:00 2001 From: Denny Crane Date: Wed, 17 Aug 2022 09:40:01 -0300 Subject: [PATCH 6/6] Update settings.md --- docs/ru/operations/settings/settings.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index 5ad6e4ef3b6..abaa05639c6 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -3790,14 +3790,14 @@ Exception: Total regexp lengths too large. ## enable_positional_arguments {#enable-positional-arguments} -Включает и отключает поддержку позиционных аргументов для [GROUP BY](../../sql-reference/statements/select/group-by.md), [LIMIT BY](../../sql-reference/statements/select/limit-by.md), [ORDER BY](../../sql-reference/statements/select/order-by.md). Если вы хотите использовать номера столбцов вместо названий в выражениях этих операторов, установите `enable_positional_arguments = 1`. +Включает и отключает поддержку позиционных аргументов для [GROUP BY](../../sql-reference/statements/select/group-by.md), [LIMIT BY](../../sql-reference/statements/select/limit-by.md), [ORDER BY](../../sql-reference/statements/select/order-by.md). Возможные значения: - 0 — Позиционные аргументы не поддерживаются. - 1 — Позиционные аргументы поддерживаются: можно использовать номера столбцов вместо названий столбцов. -Значение по умолчанию: `0`. +Значение по умолчанию: `1`. **Пример** @@ -3808,8 +3808,6 @@ CREATE TABLE positional_arguments(one Int, two Int, three Int) ENGINE=Memory(); INSERT INTO positional_arguments VALUES (10, 20, 30), (20, 20, 10), (30, 10, 20); -SET enable_positional_arguments = 1; - SELECT * FROM positional_arguments ORDER BY 2,3; ```