LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/sqlite - ogrsqliteexecutesql.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 427 369 86.4 %
Date: 2012-12-26 Functions: 14 11 78.6 %

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

Generated by: LCOV version 1.7