Coverage Report

Created: 2025-08-11 09:23

/src/gdal/ogr/ogrsf_frmts/sqlite/ogrsqlitevirtualogr.cpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  SQLite Virtual Table module using OGR layers
5
 * Author:   Even Rouault, even dot rouault at spatialys.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2012-2013, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#define DEFINE_OGRSQLiteSQLFunctionsSetCaseSensitiveLike
14
15
#include "cpl_port.h"
16
#include "ogrsqlitevirtualogr.h"
17
18
#include <cctype>
19
#include <cstdio>
20
#include <cstdlib>
21
#include <cstring>
22
#include <limits>
23
#include <map>
24
#include <set>
25
#include <string>
26
#include <utility>
27
#include <vector>
28
29
#include "cpl_conv.h"
30
#include "cpl_error.h"
31
#include "cpl_string.h"
32
33
/************************************************************************/
34
/*                  OGR2SQLITE_GetNameForGeometryColumn()               */
35
/************************************************************************/
36
37
CPLString OGR2SQLITE_GetNameForGeometryColumn(OGRLayer *poLayer)
38
0
{
39
0
    const char *pszGeomColumn = poLayer->GetGeometryColumn();
40
0
    if (pszGeomColumn != nullptr && !EQUAL(pszGeomColumn, ""))
41
0
    {
42
0
        if (poLayer->GetLayerDefn()->GetFieldIndex(pszGeomColumn) < 0)
43
0
            return pszGeomColumn;
44
0
    }
45
46
0
    CPLString osGeomCol("GEOMETRY");
47
0
    int nTry = 2;
48
0
    while (poLayer->GetLayerDefn()->GetFieldIndex(osGeomCol) >= 0)
49
0
    {
50
0
        osGeomCol.Printf("GEOMETRY%d", nTry++);
51
0
    }
52
0
    return osGeomCol;
53
0
}
54
55
#if !defined(HAVE_SQLITE3EXT_H)
56
57
// Stub functions
58
59
void OGR2SQLITE_Register()
60
{
61
}
62
63
OGR2SQLITEModule *OGR2SQLITE_Setup(GDALDataset *, OGRSQLiteDataSource *)
64
{
65
    return nullptr;
66
}
67
68
void OGR2SQLITE_SetCaseSensitiveLike(OGR2SQLITEModule *, bool)
69
{
70
}
71
72
int OGR2SQLITE_AddExtraDS(OGR2SQLITEModule *, GDALDataset *)
73
{
74
    return 0;
75
}
76
77
#else
78
79
/************************************************************************/
80
/*                           OGR2SQLITE_Register()                      */
81
/************************************************************************/
82
83
CPL_C_START
84
int CPL_DLL OGR2SQLITE_static_register(sqlite3 *hDB, char **pzErrMsg,
85
                                       void *pApi);
86
CPL_C_END
87
88
/* We call this function so that each time a db is created, */
89
/* OGR2SQLITE_static_register is called, to initialize the sqlite3_api */
90
/* structure with the right pointers. */
91
/* We need to declare this function before including sqlite3ext.h, since */
92
/* sqlite 3.8.7, sqlite3_auto_extension can be a macro (#5725) */
93
94
void OGR2SQLITE_Register()
95
311
{
96
#if !defined(SQLITE_HAS_NON_DEPRECATED_AUTO_EXTENSION) && defined(__GNUC__)
97
#pragma GCC diagnostic push
98
#pragma GCC diagnostic ignored "-Wdeprecated"
99
#endif
100
311
    sqlite3_auto_extension(
101
311
        reinterpret_cast<void (*)(void)>(OGR2SQLITE_static_register));
102
#if !defined(SQLITE_HAS_NON_DEPRECATED_AUTO_EXTENSION) && defined(__GNUC__)
103
#pragma GCC diagnostic pop
104
#endif
105
311
}
106
107
#define VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
108
// #define DEBUG_OGR2SQLITE
109
110
#include "gdal_priv.h"
111
#include "ogr_api.h"
112
#include "ogr_core.h"
113
#include "ogr_feature.h"
114
#include "ogr_geometry.h"
115
#include "ogr_p.h"
116
#include "ogr_spatialref.h"
117
#include "ogrsf_frmts.h"
118
#include "ogrsqlitesqlfunctions.h"
119
#include "ogrsqliteutility.h"
120
#include "ogr_swq.h"
121
#include "sqlite3.h"
122
#include "sqlite3ext.h"
123
124
#undef SQLITE_EXTENSION_INIT1
125
#define SQLITE_EXTENSION_INIT1                                                 \
126
    const sqlite3_api_routines *sqlite3_api = nullptr;
127
128
/* Declaration of sqlite3_api structure */
129
static SQLITE_EXTENSION_INIT1
130
131
/* The layout of fields is :
132
   0   : RegularField0
133
   ...
134
   n-1 : RegularField(n-1)
135
   n   : OGR_STYLE (may be HIDDEN)
136
   n+1 : GEOMETRY
137
*/
138
139
#define COMPILATION_ALLOWED
140
#include "ogrsqlitesqlfunctions.cpp" /* yes the .cpp file, to make it work on Windows with load_extension('gdalXX.dll') */
141
#undef COMPILATION_ALLOWED
142
143
    /************************************************************************/
144
    /*                           OGR2SQLITEModule                           */
145
    /************************************************************************/
146
147
    class OGR2SQLITEModule
148
{
149
#ifdef DEBUG
150
    void *pDummy = nullptr; /* to track memory leaks */
151
#endif
152
    sqlite3 *hDB = nullptr; /* *NOT* to be freed */
153
154
    GDALDataset *poDS = nullptr; /* *NOT* to be freed */
155
    std::vector<std::unique_ptr<GDALDataset>>
156
        apoExtraDS{}; /* each datasource to be freed */
157
158
    OGRSQLiteDataSource *poSQLiteDS =
159
        nullptr; /* *NOT* to be freed, might be NULL */
160
161
    std::map<CPLString, OGRLayer *> oMapVTableToOGRLayer{};
162
163
    void *hHandleSQLFunctions = nullptr;
164
165
    CPL_DISALLOW_COPY_ASSIGN(OGR2SQLITEModule)
166
167
  public:
168
    OGR2SQLITEModule();
169
    ~OGR2SQLITEModule();
170
171
    int Setup(GDALDataset *poDS, OGRSQLiteDataSource *poSQLiteDS);
172
    int Setup(sqlite3 *hDB);
173
174
    GDALDataset *GetDS()
175
0
    {
176
0
        return poDS;
177
0
    }
178
179
    int AddExtraDS(GDALDataset *poDS);
180
    GDALDataset *GetExtraDS(int nIndex);
181
182
    int FetchSRSId(const OGRSpatialReference *poSRS);
183
184
    void RegisterVTable(const char *pszVTableName, OGRLayer *poLayer);
185
    void UnregisterVTable(const char *pszVTableName);
186
    OGRLayer *GetLayerForVTable(const char *pszVTableName);
187
188
    void SetHandleSQLFunctions(void *hHandleSQLFunctionsIn);
189
190
    void SetCaseSensitiveLike(bool b)
191
0
    {
192
0
        OGRSQLiteSQLFunctionsSetCaseSensitiveLike(hHandleSQLFunctions, b);
193
0
    }
194
};
195
196
/************************************************************************/
197
/*                        OGR2SQLITEModule()                            */
198
/************************************************************************/
199
200
OGR2SQLITEModule::OGR2SQLITEModule()
201
#ifdef DEBUG
202
    : pDummy(CPLMalloc(1))
203
#endif
204
3.66k
{
205
3.66k
}
206
207
/************************************************************************/
208
/*                          ~OGR2SQLITEModule                           */
209
/************************************************************************/
210
211
OGR2SQLITEModule::~OGR2SQLITEModule()
212
3.66k
{
213
#ifdef DEBUG
214
    CPLFree(pDummy);
215
#endif
216
217
3.66k
    apoExtraDS.clear();
218
219
3.66k
    OGRSQLiteUnregisterSQLFunctions(hHandleSQLFunctions);
220
3.66k
}
221
222
/************************************************************************/
223
/*                        SetHandleSQLFunctions()                       */
224
/************************************************************************/
225
226
void OGR2SQLITEModule::SetHandleSQLFunctions(void *hHandleSQLFunctionsIn)
227
3.66k
{
228
3.66k
    CPLAssert(hHandleSQLFunctions == nullptr);
229
3.66k
    hHandleSQLFunctions = hHandleSQLFunctionsIn;
230
3.66k
}
231
232
/************************************************************************/
233
/*                            AddExtraDS()                              */
234
/************************************************************************/
235
236
int OGR2SQLITEModule::AddExtraDS(GDALDataset *poDSIn)
237
0
{
238
0
    const int nRet = static_cast<int>(apoExtraDS.size());
239
0
    apoExtraDS.push_back(std::unique_ptr<GDALDataset>(poDSIn));
240
0
    return nRet;
241
0
}
242
243
/************************************************************************/
244
/*                            GetExtraDS()                              */
245
/************************************************************************/
246
247
GDALDataset *OGR2SQLITEModule::GetExtraDS(int nIndex)
248
0
{
249
0
    if (nIndex < 0 || nIndex >= static_cast<int>(apoExtraDS.size()))
250
0
        return nullptr;
251
0
    return apoExtraDS[nIndex].get();
252
0
}
253
254
/************************************************************************/
255
/*                                Setup()                               */
256
/************************************************************************/
257
258
int OGR2SQLITEModule::Setup(GDALDataset *poDSIn,
259
                            OGRSQLiteDataSource *poSQLiteDSIn)
260
55
{
261
55
    CPLAssert(poDS == nullptr);
262
55
    CPLAssert(poSQLiteDS == nullptr);
263
55
    poDS = poDSIn;
264
55
    poSQLiteDS = poSQLiteDSIn;
265
55
    return Setup(poSQLiteDS->GetDB());
266
55
}
267
268
/************************************************************************/
269
/*                            FetchSRSId()                              */
270
/************************************************************************/
271
272
// TODO(schwehr): Refactor FetchSRSId to be much simpler.
273
int OGR2SQLITEModule::FetchSRSId(const OGRSpatialReference *poSRS)
274
0
{
275
0
    int nSRSId = -1;
276
277
0
    if (poSQLiteDS != nullptr)
278
0
    {
279
0
        nSRSId = poSQLiteDS->GetUndefinedSRID();
280
0
        if (poSRS != nullptr)
281
0
            nSRSId = poSQLiteDS->FetchSRSId(poSRS);
282
0
    }
283
0
    else
284
0
    {
285
0
        if (poSRS != nullptr)
286
0
        {
287
0
            const char *pszAuthorityName = poSRS->GetAuthorityName(nullptr);
288
0
            if (pszAuthorityName != nullptr && EQUAL(pszAuthorityName, "EPSG"))
289
0
            {
290
0
                const char *pszAuthorityCode = poSRS->GetAuthorityCode(nullptr);
291
0
                if (pszAuthorityCode != nullptr && strlen(pszAuthorityCode) > 0)
292
0
                {
293
0
                    nSRSId = atoi(pszAuthorityCode);
294
0
                }
295
0
            }
296
0
        }
297
0
    }
298
299
0
    return nSRSId;
300
0
}
301
302
/************************************************************************/
303
/*                          RegisterVTable()                            */
304
/************************************************************************/
305
306
void OGR2SQLITEModule::RegisterVTable(const char *pszVTableName,
307
                                      OGRLayer *poLayer)
308
0
{
309
0
    oMapVTableToOGRLayer[pszVTableName] = poLayer;
310
0
}
311
312
/************************************************************************/
313
/*                          UnregisterVTable()                          */
314
/************************************************************************/
315
316
void OGR2SQLITEModule::UnregisterVTable(const char *pszVTableName)
317
0
{
318
0
    oMapVTableToOGRLayer[pszVTableName] = nullptr;
319
0
}
320
321
/************************************************************************/
322
/*                          GetLayerForVTable()                         */
323
/************************************************************************/
324
325
OGRLayer *OGR2SQLITEModule::GetLayerForVTable(const char *pszVTableName)
326
0
{
327
0
    std::map<CPLString, OGRLayer *>::iterator oIter =
328
0
        oMapVTableToOGRLayer.find(pszVTableName);
329
0
    if (oIter == oMapVTableToOGRLayer.end())
330
0
    {
331
0
        if (poDS == poSQLiteDS)
332
0
            return poSQLiteDS->GetLayerByName(pszVTableName);
333
0
        return nullptr;
334
0
    }
335
336
0
    OGRLayer *poLayer = oIter->second;
337
0
    if (poLayer == nullptr)
338
0
    {
339
        /* If the associate layer is null, then try to "ping" the virtual */
340
        /* table since we know that we have managed to create it before */
341
0
        if (sqlite3_exec(hDB,
342
0
                         CPLSPrintf("PRAGMA table_info(\"%s\")",
343
0
                                    SQLEscapeName(pszVTableName).c_str()),
344
0
                         nullptr, nullptr, nullptr) == SQLITE_OK)
345
0
        {
346
0
            poLayer = oMapVTableToOGRLayer[pszVTableName];
347
0
        }
348
0
    }
349
350
0
    return poLayer;
351
0
}
352
353
/* See http://www.sqlite.org/vtab.html for the documentation on how to
354
   implement a new module for the Virtual Table mechanism. */
355
356
/************************************************************************/
357
/*                            OGR2SQLITE_vtab                           */
358
/************************************************************************/
359
360
typedef struct
361
{
362
    /* Mandatory fields by sqlite3: don't change or reorder them ! */
363
    const sqlite3_module *pModule;
364
    int nRef;
365
    char *zErrMsg;
366
367
    /* Extension fields */
368
    char *pszVTableName;
369
    OGR2SQLITEModule *poModule;
370
    GDALDataset *poDS;
371
    int bCloseDS;
372
    OGRLayer *poLayer;
373
    int nMyRef;
374
    bool bHasFIDColumn;
375
} OGR2SQLITE_vtab;
376
377
/************************************************************************/
378
/*                          OGR2SQLITE_vtab_cursor                      */
379
/************************************************************************/
380
381
typedef struct
382
{
383
    /* Mandatory fields by sqlite3: don't change or reorder them ! */
384
    OGR2SQLITE_vtab *pVTab;
385
386
    /* Extension fields */
387
    GDALDataset *poDupDataSource;
388
    OGRLayer *poLayer;
389
    OGRFeature *poFeature;
390
391
    /* nFeatureCount >= 0 if the layer has a feast feature count capability. */
392
    /* In which case nNextWishedIndex and nCurFeatureIndex */
393
    /* will be used to avoid useless GetNextFeature() */
394
    /* Helps in SELECT COUNT(*) FROM xxxx scenarios */
395
    GIntBig nFeatureCount;
396
    GIntBig nNextWishedIndex;
397
    GIntBig nCurFeatureIndex;
398
399
    GByte *pabyGeomBLOB;
400
    int nGeomBLOBLen;
401
} OGR2SQLITE_vtab_cursor;
402
403
#ifdef VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
404
405
/************************************************************************/
406
/*                     OGR2SQLITEDetectSuspiciousUsage()                */
407
/************************************************************************/
408
409
static int OGR2SQLITEDetectSuspiciousUsage(sqlite3 *hDB,
410
                                           const char *pszVirtualTableName,
411
                                           char **pzErr)
