Skip to content

Commit af0d6b9

Browse files
author
Hugo Mercier
committed
Fix virtual layer queries with accents in layer name
1 parent bd3cf76 commit af0d6b9

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

330330
#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);}
331-
#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());}
331+
#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());}
332332

333333
if ( argc < 4 )
334334
{
335-
std::string err( "Missing arguments: layer_id | provider, source" );
335+
QString err( "Missing arguments: layer_id | provider, source" );
336336
RETURN_CPPSTR_ERROR( err );
337337
return SQLITE_ERROR;
338338
}
@@ -345,7 +345,7 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
345345
// CREATE VIRTUAL TABLE vtab USING QgsVLayer(layer_id)
346346
// vtab = argv[2]
347347
// layer_id = argv[3]
348-
QString layerid( argv[3] );
348+
QString layerid = QString::fromUtf8( argv[3] );
349349
if ( layerid.size() >= 1 && layerid[0] == '\'' )
350350
{
351351
layerid = layerid.mid( 1, layerid.size() - 2 );
@@ -355,8 +355,8 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
355355
{
356356
if ( outErr )
357357
{
358-
std::string err( "Cannot find layer " );
359-
err += argv[3];
358+
QString err( "Cannot find layer " );
359+
err += QString::fromUtf8( argv[3] );
360360
RETURN_CPPSTR_ERROR( err );
361361
}
362362
return SQLITE_ERROR;
@@ -372,7 +372,7 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
372372
// source = argv[4]
373373
// encoding = argv[5]
374374
QString provider = argv[3];
375-
QString source = argv[4];
375+
QString source = QString::fromUtf8( argv[4] );
376376
QString encoding = "UTF-8";
377377
if ( argc == 6 )
378378
{
@@ -390,17 +390,16 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
390390
}
391391
try
392392
{
393-
newVtab.reset( new VTable( sql, provider, source, argv[2], encoding ) );
393+
newVtab.reset( new VTable( sql, provider, source, QString::fromUtf8( argv[2] ), encoding ) );
394394
}
395395
catch ( std::runtime_error& e )
396396
{
397-
std::string err( e.what() );
398-
RETURN_CPPSTR_ERROR( err );
397+
RETURN_CSTR_ERROR( e.what() );
399398
return SQLITE_ERROR;
400399
}
401400
}
402401

403-
r = sqlite3_declare_vtab( sql, newVtab->creationString().toLocal8Bit().constData() );
402+
r = sqlite3_declare_vtab( sql, newVtab->creationString().toUtf8().constData() );
404403
if ( r )
405404
{
406405
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)