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