412
0
{
413
0
    char **papszResult = nullptr;
414
0
    int nRowCount = 0;
415
0
    int nColCount = 0;
416
417
    /* Collect database names */
418
0
    sqlite3_get_table(hDB, "PRAGMA database_list", &papszResult, &nRowCount,
419
0
                      &nColCount, nullptr);
420
421
0
    std::vector<CPLString> aosDatabaseNames;
422
0
    for (int i = 1; i <= nRowCount; i++)
423
0
    {
424
0
        const char *pszUnescapedName = papszResult[i * nColCount + 1];
425
0
        aosDatabaseNames.push_back(CPLSPrintf(
426
0
            "\"%s\".sqlite_master", SQLEscapeName(pszUnescapedName).c_str()));
427
0
    }
428
429
    /* Add special database (just in case, not sure it is really needed) */
430
0
    aosDatabaseNames.push_back("sqlite_temp_master");
431
432
0
    sqlite3_free_table(papszResult);
433
0
    papszResult = nullptr;
434
435
    /* Check the triggers of each database */
436
0
    for (const auto &osDBName : aosDatabaseNames)
437
0
    {
438
0
        nRowCount = 0;
439
0
        nColCount = 0;
440
441
0
        const char *pszSQL =
442
0
            CPLSPrintf("SELECT name, sql FROM %s "
443
0
                       "WHERE (type = 'trigger' OR type = 'view') AND ("
444
0
                       "sql LIKE '%%%s%%' OR "
445
0
                       "sql LIKE '%%\"%s\"%%' OR "
446
0
                       "sql LIKE '%%ogr_layer_%%' )",
447
0
                       osDBName.c_str(), pszVirtualTableName,
448
0
                       SQLEscapeName(pszVirtualTableName).c_str());
449
450
0
        sqlite3_get_table(hDB, pszSQL, &papszResult, &nRowCount, &nColCount,
451
0
                          nullptr);
452
453
0
        sqlite3_free_table(papszResult);
454
0
        papszResult = nullptr;
455
456
0
        if (nRowCount > 0)
457
0
        {
458
0
            if (!CPLTestBool(CPLGetConfigOption(
459
0
                    "ALLOW_VIRTUAL_OGR_FROM_TRIGGER_AND_VIEW", "NO")))
460
0
            {
461
0
                *pzErr = sqlite3_mprintf(
462
0
                    "A trigger and/or view might reference VirtualOGR table "
463
0
                    "'%s'.\n"
464
0
                    "This is suspicious practice that could be used to steal "
465
0
                    "data without your consent.\n"
466
0
                    "Disabling access to it unless you define the "
467
0
                    "ALLOW_VIRTUAL_OGR_FROM_TRIGGER_AND_VIEW "
468
0
                    "configuration option to YES.",
469
0
                    pszVirtualTableName);
470
0
                return TRUE;
471
0
            }
472
0
        }
473
0
    }
474
475
0
    return FALSE;
476
0
}
477
478
#endif  // VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
479
480
/************************************************************************/
481
/*                      OGR2SQLITE_ConnectCreate()                      */
482
/************************************************************************/
483
484
static int OGR2SQLITE_DisconnectDestroy(sqlite3_vtab *pVTab);
485
486
static int OGR2SQLITE_ConnectCreate(sqlite3 *hDB, void *pAux, int argc,
487
                                    const char *const *argv,
488
                                    sqlite3_vtab **ppVTab, char **pzErr)
