Skip to content

Commit 682023f

Browse files
author
Hugo Mercier
committed
Fix virtual layer queries with accents in layer name
(cherry-picked from af0d6b9)
1 parent d130b32 commit 682023f

File tree

3 files changed

+26
-13
lines changed

3 files changed

+26
-13
lines changed

src/providers/virtual/qgsvirtuallayerqueryparser.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@ namespace QgsVirtualLayerQueryParser
3939
while ( true )
4040
{
4141
char *errMsg = nullptr;
42-
int r = sqlite3_exec( db.get(), query.toLocal8Bit().constData(), nullptr, nullptr, &errMsg );
43-
QString err = errMsg;
42+
int r = sqlite3_exec( db.get(), query.toUtf8().constData(), nullptr, nullptr, &errMsg );
43+
QString err = QString::fromUtf8( errMsg );
4444
if ( r && err.startsWith( noSuchError ) )
4545
{
4646
QString tableName = err.mid( noSuchError.size() );
4747
tables << tableName;
4848

4949
// create a dummy table to skip this error
5050
QString createStr = QString( "CREATE TABLE \"%1\" (id int)" ).arg( tableName.replace( "\"", "\"\"" ) );
51-
( void )sqlite3_exec( db.get(), createStr.toLocal8Bit().constData(), nullptr, NULL, NULL );
51+
( void )sqlite3_exec( db.get(), createStr.toUtf8().constData(), nullptr, NULL, NULL );
5252
}
5353
else
5454
{

src/providers/virtual/qgsvirtuallayersqlitemodule.cpp

+9-10
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,11 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
324324
Q_UNUSED( isCreated );
325325

326326
#define RETURN_CSTR_ERROR(err) if (outErr) {size_t s = strlen(err); *outErr=reinterpret_cast<char*>(sqlite3_malloc( static_cast<int>( s ) +1)); strncpy(*outErr, err, s);}
327-
#define RETURN_CPPSTR_ERROR(err) if (outErr) {*outErr=reinterpret_cast<char*>(sqlite3_malloc( static_cast<int>( err.size() )+1)); strncpy(*outErr, err.c_str(), err.size());}
327+
#define RETURN_CPPSTR_ERROR(err) if (outErr) {*outErr=reinterpret_cast<char*>(sqlite3_malloc( static_cast<int>( err.toUtf8().size() )+1)); strncpy(*outErr, err.toUtf8().constData(), err.toUtf8().size());}
328328

329329
if ( argc < 4 )
330330
{
331-
std::string err( "Missing arguments: layer_id | provider, source" );
331+
QString err( "Missing arguments: layer_id | provider, source" );
332332
RETURN_CPPSTR_ERROR( err );
333333
return SQLITE_ERROR;
334334
}
@@ -341,7 +341,7 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
341341
// CREATE VIRTUAL TABLE vtab USING QgsVLayer(layer_id)
342342
// vtab = argv[2]
343343
// layer_id = argv[3]
344-
QString layerid( argv[3] );
344+
QString layerid = QString::fromUtf8( argv[3] );
345345
if ( layerid.size() >= 1 && layerid[0] == '\'' )
346346
{
347347
layerid = layerid.mid( 1, layerid.size() - 2 );
@@ -351,8 +351,8 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
351351
{
352352
if ( outErr )
353353
{
354-
std::string err( "Cannot find layer " );
355-
err += argv[3];
354+
QString err( "Cannot find layer " );
355+
err += QString::fromUtf8( argv[3] );
356356
RETURN_CPPSTR_ERROR( err );
357357
}
358358
return SQLITE_ERROR;
@@ -368,7 +368,7 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
368368
// source = argv[4]
369369
// encoding = argv[5]
370370
QString provider = argv[3];
371-
QString source = argv[4];
371+
QString source = QString::fromUtf8( argv[4] );
372372
QString encoding = "UTF-8";
373373
if ( argc == 6 )
374374
{
@@ -386,17 +386,16 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
386386
}
387387
try
388388
{
389-
newVtab.reset( new VTable( sql, provider, source, argv[2], encoding ) );
389+
newVtab.reset( new VTable( sql, provider, source, QString::fromUtf8( argv[2] ), encoding ) );
390390
}
391391
catch ( std::runtime_error& e )
392392
{
393-
std::string err( e.what() );
394-
RETURN_CPPSTR_ERROR( err );
393+
RETURN_CSTR_ERROR( e.what() );
395394
return SQLITE_ERROR;
396395
}
397396
}
398397

399-
r = sqlite3_declare_vtab( sql, newVtab->creationString().toLocal8Bit().constData() );
398+
r = sqlite3_declare_vtab( sql, newVtab->creationString().toUtf8().constData() );
400399
if ( r )
401400
{
402401
RETURN_CSTR_ERROR( sqlite3_errmsg( sql ) );

tests/src/python/test_provider_virtual.py

+14
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,20 @@ def test_query_with_accents(self):
738738
ids = [f.id() for f in vl2.getFeatures()]
739739
self.assertEqual(ids, [])
740740

741+
def test_layer_with_accents(self):
742+
l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), u"françéà", "ogr", False)
743+
self.assertEqual(l1.isValid(), True)
744+
QgsMapLayerRegistry.instance().addMapLayer(l1)
745+
746+
df = QgsVirtualLayerDefinition()
747+
df.setQuery(u'select * from "françéà"')
748+
749+
vl = QgsVectorLayer(df.toString(), "testq", "virtual")
750+
self.assertEqual(vl.isValid(), True)
751+
ids = [f.id() for f in vl.getFeatures()]
752+
self.assertEqual(len(ids), 4)
753+
754+
QgsMapLayerRegistry.instance().removeMapLayer(l1.id())
741755

742756
if __name__ == '__main__':
743757
unittest.main()

0 commit comments

Comments
 (0)