Skip to content

Fixed output to compressed table functions -- Better fix for #13871#21325

Closed
excitoon wants to merge 5 commits intoClickHouse:masterfrom
excitoon-favorites:fixfinalize
Closed

Fixed output to compressed table functions -- Better fix for #13871#21325
excitoon wants to merge 5 commits intoClickHouse:masterfrom
excitoon-favorites:fixfinalize

Conversation

@excitoon
Copy link
Copy Markdown
Contributor

@excitoon excitoon commented Mar 1, 2021

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

Changelog category (leave one):

  • Bug Fix

Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):

Fixed output to compressed table functions -- Better fix for #13871, reverts #15376

@robot-clickhouse robot-clickhouse added the pr-bugfix Pull request with bugfix, not backported by default label Mar 1, 2021
@excitoon excitoon changed the title Fixed output to compressed table functions -- Better fix for #15376 Fixed output to compressed table functions -- Better fix for #13871 Mar 1, 2021
@excitoon
Copy link
Copy Markdown
Contributor Author

excitoon commented Mar 1, 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.

Fixed in #21305 (and in a little bit better way), same for all other writers

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.

And BTW finalize() is a public part of interface (and this is a why it does not shows the conflicts partially)

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.

This is a good fix as well, but as I see write buffers shall pass finalize() to underlying write buffer anyway.

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.

Indeed, there should be finalize(), not next() (here

and in all similar places).

Can you send a separate patch for this?

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.

I do not agree, and finish() there shall be called from finalize(), not a destructor.

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.

I see, we shall call finalize() of underlying buffer from finish(), but finish() shall be the same thing as finalize actually.

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.

Comment on lines 101 to 108
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.

But this will hide write error in case of exception, the idea of #19451 is to move such code into the callers (although it is quite a challenge)

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.

Unfortunately, I don't get this change, did you find a way to process two exceptions simultaneously? Is std::terminate a better thing than logging here?

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.

Is std::terminate a better thing than logging here?

Yes, since ignoring write error is unacceptable, it is better to terminate.

Basically it should not be possible if all callers calls finalize(), but if some code path will miss it, then the error may be ignored and the user will not get any error (yes there will be an error in error log, but this is not enough)

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.

But why it does not call finalize() anymore? AFAIU it should call finalize() not next()?

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.

@azat As I understand, finalize() is called before query returns to client, but this call was forgotten when we made compression argument, and behavior of table functions with and without compression became inconsistent:

cristal :) insert into table function url('https://s3.us-west-2.amazonaws.com/altinity-qa-testa/data/', 'CSVWithNames', 'd UInt64', 'deflate') SELECT * from numbers(1)

INSERT INTO FUNCTION url('https://s3.us-west-2.amazonaws.com/altinity-qa-testa/data/', 'CSVWithNames', 'd UInt64', 'deflate') SELECT *
FROM numbers(1)

Query id: ca24b2f0-b79e-4a60-91f0-85a7caf9bf66

Ok.

0 rows in set. Elapsed: 0.736 sec. 

cristal :) insert into table function url('https://s3.us-west-2.amazonaws.com/altinity-qa-testa/data/', 'CSVWithNames', 'd UInt64') SELECT * from numbers(1)

INSERT INTO FUNCTION url('https://s3.us-west-2.amazonaws.com/altinity-qa-testa/data/', 'CSVWithNames', 'd UInt64') SELECT *
FROM numbers(1)

Query id: 71a4779b-8da4-4e18-ab21-dd9abac1b1f0

→ Progress: 1.00 rows, 8.00 B (1.20 rows/s., 9.63 B/s.)  99%
0 rows in set. Elapsed: 0.939 sec. 

Received exception from server (version 21.2.1):
Code: 86. DB::Exception: Received from localhost:9000. DB::Exception: Received error from remote server /altinity-qa-testa/data/. HTTP status code: 405 Method Not Allowed, body: <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>MethodNotAllowed</Code><Message>The specified method is not allowed against this resource.</Message><Method>POST</Method><ResourceType>OBJECT</ResourceType><RequestId>M6Q1NHCWGG0F0SD0</RequestId><HostId>EGOFX9bG3aMMVswqXtCTYPJoIQ/jFHOo2AG9d0JgjdvLF+RNYK9TiQCeLgaAAg8OyKFAp8Z0iqg=</HostId></Error>. 

Previously, I fixed that with these lines of code, calling finalize() in destructor. But it is really a bad place to do so, because it involves lots of initialization code and exceptions in destructor, which shall be catch. finalize() of these write buffers is called at writeSuffix() of corresponding output stream.

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.

As I understand, finalize() is called before query returns to client

It should, can you give a stacktrace example?

but this call was forgotten when we made compression argument, and behavior of table functions with and without compression became inconsistent

Does #21305 fixes it?

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 it does.

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.

I'll copy tests to another PR.

@azat
Copy link
Copy Markdown
Member

azat commented Mar 1, 2021

@excitoon by the way, is it possible to write a test to reproduce the problem that you are trying to fix?

@excitoon excitoon force-pushed the fixfinalize branch 2 times, most recently from ea90904 to 43361c9 Compare March 2, 2021 14:06
@excitoon
Copy link
Copy Markdown
Contributor Author

excitoon commented Mar 2, 2021

@azat I added test for this in 02d4fd2 -- wrong credentials shall report an error but it doesn't happen when any compression method is chosen.

{
/// FIXME move final flush into the caller
MemoryTracker::LockExceptionInThread lock;
finish();
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.

But why do you removed finish()? What if someone will forget to call finalize()?

@azat
Copy link
Copy Markdown
Member

azat commented Mar 4, 2021

Integration tests (asan) — fail: 2, passed: 1161, error: 0
Integration tests (release) — fail: 2, passed: 1161, error: 0
Integration tests (thread) — fail: 4, passed: 1042, error: 24

Test failures looks related

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-bugfix Pull request with bugfix, not backported by default

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants