Skip to content

Commit fbe4f88

Browse files
committed
Merge remote-tracking branch 'origin/master' into pr-lazy-materialization
2 parents 990209f + 647bc87 commit fbe4f88

30 files changed

+384
-44
lines changed

.github/workflows/create_release.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,10 @@ jobs:
135135
./utils/list-versions/update-docker-version.sh
136136
echo "Generate ChangeLog"
137137
export CI=1
138+
docker pull clickhouse/style-test:latest
138139
docker run -u "${UID}:${GID}" -e PYTHONUNBUFFERED=1 -e CI=1 --network=host \
139140
--volume=".:/wd" --workdir="/wd" \
140-
clickhouse/style-test \
141+
clickhouse/style-test:latest \
141142
./tests/ci/changelog.py -v --debug-helpers \
142143
--gh-user-or-token ${{ secrets.ROBOT_CLICKHOUSE_COMMIT_TOKEN }} \
143144
--jobs=5 \

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
* Enhance `SummingMergeTree` validation to skip aggregation for columns used in partition or sort keys. [#78022](https://github.com/ClickHouse/ClickHouse/pull/78022) ([Pervakov Grigorii](https://github.com/GrigoryPervakov)).
2424

2525
#### New Feature
26-
* Support correlated subqueries as an argument of `EXISTS` expression in the `WHERE` clause. Closes [#72459](https://github.com/ClickHouse/ClickHouse/issues/72459). [#76078](https://github.com/ClickHouse/ClickHouse/pull/76078) ([Dmitry Novik](https://github.com/novikd)).
2726
* Added CPU slot scheduling for workloads, see [the docs](https://clickhouse.com/docs/operations/workload-scheduling#cpu_scheduling) for details. [#77595](https://github.com/ClickHouse/ClickHouse/pull/77595) ([Sergei Trifonov](https://github.com/serxa)).
2827
* `clickhouse-local` will retain its databases after restart if you specify the `--path` command line argument. This closes [#50647](https://github.com/ClickHouse/ClickHouse/issues/50647). This closes [#49947](https://github.com/ClickHouse/ClickHouse/issues/49947). [#71722](https://github.com/ClickHouse/ClickHouse/pull/71722) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
2928
* Reject queries when the server is overloaded. The decision is made based on the ratio of wait time (`OSCPUWaitMicroseconds`) to busy time (`OSCPUVirtualTimeMicroseconds`). The query is dropped with some probability, when this ratio is between `min_os_cpu_wait_time_ratio_to_throw` and `max_os_cpu_wait_time_ratio_to_throw` (those are query level settings). [#63206](https://github.com/ClickHouse/ClickHouse/pull/63206) ([Alexey Katsman](https://github.com/alexkats)).
@@ -48,6 +47,7 @@
4847
* Support password based auth in SSH protocol in ClickHouse. [#78586](https://github.com/ClickHouse/ClickHouse/pull/78586) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
4948

5049
#### Experimental Feature
50+
* Support correlated subqueries as an argument of `EXISTS` expression in the `WHERE` clause. Closes [#72459](https://github.com/ClickHouse/ClickHouse/issues/72459). [#76078](https://github.com/ClickHouse/ClickHouse/pull/76078) ([Dmitry Novik](https://github.com/novikd)).
5151
* Functions `sparseGrams` and `sparseGramsHashes` with ASCII and UTF8 versions added. Author: [scanhex12](https://github.com/scanhex12). [#78176](https://github.com/ClickHouse/ClickHouse/pull/78176) ([Pervakov Grigorii](https://github.com/GrigoryPervakov)). Do not use it: the implementation will change in the next versions.
5252

5353
#### Performance Improvement
@@ -114,7 +114,7 @@
114114

115115
#### Bug Fix (user-visible misbehavior in an official stable release)
116116
* Fix incorrect projection analysis when `count(Nullable)` is used in aggregate projections. This fixes [#74495](https://github.com/ClickHouse/ClickHouse/issues/74495) . This PR also adds some logs around projection analysis to clarify why a projection is used or why not. [#74498](https://github.com/ClickHouse/ClickHouse/pull/74498) ([Amos Bird](https://github.com/amosbird)).
117-
* Fix "Part <...> does not contain in snapshot of previous virtual parts. (PART_IS_TEMPORARILY_LOCKED)" during DETACH PART. [#76039](https://github.com/ClickHouse/ClickHouse/pull/76039) ([Aleksei Filatov](https://github.com/aalexfvk)).
117+
* Fix `Part <...> does not contain in snapshot of previous virtual parts. (PART_IS_TEMPORARILY_LOCKED)` during `DETACH PART`. [#76039](https://github.com/ClickHouse/ClickHouse/pull/76039) ([Aleksei Filatov](https://github.com/aalexfvk)).
118118
* Fix not working skip indexes with expression with literals in analyzer and remove trivial casts during indexes analysis. [#77229](https://github.com/ClickHouse/ClickHouse/pull/77229) ([Pavel Kruglov](https://github.com/Avogar)).
119119
* Fix a bug when `close_session` query parameter didn't have any effect leading to named sessions being closed only after `session_timeout`. [#77336](https://github.com/ClickHouse/ClickHouse/pull/77336) ([Alexey Katsman](https://github.com/alexkats)).
120120
* Fixed receiving messages from NATS server without attached Materialized Views. [#77392](https://github.com/ClickHouse/ClickHouse/pull/77392) ([Dmitry Novikov](https://github.com/dmitry-sles-novikov)).

ci/docker/style-test/requirements.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,8 @@ yamllint==1.26.3
33
codespell==2.2.1
44
mypy==1.15.0
55
pylint==3.1.0
6-
tqdm==4.67.1 # required for change log generation
6+
# required for change log generation:
7+
tqdm==4.67.1
8+
thefuzz==0.22.1
9+
PyGitHub==2.6.1
10+
boto3==1.37.38

ci/jobs/scripts/check_style/aspell-ignore/en/aspell-dict.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,7 @@ distinctdynamictypes
17281728
distinctjsonpaths
17291729
distro
17301730
divideDecimal
1731+
divideOrNull
17311732
dmesg
17321733
doesnt
17331734
domainRFC
@@ -2038,6 +2039,7 @@ inodes
20382039
instantiation
20392040
instantiations
20402041
intDiv
2042+
intDivOrNull
20412043
intDivOrZero
20422044
intExp
20432045
intHash
@@ -2264,6 +2266,7 @@ mmap
22642266
mmapped
22652267
modularization
22662268
moduli
2269+
moduloOrNull
22672270
moduloOrZero
22682271
mongoc
22692272
mongocxx
@@ -2476,6 +2479,7 @@ positionCaseInsensitive
24762479
positionCaseInsensitiveUTF
24772480
positionUTF
24782481
positiveModulo
2482+
positiveModuloOrNull
24792483
postfix
24802484
postfixes
24812485
postgres

docs/en/sql-reference/functions/arithmetic-functions.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ divide(a, b)
9393

9494
Alias: `a / b` (operator)
9595

96+
## divideOrNull {#divideornull}
97+
98+
Like [divide](#divide) but returns null when the divisor is zero.
99+
100+
**Syntax**
101+
102+
```sql
103+
divideOrNull(a, b)
104+
```
105+
96106
## intDiv {#intdiv}
97107

98108
Performs an integer division of two values `a` by `b`, i.e. computes the quotient rounded down to the next smallest integer.
@@ -144,6 +154,16 @@ Same as `intDiv` but returns zero when dividing by zero or when dividing a minim
144154
intDivOrZero(a, b)
145155
```
146156

157+
## intDivOrNull {#intdivornull}
158+
159+
Like [intDiv](#intdiv) but returns null when the divisor is zero.
160+
161+
**Syntax**
162+
163+
```sql
164+
intDivOrNull(a, b)
165+
```
166+
147167
## isFinite {#isfinite}
148168

149169
Returns 1 if the Float32 or Float64 argument not infinite and not a NaN, otherwise this function returns 0.
@@ -236,6 +256,16 @@ Like [modulo](#modulo) but returns zero when the divisor is zero.
236256
moduloOrZero(a, b)
237257
```
238258

259+
## moduloOrNull {#moduloornull}
260+
261+
Like [modulo](#modulo) but returns null when the divisor is zero.
262+
263+
**Syntax**
264+
265+
```sql
266+
moduloOrNull(a, b)
267+
```
268+
239269
## positiveModulo(a, b) {#positivemoduloa-b}
240270

241271
Like [modulo](#modulo) but always returns a non-negative number.
@@ -268,6 +298,16 @@ Result:
268298
└────────────────────────┘
269299
```
270300

301+
## positiveModuloOrNull(a, b) {#positivemoduloornulla-b}
302+
303+
Like [positiveModulo](#positivemoduloa-b) but returns null when the divisor is zero.
304+
305+
**Syntax**
306+
307+
```sql
308+
positiveModuloOrNull(a, b)
309+
```
310+
271311
## negate {#negate}
272312

273313
Negates a value `a`. The result is always signed.

docs/en/sql-reference/statements/show.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ The `SHOW CLUSTER(S)` statement returns a list of clusters.
500500
All available clusters are listed in the [`system.clusters`](../../operations/system-tables/clusters.md) table.
501501

502502
:::note
503-
The `SHOW CLUSTER name` query displays the contents of `system.clusters` table for the specified cluster name.
503+
The `SHOW CLUSTER name` query displays `cluster`, `shard_num`, `replica_num`, `host_name`, `host_address`, and `port` of the `system.clusters` table for the specified cluster name.
504504
:::
505505

506506
### Syntax {#syntax-20}
@@ -546,16 +546,10 @@ Row 1:
546546
──────
547547
cluster: test_shard_localhost
548548
shard_num: 1
549-
shard_weight: 1
550549
replica_num: 1
551550
host_name: localhost
552551
host_address: 127.0.0.1
553552
port: 9000
554-
is_local: 1
555-
user: default
556-
default_database:
557-
errors_count: 0
558-
estimated_recovery_time: 0
559553
```
560554

561555
## SHOW SETTINGS {#show-settings}

src/Functions/DivisionUtils.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,21 @@ struct DivideIntegralImpl
109109
#endif
110110
};
111111

112+
template <typename A, typename B>
113+
struct DivideIntegralOrNullImpl : DivideIntegralImpl<A, B>
114+
{
115+
using ResultType = typename NumberTraits::ResultOfIntegerDivision<A, B>::Type;
116+
117+
template<typename Result = ResultType>
118+
static Result apply(A a, B b)
119+
{
120+
if (unlikely(divisionLeadsToFPE(a, b)))
121+
return 0;
122+
else
123+
return DivideIntegralImpl<A, B>::apply(a, b);
124+
}
125+
};
126+
112127
template <typename A, typename B>
113128
struct ModuloImpl
114129
{
@@ -168,6 +183,21 @@ struct ModuloLegacyImpl : ModuloImpl<A, B>
168183
using ResultType = typename NumberTraits::ResultOfModuloLegacy<A, B>::Type;
169184
};
170185

186+
template <typename A, typename B>
187+
struct ModuloOrNullImpl : ModuloImpl<A, B>
188+
{
189+
using ResultType = typename NumberTraits::ResultOfModulo<A, B>::Type;
190+
191+
template <typename Result = ResultType>
192+
static Result apply(A a, B b)
193+
{
194+
if (unlikely(divisionLeadsToFPE(a, b)))
195+
return 0;
196+
else
197+
return ModuloImpl<A, B>::apply(a, b);
198+
}
199+
};
200+
171201
template <typename A, typename B>
172202
struct PositiveModuloImpl : ModuloImpl<A, B>
173203
{
@@ -196,4 +226,19 @@ struct PositiveModuloImpl : ModuloImpl<A, B>
196226
}
197227
};
198228

229+
template <typename A, typename B>
230+
struct PositiveModuloOrNullImpl : PositiveModuloImpl<A, B>
231+
{
232+
using ResultType = typename NumberTraits::ResultOfPositiveModulo<A, B>::Type;
233+
234+
template <typename Result = ResultType>
235+
static Result apply(A a, B b)
236+
{
237+
if (unlikely(divisionLeadsToFPE(a, b)))
238+
return 0;
239+
else
240+
return PositiveModuloImpl<A, B>::apply(a, b);
241+
}
242+
};
243+
199244
}

src/Functions/FunctionBinaryArithmetic.h

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ class FunctionBinaryArithmetic : public IFunction
815815
static constexpr bool is_modulo = IsOperation<Op>::modulo;
816816
static constexpr bool is_int_div = IsOperation<Op>::int_div;
817817
static constexpr bool is_int_div_or_zero = IsOperation<Op>::int_div_or_zero;
818+
static constexpr bool is_division_or_null = IsOperation<Op>::division_or_null;
818819

819820
ContextPtr context;
820821
bool check_decimal_overflow = true;
@@ -1615,7 +1616,10 @@ class FunctionBinaryArithmetic : public IFunction
16151616
/// We shouldn't use default implementation for nulls for the case when operation is divide,
16161617
/// intDiv or modulo and denominator is Nullable(Something), because it may cause division
16171618
/// by zero error (when value is Null we store default value 0 in nested column).
1618-
return !division_by_nullable;
1619+
/// And we also shouldn't use default implementation for nulls for the case when operation is
1620+
/// divideOrNull, intDivOrNull, moduloOrNull or positiveModuloOrNull, because it will return
1621+
/// null when the divisor is zero, and it is conflict with the default implementation.
1622+
return !division_by_nullable && !is_division_or_null;
16191623
}
16201624

16211625
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & arguments) const override
@@ -1926,7 +1930,12 @@ class FunctionBinaryArithmetic : public IFunction
19261930
});
19271931

19281932
if (valid)
1929-
return type_res;
1933+
{
1934+
if constexpr (is_division_or_null)
1935+
return makeNullable(type_res);
1936+
else
1937+
return type_res;
1938+
}
19301939

19311940
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal types {} and {} of arguments of function {}",
19321941
arguments[0]->getName(), arguments[1]->getName(), String(name));
@@ -2420,7 +2429,6 @@ ColumnPtr executeStringInteger(const ColumnsWithTypeAndName & arguments, const A
24202429
if (division_by_nullable && !right_nullmap)
24212430
{
24222431
assert(right_argument.type->isNullable());
2423-
24242432
bool is_const = checkColumnConst<ColumnNullable>(right_argument.column.get());
24252433
const ColumnNullable * nullable_column = is_const ? checkAndGetColumnConstData<ColumnNullable>(right_argument.column.get())
24262434
: checkAndGetColumn<ColumnNullable>(right_argument.column.get());
@@ -2430,6 +2438,27 @@ ColumnPtr executeStringInteger(const ColumnsWithTypeAndName & arguments, const A
24302438
return wrapInNullable(res, arguments, result_type, input_rows_count);
24312439
}
24322440

2441+
/// Process special case when operation is divideOrNull, intDivOrNull, moduloOrNull or positiveModuloOrNull.
2442+
if (is_division_or_null)
2443+
{
2444+
if (left_argument.column->onlyNull() || right_argument.column->onlyNull())
2445+
{
2446+
auto res = removeNullable(result_type)->createColumn();
2447+
res->insertManyDefaults(input_rows_count);
2448+
auto null_map_col = ColumnUInt8::create(input_rows_count, 1);
2449+
return !null_map_col->empty() ? wrapInNullable(std::move(res), std::move(null_map_col)) : makeNullable(std::move(res));
2450+
}
2451+
else if (result_type->isNullable())
2452+
{
2453+
auto null_map_col = ColumnUInt8::create(input_rows_count, 0);
2454+
PaddedPODArray<UInt8> & null_map_data = null_map_col->getData();
2455+
for (size_t i = 0; i < input_rows_count; ++i)
2456+
null_map_data[i] = left_argument.column->isNullAt(i) || !right_argument.column->getBool(i);
2457+
auto res = executeImpl2(createBlockWithNestedColumns(arguments), removeNullable(result_type), input_rows_count, right_nullmap);
2458+
return !null_map_col->empty() ? wrapInNullable(res, std::move(null_map_col)) : makeNullable(res);
2459+
}
2460+
}
2461+
24332462
/// Special case - one or both arguments are IPv4
24342463
if (isIPv4(arguments[0].type) || isIPv4(arguments[1].type))
24352464
{

src/Functions/IsOperation.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ template <typename, typename> struct PlusImpl;
1212
template <typename, typename> struct MinusImpl;
1313
template <typename, typename> struct MultiplyImpl;
1414
template <typename, typename> struct DivideFloatingImpl;
15+
template <typename, typename> struct DivideFloatingOrNullImpl;
1516
template <typename, typename> struct DivideIntegralImpl;
1617
template <typename, typename> struct DivideIntegralOrZeroImpl;
18+
template <typename, typename> struct DivideIntegralOrNullImpl;
1719
template <typename, typename> struct LeastBaseImpl;
1820
template <typename, typename> struct GreatestBaseImpl;
1921
template <typename, typename> struct ModuloImpl;
22+
template <typename, typename> struct ModuloOrNullImpl;
2023
template <typename, typename> struct PositiveModuloImpl;
24+
template <typename, typename> struct PositiveModuloOrNullImpl;
2125
template <typename, typename> struct EqualsOp;
2226
template <typename, typename> struct NotEqualsOp;
2327
template <typename, typename> struct LessOrEqualsOp;
@@ -51,10 +55,14 @@ struct IsOperation
5155
static constexpr bool minus = IsSameOperation<Op, MinusImpl>::value;
5256
static constexpr bool multiply = IsSameOperation<Op, MultiplyImpl>::value;
5357
static constexpr bool div_floating = IsSameOperation<Op, DivideFloatingImpl>::value;
58+
static constexpr bool div_floating_or_null = IsSameOperation<Op, DivideFloatingOrNullImpl>::value;
5459
static constexpr bool int_div = IsSameOperation<Op, DivideIntegralImpl>::value;
5560
static constexpr bool int_div_or_zero = IsSameOperation<Op, DivideIntegralOrZeroImpl>::value;
61+
static constexpr bool int_div_or_null = IsSameOperation<Op, DivideIntegralOrNullImpl>::value;
5662
static constexpr bool modulo = IsSameOperation<Op, ModuloImpl>::value;
63+
static constexpr bool modulo_or_null = IsSameOperation<Op, ModuloOrNullImpl>::value;
5764
static constexpr bool positive_modulo = IsSameOperation<Op, PositiveModuloImpl>::value;
65+
static constexpr bool positive_modulo_or_null = IsSameOperation<Op, PositiveModuloOrNullImpl>::value;
5866
static constexpr bool least = IsSameOperation<Op, LeastBaseImpl>::value;
5967
static constexpr bool greatest = IsSameOperation<Op, GreatestBaseImpl>::value;
6068

@@ -63,6 +71,7 @@ struct IsOperation
6371
static constexpr bool division = div_floating || int_div || int_div_or_zero || modulo || positive_modulo;
6472
// NOTE: allow_decimal should not fully contain `division` because of divInt
6573
static constexpr bool allow_decimal = plus || minus || multiply || division || least || greatest;
74+
static constexpr bool division_or_null = modulo_or_null || positive_modulo_or_null || int_div_or_null || div_floating_or_null;
6675
};
6776

6877
}

0 commit comments

Comments
 (0)