Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL: Implement binary format support for SQL clear cursor #84230

Merged

Conversation

luigidellaquila
Copy link
Contributor

  • support binary_format parameter on _sql/close
  • make cursor close response consistent with the query protocol
    (ie. in ODBC/JDBC/CLI return CBOR response for cursor close - as for query)

Fixes #53359

- support binary_format parameter on _sql/close
- make cursor close response consistent with the query protocol
  (ie. in ODBC/JDBC/CLI return CBOR response for cursor close - as for query)
@luigidellaquila luigidellaquila added >bug :Analytics/SQL SQL querying Team:QL (Deprecated) Meta label for query languages team labels Feb 22, 2022
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-ql (Team:QL)

@luigidellaquila
Copy link
Contributor Author

@elasticmachine update branch

@elasticsearchmachine
Copy link
Collaborator

Hi @luigidellaquila, I've created a changelog YAML for you.

@elasticmachine
Copy link
Collaborator

expected head sha didn’t match current head ref.

@luigidellaquila
Copy link
Contributor Author

@elasticmachine update branch

Copy link
Contributor

@Luegg Luegg left a comment

Choose a reason for hiding this comment

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

I've left some comments but I don't understand the motivation behind the change. The JDBC driver and CLI seem to work as is (but 👍 for adding JdbcCloseCursorIT) and the binary_format parameter is not documented anywhere.

Also, out of curiosity, I couldn't find much information about binary_format. Why is this a flag instead of using Accept for the content negotiation?

Maybe @bpintea do you have more background?

@luigidellaquila
Copy link
Contributor Author

Thank you very much for the comments @Luegg
I'm also in doubt of misinterpreting #53359, probably @bpintea can shed some light.
JDBC and CLI work fine already indeed, this fix just adds a little bit of consistency (ie. ask for binary, get CBOR), but I agree with you that it's not strictly necessary.

@bpintea
Copy link
Contributor

bpintea commented Feb 24, 2022

I don't understand the motivation behind the change.

As noted in PR's description, the motivation is to "make cursor close response consistent": currently, CBOR is used by default, both for requests and responses. The drivers indicate the need for a CBOR answer with the binary_format body attribute. This indication works currently throughout the SQL API, except for the _sql/close endpoint. In this case the driver's can not ask for CBOR answer (since the request would fail, #53359).

The JDBC driver and CLI seem to work as is

They either "work" inconsistently (in respect to the body format), or leave cursors unclosed.

the binary_format parameter is not documented anywhere.

This has been by choice, I believe.

Why is this a flag instead of using Accept for the content negotiation?

No longer sure either, might have been to keep the format unchangeable to (HTTP) proxies. #48261 has a few comments around, but not on this question.

@Luegg
Copy link
Contributor

Luegg commented Feb 24, 2022

Thanks for the elaborations 👍 Consistency itself also makes sense of course, but I was unsure wether there was something else.

Copy link
Contributor

@bpintea bpintea left a comment

Choose a reason for hiding this comment

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

Looks good, left a few more notes.


@Override
public RestResponse buildResponse(SqlClearCursorResponse response) throws Exception {
assert mediaType instanceof XContentType;
Copy link
Contributor

Choose a reason for hiding this comment

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

Indeed, this could actually be checked (and tested), instead of an assert: one could still send an Accept with a CSV value or something that wouldn't make sense?

@luigidellaquila
Copy link
Contributor Author

@elasticmachine update branch

@luigidellaquila
Copy link
Contributor Author

Added a new batch of changes that addresses all the comments.

Copy link
Member

@costin costin left a comment

Choose a reason for hiding this comment

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

No need to extend the logic beyond CBOR (binary) and XContent.
Please include also a test/set of backwards compatibility tests to check the proper interaction between old clients (that do NOT set the backwards compatibility flag) with the current code.

index("library", "2", builder -> { builder.field("name", "bar"); });
index("library", "3", builder -> { builder.field("name", "baz"); });

try (Connection connection = createConnection(connectionProperties())) {
Copy link
Member

Choose a reason for hiding this comment

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

Same comment as above.

@@ -43,9 +48,11 @@
PARSER.declareString(optionalConstructorArg(), MODE);
PARSER.declareString(optionalConstructorArg(), CLIENT_ID);
PARSER.declareString(optionalConstructorArg(), VERSION);
PARSER.declareBoolean(SqlClearCursorRequest::binaryCommunication, BINARY_FORMAT);
Copy link
Member

Choose a reason for hiding this comment

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

Declaring this field mandatory (instead of optional), breaks backwards compatibility for clients that do not set this parameter.

Copy link
Contributor Author

@luigidellaquila luigidellaquila Mar 10, 2022

Choose a reason for hiding this comment

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

Not sure I got it, maybe I'm misinterpreting some logic here.
Isn't it optional already? (see also test https://github.com/elastic/elasticsearch/pull/84230/files#diff-7d14bc9a0a5fb5167a3d7eea6b457ea14324136f334a33df4417ec5f78fefb84R102 )

Copy link
Member

Choose a reason for hiding this comment

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

I read the above as having constructorArg() in a similar style to the previous declaration.

/*
* see getResponseMediaType(RestRequest, SqlQueryRequest)
*/
public static MediaType getResponseMediaType(RestRequest request, SqlClearCursorRequest sqlRequest) {
Copy link
Member

Choose a reason for hiding this comment

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

This shouldn't be necessary, see my previous comment.

@luigidellaquila
Copy link
Contributor Author

@elasticmachine update branch

Copy link
Member

@costin costin left a comment

Choose a reason for hiding this comment

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

Left comments.

Copy link
Contributor

@bpintea bpintea left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@astefan astefan left a comment

Choose a reason for hiding this comment

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

Good work so far. I've left some questions mostly looking for explanations on why a specific approach has been considered.
Also, please, have a look at JdbcHttpClientRequestTests where the binary comm is checked for a query request. I think the same should happen for a query close request.

@luigidellaquila
Copy link
Contributor Author

@elasticmachine update branch

@luigidellaquila
Copy link
Contributor Author

@elasticmachine update branch

Copy link
Member

@costin costin left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@astefan astefan left a comment

Choose a reason for hiding this comment

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

You need to adjust SqlClearCursorRequestTests to account for the new component.
mutateInstance should probably look something like this

    protected TestSqlClearCursorRequest mutateInstance(TestSqlClearCursorRequest instance) throws IOException {
        @SuppressWarnings("unchecked")
        Consumer<TestSqlClearCursorRequest> mutator = randomFrom(
            request -> request.requestInfo(randomValueOtherThan(request.requestInfo(), this::randomRequestInfo)),
            request -> request.setCursor(randomValueOtherThan(request.getCursor(), SqlQueryResponseTests::randomStringCursor)),
            request -> request.binaryCommunication(randomValueOtherThan(request.binaryCommunication(), () -> randomBoolean()))
        );
        TestSqlClearCursorRequest newRequest = new TestSqlClearCursorRequest(instance.requestInfo(), instance.getCursor());
        newRequest.binaryCommunication(instance.binaryCommunication());
        mutator.accept(newRequest);
        return newRequest;
    }

createTestInstance() should also consider a random value for binaryCommunication.

@luigidellaquila
Copy link
Contributor Author

@elasticmachine update branch

Copy link
Contributor

@astefan astefan left a comment

Choose a reason for hiding this comment

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

LGTM

@luigidellaquila luigidellaquila merged commit d6486ab into elastic:master Apr 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Analytics/SQL SQL querying >bug Team:QL (Deprecated) Meta label for query languages team v8.3.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SQL: the closing endpoint rejects the binary format parameter
8 participants