When upgrading a field / changing it's type using pgsql:changeField, it's impossible to make a field a serial, bigserial, or numeric. This appears to be because of confusion between the typecast that is required to do the data-conversion and the field-type we are creating. As is currently stands, pgsql:changeField() is forcing serial, bigserial, or numeric to be int.
We found this issue because of this contrib issue: #1657910: Field type update fails in PostgreSQL
Related to this, is that there should better logic around when we need to force explicit casting with a USING statement. It's not always required, and we shouldn't use it unless we need to.
Comment | File | Size | Author |
---|---|---|---|
#59 | 1668644-59.patch | 4.55 KB | poker10 |
#57 | 1668644.51.d7.patch | 4.62 KB | joseph.olstad |
#51 | 1668644.51.d7.patch | 4.62 KB | Island Usurper |
Comments
Comment #1
phayes CreditAttribution: phayes commentedAssigning this to myself to create a patch.
Comment #2
tim.plunkettCan you confirm that this is a bug in D8 as well?
Comment #3
Brandonian CreditAttribution: Brandonian commented@tim.plunkett, it appears so. Haven't actually tried it, but the same block of code appears in the D8 pgsql database driver, lines 519-521.
http://drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/lib/D...
Comment #4
phayes CreditAttribution: phayes commentedThere are two problems here
Line 543 shouldn't be using the
$typecast
variable as the target field typeLines 519 et al should have better logic on when we need to do any typecasting. Not all these types require a cast. Running the command "\dC" in postgres shell shows the matrix of which combination of field-types we can rely on to have automatic type-casting, and which ones need manual intervention.
Comment #5
phayes CreditAttribution: phayes commentedI'm just posting my research here as I go along, hope you folks don't mind...
If we want to figure out dynamically when we need to do the casting, we can use this query to get a list of all supported casts:
See http://www.postgresql.org/docs/9.1/static/catalog-pg-cast.html
Comment #6
chx CreditAttribution: chx commentedWow, amazing , someone working on postgresql! I very much like it. Thanks.
Comment #7
phayes CreditAttribution: phayes commentedSo, in the end, the problem ended by being far simpler than I had thought it was. Attached is a patch that fixes this. It's still untested (need to figure-out how to run simple-tests using postgres).
The basic problem was two fold:
1. Really confusing inline documentation, there is no need to "cast" anything...
2. What's really happening is that serial and bigserial do not exist when ALTERing a table, only when CREATEing one. So we need to cast them as integers then manually apply their sequence. Somehow numeric was using the same logic, which was what was causing problems.
This fix:
1. Cleans up inline documentation and variable names to be less confusing
2. Removes numerics being treated as integers (only serial and bigserial are not treated as inegeters)
Comment #8
phayes CreditAttribution: phayes commented[duplicate posting]
Comment #9
tim.plunkettSo this is the only change here, the rest is a variable rename? Fair enough.
I think the asterisks around only are unneeded. I'd swap the double quotes around serial for single quotes, and add them around int, or remove it from serail.
Comment #10
phayes CreditAttribution: phayes commented[duplicate posting]
Comment #11
phayes CreditAttribution: phayes commentedBah, sorry about all the double-posts. I was having crappy internet problems.
Comment #12
phayes CreditAttribution: phayes commentedAttached is an updated version with the requested changes. Still needs full testing.
Comment #13
phayes CreditAttribution: phayes commentedThis is proving really difficult to test. Without the patch all sorts of tests fail for me, so it's pretty much impossible to run tests against the patch...
Comment #14
tim.plunkettBut with them it does pass? Isn't that enough proof?
Comment #15
phayes CreditAttribution: phayes commentedNo, they both fail equally. :-(
Comment #16
phayes CreditAttribution: phayes commentedSo how should we go forward with this?
The situation is such
1. This is a bug in D7 and D8. The fix appears to work on both.
2. The current build of D8 appears to break unit tests all over the place when testing on postgres. These breakages are unrelated to this patch.
It seems to me that we cannot reasonably wait for all of postgres to work in D8 before accepting this patch, which is breaking people's live, in-production drupal sites in D7.
I propose one of two courses of action:
A. Apply this patch to D8 after more thorough hand-testing, even if unit tests break. Backport it to D7.
B. Apply this patch to D7. Wait for it's application to D8 until all D8 unit-tests pass under postgres.
Comment #17
chx CreditAttribution: chx commentedA.
If your unit tests are broken already, it won't get worse. However, regressing in D8 (ie B) would be.
Comment #18
Brandonian CreditAttribution: Brandonian commentedRe-rolled the patch from #11 and hand-tested. It seems to work for me. Marking as reviewed and tested.
Comment #19
catchDo the current schema tests we have fail in PostgreSQL without this patch applied? If not let's add the coverage here.
Comment #20
geaseI'm not sure it's a right place to post, but here's a backport of #18 to d7.
Comment #22
yoroy CreditAttribution: yoroy commentedComment #22.0
yoroy CreditAttribution: yoroy commentedUsing proper terminology
Comment #23
slippast CreditAttribution: slippast commentedThe D7 patch from #20 fixed the following problem with the Get Locations module, just an FYI:
Comment #24
milos.kroulik CreditAttribution: milos.kroulik commentedPatch from #20 works for me. Can this change to RTBC?
Comment #26
Island Usurper CreditAttribution: Island Usurper commentedWhere are the schema tests in D8, mentioned in #19? I was going to try to write a test, but I only found ConnectionTest, which uses a mock database connection. Are there tests for the various database drivers?
Comment #27
bzrudi71 CreditAttribution: bzrudi71 commentedRe #26, please see core/modules/system/src/Tests/Database/
Thanks!
Comment #28
bzrudi71 CreditAttribution: bzrudi71 commentedRe #26, please see core/modules/system/src/Tests/Database/
Thanks!
Comment #29
Island Usurper CreditAttribution: Island Usurper commentedOK, two files, one being just tests, which will fail when using PostgreSQL, and the other being the tests plus an updated version of #20 so that it applies to 8.0.x-dev.
Comment #30
Island Usurper CreditAttribution: Island Usurper commentedComment #33
Island Usurper CreditAttribution: Island Usurper commentedApply to head. Yay, asserting field characteristics doesn't remove the field any more. I should probably make a new issue for the wrong comment about precision and scale I found.
Comment #34
Island Usurper CreditAttribution: Island Usurper commentedCan't ever remember to change the status.
Comment #35
bzrudi71 CreditAttribution: bzrudi71 commentedNice, thanks @Island Usurper. Even if currently not used in core it's a nice addition for contrib and should help with the D8 upgrade path. I did testing with PostgreSQL and all tests pass, but it seems a bit odd to create 8000+ tables resulting in 25000+ tests for Schema?
Drupal\system\Tests\Database\SchemaTest 25774 passes
Comment #36
Island Usurper CreditAttribution: Island Usurper commentedYeah, I thought about that, @bzrudi71, but I eventually decided to go for completeness because I couldn't decide where "enough" was. If someone who is more familiar with testing wants to chime in to say, "We only need to make sure that one combination of precision and scale work. It's safe to assume the rest will too", that'd be great. I can certainly rewrite the patch that way, or someone else can jump in, too.
Comment #37
bzrudi71 CreditAttribution: bzrudi71 commented+1 for
:-)
Comment #38
Island Usurper CreditAttribution: Island Usurper commentedAlright, smaller test it is.
Comment #39
daffie CreditAttribution: daffie commentedThe patch looks good to me.
The only problem for me is the number of new tests. Almost 5700 new tests and 1900 table creations.
Comment #40
bzrudi71 CreditAttribution: bzrudi71 commentedYes, still way to much tests I think ;-)
Comment #41
daffie CreditAttribution: daffie commentedTalked to catch on IRC and his suggestion would be to limit the number of new tests to 1 or 2.
Comment #42
daffie CreditAttribution: daffie commentedComment #43
Island Usurper CreditAttribution: Island Usurper commentedTook out the different sizes for the int columns, and half of the "not null", "initial", and "default" variations. Now SchemaTest runs with 748 total passes.
Comment #44
bzrudi71 CreditAttribution: bzrudi71 commentedWe have currently 658 tests in Schema without patch:
Drupal\system\Tests\Database\SchemaTest 658 passes
with patch:
Drupal\system\Tests\Database\SchemaTest 748 passes
The test itself takes just a second or two to complete, so I no longer see a problem with the number of tests. Reviewed the patch but didn't find anything wrong.
+1 for RTBC.
Comment #45
daffie CreditAttribution: daffie commentedCan we rewrite this function so that it is a lot more compact and improve its readability.
Comment #46
Island Usurper CreditAttribution: Island Usurper commentedThe first two thirds are just setting up data structures for Schema API. I don't know that there's much that can be done there. It follows the same style and setup as other test functions in that class, so if you think this function is too verbose, maybe there should be a new issue to refactor more of the tests.
Comment #47
daffie CreditAttribution: daffie commentedUpdated and compacted SchemaTest::testSchemaChangeField().
Comment #48
bzrudi71 CreditAttribution: bzrudi71 commentedI think all concerns are addressed now and I found nothing obvious during a second review. RTBC and thanks all!
Comment #49
alexpottThis issue addresses a major bug and is allowed per https://www.drupal.org/core/beta-changes. Committed 6e51cc1 and pushed to 8.0.x. Thanks!
Tested using SQLite - no new fail introduced.
Fixed on commit
Comment #51
Island Usurper CreditAttribution: Island Usurper commentedHere is the patch from #47 ported to D7. I had to include a change assertFieldCharacteristics() that was in #29 because there is a change that hasn't been backported yet, but is necessary for this test to work. Basically, assertFieldCharacteristics() shouldn't drop the field it tests.
Should we find the issue that took care of that and make sure it gets properly backported before dealing with this?
Comment #57
joseph.olstadwake up testbot
Comment #58
poker10 CreditAttribution: poker10 at ActivIT s.r.o. commentedRerolled the patch (does not applied anymore).
Comment #59
poker10 CreditAttribution: poker10 at ActivIT s.r.o. commentedSorry, my mistake, wrong file.