489
0
{
490
#ifdef DEBUG_OGR2SQLITE
491
    CPLDebug("OGR2SQLITE", "ConnectCreate(%s)", argv[2]);
492
#endif
493
494
0
    OGR2SQLITEModule *poModule = static_cast<OGR2SQLITEModule *>(pAux);
495
0
    OGRLayer *poLayer = nullptr;
496
0
    bool bExposeOGR_STYLE = false;
497
0
    bool bCloseDS = false;
498
0
    bool bInternalUse = false;
499
0
    bool bExposeOGRNativeData = false;
500
501
    /* -------------------------------------------------------------------- */
502
    /*      If called from ogrexecutesql.cpp                                */
503
    /* -------------------------------------------------------------------- */
504
0
    GDALDataset *poDS = poModule->GetDS();
505
0
    if (poDS != nullptr && (argc == 6 || argc == 7) &&
506
0
        CPLGetValueType(argv[3]) == CPL_VALUE_INTEGER)
507
0
    {
508
0
        bInternalUse = true;
509
510
0
        int nDSIndex = atoi(argv[3]);
511
0
        if (nDSIndex >= 0)
512
0
        {
513
0
            poDS = poModule->GetExtraDS(nDSIndex);
514
0
            if (poDS == nullptr)
515
0
            {
516
0
                *pzErr =
517
0
                    sqlite3_mprintf("Invalid dataset index : %d", nDSIndex);
518
0
                return SQLITE_ERROR;
519
0
            }
520
0
        }
521
0
        CPLString osLayerName(SQLUnescape(argv[4]));
522
523
0
        poLayer = poDS->GetLayerByName(osLayerName);
524
0
        if (poLayer == nullptr)
525
0
        {
526
0
            *pzErr =
527
0
                sqlite3_mprintf("Cannot find layer '%s' in '%s'",
528
0
                                osLayerName.c_str(), poDS->GetDescription());
529
0
            return SQLITE_ERROR;
530
0
        }
531
532
0
        bExposeOGR_STYLE = atoi(SQLUnescape(argv[5])) != 0;
533
0
        bExposeOGRNativeData =
534
0
            (argc == 7) ? atoi(SQLUnescape(argv[6])) != 0 : false;
535
0
    }
536
0
#ifdef VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
537
    /* -------------------------------------------------------------------- */
538
    /*      If called from outside (OGR loaded as a sqlite3 extension)      */
539
    /* -------------------------------------------------------------------- */
540
0
    else
541
0
    {
542
0
        if (argc < 4 || argc > 8)
543
0
        {
544
0
            *pzErr = sqlite3_mprintf(
545
0
                "Expected syntax: CREATE VIRTUAL TABLE xxx USING "
546
0
                "VirtualOGR(datasource_name[, update_mode, [layer_name[, "
547
0
                "expose_ogr_style[, expose_ogr_native_data]]]])");
548
0
            return SQLITE_ERROR;
549
0
        }
550
551
0
        if (OGR2SQLITEDetectSuspiciousUsage(hDB, argv[2], pzErr))
552
0
        {
553
0
            return SQLITE_ERROR;
554
0
        }
555
556
0
        CPLString osDSName(SQLUnescape(argv[3]));
557
0
        CPLString osUpdate(SQLUnescape((argc >= 5) ? argv[4] : "0"));
558
559
0
        if (!EQUAL(osUpdate, "1") && !EQUAL(osUpdate, "0"))
560
0
        {
561
0
            *pzErr = sqlite3_mprintf("update_mode parameter should be 0 or 1");
562
0
            return SQLITE_ERROR;
563
0
        }
564
565
0
        const bool bUpdate = atoi(osUpdate) != 0;
566
567
0
        poDS = GDALDataset::Open(
568
0
            osDSName.c_str(),
569
0
            GDAL_OF_VECTOR | (bUpdate ? GDAL_OF_UPDATE : GDAL_OF_READONLY),
570
0
            nullptr, nullptr, nullptr);
571
0
        if (poDS == nullptr)
572
0
        {
573
0
            *pzErr = sqlite3_mprintf("Cannot open datasource '%s'",
574
0
                                     osDSName.c_str());
575
0
            return SQLITE_ERROR;
576
0
        }
577
578
0
        CPLString osLayerName;
579
0
        if (argc >= 6)
580
0
        {
581
0
            osLayerName = SQLUnescape(argv[5]);
582
0
            poLayer = poDS->GetLayerByName(osLayerName);
583
0
        }
584
0
        else
585
0
        {
586
0
            if (poDS->GetLayerCount() == 0)
587
0
            {
588
0
                *pzErr = sqlite3_mprintf("Datasource '%s' has no layers",
589
0
                                         osDSName.c_str());
590
0
                poDS->Release();
591
0
                return SQLITE_ERROR;
592
0
            }
593
594
0
            if (poDS->GetLayerCount() > 1)
595
0
            {
596
0
                *pzErr =
597
0
                    sqlite3_mprintf("Datasource '%s' has more than one layers, "
598
0
                                    "and none was explicitly selected.",
599
0
                                    osDSName.c_str());
600
0
                poDS->Release();
601
0
                return SQLITE_ERROR;
602
0
            }
603
604
0
            poLayer = poDS->GetLayer(0);
605
0
        }
606
607
0
        if (poLayer == nullptr)
608
0
        {
609
0
            *pzErr = sqlite3_mprintf("Cannot find layer '%s' in '%s'",
610
0
                                     osLayerName.c_str(), osDSName.c_str());
611
0
            poDS->Release();
612
0
            return SQLITE_ERROR;
613
0
        }
614
615
0
        if (argc >= 7)
616
0
        {
617
0
            bExposeOGR_STYLE = atoi(SQLUnescape(argv[6])) != 0;
618
0
        }
619
0
        if (argc >= 8)
620
0
        {
621
0
            bExposeOGRNativeData = atoi(SQLUnescape(argv[7])) != 0;
622
0
        }
623
624
0
        bCloseDS = true;
625
0
    }
626
0
#endif  // VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
627
0
    OGR2SQLITE_vtab *vtab =
628
0
        static_cast<OGR2SQLITE_vtab *>(CPLCalloc(1, sizeof(OGR2SQLITE_vtab)));
629
    /* We do not need to fill the non-extended fields */
630
0
    vtab->pszVTableName = CPLStrdup(SQLEscapeName(argv[2]));
631
0
    vtab->poModule = poModule;
632
0
    vtab->poDS = poDS;
633
0
    vtab->bCloseDS = bCloseDS;
634
0
    vtab->poLayer = poLayer;
635
0
    vtab->nMyRef = 0;
636
637
0
    poModule->RegisterVTable(vtab->pszVTableName, poLayer);
638
639
0
    *ppVTab = reinterpret_cast<sqlite3_vtab *>(vtab);
640
641
0
    CPLString osSQL;
642
0
    osSQL = "CREATE TABLE ";
643
0
    osSQL += "\"";
644
0
    osSQL += SQLEscapeName(argv[2]);
645
0
    osSQL += "\"";
646
0
    osSQL += "(";
647
648
0
    bool bAddComma = false;
649
650
0
    const OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
651
652
0
    const char *pszFIDColumn = poLayer->GetFIDColumn();
653
0
    std::set<std::string> oSetNamesUC;
654
0
    if (pszFIDColumn[0])
655
0
    {
656
0
        osSQL += "\"";
657
0
        osSQL += SQLEscapeName(pszFIDColumn);
658
0
        oSetNamesUC.insert(CPLString(pszFIDColumn).toupper());
659
0
        if (poFDefn->GetFieldIndex(pszFIDColumn) >= 0)
660
0
            osSQL += "\" INTEGER PRIMARY KEY NOT NULL";
661
0
        else
662
0
            osSQL += "\" INTEGER HIDDEN PRIMARY KEY NOT NULL";
663
0
        bAddComma = true;
664
0
        vtab->bHasFIDColumn = true;
665
0
    }
666
667
0
    bool bHasOGR_STYLEField = false;
668
0
    for (int i = 0; i < poFDefn->GetFieldCount(); i++)
669
0
    {
670
0
        const OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn(i);
671
672
0
        if (bAddComma)
673
0
            osSQL += ",";
674
0
        bAddComma = true;
675
676
0
        if (EQUAL(poFieldDefn->GetNameRef(), "OGR_STYLE"))
677
0
            bHasOGR_STYLEField = true;
678
679
0
        CPLString osFieldName(poFieldDefn->GetNameRef());
680
0
        int nCounter = 2;
681
0
        while (oSetNamesUC.find(CPLString(osFieldName).toupper()) !=
682
0
               oSetNamesUC.end())
683
0
        {
684
0
            do
685
0
            {
686
0
                osFieldName.Printf("%s%d", poFieldDefn->GetNameRef(), nCounter);
687
0
                nCounter++;
688
0
            } while (poFDefn->GetFieldIndex(osFieldName) >= 0);
689
0
        }
690
0
        oSetNamesUC.insert(CPLString(osFieldName).toupper());
691
692
0
        osSQL += "\"";
693
0
        osSQL += SQLEscapeName(osFieldName);
694
0
        osSQL += "\"";
695
0
        osSQL += " ";
696
697
0
        std::string osType(OGRSQLiteFieldDefnToSQliteFieldDefn(
698
0
            poFieldDefn, bInternalUse, false));
699
0
        if (bInternalUse)
700
0
        {
701
0
            const auto &osDomainName = poFieldDefn->GetDomainName();
702
0
            if (!osDomainName.empty())
703
0
            {
704
                // Avoids illegal VARCHAR(n)_BEGIN_DOMAIN_NAME_... to be
705
                // emitted
706
0
                if (poFieldDefn->GetType() == OFTString)
707
0
                    osType = "VARCHAR";
708
0
                osType += "_BEGIN_DOMAIN_NAME_";
709
0
                char *pszEncoded = CPLBinaryToHex(
710
0
                    static_cast<int>(osDomainName.size()),
711
0
                    reinterpret_cast<const GByte *>(osDomainName.data()));
712
0
                osType += pszEncoded;
713
0
                CPLFree(pszEncoded);
714
0
                osType += "_END_DOMAIN_NAME";
715
0
            }
716
0
        }
717
0
        osSQL += osType;
718
719
0
        if (EQUAL(poFieldDefn->GetNameRef(), pszFIDColumn))
720
0
            osSQL += " HIDDEN";
721
0
    }
722
723
0
    if (bAddComma)
724
0
        osSQL += ",";
725
726
0
    if (bHasOGR_STYLEField)
727
0
    {
728
0
        osSQL += "'dummy' VARCHAR HIDDEN";
729
0
    }
730
0
    else
731
0
    {
732
0
        osSQL += "OGR_STYLE VARCHAR";
733
0
        if (!bExposeOGR_STYLE)
734
0
            osSQL += " HIDDEN";
735
0
    }
736
737
0
    for (int i = 0; i < poFDefn->GetGeomFieldCount(); i++)
738
0
    {
739
0
        osSQL += ",";
740
741
0
        const OGRGeomFieldDefn *poFieldDefn = poFDefn->GetGeomFieldDefn(i);
742
743
0
        osSQL += "\"";
744
0
        if (i == 0)
745
0
            osSQL +=
746
0
                SQLEscapeName(OGR2SQLITE_GetNameForGeometryColumn(poLayer));
747
0
        else
748
0
            osSQL += SQLEscapeName(poFieldDefn->GetNameRef());
749
0
        osSQL += "\"";
750
0
        osSQL += " BLOB";
751
752
        /* We use a special column type, e.g. BLOB_POINT_25D_4326 */
753
        /* when the virtual table is created by OGRSQLiteExecuteSQL() */
754
        /* and thus for internal use only. */
755
0
        if (bInternalUse)
756
0
        {
757
0
            osSQL += "_";
758
0
            osSQL += OGRToOGCGeomType(poFieldDefn->GetType());
759
0
            osSQL += "_XY";
760
0
            if (wkbHasZ(poFieldDefn->GetType()))
761
0
                osSQL += "Z";
762
0
            if (wkbHasM(poFieldDefn->GetType()))
763
0
                osSQL += "M";
764
0
            const OGRSpatialReference *poSRS = poFieldDefn->GetSpatialRef();
765
0
            if (poSRS == nullptr && i == 0)
766
0
                poSRS = poLayer->GetSpatialRef();
767
0
            int nSRID = poModule->FetchSRSId(poSRS);
768
0
            if (nSRID >= 0)
769
0
            {
770
0
                osSQL += "_";
771
0
                osSQL += CPLSPrintf("%d", nSRID);
772
0
            }
773
0
        }
774
0
    }
775
776
0
    osSQL += ", OGR_NATIVE_DATA VARCHAR";
777
0
    if (!bExposeOGRNativeData)
778
0
        osSQL += " HIDDEN";
779
0
    osSQL += ", OGR_NATIVE_MEDIA_TYPE VARCHAR";
780
0
    if (!bExposeOGRNativeData)
781
0
        osSQL += " HIDDEN";
782
783
0
    osSQL += ")";
784
785
0
    CPLDebug("OGR2SQLITE", "sqlite3_declare_vtab(%s)", osSQL.c_str());
786
0
    if (sqlite3_declare_vtab(hDB, osSQL.c_str()) != SQLITE_OK)
787
0
    {
788
0
        *pzErr = sqlite3_mprintf("CREATE VIRTUAL: invalid SQL statement : %s",
789
0
                                 osSQL.c_str());
790
0
        OGR2SQLITE_DisconnectDestroy(reinterpret_cast<sqlite3_vtab *>(vtab));
791
0
        return SQLITE_ERROR;
792
0
    }
793
794
0
    return SQLITE_OK;
795
0
}
796
797
/************************************************************************/
798
/*                       OGR2SQLITE_IsHandledOp()                       */
799
/************************************************************************/
800
801
static bool OGR2SQLITE_IsHandledOp(int op)
802
0
{
803
0
    switch (op)
804
0
    {
805
0
        case SQLITE_INDEX_CONSTRAINT_EQ:
806
0
            return true;
807
0
        case SQLITE_INDEX_CONSTRAINT_GT:
808
0
            return true;
809
0
        case SQLITE_INDEX_CONSTRAINT_LE:
810
0
            return true;
811
0
        case SQLITE_INDEX_CONSTRAINT_LT:
812
0
            return true;
813
0
        case SQLITE_INDEX_CONSTRAINT_GE:
814
0
            return true;
815
0
        case SQLITE_INDEX_CONSTRAINT_MATCH:
816
0
            return false;  // unhandled
817
0
#ifdef SQLITE_INDEX_CONSTRAINT_LIKE
818
        /* SQLite >= 3.10 */
819
0
        case SQLITE_INDEX_CONSTRAINT_LIKE:
820
0
            return true;
821
0
        case SQLITE_INDEX_CONSTRAINT_GLOB:
822
0
            return false;  // unhandled
823
0
        case SQLITE_INDEX_CONSTRAINT_REGEXP:
824
0
            return false;  // unhandled
825
0
#endif
826
0
#ifdef SQLITE_INDEX_CONSTRAINT_NE
827
            /* SQLite >= 3.21 */
828
0
        case SQLITE_INDEX_CONSTRAINT_NE:
829
0
            return true;
830
0
        case SQLITE_INDEX_CONSTRAINT_ISNOT:
831
0
            return false;  // OGR SQL only handles IS [NOT] NULL
832
0
        case SQLITE_INDEX_CONSTRAINT_ISNOTNULL:
833
0
            return true;
834
0
        case SQLITE_INDEX_CONSTRAINT_ISNULL:
835
0
            return true;
836
0
            ;
837
0
        case SQLITE_INDEX_CONSTRAINT_IS:
838
0
            return false;  // OGR SQL only handles IS [NOT] NULL
839
0
#endif
840
0
        default:
841
0
            break;
842
0
    }
843
0
    return false;
844
0
}
845
846
/************************************************************************/
847
/*                        OGR2SQLITE_BestIndex()                        */
848
/************************************************************************/
849
850
static int OGR2SQLITE_BestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pIndex)
851
0
{
852
0
    OGR2SQLITE_vtab *pMyVTab = reinterpret_cast<OGR2SQLITE_vtab *>(pVTab);
853
0
    OGRFeatureDefn *poFDefn = pMyVTab->poLayer->GetLayerDefn();
854
855
#ifdef DEBUG_OGR2SQLITE
856
    CPLString osQueryPatternUsable, osQueryPatternNotUsable;
857
    for (int i = 0; i < pIndex->nConstraint; i++)
858
    {
859
        int iCol = pIndex->aConstraint[i].iColumn;
860
        const char *pszFieldName = NULL;
861
862
        if (pMyVTab->bHasFIDColumn && iCol >= 0)
863
            --iCol;
864
865
        if (iCol == -1)
866
            pszFieldName = "FID";
867
        else if (iCol >= 0 && iCol < poFDefn->GetFieldCount())
868
            pszFieldName = poFDefn->GetFieldDefn(iCol)->GetNameRef();
869
        else
870
            pszFieldName = "unknown_field";
871
872
        const char *pszOp = NULL;
873
        switch (pIndex->aConstraint[i].op)
874
        {
875
            case SQLITE_INDEX_CONSTRAINT_EQ:
876
                pszOp = " = ";
877
                break;
878
            case SQLITE_INDEX_CONSTRAINT_GT:
879
                pszOp = " > ";
880
                break;
881
            case SQLITE_INDEX_CONSTRAINT_LE:
882
                pszOp = " <= ";
883
                break;
884
            case SQLITE_INDEX_CONSTRAINT_LT:
885
                pszOp = " < ";
886
                break;
887
            case SQLITE_INDEX_CONSTRAINT_GE:
888
                pszOp = " >= ";
889
                break;
890
            case SQLITE_INDEX_CONSTRAINT_MATCH:
891
                pszOp = " MATCH ";
892
                break;
893
#ifdef SQLITE_INDEX_CONSTRAINT_LIKE
894
            /* SQLite >= 3.10 */
895
            case SQLITE_INDEX_CONSTRAINT_LIKE:
896
                pszOp = " LIKE ";
897
                break;
898
            case SQLITE_INDEX_CONSTRAINT_GLOB:
899
                pszOp = " GLOB ";
900
                break;
901
            case SQLITE_INDEX_CONSTRAINT_REGEXP:
902
                pszOp = " REGEXP ";
903
                break;
904
#endif
905
#ifdef SQLITE_INDEX_CONSTRAINT_NE
906
            /* SQLite >= 3.21 */
907
            case SQLITE_INDEX_CONSTRAINT_NE:
908
                pszOp = " <> ";
909
                break;
910
            case SQLITE_INDEX_CONSTRAINT_ISNOT:
911
                pszOp = " IS NOT ";
912
                break;
913
            case SQLITE_INDEX_CONSTRAINT_ISNOTNULL:
914
                pszOp = " IS NOT NULL";
915
                break;
916
            case SQLITE_INDEX_CONSTRAINT_ISNULL:
917
                pszOp = " IS NULL";
918
                break;
919
            case SQLITE_INDEX_CONSTRAINT_IS:
920
                pszOp = " IS ";
921
                break;
922
#endif
923
            default:
924
                pszOp = " (unknown op) ";
925
                break;
926
        }
927
928
        if (pIndex->aConstraint[i].usable)
929
        {
930
            if (!osQueryPatternUsable.empty())
931
                osQueryPatternUsable += " AND ";
932
            osQueryPatternUsable += pszFieldName;
933
            osQueryPatternUsable += pszOp;
934
            osQueryPatternUsable += "?";
935
        }
936
        else
937
        {
938
            if (!osQueryPatternNotUsable.empty())
939
                osQueryPatternNotUsable += " AND ";
940
            osQueryPatternNotUsable += pszFieldName;
941
            osQueryPatternNotUsable += pszOp;
942
            osQueryPatternNotUsable += "?";
943
        }
944
    }
945
    CPLDebug("OGR2SQLITE", "BestIndex, usable ( %s ), not usable ( %s )",
946
             osQueryPatternUsable.c_str(), osQueryPatternNotUsable.c_str());
947
#endif
948
949
0
    int nConstraints = 0;
950
0
    for (int i = 0; i < pIndex->nConstraint; i++)
951
0
    {
952
0
        int iCol = pIndex->aConstraint[i].iColumn;
953
954
0
        if (pMyVTab->bHasFIDColumn && iCol >= 0)
955
0
            --iCol;
956
957
0
        if (pIndex->aConstraint[i].usable &&
958
0
            OGR2SQLITE_IsHandledOp(pIndex->aConstraint[i].op) &&
959
0
            iCol < poFDefn->GetFieldCount() &&
960
0
            (iCol < 0 || poFDefn->GetFieldDefn(iCol)->GetType() != OFTBinary))
961
0
        {
962
0
            pIndex->aConstraintUsage[i].argvIndex = nConstraints + 1;
963
0
            pIndex->aConstraintUsage[i].omit = true;
964
965
0
            nConstraints++;
966
0
        }
967
0
        else
968
0
        {
969
0
            pIndex->aConstraintUsage[i].argvIndex = 0;
970
0
            pIndex->aConstraintUsage[i].omit = false;
971
0
        }
972
0
    }
973
974
0
    int *panConstraints = nullptr;
975
976
0
    if (nConstraints)
977
0
    {
978
0
        panConstraints = static_cast<int *>(sqlite3_malloc(
979
0
            static_cast<int>(sizeof(int)) * (1 + 2 * nConstraints)));
980
0
        panConstraints[0] = nConstraints;
981
982
0
        nConstraints = 0;
983
984
0
        for (int i = 0; i < pIndex->nConstraint; i++)
985
0
        {
986
0
            if (pIndex->aConstraintUsage[i].omit)
987
0
            {
988
0
                panConstraints[2 * nConstraints + 1] =
989
0
                    pIndex->aConstraint[i].iColumn;
990
0
                panConstraints[2 * nConstraints + 2] =
991
0
                    pIndex->aConstraint[i].op;
992
993
0
                nConstraints++;
994
0
            }
995
0
        }
996
0
    }
997
998
0
    pIndex->orderByConsumed = false;
999
0
    pIndex->idxNum = 0;
1000
1001
0
    if (nConstraints != 0)
1002
0
    {
1003
0
        pIndex->idxStr = reinterpret_cast<char *>(panConstraints);
1004
0
        pIndex->needToFreeIdxStr = true;
1005
0
    }
1006
0
    else
1007
0
    {
1008
0
        pIndex->idxStr = nullptr;
1009
0
        pIndex->needToFreeIdxStr = false;
1010
0
    }
1011
1012
0
    return SQLITE_OK;
1013
0
}
1014
1015
/************************************************************************/
1016
/*                      OGR2SQLITE_DisconnectDestroy()                  */
1017
/************************************************************************/
1018
1019
static int OGR2SQLITE_DisconnectDestroy(sqlite3_vtab *pVTab)
1020
0
{
1021
0
    OGR2SQLITE_vtab *pMyVTab = reinterpret_cast<OGR2SQLITE_vtab *>(pVTab);
1022
1023
#ifdef DEBUG_OGR2SQLITE
1024
    CPLDebug("OGR2SQLITE", "DisconnectDestroy(%s)", pMyVTab->pszVTableName);
1025
#endif
1026
1027
0
    sqlite3_free(pMyVTab->zErrMsg);
1028
0
    if (pMyVTab->bCloseDS)
1029
0
        pMyVTab->poDS->Release();
1030
0
    pMyVTab->poModule->UnregisterVTable(pMyVTab->pszVTableName);
1031
0
    CPLFree(pMyVTab->pszVTableName);
1032
0
    CPLFree(pMyVTab);
1033
1034
0
    return SQLITE_OK;
1035
0
}
1036
1037
/************************************************************************/
1038
/*                           OGR2SQLITE_Open()                          */
1039
/************************************************************************/
1040
1041
static int OGR2SQLITE_Open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor)
1042
0
{
1043
0
    OGR2SQLITE_vtab *pMyVTab = reinterpret_cast<OGR2SQLITE_vtab *>(pVTab);
1044
#ifdef DEBUG_OGR2SQLITE
1045
    CPLDebug("OGR2SQLITE", "Open(%s, %s)", pMyVTab->poDS->GetDescription(),
1046
             pMyVTab->poLayer->GetDescription());
1047
#endif
1048
1049
0
    GDALDataset *poDupDataSource = nullptr;
1050
0
    OGRLayer *poLayer = nullptr;
1051
1052
0
    if (pMyVTab->nMyRef == 0)
1053
0
    {
1054
0
        poLayer = pMyVTab->poLayer;
1055
0
    }
1056
0
    else
1057
0
    {
1058
0
        poDupDataSource = GDALDataset::FromHandle(
1059
0
            OGROpen(pMyVTab->poDS->GetDescription(), FALSE, nullptr));
1060
0
        if (poDupDataSource == nullptr)
1061
0
            return SQLITE_ERROR;
1062
0
        poLayer = poDupDataSource->GetLayerByName(pMyVTab->poLayer->GetName());
1063
0
        if (poLayer == nullptr)
1064
0
        {
1065
0
            delete poDupDataSource;
1066
0
            return SQLITE_ERROR;
1067
0
        }
1068
0
        if (!poLayer->GetLayerDefn()->IsSame(pMyVTab->poLayer->GetLayerDefn()))
1069
0
        {
1070
0
            delete poDupDataSource;
1071
0
            return SQLITE_ERROR;
1072
0
        }
1073
0
    }
1074
0
    pMyVTab->nMyRef++;
1075
1076
0
    OGR2SQLITE_vtab_cursor *pCursor = static_cast<OGR2SQLITE_vtab_cursor *>(
1077
0
        CPLCalloc(1, sizeof(OGR2SQLITE_vtab_cursor)));
1078
    // We do not need to fill the non-extended fields.
1079
0
    *ppCursor = reinterpret_cast<sqlite3_vtab_cursor *>(pCursor);
1080
1081
0
    pCursor->poDupDataSource = poDupDataSource;
1082
0
    pCursor->poLayer = poLayer;
1083
0
    pCursor->poLayer->ResetReading();
1084
0
    pCursor->poFeature = nullptr;
1085
0
    pCursor->nNextWishedIndex = 0;
1086
0
    pCursor->nCurFeatureIndex = -1;
1087
0
    pCursor->nFeatureCount = -1;
1088
1089
0
    pCursor->pabyGeomBLOB = nullptr;
1090
0
    pCursor->nGeomBLOBLen = -1;
1091
1092
0
    return SQLITE_OK;
1093
0
}
1094
1095
/************************************************************************/
1096
/*                           OGR2SQLITE_Close()                         */
1097
/************************************************************************/
1098
1099
static int OGR2SQLITE_Close(sqlite3_vtab_cursor *pCursor)
1100
0
{
1101
0
    OGR2SQLITE_vtab_cursor *pMyCursor =
1102
0
        reinterpret_cast<OGR2SQLITE_vtab_cursor *>(pCursor);
1103
0
    OGR2SQLITE_vtab *pMyVTab = pMyCursor->pVTab;
1104
#ifdef DEBUG_OGR2SQLITE
1105
    CPLDebug("OGR2SQLITE", "Close(%s, %s)", pMyVTab->poDS->GetDescription(),
1106
             pMyVTab->poLayer->GetDescription());
1107
#endif
1108
0
    pMyVTab->nMyRef--;
1109
1110
0
    delete pMyCursor->poFeature;
1111
0
    delete pMyCursor->poDupDataSource;
1112
1113
0
    CPLFree(pMyCursor->pabyGeomBLOB);
1114
1115
0
    CPLFree(pCursor);
1116
1117
0
    return SQLITE_OK;
1118
0
}
1119
1120
/************************************************************************/
1121
/*                          OGR2SQLITE_Filter()                         */
1122
/************************************************************************/
1123
1124
static int OGR2SQLITE_Filter(sqlite3_vtab_cursor *pCursor,
1125
                             CPL_UNUSED int idxNum, const char *idxStr,
1126
                             int argc, sqlite3_value **argv)
