-
Notifications
You must be signed in to change notification settings - Fork 23
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
Fix negative fractional of seconds #32
base: master
Are you sure you want to change the base?
Conversation
This created a non conforming interval such as 'P0000Y00M-12DT-13H-02M-39.-215749S'. This would not pass validation and would lead to a crash.
I'm not sure if this will be merged anymore by anyone, but the commit as it stands is not really useful - it's not even clear if it fixes anything, because the input looks like it should be invalid, at least at first sight.. A test case would be essential, and maybe you can explain (or show in the test case) how such timestamps can even occur, because I have a hard time figuring out how that would happen in normal operation. |
@sjamaan The contrib docs seem outdated and I cannot get the tests to run, so I'm not going to write one, sorry. But this is a really simple problem. If you have an interval with negative microseconds, the code on line 101 ( So in short, I can have an interval with negative microseconds, save it to the database successfully but then during retrieval and deserialization from the DB it will crash due to the cast to string hack that didn't realize that microseconds can be negative. If this project is not actively maintained then whoever owns it should consider handing it over to something like https://jazzband.co/. |
It looks like your entire interval is negative. But it's not just microseconds that are disallowed by the ISO syntax. AFAICT the BNF simply doesn't allow for negative intervals at all. Adjusting it like in your commit looks like it would produce an incorrect result which means the output doesn't match the input. I can't imagine a situation where you'd want that. In such a case, it would be better to strip the microseconds from your input. Ideally, in this library, either the deserialization should be changed so that it can handle negative intervals properly (which is probably possible, perhaps by encoding negative/positive in a separate value or by using a different parser), or at worst the value should be rejected at input. Anyway, like I said I'm not using this library anymore myself, so I'll leave it to someone from Code Yellow to decide what to do. Your suggestion to "donate" it to Jazz Band sounds good. @abzainuddin could you look into this? |
Yes, that's correct, but I'm just giving an example man. You can repro it with something like
Yes, but this library explicitly does not really conform to the standard, neither does So what I'm proposing with this PR is a localized fix to a localized hack in the first place, that actually makes this work as it was originally intended. If you want to propose a bigger rewrite then that's another story. |
Sure. But something like Intuitively, normalization makes more sense than mixing and matching positive and negative numbers, although that is allowed, even in Postgres durations (I guess you couldn't do that for days and months, and there may be semantic issues with doing it for the smaller values too - I haven't really thought that through).
I had forgotten all about that, sorry for the unnecessary derailment of the conversation!
IMO, that's the wrong approach - the idea is that this library should faithfully store what you pass in (modulo any normalizations), and return it as well (most of the test suite is about ensuring that values survive DB roundtrips). It might be an edge case for you in your use case, but in general, hacking around it would be a bit broken. Now, I fully admit using the "ISO representation with extensions" is also a bit of a hack to make parsing easy, but I always approached the design of the library to be fully correct when viewed "from the outside".
It looks like the parser simply interprets the seconds as a floating point number, so your patch might even be correct as it stands. I'm not sure what would happen if the seconds are zero or positive, though. I suspect it would get parsed as a positive number then, which would be incorrect. Like I said, it really needs some tests. |
Sure, but This is clearly caused by somebody overlooking that when implementing the logic in Futhermore, you can have intervals generated on the postgres side (calculated columns) and the
Actually, it's not even an edge case, it's impossible according to postgres specification: https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-INTERVAL-INPUT It only stores months, days and microseconds, which means that postgres will never give me an interval where seconds are positive and microseconds negative. Which makes the fix 100% safe. I feel like I have now explained the problem in enough detail. As I said, I can't run tests and unfortunately I don't have time to debug why. If you want to expand the PR with some tests coverage, please do so, contributions welcome. |
This created a non conforming interval such as
P0000Y00M-12DT-13H-02M-39.-215749S
. This would not pass validation and would lead to a crash.