LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/generic - ogrdatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 693 525 75.8 %
Date: 2012-12-26 Functions: 52 37 71.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrdatasource.cpp 24813 2012-08-20 21:08:33Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  The generic portions of the OGRDataSource class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999,  Les Technologies SoftMap Inc.
      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 "swq.h"
      31                 : #include "ogrsf_frmts.h"
      32                 : #include "ogr_api.h"
      33                 : #include "ogr_p.h"
      34                 : #include "ogr_gensql.h"
      35                 : #include "ogr_attrind.h"
      36                 : #include "cpl_multiproc.h"
      37                 : #include "ogrunionlayer.h"
      38                 : 
      39                 : #ifdef SQLITE_ENABLED
      40                 : #include "../sqlite/ogrsqliteexecutesql.h"
      41                 : #endif
      42                 : 
      43                 : CPL_CVSID("$Id: ogrdatasource.cpp 24813 2012-08-20 21:08:33Z rouault $");
      44                 : 
      45                 : /************************************************************************/
      46                 : /*                           ~OGRDataSource()                           */
      47                 : /************************************************************************/
      48                 : 
      49           17342 : OGRDataSource::OGRDataSource()
      50                 : 
      51                 : {
      52           17342 :     m_poStyleTable = NULL;
      53           17342 :     m_nRefCount = 0;
      54           17342 :     m_poDriver = NULL;
      55           17342 :     m_hMutex = NULL;
      56           17342 : }
      57                 : 
      58                 : /************************************************************************/
      59                 : /*                           ~OGRDataSource()                           */
      60                 : /************************************************************************/
      61                 : 
      62           17342 : OGRDataSource::~OGRDataSource()
      63                 : 
      64                 : {
      65           17342 :     if ( m_poStyleTable )
      66                 :     {
      67               3 :         delete m_poStyleTable;
      68               3 :         m_poStyleTable = NULL;
      69                 :     }
      70                 : 
      71           17342 :     if( m_hMutex != NULL )
      72             935 :         CPLDestroyMutex( m_hMutex );
      73           17342 : }
      74                 : 
      75                 : /************************************************************************/
      76                 : /*                         DestroyDataSource()                          */
      77                 : /************************************************************************/
      78                 : 
      79             696 : void OGRDataSource::DestroyDataSource( OGRDataSource *poDS )
      80                 : 
      81                 : {
      82             696 :     delete poDS;
      83             696 : }
      84                 : 
      85                 : /************************************************************************/
      86                 : /*                           OGR_DS_Destroy()                           */
      87                 : /************************************************************************/
      88                 : 
      89              48 : void OGR_DS_Destroy( OGRDataSourceH hDS )
      90                 : 
      91                 : {
      92              48 :     VALIDATE_POINTER0( hDS, "OGR_DS_Destroy" );
      93              48 :     delete (OGRDataSource *) hDS;
      94                 : }
      95                 : 
      96                 : /************************************************************************/
      97                 : /*                              Release()                               */
      98                 : /************************************************************************/
      99                 : 
     100               0 : OGRErr OGRDataSource::Release()
     101                 : 
     102                 : {
     103               0 :     return OGRSFDriverRegistrar::GetRegistrar()->ReleaseDataSource( this );
     104                 : }
     105                 : 
     106                 : /************************************************************************/
     107                 : /*                             Reference()                              */
     108                 : /************************************************************************/
     109                 : 
     110            1486 : int OGRDataSource::Reference()
     111                 : 
     112                 : {
     113            1486 :     return ++m_nRefCount;
     114                 : }
     115                 : 
     116                 : /************************************************************************/
     117                 : /*                          OGR_DS_Reference()                          */
     118                 : /************************************************************************/
     119                 : 
     120               0 : int OGR_DS_Reference( OGRDataSourceH hDataSource )
     121                 : 
     122                 : {
     123               0 :     VALIDATE_POINTER1( hDataSource, "OGR_DS_Reference", 0 );
     124                 : 
     125               0 :     return ((OGRDataSource *) hDataSource)->Reference();
     126                 : }
     127                 : 
     128                 : /************************************************************************/
     129                 : /*                            Dereference()                             */
     130                 : /************************************************************************/
     131                 : 
     132              52 : int OGRDataSource::Dereference()
     133                 : 
     134                 : {
     135              52 :     return --m_nRefCount;
     136                 : }
     137                 : 
     138                 : /************************************************************************/
     139                 : /*                         OGR_DS_Dereference()                         */
     140                 : /************************************************************************/
     141                 : 
     142               0 : int OGR_DS_Dereference( OGRDataSourceH hDataSource )
     143                 : 
     144                 : {
     145               0 :     VALIDATE_POINTER1( hDataSource, "OGR_DS_Dereference", 0 );
     146                 : 
     147               0 :     return ((OGRDataSource *) hDataSource)->Dereference();
     148                 : }
     149                 : 
     150                 : /************************************************************************/
     151                 : /*                            GetRefCount()                             */
     152                 : /************************************************************************/
     153                 : 
     154              98 : int OGRDataSource::GetRefCount() const
     155                 : 
     156                 : {
     157              98 :     return m_nRefCount;
     158                 : }
     159                 : 
     160                 : /************************************************************************/
     161                 : /*                         OGR_DS_GetRefCount()                         */
     162                 : /************************************************************************/
     163                 : 
     164               4 : int OGR_DS_GetRefCount( OGRDataSourceH hDataSource )
     165                 : 
     166                 : {
     167               4 :     VALIDATE_POINTER1( hDataSource, "OGR_DS_GetRefCount", 0 );
     168                 : 
     169               4 :     return ((OGRDataSource *) hDataSource)->GetRefCount();
     170                 : }
     171                 : 
     172                 : /************************************************************************/
     173                 : /*                         GetSummaryRefCount()                         */
     174                 : /************************************************************************/
     175                 : 
     176              19 : int OGRDataSource::GetSummaryRefCount() const
     177                 : 
     178                 : {
     179              19 :     CPLMutexHolderD( (void **) &m_hMutex );
     180              19 :     int nSummaryCount = m_nRefCount;
     181                 :     int iLayer;
     182              19 :     OGRDataSource *poUseThis = (OGRDataSource *) this;
     183                 : 
     184              38 :     for( iLayer=0; iLayer < poUseThis->GetLayerCount(); iLayer++ )
     185              19 :         nSummaryCount += poUseThis->GetLayer( iLayer )->GetRefCount();
     186                 : 
     187              19 :     return nSummaryCount;
     188                 : }
     189                 : 
     190                 : /************************************************************************/
     191                 : /*                     OGR_DS_GetSummaryRefCount()                      */
     192                 : /************************************************************************/
     193                 : 
     194               0 : int OGR_DS_GetSummaryRefCount( OGRDataSourceH hDataSource )
     195                 : 
     196                 : {
     197               0 :     VALIDATE_POINTER1( hDataSource, "OGR_DS_GetSummaryRefCount", 0 );
     198                 : 
     199               0 :     return ((OGRDataSource *) hDataSource)->GetSummaryRefCount();
     200                 : }
     201                 : 
     202                 : /************************************************************************/
     203                 : /*                            CreateLayer()                             */
     204                 : /************************************************************************/
     205                 : 
     206               0 : OGRLayer *OGRDataSource::CreateLayer( const char * pszName,
     207                 :                                       OGRSpatialReference * poSpatialRef,
     208                 :                                       OGRwkbGeometryType eGType,
     209                 :                                       char **papszOptions )
     210                 : 
     211                 : {
     212                 :     (void) eGType;
     213                 :     (void) poSpatialRef;
     214                 :     (void) pszName;
     215                 :     (void) papszOptions;
     216                 : 
     217                 :     CPLError( CE_Failure, CPLE_NotSupported,
     218               0 :               "CreateLayer() not supported by this data source." );
     219                 :               
     220               0 :     return NULL;
     221                 : }
     222                 : 
     223                 : /************************************************************************/
     224                 : /*                         OGR_DS_CreateLayer()                         */
     225                 : /************************************************************************/
     226                 : 
     227            1566 : OGRLayerH OGR_DS_CreateLayer( OGRDataSourceH hDS, 
     228                 :                               const char * pszName,
     229                 :                               OGRSpatialReferenceH hSpatialRef,
     230                 :                               OGRwkbGeometryType eType,
     231                 :                               char ** papszOptions )
     232                 : 
     233                 : {
     234            1566 :     VALIDATE_POINTER1( hDS, "OGR_DS_CreateLayer", NULL );
     235                 : 
     236            1566 :     if (pszName == NULL)
     237                 :     {
     238               0 :         CPLError ( CE_Failure, CPLE_ObjectNull, "Name was NULL in OGR_DS_CreateLayer");
     239               0 :         return 0;
     240                 :     }
     241                 :     return (OGRLayerH) ((OGRDataSource *)hDS)->CreateLayer( 
     242            1566 :         pszName, (OGRSpatialReference *) hSpatialRef, eType, papszOptions );
     243                 : }
     244                 : 
     245                 : /************************************************************************/
     246                 : /*                             CopyLayer()                              */
     247                 : /************************************************************************/
     248                 : 
     249              37 : OGRLayer *OGRDataSource::CopyLayer( OGRLayer *poSrcLayer, 
     250                 :                                     const char *pszNewName, 
     251                 :                                     char **papszOptions )
     252                 : 
     253                 : {
     254              37 :     OGRFeatureDefn *poSrcDefn = poSrcLayer->GetLayerDefn();
     255              37 :     OGRLayer *poDstLayer = NULL;
     256                 : 
     257                 : /* -------------------------------------------------------------------- */
     258                 : /*      Create the layer.                                               */
     259                 : /* -------------------------------------------------------------------- */
     260              37 :     if( !TestCapability( ODsCCreateLayer ) )
     261                 :     {
     262                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     263               0 :                   "This datasource does not support creation of layers." );
     264               0 :         return NULL;
     265                 :     }
     266                 : 
     267              37 :     CPLErrorReset();
     268              37 :     poDstLayer = CreateLayer( pszNewName, poSrcLayer->GetSpatialRef(),
     269              74 :                               poSrcDefn->GetGeomType(), papszOptions );
     270                 :     
     271              37 :     if( poDstLayer == NULL )
     272               0 :         return NULL;
     273                 : 
     274                 : /* -------------------------------------------------------------------- */
     275                 : /*      Add fields.  Default to copy all fields, and make sure to       */
     276                 : /*      establish a mapping between indices, rather than names, in      */
     277                 : /*      case the target datasource has altered it (e.g. Shapefile       */
     278                 : /*      limited to 10 char field names).                                */
     279                 : /* -------------------------------------------------------------------- */
     280              37 :     int         nSrcFieldCount = poSrcDefn->GetFieldCount();
     281              37 :     int         nDstFieldCount = 0;
     282                 :     int         iField, *panMap;
     283                 : 
     284                 :     // Initialize the index-to-index map to -1's
     285              37 :     panMap = (int *) CPLMalloc( sizeof(int) * nSrcFieldCount );
     286             116 :     for( iField=0; iField < nSrcFieldCount; iField++)
     287              79 :         panMap[iField] = -1;
     288                 : 
     289                 :     /* Caution : at the time of writing, the MapInfo driver */
     290                 :     /* returns NULL until a field has been added */
     291              37 :     OGRFeatureDefn* poDstFDefn = poDstLayer->GetLayerDefn();
     292              37 :     if (poDstFDefn)
     293              37 :         nDstFieldCount = poDstFDefn->GetFieldCount();    
     294             116 :     for( iField = 0; iField < nSrcFieldCount; iField++ )
     295                 :     {
     296              79 :         OGRFieldDefn* poSrcFieldDefn = poSrcDefn->GetFieldDefn(iField);
     297              79 :         OGRFieldDefn oFieldDefn( poSrcFieldDefn );
     298                 : 
     299                 :         /* The field may have been already created at layer creation */
     300              79 :         int iDstField = -1;
     301              79 :         if (poDstFDefn)
     302              79 :             iDstField = poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
     303              79 :         if (iDstField >= 0)
     304                 :         {
     305               0 :             panMap[iField] = iDstField;
     306                 :         }
     307              79 :         else if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
     308                 :         {
     309                 :             /* now that we've created a field, GetLayerDefn() won't return NULL */
     310              79 :             if (poDstFDefn == NULL)
     311               0 :                 poDstFDefn = poDstLayer->GetLayerDefn();
     312                 : 
     313                 :             /* Sanity check : if it fails, the driver is buggy */
     314              79 :             if (poDstFDefn != NULL &&
     315                 :                 poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
     316                 :             {
     317                 :                 CPLError(CE_Warning, CPLE_AppDefined,
     318                 :                          "The output driver has claimed to have added the %s field, but it did not!",
     319               0 :                          oFieldDefn.GetNameRef() );
     320                 :             }
     321                 :             else
     322                 :             {
     323              79 :                 panMap[iField] = nDstFieldCount;
     324              79 :                 nDstFieldCount ++;
     325                 :             }
     326                 :         }
     327                 :     }
     328                 : 
     329                 : /* -------------------------------------------------------------------- */
     330                 : /*      Check if the destination layer supports transactions and set a  */
     331                 : /*      default number of features in a single transaction.             */
     332                 : /* -------------------------------------------------------------------- */
     333              37 :     int nGroupTransactions = 0;
     334              37 :     if( poDstLayer->TestCapability( OLCTransactions ) )
     335               4 :         nGroupTransactions = 128;
     336                 : 
     337                 : /* -------------------------------------------------------------------- */
     338                 : /*      Transfer features.                                              */
     339                 : /* -------------------------------------------------------------------- */
     340                 :     OGRFeature  *poFeature;
     341                 : 
     342              37 :     poSrcLayer->ResetReading();
     343                 : 
     344              37 :     if( nGroupTransactions <= 0 )
     345                 :     {
     346              42 :       while( TRUE )
     347                 :       {
     348              75 :         OGRFeature      *poDstFeature = NULL;
     349                 : 
     350              75 :         poFeature = poSrcLayer->GetNextFeature();
     351                 :         
     352              75 :         if( poFeature == NULL )
     353                 :             break;
     354                 : 
     355              42 :         CPLErrorReset();
     356              42 :         poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
     357                 : 
     358              42 :         if( poDstFeature->SetFrom( poFeature, panMap, TRUE ) != OGRERR_NONE )
     359                 :         {
     360                 :             CPLError( CE_Failure, CPLE_AppDefined,
     361                 :                       "Unable to translate feature %ld from layer %s.\n",
     362               0 :                       poFeature->GetFID(), poSrcDefn->GetName() );
     363               0 :             OGRFeature::DestroyFeature( poFeature );
     364               0 :             return poDstLayer;
     365                 :         }
     366                 : 
     367              42 :         poDstFeature->SetFID( poFeature->GetFID() );
     368                 : 
     369              42 :         OGRFeature::DestroyFeature( poFeature );
     370                 : 
     371              42 :         CPLErrorReset();
     372              42 :         if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE )
     373                 :         {
     374               0 :             OGRFeature::DestroyFeature( poDstFeature );
     375               0 :             return poDstLayer;
     376                 :         }
     377                 : 
     378              42 :         OGRFeature::DestroyFeature( poDstFeature );
     379                 :       }
     380                 :     }
     381                 :     else
     382                 :     {
     383               4 :       int i, bStopTransfer = FALSE, bStopTransaction = FALSE;
     384               4 :       int nFeatCount = 0; // Number of features in the temporary array
     385               4 :       int nFeaturesToAdd = 0;
     386                 :       OGRFeature **papoDstFeature =
     387               4 :           (OGRFeature **)CPLCalloc(sizeof(OGRFeature *), nGroupTransactions);
     388              12 :       while( !bStopTransfer )
     389                 :       {
     390                 : /* -------------------------------------------------------------------- */
     391                 : /*      Fill the array with features                                    */
     392                 : /* -------------------------------------------------------------------- */
     393              76 :         for( nFeatCount = 0; nFeatCount < nGroupTransactions; nFeatCount++ )
     394                 :         {
     395              76 :             poFeature = poSrcLayer->GetNextFeature();
     396                 : 
     397              76 :             if( poFeature == NULL )
     398                 :             {
     399               4 :                 bStopTransfer = 1;
     400               4 :                 break;
     401                 :             }
     402                 : 
     403              72 :             CPLErrorReset();
     404              72 :             papoDstFeature[nFeatCount] =
     405              72 :                         OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
     406                 : 
     407              72 :             if( papoDstFeature[nFeatCount]->SetFrom( poFeature, panMap, TRUE ) != OGRERR_NONE )
     408                 :             {
     409               0 :                 OGRFeature::DestroyFeature( poFeature );
     410                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     411                 :                           "Unable to translate feature %ld from layer %s.\n",
     412               0 :                           poFeature->GetFID(), poSrcDefn->GetName() );
     413               0 :                 bStopTransfer = TRUE;
     414               0 :                 break;
     415                 :             }
     416                 : 
     417              72 :             papoDstFeature[nFeatCount]->SetFID( poFeature->GetFID() );
     418                 : 
     419              72 :             OGRFeature::DestroyFeature( poFeature );
     420                 :         }
     421               4 :         nFeaturesToAdd = nFeatCount;
     422                 : 
     423               4 :         CPLErrorReset();
     424               4 :         bStopTransaction = FALSE;
     425              12 :         while( !bStopTransaction )
     426                 :         {
     427               4 :             bStopTransaction = TRUE;
     428               4 :             poDstLayer->StartTransaction();
     429              76 :             for( i = 0; i < nFeaturesToAdd; i++ )
     430                 :             {
     431              72 :                 if( poDstLayer->CreateFeature( papoDstFeature[i] ) != OGRERR_NONE )
     432                 :                 {
     433               0 :                     nFeaturesToAdd = i;
     434               0 :                     bStopTransfer = TRUE;
     435               0 :                     bStopTransaction = FALSE;
     436                 :                 }
     437                 :             }
     438               4 :             if( bStopTransaction )
     439               4 :                 poDstLayer->CommitTransaction();
     440                 :             else
     441               0 :                 poDstLayer->RollbackTransaction();
     442                 :         }
     443                 : 
     444              76 :         for( i = 0; i < nFeatCount; i++ )
     445              72 :             OGRFeature::DestroyFeature( papoDstFeature[i] );
     446                 :       }
     447               4 :       CPLFree(papoDstFeature);
     448                 :     }
     449                 : 
     450              37 :     CPLFree(panMap);
     451                 : 
     452              37 :     return poDstLayer;
     453                 : }
     454                 : 
     455                 : /************************************************************************/
     456                 : /*                          OGR_DS_CopyLayer()                          */
     457                 : /************************************************************************/
     458                 : 
     459               4 : OGRLayerH OGR_DS_CopyLayer( OGRDataSourceH hDS, 
     460                 :                             OGRLayerH hSrcLayer, const char *pszNewName,
     461                 :                             char **papszOptions )
     462                 : 
     463                 : {
     464               4 :     VALIDATE_POINTER1( hDS, "OGR_DS_CopyLayer", NULL );
     465               4 :     VALIDATE_POINTER1( hSrcLayer, "OGR_DS_CopyLayer", NULL );
     466               4 :     VALIDATE_POINTER1( pszNewName, "OGR_DS_CopyLayer", NULL );
     467                 : 
     468                 :     return (OGRLayerH) 
     469                 :         ((OGRDataSource *) hDS)->CopyLayer( (OGRLayer *) hSrcLayer, 
     470               4 :                                             pszNewName, papszOptions );
     471                 : }
     472                 : 
     473                 : /************************************************************************/
     474                 : /*                            DeleteLayer()                             */
     475                 : /************************************************************************/
     476                 : 
     477               0 : OGRErr OGRDataSource::DeleteLayer( int iLayer )
     478                 : 
     479                 : {
     480                 :     (void) iLayer;
     481                 :     CPLError( CE_Failure, CPLE_NotSupported,
     482               0 :               "DeleteLayer() not supported by this data source." );
     483                 :               
     484               0 :     return OGRERR_UNSUPPORTED_OPERATION;
     485                 : }
     486                 : 
     487                 : /************************************************************************/
     488                 : /*                         OGR_DS_DeleteLayer()                         */
     489                 : /************************************************************************/
     490                 : 
     491              15 : OGRErr OGR_DS_DeleteLayer( OGRDataSourceH hDS, int iLayer )
     492                 : 
     493                 : {
     494              15 :     VALIDATE_POINTER1( hDS, "OGR_DS_DeleteLayer", OGRERR_INVALID_HANDLE );
     495                 : 
     496              15 :     return ((OGRDataSource *) hDS)->DeleteLayer( iLayer );
     497                 : }
     498                 : 
     499                 : /************************************************************************/
     500                 : /*                           GetLayerByName()                           */
     501                 : /************************************************************************/
     502                 : 
     503            4018 : OGRLayer *OGRDataSource::GetLayerByName( const char *pszName )
     504                 : 
     505                 : {
     506            4018 :     CPLMutexHolderD( &m_hMutex );
     507                 : 
     508            4018 :     if ( ! pszName )
     509               0 :         return NULL;
     510                 : 
     511                 :     int  i;
     512                 : 
     513                 :     /* first a case sensitive check */
     514          261517 :     for( i = 0; i < GetLayerCount(); i++ )
     515                 :     {
     516          259948 :         OGRLayer *poLayer = GetLayer(i);
     517                 : 
     518          259948 :         if( strcmp( pszName, poLayer->GetName() ) == 0 )
     519            2449 :             return poLayer;
     520                 :     }
     521                 : 
     522                 :     /* then case insensitive */
     523          254047 :     for( i = 0; i < GetLayerCount(); i++ )
     524                 :     {
     525          252505 :         OGRLayer *poLayer = GetLayer(i);
     526                 : 
     527          252505 :         if( EQUAL( pszName, poLayer->GetName() ) )
     528              27 :             return poLayer;
     529                 :     }
     530                 : 
     531            1542 :     return NULL;
     532                 : }
     533                 : 
     534                 : /************************************************************************/
     535                 : /*                       OGR_DS_GetLayerByName()                        */
     536                 : /************************************************************************/
     537                 : 
     538            1952 : OGRLayerH OGR_DS_GetLayerByName( OGRDataSourceH hDS, const char *pszName )
     539                 : 
     540                 : {
     541            1952 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetLayerByName", NULL );
     542                 : 
     543            1952 :     return (OGRLayerH) ((OGRDataSource *) hDS)->GetLayerByName( pszName );
     544                 : }
     545                 : 
     546                 : /************************************************************************/
     547                 : /*                       ProcessSQLCreateIndex()                        */
     548                 : /*                                                                      */
     549                 : /*      The correct syntax for creating an index in our dialect of      */
     550                 : /*      SQL is:                                                         */
     551                 : /*                                                                      */
     552                 : /*        CREATE INDEX ON <layername> USING <columnname>                */
     553                 : /************************************************************************/
     554                 : 
     555               8 : OGRErr OGRDataSource::ProcessSQLCreateIndex( const char *pszSQLCommand )
     556                 : 
     557                 : {
     558               8 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
     559                 : 
     560                 : /* -------------------------------------------------------------------- */
     561                 : /*      Do some general syntax checking.                                */
     562                 : /* -------------------------------------------------------------------- */
     563              40 :     if( CSLCount(papszTokens) != 6 
     564               8 :         || !EQUAL(papszTokens[0],"CREATE")
     565               8 :         || !EQUAL(papszTokens[1],"INDEX")
     566               8 :         || !EQUAL(papszTokens[2],"ON")
     567               8 :         || !EQUAL(papszTokens[4],"USING") )
     568                 :     {
     569               0 :         CSLDestroy( papszTokens );
     570                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     571                 :                   "Syntax error in CREATE INDEX command.\n"
     572                 :                   "Was '%s'\n"
     573                 :                   "Should be of form 'CREATE INDEX ON <table> USING <field>'",
     574               0 :                   pszSQLCommand );
     575               0 :         return OGRERR_FAILURE;
     576                 :     }
     577                 : 
     578                 : /* -------------------------------------------------------------------- */
     579                 : /*      Find the named layer.                                           */
     580                 : /* -------------------------------------------------------------------- */
     581                 :     int  i;
     582               8 :     OGRLayer *poLayer = NULL;
     583                 : 
     584                 :     {
     585               8 :         CPLMutexHolderD( &m_hMutex );
     586                 : 
     587               8 :         for( i = 0; i < GetLayerCount(); i++ )
     588                 :         {
     589               8 :             poLayer = GetLayer(i);
     590                 :             
     591               8 :             if( EQUAL(poLayer->GetName(),papszTokens[3]) )
     592               8 :                 break;
     593                 :         }
     594                 :         
     595               8 :         if( i >= GetLayerCount() )
     596                 :         {
     597                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     598                 :                       "CREATE INDEX ON failed, no such layer as `%s'.",
     599               0 :                       papszTokens[3] );
     600               0 :             CSLDestroy( papszTokens );
     601               0 :             return OGRERR_FAILURE;
     602               0 :         }
     603                 :     }
     604                 : 
     605                 : /* -------------------------------------------------------------------- */
     606                 : /*      Does this layer even support attribute indexes?                 */
     607                 : /* -------------------------------------------------------------------- */
     608               8 :     if( poLayer->GetIndex() == NULL )
     609                 :     {
     610                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     611               0 :                   "CREATE INDEX ON not supported by this driver." );
     612               0 :         CSLDestroy( papszTokens );
     613               0 :         return OGRERR_FAILURE;
     614                 :     }
     615                 : 
     616                 : /* -------------------------------------------------------------------- */
     617                 : /*      Find the named field.                                           */
     618                 : /* -------------------------------------------------------------------- */
     619              12 :     for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
     620                 :     {
     621              12 :         if( EQUAL(papszTokens[5],
     622                 :                   poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) )
     623               8 :             break;
     624                 :     }
     625                 : 
     626               8 :     CSLDestroy( papszTokens );
     627                 : 
     628               8 :     if( i >= poLayer->GetLayerDefn()->GetFieldCount() )
     629                 :     {
     630                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     631                 :                   "`%s' failed, field not found.",
     632               0 :                   pszSQLCommand );
     633               0 :         return OGRERR_FAILURE;
     634                 :     }
     635                 : 
     636                 : /* -------------------------------------------------------------------- */
     637                 : /*      Attempt to create the index.                                    */
     638                 : /* -------------------------------------------------------------------- */
     639                 :     OGRErr eErr;
     640                 : 
     641               8 :     eErr = poLayer->GetIndex()->CreateIndex( i );
     642               8 :     if( eErr == OGRERR_NONE )
     643               8 :         eErr = poLayer->GetIndex()->IndexAllFeatures( i );
     644                 :     else
     645                 :     {
     646               0 :         if( strlen(CPLGetLastErrorMsg()) == 0 )
     647                 :             CPLError( CE_Failure, CPLE_AppDefined,
     648               0 :                     "Cannot '%s'", pszSQLCommand);
     649                 :     }
     650                 : 
     651               8 :     return eErr;
     652                 : }
     653                 : 
     654                 : /************************************************************************/
     655                 : /*                        ProcessSQLDropIndex()                         */
     656                 : /*                                                                      */
     657                 : /*      The correct syntax for droping one or more indexes in           */
     658                 : /*      the OGR SQL dialect is:                                         */
     659                 : /*                                                                      */
     660                 : /*          DROP INDEX ON <layername> [USING <columnname>]              */
     661                 : /************************************************************************/
     662                 : 
     663               2 : OGRErr OGRDataSource::ProcessSQLDropIndex( const char *pszSQLCommand )
     664                 : 
     665                 : {
     666               2 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
     667                 : 
     668                 : /* -------------------------------------------------------------------- */
     669                 : /*      Do some general syntax checking.                                */
     670                 : /* -------------------------------------------------------------------- */
     671              10 :     if( (CSLCount(papszTokens) != 4 && CSLCount(papszTokens) != 6)
     672               2 :         || !EQUAL(papszTokens[0],"DROP")
     673               2 :         || !EQUAL(papszTokens[1],"INDEX")
     674               2 :         || !EQUAL(papszTokens[2],"ON") 
     675               2 :         || (CSLCount(papszTokens) == 6 && !EQUAL(papszTokens[4],"USING")) )
     676                 :     {
     677               0 :         CSLDestroy( papszTokens );
     678                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     679                 :                   "Syntax error in DROP INDEX command.\n"
     680                 :                   "Was '%s'\n"
     681                 :                   "Should be of form 'DROP INDEX ON <table> [USING <field>]'",
     682               0 :                   pszSQLCommand );
     683               0 :         return OGRERR_FAILURE;
     684                 :     }
     685                 : 
     686                 : /* -------------------------------------------------------------------- */
     687                 : /*      Find the named layer.                                           */
     688                 : /* -------------------------------------------------------------------- */
     689                 :     int  i;
     690               2 :     OGRLayer *poLayer=NULL;
     691                 : 
     692                 :     {
     693               2 :         CPLMutexHolderD( &m_hMutex );
     694                 : 
     695               2 :         for( i = 0; i < GetLayerCount(); i++ )
     696                 :         {
     697               2 :             poLayer = GetLayer(i);
     698                 :         
     699               2 :             if( EQUAL(poLayer->GetName(),papszTokens[3]) )
     700               2 :                 break;
     701                 :         }
     702                 : 
     703               2 :         if( i >= GetLayerCount() )
     704                 :         {
     705                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     706                 :                       "CREATE INDEX ON failed, no such layer as `%s'.",
     707               0 :                       papszTokens[3] );
     708               0 :             CSLDestroy( papszTokens );
     709               0 :             return OGRERR_FAILURE;
     710               0 :         }
     711                 :     }
     712                 : 
     713                 : /* -------------------------------------------------------------------- */
     714                 : /*      Does this layer even support attribute indexes?                 */
     715                 : /* -------------------------------------------------------------------- */
     716               2 :     if( poLayer->GetIndex() == NULL )
     717                 :     {
     718                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     719               0 :                   "Indexes not supported by this driver." );
     720               0 :         CSLDestroy( papszTokens );
     721               0 :         return OGRERR_FAILURE;
     722                 :     }
     723                 : 
     724                 : /* -------------------------------------------------------------------- */
     725                 : /*      If we weren't given a field name, drop all indexes.             */
     726                 : /* -------------------------------------------------------------------- */
     727                 :     OGRErr eErr;
     728                 : 
     729               2 :     if( CSLCount(papszTokens) == 4 )
     730                 :     {
     731               0 :         for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
     732                 :         {
     733                 :             OGRAttrIndex *poAttrIndex;
     734                 : 
     735               0 :             poAttrIndex = poLayer->GetIndex()->GetFieldIndex(i);
     736               0 :             if( poAttrIndex != NULL )
     737                 :             {
     738               0 :                 eErr = poLayer->GetIndex()->DropIndex( i );
     739               0 :                 if( eErr != OGRERR_NONE )
     740               0 :                     return eErr;
     741                 :             }
     742                 :         }
     743                 : 
     744               0 :         CSLDestroy(papszTokens);
     745               0 :         return OGRERR_NONE;
     746                 :     }
     747                 : 
     748                 : /* -------------------------------------------------------------------- */
     749                 : /*      Find the named field.                                           */
     750                 : /* -------------------------------------------------------------------- */
     751               3 :     for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
     752                 :     {
     753               3 :         if( EQUAL(papszTokens[5],
     754                 :                   poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) )
     755               2 :             break;
     756                 :     }
     757                 : 
     758               2 :     CSLDestroy( papszTokens );
     759                 : 
     760               2 :     if( i >= poLayer->GetLayerDefn()->GetFieldCount() )
     761                 :     {
     762                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     763                 :                   "`%s' failed, field not found.",
     764               0 :                   pszSQLCommand );
     765               0 :         return OGRERR_FAILURE;
     766                 :     }
     767                 : 
     768                 : /* -------------------------------------------------------------------- */
     769                 : /*      Attempt to drop the index.                                      */
     770                 : /* -------------------------------------------------------------------- */
     771               2 :     eErr = poLayer->GetIndex()->DropIndex( i );
     772                 : 
     773               2 :     return eErr;
     774                 : }
     775                 : 
     776                 : /************************************************************************/
     777                 : /*                        ProcessSQLDropTable()                         */
     778                 : /*                                                                      */
     779                 : /*      The correct syntax for dropping a table (layer) in the OGR SQL  */
     780                 : /*      dialect is:                                                     */
     781                 : /*                                                                      */
     782                 : /*          DROP TABLE <layername>                                      */
     783                 : /************************************************************************/
     784                 : 
     785             500 : OGRErr OGRDataSource::ProcessSQLDropTable( const char *pszSQLCommand )
     786                 : 
     787                 : {
     788             500 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
     789                 : 
     790                 : /* -------------------------------------------------------------------- */
     791                 : /*      Do some general syntax checking.                                */
     792                 : /* -------------------------------------------------------------------- */
     793            1500 :     if( CSLCount(papszTokens) != 3
     794             500 :         || !EQUAL(papszTokens[0],"DROP")
     795             500 :         || !EQUAL(papszTokens[1],"TABLE") )
     796                 :     {
     797               0 :         CSLDestroy( papszTokens );
     798                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     799                 :                   "Syntax error in DROP TABLE command.\n"
     800                 :                   "Was '%s'\n"
     801                 :                   "Should be of form 'DROP TABLE <table>'",
     802               0 :                   pszSQLCommand );
     803               0 :         return OGRERR_FAILURE;
     804                 :     }
     805                 : 
     806                 : /* -------------------------------------------------------------------- */
     807                 : /*      Find the named layer.                                           */
     808                 : /* -------------------------------------------------------------------- */
     809                 :     int  i;
     810             500 :     OGRLayer *poLayer=NULL;
     811                 : 
     812           40199 :     for( i = 0; i < GetLayerCount(); i++ )
     813                 :     {
     814           40199 :         poLayer = GetLayer(i);
     815                 :         
     816           40199 :         if( EQUAL(poLayer->GetName(),papszTokens[2]) )
     817             500 :             break;
     818                 :     }
     819                 :     
     820             500 :     if( i >= GetLayerCount() )
     821                 :     {
     822                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     823                 :                   "DROP TABLE failed, no such layer as `%s'.",
     824               0 :                   papszTokens[2] );
     825               0 :         CSLDestroy( papszTokens );
     826               0 :         return OGRERR_FAILURE;
     827                 :     }
     828                 : 
     829             500 :     CSLDestroy( papszTokens );
     830                 : 
     831                 : /* -------------------------------------------------------------------- */
     832                 : /*      Delete it.                                                      */
     833                 : /* -------------------------------------------------------------------- */
     834                 : 
     835             500 :     return DeleteLayer( i );
     836                 : }
     837                 : 
     838                 : /************************************************************************/
     839                 : /*                    OGRDataSourceParseSQLType()                       */
     840                 : /************************************************************************/
     841                 : 
     842                 : /* All arguments will be altered */
     843               6 : static OGRFieldType OGRDataSourceParseSQLType(char* pszType, int& nWidth, int &nPrecision)
     844                 : {
     845               6 :     char* pszParenthesis = strchr(pszType, '(');
     846               6 :     if (pszParenthesis)
     847                 :     {
     848               4 :         nWidth = atoi(pszParenthesis + 1);
     849               4 :         *pszParenthesis = '\0';
     850               4 :         char* pszComma = strchr(pszParenthesis + 1, ',');
     851               4 :         if (pszComma)
     852               2 :             nPrecision = atoi(pszComma + 1);
     853                 :     }
     854                 : 
     855               6 :     OGRFieldType eType = OFTString;
     856               6 :     if (EQUAL(pszType, "INTEGER"))
     857               0 :         eType = OFTInteger;
     858               6 :     else if (EQUAL(pszType, "INTEGER[]"))
     859               0 :         eType = OFTIntegerList;
     860               8 :     else if (EQUAL(pszType, "FLOAT") ||
     861                 :              EQUAL(pszType, "NUMERIC") ||
     862                 :              EQUAL(pszType, "DOUBLE") /* unofficial alias */ ||
     863                 :              EQUAL(pszType, "REAL") /* unofficial alias */)
     864               2 :         eType = OFTReal;
     865               4 :     else if (EQUAL(pszType, "FLOAT[]") ||
     866                 :              EQUAL(pszType, "NUMERIC[]") ||
     867                 :              EQUAL(pszType, "DOUBLE[]") /* unofficial alias */ ||
     868                 :              EQUAL(pszType, "REAL[]") /* unofficial alias */)
     869               0 :         eType = OFTRealList;
     870               8 :     else if (EQUAL(pszType, "CHARACTER") ||
     871                 :              EQUAL(pszType, "TEXT") /* unofficial alias */ ||
     872                 :              EQUAL(pszType, "STRING") /* unofficial alias */ ||
     873                 :              EQUAL(pszType, "VARCHAR") /* unofficial alias */)
     874               4 :         eType = OFTString;
     875               0 :     else if (EQUAL(pszType, "TEXT[]") ||
     876                 :              EQUAL(pszType, "STRING[]") /* unofficial alias */||
     877                 :              EQUAL(pszType, "VARCHAR[]") /* unofficial alias */)
     878               0 :         eType = OFTStringList;
     879               0 :     else if (EQUAL(pszType, "DATE"))
     880               0 :         eType = OFTDate;
     881               0 :     else if (EQUAL(pszType, "TIME"))
     882               0 :         eType = OFTTime;
     883               0 :     else if (EQUAL(pszType, "TIMESTAMP") ||
     884                 :              EQUAL(pszType, "DATETIME") /* unofficial alias */ )
     885               0 :         eType = OFTDateTime;
     886                 :     else
     887                 :     {
     888                 :         CPLError(CE_Warning, CPLE_NotSupported,
     889                 :                  "Unsupported column type '%s'. Defaulting to VARCHAR",
     890               0 :                  pszType);
     891                 :     }
     892               6 :     return eType;
     893                 : }
     894                 : 
     895                 : /************************************************************************/
     896                 : /*                    ProcessSQLAlterTableAddColumn()                   */
     897                 : /*                                                                      */
     898                 : /*      The correct syntax for adding a column in the OGR SQL           */
     899                 : /*      dialect is:                                                     */
     900                 : /*                                                                      */
     901                 : /*          ALTER TABLE <layername> ADD [COLUMN] <columnname> <columntype>*/
     902                 : /************************************************************************/
     903                 : 
     904               2 : OGRErr OGRDataSource::ProcessSQLAlterTableAddColumn( const char *pszSQLCommand )
     905                 : 
     906                 : {
     907               2 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
     908                 : 
     909                 : /* -------------------------------------------------------------------- */
     910                 : /*      Do some general syntax checking.                                */
     911                 : /* -------------------------------------------------------------------- */
     912               2 :     const char* pszLayerName = NULL;
     913               2 :     const char* pszColumnName = NULL;
     914               2 :     char* pszType = NULL;
     915               2 :     int iTypeIndex = 0;
     916               2 :     int nTokens = CSLCount(papszTokens);
     917                 : 
     918              11 :     if( nTokens >= 7
     919               2 :         && EQUAL(papszTokens[0],"ALTER")
     920               2 :         && EQUAL(papszTokens[1],"TABLE")
     921               2 :         && EQUAL(papszTokens[3],"ADD")
     922               2 :         && EQUAL(papszTokens[4],"COLUMN"))
     923                 :     {
     924               1 :         pszLayerName = papszTokens[2];
     925               1 :         pszColumnName = papszTokens[5];
     926               1 :         iTypeIndex = 6;
     927                 :     }
     928               5 :     else if( nTokens >= 6
     929               1 :              && EQUAL(papszTokens[0],"ALTER")
     930               1 :              && EQUAL(papszTokens[1],"TABLE")
     931               1 :              && EQUAL(papszTokens[3],"ADD"))
     932                 :     {
     933               1 :         pszLayerName = papszTokens[2];
     934               1 :         pszColumnName = papszTokens[4];
     935               1 :         iTypeIndex = 5;
     936                 :     }
     937                 :     else
     938                 :     {
     939               0 :         CSLDestroy( papszTokens );
     940                 :         CPLError( CE_Failure, CPLE_AppDefined,
     941                 :                   "Syntax error in ALTER TABLE ADD COLUMN command.\n"
     942                 :                   "Was '%s'\n"
     943                 :                   "Should be of form 'ALTER TABLE <layername> ADD [COLUMN] <columnname> <columntype>'",
     944               0 :                   pszSQLCommand );
     945               0 :         return OGRERR_FAILURE;
     946                 :     }
     947                 : 
     948                 : /* -------------------------------------------------------------------- */
     949                 : /*      Merge type components into a single string if there were split  */
     950                 : /*      with spaces                                                     */
     951                 : /* -------------------------------------------------------------------- */
     952               2 :     CPLString osType;
     953               6 :     for(int i=iTypeIndex;i<nTokens;i++)
     954                 :     {
     955               4 :         osType += papszTokens[i];
     956               4 :         CPLFree(papszTokens[i]);
     957                 :     }
     958               2 :     pszType = papszTokens[iTypeIndex] = CPLStrdup(osType);
     959               2 :     papszTokens[iTypeIndex + 1] = NULL;
     960                 : 
     961                 : /* -------------------------------------------------------------------- */
     962                 : /*      Find the named layer.                                           */
     963                 : /* -------------------------------------------------------------------- */
     964               2 :     OGRLayer *poLayer = GetLayerByName(pszLayerName);
     965               2 :     if( poLayer == NULL )
     966                 :     {
     967                 :         CPLError( CE_Failure, CPLE_AppDefined,
     968                 :                   "%s failed, no such layer as `%s'.",
     969                 :                   pszSQLCommand,
     970               0 :                   pszLayerName );
     971               0 :         CSLDestroy( papszTokens );
     972               0 :         return OGRERR_FAILURE;
     973                 :     }
     974                 : 
     975                 : /* -------------------------------------------------------------------- */
     976                 : /*      Add column.                                                     */
     977                 : /* -------------------------------------------------------------------- */
     978                 : 
     979               2 :     int nWidth = 0, nPrecision = 0;
     980               2 :     OGRFieldType eType = OGRDataSourceParseSQLType(pszType, nWidth, nPrecision);
     981               2 :     OGRFieldDefn oFieldDefn(pszColumnName, eType);
     982               2 :     oFieldDefn.SetWidth(nWidth);
     983               2 :     oFieldDefn.SetPrecision(nPrecision);
     984                 : 
     985               2 :     CSLDestroy( papszTokens );
     986                 : 
     987               2 :     return poLayer->CreateField( &oFieldDefn );
     988                 : }
     989                 : 
     990                 : /************************************************************************/
     991                 : /*                    ProcessSQLAlterTableDropColumn()                  */
     992                 : /*                                                                      */
     993                 : /*      The correct syntax for droping a column in the OGR SQL          */
     994                 : /*      dialect is:                                                     */
     995                 : /*                                                                      */
     996                 : /*          ALTER TABLE <layername> DROP [COLUMN] <columnname>          */
     997                 : /************************************************************************/
     998                 : 
     999               2 : OGRErr OGRDataSource::ProcessSQLAlterTableDropColumn( const char *pszSQLCommand )
    1000                 : 
    1001                 : {
    1002               2 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
    1003                 : 
    1004                 : /* -------------------------------------------------------------------- */
    1005                 : /*      Do some general syntax checking.                                */
    1006                 : /* -------------------------------------------------------------------- */
    1007               2 :     const char* pszLayerName = NULL;
    1008               2 :     const char* pszColumnName = NULL;
    1009               6 :     if( CSLCount(papszTokens) == 6
    1010               1 :         && EQUAL(papszTokens[0],"ALTER")
    1011               1 :         && EQUAL(papszTokens[1],"TABLE")
    1012               1 :         && EQUAL(papszTokens[3],"DROP")
    1013               1 :         && EQUAL(papszTokens[4],"COLUMN"))
    1014                 :     {
    1015               1 :         pszLayerName = papszTokens[2];
    1016               1 :         pszColumnName = papszTokens[5];
    1017                 :     }
    1018               4 :     else if( CSLCount(papszTokens) == 5
    1019               1 :              && EQUAL(papszTokens[0],"ALTER")
    1020               1 :              && EQUAL(papszTokens[1],"TABLE")
    1021               1 :              && EQUAL(papszTokens[3],"DROP"))
    1022                 :     {
    1023               1 :         pszLayerName = papszTokens[2];
    1024               1 :         pszColumnName = papszTokens[4];
    1025                 :     }
    1026                 :     else
    1027                 :     {
    1028               0 :         CSLDestroy( papszTokens );
    1029                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1030                 :                   "Syntax error in ALTER TABLE DROP COLUMN command.\n"
    1031                 :                   "Was '%s'\n"
    1032                 :                   "Should be of form 'ALTER TABLE <layername> DROP [COLUMN] <columnname>'",
    1033               0 :                   pszSQLCommand );
    1034               0 :         return OGRERR_FAILURE;
    1035                 :     }
    1036                 : 
    1037                 : /* -------------------------------------------------------------------- */
    1038                 : /*      Find the named layer.                                           */
    1039                 : /* -------------------------------------------------------------------- */
    1040               2 :     OGRLayer *poLayer = GetLayerByName(pszLayerName);
    1041               2 :     if( poLayer == NULL )
    1042                 :     {
    1043                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1044                 :                   "%s failed, no such layer as `%s'.",
    1045                 :                   pszSQLCommand,
    1046               0 :                   pszLayerName );
    1047               0 :         CSLDestroy( papszTokens );
    1048               0 :         return OGRERR_FAILURE;
    1049                 :     }
    1050                 : 
    1051                 : /* -------------------------------------------------------------------- */
    1052                 : /*      Find the field.                                                 */
    1053                 : /* -------------------------------------------------------------------- */
    1054                 : 
    1055               2 :     int nFieldIndex = poLayer->GetLayerDefn()->GetFieldIndex(pszColumnName);
    1056               2 :     if( nFieldIndex < 0 )
    1057                 :     {
    1058                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1059                 :                   "%s failed, no such field as `%s'.",
    1060                 :                   pszSQLCommand,
    1061               0 :                   pszColumnName );
    1062               0 :         CSLDestroy( papszTokens );
    1063               0 :         return OGRERR_FAILURE;
    1064                 :     }
    1065                 : 
    1066                 : 
    1067                 : /* -------------------------------------------------------------------- */
    1068                 : /*      Remove it.                                                      */
    1069                 : /* -------------------------------------------------------------------- */
    1070                 : 
    1071               2 :     CSLDestroy( papszTokens );
    1072                 : 
    1073               2 :     return poLayer->DeleteField( nFieldIndex );
    1074                 : }
    1075                 : 
    1076                 : /************************************************************************/
    1077                 : /*                 ProcessSQLAlterTableRenameColumn()                   */
    1078                 : /*                                                                      */
    1079                 : /*      The correct syntax for renaming a column in the OGR SQL         */
    1080                 : /*      dialect is:                                                     */
    1081                 : /*                                                                      */
    1082                 : /*       ALTER TABLE <layername> RENAME [COLUMN] <oldname> TO <newname> */
    1083                 : /************************************************************************/
    1084                 : 
    1085               2 : OGRErr OGRDataSource::ProcessSQLAlterTableRenameColumn( const char *pszSQLCommand )
    1086                 : 
    1087                 : {
    1088               2 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
    1089                 : 
    1090                 : /* -------------------------------------------------------------------- */
    1091                 : /*      Do some general syntax checking.                                */
    1092                 : /* -------------------------------------------------------------------- */
    1093               2 :     const char* pszLayerName = NULL;
    1094               2 :     const char* pszOldColName = NULL;
    1095               2 :     const char* pszNewColName = NULL;
    1096               7 :     if( CSLCount(papszTokens) == 8
    1097               1 :         && EQUAL(papszTokens[0],"ALTER")
    1098               1 :         && EQUAL(papszTokens[1],"TABLE")
    1099               1 :         && EQUAL(papszTokens[3],"RENAME")
    1100               1 :         && EQUAL(papszTokens[4],"COLUMN")
    1101               1 :         && EQUAL(papszTokens[6],"TO"))
    1102                 :     {
    1103               1 :         pszLayerName = papszTokens[2];
    1104               1 :         pszOldColName = papszTokens[5];
    1105               1 :         pszNewColName = papszTokens[7];
    1106                 :     }
    1107               5 :     else if( CSLCount(papszTokens) == 7
    1108               1 :              && EQUAL(papszTokens[0],"ALTER")
    1109               1 :              && EQUAL(papszTokens[1],"TABLE")
    1110               1 :              && EQUAL(papszTokens[3],"RENAME")
    1111               1 :              && EQUAL(papszTokens[5],"TO"))
    1112                 :     {
    1113               1 :         pszLayerName = papszTokens[2];
    1114               1 :         pszOldColName = papszTokens[4];
    1115               1 :         pszNewColName = papszTokens[6];
    1116                 :     }
    1117                 :     else
    1118                 :     {
    1119               0 :         CSLDestroy( papszTokens );
    1120                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1121                 :                   "Syntax error in ALTER TABLE RENAME COLUMN command.\n"
    1122                 :                   "Was '%s'\n"
    1123                 :                   "Should be of form 'ALTER TABLE <layername> RENAME [COLUMN] <columnname> TO <newname>'",
    1124               0 :                   pszSQLCommand );
    1125               0 :         return OGRERR_FAILURE;
    1126                 :     }
    1127                 : 
    1128                 : /* -------------------------------------------------------------------- */
    1129                 : /*      Find the named layer.                                           */
    1130                 : /* -------------------------------------------------------------------- */
    1131               2 :     OGRLayer *poLayer = GetLayerByName(pszLayerName);
    1132               2 :     if( poLayer == NULL )
    1133                 :     {
    1134                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1135                 :                   "%s failed, no such layer as `%s'.",
    1136                 :                   pszSQLCommand,
    1137               0 :                   pszLayerName );
    1138               0 :         CSLDestroy( papszTokens );
    1139               0 :         return OGRERR_FAILURE;
    1140                 :     }
    1141                 : 
    1142                 : /* -------------------------------------------------------------------- */
    1143                 : /*      Find the field.                                                 */
    1144                 : /* -------------------------------------------------------------------- */
    1145                 : 
    1146               2 :     int nFieldIndex = poLayer->GetLayerDefn()->GetFieldIndex(pszOldColName);
    1147               2 :     if( nFieldIndex < 0 )
    1148                 :     {
    1149                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1150                 :                   "%s failed, no such field as `%s'.",
    1151                 :                   pszSQLCommand,
    1152               0 :                   pszOldColName );
    1153               0 :         CSLDestroy( papszTokens );
    1154               0 :         return OGRERR_FAILURE;
    1155                 :     }
    1156                 : 
    1157                 : /* -------------------------------------------------------------------- */
    1158                 : /*      Rename column.                                                  */
    1159                 : /* -------------------------------------------------------------------- */
    1160               2 :     OGRFieldDefn* poOldFieldDefn = poLayer->GetLayerDefn()->GetFieldDefn(nFieldIndex);
    1161               2 :     OGRFieldDefn oNewFieldDefn(poOldFieldDefn);
    1162               2 :     oNewFieldDefn.SetName(pszNewColName);
    1163                 : 
    1164               2 :     CSLDestroy( papszTokens );
    1165                 : 
    1166               2 :     return poLayer->AlterFieldDefn( nFieldIndex, &oNewFieldDefn, ALTER_NAME_FLAG );
    1167                 : }
    1168                 : 
    1169                 : /************************************************************************/
    1170                 : /*                 ProcessSQLAlterTableAlterColumn()                    */
    1171                 : /*                                                                      */
    1172                 : /*      The correct syntax for altering the type of a column in the     */
    1173                 : /*      OGR SQL dialect is:                                             */
    1174                 : /*                                                                      */
    1175                 : /*   ALTER TABLE <layername> ALTER [COLUMN] <columnname> TYPE <newtype> */
    1176                 : /************************************************************************/
    1177                 : 
    1178               4 : OGRErr OGRDataSource::ProcessSQLAlterTableAlterColumn( const char *pszSQLCommand )
    1179                 : 
    1180                 : {
    1181               4 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
    1182                 : 
    1183                 : /* -------------------------------------------------------------------- */
    1184                 : /*      Do some general syntax checking.                                */
    1185                 : /* -------------------------------------------------------------------- */
    1186               4 :     const char* pszLayerName = NULL;
    1187               4 :     const char* pszColumnName = NULL;
    1188               4 :     char* pszType = NULL;
    1189               4 :     int iTypeIndex = 0;
    1190               4 :     int nTokens = CSLCount(papszTokens);
    1191                 : 
    1192              16 :     if( nTokens >= 8
    1193               2 :         && EQUAL(papszTokens[0],"ALTER")
    1194               2 :         && EQUAL(papszTokens[1],"TABLE")
    1195               2 :         && EQUAL(papszTokens[3],"ALTER")
    1196               2 :         && EQUAL(papszTokens[4],"COLUMN")
    1197               2 :         && EQUAL(papszTokens[6],"TYPE"))
    1198                 :     {
    1199               2 :         pszLayerName = papszTokens[2];
    1200               2 :         pszColumnName = papszTokens[5];
    1201               2 :         iTypeIndex = 7;
    1202                 :     }
    1203              12 :     else if( nTokens >= 7
    1204               2 :              && EQUAL(papszTokens[0],"ALTER")
    1205               2 :              && EQUAL(papszTokens[1],"TABLE")
    1206               2 :              && EQUAL(papszTokens[3],"ALTER")
    1207               2 :              && EQUAL(papszTokens[5],"TYPE"))
    1208                 :     {
    1209               2 :         pszLayerName = papszTokens[2];
    1210               2 :         pszColumnName = papszTokens[4];
    1211               2 :         iTypeIndex = 6;
    1212                 :     }
    1213                 :     else
    1214                 :     {
    1215               0 :         CSLDestroy( papszTokens );
    1216                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1217                 :                   "Syntax error in ALTER TABLE ALTER COLUMN command.\n"
    1218                 :                   "Was '%s'\n"
    1219                 :                   "Should be of form 'ALTER TABLE <layername> ALTER [COLUMN] <columnname> TYPE <columntype>'",
    1220               0 :                   pszSQLCommand );
    1221               0 :         return OGRERR_FAILURE;
    1222                 :     }
    1223                 : 
    1224                 : /* -------------------------------------------------------------------- */
    1225                 : /*      Merge type components into a single string if there were split  */
    1226                 : /*      with spaces                                                     */
    1227                 : /* -------------------------------------------------------------------- */
    1228               4 :     CPLString osType;
    1229               8 :     for(int i=iTypeIndex;i<nTokens;i++)
    1230                 :     {
    1231               4 :         osType += papszTokens[i];
    1232               4 :         CPLFree(papszTokens[i]);
    1233                 :     }
    1234               4 :     pszType = papszTokens[iTypeIndex] = CPLStrdup(osType);
    1235               4 :     papszTokens[iTypeIndex + 1] = NULL;
    1236                 : 
    1237                 : /* -------------------------------------------------------------------- */
    1238                 : /*      Find the named layer.                                           */
    1239                 : /* -------------------------------------------------------------------- */
    1240               4 :     OGRLayer *poLayer = GetLayerByName(pszLayerName);
    1241               4 :     if( poLayer == NULL )
    1242                 :     {
    1243                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1244                 :                   "%s failed, no such layer as `%s'.",
    1245                 :                   pszSQLCommand,
    1246               0 :                   pszLayerName );
    1247               0 :         CSLDestroy( papszTokens );
    1248               0 :         return OGRERR_FAILURE;
    1249                 :     }
    1250                 : 
    1251                 : /* -------------------------------------------------------------------- */
    1252                 : /*      Find the field.                                                 */
    1253                 : /* -------------------------------------------------------------------- */
    1254                 : 
    1255               4 :     int nFieldIndex = poLayer->GetLayerDefn()->GetFieldIndex(pszColumnName);
    1256               4 :     if( nFieldIndex < 0 )
    1257                 :     {
    1258                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1259                 :                   "%s failed, no such field as `%s'.",
    1260                 :                   pszSQLCommand,
    1261               0 :                   pszColumnName );
    1262               0 :         CSLDestroy( papszTokens );
    1263               0 :         return OGRERR_FAILURE;
    1264                 :     }
    1265                 : 
    1266                 : /* -------------------------------------------------------------------- */
    1267                 : /*      Alter column.                                                   */
    1268                 : /* -------------------------------------------------------------------- */
    1269                 : 
    1270               4 :     OGRFieldDefn* poOldFieldDefn = poLayer->GetLayerDefn()->GetFieldDefn(nFieldIndex);
    1271               4 :     OGRFieldDefn oNewFieldDefn(poOldFieldDefn);
    1272                 : 
    1273               4 :     int nWidth = 0, nPrecision = 0;
    1274               4 :     OGRFieldType eType = OGRDataSourceParseSQLType(pszType, nWidth, nPrecision);
    1275               4 :     oNewFieldDefn.SetType(eType);
    1276               4 :     oNewFieldDefn.SetWidth(nWidth);
    1277               4 :     oNewFieldDefn.SetPrecision(nPrecision);
    1278                 : 
    1279               4 :     int nFlags = 0;
    1280               4 :     if (poOldFieldDefn->GetType() != oNewFieldDefn.GetType())
    1281               2 :         nFlags |= ALTER_TYPE_FLAG;
    1282               4 :     if (poOldFieldDefn->GetWidth() != oNewFieldDefn.GetWidth() ||
    1283                 :         poOldFieldDefn->GetPrecision() != oNewFieldDefn.GetPrecision())
    1284               4 :         nFlags |= ALTER_WIDTH_PRECISION_FLAG;
    1285                 : 
    1286               4 :     CSLDestroy( papszTokens );
    1287                 : 
    1288               4 :     if (nFlags == 0)
    1289               0 :         return OGRERR_NONE;
    1290                 :     else
    1291               4 :         return poLayer->AlterFieldDefn( nFieldIndex, &oNewFieldDefn, nFlags );
    1292                 : }
    1293                 : 
    1294                 : /************************************************************************/
    1295                 : /*                             ExecuteSQL()                             */
    1296                 : /************************************************************************/
    1297                 : 
    1298            1337 : OGRLayer * OGRDataSource::ExecuteSQL( const char *pszStatement,
    1299                 :                                       OGRGeometry *poSpatialFilter,
    1300                 :                                       const char *pszDialect )
    1301                 : 
    1302                 : {
    1303            1337 :     swq_select *psSelectInfo = NULL;
    1304                 : 
    1305            1337 :     if( pszDialect != NULL && EQUAL(pszDialect, "SQLite") )
    1306                 :     {
    1307                 : #ifdef SQLITE_ENABLED
    1308             222 :         return OGRSQLiteExecuteSQL( this, pszStatement, poSpatialFilter, pszDialect );
    1309                 : #else
    1310                 :         CPLError(CE_Failure, CPLE_NotSupported,
    1311                 :                  "The SQLite driver needs to be compiled to support the SQLite SQL dialect");
    1312                 :         return NULL;
    1313                 : #endif
    1314                 :     }
    1315                 : 
    1316                 : /* -------------------------------------------------------------------- */
    1317                 : /*      Handle CREATE INDEX statements specially.                       */
    1318                 : /* -------------------------------------------------------------------- */
    1319            1115 :     if( EQUALN(pszStatement,"CREATE INDEX",12) )
    1320                 :     {
    1321               8 :         ProcessSQLCreateIndex( pszStatement );
    1322               8 :         return NULL;
    1323                 :     }
    1324                 :     
    1325                 : /* -------------------------------------------------------------------- */
    1326                 : /*      Handle DROP INDEX statements specially.                         */
    1327                 : /* -------------------------------------------------------------------- */
    1328            1107 :     if( EQUALN(pszStatement,"DROP INDEX",10) )
    1329                 :     {
    1330               2 :         ProcessSQLDropIndex( pszStatement );
    1331               2 :         return NULL;
    1332                 :     }
    1333                 :     
    1334                 : /* -------------------------------------------------------------------- */
    1335                 : /*      Handle DROP TABLE statements specially.                         */
    1336                 : /* -------------------------------------------------------------------- */
    1337            1105 :     if( EQUALN(pszStatement,"DROP TABLE",10) )
    1338                 :     {
    1339             500 :         ProcessSQLDropTable( pszStatement );
    1340             500 :         return NULL;
    1341                 :     }
    1342                 : 
    1343                 : /* -------------------------------------------------------------------- */
    1344                 : /*      Handle ALTER TABLE statements specially.                        */
    1345                 : /* -------------------------------------------------------------------- */
    1346             605 :     if( EQUALN(pszStatement,"ALTER TABLE",11) )
    1347                 :     {
    1348              10 :         char **papszTokens = CSLTokenizeString( pszStatement );
    1349              20 :         if( CSLCount(papszTokens) >= 4 &&
    1350              10 :             EQUAL(papszTokens[3],"ADD") )
    1351                 :         {
    1352               2 :             ProcessSQLAlterTableAddColumn( pszStatement );
    1353               2 :             CSLDestroy(papszTokens);
    1354               2 :             return NULL;
    1355                 :         }
    1356              16 :         else if( CSLCount(papszTokens) >= 4 &&
    1357               8 :                  EQUAL(papszTokens[3],"DROP") )
    1358                 :         {
    1359               2 :             ProcessSQLAlterTableDropColumn( pszStatement );
    1360               2 :             CSLDestroy(papszTokens);
    1361               2 :             return NULL;
    1362                 :         }
    1363              12 :         else if( CSLCount(papszTokens) >= 4 &&
    1364               6 :                  EQUAL(papszTokens[3],"RENAME") )
    1365                 :         {
    1366               2 :             ProcessSQLAlterTableRenameColumn( pszStatement );
    1367               2 :             CSLDestroy(papszTokens);
    1368               2 :             return NULL;
    1369                 :         }
    1370               8 :         else if( CSLCount(papszTokens) >= 4 &&
    1371               4 :                  EQUAL(papszTokens[3],"ALTER") )
    1372                 :         {
    1373               4 :             ProcessSQLAlterTableAlterColumn( pszStatement );
    1374               4 :             CSLDestroy(papszTokens);
    1375               4 :             return NULL;
    1376                 :         }
    1377                 :         else
    1378                 :         {
    1379                 :             CPLError( CE_Failure, CPLE_AppDefined,
    1380                 :                       "Unsupported ALTER TABLE command : %s",
    1381               0 :                       pszStatement );
    1382               0 :             CSLDestroy(papszTokens);
    1383               0 :             return NULL;
    1384                 :         }
    1385                 :     }
    1386                 :     
    1387                 : /* -------------------------------------------------------------------- */
    1388                 : /*      Preparse the SQL statement.                                     */
    1389                 : /* -------------------------------------------------------------------- */
    1390             595 :     psSelectInfo = new swq_select();
    1391             595 :     if( psSelectInfo->preparse( pszStatement ) != CPLE_None )
    1392                 :     {
    1393             121 :         delete psSelectInfo;
    1394             121 :         return NULL;
    1395                 :     }
    1396                 : 
    1397                 : /* -------------------------------------------------------------------- */
    1398                 : /*      If there is no UNION ALL, build result layer.                   */
    1399                 : /* -------------------------------------------------------------------- */
    1400             474 :     if( psSelectInfo->poOtherSelect == NULL )
    1401                 :     {
    1402                 :         return BuildLayerFromSelectInfo(psSelectInfo,
    1403                 :                                         poSpatialFilter,
    1404             472 :                                         pszDialect);
    1405                 :     }
    1406                 : 
    1407                 : /* -------------------------------------------------------------------- */
    1408                 : /*      Build result union layer.                                       */
    1409                 : /* -------------------------------------------------------------------- */
    1410               2 :     int nSrcLayers = 0;
    1411               2 :     OGRLayer** papoSrcLayers = NULL;
    1412                 : 
    1413               4 :     do
    1414                 :     {
    1415               4 :         swq_select* psNextSelectInfo = psSelectInfo->poOtherSelect;
    1416               4 :         psSelectInfo->poOtherSelect = NULL;
    1417                 : 
    1418                 :         OGRLayer* poLayer = BuildLayerFromSelectInfo(psSelectInfo,
    1419                 :                                                      poSpatialFilter,
    1420               4 :                                                      pszDialect);
    1421               4 :         if( poLayer == NULL )
    1422                 :         {
    1423                 :             /* Each source layer owns an independant select info */
    1424               0 :             for(int i=0;i<nSrcLayers;i++)
    1425               0 :                 delete papoSrcLayers[i];
    1426               0 :             CPLFree(papoSrcLayers);
    1427                 : 
    1428                 :             /* So we just have to destroy the remaining select info */
    1429               0 :             delete psNextSelectInfo;
    1430                 : 
    1431               0 :             return NULL;
    1432                 :         }
    1433                 :         else
    1434                 :         {
    1435                 :             papoSrcLayers = (OGRLayer**) CPLRealloc(papoSrcLayers,
    1436               4 :                                 sizeof(OGRLayer*) * (nSrcLayers + 1));
    1437               4 :             papoSrcLayers[nSrcLayers] = poLayer;
    1438               4 :             nSrcLayers ++;
    1439                 : 
    1440               4 :             psSelectInfo = psNextSelectInfo;
    1441                 :         }
    1442                 :     }
    1443                 :     while( psSelectInfo != NULL );
    1444                 : 
    1445                 :     return new OGRUnionLayer("SELECT",
    1446                 :                                 nSrcLayers,
    1447                 :                                 papoSrcLayers,
    1448               2 :                                 TRUE);
    1449                 : }
    1450                 : 
    1451                 : /************************************************************************/
    1452                 : /*                        BuildLayerFromSelectInfo()                    */
    1453                 : /************************************************************************/
    1454                 : 
    1455             476 : OGRLayer* OGRDataSource::BuildLayerFromSelectInfo(void* psSelectInfoIn,
    1456                 :                                                   OGRGeometry *poSpatialFilter,
    1457                 :                                                   const char *pszDialect)
    1458                 : {
    1459             476 :     swq_select* psSelectInfo = (swq_select*) psSelectInfoIn;
    1460                 : 
    1461                 :     swq_field_list sFieldList;
    1462             476 :     int            nFIDIndex = 0;
    1463             476 :     OGRGenSQLResultsLayer *poResults = NULL;
    1464             476 :     char *pszWHERE = NULL;
    1465                 : 
    1466             476 :     memset( &sFieldList, 0, sizeof(sFieldList) );
    1467                 : 
    1468                 : /* -------------------------------------------------------------------- */
    1469                 : /*      Validate that all the source tables are recognised, count       */
    1470                 : /*      fields.                                                         */
    1471                 : /* -------------------------------------------------------------------- */
    1472             476 :     int  nFieldCount = 0, iTable, iField;
    1473                 :     int  iEDS;
    1474             476 :     int  nExtraDSCount = 0;
    1475             476 :     OGRDataSource** papoExtraDS = NULL;
    1476             476 :     OGRSFDriverRegistrar *poReg=OGRSFDriverRegistrar::GetRegistrar();
    1477                 : 
    1478             970 :     for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ )
    1479                 :     {
    1480             499 :         swq_table_def *psTableDef = psSelectInfo->table_defs + iTable;
    1481                 :         OGRLayer *poSrcLayer;
    1482             499 :         OGRDataSource *poTableDS = this;
    1483                 : 
    1484             499 :         if( psTableDef->data_source != NULL )
    1485                 :         {
    1486                 :             poTableDS = (OGRDataSource *) 
    1487               5 :                 OGROpenShared( psTableDef->data_source, FALSE, NULL );
    1488               5 :             if( poTableDS == NULL )
    1489                 :             {
    1490               0 :                 if( strlen(CPLGetLastErrorMsg()) == 0 )
    1491                 :                     CPLError( CE_Failure, CPLE_AppDefined, 
    1492                 :                               "Unable to open secondary datasource\n"
    1493                 :                               "`%s' required by JOIN.",
    1494               0 :                               psTableDef->data_source );
    1495                 : 
    1496               0 :                 delete psSelectInfo;
    1497               0 :                 goto end;
    1498                 :             }
    1499                 : 
    1500                 :             /* Keep in an array to release at the end of this function */
    1501                 :             papoExtraDS = (OGRDataSource** )CPLRealloc(papoExtraDS,
    1502               5 :                                sizeof(OGRDataSource*) * (nExtraDSCount + 1));
    1503               5 :             papoExtraDS[nExtraDSCount++] = poTableDS;
    1504                 :         }
    1505                 : 
    1506             499 :         poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name );
    1507                 : 
    1508             499 :         if( poSrcLayer == NULL )
    1509                 :         {
    1510                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    1511                 :                       "SELECT from table %s failed, no such table/featureclass.",
    1512               5 :                       psTableDef->table_name );
    1513               5 :             delete psSelectInfo;
    1514               5 :             goto end;
    1515                 :         }
    1516                 : 
    1517             494 :         nFieldCount += poSrcLayer->GetLayerDefn()->GetFieldCount();
    1518                 :     }
    1519                 :     
    1520                 : /* -------------------------------------------------------------------- */
    1521                 : /*      Build the field list for all indicated tables.                  */
    1522                 : /* -------------------------------------------------------------------- */
    1523                 : 
    1524             471 :     sFieldList.table_count = psSelectInfo->table_count;
    1525             471 :     sFieldList.table_defs = psSelectInfo->table_defs;
    1526                 : 
    1527             471 :     sFieldList.count = 0;
    1528             471 :     sFieldList.names = (char **) CPLMalloc( sizeof(char *) * (nFieldCount+SPECIAL_FIELD_COUNT) );
    1529                 :     sFieldList.types = (swq_field_type *)  
    1530             471 :         CPLMalloc( sizeof(swq_field_type) * (nFieldCount+SPECIAL_FIELD_COUNT) );
    1531                 :     sFieldList.table_ids = (int *) 
    1532             471 :         CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) );
    1533                 :     sFieldList.ids = (int *) 
    1534             471 :         CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) );
    1535                 :     
    1536             964 :     for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ )
    1537                 :     {
    1538             493 :         swq_table_def *psTableDef = psSelectInfo->table_defs + iTable;
    1539             493 :         OGRDataSource *poTableDS = this;
    1540                 :         OGRLayer *poSrcLayer;
    1541                 :         
    1542             493 :         if( psTableDef->data_source != NULL )
    1543                 :         {
    1544                 :             poTableDS = (OGRDataSource *) 
    1545               5 :                 OGROpenShared( psTableDef->data_source, FALSE, NULL );
    1546               5 :             CPLAssert( poTableDS != NULL );
    1547               5 :             poTableDS->Dereference();
    1548                 :         }
    1549                 : 
    1550             493 :         poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name );
    1551                 : 
    1552            5922 :         for( iField = 0; 
    1553            2961 :              iField < poSrcLayer->GetLayerDefn()->GetFieldCount();
    1554                 :              iField++ )
    1555                 :         {
    1556            2468 :             OGRFieldDefn *poFDefn=poSrcLayer->GetLayerDefn()->GetFieldDefn(iField);
    1557            2468 :             int iOutField = sFieldList.count++;
    1558            2468 :             sFieldList.names[iOutField] = (char *) poFDefn->GetNameRef();
    1559            2468 :             if( poFDefn->GetType() == OFTInteger )
    1560             694 :                 sFieldList.types[iOutField] = SWQ_INTEGER;
    1561            1774 :             else if( poFDefn->GetType() == OFTReal )
    1562             530 :                 sFieldList.types[iOutField] = SWQ_FLOAT;
    1563            1244 :             else if( poFDefn->GetType() == OFTString )
    1564            1155 :                 sFieldList.types[iOutField] = SWQ_STRING;
    1565                 :             else
    1566              89 :                 sFieldList.types[iOutField] = SWQ_OTHER;
    1567                 : 
    1568            2468 :             sFieldList.table_ids[iOutField] = iTable;
    1569            2468 :             sFieldList.ids[iOutField] = iField;
    1570                 :         }
    1571                 : 
    1572             493 :         if( iTable == 0 )
    1573             471 :             nFIDIndex = poSrcLayer->GetLayerDefn()->GetFieldCount();
    1574                 :     }
    1575                 : 
    1576                 : /* -------------------------------------------------------------------- */
    1577                 : /*      Expand '*' in 'SELECT *' now before we add the pseudo fields    */
    1578                 : /* -------------------------------------------------------------------- */
    1579             471 :     if( psSelectInfo->expand_wildcard( &sFieldList )  != CE_None )
    1580                 :     {
    1581               0 :         delete psSelectInfo;
    1582               0 :         goto end;
    1583                 :     }
    1584                 : 
    1585            2826 :     for (iField = 0; iField < SPECIAL_FIELD_COUNT; iField++)
    1586                 :     {
    1587            2355 :         sFieldList.names[sFieldList.count] = (char*) SpecialFieldNames[iField];
    1588            2355 :         sFieldList.types[sFieldList.count] = SpecialFieldTypes[iField];
    1589            2355 :         sFieldList.table_ids[sFieldList.count] = 0;
    1590            2355 :         sFieldList.ids[sFieldList.count] = nFIDIndex + iField;
    1591            2355 :         sFieldList.count++;
    1592                 :     }
    1593                 :     
    1594                 : /* -------------------------------------------------------------------- */
    1595                 : /*      Finish the parse operation.                                     */
    1596                 : /* -------------------------------------------------------------------- */
    1597             471 :     if( psSelectInfo->parse( &sFieldList, 0 ) != CE_None )
    1598                 :     {
    1599              24 :         delete psSelectInfo;
    1600              24 :         goto end;
    1601                 :     }
    1602                 : 
    1603                 : /* -------------------------------------------------------------------- */
    1604                 : /*      Extract the WHERE expression to use separately.                 */
    1605                 : /* -------------------------------------------------------------------- */
    1606             447 :     if( psSelectInfo->where_expr != NULL )
    1607                 :     {
    1608             831 :         if (m_poDriver && (
    1609             277 :                 EQUAL(m_poDriver->GetName(), "PostgreSQL") ||
    1610             277 :                 EQUAL(m_poDriver->GetName(), "FileGDB" )) )
    1611              16 :             pszWHERE = psSelectInfo->where_expr->Unparse( &sFieldList, '"' );
    1612                 :         else
    1613             261 :             pszWHERE = psSelectInfo->where_expr->Unparse( &sFieldList, '\'' );
    1614                 :         //CPLDebug( "OGR", "Unparse() -> %s", pszWHERE );
    1615                 :     }
    1616                 : 
    1617                 : /* -------------------------------------------------------------------- */
    1618                 : /*      Everything seems OK, try to instantiate a results layer.        */
    1619                 : /* -------------------------------------------------------------------- */
    1620                 : 
    1621                 :     poResults = new OGRGenSQLResultsLayer( this, psSelectInfo,
    1622                 :                                            poSpatialFilter,
    1623                 :                                            pszWHERE,
    1624             447 :                                            pszDialect );
    1625                 : 
    1626             447 :     CPLFree( pszWHERE );
    1627                 : 
    1628                 :     // Eventually, we should keep track of layers to cleanup.
    1629                 : 
    1630                 : end:
    1631             476 :     CPLFree( sFieldList.names );
    1632             476 :     CPLFree( sFieldList.types );
    1633             476 :     CPLFree( sFieldList.table_ids );
    1634             476 :     CPLFree( sFieldList.ids );
    1635                 : 
    1636                 :     /* Release the datasets we have opened with OGROpenShared() */
    1637                 :     /* It is safe to do that as the 'new OGRGenSQLResultsLayer' itself */
    1638                 :     /* has taken a reference on them, which it will release in its */
    1639                 :     /* destructor */
    1640             481 :     for(iEDS = 0; iEDS < nExtraDSCount; iEDS++)
    1641               5 :         poReg->ReleaseDataSource( papoExtraDS[iEDS] );
    1642             476 :     CPLFree(papoExtraDS);
    1643                 : 
    1644             476 :     return poResults;
    1645                 : }
    1646                 : 
    1647                 : /************************************************************************/
    1648                 : /*                         OGR_DS_ExecuteSQL()                          */
    1649                 : /************************************************************************/
    1650                 : 
    1651            2139 : OGRLayerH OGR_DS_ExecuteSQL( OGRDataSourceH hDS, 
    1652                 :                              const char *pszStatement,
    1653                 :                              OGRGeometryH hSpatialFilter,
    1654                 :                              const char *pszDialect )
    1655                 : 
    1656                 : {
    1657            2139 :     VALIDATE_POINTER1( hDS, "OGR_DS_ExecuteSQL", NULL );
    1658                 : 
    1659                 :     return (OGRLayerH) 
    1660                 :         ((OGRDataSource *)hDS)->ExecuteSQL( pszStatement,
    1661                 :                                             (OGRGeometry *) hSpatialFilter,
    1662            2139 :                                             pszDialect );
    1663                 : }
    1664                 : 
    1665                 : /************************************************************************/
    1666                 : /*                          ReleaseResultSet()                          */
    1667                 : /************************************************************************/
    1668                 : 
    1669             610 : void OGRDataSource::ReleaseResultSet( OGRLayer * poResultsSet )
    1670                 : 
    1671                 : {
    1672             610 :     delete poResultsSet;
    1673             610 : }
    1674                 : 
    1675                 : /************************************************************************/
    1676                 : /*                      OGR_DS_ReleaseResultSet()                       */
    1677                 : /************************************************************************/
    1678                 : 
    1679            1008 : void OGR_DS_ReleaseResultSet( OGRDataSourceH hDS, OGRLayerH hLayer )
    1680                 : 
    1681                 : {
    1682            1008 :     VALIDATE_POINTER0( hDS, "OGR_DS_ReleaseResultSet" );
    1683                 : 
    1684            1008 :     ((OGRDataSource *) hDS)->ReleaseResultSet( (OGRLayer *) hLayer );
    1685                 : }
    1686                 : 
    1687                 : /************************************************************************/
    1688                 : /*                       OGR_DS_TestCapability()                        */
    1689                 : /************************************************************************/
    1690                 : 
    1691              54 : int OGR_DS_TestCapability( OGRDataSourceH hDS, const char *pszCap )
    1692                 : 
    1693                 : {
    1694              54 :     VALIDATE_POINTER1( hDS, "OGR_DS_TestCapability", 0 );
    1695              54 :     VALIDATE_POINTER1( pszCap, "OGR_DS_TestCapability", 0 );
    1696                 : 
    1697              54 :     return ((OGRDataSource *) hDS)->TestCapability( pszCap );
    1698                 : }
    1699                 : 
    1700                 : /************************************************************************/
    1701                 : /*                        OGR_DS_GetLayerCount()                        */
    1702                 : /************************************************************************/
    1703                 : 
    1704             260 : int OGR_DS_GetLayerCount( OGRDataSourceH hDS )
    1705                 : 
    1706                 : {
    1707             260 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetLayerCount", 0 );
    1708                 : 
    1709             260 :     return ((OGRDataSource *)hDS)->GetLayerCount();
    1710                 : }
    1711                 : 
    1712                 : /************************************************************************/
    1713                 : /*                          OGR_DS_GetLayer()                           */
    1714                 : /************************************************************************/
    1715                 : 
    1716            5083 : OGRLayerH OGR_DS_GetLayer( OGRDataSourceH hDS, int iLayer )
    1717                 : 
    1718                 : {
    1719            5083 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetLayer", NULL );
    1720                 : 
    1721            5083 :     return (OGRLayerH) ((OGRDataSource*)hDS)->GetLayer( iLayer );
    1722                 : }
    1723                 : 
    1724                 : /************************************************************************/
    1725                 : /*                           OGR_DS_GetName()                           */
    1726                 : /************************************************************************/
    1727                 : 
    1728              31 : const char *OGR_DS_GetName( OGRDataSourceH hDS )
    1729                 : 
    1730                 : {
    1731              31 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetName", NULL );
    1732                 : 
    1733              31 :     return ((OGRDataSource*)hDS)->GetName();
    1734                 : }
    1735                 : 
    1736                 : /************************************************************************/
    1737                 : /*                             SyncToDisk()                             */
    1738                 : /************************************************************************/
    1739                 : 
    1740               0 : OGRErr OGRDataSource::SyncToDisk()
    1741                 : 
    1742                 : {
    1743               0 :     CPLMutexHolderD( &m_hMutex );
    1744                 :     int i;
    1745                 :     OGRErr eErr;
    1746                 : 
    1747               0 :     for( i = 0; i < GetLayerCount(); i++ )
    1748                 :     {
    1749               0 :         OGRLayer *poLayer = GetLayer(i);
    1750                 : 
    1751               0 :         if( poLayer )
    1752                 :         {
    1753               0 :             eErr = poLayer->SyncToDisk();
    1754               0 :             if( eErr != OGRERR_NONE )
    1755               0 :                 return eErr;
    1756                 :         }
    1757                 :     }
    1758                 : 
    1759               0 :     return OGRERR_NONE;
    1760                 : }
    1761                 : 
    1762                 : /************************************************************************/
    1763                 : /*                         OGR_DS_SyncToDisk()                          */
    1764                 : /************************************************************************/
    1765                 : 
    1766               0 : OGRErr OGR_DS_SyncToDisk( OGRDataSourceH hDS )
    1767                 : 
    1768                 : {
    1769               0 :     VALIDATE_POINTER1( hDS, "OGR_DS_SyncToDisk", OGRERR_INVALID_HANDLE );
    1770                 : 
    1771               0 :     return ((OGRDataSource *) hDS)->SyncToDisk();
    1772                 : }
    1773                 : 
    1774                 : /************************************************************************/
    1775                 : /*                             GetDriver()                              */
    1776                 : /************************************************************************/
    1777                 : 
    1778            4395 : OGRSFDriver *OGRDataSource::GetDriver() const
    1779                 : 
    1780                 : {
    1781            4395 :     return m_poDriver;
    1782                 : }
    1783                 : 
    1784                 : /************************************************************************/
    1785                 : /*                          OGR_DS_GetDriver()                          */
    1786                 : /************************************************************************/
    1787                 : 
    1788             110 : OGRSFDriverH OGR_DS_GetDriver( OGRDataSourceH hDS )
    1789                 : 
    1790                 : {
    1791             110 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetDriver", NULL );
    1792                 : 
    1793             110 :     return (OGRSFDriverH) ((OGRDataSource *) hDS)->GetDriver();
    1794                 : }
    1795                 : 
    1796                 : /************************************************************************/
    1797                 : /*                             SetDriver()                              */
    1798                 : /************************************************************************/
    1799                 : 
    1800             586 : void OGRDataSource::SetDriver( OGRSFDriver *poDriver ) 
    1801                 : 
    1802                 : {
    1803             586 :     m_poDriver = poDriver;
    1804             586 : }
    1805                 : 
    1806                 : /************************************************************************/
    1807                 : /*                            GetStyleTable()                           */
    1808                 : /************************************************************************/
    1809                 : 
    1810              83 : OGRStyleTable *OGRDataSource::GetStyleTable()
    1811                 : {
    1812              83 :     return m_poStyleTable;
    1813                 : }
    1814                 : 
    1815                 : /************************************************************************/
    1816                 : /*                         SetStyleTableDirectly()                      */
    1817                 : /************************************************************************/
    1818                 : 
    1819               0 : void OGRDataSource::SetStyleTableDirectly( OGRStyleTable *poStyleTable )
    1820                 : {
    1821               0 :     if ( m_poStyleTable )
    1822               0 :         delete m_poStyleTable;
    1823               0 :     m_poStyleTable = poStyleTable;
    1824               0 : }
    1825                 : 
    1826                 : /************************************************************************/
    1827                 : /*                            SetStyleTable()                           */
    1828                 : /************************************************************************/
    1829                 : 
    1830              83 : void OGRDataSource::SetStyleTable(OGRStyleTable *poStyleTable)
    1831                 : {
    1832              83 :     if ( m_poStyleTable )
    1833               0 :         delete m_poStyleTable;
    1834              83 :     if ( poStyleTable )
    1835               0 :         m_poStyleTable = poStyleTable->Clone();
    1836              83 : }
    1837                 : 
    1838                 : /************************************************************************/
    1839                 : /*                         OGR_DS_GetStyleTable()                       */
    1840                 : /************************************************************************/
    1841                 : 
    1842               0 : OGRStyleTableH OGR_DS_GetStyleTable( OGRDataSourceH hDS )
    1843                 : 
    1844                 : {
    1845               0 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetStyleTable", NULL );
    1846                 :     
    1847               0 :     return (OGRStyleTableH) ((OGRDataSource *) hDS)->GetStyleTable( );
    1848                 : }
    1849                 : 
    1850                 : /************************************************************************/
    1851                 : /*                         OGR_DS_SetStyleTableDirectly()               */
    1852                 : /************************************************************************/
    1853                 : 
    1854               0 : void OGR_DS_SetStyleTableDirectly( OGRDataSourceH hDS,
    1855                 :                                    OGRStyleTableH hStyleTable )
    1856                 : 
    1857                 : {
    1858               0 :     VALIDATE_POINTER0( hDS, "OGR_DS_SetStyleTableDirectly" );
    1859                 :     
    1860               0 :     ((OGRDataSource *) hDS)->SetStyleTableDirectly( (OGRStyleTable *) hStyleTable);
    1861                 : }
    1862                 : 
    1863                 : /************************************************************************/
    1864                 : /*                         OGR_DS_SetStyleTable()                       */
    1865                 : /************************************************************************/
    1866                 : 
    1867               0 : void OGR_DS_SetStyleTable( OGRDataSourceH hDS, OGRStyleTableH hStyleTable )
    1868                 : 
    1869                 : {
    1870               0 :     VALIDATE_POINTER0( hDS, "OGR_DS_SetStyleTable" );
    1871               0 :     VALIDATE_POINTER0( hStyleTable, "OGR_DS_SetStyleTable" );
    1872                 :     
    1873               0 :     ((OGRDataSource *) hDS)->SetStyleTable( (OGRStyleTable *) hStyleTable);
    1874                 : }

Generated by: LCOV version 1.7