1127
0
{
1128
0
    OGR2SQLITE_vtab_cursor *pMyCursor =
1129
0
        reinterpret_cast<OGR2SQLITE_vtab_cursor *>(pCursor);
1130
#ifdef DEBUG_OGR2SQLITE
1131
    CPLDebug("OGR2SQLITE", "Filter");
1132
#endif
1133
1134
0
    const int *panConstraints = reinterpret_cast<const int *>(idxStr);
1135
0
    int nConstraints = panConstraints ? panConstraints[0] : 0;
1136
1137
0
    if (nConstraints != argc)
1138
0
        return SQLITE_ERROR;
1139
1140
0
    CPLString osAttributeFilter;
1141
1142
0
    OGRFeatureDefn *poFDefn = pMyCursor->poLayer->GetLayerDefn();
1143
1144
0
    for (int i = 0; i < argc; i++)
1145
0
    {
1146
0
        int nCol = panConstraints[2 * i + 1];
1147
0
        OGRFieldDefn *poFieldDefn = nullptr;
1148
1149
0
        if (pMyCursor->pVTab->bHasFIDColumn && nCol >= 0)
1150
0
        {
1151
0
            --nCol;
1152
0
        }
1153
1154
0
        if (nCol >= 0)
1155
0
        {
1156
0
            poFieldDefn = poFDefn->GetFieldDefn(nCol);
1157
0
            if (poFieldDefn == nullptr)
1158
0
                return SQLITE_ERROR;
1159
0
        }
1160
1161
0
        if (i != 0)
1162
0
            osAttributeFilter += " AND ";
1163
1164
0
        if (poFieldDefn != nullptr)
1165
0
        {
1166
0
            const char *pszFieldName = poFieldDefn->GetNameRef();
1167
0
            char ch = '\0';
1168
0
            bool bNeedsQuoting = swq_is_reserved_keyword(pszFieldName) != 0;
1169
0
            for (int j = 0; !bNeedsQuoting && (ch = pszFieldName[j]) != '\0';
1170
0
                 j++)
1171
0
            {
1172
0
                if (!(isalnum(static_cast<unsigned char>(ch)) || ch == '_'))
1173
0
                    bNeedsQuoting = true;
1174
0
            }
1175
1176
0
            if (bNeedsQuoting)
1177
0
            {
1178
0
                osAttributeFilter += '"';
1179
0
                osAttributeFilter += SQLEscapeName(pszFieldName);
1180
0
                osAttributeFilter += '"';
1181
0
            }
1182
0
            else
1183
0
            {
1184
0
                osAttributeFilter += pszFieldName;
1185
0
            }
1186
0
        }
1187
0
        else
1188
0
        {
1189
0
            const char *pszSrcFIDColumn = pMyCursor->poLayer->GetFIDColumn();
1190
0
            if (pszSrcFIDColumn && *pszSrcFIDColumn != '\0')
1191
0
            {
1192
0
                osAttributeFilter += '"';
1193
0
                osAttributeFilter += SQLEscapeName(pszSrcFIDColumn);
1194
0
                osAttributeFilter += '"';
1195
0
            }
1196
0
            else
1197
0
            {
1198
0
                osAttributeFilter += "FID";
1199
0
            }
1200
0
        }
1201
1202
0
        bool bExpectRightOperator = true;
1203
0
        std::string osOp;
1204
0
        const auto eSQLiteConstraintOp = panConstraints[2 * i + 2];
1205
0
        switch (eSQLiteConstraintOp)
1206
0
        {
1207
0
            case SQLITE_INDEX_CONSTRAINT_EQ:
1208
0
                osOp = " = ";
1209
0
                break;
1210
0
            case SQLITE_INDEX_CONSTRAINT_GT:
1211
0
                osAttributeFilter += " > ";
1212
0
                break;
1213
0
            case SQLITE_INDEX_CONSTRAINT_LE:
1214
0
                osAttributeFilter += " <= ";
1215
0
                break;
1216
0
            case SQLITE_INDEX_CONSTRAINT_LT:
1217
0
                osAttributeFilter += " < ";
1218
0
                break;
1219
0
            case SQLITE_INDEX_CONSTRAINT_GE:
1220
0
                osAttributeFilter += " >= ";
1221
0
                break;
1222
                // unhandled: SQLITE_INDEX_CONSTRAINT_MATCH
1223
0
#ifdef SQLITE_INDEX_CONSTRAINT_LIKE
1224
            /* SQLite >= 3.10 */
1225
0
            case SQLITE_INDEX_CONSTRAINT_LIKE:
1226
0
                osAttributeFilter += " LIKE ";
1227
0
                break;
1228
                // unhandled: SQLITE_INDEX_CONSTRAINT_GLOB
1229
                // unhandled: SQLITE_INDEX_CONSTRAINT_REGEXP
1230
0
#endif
1231
0
#ifdef SQLITE_INDEX_CONSTRAINT_NE
1232
            /* SQLite >= 3.21 */
1233
0
            case SQLITE_INDEX_CONSTRAINT_NE:
1234
0
                osAttributeFilter += " <> ";
1235
0
                break;
1236
            // case SQLITE_INDEX_CONSTRAINT_ISNOT: osAttributeFilter += " IS NOT
1237
            // "; break;
1238
0
            case SQLITE_INDEX_CONSTRAINT_ISNOTNULL:
1239
0
                osAttributeFilter += " IS NOT NULL";
1240
0
                bExpectRightOperator = false;
1241
0
                break;
1242
0
            case SQLITE_INDEX_CONSTRAINT_ISNULL:
1243
0
                osAttributeFilter += " IS NULL";
1244
0
                bExpectRightOperator = false;
1245
0
                break;
1246
                // case SQLITE_INDEX_CONSTRAINT_IS: osAttributeFilter += " IS ";
1247
                // break;
1248
0
#endif
1249
0
            default:
1250
0
            {
1251
0
                sqlite3_free(pMyCursor->pVTab->zErrMsg);
1252
0
                pMyCursor->pVTab->zErrMsg =
1253
0
                    sqlite3_mprintf("Unhandled constraint operator : %d",
1254
0
                                    panConstraints[2 * i + 2]);
1255
0
                return SQLITE_ERROR;
1256
0
            }
1257
0
        }
1258
1259
0
        if (bExpectRightOperator)
1260
0
        {
1261
0
            const auto eSQLiteType = sqlite3_value_type(argv[i]);
1262
0
            if (eSQLiteType == SQLITE_INTEGER)
1263
0
            {
1264
0
                osAttributeFilter += osOp;
1265
0
                osAttributeFilter +=
1266
0
                    CPLSPrintf(CPL_FRMT_GIB, sqlite3_value_int64(argv[i]));
1267
0
            }
1268
0
            else if (eSQLiteType == SQLITE_FLOAT)
1269
0
            {  // Insure that only Decimal.Points are used, never local settings
1270
                // such as Decimal.Comma.
1271
0
                osAttributeFilter += osOp;
1272
0
                osAttributeFilter +=
1273
0
                    CPLSPrintf("%.17g", sqlite3_value_double(argv[i]));
1274
0
            }
1275
0
            else if (eSQLiteType == SQLITE_TEXT)
1276
0
            {
1277
0
                osAttributeFilter += osOp;
1278
0
                osAttributeFilter += "'";
1279
0
                osAttributeFilter +=
1280
0
                    SQLEscapeLiteral(reinterpret_cast<const char *>(
1281
0
                        sqlite3_value_text(argv[i])));
1282
0
                osAttributeFilter += "'";
1283
0
            }
1284
0
            else if (eSQLiteConstraintOp == SQLITE_INDEX_CONSTRAINT_EQ &&
1285
0
                     eSQLiteType == SQLITE_NULL)
1286
0
            {
1287
0
                osAttributeFilter += " IN (NULL)";
1288
0
            }
1289
0
            else
1290
0
            {
1291
0
                sqlite3_free(pMyCursor->pVTab->zErrMsg);
1292
0
                pMyCursor->pVTab->zErrMsg = sqlite3_mprintf(
1293
0
                    "Unhandled constraint data type : %d", eSQLiteType);
1294
0
                return SQLITE_ERROR;
1295
0
            }
1296
0
        }
1297
0
    }
1298
1299
#ifdef DEBUG_OGR2SQLITE
1300
    CPLDebug("OGR2SQLITE", "Attribute filter : %s", osAttributeFilter.c_str());
1301
#endif
1302
1303
0
    if (pMyCursor->poLayer->SetAttributeFilter(!osAttributeFilter.empty()
1304
0
                                                   ? osAttributeFilter.c_str()
1305
0
                                                   : nullptr) != OGRERR_NONE)
1306
0
    {
1307
0
        sqlite3_free(pMyCursor->pVTab->zErrMsg);
1308
0
        pMyCursor->pVTab->zErrMsg = sqlite3_mprintf(
1309
0
            "Cannot apply attribute filter : %s", osAttributeFilter.c_str());
1310
0
        return SQLITE_ERROR;
1311
0
    }
1312
1313
0
    if (pMyCursor->poLayer->TestCapability(OLCFastFeatureCount))
1314
0
        pMyCursor->nFeatureCount = pMyCursor->poLayer->GetFeatureCount();
1315
0
    else
1316
0
        pMyCursor->nFeatureCount = -1;
1317
0
    pMyCursor->poLayer->ResetReading();
1318
1319
0
    if (pMyCursor->nFeatureCount < 0)
1320
0
    {
1321
0
        pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
1322
#ifdef DEBUG_OGR2SQLITE
1323
        CPLDebug("OGR2SQLITE", "GetNextFeature() --> " CPL_FRMT_GIB,
1324
                 pMyCursor->poFeature ? pMyCursor->poFeature->GetFID() : -1);
1325
#endif
1326
0
    }
1327
1328
0
    pMyCursor->nNextWishedIndex = 0;
1329
0
    pMyCursor->nCurFeatureIndex = -1;
1330
1331
0
    return SQLITE_OK;
1332
0
}
1333
1334
/************************************************************************/
1335
/*                          OGR2SQLITE_Next()                           */
1336
/************************************************************************/
1337
1338
static int OGR2SQLITE_Next(sqlite3_vtab_cursor *pCursor)
1339
0
{
1340
0
    OGR2SQLITE_vtab_cursor *pMyCursor =
1341
0
        reinterpret_cast<OGR2SQLITE_vtab_cursor *>(pCursor);
1342
#ifdef DEBUG_OGR2SQLITE
1343
    CPLDebug("OGR2SQLITE", "Next");
1344
#endif
1345
1346
0
    pMyCursor->nNextWishedIndex++;
1347
0
    if (pMyCursor->nFeatureCount < 0)
1348
0
    {
1349
0
        delete pMyCursor->poFeature;
1350
0
        pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
1351
1352
0
        CPLFree(pMyCursor->pabyGeomBLOB);
1353
0
        pMyCursor->pabyGeomBLOB = nullptr;
1354
0
        pMyCursor->nGeomBLOBLen = -1;
1355
1356
#ifdef DEBUG_OGR2SQLITE
1357
        CPLDebug("OGR2SQLITE", "GetNextFeature() --> " CPL_FRMT_GIB,
1358
                 pMyCursor->poFeature ? pMyCursor->poFeature->GetFID() : -1);
1359
#endif
1360
0
    }
1361
0
    return SQLITE_OK;
1362
0
}
1363
1364
/************************************************************************/
1365
/*                          OGR2SQLITE_Eof()                            */
1366
/************************************************************************/
1367
1368
static int OGR2SQLITE_Eof(sqlite3_vtab_cursor *pCursor)
1369
0
{
1370
0
    OGR2SQLITE_vtab_cursor *pMyCursor =
1371
0
        reinterpret_cast<OGR2SQLITE_vtab_cursor *>(pCursor);
1372
#ifdef DEBUG_OGR2SQLITE
1373
    CPLDebug("OGR2SQLITE", "Eof");
1374
#endif
1375
1376
0
    if (pMyCursor->nFeatureCount < 0)
1377
0
    {
1378
0
        return pMyCursor->poFeature == nullptr;
1379
0
    }
1380
0
    else
1381
0
    {
1382
0
        return pMyCursor->nNextWishedIndex >= pMyCursor->nFeatureCount;
1383
0
    }
1384
0
}
1385
1386
/************************************************************************/
1387
/*                      OGR2SQLITE_GoToWishedIndex()                    */
1388
/************************************************************************/
1389
1390
static void OGR2SQLITE_GoToWishedIndex(OGR2SQLITE_vtab_cursor *pMyCursor)
1391
0
{
1392
0
    if (pMyCursor->nFeatureCount >= 0)
1393
0
    {
1394
0
        if (pMyCursor->nCurFeatureIndex < pMyCursor->nNextWishedIndex)
1395
0
        {
1396
0
            do
1397
0
            {
1398
0
                pMyCursor->nCurFeatureIndex++;
1399
1400
0
                delete pMyCursor->poFeature;
1401
0
                pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
1402
#ifdef DEBUG_OGR2SQLITE
1403
                CPLDebug("OGR2SQLITE", "GetNextFeature() --> " CPL_FRMT_GIB,
1404
                         pMyCursor->poFeature ? pMyCursor->poFeature->GetFID()
1405
                                              : -1);
1406
#endif
1407
0
            } while (pMyCursor->nCurFeatureIndex < pMyCursor->nNextWishedIndex);
1408
1409
0
            CPLFree(pMyCursor->pabyGeomBLOB);
1410
0
            pMyCursor->pabyGeomBLOB = nullptr;
1411
0
            pMyCursor->nGeomBLOBLen = -1;
1412
0
        }
1413
0
    }
1414
0
}
1415
1416
/************************************************************************/
1417
/*                    OGR2SQLITE_ExportGeometry()                       */
1418
/************************************************************************/
1419
1420
static void OGR2SQLITE_ExportGeometry(OGRGeometry *poGeom, int nSRSId,
1421
                                      GByte *&pabyGeomBLOB, int &nGeomBLOBLen)
1422
0
{
1423
0
    if (OGRSQLiteLayer::ExportSpatiaLiteGeometry(poGeom, nSRSId, wkbNDR, FALSE,
1424
0
                                                 FALSE, &pabyGeomBLOB,
1425
0
                                                 &nGeomBLOBLen) != OGRERR_NONE)
1426
0
    {
1427
0
        nGeomBLOBLen = 0;
1428
0
    }
1429
    /* This is a hack: we add the original curve geometry after */
1430
    /* the spatialite blob */
1431
0
    else if (poGeom->hasCurveGeometry())
1432
0
    {
1433
0
        const size_t nWkbSize = poGeom->WkbSize();
1434
0
        if (nWkbSize + 1 >
1435
0
            static_cast<size_t>(std::numeric_limits<int>::max()) - nGeomBLOBLen)
1436
0
        {
1437
0
            CPLError(CE_Failure, CPLE_NotSupported, "Too large geometry");
1438
0
            nGeomBLOBLen = 0;
1439
0
            return;
1440
0
        }
1441
1442
0
        pabyGeomBLOB = static_cast<GByte *>(
1443
0
            CPLRealloc(pabyGeomBLOB, nGeomBLOBLen + nWkbSize + 1));
1444
0
        poGeom->exportToWkb(wkbNDR, pabyGeomBLOB + nGeomBLOBLen, wkbVariantIso);
1445
        /* Cheat a bit and add a end-of-blob spatialite marker */
1446
0
        pabyGeomBLOB[nGeomBLOBLen + nWkbSize] = 0xFE;
1447
0
        nGeomBLOBLen += static_cast<int>(nWkbSize) + 1;
1448
0
    }
1449
0
}
1450
1451
/************************************************************************/
1452
/*                         OGR2SQLITE_Column()                          */
1453
/************************************************************************/
1454
1455
static int OGR2SQLITE_Column(sqlite3_vtab_cursor *pCursor,
1456
                             sqlite3_context *pContext, int nCol)
