LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/generic - ogrdatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 648 487 75.2 %
Date: 2012-04-28 Functions: 51 36 70.6 %

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

Generated by: LCOV version 1.7