Skip to content

Commit

Permalink
Merge pull request OSGeo#9649 from rouault/fix_9648
Browse files Browse the repository at this point in the history
ExecuteSQL() with OGRSQL and SQLITE dialects: get OLCStringsAsUTF8 from underlying layer
  • Loading branch information
rouault authored Apr 14, 2024
2 parents ecc53c0 + abe8d7f commit 0c669f3
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
9 changes: 9 additions & 0 deletions autotest/ogr/ogr_shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -1983,6 +1983,15 @@ def test_ogr_shape_50():

assert reconv_possible, "TestCapability(OLCStringsAsUTF8) should return TRUE"

with ds.ExecuteSQL(f"SELECT * FROM {lyr.GetName()}") as sql_lyr:
assert sql_lyr.TestCapability(ogr.OLCStringsAsUTF8)

if ogr.GetDriverByName("SQLITE"):
with ds.ExecuteSQL(
f"SELECT * FROM {lyr.GetName()}", dialect="SQLITE"
) as sql_lyr:
assert sql_lyr.TestCapability(ogr.OLCStringsAsUTF8)


###############################################################################
# Test that we can add a field when there's no dbf file initially
Expand Down
7 changes: 7 additions & 0 deletions ogr/ogrsf_frmts/generic/ogr_gensql.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,13 @@ int OGRGenSQLResultsLayer::TestCapability(const char *pszCap)
if (EQUAL(pszCap, OLCFastFeatureCount))
return TRUE;
}

if (EQUAL(pszCap, OLCStringsAsUTF8) || EQUAL(pszCap, OLCCurveGeometries) ||
EQUAL(pszCap, OLCMeasuredGeometries) || EQUAL(pszCap, OLCZGeometries))
{
return poSrcLayer->TestCapability(pszCap);
}

return FALSE;
}

Expand Down
34 changes: 27 additions & 7 deletions ogr/ogrsf_frmts/sqlite/ogrsqliteexecutesql.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,14 +493,18 @@ OGRLayer *OGRSQLiteExecuteSQL(GDALDataset *, const char *, OGRGeometry *,

class OGRSQLiteExecuteSQLLayer final : public OGRSQLiteSelectLayer
{
char *pszTmpDBName;
char *m_pszTmpDBName = nullptr;
bool m_bStringsAsUTF8 = false;

public:
OGRSQLiteExecuteSQLLayer(char *pszTmpDBName, OGRSQLiteDataSource *poDS,
const CPLString &osSQL, sqlite3_stmt *hStmt,
bool bUseStatementForGetNextFeature,
bool bEmptyLayer, bool bCanReopenBaseDS);
bool bEmptyLayer, bool bCanReopenBaseDS,
bool bStringsAsUTF8);
virtual ~OGRSQLiteExecuteSQLLayer();

int TestCapability(const char *pszCap) override;
};

/************************************************************************/
Expand All @@ -510,11 +514,11 @@ class OGRSQLiteExecuteSQLLayer final : public OGRSQLiteSelectLayer
OGRSQLiteExecuteSQLLayer::OGRSQLiteExecuteSQLLayer(
char *pszTmpDBNameIn, OGRSQLiteDataSource *poDSIn, const CPLString &osSQL,
sqlite3_stmt *hStmtIn, bool bUseStatementForGetNextFeature,
bool bEmptyLayer, bool bCanReopenBaseDS)
bool bEmptyLayer, bool bCanReopenBaseDS, bool bStringsAsUTF8)
: OGRSQLiteSelectLayer(poDSIn, osSQL, hStmtIn,
bUseStatementForGetNextFeature, bEmptyLayer, true,
bCanReopenBaseDS),
pszTmpDBName(pszTmpDBNameIn)
m_pszTmpDBName(pszTmpDBNameIn), m_bStringsAsUTF8(bStringsAsUTF8)
{
}

Expand All @@ -531,8 +535,19 @@ OGRSQLiteExecuteSQLLayer::~OGRSQLiteExecuteSQLLayer()
Finalize();

delete m_poDS;
VSIUnlink(pszTmpDBName);
CPLFree(pszTmpDBName);
VSIUnlink(m_pszTmpDBName);
CPLFree(m_pszTmpDBName);
}

/************************************************************************/
/* TestCapability() */
/************************************************************************/

int OGRSQLiteExecuteSQLLayer::TestCapability(const char *pszCap)
{
if (EQUAL(pszCap, OLCStringsAsUTF8))
return m_bStringsAsUTF8;
return OGRSQLiteSelectLayer::TestCapability(pszCap);
}

/************************************************************************/
Expand Down Expand Up @@ -993,6 +1008,7 @@ OGRLayer *OGRSQLiteExecuteSQL(GDALDataset *poDS, const char *pszStatement,
/* For each of those tables, create a Virtual Table. */
/* -------------------------------------------------------------------- */
OGRLayer *poSingleSrcLayer = nullptr;
bool bStringsAsUTF8 = true;
for (; oIter != oSetLayers.end(); ++oIter)
{
const LayerDesc &oLayerDesc = *oIter;
Expand Down Expand Up @@ -1049,6 +1065,9 @@ OGRLayer *OGRSQLiteExecuteSQL(GDALDataset *poDS, const char *pszStatement,
nExtraDS = OGR2SQLITE_AddExtraDS(poModule, poOtherDS);
}

if (!poLayer->TestCapability(OLCStringsAsUTF8))
bStringsAsUTF8 = false;

if (oSetLayers.size() == 1)
poSingleSrcLayer = poLayer;

Expand Down Expand Up @@ -1158,7 +1177,8 @@ OGRLayer *OGRSQLiteExecuteSQL(GDALDataset *poDS, const char *pszStatement,
!(poDrv && EQUAL(poDrv->GetDescription(), "Memory"));
OGRSQLiteSelectLayer *poLayer = new OGRSQLiteExecuteSQLLayer(
pszTmpDBName, poSQLiteDS, pszStatement, hSQLStmt,
bUseStatementForGetNextFeature, bEmptyLayer, bCanReopenBaseDS);
bUseStatementForGetNextFeature, bEmptyLayer, bCanReopenBaseDS,
bStringsAsUTF8);

if (poSpatialFilter != nullptr)
poLayer->SetSpatialFilter(0, poSpatialFilter);
Expand Down

0 comments on commit 0c669f3

Please sign in to comment.