Skip to content

Commit 3ed0066

Browse files
author
Hugo Mercier
committed
Fix virtual layer queries with accents in layer name
(cherry-picked from af0d6b9)
1 parent 5ae34ed commit 3ed0066

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-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
@@ -327,11 +327,11 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
327327
Q_UNUSED( isCreated );
328328

329329
#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);}
330-
#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());}
330+
#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());}
331331

332332
if ( argc < 4 )
333333
{
334-
std::string err( "Missing arguments: layer_id | provider, source" );
334+
QString err( "Missing arguments: layer_id | provider, source" );
335335
RETURN_CPPSTR_ERROR( err );
336336
return SQLITE_ERROR;
337337
}
@@ -344,7 +344,7 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
344344
// CREATE VIRTUAL TABLE vtab USING QgsVLayer(layer_id)
345345
// vtab = argv[2]
346346
// layer_id = argv[3]
347-
QString layerid( argv[3] );
347+
QString layerid = QString::fromUtf8( argv[3] );
348348
if ( layerid.size() >= 1 && layerid[0] == '\'' )
349349
{
350350
layerid = layerid.mid( 1, layerid.size() - 2 );
@@ -354,8 +354,8 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
354354
{
355355
if ( outErr )
356356
{
357-
std::string err( "Cannot find layer " );
358-
err += argv[3];
357+
QString err( "Cannot find layer " );
358+
err += QString::fromUtf8( argv[3] );
359359
RETURN_CPPSTR_ERROR( err );
360360
}
361361
return SQLITE_ERROR;
@@ -371,7 +371,7 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
371371
// source = argv[4]
372372
// encoding = argv[5]
373373
QString provider = argv[3];
374-
QString source = argv[4];
374+
QString source = QString::fromUtf8( argv[4] );
375375
QString encoding = "UTF-8";
376376
if ( argc == 6 )
377377
{
@@ -389,17 +389,16 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
389389
}
390390
try
391391
{
392-
newVtab.reset( new VTable( sql, provider, source, argv[2], encoding ) );
392+
newVtab.reset( new VTable( sql, provider, source, QString::fromUtf8( argv[2] ), encoding ) );
393393
}
394394
catch ( std::runtime_error& e )
395395
{
396-
std::string err( e.what() );
397-
RETURN_CPPSTR_ERROR( err );
396+
RETURN_CSTR_ERROR( e.what() );
398397
return SQLITE_ERROR;
399398
}
400399
}
401400

402-
r = sqlite3_declare_vtab( sql, newVtab->creationString().toLocal8Bit().constData() );
401+
r = sqlite3_declare_vtab( sql, newVtab->creationString().toUtf8().constData() );
403402
if ( r )
404403
{
405404
RETURN_CSTR_ERROR( sqlite3_errmsg( sql ) );

tests/src/python/test_provider_virtual.py

+15
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,21 @@ def test_query_with_accents(self):
733733
ids = [f.id() for f in vl2.getFeatures()]
734734
self.assertEqual(ids, [])
735735

736+
def test_layer_with_accents(self):
737+
l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), u"françéà", "ogr", False)
738+
self.assertEqual(l1.isValid(), True)
739+
QgsMapLayerRegistry.instance().addMapLayer(l1)
740+
741+
df = QgsVirtualLayerDefinition()
742+
df.setQuery(u'select * from "françéà"')
743+
744+
vl = QgsVectorLayer(df.toString(), "testq", "virtual")
745+
self.assertEqual(vl.isValid(), True)
746+
ids = [f.id() for f in vl.getFeatures()]
747+
self.assertEqual(len(ids), 4)
748+
749+
QgsMapLayerRegistry.instance().removeMapLayer(l1.id())
750+
736751
def test_joined_layers_conversion(self):
737752
v1 = QgsVectorLayer("Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory")
738753
self.assertEqual(v1.isValid(), True)

0 commit comments

Comments
 (0)