-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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 pg bigint pk not text #34780
Fix pg bigint pk not text #34780
Conversation
QGIS uses signed 64bit feature ids. Positive values for features from the data source and negative values for feature ids of new unsaved features. Where possible QGIS uses the actual key from the datasource, but for datasource that have wider keys (eg. full 64bit, bigint, strings, compound keys etc.), we remap the keys to positive features ids. See also #3036 |
Thanks for pointing that out. So, PktUint64 stays. The problem with forcing bigint/bigserial keys to PktFidMap is that QGIS casts those to text, generating queries such as:
This, on a table with currently 10 million records (polygons), takes 4+ seconds on a very robust PostgreSQL 12 server, with only a single user; when editing a . We chose to use bigserial for the id because we expect this table to grow larger than 2 billion records. With the changes in this PR, the generated queries are as follows:
|
I'm afraid that the only robust solution is to check at layer load time if the pk column contains any value <= 0 and use the pk map in that case. If the check passes, we can probably handle the signed pk as if it was an unsigned one. |
It should be possible to use aa pk map locally and still send the requests as integer. |
Yes, I'd think the main problem is the missing support for |
Server standalone bugfixes
Add missing attributes at QgsAttributeEditorContext creation.
Try to make PG raster test more robust
Adds the ability to set a temporal range for a project
Adds: @map_start_time: Start of the map's temporal time range (as a datetime value) @map_end_time: End of the map's temporal time range (as a datetime value) @map_interval: Duration of the map's temporal time range (as an interval value)
* MDAL 0.5.90 : support for custom Logger and 1D meshes * [FEATURE] [MESH] Support rendering of 1D meshes, see qgis/QGIS-Enhancement-Proposals#164 1D mesh consist of edges (edge is straight line segment with 2 vertices) and the data that is defined on either vertices or edges. Such data can be loaded by MDAL and rendered as mesh layer in QGIS.
This gives users control over where a callout should join to the label text. (Previously, you only had control over where the callout would join to the corresponding feature geometry). Choices include: - Closest point (previous behavior) - Label Centroid - Fixed corners: Top left/top right/bottom left/bottom right/etc Data defined control over the label anchor is also possible
Allows selection of an existing database table for a specific database provider connection (the provider must implement the connections API)
Regarding point 6, looking at the code it seems there is something wrong here: if I get it right,
if is for when the PK needs to be guessed. So, in case the PK is known from the URI it is always treated like a FID map and that is probably wrong, we should get the PK type in that case and act accordingly (but that would not be enough to solve your issue of course).
The other consideration is that given the way QGIS is implemented you cannot use negative keys outside the provider internals (i.e. a So, option 6 may work in a few cases (when there are no negative PKs in the existing table and there is a guarantee that other applications will never add rows with negative PKs to the table) and it has the "problem" of requiring an extra query to determine the presence of negative PKs at load time. Solution 7 may be more easy to implement and looks more robust, I think you should work on that one first, you should be able use the map even when you have negative IDs in the existing table. In any event, if you do want to continue work on this issue (which is of course very welcome) I think you should start adding a few failing test data cases to With a decent test bed it will be much easier to test any potential solution we can come up with. |
Other providers return an "invalid" col type from geometryColumnTypes let's keep it that way (for now)
Mssql connections api
Returns the correct version for the Proj library linked against the running PostGIS.
On PostgreSQL tables whose primary keys are of type bigint/bigserial, QGIS used to cast the primary keys to text, causing the database to do bigint::text castas and full table scans instead of using the indices, causing in turn slowness on updates and other queries. This fix creates a new QgsPostgresPrimaryKeyType, PktInt64. PostgreSQL don't know about unsigned types, so the PK type PktUint64 loses sense. Knowing that the PK is an integer type, QGIS won't cast it to text anymore, thus enabling the correct use of database indices.
… into fix_pg_bigint_pk_not_text
PostgreSQL bigint primary keys are no longer cast to text on queries/updates. Internally we keep a FID map between the real database value and the internal QGIS feature ID. Thus, we preserve the QGIS semantics of using negative FIDs for newly added features, while still allowing users to edit attributes whose PKs are bigint non-positive.
Following @elpaso 's recommendations, I've gone with @m-kuhn and @jef-n idea, which is to treat int8 keys as fidmaps internally, but sending those values to the DBMS as bare values, without quoting or casting them to text. My preliminary test went very well, as I could edit fields with both positive and negative IDs, and they were sent to the DBMS as they were originally; also, because we are using the existing fidmap mechanism, we don't have clashes with QGIS internal FID handling. Looks very good to me! Now I will finish my homework (assigned by @elpaso ) and write those formal tests. Thank you so much! |
I shouldn't have rebased my branch before merging, right?... |
Thanks for the update. Promosing! There is nothing wrong about rebasing per se. But here, something seems to have gone wrong. What I would do: Start a new branch from QGIS master and cherry-pick your commits onto it E.g.
Fingers crossed PS: |
That rebase looks wrong. |
@roya0045 , yes, it does. This is what I did:
and that's how it got so messed up. |
@espinafre why didn't you just |
@roya0045 because I hadn't thought of that, dumb me :D I'll do that next time, thanks for the tip! |
Please see #35162 instead; it contains only the changes that fixes the bug, without the whole merge/rebase mess. |
On PostgreSQL tables whose primary keys are of type bigint/bigserial,
QGIS used to cast the primary keys to text, causing the database to do
bigint::text castas and full table scans instead of using the indices,
causing in turn slowness on updates and other queries.
This fix creates a new QgsPostgresPrimaryKeyType, PktInt64. PostgreSQL
don't know about unsigned types, so the PK type PktUint64 loses sense.
Knowing that the PK is an integer type, QGIS won't cast it to text
anymore, thus enabling the correct use of database indices.
Fixes #34077