1457
0
{
1458
#ifdef DEBUG_OGR2SQLITE
1459
    CPLDebug("OGR2SQLITE", "Column %d", nCol);
1460
#endif
1461
1462
0
    OGR2SQLITE_vtab_cursor *pMyCursor =
1463
0
        reinterpret_cast<OGR2SQLITE_vtab_cursor *>(pCursor);
1464
1465
0
    OGR2SQLITE_GoToWishedIndex(pMyCursor);
1466
1467
0
    OGRFeature *poFeature = pMyCursor->poFeature;
1468
0
    if (poFeature == nullptr)
1469
0
        return SQLITE_ERROR;
1470
1471
0
    if (pMyCursor->pVTab->bHasFIDColumn)
1472
0
    {
1473
0
        if (nCol == 0)
1474
0
        {
1475
0
            sqlite3_result_int64(pContext, poFeature->GetFID());
1476
0
            return SQLITE_OK;
1477
0
        }
1478
0
        --nCol;
1479
0
    }
1480
1481
0
    OGRFeatureDefn *poFDefn = pMyCursor->poLayer->GetLayerDefn();
1482
0
    int nFieldCount = poFDefn->GetFieldCount();
1483
1484
0
    if (nCol == nFieldCount)
1485
0
    {
1486
0
        sqlite3_result_text(pContext, poFeature->GetStyleString(), -1,
1487
0
                            SQLITE_TRANSIENT);
1488
0
        return SQLITE_OK;
1489
0
    }
1490
0
    else if (nCol == (nFieldCount + 1) && poFDefn->GetGeomType() != wkbNone)
1491
0
    {
1492
0
        if (pMyCursor->nGeomBLOBLen < 0)
1493
0
        {
1494
0
            OGRGeometry *poGeom = poFeature->GetGeometryRef();
1495
0
            if (poGeom == nullptr)
1496
0
            {
1497
0
                pMyCursor->nGeomBLOBLen = 0;
1498
0
            }
1499
0
            else
1500
0
            {
1501
0
                CPLAssert(pMyCursor->pabyGeomBLOB == nullptr);
1502
1503
0
                const OGRSpatialReference *poSRS =
1504
0
                    poGeom->getSpatialReference();
1505
0
                int nSRSId = pMyCursor->pVTab->poModule->FetchSRSId(poSRS);
1506
1507
0
                OGR2SQLITE_ExportGeometry(poGeom, nSRSId,
1508
0
                                          pMyCursor->pabyGeomBLOB,
1509
0
                                          pMyCursor->nGeomBLOBLen);
1510
0
            }
1511
0
        }
1512
1513
0
        if (pMyCursor->nGeomBLOBLen == 0)
1514
0
        {
1515
0
            sqlite3_result_null(pContext);
1516
0
        }
1517
0
        else
1518
0
        {
1519
0
            GByte *pabyGeomBLOBDup =
1520
0
                static_cast<GByte *>(CPLMalloc(pMyCursor->nGeomBLOBLen));
1521
0
            memcpy(pabyGeomBLOBDup, pMyCursor->pabyGeomBLOB,
1522
0
                   pMyCursor->nGeomBLOBLen);
1523
0
            sqlite3_result_blob(pContext, pabyGeomBLOBDup,
1524
0
                                pMyCursor->nGeomBLOBLen, CPLFree);
1525
0
        }
1526
1527
0
        return SQLITE_OK;
1528
0
    }
1529
0
    else if (nCol > (nFieldCount + 1) &&
1530
0
             nCol - (nFieldCount + 1) < poFDefn->GetGeomFieldCount())
1531
0
    {
1532
0
        OGRGeometry *poGeom =
1533
0
            poFeature->GetGeomFieldRef(nCol - (nFieldCount + 1));
1534
0
        if (poGeom == nullptr)
1535
0
        {
1536
0
            sqlite3_result_null(pContext);
1537
0
        }
1538
0
        else
1539
0
        {
1540
0
            const OGRSpatialReference *poSRS = poGeom->getSpatialReference();
1541
0
            int nSRSId = pMyCursor->pVTab->poModule->FetchSRSId(poSRS);
1542
1543
0
            GByte *pabyGeomBLOB = nullptr;
1544
0
            int nGeomBLOBLen = 0;
1545
0
            OGR2SQLITE_ExportGeometry(poGeom, nSRSId, pabyGeomBLOB,
1546
0
                                      nGeomBLOBLen);
1547
1548
0
            if (nGeomBLOBLen == 0)
1549
0
            {
1550
0
                sqlite3_result_null(pContext);
1551
0
            }
1552
0
            else
1553
0
            {
1554
0
                sqlite3_result_blob(pContext, pabyGeomBLOB, nGeomBLOBLen,
1555
0
                                    CPLFree);
1556
0
            }
1557
0
        }
1558
0
        return SQLITE_OK;
1559
0
    }
1560
0
    else if (nCol == nFieldCount + 1 + poFDefn->GetGeomFieldCount())
1561
0
    {
1562
0
        sqlite3_result_text(pContext, poFeature->GetNativeData(), -1,
1563
0
                            SQLITE_TRANSIENT);
1564
0
        return SQLITE_OK;
1565
0
    }
1566
0
    else if (nCol == nFieldCount + 1 + poFDefn->GetGeomFieldCount() + 1)
1567
0
    {
1568
0
        sqlite3_result_text(pContext, poFeature->GetNativeMediaType(), -1,
1569
0
                            SQLITE_TRANSIENT);
1570
0
        return SQLITE_OK;
1571
0
    }
1572
0
    else if (nCol < 0 ||
1573
0
             nCol >= nFieldCount + 1 + poFDefn->GetGeomFieldCount() + 2)
1574
0
    {
1575
0
        return SQLITE_ERROR;
1576
0
    }
1577
0
    else if (!poFeature->IsFieldSetAndNotNull(nCol))
1578
0
    {
1579
0
        sqlite3_result_null(pContext);
1580
0
        return SQLITE_OK;
1581
0
    }
1582
1583
0
    switch (poFDefn->GetFieldDefn(nCol)->GetType())
1584
0
    {
1585
0
        case OFTInteger:
1586
0
            sqlite3_result_int(pContext, poFeature->GetFieldAsInteger(nCol));
1587
0
            break;
1588
1589
0
        case OFTInteger64:
1590
0
            sqlite3_result_int64(pContext,
1591
0
                                 poFeature->GetFieldAsInteger64(nCol));
1592
0
            break;
1593
1594
0
        case OFTReal:
1595
0
            sqlite3_result_double(pContext, poFeature->GetFieldAsDouble(nCol));
1596
0
            break;
1597
1598
0
        case OFTBinary:
1599
0
        {
1600
0
            int nSize = 0;
1601
0
            GByte *pBlob = poFeature->GetFieldAsBinary(nCol, &nSize);
1602
0
            sqlite3_result_blob(pContext, pBlob, nSize, SQLITE_TRANSIENT);
1603
0
            break;
1604
0
        }
1605
1606
0
        case OFTDateTime:
1607
0
        {
1608
0
            char *pszStr = OGRGetXMLDateTime(poFeature->GetRawFieldRef(nCol));
1609
0
            sqlite3_result_text(pContext, pszStr, -1, SQLITE_TRANSIENT);
1610
0
            CPLFree(pszStr);
1611
0
            break;
1612
0
        }
1613
1614
0
        case OFTDate:
1615
0
        {
1616
0
            int nYear, nMonth, nDay, nHour, nMinute, nSecond, nTZ;
1617
0
            poFeature->GetFieldAsDateTime(nCol, &nYear, &nMonth, &nDay, &nHour,
1618
0
                                          &nMinute, &nSecond, &nTZ);
1619
0
            char szBuffer[64];
1620
0
            snprintf(szBuffer, sizeof(szBuffer), "%04d-%02d-%02d", nYear,
1621
0
                     nMonth, nDay);
1622
0
            sqlite3_result_text(pContext, szBuffer, -1, SQLITE_TRANSIENT);
1623
0
            break;
1624
0
        }
1625
1626
0
        case OFTTime:
1627
0
        {
1628
0
            int nYear = 0;
1629
0
            int nMonth = 0;
1630
0
            int nDay = 0;
1631
0
            int nHour = 0;
1632
0
            int nMinute = 0;
1633
0
            int nTZ = 0;
1634
0
            float fSecond = 0.0f;
1635
0
            poFeature->GetFieldAsDateTime(nCol, &nYear, &nMonth, &nDay, &nHour,
1636
0
                                          &nMinute, &fSecond, &nTZ);
1637
0
            char szBuffer[64];
1638
0
            if (OGR_GET_MS(fSecond) != 0)
1639
0
                snprintf(szBuffer, sizeof(szBuffer), "%02d:%02d:%06.3f", nHour,
1640
0
                         nMinute, fSecond);
1641
0
            else
1642
0
                snprintf(szBuffer, sizeof(szBuffer), "%02d:%02d:%02d", nHour,
1643
0
                         nMinute, static_cast<int>(fSecond));
1644
0
            sqlite3_result_text(pContext, szBuffer, -1, SQLITE_TRANSIENT);
1645
0
            break;
1646
0
        }
1647
1648
0
        default:
1649
0
            sqlite3_result_text(pContext, poFeature->GetFieldAsString(nCol), -1,
1650
0
                                SQLITE_TRANSIENT);
1651
0
            break;
1652
0
    }
1653
1654
0
    return SQLITE_OK;
1655
0
}
1656
1657
/************************************************************************/
1658
/*                         OGR2SQLITE_Rowid()                           */
1659
/************************************************************************/
1660
1661
static int OGR2SQLITE_Rowid(sqlite3_vtab_cursor *pCursor, sqlite3_int64 *pRowid)
1662
0
{
1663
0
    OGR2SQLITE_vtab_cursor *pMyCursor =
1664
0
        reinterpret_cast<OGR2SQLITE_vtab_cursor *>(pCursor);
1665
#ifdef DEBUG_OGR2SQLITE
1666
    CPLDebug("OGR2SQLITE", "Rowid");
1667
#endif
1668
1669
0
    OGR2SQLITE_GoToWishedIndex(pMyCursor);
1670
1671
0
    if (pMyCursor->poFeature == nullptr)
1672
0
        return SQLITE_ERROR;
1673
1674
0
    *pRowid = pMyCursor->poFeature->GetFID();
1675
1676
0
    return SQLITE_OK;
1677
0
}
1678
1679
/************************************************************************/
1680
/*                         OGR2SQLITE_Rename()                          */
1681
/************************************************************************/
1682
1683
static int OGR2SQLITE_Rename(CPL_UNUSED sqlite3_vtab *pVtab,
1684
                             CPL_UNUSED const char *zNew)
1685
0
{
1686
    // CPLDebug("OGR2SQLITE", "Rename");
1687
0
    return SQLITE_ERROR;
1688
0
}
1689
1690
#if 0
1691
/************************************************************************/
1692
/*                        OGR2SQLITE_FindFunction()                     */
1693
/************************************************************************/
1694
1695
static
1696
int OGR2SQLITE_FindFunction(sqlite3_vtab *pVtab,
1697
                            int nArg,
1698
                            const char *zName,
1699
                            void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
1700
                            void **ppArg)
1701
{
1702
    CPLDebug("OGR2SQLITE", "FindFunction %s", zName);
1703
1704
    return 0;
1705
}
1706
#endif
1707
1708
/************************************************************************/
1709
/*                     OGR2SQLITE_FeatureFromArgs()                     */
1710
/************************************************************************/
1711
1712
static OGRFeature *OGR2SQLITE_FeatureFromArgs(OGR2SQLITE_vtab *pMyVTab,
1713
                                              int argc, sqlite3_value **argv)
1714
0
{
1715
0
    OGRLayer *poLayer = pMyVTab->poLayer;
1716
0
    OGRFeatureDefn *poLayerDefn = poLayer->GetLayerDefn();
1717
0
    const int nFieldCount = poLayerDefn->GetFieldCount();
1718
0
    const int nGeomFieldCount = poLayerDefn->GetGeomFieldCount();
1719
    // The argv[0] parameter is the rowid of a row in the virtual table to be deleted.
1720
    // The argv[1] parameter is the rowid of a new row to be inserted into the virtual table
1721
    // If bHasFIDColumn, we have an extra column, before the attributes
1722
0
    const int nLeadingColumns = pMyVTab->bHasFIDColumn ? 3 : 2;
1723
0
    if (argc != nLeadingColumns + nFieldCount + 1 + /* OGR_STYLE */
1724
0
                    nGeomFieldCount + 2 /* NativeData and NativeMediaType */)
1725
0
    {
1726
0
        CPLDebug("OGR2SQLITE", "Did not get expect argument count : %d, %d",
1727
0
                 argc, nLeadingColumns + nFieldCount + 1 + nGeomFieldCount + 2);
1728
0
        return nullptr;
1729
0
    }
1730
1731
0
    auto poFeature = std::make_unique<OGRFeature>(poLayerDefn);
1732
1733
0
    if (pMyVTab->bHasFIDColumn)
1734
0
    {
1735
0
        if (sqlite3_value_type(argv[2]) == SQLITE_INTEGER)
1736
0
        {
1737
0
            if (sqlite3_value_type(argv[1]) == SQLITE_INTEGER &&
1738
0
                sqlite3_value_int64(argv[1]) != sqlite3_value_int64(argv[2]))
1739
0
            {
1740
0
                CPLError(CE_Failure, CPLE_AppDefined,
1741
0
                         "Value provided through ROWID and %s are different",
1742
0
                         poLayer->GetFIDColumn());
1743
0
                return nullptr;
1744
0
            }
1745
0
            poFeature->SetFID(sqlite3_value_int64(argv[2]));
1746
0
        }
1747
0
    }
1748
0
    else if (sqlite3_value_type(argv[1]) == SQLITE_INTEGER)
1749
0
    {
1750
0
        poFeature->SetFID(sqlite3_value_int64(argv[1]));
1751
0
    }
1752
1753
0
    int iArgc = nLeadingColumns;
1754
0
    for (int i = 0; i < nFieldCount; i++, ++iArgc)
1755
0
    {
1756
0
        switch (sqlite3_value_type(argv[iArgc]))
1757
0
        {
1758
0
            case SQLITE_NULL:
1759
0
                poFeature->SetFieldNull(i);
1760
0
                break;
1761
0
            case SQLITE_INTEGER:
1762
0
                poFeature->SetField(i, sqlite3_value_int64(argv[iArgc]));
1763
0
                break;
1764
0
            case SQLITE_FLOAT:
1765
0
                poFeature->SetField(i, sqlite3_value_double(argv[iArgc]));
1766
0
                break;
1767
0
            case SQLITE_TEXT:
1768
0
            {
1769
0
                const char *pszValue = reinterpret_cast<const char *>(
1770
0
                    sqlite3_value_text(argv[iArgc]));
1771
0
                switch (poLayerDefn->GetFieldDefn(i)->GetType())
1772
0
                {
1773
0
                    case OFTDate:
1774
0
                    case OFTTime:
1775
0
                    case OFTDateTime:
1776
0
                        if (!OGRParseDate(pszValue,
1777
0
                                          poFeature->GetRawFieldRef(i), 0))
1778
0
                            poFeature->SetField(i, pszValue);
1779
0
                        break;
1780
1781
0
                    default:
1782
0
                        poFeature->SetField(i, pszValue);
1783
0
                        break;
1784
0
                }
1785
0
                break;
1786
0
            }
1787
0
            case SQLITE_BLOB:
1788
0
            {
1789
0
                GByte *paby = reinterpret_cast<GByte *>(
1790
0
                    const_cast<void *>(sqlite3_value_blob(argv[iArgc])));
1791
0
                int nLen = sqlite3_value_bytes(argv[iArgc]);
1792
0
                poFeature->SetField(i, nLen, paby);
1793
0
                break;
1794
0
            }
1795
0
            default:
1796
0
                break;
1797
0
        }
1798
0
    }
1799
1800
0
    if (sqlite3_value_type(argv[iArgc]) == SQLITE_TEXT)
1801
0
    {
1802
0
        poFeature->SetStyleString(
1803
0
            reinterpret_cast<const char *>(sqlite3_value_text(argv[iArgc])));
1804
0
    }
1805
0
    ++iArgc;
1806
1807
0
    for (int i = 0; i < nGeomFieldCount; i++, ++iArgc)
1808
0
    {
1809
0
        if (sqlite3_value_type(argv[iArgc]) == SQLITE_BLOB)
1810
0
        {
1811
0
            const GByte *pabyBlob = reinterpret_cast<const GByte *>(
1812
0
                sqlite3_value_blob(argv[iArgc]));
1813
0
            int nLen = sqlite3_value_bytes(argv[iArgc]);
1814
0
            OGRGeometry *poGeom = nullptr;
1815
0
            if (OGRSQLiteLayer::ImportSpatiaLiteGeometry(
1816
0
                    pabyBlob, nLen, &poGeom) == OGRERR_NONE)
1817
0
            {
1818
                /*                OGRwkbGeometryType eGeomFieldType =
1819
                                    poFeature->GetDefnRef()->GetGeomFieldDefn(i)->GetType();
1820
                                if( OGR_GT_IsCurve(eGeomFieldType) &&
1821
                   !OGR_GT_IsCurve(poGeom->getGeometryType()) )
1822
                                {
1823
                                    OGRGeometry* poCurveGeom =
1824
                   poGeom->getCurveGeometry();
1825
                                    poFeature->SetGeomFieldDirectly(i,
1826
                   poCurveGeom); delete poCurveGeom;
1827
                                }
1828
                                else*/
1829
0
                poFeature->SetGeomFieldDirectly(i, poGeom);
1830
0
            }
1831
0
        }
1832
0
    }
1833
1834
0
    if (sqlite3_value_type(argv[iArgc]) == SQLITE_TEXT)
1835
0
    {
1836
0
        poFeature->SetNativeData(
1837
0
            reinterpret_cast<const char *>(sqlite3_value_text(argv[iArgc])));
1838
0
    }
1839
0
    ++iArgc;
1840
1841
0
    if (sqlite3_value_type(argv[iArgc]) == SQLITE_TEXT)
1842
0
    {
1843
0
        poFeature->SetNativeMediaType(
1844
0
            reinterpret_cast<const char *>(sqlite3_value_text(argv[iArgc])));
1845
0
    }
1846
1847
0
    return poFeature.release();
1848
0
}
1849
1850
/************************************************************************/
1851
/*                            OGR2SQLITE_Update()                       */
1852
/************************************************************************/
1853
1854
static int OGR2SQLITE_Update(sqlite3_vtab *pVTab, int argc,
1855
                             sqlite3_value **argv, sqlite_int64 *pRowid)
