Skip to content

CompileExpressions comparison function constant case fix#24023

Merged
kitaisreal merged 9 commits intoClickHouse:masterfrom
kitaisreal:compile-expressions-comparison-function-constant-case-with-alias-fix
May 20, 2021
Merged

CompileExpressions comparison function constant case fix#24023
kitaisreal merged 9 commits intoClickHouse:masterfrom
kitaisreal:compile-expressions-comparison-function-constant-case-with-alias-fix

Conversation

@kitaisreal
Copy link
Copy Markdown
Contributor

I hereby agree to the terms of the CLA available at: https://yandex.ru/legal/cla/?lang=en

Fixes #24020.

Changelog category (leave one):

  • Not for changelog (changelog entry is not required)

@robot-clickhouse robot-clickhouse added the pr-not-for-changelog This PR should not be mentioned in the changelog label May 11, 2021
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo? Noomparision

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

@alesapin alesapin self-assigned this May 12, 2021
@alesapin
Copy link
Copy Markdown
Member

SQLancer found more:

--java.lang.AssertionError: SELECT SUM((t0.c1) or (((((t0.c0) IS NOT NULL)) IS NOT NULL))), MAX((((t0.c1)>=(((t0.c1) IS NULL)))) or (t0.c1)), COUNT(((((((t0.c1) IS NULL)) IS NULL))==(((t0.c1)>=(t0.c0))))), COUNT((t0.c0) and ((- (((t0.c0)<=(t0.c1)))))), SUM((- (t0.c1))) FROM t0 GROUP BY t0.c1, t0.c0 HAVING (NOT (t0.c1)) UNION ALL SELECT SUM((t0.c1) or (((((t0.c0) IS NOT NULL)) IS NOT NULL))), MAX((((t0.c1)>=(((t0.c1) IS NULL)))) or (t0.c1)), COUNT(((((((t0.c1) IS NULL)) IS NULL))==(((t0.c1)>=(t0.c0))))), COUNT((t0.c0) and ((- (((t0.c0)<=(t0.c1)))))), SUM((- (t0.c1))) FROM t0 GROUP BY t0.c1, t0.c0 HAVING (NOT ((NOT (t0.c1)))) UNION ALL SELECT SUM((t0.c1) or (((((t0.c0) IS NOT NULL)) IS NOT NULL))), MAX((((t0.c1)>=(((t0.c1) IS NULL)))) or (t0.c1)), COUNT(((((((t0.c1) IS NULL)) IS NULL))=(((t0.c1)>=(t0.c0))))), COUNT((t0.c0) and ((- (((t0.c0)<=(t0.c1)))))), SUM((- (t0.c1))) FROM t0 GROUP BY t0.c1, t0.c0 HAVING (((NOT (t0.c1))) IS NULL) SETTINGS aggregate_functions_null_for_empty=1, enable_optimize_predicate_expression=0;
--	at sqlancer.common.query.SQLQueryAdapter.checkException(SQLQueryAdapter.java:100)
--	at sqlancer.common.query.SQLQueryAdapter.executeAndGet(SQLQueryAdapter.java:131)
--	at sqlancer.ComparatorHelper.getResultSetFirstColumnAsString(ComparatorHelper.java:54)
--	at sqlancer.clickhouse.oracle.tlp.ClickHouseTLPHavingOracle.check(ClickHouseTLPHavingOracle.java:66)
--	at sqlancer.ProviderAdapter.generateAndTestDatabase(ProviderAdapter.java:49)
--	at sqlancer.Main$DBMSExecutor.run(Main.java:326)
--	at sqlancer.Main$2.run(Main.java:510)
--	at sqlancer.Main$2.runThread(Main.java:488)
--	at sqlancer.Main$2.run(Main.java:478)
--	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
--	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
--	at java.base/java.lang.Thread.run(Thread.java:832)
--Caused by: ru.yandex.clickhouse.except.ClickHouseException: ClickHouse exception, code: 44, host: localhost, port: 8123; Code: 44, e.displayText() = DB::Exception: Cannot convert column `equals(isNull(isNull(c1)), greaterOrEquals(c1, c0))` because it is non constant in source stream but must be constant in result (version 21.6.1.6812)```

@qoega
Copy link
Copy Markdown
Member

qoega commented May 12, 2021

Why Cannot convert column is not a LOGICAL_ERROR? We should find bugs like this in AST Fuzzer

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done by the expression analyzer at about the same stage where it evaluates constants.

@kitaisreal kitaisreal force-pushed the compile-expressions-comparison-function-constant-case-with-alias-fix branch from 1f48e58 to af8e0d7 Compare May 13, 2021 14:19
Comment on lines 43 to 44
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, but maybe we can replace the whole function to literal 1 or literal 0

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KochetovNicolai right now seems easier to understand what is going on.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls remove debug output

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@kitaisreal kitaisreal force-pushed the compile-expressions-comparison-function-constant-case-with-alias-fix branch 2 times, most recently from c2b324f to 6c33480 Compare May 15, 2021 15:30
SELECT count() FROM system.numbers WHERE number != number;
SELECT count() FROM system.numbers WHERE number < number;
SELECT count() FROM system.numbers WHERE number > number;
-- SELECT count() FROM system.numbers WHERE number != number;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope we will revert this?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not so easy to do.
It's actually not so clear why reading from infinite table must return at all.
We can go farter and want a query SELECT count() FROM system.numbers WHERE number < 10 return 10. But is it necessary?

This optimizations is implemented in a not obvious way for now. We expected that a function != for two same non-constant arguments will return constant 0, and assume that constant will remain. It could have been ok if we had some meta info that columns are really same. But we just compare two ptrs. I don't think there is a guarantee that it is true for all other blocks. (However, I could not find counterexample. Queries like where x != if(blockNumber() == 0, x, y) work correctly only because blockNumber does not return constant.)

@alesapin
Copy link
Copy Markdown
Member

alesapin commented May 18, 2021

Stress test:

zgrep -a '8c05de33-7dd9-47ef-a4b0-d7ee11ddbac1' clickhouse-server.log.gz
2021.05.18 00:09:15.537857 [ 35027 ] {8c05de33-7dd9-47ef-a4b0-d7ee11ddbac1} <Debug> executeQuery: (from [::1]:50154, using production parser) (comment: /usr/share/clickhouse-test/queries/0_stateless/00429_long_http_bufferization.sh) SELECT greatest(toUInt8(1), toUInt8(intHash64(number))) FROM system.numbers LIMIT 2500000 FORMAT RowBinary
2021.05.18 00:09:15.544607 [ 35027 ] {8c05de33-7dd9-47ef-a4b0-d7ee11ddbac1} <Trace> ContextAccess (default): Access granted: SELECT(number) ON system.numbers
2021.05.18 00:09:15.546831 [ 35027 ] {8c05de33-7dd9-47ef-a4b0-d7ee11ddbac1} <Trace> InterpreterSelectQuery: FetchColumns -> Complete
2021.05.18 00:09:18.726076 [ 35027 ] {8c05de33-7dd9-47ef-a4b0-d7ee11ddbac1} <Information> executeQuery: Read 2500000 rows, 19.07 MiB in 3.187516281 sec., 784309 rows/sec., 5.98 MiB/sec.
2021.05.18 00:09:18.819026 [ 35027 ] {8c05de33-7dd9-47ef-a4b0-d7ee11ddbac1} <Debug> DynamicQueryHandler: Done processing query
2021.05.18 00:09:37.379188 [ 78460 ] {} <Fatal> BaseDaemon: (version 21.6.1.6862, build id: 902A04D557495CBDC22EAA45AEF413357E72A75C) (from thread 35027) (query_id: 8c05de33-7dd9-47ef-a4b0-d7ee11ddbac1) Received signal Aborted (6)
2021.05.18 00:09:37.378816 [ 78460 ] {} <Fatal> BaseDaemon: ########################################
2021.05.18 00:09:37.379421 [ 78460 ] {} <Fatal> BaseDaemon: 
2021.05.18 00:09:37.498338 [ 78460 ] {} <Fatal> BaseDaemon: Stack trace: 0x7f08fdd2b18b 0x7f08fdd0a859 0x8f7cf6e 0x921335d 0x1931b354 0x1931b247 0x9009a3b 0x143c12a8 0x143488fe 0x1433fd0f 0x143ba4e1 0x16fa81a3 0x16fa8930 0x1711fb02 0x1711df90 0x1711c708 0x8f7776d 0x7f08fdee0609 0x7f08fde07293
2021.05.18 00:09:37.498812 [ 78460 ] {} <Fatal> BaseDaemon: 5. raise @ 0x4618b in /usr/lib/x86_64-linux-gnu/libc-2.31.so
2021.05.18 00:09:37.499068 [ 78460 ] {} <Fatal> BaseDaemon: 6. abort @ 0x25859 in /usr/lib/x86_64-linux-gnu/libc-2.31.so
2021.05.18 00:09:50.095824 [ 78460 ] {} <Fatal> BaseDaemon: 7. abort @ 0x8f7cf6e in /usr/bin/clickhouse
2021.05.18 00:09:50.598741 [ 78460 ] {} <Fatal> BaseDaemon: 8. ./obj-x86_64-linux-gnu/../base/daemon/BaseDaemon.cpp:0: terminate_handler() @ 0x921335d in /usr/bin/clickhouse
2021.05.18 00:09:50.648051 [ 78460 ] {} <Fatal> BaseDaemon: 9. ./obj-x86_64-linux-gnu/../contrib/libcxxabi/src/cxa_handlers.cpp:61: std::__terminate(void (*)()) @ 0x1931b354 in /usr/bin/clickhouse
2021.05.18 00:09:50.695754 [ 78460 ] {} <Fatal> BaseDaemon: 10.1. inlined from ./obj-x86_64-linux-gnu/../contrib/libcxxabi/src/include/atomic_support.h:78: void (*std::__1::(anonymous namespace)::__libcpp_atomic_load<void (*)()>(void (* const*)(), int))()
2021.05.18 00:09:50.695959 [ 78460 ] {} <Fatal> BaseDaemon: 10.2. inlined from ../contrib/libcxxabi/src/cxa_handlers.cpp:49: std::get_terminate()
2021.05.18 00:09:50.696065 [ 78460 ] {} <Fatal> BaseDaemon: 10. ../contrib/libcxxabi/src/cxa_handlers.cpp:92: std::terminate() @ 0x1931b247 in /usr/bin/clickhouse
2021.05.18 00:10:03.808964 [ 292 ] {} <Fatal> Application: Child process was terminated by signal 6.

addr2line:

$ addr2line -iCe ./clickhouse 0x7f08fdd2b18b 0x7f08fdd0a859 0x8f7cf6e 0x921335d 0x1931b354 0x1931b247 0x9009a3b 0x143c12a8 0x143488fe 0x1433fd0f 0x143ba4e1 0x16fa81a3 0x16fa8930 0x1711fb02 0x1711df90 0x1711c708 0x8f7776d 0x7f08fdee0609 0x7f08fde07293
??:0
??:0
??:?
BaseDaemon.cpp:?
./obj-x86_64-linux-gnu/../contrib/libcxxabi/src/cxa_handlers.cpp:61
./obj-x86_64-linux-gnu/../contrib/libcxxabi/src/include/atomic_support.h:78
./obj-x86_64-linux-gnu/../contrib/libcxxabi/src/cxa_handlers.cpp:49
./obj-x86_64-linux-gnu/../contrib/libcxxabi/src/cxa_handlers.cpp:92
main.cpp:?
./obj-x86_64-linux-gnu/../src/IO/BufferWithOwnMemory.h:48
./obj-x86_64-linux-gnu/../src/IO/BufferWithOwnMemory.h:137
./obj-x86_64-linux-gnu/../src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp:201
./obj-x86_64-linux-gnu/../contrib/libcxx/include/memory:2615
./obj-x86_64-linux-gnu/../contrib/libcxx/include/memory:2518
./obj-x86_64-linux-gnu/../contrib/libcxx/include/memory:3212
./obj-x86_64-linux-gnu/../src/Server/HTTPHandler.h:43
./obj-x86_64-linux-gnu/../src/Server/HTTPHandler.cpp:933
??:?
./obj-x86_64-linux-gnu/../contrib/poco/Net/src/TCPServerConnection.cpp:57
./obj-x86_64-linux-gnu/../contrib/poco/Net/src/TCPServerDispatcher.cpp:114
./obj-x86_64-linux-gnu/../contrib/poco/Foundation/include/Poco/ScopedLock.h:36
./obj-x86_64-linux-gnu/../contrib/poco/Foundation/src/ThreadPool.cpp:213
./obj-x86_64-linux-gnu/../contrib/poco/Foundation/src/Thread.cpp:56
./obj-x86_64-linux-gnu/../contrib/poco/Foundation/include/Poco/SharedPtr.h:277
./obj-x86_64-linux-gnu/../contrib/poco/Foundation/include/Poco/SharedPtr.h:156
./obj-x86_64-linux-gnu/../contrib/poco/Foundation/include/Poco/SharedPtr.h:208
./obj-x86_64-linux-gnu/../contrib/poco/Foundation/src/Thread_POSIX.cpp:360
crtstuff.c:?
??:0
??:0

@alesapin
Copy link
Copy Markdown
Member

Wait for perf tests and merge.

@alesapin
Copy link
Copy Markdown
Member


+1.249x | 0.249 | 0.247 | agg_functions_min_max_any
-- | -- | -- | --


Flap?

@alesapin
Copy link
Copy Markdown
Member

I'll retry the task.

@alesapin
Copy link
Copy Markdown
Member

column_column_comparison | xml.etree.ElementTree.ParseError: no element found: line 39, column 0

@kitaisreal kitaisreal merged commit af78649 into ClickHouse:master May 20, 2021
azat added a commit to azat/ClickHouse that referenced this pull request Sep 16, 2021
This will avoid possible std::terminate, like in [1]:

  [1]: ClickHouse#24023 (comment)
@azat
Copy link
Copy Markdown
Member

azat commented Sep 29, 2021

@kitaisreal looks like this should be backported?

@kitaisreal kitaisreal added the pr-must-backport Pull request should be backported intentionally. Use this label with great care! label Sep 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-must-backport Pull request should be backported intentionally. Use this label with great care! pr-not-for-changelog This PR should not be mentioned in the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot convert column less(c0, c1) because it is non constant in source stream but must be constant in result

7 participants