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

PostgreSQL provider don't cast bigint PKs to text #35162

Merged
merged 14 commits into from Apr 17, 2020

Conversation

espinafre
Copy link
Contributor

@espinafre espinafre commented Mar 18, 2020

This PR is instead of botched #34780 (because of my mistakes with git merging/rebasing); please see the whole discussion there. In addition, a test case for updating tables with positive, zero, negative PKs; I couldn't find a way to test if the queries are being sent to the PostgreSQL backend as designed from within the testing framework. @elpaso , @m-kuhn , is this mergeable? I'm hoping to backport this in time for the next 3.10 and 3.12 point releases.

Fixes #34077
Partially fixes #34264

@github-actions github-actions bot added this to the 3.14.0 milestone Mar 18, 2020
Copy link
Member

@m-kuhn m-kuhn left a comment

Choose a reason for hiding this comment

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

It looks generally good to me, thanks.
I can imagine that adding tests for what's sent to the db is hard to do, so I'm good with sticking to functional tests and trusting your performance tests (and hoping no regressions are introduced for the latter).

src/providers/postgres/qgspostgresconn.cpp Show resolved Hide resolved
tests/src/python/test_provider_postgres.py Outdated Show resolved Hide resolved
tests/src/python/test_provider_postgres.py Outdated Show resolved Hide resolved
@elpaso
Copy link
Contributor

elpaso commented Mar 18, 2020

LGTM, the test coverage on PG is pretty good, so I guess that if the tests are passing we should not expect regressions.

@espinafre
Copy link
Contributor Author

Travis is still choking on formatting, it is as if it hasn't seen ad8f89b . Locally running ctest -V -R qgis_indentation results in success.

@m-kuhn
Copy link
Member

m-kuhn commented Mar 18, 2020

See https://github.com/qgis/QGIS/blob/master/.github/CONTRIBUTING.md#contributing-to-qgis for some hints how to get your code formatted automatically

@espinafre
Copy link
Contributor Author

I've ran prepare-commit.sh before pushing the C++ code, but I think I missed it when adding the test code, thanks. What can I do about the failed qgis_sip_uptodate test? It passes when I run locally with ctest -V -R qgis_sip_uptodate

@espinafre
Copy link
Contributor Author

This is the full output of my local ctest -v -R qgis_sip_uptodate (which fails on Travis):

UpdateCTestConfiguration  from :/home/jose/sw/qgis/QGIS/build-master/DartConfiguration.tcl
Parse Config file:/home/jose/sw/qgis/QGIS/build-master/DartConfiguration.tcl
 Add coverage exclude regular expressions.
 Add coverage exclude: /CMakeFiles/CMakeTmp/
SetCTestConfiguration:CMakeCommand:/usr/bin/cmake
UpdateCTestConfiguration  from :/home/jose/sw/qgis/QGIS/build-master/DartConfiguration.tcl
Parse Config file:/home/jose/sw/qgis/QGIS/build-master/DartConfiguration.tcl
Test project /home/jose/sw/qgis/QGIS/build-master
Constructing a list of tests
Done constructing a list of tests
Updating test list for fixtures
Added 0 tests to meet fixture requirements
Checking test dependency graph...
Checking test dependency graph end
test 577
    Start 577: qgis_sip_uptodate

577: Test command: /home/jose/sw/qgis/QGIS/tests/code_layout/test_sipfiles_uptodate.sh
577: Test timeout computed to be: 1500
1/1 Test #577: qgis_sip_uptodate ................   Passed   85.44 sec

The following tests passed:
        qgis_sip_uptodate

100% tests passed, 0 tests failed out of 1

Total Test time (real) =  85.46 sec

@m-kuhn
Copy link
Member

m-kuhn commented Mar 18, 2020

I've ran prepare-commit.sh before pushing the C++ code,

You need to run it before committing (it will only work on uncommitted files to save some time).
Does ./scripts/sipify_all.sh modify files?

@espinafre
Copy link
Contributor Author

espinafre commented Mar 18, 2020

I've ran prepare-commit.sh before pushing the C++ code,

You need to run it before committing (it will only work on uncommitted files to save some time).
Does ./scripts/sipify_all.sh modify files?

Only testdata/untracked files. After running it, git status gives:

