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