1856
0
{
1857
0
    CPLDebug("OGR2SQLITE", "OGR2SQLITE_Update");
1858
1859
0
    OGR2SQLITE_vtab *pMyVTab = reinterpret_cast<OGR2SQLITE_vtab *>(pVTab);
1860
0
    OGRLayer *poLayer = pMyVTab->poLayer;
1861
1862
0
    if (argc == 1)
1863
0
    {
1864
        /* DELETE */
1865
1866
0
        OGRErr eErr = poLayer->DeleteFeature(sqlite3_value_int64(argv[0]));
1867
1868
0
        return (eErr == OGRERR_NONE) ? SQLITE_OK : SQLITE_ERROR;
1869
0
    }
1870
0
    else if (argc > 1 && sqlite3_value_type(argv[0]) == SQLITE_NULL)
1871
0
    {
1872
        /* INSERT */
1873
1874
0
        OGRFeature *poFeature = OGR2SQLITE_FeatureFromArgs(pMyVTab, argc, argv);
1875
0
        if (poFeature == nullptr)
1876
0
            return SQLITE_ERROR;
1877
1878
0
        OGRErr eErr = poLayer->CreateFeature(poFeature);
1879
0
        if (eErr == OGRERR_NONE)
1880
0
            *pRowid = poFeature->GetFID();
1881
1882
0
        delete poFeature;
1883
1884
0
        return (eErr == OGRERR_NONE) ? SQLITE_OK : SQLITE_ERROR;
1885
0
    }
1886
0
    else if (argc > 1 && sqlite3_value_type(argv[0]) == SQLITE_INTEGER &&
1887
0
             sqlite3_value_type(argv[1]) == SQLITE_INTEGER &&
1888
0
             sqlite3_value_int64(argv[0]) == sqlite3_value_int64(argv[1]))
1889
0
    {
1890
        /* UPDATE */
1891
1892
0
        OGRFeature *poFeature = OGR2SQLITE_FeatureFromArgs(pMyVTab, argc, argv);
1893
0
        if (poFeature == nullptr)
1894
0
            return SQLITE_ERROR;
1895
1896
0
        OGRErr eErr = poLayer->SetFeature(poFeature);
1897
1898
0
        delete poFeature;
1899
1900
0
        return (eErr == OGRERR_NONE) ? SQLITE_OK : SQLITE_ERROR;
1901
0
    }
1902
1903
    // UPDATE table SET rowid=rowid+1 WHERE ... unsupported
1904
1905
0
    return SQLITE_ERROR;
1906
0
}
1907
1908
/************************************************************************/
1909
/*                        sOGR2SQLITEModule                             */
1910
/************************************************************************/
1911
1912
static const struct sqlite3_module sOGR2SQLITEModule = {
1913
    1,                        /* iVersion */
1914
    OGR2SQLITE_ConnectCreate, /* xCreate */
1915
    OGR2SQLITE_ConnectCreate, /* xConnect */
1916
    OGR2SQLITE_BestIndex,
1917
    OGR2SQLITE_DisconnectDestroy, /* xDisconnect */
1918
    OGR2SQLITE_DisconnectDestroy, /* xDestroy */
1919
    OGR2SQLITE_Open,
1920
    OGR2SQLITE_Close,
1921
    OGR2SQLITE_Filter,
1922
    OGR2SQLITE_Next,
1923
    OGR2SQLITE_Eof,
1924
    OGR2SQLITE_Column,
1925
    OGR2SQLITE_Rowid,
1926
    OGR2SQLITE_Update,
1927
    nullptr, /* xBegin */
1928
    nullptr, /* xSync */
1929
    nullptr, /* xCommit */
1930
    nullptr, /* xFindFunctionRollback */
1931
    nullptr,
1932
    /* xFindFunction */  // OGR2SQLITE_FindFunction;
1933
    OGR2SQLITE_Rename,
1934
    nullptr,  // xSavepoint
1935
    nullptr,  // xRelease
1936
    nullptr,  // xRollbackTo
1937
    nullptr,  // xShadowName
1938
#if SQLITE_VERSION_NUMBER >=                                                   \
1939
    3044000L /* should be the first version with the below symbols */
1940
    nullptr,  // xIntegrity
1941
#endif
1942
};
1943
1944
/************************************************************************/
1945
/*                           OGR2SQLITE_GetLayer()                      */
1946
/************************************************************************/
1947
1948
static OGRLayer *OGR2SQLITE_GetLayer(const char *pszFuncName,
1949
                                     sqlite3_context *pContext, int argc,
1950
                                     sqlite3_value **argv)
1951
0
{
1952
0
    if (argc != 1)
1953
0
    {
1954
0
        CPLError(CE_Failure, CPLE_AppDefined, "%s: %s(): %s", "VirtualOGR",
1955
0
                 pszFuncName, "Invalid number of arguments");
1956
0
        sqlite3_result_null(pContext);
1957
0
        return nullptr;
1958
0
    }
1959
1960
0
    if (sqlite3_value_type(argv[0]) != SQLITE_TEXT)
1961
0
    {
1962
0
        CPLError(CE_Failure, CPLE_AppDefined, "%s: %s(): %s", "VirtualOGR",
1963
0
                 pszFuncName, "Invalid argument type");
1964
0
        sqlite3_result_null(pContext);
1965
0
        return nullptr;
1966
0
    }
1967
1968
0
    const char *pszVTableName =
1969
0
        reinterpret_cast<const char *>(sqlite3_value_text(argv[0]));
1970
1971
0
    OGR2SQLITEModule *poModule =
1972
0
        static_cast<OGR2SQLITEModule *>(sqlite3_user_data(pContext));
1973
1974
0
    OGRLayer *poLayer = poModule->GetLayerForVTable(SQLUnescape(pszVTableName));
1975
0
    if (poLayer == nullptr)
1976
0
    {
1977
0
        CPLError(CE_Failure, CPLE_AppDefined, "%s: %s(): %s", "VirtualOGR",
1978
0
                 pszFuncName, "Unknown virtual table");
1979
0
        sqlite3_result_null(pContext);
1980
0
        return nullptr;
1981
0
    }
1982
1983
0
    return poLayer;
1984
0
}
1985
1986
/************************************************************************/
1987
/*                       OGR2SQLITE_ogr_layer_Extent()                  */
1988
/************************************************************************/
1989
1990
static void OGR2SQLITE_ogr_layer_Extent(sqlite3_context *pContext, int argc,
1991
                                        sqlite3_value **argv)
1992
0
{
1993
0
    OGRLayer *poLayer =
1994
0
        OGR2SQLITE_GetLayer("ogr_layer_Extent", pContext, argc, argv);
1995
0
    if (poLayer == nullptr)
1996
0
        return;
1997
1998
0
    OGR2SQLITEModule *poModule =
1999
0
        static_cast<OGR2SQLITEModule *>(sqlite3_user_data(pContext));
2000
2001
0
    if (poLayer->GetGeomType() == wkbNone)
2002
0
    {
2003
0
        sqlite3_result_null(pContext);
2004
0
        return;
2005
0
    }
2006
2007
0
    OGREnvelope sExtent;
2008
0
    if (poLayer->GetExtent(&sExtent) != OGRERR_NONE)
2009
0
    {
2010
0
        CPLError(CE_Failure, CPLE_AppDefined, "%s: %s(): %s", "VirtualOGR",
2011
0
                 "ogr_layer_Extent", "Cannot fetch layer extent");
2012
0
        sqlite3_result_null(pContext);
2013
0
        return;
2014
0
    }
2015
2016
0
    OGRPolygon oPoly;
2017
0
    OGRLinearRing *poRing = new OGRLinearRing();
2018
0
    oPoly.addRingDirectly(poRing);
2019
0
    poRing->addPoint(sExtent.MinX, sExtent.MinY);
2020
0
    poRing->addPoint(sExtent.MaxX, sExtent.MinY);
2021
0
    poRing->addPoint(sExtent.MaxX, sExtent.MaxY);
2022
0
    poRing->addPoint(sExtent.MinX, sExtent.MaxY);
2023
0
    poRing->addPoint(sExtent.MinX, sExtent.MinY);
2024
2025
0
    GByte *pabySLBLOB = nullptr;
2026
0
    int nBLOBLen = 0;
2027
0
    int nSRID = poModule->FetchSRSId(poLayer->GetSpatialRef());
2028
0
    if (OGRSQLiteLayer::ExportSpatiaLiteGeometry(&oPoly, nSRID, wkbNDR, FALSE,
2029
0
                                                 FALSE, &pabySLBLOB,
2030
0
                                                 &nBLOBLen) == OGRERR_NONE)
2031
0
    {
2032
0
        sqlite3_result_blob(pContext, pabySLBLOB, nBLOBLen, CPLFree);
2033
0
    }
2034
0
    else
2035
0
    {
2036
0
        sqlite3_result_null(pContext);
2037
0
    }
2038
0
}
2039
2040
/************************************************************************/
2041
/*                       OGR2SQLITE_ogr_layer_SRID()                    */
2042
/************************************************************************/
2043
2044
static void OGR2SQLITE_ogr_layer_SRID(sqlite3_context *pContext, int argc,
2045
                                      sqlite3_value **argv)
2046
0
{
2047
0
    OGRLayer *poLayer =
2048
0
        OGR2SQLITE_GetLayer("OGR2SQLITE_ogr_layer_SRID", pContext, argc, argv);
2049
0
    if (poLayer == nullptr)
2050
0
        return;
2051
2052
0
    OGR2SQLITEModule *poModule =
2053
0
        static_cast<OGR2SQLITEModule *>(sqlite3_user_data(pContext));
2054
2055
0
    if (poLayer->GetGeomType() == wkbNone)
2056
0
    {
2057
0
        sqlite3_result_null(pContext);
2058
0
        return;
2059
0
    }
2060
2061
0
    int nSRID = poModule->FetchSRSId(poLayer->GetSpatialRef());
2062
0
    sqlite3_result_int(pContext, nSRID);
2063
0
}
2064
2065
/************************************************************************/
2066
/*                 OGR2SQLITE_ogr_layer_GeometryType()                  */
2067
/************************************************************************/
2068
2069
static void OGR2SQLITE_ogr_layer_GeometryType(sqlite3_context *pContext,
2070
                                              int argc, sqlite3_value **argv)
2071
0
{
2072
0
    OGRLayer *poLayer = OGR2SQLITE_GetLayer("OGR2SQLITE_ogr_layer_GeometryType",
2073
0
                                            pContext, argc, argv);
2074
0
    if (poLayer == nullptr)
2075
0
        return;
2076
2077
0
    OGRwkbGeometryType eType = poLayer->GetGeomType();
2078
2079
0
    if (eType == wkbNone)
2080
0
    {
2081
0
        sqlite3_result_null(pContext);
2082
0
        return;
2083
0
    }
2084
2085
0
    const char *psz2DName = OGRToOGCGeomType(eType);
2086
0
    if (wkbHasZ(eType))
2087
0
        sqlite3_result_text(pContext, CPLSPrintf("%s Z", psz2DName), -1,
2088
0
                            SQLITE_TRANSIENT);
2089
0
    else
2090
0
        sqlite3_result_text(pContext, psz2DName, -1, SQLITE_TRANSIENT);
2091
0
}
2092
2093
/************************************************************************/
2094
/*                OGR2SQLITE_ogr_layer_FeatureCount()                   */
2095
/************************************************************************/
2096
2097
static void OGR2SQLITE_ogr_layer_FeatureCount(sqlite3_context *pContext,
2098
                                              int argc, sqlite3_value **argv)
2099
0
{
2100
0
    OGRLayer *poLayer = OGR2SQLITE_GetLayer("OGR2SQLITE_ogr_layer_FeatureCount",
2101
0
                                            pContext, argc, argv);
2102
0
    if (poLayer == nullptr)
2103
0
        return;
2104
2105
0
    sqlite3_result_int64(pContext, poLayer->GetFeatureCount());
2106
0
}
2107
2108
/************************************************************************/
2109
/*                      OGR2SQLITEDestroyModule()                       */
2110
/************************************************************************/
2111
2112
static void OGR2SQLITEDestroyModule(void *pData)
2113
3.66k
{
2114
    // Comment out this debug message, as the module can be registered in the
2115
    // connection of proj.db that is since PROJ 8.1 a cache that is destroyed at
2116
    // PROJ unloading, after GDAL itself has cleaned up itself. CPLDebug("OGR",
2117
    // "Unloading VirtualOGR module");
2118
3.66k
    delete static_cast<OGR2SQLITEModule *>(pData);
2119
3.66k
}
2120
2121
/* ENABLE_VIRTUAL_OGR_SPATIAL_INDEX is not defined */
2122
#ifdef ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
2123
2124
/************************************************************************/
2125
/*                    OGR2SQLITESpatialIndex_vtab                       */
2126
/************************************************************************/
2127
2128
typedef struct
2129
{
2130
    /* Mandatory fields by sqlite3: don't change or reorder them ! */
2131
    const sqlite3_module *pModule;
2132
    int nRef;
2133
    char *zErrMsg;
2134
2135
    /* Extension fields */
2136
    char *pszVTableName;
2137
    OGR2SQLITEModule *poModule;
2138
    GDALDataset *poDS;
2139
    int bCloseDS;
2140
    OGRLayer *poLayer;
2141
    int nMyRef;
2142
} OGR2SQLITESpatialIndex_vtab;
2143
2144
/************************************************************************/
2145
/*                  OGR2SQLITESpatialIndex_vtab_cursor                  */
2146
/************************************************************************/
2147
2148
typedef struct
2149
{
2150
    /* Mandatory fields by sqlite3: don't change or reorder them ! */
2151
    OGR2SQLITESpatialIndex_vtab *pVTab;
2152
2153
    /* Extension fields */
2154
    GDALDataset *poDupDataSource;
2155
    OGRLayer *poLayer;
2156
    OGRFeature *poFeature;
2157
    int bHasSetBounds;
2158
    double dfMinX;
2159
    double dfMinY;
2160
    double dfMaxX;
2161
    double dfMaxY;
2162
} OGR2SQLITESpatialIndex_vtab_cursor;
2163
2164
/************************************************************************/
2165
/*                   OGR2SQLITESpatialIndex_ConnectCreate()             */
2166
/************************************************************************/
2167
2168
static int OGR2SQLITESpatialIndex_ConnectCreate(sqlite3 *hDB, void *pAux,
2169
                                                int argc,
2170
                                                const char *const *argv,
2171
                                                sqlite3_vtab **ppVTab,
2172
                                                char **pzErr)