On branch pg_bigint_pk_no_cast
Your branch is up to date with 'origin/pg_bigint_pk_no_cast'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   python/plugins/processing/tests/testdata/custom/circular_strings.gpkg
        modified:   python/plugins/processing/tests/testdata/custom/multi_polys_with_empty_geoms.gpkg
        modified:   python/plugins/processing/tests/testdata/custom/pol.gpkg
        modified:   python/plugins/processing/tests/testdata/expected/merged_pol.gpkg
        modified:   python/plugins/processing/tests/testdata/expected/multi_polys_non_null_one_empty.gpkg
        modified:   python/plugins/processing/tests/testdata/expected/results_remove_null_geometries.gpkg
        modified:   tests/testdata/analysis/dem.tif.aux.xml
        modified:   tests/testdata/analysis/slope.tif.aux.xml
        modified:   tests/testdata/control_images/expected_raster_linedensity/linedensity_testcase1.tif.aux.xml
        modified:   tests/testdata/control_images/expected_raster_linedensity/linedensity_testcase2.tif.aux.xml
        modified:   tests/testdata/control_images/fillNoData/fillnodata_testcase1.tif.aux.xml
        modified:   tests/testdata/control_images/fillNoData/fillnodata_testcase2.tif.aux.xml
        modified:   tests/testdata/control_images/fillNoData/fillnodata_testcase3.tif.aux.xml
        modified:   tests/testdata/curved_polys.gpkg
        modified:   tests/testdata/points_gpkg.gpkg
        modified:   tests/testdata/zonalstatistics/raster.tif.aux.xml
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        patch
        python/analysis/auto_additions/qgsgeometrycheck.py.temp
        python/core/auto_additions/qgis.py.temp
        python/core/auto_additions/qgsabstractdatabaseproviderconnection.py.temp
        python/core/auto_additions/qgsabstractgeometry.py.temp
        python/core/auto_additions/qgsauthmanager.py.temp
        python/core/auto_additions/qgsdataitem.py.temp
        python/core/auto_additions/qgsdatasourceuri.py.temp
        python/core/auto_additions/qgsdefaultvalue.py.temp
        python/core/auto_additions/qgsdxfexport.py.temp
        python/core/auto_additions/qgseditformconfig.py.temp
        python/core/auto_additions/qgsfieldproxymodel.py.temp
  <... snip ...>

@m-kuhn
Copy link
Member

m-kuhn commented Mar 18, 2020

Ah wait, that remaining thing seems to be something that changed on master meanwhile. The test has a weird behavior with respect to comparing "master merged into pr" with plain "pr".
Can you do a rebase on latest master locally again and force push?

git fetch upstream
git rebase upstream/master
git push -f

@espinafre
Copy link
Contributor Author

Ah wait, that remaining thing seems to be something that changed on master meanwhile. The test has a weird behavior with respect to comparing "master merged into pr" with plain "pr".
Can you do a rebase on latest master locally again and force push?

git fetch upstream
git rebase upstream/master
git push -f

Done. Let's see how Travis likes this, thank you for the tip.

@espinafre
Copy link
Contributor Author

Travis failed the same test...

@espinafre
Copy link
Contributor Author

I've done a make clean and re-ran ./scripts/sipify_all.sh, which made the change in commit 6767395; this is what I just pushed.

@espinafre
Copy link
Contributor Author

Now another test failed on Travis, but passed locally: PyQgsPostgresRasterProvider. I've got no idea why.

@espinafre
Copy link
Contributor Author

Did nothing this time, just fetched upstream/master, rebased against it, and pushed -f, according to @m-kuhn instructions. The previous failing test in Travis still passes locally (PyQgsPostgresRasterProvider).

@nyalldawson
Copy link
Collaborator

If you really want to test this fully (and I would strongly suggest you do), then you need to implement the ProviderTestCase in a class which uses a bigint primary key.

Checkout TestPyQgsPostgresProviderCompoundKey in test_provider_postgres.py for a template on how to do this

@espinafre
Copy link
Contributor Author

If you really want to test this fully (and I would strongly suggest you do), then you need to implement the ProviderTestCase in a class which uses a bigint primary key.

Checkout TestPyQgsPostgresProviderCompoundKey in test_provider_postgres.py for a template on how to do this

Hi, don't you think that the methods testPktUpdateBigintPk and testPktUpdateBigintPkNonFirst that I wrote in 0853029 are enough? Those exercise loading and saving features with bigint PKs, for a table with an ordinary bigint pk and another table whose PK is not the first one defined.

@nyalldawson
Copy link
Collaborator

Hi, don't you think that the methods testPktUpdateBigintPk and testPktUpdateBigintPkNonFirst that I wrote in 0853029 are enough? Those exercise loading and saving features with bigint PKs, for a table with an ordinary bigint pk and another table whose PK is not the first one defined.

Depends how confident you want to be. If you implement the ProviderTestCase then you can 100% sleep at night knowing you're covered in all existing conceivable situations, and will also be automatically covered whenever new functionality is added to the providers...

@nyalldawson
Copy link
Collaborator

(just to clarify: the provider test class is a mega stress test. It throws thousands of edge cases at the provider to make sure they handle them correctly).

@espinafre
Copy link
Contributor Author

(just to clarify: the provider test class is a mega stress test. It throws thousands of edge cases at the provider to make sure they handle them correctly).

Thanks for the pointer, and for enlightening me as always, I'm working on it. Just subclassing the ProviderTestCase and adjusting the data source? Is there any requirements for the data source (geometry type for example)? Also, is there a need for one subclass for each kind of table (that is, with a single ordinary PK, with a PK which is not defined as the first field, with a composite PK in which at least one member is a bigint...)? Sorry for the torrent of questions, but you provoked it :D

@espinafre
Copy link
Contributor Author

I still cannot figure out why the test PyQgsPostgresRasterProvider fails on Travis but not on my own system (PostgreSQL 12 + postgisraster 3.0), neither on Azure.

