-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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
[5.5] Better precision support on datetime columns #22122
[5.5] Better precision support on datetime columns #22122
Conversation
939875f
to
fe41f82
Compare
Actually, mssql doesn't take 0 as default precision. @sisve knows about it. |
@Dylan-DPC Yup, SQL Server does use a default of 7 fractional seconds on Note however I'm not changing anything related to that - no existing behavior is being changed, both It indeed won't allow you to use an explicit precision of 0 for SQL Server, but this leads us to the inconsistencies previously discussed - in fact, |
I imagine that the migration system would have a much easier time figuring out what the developer expects if the parameters had a default value of null, instead of 0. Null would be the "meh, don't care, surprise me" setting where 0 is the "I want precision of 0". I see no problems with changing the default value for precisions from 0 to null for all datetime types, but that is out-of-scope for this PR. What I really want is the keep the backward compatibility for things like Regarding the secret ritualistic knowledge I possess about SQL Server; the default precision for a time(x) is 7. The current implementation will block users from creating a So, the only thing I want to change about this PR is the default value for $precision to null. You linked the SQL 92 grammar, but it's not containing the Syntax Rules. These are important because it shows that the default precision of time and datetime differs. That's totally not relevant to this PR, but interesting none the less.
Source: SQL92, section 6.1 <data type>, Syntax rules |
Hey, I just realized, this PR is named to include all datetime fields so it's not at all out-of-scope to change the default value for them all to null. I was reading the diff and thinking it was only focusing on the time/timeTz methods. This means we can solve most things. Hah! |
These huge PRs with tiresomely long explanations are very hard to find the time to manage. We need good TLDR. |
@sisve What about moving that later requirement into a separated PR? Just to make this one "reviewable" - it has already a reasonable amount of lines changed to review. 😅 With this PR we will still be lacking support for specifying I think it's still worth opening a new internals topic on this subject to discuss and summarize all the existing inconsistencies, their possible solutions, impacts, etc. What do you think? 😃 @taylorotwell I'll be providing a TLDR section to the PR description ASAP. 😉 |
TL;DR: Add support for custom precision when using |
Proposal
This was split from #22004.
Currently we have precision support on
dateTime()
,dateTimeTz()
,timestamp()
andtimestampTz()
columns. However, the SQL-92 standard (ANSI X3.135-1992 and ISO/IEC 9075:1992) allows us to also specify precisions on time columns and except for SQLite (which does not support columns precisions at all) all other database drivers does support them.*This was recently requested in #22048 where OP was thinking it was already there. I'm proposing that we start honoring the given precision on both
time()
andtimeTz()
columns so the framework follow the usage expectation.* MySQL added this to TIME, DATETIME and TIMESTAMP in 5.6.4
Implementation
This time I'm just changing the
time()
andtimeTz()
methods behavior when a precision is explicitly given, so it should match the developer expectation. Previously I was doing more, but I left the inconsistencies changes to a future work. This was made this way to make it easier to get it accepted and even be pushed to 5.5 if desired.Some related code simplifications were done with no behavior changes - this was done to make things easier to understand. I've also rewritten related tests and I increased the test suite's testability on this subject. To ease reviewing code changes I've made a detailed summary below.
Changes
I'm targeting this for 5.5 first just because I'm not sure where it would be desirable since it's a feature that would be applied only to new installations and just adds a non-existing behaviour that matches the usage expectation. If this would be acceptable just for 5.6, let me know and I'll rebase it accordingly ASAP. 😉
Code
Illuminate\Database\Schema\Blueprint
$precision
argument to the missingtimeTz()
method.Illuminate\Database\Schema\Grammars\MySqlGrammar
typeTime()
to honor the given precision.typeTimeTz()
totypeTime()
.typeTimestamp()
implementation. (no behavior change)Illuminate\Database\Schema\Grammars\PostgresGrammar
typeTime()
andtypeTimeTz()
methods to honor the given precision.typeTimestamp()
andtypeTimestampTz()
implementations. (no behavior change)Illuminate\Database\Schema\Grammars\SQLiteGrammar
typeDateTimeTz()
totypeDateTime()
.typeTimeTz()
totypeTime()
.typeTimestamp()
implementation. (no behavior change)typeTimestampTz()
totypeTimestamp()
.Illuminate\Database\Schema\Grammars\SqlServerGrammar
typeTime()
to honor the given precision.typeTimeTz()
totypeTime()
.typeTimestamp()
andtypeTimestampTz()
implementation. (no behavior change)Tests
22 new tests, 34 new assertions, 10 unneeded assertions removed
Illuminate\Tests\Database\DatabaseMySqlSchemaGrammarTest
Illuminate\Tests\Database\DatabasePostgresSchemaGrammarTest
Illuminate\Tests\Database\DatabaseSQLiteSchemaGrammarTest
Illuminate\Tests\Database\DatabaseSqlServerSchemaGrammarTest
testAddingTimeWithPrecision()
,testAddingTimeTzWithPrecision()
,testAddingDateTimeWithPrecision()
,testAddingDateTimeTzWithPrecision()
,testAddingTimestampWithPrecision()
andtestAddingTimestampTzWithPrecision()
methods. Existing MySQL and SQL Server tests got rearranged.testAddingTimestampWithDefault()
,testAddingTimestampTzWithDefault()
,testAddingTimestamps()
andtestAddingTimestampsTz()
methods - there's no need to test this twice.Illuminate\Tests\Database\DatabaseSchemaBlueprintTest
testDefaultCurrentTimestamp()
to fix the PostgreSQL test. It was usingCURRENT_TIMESTAMP(0)
intypeTimestamp()
but this was never needed - if you specify a precision on the column you aren't required to also declare it on the datetime function.