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

Raise exception by default in expression_to_value #60

Merged
merged 8 commits into from
Aug 28, 2024
Merged

Conversation

xiaoyu-meng-mxy
Copy link
Collaborator

The Error we saw is here

The user passes in an sqglot.exp.In expression and by default it returns the name of that In clause. This silently fallback is hard to debug so we want to raise an exception instead.

Automatically convert the expression to string instead of return the name also seems not good because I guess the assumption here is a variable can only be int, float or str. If we end up parsed out an expression, it's something wrong.

@barakalon

@xiaoyu-meng-mxy
Copy link
Collaborator Author

Looking into the utf8 error in the tests 😕

@xiaoyu-meng-mxy
Copy link
Collaborator Author

Okay I guess for now utf8mb4_0900_ai_ci is the by default client charset

# Sqlglot by-default runs `SET NAMES 'utf8mb4'` if no charset specified, which removes COLLATE settings
# See https://github.com/sqlalchemy/sqlalchemy/discussions/7858
await conn.execute(
text("SET NAMES 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci'")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this is very nasty :(

setup.py Outdated
@@ -20,7 +20,7 @@
"dev": [
"aiomysql",
"mypy",
"mysql-connector-python",
"mysql-connector-python<9.0.0",
Copy link
Collaborator Author

@xiaoyu-meng-mxy xiaoyu-meng-mxy Aug 28, 2024

Choose a reason for hiding this comment

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

I believe there is a behavior change for the default collation ("SET NAMES 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci' was added while making a new connection)

Was trying to fix it in https://github.com/kelsin/mysql-mimic/pull/60/files/cd22920bbe455bc711d6c601d80fc17c40e5a2f9 but failed (it can work in python >= 3.9 but failed in python 3.7, probably because it is using mysql-connector-python 8.0 for python 3.7 but 9.0 for python 3.11

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Another issue combined with the above is sqlalchemy set SET NAMES 'utf8mb4' on connection, which removed that COLLATE which means we need special handling in testing for sqlalchemy.

So, probably limit mysql-connector is the best way to resolve the issue 🫤

Copy link
Owner

Choose a reason for hiding this comment

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

We should avoid limiting mysql-connector. It implies mysql-mimic doesn't work with the latest version of mysql-connector.

Can we just change the expected collation in tests?
Or change the collation when connecting in tests?
https://dev.mysql.com/doc/connector-python/en/connector-python-connectargs.html
https://github.com/kelsin/mysql-mimic/blob/main/tests/conftest.py#L210
And I think you can set connect args in the sqlalchemy URL

Copy link
Collaborator Author

@xiaoyu-meng-mxy xiaoyu-meng-mxy Aug 28, 2024

Choose a reason for hiding this comment

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

I see, it makes sense!

Going to run the set names/collate query on each of the connection

@@ -60,4 +60,4 @@ def expression_to_value(expression: exp.Expression) -> Any:
return True
if expression.name == "OFF":
return False
return expression.name
raise ValueError(f"Unexpected expression: {expression}")
Copy link
Owner

Choose a reason for hiding this comment

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

We should raise a https://github.com/kelsin/mysql-mimic/blob/main/mysql_mimic/errors.py#L44

Sometimes I'll go and try to find an appropriate error code here: https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html

But other times I give up and just use the default.

In this case, I think MySQL allows query expressions here: https://dev.mysql.com/doc/refman/8.0/en/set-variable.html

So maybe we throw some kind of "not supported yet" error, like this: https://github.com/kelsin/mysql-mimic/blob/main/mysql_mimic/session.py#L521

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah this makes a lot of sense.

I did not go to https://dev.mysql.com/doc/refman/8.0/en/set-variable.html and check expression is allowed

setup.py Outdated
@@ -20,7 +20,7 @@
"dev": [
"aiomysql",
"mypy",
"mysql-connector-python",
"mysql-connector-python<9.0.0",
Copy link
Owner

Choose a reason for hiding this comment

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

We should avoid limiting mysql-connector. It implies mysql-mimic doesn't work with the latest version of mysql-connector.

Can we just change the expected collation in tests?
Or change the collation when connecting in tests?
https://dev.mysql.com/doc/connector-python/en/connector-python-connectargs.html
https://github.com/kelsin/mysql-mimic/blob/main/tests/conftest.py#L210
And I think you can set connect args in the sqlalchemy URL

@xiaoyu-meng-mxy xiaoyu-meng-mxy merged commit 18e6587 into main Aug 28, 2024
7 checks passed
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.

2 participants