Repository navigation
Full repo findings - #60
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fix output completion and access, batch persisted extents, protect threaded progress callbacks, and verify Release builds on pull requests. Update regression tests, documentation, and shared memory. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Julian-MW
left a comment
There was a problem hiding this comment.
Automated review. Final decision is with the human reviewer.
Findings (line comments are not attachable through this integration, so each finding carries file:line):
1. Severity: Major | Confidence: Medium — src/MapWinGIS.Core/src/vector/VectorDataset.cpp:235
Issue: The layer name is interpolated unquoted into RECOMPUTE EXTENT ON <layerName>. OGR SQL requires identifiers containing spaces or special characters to be double-quoted.
Impact: Shapefile layers derived from file names with spaces (e.g. my layer.shp) make every VectorDataset::Flush() after a geometry edit throw CoreError, breaking the documented "call Flush before closing" workflow for exactly those files; an embedded " can also garble the statement.
Fix: Quote and escape the identifier:
std::string escaped(layerName);
std::string::size_type pos = 0;
while ((pos = escaped.find('"', pos)) != std::string::npos)
{
escaped.insert(pos, "\"");
pos += 2;
}
const std::string sql = "RECOMPUTE EXTENT ON \"" + escaped + "\"";2. Severity: Minor | Confidence: Medium — src/MapWinGIS.Core/src/vector/VectorDataset.cpp:202
Issue: _extentNeedsExactRecalculation and _storedExtentDirty are set before the SetFeature() result is known, so they remain set when the write fails.
Impact: After a rejected geometry write, a later Flush() runs a RECOMPUTE EXTENT scan for data that never changed (wasted O(n)), and if the scan errors, Flush() throws for a write that did not happen. The extent-invalidation behavior itself is intentional per FailedGeometryWritesDiscardTheEditedFeatureAndExtentCache, but the stored-extent dirty flag is not.
Fix: Set _storedExtentDirty = true only when result == OGRERR_NONE, or clear both flags on the failure path.
3. Severity: Minor | Confidence: Low — src/MapWinGIS.Core/src/gdal/GdalAlgorithmRunner.cpp:636
Issue: The failure cleanup calls output->Get<GDALArgDatasetValue>().Close() unconditionally, but the persistent-output success path already closed the output via outputValue->Close() (~line 561).
Impact: If GDALArgDatasetValue::Close() reports failure (or UB) on an already-closed value, a spurious "GDAL algorithm output could not be closed" failure is appended after the run already failed, masking the root diagnostic.
Fix: Track whether the output was already closed in the persistent branch, or make the cleanup close conditional on the output still being open.
4. Severity: Suggestion | Confidence: Low — src/MapWinGIS.Core/src/gdal/GdalAlgorithmRunner.cpp:89
Issue: Any non-empty GetDescription() is treated as a reopen path, even when it is not a path (connection strings, driver pseudo-names).
Impact: Benign but noisy: GDALOpenEx is attempted against a non-path string and the "no dataset could be reopened" warning fires for outputs that were never meant to be reopened.
Fix: Prefer output.GetName() when set, or sanity-check the description (e.g. reject strings containing =/connection prefixes) before reopening.
5. Severity: Suggestion | Confidence: Low — src/MapWinGIS.Core/src/gdal/GdalRuntime.cpp:242
Issue: RethrowCallbackException() locks callbackMutex, the same mutex HandleProgress holds while invoking the user callback.
Impact: Not reachable through the public API today, but a callback that somehow triggers exception rethrow on its own adapter (or any future API that calls it from inside a callback) deadlocks. Consider documenting that RethrowCallbackException must not be called from a progress callback, or use a separate mutex/atomic flag for the exception pointer.
CI status at review time: build (x64, Debug) succeeded; build (x64, Release) still in progress.
- Keep stored extent dirty state tied to successful geometry writes - Preserve GDAL raw layer-name syntax for extent recomputation - Avoid closing an already closed algorithm output Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use the explicit algorithm output name before a dataset description - Verify output reopening follows the configured name when descriptions differ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Fixed in f62a183: Mark stored extents dirty only after successful geometry writes, and avoid closing a successfully closed persistent output again. |
Fix the repository review findings and their follow-up comments: rejected vector edits, stale or failed extent queries, GDAL completion and output ownership, callback thread safety, GDI clipping, and build/deployment configuration.
Runner-owned persistent outputs pass a checked close after successful finalization. Reopening uses all registered readers and preserves update access where supported. An unavailable reader produces a warning and no returned dataset without failing a successful write. Failed or cancelled runs do not reopen outputs. Caller-owned outputs retain their lifetime contract.
Geometry edits invalidate the cached extent. Call
VectorDataset::Flush()before closing to persist exact Shapefile and GeoPackage bounds. It batches stored-extent scans per dirty layer and permits retry after recomputation failures. Warning-only unavailable extents use the exact-scan fallback, which skips attributes.The shared progress adapter serializes worker callbacks and protects cancellation and exception state. Legacy warp keeps support for
-multiand threaded warp options. GDI skips layer traversal when the effective clip is empty.Pull requests now build and test both Debug and full-driver Release for x64, with a 180-minute job timeout. Build configuration checks exercise the documented
tests%3Bfull-driverscommand-line value. Runtime deployment uses an explicit property enabled by Core. README, public API documentation, related guides, and shared memory match these changes.Debug and default-driver Release x64 build without warnings. Each configuration passes all 338 enabled native tests. Three opt-in tests remain skipped. Build configuration checks pass.
Full-driver Release remains blocked locally: libpq's Release alignment-test executable receives Windows access denied (
WinError 5). The compiler and linker succeed, but Windows prevents execution of the generated probe. The new PR-time Release CI job covers this configuration before merge.