-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat(lua): add legacy-float flag for Lua 5.1 number compatibility #6149
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review completed. 1 suggestion posted.
Comment augment review to trigger a new review at any time.
romange
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good. @dranikpg PTAL as well
| string flags = absl::GetFlag(FLAGS_default_lua_flags); | ||
|
|
||
| static_assert(ScriptParams{}.atomic && !ScriptParams{}.undeclared_keys); | ||
| static_assert(ScriptParams{}.atomic && !ScriptParams{}.undeclared_keys && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a weird assert, what does it check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the default values of parameters, but yeah its a little weird 😅
| } | ||
|
|
||
| const char* kFloatAsIntShas[] = { | ||
| "8c4dafdf9b6b7bcf511a0d1ec0518bed9260e16d", // django-cacheops |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have multiple scripts? I saw you changed only one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reused the same list of django-cacheops mentioned above. Only one of them has the same hash as the master branch. I guess the hashes can be used from previous versions, and my assumption is that we have to make these scripts work.
|
I think it's an ok solution. The core problem is around the following incompatibility against valkey: and I think we can solve it directly in |
|
specifically, I think you can do a fix in |
| string flags = absl::GetFlag(FLAGS_default_lua_flags); | ||
|
|
||
| static_assert(ScriptParams{}.atomic && !ScriptParams{}.undeclared_keys); | ||
| static_assert(ScriptParams{}.atomic && !ScriptParams{}.undeclared_keys && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the default values of parameters, but yeah its a little weird 😅
src/core/interpreter.cc
Outdated
| const char* code = enable ? kEnableLegacyFloat : kDisableLegacyFloat; | ||
| RunSafe(lua_, code, enable ? "@enable_legacy_float" : "@disable_legacy_float"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets store the state and run it only if it changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because this will decrease performance even for the normal path
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the implementation. Please take a look.
| // Valid flags are: | ||
| // - allow-undeclared-keys -> undeclared_keys=true | ||
| // - disable-atomicity -> atomic=false | ||
| // - legacy-float -> float_as_int=true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe it would've been easier if it was a global flag, as I assume that if someones uses it, he'll use it for all scripts... but this is cleaner of course this way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to use it per script
dranikpg
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should have a much smaller performance impact now, and is cleaner
| double num = token->value.number; | ||
| double intpart; | ||
| /* Check if legacy float mode is enabled via global variable */ | ||
| lua_getglobal(l, "__dfly_legacy_float__"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that now it's much cleaner. But I must ask @dranikpg @vyavdoshenko why not use lua_pushinteger unconditionally if the number is integer ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in other words, why do we need __dfly_legacy_float__ mode at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The flag preserves user choice. Scripts migrated from legacy Lua 4.1 can opt into legacy behavior, while new scripts keep Lua 5.4 semantics. Making it unconditional removes that flexibility.
If you insist on making it unconditionally, I will fix it, but in my opinion, it is better to save float behavior for future scripts.
Introduces a legacy-float script flag that makes cjson.decode compatible with Lua 5.1 behavior.
The core incompatibility:
Libraries like django-cacheops depend on this behavior.
Solution:
Patched lua_cjson.c to check a Lua global variable
__dfly_legacy_float__. When enabled, cjson.decode pushes integers instead of floats for whole numbers.Usage via script header:
Via command line (for all scripts):
Fixes: #6147