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

Make the connection aware of the current keyspace #180

Merged
merged 2 commits into from
Mar 1, 2022

Conversation

rbino
Copy link
Contributor

@rbino rbino commented Apr 7, 2020

Use the keyspace information to add it to %Prepared{} structs so that it can be used together with the statement as key in the prepared cache. This avoids erroneously using queries that were prepared against another keyspace.

To do so, response decoding has been moved inside the connection, akin to what was already done in handle_prepare to populate the prepared cache. The decode function in query structs is now simply an identity since the result gets there already decoded.

This also includes a minor fixup in the keyspace returned by setup_all by IntegrationCase.

Fix #179

else
%_{} = response ->
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@whatyouhide here I was not sure if I have to explicitly list all the possible structs that can be returned by decode_response, like

%kind{} when kind in [...]

let me know if you prefer it that way or, option 3, if I should skip the last line in the with statement and do something like

case state.protocol_module.decode_response(frame, query, options) do
  %SetKeyspace{keyspace: keyspace} ->
    {:ok, query, response, %{state | current_keyspace: keyspace}}

  response ->
    {:ok, query, response, state}
end

@whatyouhide
Copy link
Owner

@lexmag hey! Could you please take a look at this when you can, since you're more familiar with prepared queries than I am :) I'll be able to look at this late next week 😞

@rbino
Copy link
Contributor Author

rbino commented Jul 23, 2020

@lexmag @whatyouhide any update on this?

Also, I think we're going to win a prize for the longest running CI in Github's history since it's Waiting for status to be reported since April 😃

@whatyouhide
Copy link
Owner

Also, I think we're going to win a prize for the longest running CI in Github's history since it's Waiting for status to be reported since April 😃

Ahah, Travis dropped the ball a bit 😄 I will not be able to review this anytime soon, swamped with work and other commitments, sorry 😞 Will try to get to it as soon as possible!

@rbino
Copy link
Contributor Author

rbino commented Feb 28, 2022

Hey @whatyouhide! Since I saw some activity on the repo (and the removal of Travis which was cursing this PR) I rebased this on the current main branch.

I checked with the test and this is still relevant (i.e. the original bug is still there). The failing test in the CI is a result of #211.

Let me know if I need to change something.

Copy link
Owner

@whatyouhide whatyouhide left a comment

Choose a reason for hiding this comment

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

Hey @rbino, yes indeed, I am finally giving some love to Xandra.

So, as I understand your changes revolve around decoding the responses from C* in the connection module and not in the various "query" modules (Xandra.Batch, ...). I think this still happens in the caller and not in the connection process, so that should be fine.

Comment on lines +24 to +29
module_suffix =
inspect(__MODULE__)
|> String.replace(".", "")
|> String.downcase()

keyspace = "xandra_test_" <> module_suffix
Copy link
Owner

Choose a reason for hiding this comment

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

Why is this necessary? Can't we compare with String.downcase/1 from the query result in the new tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@whatyouhide as I explained in the commit message, I changed the test helper because the keyspace actually gets created lowercased (see https://docs.datastax.com/en/cql-oss/3.x/cql/cql_reference/ucase-lcase_r.html). The other tests didn't care because the name just gets passed as is and is translated by the DB automatically, but matching explicitly on the returned keyspace name revealed the inconsistency.

Of course I can just change this just in my test, I just thought that it was better to fix the inconsistency at the source so that tests can use the correct created keyspace name, let me know what I should do.

The keyspace that was created for the tests was effectively always created as
lowercase (see
https://docs.datastax.com/en/cql-oss/3.x/cql/cql_reference/ucase-lcase_r.html).
This does not matter when using a USE statement since that gets lowercased too
on the Cassandra side but it matters when explicitly matching on the returned
keyspace in the SetKeyspace struct.
Use the keyspace information to add it to `%Prepared{}` structs so that it can
be used together with the statement as key in the prepared cache. This avoids
erroneously using queries that were prepared against another keyspace.

To do so, response decoding has been moved inside the connection, akin to what
was already done in `handle_prepare` to populate the prepared cache. The decode
function in query structs is now simply an identity since the result gets there
already decoded.

Fix whatyouhide#179
@whatyouhide whatyouhide merged commit 63286bf into whatyouhide:main Mar 1, 2022
@whatyouhide
Copy link
Owner

This is fantastic, thank you so much @rbino. 💟

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Prepared statements generate wrong results when combined with USE statements
2 participants