Skip to content

Commit

Permalink
Merge pull request OSGeo#8709 from rouault/fix_8677
Browse files Browse the repository at this point in the history
SQLite: fix SRS retrieval of a SELECT layer from a non-Spatialite DB …
  • Loading branch information
rouault authored Nov 14, 2023
2 parents 9923dc7 + 32a68bb commit 61b83a3
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 25 deletions.
24 changes: 24 additions & 0 deletions autotest/ogr/ogr_sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -2770,6 +2770,30 @@ def test_ogr_sqlite_38(sqlite_test_db):
ds = None


###############################################################################
# Test querying a point column in a non-Spatialite DB
# (https://github.com/OSGeo/gdal/issues/8677)
# Also test with a Spatialite DB while we are it...


@pytest.mark.parametrize("spatialite", [True, False])
def test_ogr_spatialite_point_sql_check_srs(sqlite_test_db):

with sqlite_test_db.ExecuteSQL("SQLITE_HAS_COLUMN_METADATA()") as sql_lyr:
if sql_lyr.GetNextFeature().GetField(0) != 1:
pytest.skip("sqlite built without SQLITE_HAS_COLUMN_METADATA")

srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
lyr = sqlite_test_db.CreateLayer("point", srs=srs, geom_type=ogr.wkbPoint)
feat = ogr.Feature(lyr.GetLayerDefn())
feat.SetGeometryDirectly(ogr.CreateGeometryFromWkt("POINT(1 2)"))
lyr.CreateFeature(feat)
with sqlite_test_db.ExecuteSQL("SELECT * FROM point") as sql_lyr:
assert sql_lyr.GetLayerDefn().GetGeomFieldCount() == 1
assert sql_lyr.GetSpatialRef().GetAuthorityCode(None) == "4326"


###############################################################################
# Test spatial filters with point extent

Expand Down
57 changes: 32 additions & 25 deletions ogr/ogrsf_frmts/sqlite/ogrsqliteselectlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,20 @@ OGRSQLiteSelectLayer::OGRSQLiteSelectLayer(
m_poFeatureDefn->myGetGeomFieldDefn(iField);
if (wkbFlatten(poGeomFieldDefn->GetType()) != wkbUnknown)
continue;

if (sqlite3_column_type(m_hStmt, poGeomFieldDefn->m_iCol) ==
SQLITE_BLOB &&
sqlite3_column_bytes(m_hStmt, poGeomFieldDefn->m_iCol) > 39)
const auto nColType =
sqlite3_column_type(m_hStmt, poGeomFieldDefn->m_iCol);
if (nColType == SQLITE_BLOB)
{
// Is it a Spatialite geometry ?
const GByte *pabyBlob = (const GByte *)sqlite3_column_blob(
m_hStmt, poGeomFieldDefn->m_iCol);
int eByteOrder = pabyBlob[1];
if (pabyBlob[0] == 0x00 &&
(eByteOrder == wkbNDR || eByteOrder == wkbXDR) &&
if (sqlite3_column_bytes(m_hStmt, poGeomFieldDefn->m_iCol) >
39 &&
pabyBlob[0] == 0x00 &&
(pabyBlob[1] == wkbNDR || pabyBlob[1] == wkbXDR) &&
pabyBlob[38] == 0x7C)
{
const int eByteOrder = pabyBlob[1];
int nSRSId = 0;
memcpy(&nSRSId, pabyBlob + 2, 4);
#ifdef CPL_LSB
Expand All @@ -126,31 +128,36 @@ OGRSQLiteSelectLayer::OGRSQLiteSelectLayer(
}
else
CPLErrorReset();

continue;
}
}

#ifdef SQLITE_HAS_COLUMN_METADATA
else if (iField == 0)
if (iField == 0 &&
(nColType == SQLITE_NULL || nColType == SQLITE_BLOB))
{
const char *pszTableName =
sqlite3_column_table_name(m_hStmt, poGeomFieldDefn->m_iCol);
if (pszTableName != nullptr)
{
const char *pszTableName = sqlite3_column_table_name(
m_hStmt, poGeomFieldDefn->m_iCol);
if (pszTableName != nullptr)
CPLErrorStateBackuper oErrorStateBackuper;
CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler);
OGRSQLiteLayer *m_poLayer =
cpl::down_cast<OGRSQLiteLayer *>(
m_poDS->GetLayerByName(pszTableName));
if (m_poLayer != nullptr &&
m_poLayer->GetLayerDefn()->GetGeomFieldCount() > 0)
{
OGRSQLiteLayer *m_poLayer =
(OGRSQLiteLayer *)m_poDS->GetLayerByName(
pszTableName);
if (m_poLayer != nullptr &&
m_poLayer->GetLayerDefn()->GetGeomFieldCount() > 0)
{
OGRSQLiteGeomFieldDefn *poSrcGFldDefn =
m_poLayer->myGetLayerDefn()->myGetGeomFieldDefn(
0);
poGeomFieldDefn->m_nSRSId = poSrcGFldDefn->m_nSRSId;
poGeomFieldDefn->SetSpatialRef(
poSrcGFldDefn->GetSpatialRef());
}
OGRSQLiteGeomFieldDefn *poSrcGFldDefn =
m_poLayer->myGetLayerDefn()->myGetGeomFieldDefn(0);
poGeomFieldDefn->m_nSRSId = poSrcGFldDefn->m_nSRSId;
poGeomFieldDefn->SetSpatialRef(
poSrcGFldDefn->GetSpatialRef());
}
}
#endif
}
#endif
}
}
else
Expand Down

0 comments on commit 61b83a3

Please sign in to comment.