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