@nyalldawson
Copy link
Collaborator

I still cannot figure out why the test PyQgsPostgresRasterProvider fails on Travis but not on my own system (PostgreSQL 12 + postgisraster 3.0), neither on Azure.

It's unrelated -- it fails randomly regardless of the PR

@nyalldawson
Copy link
Collaborator

Just subclassing the ProviderTestCase and adjusting the data source? Is there any requirements for the data source (geometry type for example)?

Yes - look at how "someDataCompound" is loaded in tests/testdata/provider/testdata_pg.sql. You need to load in the same reference data rows (but with the different primary key type). Everything from the "pk" field onward needs to stay the same.

If you want to also run the editing reference tests then you need to implement getEditableLayer in your test subclass. See TestPyQgsPostgresProvider.getEditableLayer for how this is done (basically it needs to drop the existing editable version of the table, then recreate it anew, since each test in the editable part of the test suite wants a clean copy of this table to work from, and it'll mangle it up during its tests.)

Also, is there a need for one subclass for each kind of table (that is, with a single ordinary PK, with a PK which is not defined as the first field, with a composite PK in which at least one member is a bigint...)

If they aren't already covered, then yes -- this would be very valuable! It's probably the biggest (only?) remaining gap in the test coverage of postgres provider.

@elpaso
Copy link
Contributor

elpaso commented Mar 20, 2020

I still cannot figure out why the test PyQgsPostgresRasterProvider fails on Travis but not on my own system (PostgreSQL 12 + postgisraster 3.0), neither on Azure.

It's unrelated -- it fails randomly regardless of the PR

I hoped it was fixed. Is it still flacky?

@roya0045
Copy link
Contributor

@elpaso a rebase should fix this, but now the azure build is bjorked.

@m-kuhn m-kuhn closed this Mar 21, 2020
@m-kuhn m-kuhn reopened this Mar 21, 2020
@espinafre
Copy link
Contributor Author

I've added a FeatureSourceTestCase subclass to the test cases, as instructed by @nyalldawson , with the getSource/getEditableLayer implemented. That's why it took so long, and it was good too, because I caught an omission that I corrected in my last "real" commit ( 742454b ).

I've noted on the method overrides (with TODO annotations) where the code diverges from the original classes, and why, in order to correct those issues in the future.

All those tests pass locally, on my machine, with PostgreSQL version 12.1 and LANG=en_US.UTF-8.

Is this mergeable?

@espinafre espinafre requested a review from m-kuhn April 16, 2020 17:08
@espinafre
Copy link
Contributor Author

espinafre commented Apr 16, 2020

I think @nyalldawson should take a look at the Python test ( d4672b0 ). Also, this should be backportable to 3.12 and 3.10 without issues. The github interface doesn't allow me to add @nyalldawson to the list of reviewers. @m-kuhn , can you do that? Thank you very much.

@elpaso
Copy link
Contributor

elpaso commented Apr 17, 2020

@espinafre we don't usually assign anything to anyone, unless we know for sure that the developer agreed.

Copy link
Member

@m-kuhn m-kuhn left a comment

Choose a reason for hiding this comment

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

It looks good to me as far as I can tell. It's not trivial to understand each change (but that's in the nature of this code, not related to your work), so I'll trust the tests and general good look.

Some minor code style requests and we are good to ship it in my opinion.

I would like to wait for one or two months with a backport to LTR to have some time for any eventual regression to be sorted out first.

src/providers/postgres/qgspostgresprovider.cpp Outdated Show resolved Hide resolved
src/providers/postgres/qgspostgresprovider.cpp Outdated Show resolved Hide resolved
src/providers/postgres/qgspostgresfeatureiterator.cpp Outdated Show resolved Hide resolved
src/providers/postgres/qgspostgresprovider.cpp Outdated Show resolved Hide resolved
@espinafre
Copy link
Contributor Author

Commit 9607570 addresses and incorporates all suggestions by @m-kuhn . Local tests still pass. Is backporting to 3.12 automatic?

@m-kuhn
Copy link
Member

m-kuhn commented Apr 17, 2020

Commit 9607570 addresses and incorporates all suggestions by @m-kuhn . Local tests still pass. Is backporting to 3.12 automatic?

👍

Now it is.

@espinafre
Copy link
Contributor Author

espinafre commented Apr 17, 2020

@espinafre we don't usually assign anything to anyone, unless we know for sure that the developer agreed.

@elpaso I've said "assigned to me" in jest, along the lines of "the teacher assigned homework to the students" :)

@espinafre
Copy link
Contributor Author

@m-kuhn Does the MXE build failure prevent the merge?

@elpaso
Copy link
Contributor

elpaso commented Apr 17, 2020 via email

@m-kuhn m-kuhn merged commit f48e1c8 into qgis:master Apr 17, 2020
@m-kuhn
Copy link
Member

m-kuhn commented Apr 17, 2020

Thanks @espinafre nice work!

@roya0045
Copy link
Contributor

@espinafre don't worry about MXE, the whole service seems to be having issues today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Squash! Remember to squash this PR, instead of merging or rebasing
Projects
None yet
6 participants