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