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