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