2173
{
2174
#ifdef DEBUG_OGR2SQLITE
2175
    CPLDebug("OGR2SQLITE", "ConnectCreate(%s)", argv[2]);
2176
#endif
2177
2178
    OGR2SQLITEModule *poModule = (OGR2SQLITEModule *)pAux;
2179
2180
    /* -------------------------------------------------------------------- */
2181
    /*      If called from ogrexecutesql.cpp                                */
2182
    /* -------------------------------------------------------------------- */
2183
    GDALDataset *poDS = poModule->GetDS();
2184
    if (poDS == NULL)
2185
        return SQLITE_ERROR;
2186
2187
    if (argc != 10)
2188
    {
2189
        *pzErr =
2190
            sqlite3_mprintf("Expected syntax: CREATE VIRTUAL TABLE xxx USING "
2191
                            "VirtualOGRSpatialIndex(ds_idx, layer_name, pkid, "
2192
                            "xmin, xmax, ymin, ymax)");
2193
        return SQLITE_ERROR;
2194
    }
2195
2196
    int nDSIndex = atoi(argv[3]);
2197
    if (nDSIndex >= 0)
2198
    {
2199
        poDS = poModule->GetExtraDS(nDSIndex);
2200
        if (poDS == NULL)
2201
        {
2202
            *pzErr = sqlite3_mprintf("Invalid dataset index : %d", nDSIndex);
2203
            return SQLITE_ERROR;
2204
        }
2205
    }
2206
2207
    poDS = (GDALDataset *)OGROpen(poDS->GetName(), FALSE, NULL);
2208
    if (poDS == NULL)
2209
    {
2210
        return SQLITE_ERROR;
2211
    }
2212
2213
    CPLString osLayerName(SQLUnescape(argv[4]));
2214
2215
    OGRLayer *poLayer = poDS->GetLayerByName(osLayerName);
2216
    if (poLayer == NULL)
2217
    {
2218
        *pzErr = sqlite3_mprintf("Cannot find layer '%s' in '%s'",
2219
                                 osLayerName.c_str(), poDS->GetName());
2220
        return SQLITE_ERROR;
2221
    }
2222
2223
    OGR2SQLITESpatialIndex_vtab *vtab =
2224
        (OGR2SQLITESpatialIndex_vtab *)CPLCalloc(
2225
            1, sizeof(OGR2SQLITESpatialIndex_vtab));
2226
    // We do not need to fill the non-extended fields.
2227
    vtab->pszVTableName = CPLStrdup(SQLEscapeName(argv[2]));
2228
    vtab->poModule = poModule;
2229
    vtab->poDS = poDS;
2230
    vtab->bCloseDS = true;
2231
    vtab->poLayer = poLayer;
2232
    vtab->nMyRef = 0;
2233
2234
    *ppVTab = (sqlite3_vtab *)vtab;
2235
2236
    CPLString osSQL;
2237
    osSQL = "CREATE TABLE ";
2238
    osSQL += "\"";
2239
    osSQL += SQLEscapeName(argv[2]);
2240
    osSQL += "\"";
2241
    osSQL += "(";
2242
2243
    bool bAddComma = false;
2244
2245
    for (i = 0; i < 5; i++)
2246
    {
2247
        if (bAddComma)
2248
            osSQL += ",";
2249
        bAddComma = true;
2250
2251
        osSQL += "\"";
2252
        osSQL += SQLEscapeName(SQLUnescape(argv[5 + i]));
2253
        osSQL += "\"";
2254
        osSQL += " ";
2255
        osSQL += (i == 0) ? "INTEGER" : "FLOAT";
2256
    }
2257
2258
    osSQL += ")";
2259
2260
    CPLDebug("OGR2SQLITE", "sqlite3_declare_vtab(%s)", osSQL.c_str());
2261
    if (sqlite3_declare_vtab(hDB, osSQL.c_str()) != SQLITE_OK)
2262
    {
2263
        *pzErr = sqlite3_mprintf("CREATE VIRTUAL: invalid SQL statement : %s",
2264
                                 osSQL.c_str());
2265
        return SQLITE_ERROR;
2266
    }
2267
2268
    return SQLITE_OK;
2269
}
2270
2271
/************************************************************************/
2272
/*                      OGR2SQLITESpatialIndex_BestIndex()              */
2273
/************************************************************************/
2274
2275
static int OGR2SQLITESpatialIndex_BestIndex(sqlite3_vtab *pVTab,
2276
                                            sqlite3_index_info *pIndex)
2277
{
2278
#ifdef DEBUG_OGR2SQLITE
2279
    CPLDebug("OGR2SQLITE", "BestIndex");
2280
#endif
2281
2282
    bool bMinX = false;
2283
    bool bMinY = false;
2284
    bool bMaxX = false;
2285
    bool bMaxY = false;
2286
2287
    for (int i = 0; i < pIndex->nConstraint; i++)
2288
    {
2289
        int iCol = pIndex->aConstraint[i].iColumn;
2290
        /* MinX */
2291
        if (!bMinX && iCol == 1 && pIndex->aConstraint[i].usable &&
2292
            (pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_LE ||
2293
             pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_LT))
2294
            bMinX = true;
2295
        /* MaxX */
2296
        else if (!bMaxX && iCol == 2 && pIndex->aConstraint[i].usable &&
2297
                 (pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GE ||
2298
                  pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GT))
2299
            bMaxX = true;
2300
        /* MinY */
2301
        else if (!bMinY && iCol == 3 && pIndex->aConstraint[i].usable &&
2302
                 (pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_LE ||
2303
                  pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_LT))
2304
            bMinY = true;
2305
        /* MaxY */
2306
        else if (!bMaxY && iCol == 4 && pIndex->aConstraint[i].usable &&
2307
                 (pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GE ||
2308
                  pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GT))
2309
            bMaxY = true;
2310
        else
2311
            break;
2312
    }
2313
2314
    if (bMinX && bMinY && bMaxX && bMaxY)
2315
    {
2316
        CPLAssert(pIndex->nConstraint == 4);
2317
2318
        int nConstraints = 0;
2319
        for (int i = 0; i < pIndex->nConstraint; i++)
2320
        {
2321
            pIndex->aConstraintUsage[i].argvIndex = nConstraints + 1;
2322
            pIndex->aConstraintUsage[i].omit = true;
2323
2324
            nConstraints++;
2325
        }
2326
2327
        int *panConstraints =
2328
            (int *)sqlite3_malloc(sizeof(int) * (1 + 2 * nConstraints));
2329
        panConstraints[0] = nConstraints;
2330
2331
        nConstraints = 0;
2332
2333
        for (int i = 0; i < pIndex->nConstraint; i++)
2334
        {
2335
            if (pIndex->aConstraintUsage[i].omit)
2336
            {
2337
                panConstraints[2 * nConstraints + 1] =
2338
                    pIndex->aConstraint[i].iColumn;
2339
                panConstraints[2 * nConstraints + 2] =
2340
                    pIndex->aConstraint[i].op;
2341
2342
                nConstraints++;
2343
            }
2344
        }
2345
2346
        pIndex->idxStr = (char *)panConstraints;
2347
        pIndex->needToFreeIdxStr = true;
2348
2349
        pIndex->orderByConsumed = false;
2350
        pIndex->idxNum = 0;
2351
2352
        return SQLITE_OK;
2353
    }
2354
    else
2355
    {
2356
        CPLDebug("OGR2SQLITE",
2357
                 "OGR2SQLITESpatialIndex_BestIndex: unhandled request");
2358
        return SQLITE_ERROR;
2359
        /*
2360
                for (i = 0; i < pIndex->nConstraint; i++)
2361
                {
2362
                    pIndex->aConstraintUsage[i].argvIndex = 0;
2363
                    pIndex->aConstraintUsage[i].omit = false;
2364
                }
2365
2366
                pIndex->idxStr = NULL;
2367
                pIndex->needToFreeIdxStr = false;
2368
        */
2369
    }
2370
}
2371
2372
/************************************************************************/
2373
/*                  OGR2SQLITESpatialIndex_DisconnectDestroy()          */
2374
/************************************************************************/
2375
2376
static int OGR2SQLITESpatialIndex_DisconnectDestroy(sqlite3_vtab *pVTab)
2377
{
2378
    OGR2SQLITESpatialIndex_vtab *pMyVTab = (OGR2SQLITESpatialIndex_vtab *)pVTab;
2379
2380
#ifdef DEBUG_OGR2SQLITE
2381
    CPLDebug("OGR2SQLITE", "DisconnectDestroy(%s)", pMyVTab->pszVTableName);
2382
#endif
2383
2384
    sqlite3_free(pMyVTab->zErrMsg);
2385
    if (pMyVTab->bCloseDS)
2386
        delete pMyVTab->poDS;
2387
    CPLFree(pMyVTab->pszVTableName);
2388
    CPLFree(pMyVTab);
2389
2390
    return SQLITE_OK;
2391
}
2392
2393
/************************************************************************/
2394
/*                    OGR2SQLITESpatialIndex_Open()                     */
2395
/************************************************************************/
2396
2397
static int OGR2SQLITESpatialIndex_Open(sqlite3_vtab *pVTab,
2398
                                       sqlite3_vtab_cursor **ppCursor)
2399
{
2400
    OGR2SQLITESpatialIndex_vtab *pMyVTab = (OGR2SQLITESpatialIndex_vtab *)pVTab;
2401
#ifdef DEBUG_OGR2SQLITE
2402
    CPLDebug("OGR2SQLITE", "Open(%s, %s)", pMyVTab->poDS->GetName(),
2403
             pMyVTab->poLayer->GetName());
2404
#endif
2405
2406
    GDALDataset *poDupDataSource = NULL;
2407
    OGRLayer *poLayer = NULL;
2408
2409
    if (pMyVTab->nMyRef == 0)
2410
    {
2411
        poLayer = pMyVTab->poLayer;
2412
    }
2413
    else
2414
    {
2415
        poDupDataSource =
2416
            (GDALDataset *)OGROpen(pMyVTab->poDS->GetName(), FALSE, NULL);
2417
        if (poDupDataSource == NULL)
2418
            return SQLITE_ERROR;
2419
        poLayer = poDupDataSource->GetLayerByName(pMyVTab->poLayer->GetName());
2420
        if (poLayer == NULL)
2421
        {
2422
            delete poDupDataSource;
2423
            return SQLITE_ERROR;
2424
        }
2425
        if (!poLayer->GetLayerDefn()->IsSame(pMyVTab->poLayer->GetLayerDefn()))
2426
        {
2427
            delete poDupDataSource;
2428
            return SQLITE_ERROR;
2429
        }
2430
    }
2431
    pMyVTab->nMyRef++;
2432
2433
    OGR2SQLITESpatialIndex_vtab_cursor *pCursor =
2434
        (OGR2SQLITESpatialIndex_vtab_cursor *)CPLCalloc(
2435
            1, sizeof(OGR2SQLITESpatialIndex_vtab_cursor));
2436
    // We do not need to fill the non-extended fields.
2437
    *ppCursor = (sqlite3_vtab_cursor *)pCursor;
2438
2439
    pCursor->poDupDataSource = poDupDataSource;
2440
    pCursor->poLayer = poLayer;
2441
    pCursor->poLayer->ResetReading();
2442
    pCursor->poFeature = NULL;
2443
2444
    return SQLITE_OK;
2445
}
2446
2447
/************************************************************************/
2448
/*                      OGR2SQLITESpatialIndex_Close()                  */
2449
/************************************************************************/
2450
2451
static int OGR2SQLITESpatialIndex_Close(sqlite3_vtab_cursor *pCursor)
2452
{
2453
    OGR2SQLITESpatialIndex_vtab_cursor *pMyCursor =
2454
        (OGR2SQLITESpatialIndex_vtab_cursor *)pCursor;
2455
    OGR2SQLITESpatialIndex_vtab *pMyVTab = pMyCursor->pVTab;
2456
#ifdef DEBUG_OGR2SQLITE
2457
    CPLDebug("OGR2SQLITE", "Close(%s, %s)", pMyVTab->poDS->GetName(),
2458
             pMyVTab->poLayer->GetName());
2459
#endif
2460
    pMyVTab->nMyRef--;
2461
2462
    delete pMyCursor->poFeature;
2463
    delete pMyCursor->poDupDataSource;
2464
2465
    CPLFree(pCursor);
2466
2467
    return SQLITE_OK;
2468
}
2469
2470
/************************************************************************/
2471
/*                     OGR2SQLITESpatialIndex_Filter()                  */
2472
/************************************************************************/
2473
2474
static int OGR2SQLITESpatialIndex_Filter(sqlite3_vtab_cursor *pCursor,
2475
                                         int idxNum, const char *idxStr,
2476
                                         int argc, sqlite3_value **argv)
2477
{
2478
    OGR2SQLITESpatialIndex_vtab_cursor *pMyCursor =
2479
        (OGR2SQLITESpatialIndex_vtab_cursor *)pCursor;
2480
#ifdef DEBUG_OGR2SQLITE
2481
    CPLDebug("OGR2SQLITE", "Filter");
2482
#endif
2483
2484
    int *panConstraints = (int *)idxStr;
2485
    int nConstraints = panConstraints ? panConstraints[0] : 0;
2486
2487
    if (nConstraints != argc)
2488
        return SQLITE_ERROR;
2489
2490
    double dfMinX = 0.0;
2491
    double dfMaxX = 0.0;
2492
    double dfMinY = 0.0;
2493
    double dfMaxY = 0.0;
2494
    for (int i = 0; i < argc; i++)
2495
    {
2496
        const int nCol = panConstraints[2 * i + 1];
2497
        if (nCol < 0)
2498
            return SQLITE_ERROR;
2499
2500
        double dfVal = 0.0;
2501
        if (sqlite3_value_type(argv[i]) == SQLITE_INTEGER)
2502
            dfVal = sqlite3_value_int64(argv[i]);
2503
        else if (sqlite3_value_type(argv[i]) == SQLITE_FLOAT)
2504
            dfVal = sqlite3_value_double(argv[i]);
2505
        else
2506
            return SQLITE_ERROR;
2507
2508
        if (nCol == 1)
2509
            dfMaxX = dfVal;
2510
        else if (nCol == 2)
2511
            dfMinX = dfVal;
2512
        else if (nCol == 3)
2513
            dfMaxY = dfVal;
2514
        else if (nCol == 4)
2515
            dfMinY = dfVal;
2516
        else
2517
            return SQLITE_ERROR;
2518
    }
2519
2520
#ifdef DEBUG_OGR2SQLITE
2521
    CPLDebug("OGR2SQLITE", "Spatial filter : %.17g, %.17g, %.17g, %.17g",
2522
             dfMinX, dfMinY, dfMaxX, dfMaxY);
2523
#endif
2524
2525
    pMyCursor->poLayer->SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY);
2526
    pMyCursor->poLayer->ResetReading();
2527
2528
    pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
2529
    pMyCursor->bHasSetBounds = false;
2530
2531
    return SQLITE_OK;
2532
}
2533
2534
/************************************************************************/
2535
/*                    OGR2SQLITESpatialIndex_Next()                     */
2536
/************************************************************************/
2537
2538
static int OGR2SQLITESpatialIndex_Next(sqlite3_vtab_cursor *pCursor)
2539
{
2540
    OGR2SQLITESpatialIndex_vtab_cursor *pMyCursor =
2541
        (OGR2SQLITESpatialIndex_vtab_cursor *)pCursor;
2542
#ifdef DEBUG_OGR2SQLITE
2543
    CPLDebug("OGR2SQLITE", "Next");
2544
#endif
2545
2546
    delete pMyCursor->poFeature;
2547
    pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
2548
    pMyCursor->bHasSetBounds = false;
2549
2550
    return SQLITE_OK;
2551
}
2552
2553
/************************************************************************/
2554
/*                      OGR2SQLITESpatialIndex_Eof()                    */
2555
/************************************************************************/
2556
2557
static int OGR2SQLITESpatialIndex_Eof(sqlite3_vtab_cursor *pCursor)
2558
{
2559
    OGR2SQLITESpatialIndex_vtab_cursor *pMyCursor =
2560
        (OGR2SQLITESpatialIndex_vtab_cursor *)pCursor;
2561
#ifdef DEBUG_OGR2SQLITE
2562
    CPLDebug("OGR2SQLITE", "Eof");
2563
#endif
2564
2565
    return pMyCursor->poFeature == NULL;
2566
}
2567
2568
/************************************************************************/
2569
/*                    OGR2SQLITESpatialIndex_Column()                   */
2570
/************************************************************************/
2571
2572
static int OGR2SQLITESpatialIndex_Column(sqlite3_vtab_cursor *pCursor,
2573
                                         sqlite3_context *pContext, int nCol)
