Skip to content

Change parser to allow SET SQL_AUTO_IS_NULL=0, NAMES utf8#3776

Closed
arthurnn wants to merge 1 commit intovitessio:masterfrom
arthurnn:arthurnn/support_charset_and_vars_on_set
Closed

Change parser to allow SET SQL_AUTO_IS_NULL=0, NAMES utf8#3776
arthurnn wants to merge 1 commit intovitessio:masterfrom
arthurnn:arthurnn/support_charset_and_vars_on_set

Conversation

@arthurnn
Copy link
Copy Markdown
Contributor

Before this change, the parser would allow SET VAR=VALUE or SET NAMES charsetvalue, but would not allow both combined.
MySQL allows them and in fact our Ruby on Rails app connection driver
sends that to each connection.

This fixes the parser to allow to set a var and a charset in the same statement.

See SQL_AUTO_IS_NULL=0 was already added to the executor in another PR. So no need to add that variable option there.

cc @vmg @bryanaknight @jaredonline as this is related to #3611

Before this change the parser would allow `SET VAR=VALUE` or `SET
NAMES charsetvalue`, but would not allow both combined.
MySQL allows them, and in fact our Ruby on Rails app connection diver
sends that to each connection.

This fixes the parser to allow to set a var an a charset in the same statment.

Signed-off-by: Arthur Neves <arthurnn@gmail.com>
}
if len(vals) > 0 && charset != "" {
return &sqltypes.Result{}, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected key values and charset, must specify one")
}
Copy link
Copy Markdown
Contributor Author

@arthurnn arthurnn Mar 23, 2018

Choose a reason for hiding this comment

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

This check was there before to catch a charset and var change when they happened in the same statement. Now that is handled fine by the parser, so we can remove the check.
cc @bbeaudreault as you added to initial check in here 5faaac2

@arthurnn
Copy link
Copy Markdown
Contributor Author

I compiled and tested this locally:

mysql> SET SQL_AUTO_IS_NULL=0, NAMES 'utf8';
Query OK, 0 rows affected (0.00 sec)

mysql> SET NAMES 'utf8';
Query OK, 0 rows affected (0.00 sec)

mysql> SET SQL_AUTO_IS_NULL=0;
Query OK, 0 rows affected (0.00 sec)

mysql> SET SQL_AUTO_IS_NULL=0, wait_timeout=1;
Query OK, 0 rows affected (0.01 sec)

Seems like it works

Copy link
Copy Markdown
Collaborator

@vmg vmg left a comment

Choose a reason for hiding this comment

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

This looks great to me. Handling this on the parser is definitely the right approach. 👌

}, {
input: "set charset default",
output: "set ",
}, {
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 think it would make sense to modify Set.Format to print both the Exprs and the charset (if non-null) so that this test (and all the ones above it) would more clearly show that the parser is preserving the charset.
https://github.com/tinyspeck/vitess/blame/master/go/vt/sqlparser/ast.go#L579-L587


set_statement:
SET comment_opt update_list
SET comment_opt update_list ',' charset_or_character_set charset_value force_eof
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 don't think we should have a force_eof here since it seems to me it would allow anything after the character set, which is more lenient than I think we want this to be.

More generally I'm somewhat surprised this doesn't introduce grammar conflicts since the update_list is also a comma-separated set of expressions. As such, I don't off-hand see how the parser can figure out whether to continue processing the expressions as part of the update list as opposed to the character set case.

I suppose if it works, it works, but can you please confirm you don't get any shift-reduce or reduce-reduce conflicts when you build the grammar?

I do, however, think we should have a test case that shows the grammar won't parse this:
SET foo=1, NAMES 'utf8', bar=1

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.

I think there's a more generic way to fix this. Let me spin up a PR.

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.

❤️ @sougou

err: "sql_auto_is_null is not currently supported",
}, {
in: "set sql_auto_is_null = 0, names 'utf8'",
out: &vtgatepb.Session{Autocommit: true},
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.

We should probably have a test case of the form:

	}, {
 		in:  "set sql_auto_is_null = 0, character set ascii",
 		err: "unexpected value for charset: ascii",
 	}, {

@sougou
Copy link
Copy Markdown
Contributor

sougou commented Mar 23, 2018

The 'better' fix was more complicated than expected, but it should give us more runway for the SET statement: #3777.

@arthurnn
Copy link
Copy Markdown
Contributor Author

Closing this. #3777 ❤️ @sougou . awesome work

@arthurnn arthurnn closed this Mar 24, 2018
@arthurnn arthurnn deleted the arthurnn/support_charset_and_vars_on_set branch March 24, 2018 08:40
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.

4 participants