LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/sqlite - ogrsqliteexecutesql.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 419 371 88.5 %
Date: 2013-03-30 Functions: 14 11 78.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsqliteexecutesql.cpp 25435 2013-01-02 20:40:56Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Run SQL requests with SQLite SQL engine
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2012, Even Rouault <even dot rouault at mines dash paris dot org>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_sqlite.h"
      31                 : #include "ogr_api.h"
      32                 : #include "ogrsqlitevirtualogr.h"
      33                 : #include "ogrsqliteexecutesql.h"
      34                 : #include "cpl_multiproc.h"
      35                 : 
      36                 : #ifdef HAVE_SQLITE_VFS
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                       OGRSQLiteExecuteSQLLayer                       */
      40                 : /************************************************************************/
      41                 : 
      42                 : class OGRSQLiteExecuteSQLLayer: public OGRSQLiteSelectLayer
      43                 : {
      44                 :         char             *pszTmpDBName;
      45                 : 
      46                 :     public:
      47                 :         OGRSQLiteExecuteSQLLayer(char* pszTmpDBName,
      48                 :                                  OGRSQLiteDataSource* poDS,
      49                 :                                  CPLString osSQL,
      50                 :                                  sqlite3_stmt * hStmt,
      51                 :                                  int bUseStatementForGetNextFeature,
      52                 :                                  int bEmptyLayer );
      53                 :         virtual ~OGRSQLiteExecuteSQLLayer();
      54                 : };
      55                 : 
      56                 : /************************************************************************/
      57                 : /*                         OGRSQLiteExecuteSQLLayer()                   */
      58                 : /************************************************************************/
      59                 : 
      60             453 : OGRSQLiteExecuteSQLLayer::OGRSQLiteExecuteSQLLayer(char* pszTmpDBName,
      61                 :                                                    OGRSQLiteDataSource* poDS,
      62                 :                                                    CPLString osSQL,
      63                 :                                                    sqlite3_stmt * hStmt,
      64                 :                                                    int bUseStatementForGetNextFeature,
      65                 :                                                    int bEmptyLayer ) :
      66                 : 
      67                 :                                OGRSQLiteSelectLayer(poDS, osSQL, hStmt,
      68                 :                                                     bUseStatementForGetNextFeature,
      69             453 :                                                     bEmptyLayer)
      70                 : {
      71             453 :     this->pszTmpDBName = pszTmpDBName;
      72             453 : }
      73                 : 
      74                 : /************************************************************************/
      75                 : /*                        ~OGRSQLiteExecuteSQLLayer()                   */
      76                 : /************************************************************************/
      77                 : 
      78             453 : OGRSQLiteExecuteSQLLayer::~OGRSQLiteExecuteSQLLayer()
      79                 : {
      80                 :     /* This is a bit peculiar: we must "finalize" the OGRLayer, since */
      81                 :     /* it has objects that depend on the datasource, that we are just */
      82                 :     /* going to destroy afterwards. The issue here is that we destroy */
      83                 :     /* our own datasource ! */
      84             453 :     Finalize();
      85                 : 
      86             453 :     delete poDS;
      87             453 :     VSIUnlink(pszTmpDBName);
      88             453 :     CPLFree(pszTmpDBName);
      89             453 : }
      90                 : 
      91                 : /************************************************************************/
      92                 : /*                       OGR2SQLITEExtractUnquotedString()              */
      93                 : /************************************************************************/
      94                 : 
      95             244 : static CPLString OGR2SQLITEExtractUnquotedString(const char **ppszSQLCommand)
      96                 : {
      97             244 :     CPLString osRet;
      98             244 :     const char *pszSQLCommand = *ppszSQLCommand;
      99             244 :     char chQuoteChar = 0;
     100                 : 
     101             244 :     if( *pszSQLCommand == '"' || *pszSQLCommand == '\'' )
     102                 :     {
     103              18 :         chQuoteChar = *pszSQLCommand;
     104              18 :         pszSQLCommand ++;
     105                 :     }
     106                 : 
     107            2401 :     while( *pszSQLCommand != '\0' )
     108                 :     {
     109            2155 :         if( *pszSQLCommand == chQuoteChar &&
     110              18 :             pszSQLCommand[1] == chQuoteChar )
     111                 :         {
     112               0 :             pszSQLCommand ++;
     113               0 :             osRet += chQuoteChar;
     114                 :         }
     115            2137 :         else if( *pszSQLCommand == chQuoteChar )
     116                 :         {
     117              18 :             pszSQLCommand ++;
     118              18 :             break;
     119                 :         }
     120            2119 :         else if( chQuoteChar == '\0' &&
     121                 :                 (isspace((int)*pszSQLCommand) ||
     122                 :                  *pszSQLCommand == '.' ||
     123                 :                  *pszSQLCommand == ')' ||
     124                 :                  *pszSQLCommand == ',') )
     125             206 :             break;
     126                 :         else
     127            1913 :             osRet += *pszSQLCommand;
     128                 : 
     129            1913 :         pszSQLCommand ++;
     130                 :     }
     131                 : 
     132             244 :     *ppszSQLCommand = pszSQLCommand;
     133                 : 
     134               0 :     return osRet;
     135                 : }
     136                 : 
     137                 : /************************************************************************/
     138                 : /*                      OGR2SQLITEExtractLayerDesc()                    */
     139                 : /************************************************************************/
     140                 : 
     141                 : static
     142             230 : LayerDesc OGR2SQLITEExtractLayerDesc(const char **ppszSQLCommand)
     143                 : {
     144             230 :     CPLString osStr;
     145             230 :     const char *pszSQLCommand = *ppszSQLCommand;
     146             230 :     LayerDesc oLayerDesc;
     147                 : 
     148             460 :     while( isspace((int)*pszSQLCommand) )
     149               0 :         pszSQLCommand ++;
     150                 : 
     151             230 :     const char* pszOriginalStrStart = pszSQLCommand;
     152             230 :     oLayerDesc.osOriginalStr = pszSQLCommand;
     153                 : 
     154             230 :     osStr = OGR2SQLITEExtractUnquotedString(&pszSQLCommand);
     155                 : 
     156             230 :     if( *pszSQLCommand == '.' )
     157                 :     {
     158               6 :         oLayerDesc.osDSName = osStr;
     159               6 :         pszSQLCommand ++;
     160                 :         oLayerDesc.osLayerName =
     161               6 :                             OGR2SQLITEExtractUnquotedString(&pszSQLCommand);
     162                 :     }
     163                 :     else
     164                 :     {
     165             224 :         oLayerDesc.osLayerName = osStr;
     166                 :     }
     167                 :     
     168             230 :     oLayerDesc.osOriginalStr.resize(pszSQLCommand - pszOriginalStrStart);
     169                 : 
     170             230 :     *ppszSQLCommand = pszSQLCommand;
     171                 : 
     172             230 :     return oLayerDesc;
     173                 : }
     174                 : 
     175                 : /************************************************************************/
     176                 : /*                           OGR2SQLITEAddLayer()                       */
     177                 : /************************************************************************/
     178                 : 
     179             230 : static void OGR2SQLITEAddLayer( const char*& pszStart, int& nNum,
     180                 :                                 const char*& pszSQLCommand,
     181                 :                                 std::set<LayerDesc>& oSet,
     182                 :                                 CPLString& osModifiedSQL )
     183                 : {
     184             230 :     CPLString osTruncated(pszStart);
     185             230 :     osTruncated.resize(pszSQLCommand - pszStart);
     186             230 :     osModifiedSQL += osTruncated;
     187             230 :     pszStart = pszSQLCommand;
     188             230 :     LayerDesc oLayerDesc = OGR2SQLITEExtractLayerDesc(&pszSQLCommand);
     189             230 :     int bInsert = TRUE;
     190             230 :     if( oLayerDesc.osDSName.size() == 0 )
     191                 :     {
     192             224 :         osTruncated = pszStart;
     193             224 :         osTruncated.resize(pszSQLCommand - pszStart);
     194             224 :         osModifiedSQL += osTruncated; 
     195                 :     }
     196                 :     else
     197                 :     {
     198               6 :         std::set<LayerDesc>::iterator oIter = oSet.find(oLayerDesc);
     199               6 :         if( oIter == oSet.end() )
     200                 :         {
     201               6 :             oLayerDesc.osSubstitutedName = CPLString().Printf("_OGR_%d", nNum ++);
     202               6 :             osModifiedSQL += "\"";
     203               6 :             osModifiedSQL += oLayerDesc.osSubstitutedName;
     204               6 :             osModifiedSQL += "\"";
     205                 :         }
     206                 :         else
     207                 :         {
     208               0 :             osModifiedSQL += (*oIter).osSubstitutedName;
     209               0 :             bInsert = FALSE;
     210                 :         }
     211                 :     }
     212             230 :     if( bInsert )
     213                 :     {
     214             230 :         oSet.insert(oLayerDesc);
     215                 :     }
     216             230 :     pszStart = pszSQLCommand;
     217             230 : }
     218                 : 
     219                 : /************************************************************************/
     220                 : /*                         StartsAsSQLITEKeyWord()                      */
     221                 : /************************************************************************/
     222                 : 
     223                 : static const char* apszKeywords[] =  {
     224                 :     "WHERE", "GROUP", "ORDER", "JOIN", "UNION", "INTERSECT", "EXCEPT", "LIMIT"
     225                 : };
     226                 : 
     227             182 : static int StartsAsSQLITEKeyWord(const char* pszStr)
     228                 : {
     229                 :     int i;
     230             264 :     for(i=0;i<(int)(sizeof(apszKeywords) / sizeof(char*));i++)
     231                 :     {
     232             257 :         if( EQUALN(pszStr, apszKeywords[i], strlen(apszKeywords[i])) )
     233             175 :             return TRUE;
     234                 :     }
     235               7 :     return FALSE;
     236                 : }
     237                 : 
     238                 : /************************************************************************/
     239                 : /*                     OGR2SQLITEGetPotentialLayerNames()               */
     240                 : /************************************************************************/
     241                 : 
     242             490 : static void OGR2SQLITEGetPotentialLayerNamesInternal(const char **ppszSQLCommand,
     243                 :                                                      std::set<LayerDesc>& oSetLayers,
     244                 :                                                      std::set<CPLString>& oSetSpatialIndex,
     245                 :                                                      CPLString& osModifiedSQL,
     246                 :                                                      int& nNum)
     247                 : {
     248             490 :     const char *pszSQLCommand = *ppszSQLCommand;
     249             490 :     const char* pszStart = pszSQLCommand;
     250                 :     char ch;
     251             490 :     int nParenthesisLevel = 0;
     252             490 :     int bLookforFTableName = FALSE;
     253                 : 
     254           19142 :     while( (ch = *pszSQLCommand) != '\0' )
     255                 :     {
     256           18164 :         if( ch == '(' )
     257             462 :             nParenthesisLevel ++;
     258           17702 :         else if( ch == ')' )
     259                 :         {
     260             474 :             nParenthesisLevel --;
     261             474 :             if( nParenthesisLevel < 0 )
     262                 :             {
     263               2 :                 pszSQLCommand ++;
     264               2 :                 break;
     265                 :             }
     266                 :         }
     267                 : 
     268                 :         /* Skip literals and strings */
     269           18582 :         if( ch == '\'' || ch == '"' )
     270                 :         {
     271             420 :             char chEscapeChar = ch;
     272             420 :             pszSQLCommand ++;
     273           16752 :             while( (ch = *pszSQLCommand) != '\0' )
     274                 :             {
     275           16332 :                 if( ch == chEscapeChar && pszSQLCommand[1] == chEscapeChar )
     276               0 :                     pszSQLCommand ++;
     277           16332 :                 else if( ch == chEscapeChar )
     278                 :                 {
     279             420 :                     pszSQLCommand ++;
     280             420 :                     break;
     281                 :                 }
     282           15912 :                 pszSQLCommand ++;
     283                 :             }
     284                 :         }
     285                 : 
     286           17742 :         else if( EQUALN(pszSQLCommand, "ogr_layer_", strlen("ogr_layer_"))  )
     287                 :         {
     288             192 :             while( *pszSQLCommand != '\0' && *pszSQLCommand != '(' )
     289             172 :                 pszSQLCommand ++;
     290                 : 
     291              10 :             if( *pszSQLCommand != '(' )
     292               0 :                 break;
     293                 : 
     294              10 :             pszSQLCommand ++;
     295              10 :             nParenthesisLevel ++;
     296                 : 
     297              20 :             while( isspace((int)*pszSQLCommand) )
     298               0 :                 pszSQLCommand ++;
     299                 : 
     300                 :             OGR2SQLITEAddLayer(pszStart, nNum,
     301              10 :                                 pszSQLCommand, oSetLayers, osModifiedSQL);
     302                 :         }
     303                 : 
     304           17735 :         else if( bLookforFTableName &&
     305                 :                  EQUALN(pszSQLCommand, "f_table_name", strlen("f_table_name")) &&
     306               1 :                  (pszSQLCommand[strlen("f_table_name")] == '=' ||
     307               1 :                   isspace((int)pszSQLCommand[strlen("f_table_name")])) )
     308                 :         {
     309               1 :             pszSQLCommand += strlen("f_table_name");
     310                 : 
     311               3 :             while( isspace((int)*pszSQLCommand) )
     312               1 :                 pszSQLCommand ++;
     313                 : 
     314               1 :             if( *pszSQLCommand == '=' )
     315                 :             {
     316               1 :                 pszSQLCommand ++;
     317                 : 
     318               3 :                 while( isspace((int)*pszSQLCommand) )
     319               1 :                     pszSQLCommand ++;
     320                 : 
     321               1 :                 oSetSpatialIndex.insert(OGR2SQLITEExtractUnquotedString(&pszSQLCommand));
     322                 :             }
     323                 : 
     324               1 :             bLookforFTableName = FALSE;
     325                 :         }
     326                 : 
     327           18261 :         else if( EQUALN(pszSQLCommand, "FROM", strlen("FROM")) &&
     328             328 :                  isspace(pszSQLCommand[strlen("FROM")]) )
     329                 :         {
     330             203 :             pszSQLCommand += strlen("FROM") + 1;
     331                 : 
     332             406 :             while( isspace((int)*pszSQLCommand) )
     333               0 :                 pszSQLCommand ++;
     334                 : 
     335             204 :             if( EQUALN(pszSQLCommand, "SpatialIndex", strlen("SpatialIndex")) &&
     336               1 :                 isspace((int)pszSQLCommand[strlen("SpatialIndex")]) )
     337                 :             {
     338               1 :                 pszSQLCommand += strlen("SpatialIndex") + 1;
     339                 : 
     340               1 :                 bLookforFTableName = TRUE;
     341                 : 
     342               1 :                 continue;
     343                 :             }
     344                 : 
     345             202 :             if( *pszSQLCommand == '(' )
     346                 :             {
     347               2 :                 pszSQLCommand++;
     348                 : 
     349               2 :                 CPLString osTruncated(pszStart);
     350               2 :                 osTruncated.resize(pszSQLCommand - pszStart);
     351               2 :                 osModifiedSQL += osTruncated;
     352                 : 
     353                 :                 OGR2SQLITEGetPotentialLayerNamesInternal(
     354                 :                             &pszSQLCommand, oSetLayers, oSetSpatialIndex,
     355               2 :                             osModifiedSQL, nNum);
     356                 : 
     357               2 :                 pszStart = pszSQLCommand;
     358                 :             }
     359                 :             else
     360                 :                 OGR2SQLITEAddLayer(pszStart, nNum,
     361             200 :                                    pszSQLCommand, oSetLayers, osModifiedSQL);
     362                 : 
     363             413 :             while( *pszSQLCommand != '\0' )
     364                 :             {
     365             188 :                 if( isspace((int)*pszSQLCommand) )
     366                 :                 {
     367             182 :                     pszSQLCommand ++;
     368             364 :                     while( isspace((int)*pszSQLCommand) )
     369               0 :                         pszSQLCommand ++;
     370                 : 
     371             182 :                     if( EQUALN(pszSQLCommand, "AS", 2) )
     372                 :                     {
     373               0 :                         pszSQLCommand += 2;
     374               0 :                         while( isspace((int)*pszSQLCommand) )
     375               0 :                             pszSQLCommand ++;
     376                 :                     }
     377                 : 
     378                 :                     /* Skip alias */
     379             182 :                     if( *pszSQLCommand != '\0' &&
     380                 :                         *pszSQLCommand != ',' )
     381                 :                     {
     382             182 :                         if ( StartsAsSQLITEKeyWord(pszSQLCommand) )
     383             175 :                             break;
     384               7 :                         OGR2SQLITEExtractUnquotedString(&pszSQLCommand);
     385                 :                     }
     386                 :                 }
     387               6 :                 else if (*pszSQLCommand == ',' )
     388                 :                 {
     389               2 :                     pszSQLCommand ++;
     390               6 :                     while( isspace((int)*pszSQLCommand) )
     391               2 :                         pszSQLCommand ++;
     392                 : 
     393               2 :                     if( *pszSQLCommand == '(' )
     394                 :                     {
     395               0 :                         pszSQLCommand++;
     396                 : 
     397               0 :                         CPLString osTruncated(pszStart);
     398               0 :                         osTruncated.resize(pszSQLCommand - pszStart);
     399               0 :                         osModifiedSQL += osTruncated;
     400                 : 
     401                 :                         OGR2SQLITEGetPotentialLayerNamesInternal(
     402                 :                                                     &pszSQLCommand, oSetLayers,
     403                 :                                                     oSetSpatialIndex,
     404               0 :                                                     osModifiedSQL, nNum);
     405                 : 
     406               0 :                         pszStart = pszSQLCommand;
     407                 :                     }
     408                 :                     else
     409                 :                         OGR2SQLITEAddLayer(pszStart, nNum,
     410                 :                                            pszSQLCommand, oSetLayers,
     411               2 :                                            osModifiedSQL);
     412                 :                 }
     413                 :                 else
     414               4 :                     break;
     415                 :             }
     416                 :         }
     417           17540 :         else if ( EQUALN(pszSQLCommand, "JOIN", strlen("JOIN")) &&
     418               8 :                   isspace(pszSQLCommand[strlen("JOIN")]) )
     419                 :         {
     420               4 :             pszSQLCommand += strlen("JOIN") + 1;
     421                 :             OGR2SQLITEAddLayer(pszStart, nNum, pszSQLCommand,
     422               4 :                                oSetLayers, osModifiedSQL);
     423                 :         }
     424           17540 :         else if( EQUALN(pszSQLCommand, "INTO", strlen("INTO")) &&
     425               8 :                  isspace(pszSQLCommand[strlen("INTO")]) )
     426                 :         {
     427               8 :             pszSQLCommand += strlen("INTO") + 1;
     428                 :             OGR2SQLITEAddLayer(pszStart, nNum, pszSQLCommand,
     429               8 :                                oSetLayers, osModifiedSQL);
     430                 :         }
     431           17528 :         else if( EQUALN(pszSQLCommand, "UPDATE", strlen("UPDATE")) &&
     432               6 :                  isspace(pszSQLCommand[strlen("UPDATE")]) )
     433                 :         {
     434               6 :             pszSQLCommand += strlen("UPDATE") + 1;
     435                 :             OGR2SQLITEAddLayer(pszStart, nNum, pszSQLCommand,
     436               6 :                                oSetLayers, osModifiedSQL);
     437                 :         }
     438           17510 :         else if ( EQUALN(pszSQLCommand, "DROP TABLE ", strlen("DROP TABLE ")) )
     439                 :         {
     440               0 :             pszSQLCommand += strlen("DROP TABLE") + 1;
     441                 :             OGR2SQLITEAddLayer(pszStart, nNum, pszSQLCommand,
     442               0 :                                oSetLayers, osModifiedSQL);
     443                 :         }
     444                 :         else
     445           17510 :             pszSQLCommand ++;
     446                 :     }
     447                 : 
     448             490 :     CPLString osTruncated(pszStart);
     449             490 :     osTruncated.resize(pszSQLCommand - pszStart);
     450             490 :     osModifiedSQL += osTruncated;
     451                 : 
     452             490 :     *ppszSQLCommand = pszSQLCommand;
     453             490 : }
     454                 : 
     455             488 : static void OGR2SQLITEGetPotentialLayerNames(const char *pszSQLCommand,
     456                 :                                              std::set<LayerDesc>& oSetLayers,
     457                 :                                              std::set<CPLString>& oSetSpatialIndex,
     458                 :                                              CPLString& osModifiedSQL)
     459                 : {
     460             488 :     int nNum = 1;
     461                 :     OGR2SQLITEGetPotentialLayerNamesInternal(&pszSQLCommand, oSetLayers,
     462                 :                                              oSetSpatialIndex,
     463             488 :                                              osModifiedSQL, nNum);
     464             488 : }
     465                 : 
     466                 : /************************************************************************/
     467                 : /*               OGR2SQLITE_IgnoreAllFieldsExceptGeometry()             */
     468                 : /************************************************************************/
     469                 : 
     470                 : static
     471               2 : void OGR2SQLITE_IgnoreAllFieldsExceptGeometry(OGRLayer* poLayer)
     472                 : {
     473               2 :     char** papszIgnored = NULL;
     474               2 :     papszIgnored = CSLAddString(papszIgnored, "OGR_STYLE");
     475               2 :     OGRFeatureDefn* poFeatureDefn = poLayer->GetLayerDefn();
     476               4 :     for(int i=0; i < poFeatureDefn->GetFieldCount(); i++)
     477                 :     {
     478                 :         papszIgnored = CSLAddString(papszIgnored,
     479               2 :                         poFeatureDefn->GetFieldDefn(i)->GetNameRef());
     480                 :     }
     481               2 :     poLayer->SetIgnoredFields((const char**)papszIgnored);
     482               2 :     CSLDestroy(papszIgnored);
     483               2 : }
     484                 : 
     485                 : /************************************************************************/
     486                 : /*                          OGRSQLiteExecuteSQL()                       */
     487                 : /************************************************************************/
     488                 : 
     489             487 : OGRLayer * OGRSQLiteExecuteSQL( OGRDataSource* poDS,
     490                 :                                 const char *pszStatement,
     491                 :                                 OGRGeometry *poSpatialFilter,
     492                 :                                 const char *pszDialect )
     493                 : {
     494             487 :     char* pszTmpDBName = (char*) CPLMalloc(256);
     495             487 :     sprintf(pszTmpDBName, "/vsimem/ogr2sqlite/temp_%p.db", pszTmpDBName);
     496                 : 
     497             487 :     OGRSQLiteDataSource* poSQLiteDS = NULL;
     498                 :     int nRet;
     499             487 :     int bSpatialiteDB = FALSE;
     500                 : 
     501             487 :     CPLString osOldVal;
     502             487 :     const char* pszOldVal = CPLGetConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", NULL);
     503             487 :     if( pszOldVal != NULL )
     504                 :     {
     505               0 :         osOldVal = pszOldVal;
     506               0 :         pszOldVal = osOldVal.c_str();
     507                 :     }
     508                 : 
     509                 : /* -------------------------------------------------------------------- */
     510                 : /*      Create in-memory sqlite/spatialite DB                           */
     511                 : /* -------------------------------------------------------------------- */
     512                 : 
     513                 : #ifdef HAVE_SPATIALITE
     514                 : 
     515                 : /* -------------------------------------------------------------------- */
     516                 : /*      Creating an empty spatialite DB (with spatial_ref_sys populated */
     517                 : /*      has a non-neglectable cost. So at the first attempt, let's make */
     518                 : /*      one and cache it for later use.                                 */
     519                 : /* -------------------------------------------------------------------- */
     520                 : #if 1
     521                 :     static vsi_l_offset nEmptyDBSize = 0;
     522                 :     static GByte* pabyEmptyDB = NULL;
     523                 :     {
     524                 :         static void* hMutex = NULL;
     525             487 :         CPLMutexHolder oMutexHolder(&hMutex);
     526                 :         static int bTried = FALSE;
     527             487 :         if( !bTried &&
     528                 :             CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) )
     529                 :         {
     530               1 :             bTried = TRUE;
     531               1 :             char* pszCachedFilename = (char*) CPLMalloc(256);
     532               1 :             sprintf(pszCachedFilename, "/vsimem/ogr2sqlite/reference_%p.db",pszCachedFilename);
     533               1 :             char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES");
     534               1 :             OGRSQLiteDataSource* poCachedDS = new OGRSQLiteDataSource();
     535               2 :             nRet = poCachedDS->Create( pszCachedFilename, papszOptions );
     536               1 :             CSLDestroy(papszOptions);
     537               1 :             papszOptions = NULL;
     538               1 :             delete poCachedDS;
     539               1 :             if( nRet )
     540                 :                 /* Note: the reference file keeps the ownership of the data, so that */
     541                 :                 /* it gets released with VSICleanupFileManager() */
     542               1 :                 pabyEmptyDB = VSIGetMemFileBuffer( pszCachedFilename, &nEmptyDBSize, FALSE );
     543               1 :             CPLFree( pszCachedFilename );
     544             487 :         }
     545                 :     }
     546                 : 
     547                 :     /* The following configuration option is usefull mostly for debugging/testing */
     548             487 :     if( pabyEmptyDB != NULL && CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) )
     549                 :     {
     550             388 :         GByte* pabyEmptyDBClone = (GByte*)VSIMalloc(nEmptyDBSize);
     551             388 :         if( pabyEmptyDBClone == NULL )
     552                 :         {
     553               0 :             CPLFree(pszTmpDBName);
     554               0 :             return NULL;
     555                 :         }
     556             388 :         memcpy(pabyEmptyDBClone, pabyEmptyDB, nEmptyDBSize);
     557             388 :         VSIFCloseL(VSIFileFromMemBuffer( pszTmpDBName, pabyEmptyDBClone, nEmptyDBSize, TRUE ));
     558                 : 
     559             388 :         poSQLiteDS = new OGRSQLiteDataSource();
     560             388 :         CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO");
     561             388 :         nRet = poSQLiteDS->Open( pszTmpDBName, TRUE );
     562             388 :         CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal);
     563             388 :         if( !nRet )
     564                 :         {
     565                 :             /* should not happen really ! */
     566               0 :             delete poSQLiteDS;
     567               0 :             VSIUnlink(pszTmpDBName);
     568               0 :             CPLFree(pszTmpDBName);
     569               0 :             return NULL;
     570                 :         }
     571             388 :         bSpatialiteDB = TRUE;
     572                 :     }
     573                 : #else
     574                 :     /* No caching version */
     575                 :     poSQLiteDS = new OGRSQLiteDataSource();
     576                 :     char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES");
     577                 :     CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO");
     578                 :     nRet = poSQLiteDS->Create( pszTmpDBName, papszOptions );
     579                 :     CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal);
     580                 :     CSLDestroy(papszOptions);
     581                 :     papszOptions = NULL;
     582                 :     if( nRet )
     583                 :     {
     584                 :         bSpatialiteDB = TRUE;
     585                 :     }
     586                 : #endif
     587                 : 
     588                 :     else
     589                 :     {
     590              99 :         delete poSQLiteDS;
     591              99 :         poSQLiteDS = NULL;
     592                 : #else // HAVE_SPATIALITE
     593                 :     if( TRUE )
     594                 :     {
     595                 : #endif // HAVE_SPATIALITE
     596              99 :         poSQLiteDS = new OGRSQLiteDataSource();
     597              99 :         CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO");
     598              99 :         nRet = poSQLiteDS->Create( pszTmpDBName, NULL );
     599              99 :         CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal);
     600              99 :         if( !nRet )
     601                 :         {
     602               0 :             delete poSQLiteDS;
     603               0 :             VSIUnlink(pszTmpDBName);
     604               0 :             CPLFree(pszTmpDBName);
     605               0 :             return NULL;
     606                 :         }
     607                 :     }
     608                 : 
     609                 : /* -------------------------------------------------------------------- */
     610                 : /*      Attach the Virtual Table OGR2SQLITE module to it.               */
     611                 : /* -------------------------------------------------------------------- */
     612             487 :     OGR2SQLITEModule* poModule = OGR2SQLITE_Setup(poDS, poSQLiteDS);
     613             487 :     sqlite3* hDB = poSQLiteDS->GetDB();
     614                 : 
     615                 : /* -------------------------------------------------------------------- */
     616                 : /*      Analysze the statement to determine which tables will be used.  */
     617                 : /* -------------------------------------------------------------------- */
     618             487 :     std::set<LayerDesc> oSetLayers;
     619             487 :     std::set<CPLString> oSetSpatialIndex;
     620             487 :     CPLString osModifiedSQL;
     621                 :     OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers,
     622             487 :                                      oSetSpatialIndex, osModifiedSQL);
     623             487 :     std::set<LayerDesc>::iterator oIter = oSetLayers.begin();
     624                 : 
     625             487 :     if( strcmp(pszStatement, osModifiedSQL.c_str()) != 0 )
     626               5 :         CPLDebug("OGR", "Modified SQL: %s", osModifiedSQL.c_str());
     627             487 :     pszStatement = osModifiedSQL.c_str(); /* do not use it anymore */
     628                 : 
     629             487 :     int bFoundOGRStyle = ( osModifiedSQL.ifind("OGR_STYLE") != std::string::npos );
     630                 : 
     631                 : /* -------------------------------------------------------------------- */
     632                 : /*      For each of those tables, create a Virtual Table.               */
     633                 : /* -------------------------------------------------------------------- */
     634             487 :     for(; oIter != oSetLayers.end(); ++oIter)
     635                 :     {
     636             227 :         const LayerDesc& oLayerDesc = *oIter;
     637                 :         /*CPLDebug("OGR", "Layer desc : %s, %s, %s, %s",
     638                 :                  oLayerDesc.osOriginalStr.c_str(),
     639                 :                  oLayerDesc.osSubstitutedName.c_str(),
     640                 :                  oLayerDesc.osDSName.c_str(),
     641                 :                  oLayerDesc.osLayerName.c_str());*/
     642                 : 
     643             227 :         CPLString osSQL;
     644             227 :         OGRLayer* poLayer = NULL;
     645             227 :         CPLString osTableName;
     646                 :         int nExtraDS;
     647             227 :         if( oLayerDesc.osDSName.size() == 0 )
     648                 :         {
     649             221 :             poLayer = poDS->GetLayerByName(oLayerDesc.osLayerName);
     650                 :             /* Might be a false positive (unlikely) */
     651             221 :             if( poLayer == NULL )
     652               5 :                 continue;
     653                 : 
     654             216 :             osTableName = oLayerDesc.osLayerName;
     655                 : 
     656             216 :             nExtraDS = -1;
     657                 : 
     658                 :             osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR(%d,'%s',%d)",
     659                 :                          OGRSQLiteEscapeName(osTableName).c_str(),
     660                 :                          nExtraDS,
     661                 :                          OGRSQLiteEscape(osTableName).c_str(),
     662             216 :                          bFoundOGRStyle);
     663                 :         }
     664                 :         else
     665                 :         {
     666                 :             OGRDataSource* poOtherDS = (OGRDataSource* )
     667               6 :                 OGROpen(oLayerDesc.osDSName, FALSE, NULL);
     668               6 :             if( poOtherDS == NULL )
     669                 :             {
     670                 :                 CPLError(CE_Failure, CPLE_AppDefined,
     671                 :                          "Cannot open datasource '%s'",
     672               1 :                          oLayerDesc.osDSName.c_str() );
     673               1 :                 delete poSQLiteDS;
     674               1 :                 VSIUnlink(pszTmpDBName);
     675               1 :                 CPLFree(pszTmpDBName);
     676               1 :                 return NULL;
     677                 :             }
     678                 :             
     679               5 :             poLayer = poOtherDS->GetLayerByName(oLayerDesc.osLayerName);
     680               5 :             if( poLayer == NULL )
     681                 :             {
     682                 :                 CPLError(CE_Failure, CPLE_AppDefined,
     683                 :                          "Cannot find layer '%s' in '%s'",
     684                 :                          oLayerDesc.osLayerName.c_str(),
     685               1 :                          oLayerDesc.osDSName.c_str() );
     686               1 :                 delete poOtherDS;
     687               1 :                 delete poSQLiteDS;
     688               1 :                 VSIUnlink(pszTmpDBName);
     689               1 :                 CPLFree(pszTmpDBName);
     690               1 :                 return NULL;
     691                 :             }
     692                 : 
     693               4 :             osTableName = oLayerDesc.osSubstitutedName;
     694                 : 
     695               4 :             nExtraDS = OGR2SQLITE_AddExtraDS(poModule, poOtherDS);
     696                 : 
     697                 :             osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR(%d,'%s',%d)",
     698                 :                          OGRSQLiteEscapeName(osTableName).c_str(),
     699                 :                          nExtraDS,
     700                 :                          OGRSQLiteEscape(oLayerDesc.osLayerName).c_str(),
     701               4 :                          bFoundOGRStyle);
     702                 :         }
     703                 : 
     704             220 :         char* pszErrMsg = NULL;
     705                 :         int rc = sqlite3_exec( hDB, osSQL.c_str(),
     706             220 :                                NULL, NULL, &pszErrMsg );
     707             220 :         if( rc != SQLITE_OK )
     708                 :         {
     709                 :             CPLError(CE_Failure, CPLE_AppDefined,
     710                 :                      "Cannot create virtual table for layer '%s' : %s",
     711               0 :                      osTableName.c_str(), pszErrMsg);
     712               0 :             sqlite3_free(pszErrMsg);
     713               0 :             continue;
     714                 :         }
     715                 : 
     716             220 :         if( poLayer->GetGeomType() == wkbNone )
     717              98 :             continue;
     718                 : 
     719             122 :         CPLString osGeomColRaw(OGR2SQLITE_GetNameForGeometryColumn(poLayer));
     720             122 :         const char* pszGeomColRaw = osGeomColRaw.c_str();
     721                 : 
     722             122 :         CPLString osGeomColEscaped(OGRSQLiteEscape(pszGeomColRaw));
     723             122 :         const char* pszGeomColEscaped = osGeomColEscaped.c_str();
     724                 : 
     725             122 :         CPLString osLayerNameEscaped(OGRSQLiteEscape(osTableName));
     726             122 :         const char* pszLayerNameEscaped = osLayerNameEscaped.c_str();
     727                 : 
     728                 :         CPLString osIdxNameRaw(CPLSPrintf("idx_%s_%s",
     729             122 :                         oLayerDesc.osLayerName.c_str(), pszGeomColRaw));
     730             122 :         CPLString osIdxNameEscaped(OGRSQLiteEscapeName(osIdxNameRaw));
     731                 : 
     732                 :         /* Make sure that the SRS is injected in spatial_ref_sys */
     733             122 :         OGRSpatialReference* poSRS = poLayer->GetSpatialRef();
     734             122 :         int nSRSId = poSQLiteDS->GetUndefinedSRID();
     735             122 :         if( poSRS != NULL )
     736              25 :             nSRSId = poSQLiteDS->FetchSRSId(poSRS);
     737                 : 
     738             122 :         int bCreateSpatialIndex = FALSE;
     739             122 :         if( !bSpatialiteDB )
     740                 :         {
     741                 :             osSQL.Printf("INSERT INTO geometry_columns (f_table_name, "
     742                 :                         "f_geometry_column, geometry_format, geometry_type, "
     743                 :                         "coord_dimension, srid) "
     744                 :                         "VALUES ('%s','%s','SpatiaLite',%d,%d,%d)",
     745                 :                         pszLayerNameEscaped,
     746                 :                         pszGeomColEscaped,
     747              52 :                          (int) wkbFlatten(poLayer->GetGeomType()),
     748              52 :                         ( poLayer->GetGeomType() & wkb25DBit ) ? 3 : 2,
     749             104 :                         nSRSId);
     750                 :         }
     751                 : #ifdef HAVE_SPATIALITE
     752                 :         else
     753                 :         {
     754                 :             /* We detect the need for creating a spatial index by 2 means : */
     755                 : 
     756                 :             /* 1) if there's an explicit reference to a 'idx_layername_geometrycolumn' */
     757                 :             /*   table in the SQL --> old/traditionnal way of requesting spatial indices */
     758                 :             /*   with spatialite. */
     759                 : 
     760              70 :             std::set<LayerDesc>::iterator oIter2 = oSetLayers.begin();
     761             146 :             for(; oIter2 != oSetLayers.end(); ++oIter2)
     762                 :             {
     763              77 :                 const LayerDesc& oLayerDescIter = *oIter2;
     764              77 :                 if( EQUAL(oLayerDescIter.osLayerName, osIdxNameRaw) )
     765                 :                 {
     766               1 :                      bCreateSpatialIndex = TRUE;
     767               1 :                      break;
     768                 :                 }
     769                 :             }
     770                 : 
     771                 :             /* 2) or if there's a SELECT FROM SpatialIndex WHERE f_table_name = 'layername' */
     772              70 :             if( !bCreateSpatialIndex )
     773                 :             {
     774              69 :                 std::set<CPLString>::iterator oIter3 = oSetSpatialIndex.begin();
     775              70 :                 for(; oIter3 != oSetSpatialIndex.end(); ++oIter3)
     776                 :                 {
     777               2 :                     const CPLString& osNameIter = *oIter3;
     778               2 :                     if( EQUAL(osNameIter, oLayerDesc.osLayerName) )
     779                 :                     {
     780               1 :                         bCreateSpatialIndex = TRUE;
     781               1 :                         break;
     782                 :                     }
     783                 :                 }
     784                 :             }
     785                 : 
     786              70 :             if( poSQLiteDS->HasSpatialite4Layout() )
     787                 :             {
     788               0 :                 int nGeomType = poLayer->GetGeomType();
     789               0 :                 int nCoordDimension = 2;
     790               0 :                 if( nGeomType & wkb25DBit )
     791                 :                 {
     792               0 :                     nGeomType += 1000;
     793               0 :                     nCoordDimension = 3;
     794                 :                 }
     795                 : 
     796                 :                 osSQL.Printf("INSERT INTO geometry_columns (f_table_name, "
     797                 :                             "f_geometry_column, geometry_type, coord_dimension, "
     798                 :                             "srid, spatial_index_enabled) "
     799                 :                             "VALUES ('%s',Lower('%s'),%d ,%d ,%d, %d)",
     800                 :                             pszLayerNameEscaped,
     801                 :                             pszGeomColEscaped, nGeomType,
     802                 :                             nCoordDimension,
     803               0 :                             nSRSId, bCreateSpatialIndex );
     804                 :             }
     805                 :             else
     806                 :             {
     807              70 :                 const char *pszGeometryType = OGRToOGCGeomType(poLayer->GetGeomType());
     808              70 :                 if (pszGeometryType[0] == '\0')
     809               0 :                     pszGeometryType = "GEOMETRY";
     810                 : 
     811                 :                 osSQL.Printf("INSERT INTO geometry_columns (f_table_name, "
     812                 :                             "f_geometry_column, type, coord_dimension, "
     813                 :                             "srid, spatial_index_enabled) "
     814                 :                             "VALUES ('%s','%s','%s','%s',%d, %d)",
     815                 :                             pszLayerNameEscaped,
     816                 :                             pszGeomColEscaped, pszGeometryType,
     817              70 :                             ( poLayer->GetGeomType() & wkb25DBit ) ? "XYZ" : "XY",
     818              70 :                             nSRSId, bCreateSpatialIndex );
     819                 :             }
     820                 :         }
     821                 : #endif // HAVE_SPATIALITE
     822             122 :         sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL );
     823                 : 
     824                 : #ifdef HAVE_SPATIALITE
     825                 : /* -------------------------------------------------------------------- */
     826                 : /*      Should we create a spatial index ?.                             */
     827                 : /* -------------------------------------------------------------------- */
     828             122 :         if( !bSpatialiteDB || !bCreateSpatialIndex )
     829             120 :             continue;
     830                 : 
     831               2 :         CPLDebug("SQLITE", "Create spatial index %s", osIdxNameRaw.c_str());
     832                 : 
     833                 :         /* ENABLE_VIRTUAL_OGR_SPATIAL_INDEX is not defined */
     834                 : #ifdef ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
     835                 :         osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING "
     836                 :                      "VirtualOGRSpatialIndex(%d, '%s', pkid, xmin, xmax, ymin, ymax)",
     837                 :                      osIdxNameEscaped.c_str(),
     838                 :                      nExtraDS,
     839                 :                      OGRSQLiteEscape(oLayerDesc.osLayerName).c_str());
     840                 : 
     841                 :         rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL );
     842                 :         if( rc != SQLITE_OK )
     843                 :         {
     844                 :             CPLDebug("SQLITE",
     845                 :                      "Error occured during spatial index creation : %s",
     846                 :                      sqlite3_errmsg(hDB));
     847                 :         }
     848                 : #else //  ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
     849               2 :         rc = sqlite3_exec( hDB, "BEGIN", NULL, NULL, NULL );
     850                 : 
     851                 :         osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" "
     852                 :                      "USING rtree(pkid, xmin, xmax, ymin, ymax)",
     853               2 :                       osIdxNameEscaped.c_str());
     854                 : 
     855               2 :         if( rc == SQLITE_OK )
     856               2 :             rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL );
     857                 : 
     858               2 :         sqlite3_stmt *hStmt = NULL;
     859               2 :         if( rc == SQLITE_OK )
     860                 :         {
     861                 :             const char* pszInsertInto = CPLSPrintf(
     862                 :                 "INSERT INTO \"%s\" (pkid, xmin, xmax, ymin, ymax) "
     863               2 :                 "VALUES (?,?,?,?,?)", osIdxNameEscaped.c_str());
     864               2 :             rc = sqlite3_prepare(hDB, pszInsertInto, -1, &hStmt, NULL);
     865                 :         }
     866                 : 
     867                 :         OGRFeature* poFeature;
     868               2 :         OGREnvelope sEnvelope;
     869               2 :         OGR2SQLITE_IgnoreAllFieldsExceptGeometry(poLayer);
     870               2 :         poLayer->ResetReading();
     871                 : 
     872              14 :         while( rc == SQLITE_OK &&
     873               6 :                (poFeature = poLayer->GetNextFeature()) != NULL )
     874                 :         {
     875               4 :             OGRGeometry* poGeom = poFeature->GetGeometryRef();
     876               4 :             if( poGeom != NULL && !poGeom->IsEmpty() )
     877                 :             {
     878               4 :                 poGeom->getEnvelope(&sEnvelope);
     879                 :                 sqlite3_bind_int64(hStmt, 1,
     880               4 :                                    (sqlite3_int64) poFeature->GetFID() );
     881               4 :                 sqlite3_bind_double(hStmt, 2, sEnvelope.MinX);
     882               4 :                 sqlite3_bind_double(hStmt, 3, sEnvelope.MaxX);
     883               4 :                 sqlite3_bind_double(hStmt, 4, sEnvelope.MinY);
     884               4 :                 sqlite3_bind_double(hStmt, 5, sEnvelope.MaxY);
     885               4 :                 rc = sqlite3_step(hStmt);
     886               4 :                 if( rc == SQLITE_OK || rc == SQLITE_DONE )
     887               4 :                     rc = sqlite3_reset(hStmt);
     888                 :             }
     889               4 :             delete poFeature;
     890                 :         }
     891                 : 
     892               2 :         poLayer->SetIgnoredFields(NULL);
     893                 : 
     894               2 :         sqlite3_finalize(hStmt);
     895                 : 
     896               2 :         if( rc == SQLITE_OK )
     897               2 :             rc = sqlite3_exec( hDB, "COMMIT", NULL, NULL, NULL );
     898                 :         else
     899                 :         {
     900                 :             CPLDebug("SQLITE",
     901                 :                      "Error occured during spatial index creation : %s",
     902               0 :                      sqlite3_errmsg(hDB));
     903               0 :             rc = sqlite3_exec( hDB, "ROLLBACK", NULL, NULL, NULL );
     904                 :         }
     905                 : #endif //  ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
     906                 : 
     907                 : #endif // HAVE_SPATIALITE
     908                 : 
     909                 :     }
     910                 : 
     911                 : /* -------------------------------------------------------------------- */
     912                 : /*      Reload, so that virtual tables are recognized                   */
     913                 : /* -------------------------------------------------------------------- */
     914             485 :     poSQLiteDS->ReloadLayers();
     915                 : 
     916                 : /* -------------------------------------------------------------------- */
     917                 : /*      Prepare the statement.                                          */
     918                 : /* -------------------------------------------------------------------- */
     919                 :     /* This will speed-up layer creation */
     920                 :     /* ORDER BY are costly to evaluate and are not necessary to establish */
     921                 :     /* the layer definition. */
     922             485 :     int bUseStatementForGetNextFeature = TRUE;
     923             485 :     int bEmptyLayer = FALSE;
     924                 : 
     925             485 :     sqlite3_stmt *hSQLStmt = NULL;
     926                 :     int rc = sqlite3_prepare( hDB,
     927                 :                               pszStatement, strlen(pszStatement),
     928             485 :                               &hSQLStmt, NULL );
     929                 : 
     930             485 :     if( rc != SQLITE_OK )
     931                 :     {
     932                 :         CPLError( CE_Failure, CPLE_AppDefined,
     933                 :                 "In ExecuteSQL(): sqlite3_prepare(%s):\n  %s",
     934               3 :                 pszStatement, sqlite3_errmsg(hDB) );
     935                 : 
     936               3 :         if( hSQLStmt != NULL )
     937                 :         {
     938               0 :             sqlite3_finalize( hSQLStmt );
     939                 :         }
     940                 : 
     941               3 :         delete poSQLiteDS;
     942               3 :         VSIUnlink(pszTmpDBName);
     943               3 :         CPLFree(pszTmpDBName);
     944                 : 
     945               3 :         return NULL;
     946                 :     }
     947                 : 
     948                 : /* -------------------------------------------------------------------- */
     949                 : /*      Do we get a resultset?                                          */
     950                 : /* -------------------------------------------------------------------- */
     951             482 :     rc = sqlite3_step( hSQLStmt );
     952             482 :     if( rc != SQLITE_ROW )
     953                 :     {
     954             103 :         if ( rc != SQLITE_DONE )
     955                 :         {
     956                 :             CPLError( CE_Failure, CPLE_AppDefined,
     957                 :                   "In ExecuteSQL(): sqlite3_step(%s):\n  %s",
     958               1 :                   pszStatement, sqlite3_errmsg(hDB) );
     959                 : 
     960               1 :             sqlite3_finalize( hSQLStmt );
     961                 : 
     962               1 :             delete poSQLiteDS;
     963               1 :             VSIUnlink(pszTmpDBName);
     964               1 :             CPLFree(pszTmpDBName);
     965                 : 
     966               1 :             return NULL;
     967                 :         }
     968                 : 
     969             102 :         if( !EQUALN(pszStatement, "SELECT ", 7) )
     970                 :         {
     971                 : 
     972              28 :             sqlite3_finalize( hSQLStmt );
     973                 : 
     974              28 :             delete poSQLiteDS;
     975              28 :             VSIUnlink(pszTmpDBName);
     976              28 :             CPLFree(pszTmpDBName);
     977                 : 
     978              28 :             return NULL;
     979                 :         }
     980                 : 
     981              74 :         bUseStatementForGetNextFeature = FALSE;
     982              74 :         bEmptyLayer = TRUE;
     983                 :     }
     984                 : 
     985                 : /* -------------------------------------------------------------------- */
     986                 : /*      Create layer.                                                   */
     987                 : /* -------------------------------------------------------------------- */
     988             453 :     OGRSQLiteSelectLayer *poLayer = NULL;
     989                 : 
     990                 :     poLayer = new OGRSQLiteExecuteSQLLayer( pszTmpDBName,
     991                 :                                             poSQLiteDS, pszStatement, hSQLStmt,
     992             453 :                                             bUseStatementForGetNextFeature, bEmptyLayer );
     993                 : 
     994             453 :     if( poSpatialFilter != NULL )
     995               0 :         poLayer->SetSpatialFilter( poSpatialFilter );
     996                 : 
     997             453 :     return poLayer;
     998                 : }
     999                 : 
    1000                 : /************************************************************************/
    1001                 : /*                   OGRSQLiteGetReferencedLayers()                     */
    1002                 : /************************************************************************/
    1003                 : 
    1004               1 : std::set<LayerDesc> OGRSQLiteGetReferencedLayers(const char* pszStatement)
    1005                 : {
    1006                 : /* -------------------------------------------------------------------- */
    1007                 : /*      Analysze the statement to determine which tables will be used.  */
    1008                 : /* -------------------------------------------------------------------- */
    1009               1 :     std::set<LayerDesc> oSetLayers;
    1010               1 :     std::set<CPLString> oSetSpatialIndex;
    1011               1 :     CPLString osModifiedSQL;
    1012                 :     OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers,
    1013               1 :                                      oSetSpatialIndex, osModifiedSQL);
    1014                 : 
    1015               1 :     return oSetLayers;
    1016                 : }
    1017                 : 
    1018                 : #else // HAVE_SQLITE_VFS
    1019                 : 
    1020                 : /************************************************************************/
    1021                 : /*                          OGRSQLiteExecuteSQL()                       */
    1022                 : /************************************************************************/
    1023                 : 
    1024                 : OGRLayer * OGRSQLiteExecuteSQL( OGRDataSource* poDS,
    1025                 :                                 const char *pszStatement,
    1026                 :                                 OGRGeometry *poSpatialFilter,
    1027                 :                                 const char *pszDialect )
    1028                 : {
    1029                 :     CPLError(CE_Failure, CPLE_NotSupported,
    1030                 :                 "The SQLite version is to old to support the SQLite SQL dialect");
    1031                 :     return NULL;
    1032                 : }
    1033                 : 
    1034                 : /************************************************************************/
    1035                 : /*                   OGRSQLiteGetReferencedLayers()                     */
    1036                 : /************************************************************************/
    1037                 : 
    1038                 : std::set<LayerDesc> OGRSQLiteGetReferencedLayers(const char* pszStatement)
    1039                 : {
    1040                 :      std::set<LayerDesc> oSetLayers;
    1041                 :      return oSetLayers;
    1042                 : }
    1043                 : 
    1044                 : #endif // HAVE_SQLITE_VFS

Generated by: LCOV version 1.7