-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Skip re-querying geometry type for Oracle provider #34738
Conversation
This probably also fixes #34328 |
@@ -2614,6 +2614,15 @@ bool QgsOracleProvider::getGeometryDetails() | |||
return true; | |||
} | |||
|
|||
// Do not re-check geometry type if it is already known (f.e. when re-loading a project) | |||
if ( mRequestedGeomType != QgsWkbTypes::Unknown && mSrid > 0 ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMPORTANT: I'm not an expert/developer.
My impression is this code is executed once when we create or re-open an oracle layer (when opening a project). Not for a specific feature, but for the whole layer.
mDetectedGeomType is the type of geometry we've already chosen/found when creating a layer. So styling, labelling etc. is already set-up according to this geometry type.
When re-opening the layer again, this routine re-checks the type of geometry (and in oracle, which does not hold geometry type in meta-tables, this is an expensive action). And it is hard to say what would happen if geometry type would change say from polygon to point... all symbolisation/labelling settings will be partly incorrect/irrelevant.
If I'm not mistaken, I'm overwriting mDetectedGeomType with type which was found in previous sessions. So if a user has added a layer with type polygon, I would use polygon, if a user added a layer with line, I would use line etc.
Can you think of some use case/test I could try to test your version?
P.S. Regarding #34358 we actually are very happy that QGIS ignores the difference between polygon and multipolygon as these are all polygons in general (same symbolisation etc.).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one provider for each layer, created when you create the layer (open the project for instance).
mDetectedGeomType is the geometry detected from the database, mRequestedGeomType is the one specified by the user (specified in uri you could see on tooltip).
Can you think of some use case/test I could try to test your version?
You can have a table with mixed polygons and multipolygons and want to display only polygons. That's the way other providers work in QGIS, and that's the desired fix of the PR #34358.
P.S. Regarding #34358 we actually are very happy that QGIS ignores the difference between polygon and multipolygon as these are all polygons in general (same symbolisation etc.).
I understand your issue here. @SebastienPeillet It will indeed break the workflow of people relying on the fact that geomtype and multigeomtype are mixed now but I don't see a way to not break this with your PR. My guess is that you should have either 2 layers or convert to multi the single geometry with a view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you think of some use case/test I could try to test your version?
You can have a table with mixed polygons and multipolygons and want
to display only polygons.
mRequestedGeomType would be the type I chose when creating the layer, right? And unless I edit xml manually it will be one of the types which actually exist in the table (at the time of adding a layer).
When I'm overwriting mDetectedType with mRequestedGeomType I simply say "let's ASSUME the table still has the same geometry type". That is I assume table contents has not changed in principle (then I move a project to production environment that should always be the case).
Therefore unless table contents have changed considerably, mRequestedGeomType and mDetectedType should be the same?
Another example with polygon vs multipolygon. Say I chose polygon, so requestedtype is polygon. Now if I have estimated data on and the first fetched geometry from mixed type table is multipolygon - detectedtype would be multipolygon, should QGIS really start reshuffling configuration? That multipolygon could be one record in a million polygon table... In this case re-checking would be not only unnecessary, but even unwanted/harmful? Or am I missing something?
(You can enable row movement in Oracle and then rows could be moved/rowid changed impacting which are returned as first row even in the same db session)
P.S. The code you link to uses mRequestedType, so my proposed change should not have impact on that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is I assume table contents has not changed in principle
You cannot be sure, you could have added any geometry type to your table and you want to filter only the type you select at first. If detectedGeomType == requestedGeomType, filtering is not possible anymore.
the first fetched geometry from mixed type table is multipolygon - detectedtype would be multipolygon
Right! that's why I told you to try the GROUP BY. But I can't see a better solution when you use metadata
P.S. The code you link to uses mRequestedType, so my proposed change should not have impact on that?
You mean mRequestedGeomType, the impact will be the one described above, no filtering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could maybe skip the detection of geom type if estimated meta data is true and the mRequestedGeomType is set. And let the mDetectedGeomType to Unknow. So the filter on geometry will be enabled from featureiterator.
But we can't force mHasSpatialIndex and disable mSrid detection.
It should not break anything, hoping that I don't miss a corner case.
Does it sounds good to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree on skipping geom type testing when estimated meta data is true.
But SRID would have already been detected upon adding the layer. That is why I have a condition mSrid > 0. Why re-query?
Spatial index might be a separate issue (I'm ok with removing it from this PR and opening a new one specially for spacial index). The reason I'm setting it to true is that at least when using a view metadata shows there is no spatial index (as views do not have any indexes on them), but there actually is a spatial view on geometry table used in that view.
This index thing should probably be assumed to true when we're using a view, not a table.
Otherwise some other non trivial queries are done in loadField function which again slows down opening of project in QGIS Server (actually further/future idea is to skip loadField on project re-opening as well, as all fields are already saved in project file).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But SRID would have already been detected upon adding the layer. That is why I have a condition mSrid > 0. Why re-query?
Because it could be different from the one requested. When you add a layer to a project, you just add a configuration that point on a table, QGIS needs to check these parameters to be sure everything is fine and avoid issues later.
This is the way all providers are designed and I'm pretty sure that skipping all of this checks because of loading time won't be accepted and merged.
IMHO I think you should focus more on how to speed up the different request behind this checks instead of trying to modify QGIS. But maybe other developers won't feel the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SRID is fetched from metadata, so it's value will not change unless somebody actually decides to change data schema on-line. Therefore in normally designed system this should never happen.
I would say that QGIS should read all required metadata upon adding the layer, save it in the project and then simply use it (or refresh upon explicit request by the user). The only queries done on QGIS Server should be feature fetch queries. This would also increase all benchmarks of QGIS Server ;-)
But of course I'm not in a position to manage/rule here.
Therefore ok, I will only leave a code to skip geometry re-checking and will try to formulate further improvements in a separate PR (or should I first ask in developers mailing list?).
Thank you for your help!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that if you are willing to skip all check at layer loading (reading the project), you should ask on developers mailing list. I'm pretty sure people won't agree with this, but it's always good to have others opinion.
Thank you for your help!
You're welcome
@@ -2614,6 +2615,16 @@ bool QgsOracleProvider::getGeometryDetails() | |||
return true; | |||
} | |||
|
|||
// Do not re-check geometry type if it is already known (f.e. when re-loading a project) | |||
// and trust project data checkbox is enabled in project properties | |||
if ( QgsProject::instance()->trustLayerMetadata() && mRequestedGeomType != QgsWkbTypes::Unknown && mSrid > 0 ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This way the parameter will apply to all layers. I think a better way will be to have a per layer parameter setting in the layer uri. Look checkPrimaryKeyUnicity in postgres provider for instance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
„Trust layer“ option is on project level in QGIS GUI, so there is no way not to apply it to all layers. Or am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have to propagate it to the layer URI. Take a look on how it's done on checkPrimaryKeyUnicity in postgres provider for instance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I will try to understand how to do that.
But can you explain the idea why does it have to be done that way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For one - it's not appropriate to use QgsProject::instance() in providers or core library. This breaks QGIS server and other circumstances where multiple projects are loaded in QGIS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you suggest any other way to get the value of "Trust layer" option value?
Or copying the "Trust layer" value to a different level - namely layer - is the only way to go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can someone explain me, how I can add this code in mine qgis?
But can you explain the idea **why** does it have to be done that way?
to have a per layer parameter
|
I'm lost. There is no way to hand-pick layers where this option is on or off. Why add additional complexity which cannot be used in practice? If somebody will decide/want to move this option from project to layer level in GUI, maybe then this option will be saved in layer? Currently all layers will always be the same - all off or all on, then what is a point of per layer saving in this PR? My thinking comes from the maxima: less code is always better. |
I've checked the code in postgres provider: I do not understand how/when would this behave differently than current implementation in this PR of taking the value directly from project properties without copying it to multiple places/layers? P.S. The purpose of this PR is not to change the position/level of trust project option. |
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
What is the status of this? Should I just wait? |
Sorry, I forgot answering to you. Like I said before you can't access this parameter directly from project, because it has to be a per layer parameter. There is layers you want to trust and other you don't want to. |
The setting is on project level. There is no way you can specify which layer you trust or not. |
For now trust parameter:
Trust parameter is never accessed from any provider, and I think it will be better to continue this way. If I recall correctly, you want to avoid geometry type detection, so maybe we should add a @pblottiere @elpaso Any thoughts on this |
Just a note: I'm not a developer so I'm already stretching myself out here. Maybe additional/other new functionality could be moved to other PR's and done by real developers? The point of this PR was to fix performance blocker on Oracle, not to re-arrange the settings mechanism. |
I understand your point, the 2 seems pretty much linked IMHO. |
I for one would vote for NOT moving this setting to layer as by my practice this is an attitude to IT, not technical detail of a specific layer. |
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
While we hate to see this happen, this PR has been automatically closed because it has not had any activity in the last 21 days. If this pull request should be reconsidered, please follow the guidelines in the previous comment and reopen this pull request. Or, if you have any further questions, just ask! We love to help, and if there's anything the QGIS project can do to help push this PR forward please let us know how we can assist. |
I've added more changes (duplicating the trustLayerMetainfo setting to layer uri), but this PR was closed in the meantime. Should I create a new PR? |
The code now repeats trustLayerMetadata='1' 2n times for a project with n layers (the actual setting is 7th line in a project file ). |
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
Some help is needed. I've added logic to push trustMetadata value to layer uri:
There is a problem with updating layer uri after project settings have been updated. There is a loop through all oracle layers, local uri object is updated with updated value, but setUri line in qgsproject.cpp does not update the layer uri and I'm unable to see why and therefore find a solution.
|
If I see it correctly, #34358 implements this without copying the value to layer uri. |
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
While we hate to see this happen, this PR has been automatically closed because it has not had any activity in the last 21 days. If this pull request should be reconsidered, please follow the guidelines in the previous comment and reopen this pull request. Or, if you have any further questions, just ask! We love to help, and if there's anything the QGIS project can do to help push this PR forward please let us know how we can assist. |
Skip geometry type re-querying for Oracle as per #34737