2574
{
2575
#ifdef DEBUG_OGR2SQLITE
2576
    CPLDebug("OGR2SQLITE", "Column %d", nCol);
2577
#endif
2578
2579
    OGR2SQLITESpatialIndex_vtab_cursor *pMyCursor =
2580
        (OGR2SQLITESpatialIndex_vtab_cursor *)pCursor;
2581
2582
    OGRFeature *poFeature = pMyCursor->poFeature;
2583
    if (poFeature == NULL)
2584
        return SQLITE_ERROR;
2585
2586
    if (nCol == 0)
2587
    {
2588
        CPLDebug("OGR2SQLITE", "--> FID = " CPL_FRMT_GIB, poFeature->GetFID());
2589
        sqlite3_result_int64(pContext, poFeature->GetFID());
2590
        return SQLITE_OK;
2591
    }
2592
2593
    if (!pMyCursor->bHasSetBounds)
2594
    {
2595
        OGRGeometry *poGeom = poFeature->GetGeometryRef();
2596
        if (poGeom != NULL && !poGeom->IsEmpty())
2597
        {
2598
            OGREnvelope sEnvelope;
2599
            poGeom->getEnvelope(&sEnvelope);
2600
            pMyCursor->bHasSetBounds = true;
2601
            pMyCursor->dfMinX = sEnvelope.MinX;
2602
            pMyCursor->dfMinY = sEnvelope.MinY;
2603
            pMyCursor->dfMaxX = sEnvelope.MaxX;
2604
            pMyCursor->dfMaxY = sEnvelope.MaxY;
2605
        }
2606
    }
2607
    if (!pMyCursor->bHasSetBounds)
2608
    {
2609
        sqlite3_result_null(pContext);
2610
        return SQLITE_OK;
2611
    }
2612
2613
    if (nCol == 1)
2614
    {
2615
        sqlite3_result_double(pContext, pMyCursor->dfMinX);
2616
        return SQLITE_OK;
2617
    }
2618
    if (nCol == 2)
2619
    {
2620
        sqlite3_result_double(pContext, pMyCursor->dfMaxX);
2621
        return SQLITE_OK;
2622
    }
2623
    if (nCol == 3)
2624
    {
2625
        sqlite3_result_double(pContext, pMyCursor->dfMinY);
2626
        return SQLITE_OK;
2627
    }
2628
    if (nCol == 4)
2629
    {
2630
        sqlite3_result_double(pContext, pMyCursor->dfMaxY);
2631
        return SQLITE_OK;
2632
    }
2633
2634
    return SQLITE_ERROR;
2635
}
2636
2637
/************************************************************************/
2638
/*                    OGR2SQLITESpatialIndex_Rowid()                    */
2639
/************************************************************************/
2640
2641
static int OGR2SQLITESpatialIndex_Rowid(sqlite3_vtab_cursor *pCursor,
2642
                                        sqlite3_int64 *pRowid)
2643
{
2644
#ifdef DEBUG_OGR2SQLITE
2645
    CPLDebug("OGR2SQLITE", "Rowid");
2646
#endif
2647
2648
    return SQLITE_ERROR;
2649
}
2650
2651
/************************************************************************/
2652
/*                   OGR2SQLITESpatialIndex_Rename()                    */
2653
/************************************************************************/
2654
2655
static int OGR2SQLITESpatialIndex_Rename(sqlite3_vtab *pVtab, const char *zNew)
2656
{
2657
    // CPLDebug("OGR2SQLITE", "Rename");
2658
    return SQLITE_ERROR;
2659
}
2660
2661
/************************************************************************/
2662
/*                       sOGR2SQLITESpatialIndex                        */
2663
/************************************************************************/
2664
2665
static const struct sqlite3_module sOGR2SQLITESpatialIndex = {
2666
    1,                                    /* iVersion */
2667
    OGR2SQLITESpatialIndex_ConnectCreate, /* xCreate */
2668
    OGR2SQLITESpatialIndex_ConnectCreate, /* xConnect */
2669
    OGR2SQLITESpatialIndex_BestIndex,
2670
    OGR2SQLITESpatialIndex_DisconnectDestroy, /* xDisconnect */
2671
    OGR2SQLITESpatialIndex_DisconnectDestroy, /* xDestroy */
2672
    OGR2SQLITESpatialIndex_Open,
2673
    OGR2SQLITESpatialIndex_Close,
2674
    OGR2SQLITESpatialIndex_Filter,
2675
    OGR2SQLITESpatialIndex_Next,
2676
    OGR2SQLITESpatialIndex_Eof,
2677
    OGR2SQLITESpatialIndex_Column,
2678
    OGR2SQLITESpatialIndex_Rowid,
2679
    NULL, /* xUpdate */
2680
    NULL, /* xBegin */
2681
    NULL, /* xSync */
2682
    NULL, /* xCommit */
2683
    NULL, /* xFindFunctionRollback */
2684
    NULL, /* xFindFunction */
2685
    OGR2SQLITESpatialIndex_Rename};
2686
#endif  // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
2687
2688
/************************************************************************/
2689
/*                              Setup()                                 */
2690
/************************************************************************/
2691
2692
int OGR2SQLITEModule::Setup(sqlite3 *hDBIn)
2693
3.66k
{
2694
3.66k
    hDB = hDBIn;
2695
2696
3.66k
    int rc = sqlite3_create_module_v2(hDB, "VirtualOGR", &sOGR2SQLITEModule,
2697
3.66k
                                      this, OGR2SQLITEDestroyModule);
2698
3.66k
    if (rc != SQLITE_OK)
2699
0
        return FALSE;
2700
2701
#ifdef ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
2702
    rc = sqlite3_create_module(hDB, "VirtualOGRSpatialIndex",
2703
                               &sOGR2SQLITESpatialIndex, this);
2704
    if (rc != SQLITE_OK)
2705
        return FALSE;
2706
#endif  // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
2707
2708
3.66k
    rc = sqlite3_create_function(hDB, "ogr_layer_Extent", 1, SQLITE_ANY, this,
2709
3.66k
                                 OGR2SQLITE_ogr_layer_Extent, nullptr, nullptr);
2710
3.66k
    if (rc != SQLITE_OK)
2711
0
        return FALSE;
2712
2713
3.66k
    rc = sqlite3_create_function(hDB, "ogr_layer_SRID", 1, SQLITE_ANY, this,
2714
3.66k
                                 OGR2SQLITE_ogr_layer_SRID, nullptr, nullptr);
2715
3.66k
    if (rc != SQLITE_OK)
2716
0
        return FALSE;
2717
2718
3.66k
    rc = sqlite3_create_function(hDB, "ogr_layer_GeometryType", 1, SQLITE_ANY,
2719
3.66k
                                 this, OGR2SQLITE_ogr_layer_GeometryType,
2720
3.66k
                                 nullptr, nullptr);
2721
3.66k
    if (rc != SQLITE_OK)
2722
0
        return FALSE;
2723
2724
3.66k
    rc = sqlite3_create_function(hDB, "ogr_layer_FeatureCount", 1, SQLITE_ANY,
2725
3.66k
                                 this, OGR2SQLITE_ogr_layer_FeatureCount,
2726
3.66k
                                 nullptr, nullptr);
2727
3.66k
    if (rc != SQLITE_OK)
2728
0
        return FALSE;
2729
2730
3.66k
    SetHandleSQLFunctions(OGRSQLiteRegisterSQLFunctions(hDB));
2731
2732
3.66k
    return TRUE;
2733
3.66k
}
2734
2735
/************************************************************************/
2736
/*                        OGR2SQLITE_Setup()                            */
2737
/************************************************************************/
2738
2739
OGR2SQLITEModule *OGR2SQLITE_Setup(GDALDataset *poDS,
2740
                                   OGRSQLiteDataSource *poSQLiteDS)
2741
55
{
2742
55
    if (sqlite3_api == nullptr)
2743
0
    {
2744
        // Unlikely to happen. One theoretical possibility would be that:
2745
        // - thread A calls OGR2SQLITE_Register(), which calls sqlite3_auto_extension((void (*)(void))OGR2SQLITE_static_register)
2746
        // - thread B calls sqlite3_reset_auto_extension()
2747
        // - thread A opens a sqlite3 handle (which normally would have caused OGR2SQLITE_static_register() to be called, and setting the sqlite3_api static variable, without prior B intervention.
2748
        // - thread A calls us (OGR2SQLITE_Setup()) with sqlite3_api still set to its initial nullptr value
2749
0
        CPLError(CE_Failure, CPLE_AppDefined,
2750
0
                 "OGR2SQLITE_Setup() failed due to sqlite3_api == nullptr");
2751
0
        return nullptr;
2752
0
    }
2753
55
    OGR2SQLITEModule *poModule = new OGR2SQLITEModule();
2754
55
    poModule->Setup(poDS, poSQLiteDS);
2755
55
    return poModule;
2756
55
}
2757
2758
/************************************************************************/
2759
/*                  OGR2SQLITE_SetCaseSensitiveLike()                   */
2760
/************************************************************************/
2761
2762
void OGR2SQLITE_SetCaseSensitiveLike(OGR2SQLITEModule *poModule, bool b)
2763
0
{
2764
0
    poModule->SetCaseSensitiveLike(b);
2765
0
}
2766
2767
/************************************************************************/
2768
/*                       OGR2SQLITE_AddExtraDS()                        */
2769
/************************************************************************/
2770
2771
int OGR2SQLITE_AddExtraDS(OGR2SQLITEModule *poModule, GDALDataset *poDS)
2772
0
{
2773
0
    return poModule->AddExtraDS(poDS);
2774
0
}
2775
2776
#ifdef VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
2777
2778
/************************************************************************/
2779
/*                        sqlite3_extension_init()                      */
2780
/************************************************************************/
2781
2782
CPL_C_START
2783
int CPL_DLL sqlite3_extension_init(sqlite3 *hDB, char **pzErrMsg,
2784
                                   const sqlite3_api_routines *pApi);
2785
CPL_C_END
2786
2787
/* Entry point for dynamically loaded extension (typically called by
2788
 * load_extension()) */
2789
int sqlite3_extension_init(sqlite3 *hDB, char **pzErrMsg,
2790
                           const sqlite3_api_routines *pApi)
2791
0
{
2792
0
    CPLDebug("OGR", "OGR SQLite extension loading...");
2793
2794
0
    SQLITE_EXTENSION_INIT2(pApi);
2795
2796
    // Super hacky: this forces the malloc subsystem to be initialized.
2797
    // Normally we would not need to do this, but libgdal.so links against
2798
    // libsqlite3.so If doing SELECT load_extension('libgdal.so') from the
2799
    // sqlite3 console binary which statically links sqlite3, we might get 2
2800
    // copies of sqlite3 into memory: the static one from the sqlite3 binary,
2801
    // and the shared one linked by libgdal.so If the sqlite3_create_module_v2()
2802
    // function executed happens to be the one of the shared libsqlite3 and not
2803
    // the one of the sqlite3 binary, then the initialization of the malloc
2804
    // subsystem might not have been done. This demonstrates that our approach
2805
    // of having libgdal.so to link to libsqlite3 and be a sqlite3 extension is
2806
    // very fragile. But there aren't many other alternatives... There's no
2807
    // problem for applications (including the sqlite3 binary) that are built
2808
    // against a shared libsqlite3, since only one copy gets loaded.
2809
0
    sqlite3_free(sqlite3_malloc(1));
2810
2811
0
    *pzErrMsg = nullptr;
2812
2813
    /* Check if we have been already loaded. */
2814
    /* This is to avoid 'ogrinfo :memory: --config OGR_SQLITE_LOAD_EXTENSIONS
2815
     * libgdal.so' to crash */
2816
    /* since it would run OGR2SQLITEModule::Setup() first with
2817
     * OGR2SQLITE_static_register() */
2818
    /* and then through here. */
2819
0
    int rc =
2820
0
        sqlite3_exec(hDB, "SELECT ogr_version()", nullptr, nullptr, nullptr);
2821
2822
    /* Reset error flag */
2823
0
    sqlite3_exec(hDB, "SELECT 1", nullptr, nullptr, nullptr);
2824
2825
0
    if (rc == SQLITE_OK)
2826
0
    {
2827
2828
0
        CPLDebug("OGR", "... OGR virtual OGR already loaded !");
2829
0
        *pzErrMsg = sqlite3_mprintf(
2830
0
            "Cannot load libgdal as an extension from a OGR SQLite datasource");
2831
0
        return SQLITE_ERROR;
2832
0
    }
2833
2834
0
    OGRRegisterAll();
2835
2836
0
    OGR2SQLITEModule *poModule = new OGR2SQLITEModule();
2837
0
    if (poModule->Setup(hDB))
2838
0
    {
2839
0
        CPLDebug("OGR", "OGR SQLite extension loaded");
2840
0
        return SQLITE_OK;
2841
0
    }
2842
0
    else
2843
0
        return SQLITE_ERROR;
2844
0
}
2845
2846
#endif  // VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
2847
2848
/************************************************************************/
2849
/*                        OGR2SQLITE_static_register()                  */
2850
/************************************************************************/
2851
2852
#ifndef _WIN32
2853
extern const struct sqlite3_api_routines OGRSQLITE_static_routines;
2854
#endif
2855
2856
int OGR2SQLITE_static_register(sqlite3 *hDB, char **pzErrMsg, void *_pApi)
2857
3.74k
{
2858
3.74k
    const sqlite3_api_routines *pApi =
2859
3.74k
        static_cast<const sqlite3_api_routines *>(_pApi);
2860
3.74k
#ifndef _WIN32
2861
3.74k
    if ((pApi == nullptr) || (pApi->create_module == nullptr))
2862
0
    {
2863
0
        pApi = &OGRSQLITE_static_routines;
2864
0
    }
2865
3.74k
#endif
2866
3.74k
    SQLITE_EXTENSION_INIT2(pApi);
2867
2868
3.74k
    *pzErrMsg = nullptr;
2869
2870
    /* The config option is turned off by ogrsqliteexecutesql.cpp that needs */
2871
    /* to create a custom module */
2872
3.74k
    if (CPLTestBool(CPLGetConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "YES")))
2873
3.60k
    {
2874
        /* Can happen if SQLite is compiled with SQLITE_OMIT_LOAD_EXTENSION
2875
         * (with SQLite 3.6.10 for example) */
2876
        /* We return here OK since it is not vital for regular SQLite databases
2877
         */
2878
        /* to load the OGR SQL functions */
2879
3.60k
        if (pApi->create_module == nullptr)
2880
0
            return SQLITE_OK;
2881
2882
3.60k
        OGR2SQLITEModule *poModule = new OGR2SQLITEModule();
2883
3.60k
        return poModule->Setup(hDB) ? SQLITE_OK : SQLITE_ERROR;
2884
3.60k
    }
2885
134
    else
2886
134
    {
2887
        /* Can happen if SQLite is compiled with SQLITE_OMIT_LOAD_EXTENSION
2888
         * (with SQLite 3.6.10 for example) */
2889
        /* We return fail since Setup() will later be called, and crash */
2890
        /* if create_module isn't available */
2891
134
        if (pApi->create_module == nullptr)
2892
0
            return SQLITE_ERROR;
2893
134
    }
2894
2895
134
    return SQLITE_OK;
2896
3.74k
}
2897
2898
#endif  // HAVE_SQLITE3EXT_H