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