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: migrate prepared statements during session migration #76399

Merged
merged 5 commits into from
Feb 23, 2022

Conversation

rafiss
Copy link
Collaborator

@rafiss rafiss commented Feb 10, 2022

fixes #76398

See individual commits. The last one contains the business logic changes,
and the rest are just refactors.

Release note (sql change): The crdb_internal.serialize_session and
crdb_internal.deserialize_session now can handle prepared statements.
When deserializing, any prepared statements that existed when the
session was serialized are re-prepared. It is an error to re-prepare a
statement if the current session already has a statement with that name.

@rafiss rafiss requested review from otan and a team February 10, 2022 21:19
@rafiss rafiss requested a review from a team as a code owner February 10, 2022 21:19
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Contributor

@otan otan left a comment

Choose a reason for hiding this comment

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

changes lgtm.

one thing i am curious about - what happens to prepared statements if a schema change happened and the types change? in turn, does AddPreparedStatement during a session migration potentially change the result of the prepared statement producing an entirely different statement? is it worth testing?

@andy-kimball
Copy link
Contributor

CC @RaduBerinde to make sure to take a look at this.

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 13, 2022

what happens to prepared statements if a schema change happened and the types change?

This is the behavior without any session migration involved:

exec
CREATE TABLE t(a INT4, b TEXT, c DATE)
----

wire_prepare s2
INSERT INTO t VALUES($1, $2, $3)
----

exec
ALTER TABLE t DROP COLUMN c
----

wire_exec s2 1 cat 2022-02-10
----
ERROR: INSERT has more expressions than target columns, 3 expressions for 2 targets (SQLSTATE 42601)

in turn, does AddPreparedStatement during a session migration potentially change the result of the prepared statement producing an entirely different statement? is it worth testing?

yeah we definitely should test. given the above, i guess the two options are to not serialize a prepared statement if it's not valid at the time of serialization, or to ignore certain types of prepare errors at the time of deserialization.

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 13, 2022

We could also keep the behavior as-is and just error out. (The user-impact is that their client would get a hard disconnect rather than a graceful session migration.)

@otan
Copy link
Contributor

otan commented Feb 13, 2022

happy with erroring out. also happy for you to add this test in a separate PR.

@rafiss rafiss force-pushed the prepared-stmt-session-migration branch from 347fce3 to a1477d2 Compare February 23, 2022 01:51
@rafiss
Copy link
Collaborator Author

rafiss commented Feb 23, 2022

confirmed the behavior for prepared statements after a schema change at the last multi-tenant team meeting with signoff from @jeffswenson so going to merge this.

bors r=otan

@rafiss rafiss force-pushed the prepared-stmt-session-migration branch from a1477d2 to ad02cf5 Compare February 23, 2022 02:02
@craig
Copy link
Contributor

craig bot commented Feb 23, 2022

Canceled.

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 23, 2022

bors r=otan

Copy link
Collaborator

@jaylim-crl jaylim-crl left a comment

Choose a reason for hiding this comment

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

I believe this will fail:

t.Run("prepared_statements", func(t *testing.T) {
pgURL, cleanup := sqlutils.PGUrl(
t,
tenant.SQLAddr(),
"TestShowTransferState-errors-prepared_statements",
url.UserPassword(security.TestUser, "hunter2"),
)
defer cleanup()
conn, err := gosql.Open("postgres", pgURL.String())
require.NoError(t, err)
defer conn.Close()
// Use a dummy prepared statement.
stmt, err := conn.Prepare("SELECT 1 WHERE 1 = 1")
require.NoError(t, err)
defer stmt.Close()
var errVal, sessionState, sessionRevivalToken gosql.NullString
err = conn.QueryRow("SHOW TRANSFER STATE").Scan(&errVal, &sessionState, &sessionRevivalToken)
require.NoError(t, err)
require.True(t, errVal.Valid)
require.Equal(t, "cannot serialize a session which has portals or prepared statements", errVal.String)
require.False(t, sessionState.Valid)
require.False(t, sessionRevivalToken.Valid)
})

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @jaylim-crl and @rafiss)


pkg/sql/types/types.go, line 1746 at r5 (raw file):

// messages
//and also to produce the output of SHOW CREATE.

nit: typo here?

@jaylim-crl jaylim-crl self-requested a review February 23, 2022 03:33
@craig
Copy link
Contributor

craig bot commented Feb 23, 2022

Build failed (retrying...):

Copy link
Collaborator Author

@rafiss rafiss left a comment

Choose a reason for hiding this comment

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

ah, whoops. fixing

bors r-

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @jaylim-crl)


pkg/sql/types/types.go, line 1746 at r5 (raw file):

Previously, jaylim-crl (Jay Lim) wrote…

// messages
//and also to produce the output of SHOW CREATE.

nit: typo here?

fixed

@craig
Copy link
Contributor

craig bot commented Feb 23, 2022

Canceled.

@rafiss rafiss force-pushed the prepared-stmt-session-migration branch from ad02cf5 to 762f214 Compare February 23, 2022 04:29
Copy link
Collaborator Author

@rafiss rafiss left a comment

Choose a reason for hiding this comment

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

@jaylim-crl i edited that test, in case you want to take a look

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @jaylim-crl)

@otan
Copy link
Contributor

otan commented Feb 23, 2022

do you think this is causing the TestShowTransferState/errors/prepared_statements flake?

edit: nvm i see it is done above

Copy link
Collaborator

@jaylim-crl jaylim-crl left a comment

Choose a reason for hiding this comment

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

@jaylim-crl i edited that test, in case you want to take a look

Thanks. The test LGTM.

Reviewed 2 of 2 files at r1, 2 of 2 files at r2, 4 of 4 files at r3, 13 of 16 files at r4, 4 of 4 files at r6, 3 of 3 files at r7, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @rafiss)

This will allow us to more easily call into the code to prepare
statements when deserializing.

Release note: None
After the recent refactor for deserialize_session, it no longer needs to
be exposed.

Release note: None
Release note (sql change): The crdb_internal.serialize_session and
crdb_internal.deserialize_session now can handle prepared statements.
When deserializing, any prepared statements that existed when the
session was serialized are re-prepared. It is an error to re-prepare a
statement if the current session already has a statement with that name.
A schema change can make an existing prepared statement invalid. Rather
than returning an error when deserializing that invalid statement, now
the error will be returned only when trying to use the statement. This
makes a session migration even more transparent to the end user.

Release note: None
@rafiss rafiss force-pushed the prepared-stmt-session-migration branch from 762f214 to dda2fa9 Compare February 23, 2022 18:18
@rafiss
Copy link
Collaborator Author

rafiss commented Feb 23, 2022

tftrs!

bors r=otan

@craig
Copy link
Contributor

craig bot commented Feb 23, 2022

Build failed (retrying...):

@craig
Copy link
Contributor

craig bot commented Feb 23, 2022

Build failed:

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 23, 2022

the failures all seem to be flakes as far as i can tell..

bors r=otan

@craig
Copy link
Contributor

craig bot commented Feb 23, 2022

Build failed:

@rafiss
Copy link
Collaborator Author

rafiss commented Feb 23, 2022

yet another flake..

bors r=otan

@craig
Copy link
Contributor

craig bot commented Feb 23, 2022

Build succeeded:

@otan
Copy link
Contributor

otan commented Feb 23, 2022

congrats on winning the CI lottery!

@rafiss rafiss deleted the prepared-stmt-session-migration branch February 24, 2022 18:13
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.

sql: support prepared statements in {de}serialize_session
5 participants