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: 2011-12-18 Functions: 51 36 70.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrdatasource.cpp 23403 2011-11-20 21:01:21Z ajolma $
       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 23403 2011-11-20 21:01:21Z ajolma $");
      39                 : 
      40                 : /************************************************************************/
      41                 : /*                           ~OGRDataSource()                           */
      42                 : /************************************************************************/
      43                 : 
      44           11460 : OGRDataSource::OGRDataSource()
      45                 : 
      46                 : {
      47           11460 :     m_poStyleTable = NULL;
      48           11460 :     m_nRefCount = 0;
      49           11460 :     m_poDriver = NULL;
      50           11460 :     m_hMutex = NULL;
      51           11460 : }
      52                 : 
      53                 : /************************************************************************/
      54                 : /*                           ~OGRDataSource()                           */
      55                 : /************************************************************************/
      56                 : 
      57           11460 : OGRDataSource::~OGRDataSource()
      58                 : 
      59                 : {
      60           11460 :     if ( m_poStyleTable )
      61                 :     {
      62               3 :         delete m_poStyleTable;
      63               3 :         m_poStyleTable = NULL;
      64                 :     }
      65                 : 
      66           11460 :     if( m_hMutex != NULL )
      67             614 :         CPLDestroyMutex( m_hMutex );
      68           11460 : }
      69                 : 
      70                 : /************************************************************************/
      71                 : /*                         DestroyDataSource()                          */
      72                 : /************************************************************************/
      73                 : 
      74             348 : void OGRDataSource::DestroyDataSource( OGRDataSource *poDS )
      75                 : 
      76                 : {
      77             348 :     delete poDS;
      78             348 : }
      79                 : 
      80                 : /************************************************************************/
      81                 : /*                           OGR_DS_Destroy()                           */
      82                 : /************************************************************************/
      83                 : 
      84              44 : void OGR_DS_Destroy( OGRDataSourceH hDS )
      85                 : 
      86                 : {
      87              44 :     VALIDATE_POINTER0( hDS, "OGR_DS_Destroy" );
      88              44 :     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            1061 : int OGRDataSource::Reference()
     106                 : 
     107                 : {
     108            1061 :     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              42 : int OGRDataSource::Dereference()
     128                 : 
     129                 : {
     130              42 :     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              78 : int OGRDataSource::GetRefCount() const
     150                 : 
     151                 : {
     152              78 :     return m_nRefCount;
     153                 : }
     154                 : 
     155                 : /************************************************************************/
     156                 : /*                         OGR_DS_GetRefCount()                         */
     157                 : /************************************************************************/
     158                 : 
     159               4 : int OGR_DS_GetRefCount( OGRDataSourceH hDataSource )
     160                 : 
     161                 : {
     162               4 :     VALIDATE_POINTER1( hDataSource, "OGR_DS_GetRefCount", 0 );
     163                 : 
     164               4 :     return ((OGRDataSource *) hDataSource)->GetRefCount();
     165                 : }
     166                 : 
     167                 : /************************************************************************/
     168                 : /*                         GetSummaryRefCount()                         */
     169                 : /************************************************************************/
     170                 : 
     171              13 : int OGRDataSource::GetSummaryRefCount() const
     172                 : 
     173                 : {
     174              13 :     CPLMutexHolderD( (void **) &m_hMutex );
     175              13 :     int nSummaryCount = m_nRefCount;
     176                 :     int iLayer;
     177              13 :     OGRDataSource *poUseThis = (OGRDataSource *) this;
     178                 : 
     179              26 :     for( iLayer=0; iLayer < poUseThis->GetLayerCount(); iLayer++ )
     180              13 :         nSummaryCount += poUseThis->GetLayer( iLayer )->GetRefCount();
     181                 : 
     182              13 :     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            1420 : OGRLayerH OGR_DS_CreateLayer( OGRDataSourceH hDS, 
     223                 :                               const char * pszName,
     224                 :                               OGRSpatialReferenceH hSpatialRef,
     225                 :                               OGRwkbGeometryType eType,
     226                 :                               char ** papszOptions )
     227                 : 
     228                 : {
     229            1420 :     VALIDATE_POINTER1( hDS, "OGR_DS_CreateLayer", NULL );
     230                 : 
     231            1420 :     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            1420 :         pszName, (OGRSpatialReference *) hSpatialRef, eType, papszOptions );
     238                 : }
     239                 : 
     240                 : /************************************************************************/
     241                 : /*                             CopyLayer()                              */
     242                 : /************************************************************************/
     243                 : 
     244              23 : OGRLayer *OGRDataSource::CopyLayer( OGRLayer *poSrcLayer, 
     245                 :                                     const char *pszNewName, 
     246                 :                                     char **papszOptions )
     247                 : 
     248                 : {
     249              23 :     OGRFeatureDefn *poSrcDefn = poSrcLayer->GetLayerDefn();
     250              23 :     OGRLayer *poDstLayer = NULL;
     251                 : 
     252                 : /* -------------------------------------------------------------------- */
     253                 : /*      Create the layer.                                               */
     254                 : /* -------------------------------------------------------------------- */
     255              23 :     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              23 :     CPLErrorReset();
     263              23 :     poDstLayer = CreateLayer( pszNewName, poSrcLayer->GetSpatialRef(),
     264              46 :                               poSrcDefn->GetGeomType(), papszOptions );
     265                 :     
     266              23 :     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              51 :     for( iField = 0; iField < poSrcDefn->GetFieldCount(); iField++ )
     278              28 :         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              23 :     int nGroupTransactions = 0;
     285              23 :     if( poDstLayer->TestCapability( OLCTransactions ) )
     286               2 :         nGroupTransactions = 128;
     287                 : 
     288                 : /* -------------------------------------------------------------------- */
     289                 : /*      Transfer features.                                              */
     290                 : /* -------------------------------------------------------------------- */
     291                 :     OGRFeature  *poFeature;
     292                 : 
     293              23 :     poSrcLayer->ResetReading();
     294                 : 
     295              23 :     if( nGroupTransactions <= 0 )
     296                 :     {
     297              21 :       while( TRUE )
     298                 :       {
     299              42 :         OGRFeature      *poDstFeature = NULL;
     300                 : 
     301              42 :         poFeature = poSrcLayer->GetNextFeature();
     302                 :         
     303              42 :         if( poFeature == NULL )
     304                 :             break;
     305                 : 
     306              21 :         CPLErrorReset();
     307              21 :         poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
     308                 : 
     309              21 :         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              21 :         poDstFeature->SetFID( poFeature->GetFID() );
     319                 : 
     320              21 :         OGRFeature::DestroyFeature( poFeature );
     321                 : 
     322              21 :         CPLErrorReset();
     323              21 :         if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE )
     324                 :         {
     325               0 :             OGRFeature::DestroyFeature( poDstFeature );
     326               0 :             return poDstLayer;
     327                 :         }
     328                 : 
     329              21 :         OGRFeature::DestroyFeature( poDstFeature );
     330                 :       }
     331                 :     }
     332                 :     else
     333                 :     {
     334               2 :       int i, bStopTransfer = FALSE, bStopTransaction = FALSE;
     335               2 :       int nFeatCount = 0; // Number of features in the temporary array
     336               2 :       int nFeaturesToAdd = 0;
     337                 :       OGRFeature **papoDstFeature =
     338               2 :           (OGRFeature **)CPLCalloc(sizeof(OGRFeature *), nGroupTransactions);
     339               6 :       while( !bStopTransfer )
     340                 :       {
     341                 : /* -------------------------------------------------------------------- */
     342                 : /*      Fill the array with features                                    */
     343                 : /* -------------------------------------------------------------------- */
     344              38 :         for( nFeatCount = 0; nFeatCount < nGroupTransactions; nFeatCount++ )
     345                 :         {
     346              38 :             poFeature = poSrcLayer->GetNextFeature();
     347                 : 
     348              38 :             if( poFeature == NULL )
     349                 :             {
     350               2 :                 bStopTransfer = 1;
     351               2 :                 break;
     352                 :             }
     353                 : 
     354              36 :             CPLErrorReset();
     355              36 :             papoDstFeature[nFeatCount] =
     356              36 :                         OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
     357                 : 
     358              36 :             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              36 :             papoDstFeature[nFeatCount]->SetFID( poFeature->GetFID() );
     369                 : 
     370              36 :             OGRFeature::DestroyFeature( poFeature );
     371                 :         }
     372               2 :         nFeaturesToAdd = nFeatCount;
     373                 : 
     374               2 :         CPLErrorReset();
     375               2 :         bStopTransaction = FALSE;
     376               6 :         while( !bStopTransaction )
     377                 :         {
     378               2 :             bStopTransaction = TRUE;
     379               2 :             poDstLayer->StartTransaction();
     380              38 :             for( i = 0; i < nFeaturesToAdd; i++ )
     381                 :             {
     382              36 :                 if( poDstLayer->CreateFeature( papoDstFeature[i] ) != OGRERR_NONE )
     383                 :                 {
     384               0 :                     nFeaturesToAdd = i;
     385               0 :                     bStopTransfer = TRUE;
     386               0 :                     bStopTransaction = FALSE;
     387                 :                 }
     388                 :             }
     389               2 :             if( bStopTransaction )
     390               2 :                 poDstLayer->CommitTransaction();
     391                 :             else
     392               0 :                 poDstLayer->RollbackTransaction();
     393                 :         }
     394                 : 
     395              38 :         for( i = 0; i < nFeatCount; i++ )
     396              36 :             OGRFeature::DestroyFeature( papoDstFeature[i] );
     397                 :       }
     398               2 :       CPLFree(papoDstFeature);
     399                 :     }
     400              23 :     return poDstLayer;
     401                 : }
     402                 : 
     403                 : /************************************************************************/
     404                 : /*                          OGR_DS_CopyLayer()                          */
     405                 : /************************************************************************/
     406                 : 
     407               2 : OGRLayerH OGR_DS_CopyLayer( OGRDataSourceH hDS, 
     408                 :                             OGRLayerH hSrcLayer, const char *pszNewName,
     409                 :                             char **papszOptions )
     410                 : 
     411                 : {
     412               2 :     VALIDATE_POINTER1( hDS, "OGR_DS_CopyLayer", NULL );
     413               2 :     VALIDATE_POINTER1( hSrcLayer, "OGR_DS_CopyLayer", NULL );
     414               2 :     VALIDATE_POINTER1( pszNewName, "OGR_DS_CopyLayer", NULL );
     415                 : 
     416                 :     return (OGRLayerH) 
     417                 :         ((OGRDataSource *) hDS)->CopyLayer( (OGRLayer *) hSrcLayer, 
     418               2 :                                             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              11 : OGRErr OGR_DS_DeleteLayer( OGRDataSourceH hDS, int iLayer )
     440                 : 
     441                 : {
     442              11 :     VALIDATE_POINTER1( hDS, "OGR_DS_DeleteLayer", OGRERR_INVALID_HANDLE );
     443                 : 
     444              11 :     return ((OGRDataSource *) hDS)->DeleteLayer( iLayer );
     445                 : }
     446                 : 
     447                 : /************************************************************************/
     448                 : /*                           GetLayerByName()                           */
     449                 : /************************************************************************/
     450                 : 
     451            2537 : OGRLayer *OGRDataSource::GetLayerByName( const char *pszName )
     452                 : 
     453                 : {
     454            2537 :     CPLMutexHolderD( &m_hMutex );
     455                 : 
     456            2537 :     if ( ! pszName )
     457               0 :         return NULL;
     458                 : 
     459                 :     int  i;
     460                 : 
     461                 :     /* first a case sensitive check */
     462          259835 :     for( i = 0; i < GetLayerCount(); i++ )
     463                 :     {
     464          259667 :         OGRLayer *poLayer = GetLayer(i);
     465                 : 
     466          259667 :         if( strcmp( pszName, poLayer->GetName() ) == 0 )
     467            2369 :             return poLayer;
     468                 :     }
     469                 : 
     470                 :     /* then case insensitive */
     471             898 :     for( i = 0; i < GetLayerCount(); i++ )
     472                 :     {
     473             750 :         OGRLayer *poLayer = GetLayer(i);
     474                 : 
     475             750 :         if( EQUAL( pszName, poLayer->GetName() ) )
     476              20 :             return poLayer;
     477                 :     }
     478                 : 
     479             148 :     return NULL;
     480                 : }
     481                 : 
     482                 : /************************************************************************/
     483                 : /*                       OGR_DS_GetLayerByName()                        */
     484                 : /************************************************************************/
     485                 : 
     486            1801 : OGRLayerH OGR_DS_GetLayerByName( OGRDataSourceH hDS, const char *pszName )
     487                 : 
     488                 : {
     489            1801 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetLayerByName", NULL );
     490                 : 
     491            1801 :     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               6 : OGRErr OGRDataSource::ProcessSQLCreateIndex( const char *pszSQLCommand )
     504                 : 
     505                 : {
     506               6 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
     507                 : 
     508                 : /* -------------------------------------------------------------------- */
     509                 : /*      Do some general syntax checking.                                */
     510                 : /* -------------------------------------------------------------------- */
     511              30 :     if( CSLCount(papszTokens) != 6 
     512               6 :         || !EQUAL(papszTokens[0],"CREATE")
     513               6 :         || !EQUAL(papszTokens[1],"INDEX")
     514               6 :         || !EQUAL(papszTokens[2],"ON")
     515               6 :         || !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               6 :     OGRLayer *poLayer = NULL;
     531                 : 
     532                 :     {
     533               6 :         CPLMutexHolderD( &m_hMutex );
     534                 : 
     535               6 :         for( i = 0; i < GetLayerCount(); i++ )
     536                 :         {
     537               6 :             poLayer = GetLayer(i);
     538                 :             
     539               6 :             if( EQUAL(poLayer->GetName(),papszTokens[3]) )
     540               6 :                 break;
     541                 :         }
     542                 :         
     543               6 :         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               6 :     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               9 :     for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
     568                 :     {
     569               9 :         if( EQUAL(papszTokens[5],
     570                 :                   poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) )
     571               6 :             break;
     572                 :     }
     573                 : 
     574               6 :     CSLDestroy( papszTokens );
     575                 : 
     576               6 :     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               6 :     eErr = poLayer->GetIndex()->CreateIndex( i );
     590               6 :     if( eErr == OGRERR_NONE )
     591               6 :         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               6 :     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               2 : OGRErr OGRDataSource::ProcessSQLDropIndex( const char *pszSQLCommand )
     612                 : 
     613                 : {
     614               2 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
     615                 : 
     616                 : /* -------------------------------------------------------------------- */
     617                 : /*      Do some general syntax checking.                                */
     618                 : /* -------------------------------------------------------------------- */
     619              10 :     if( (CSLCount(papszTokens) != 4 && CSLCount(papszTokens) != 6)
     620               2 :         || !EQUAL(papszTokens[0],"DROP")
     621               2 :         || !EQUAL(papszTokens[1],"INDEX")
     622               2 :         || !EQUAL(papszTokens[2],"ON") 
     623               2 :         || (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               2 :     OGRLayer *poLayer=NULL;
     639                 : 
     640                 :     {
     641               2 :         CPLMutexHolderD( &m_hMutex );
     642                 : 
     643               2 :         for( i = 0; i < GetLayerCount(); i++ )
     644                 :         {
     645               2 :             poLayer = GetLayer(i);
     646                 :         
     647               2 :             if( EQUAL(poLayer->GetName(),papszTokens[3]) )
     648               2 :                 break;
     649                 :         }
     650                 : 
     651               2 :         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               2 :     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               2 :     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               3 :     for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
     700                 :     {
     701               3 :         if( EQUAL(papszTokens[5],
     702                 :                   poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) )
     703               2 :             break;
     704                 :     }
     705                 : 
     706               2 :     CSLDestroy( papszTokens );
     707                 : 
     708               2 :     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               2 :     eErr = poLayer->GetIndex()->DropIndex( i );
     720                 : 
     721               2 :     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             500 : OGRErr OGRDataSource::ProcessSQLDropTable( const char *pszSQLCommand )
     734                 : 
     735                 : {
     736             500 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
     737                 : 
     738                 : /* -------------------------------------------------------------------- */
     739                 : /*      Do some general syntax checking.                                */
     740                 : /* -------------------------------------------------------------------- */
     741            1500 :     if( CSLCount(papszTokens) != 3
     742             500 :         || !EQUAL(papszTokens[0],"DROP")
     743             500 :         || !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             500 :     OGRLayer *poLayer=NULL;
     759                 : 
     760           40199 :     for( i = 0; i < GetLayerCount(); i++ )
     761                 :     {
     762           40199 :         poLayer = GetLayer(i);
     763                 :         
     764           40199 :         if( EQUAL(poLayer->GetName(),papszTokens[2]) )
     765             500 :             break;
     766                 :     }
     767                 :     
     768             500 :     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             500 :     CSLDestroy( papszTokens );
     778                 : 
     779                 : /* -------------------------------------------------------------------- */
     780                 : /*      Delete it.                                                      */
     781                 : /* -------------------------------------------------------------------- */
     782                 : 
     783             500 :     return DeleteLayer( i );
     784                 : }
     785                 : 
     786                 : /************************************************************************/
     787                 : /*                    OGRDataSourceParseSQLType()                       */
     788                 : /************************************************************************/
     789                 : 
     790                 : /* All arguments will be altered */
     791               6 : static OGRFieldType OGRDataSourceParseSQLType(char* pszType, int& nWidth, int &nPrecision)
     792                 : {
     793               6 :     char* pszParenthesis = strchr(pszType, '(');
     794               6 :     if (pszParenthesis)
     795                 :     {
     796               4 :         nWidth = atoi(pszParenthesis + 1);
     797               4 :         *pszParenthesis = '\0';
     798               4 :         char* pszComma = strchr(pszParenthesis + 1, ',');
     799               4 :         if (pszComma)
     800               2 :             nPrecision = atoi(pszComma + 1);
     801                 :     }
     802                 : 
     803               6 :     OGRFieldType eType = OFTString;
     804               6 :     if (EQUAL(pszType, "INTEGER"))
     805               0 :         eType = OFTInteger;
     806               6 :     else if (EQUAL(pszType, "INTEGER[]"))
     807               0 :         eType = OFTIntegerList;
     808               8 :     else if (EQUAL(pszType, "FLOAT") ||
     809                 :              EQUAL(pszType, "NUMERIC") ||
     810                 :              EQUAL(pszType, "DOUBLE") /* unofficial alias */ ||
     811                 :              EQUAL(pszType, "REAL") /* unofficial alias */)
     812               2 :         eType = OFTReal;
     813               4 :     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               8 :     else if (EQUAL(pszType, "CHARACTER") ||
     819                 :              EQUAL(pszType, "TEXT") /* unofficial alias */ ||
     820                 :              EQUAL(pszType, "STRING") /* unofficial alias */ ||
     821                 :              EQUAL(pszType, "VARCHAR") /* unofficial alias */)
     822               4 :         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               6 :     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               2 : OGRErr OGRDataSource::ProcessSQLAlterTableAddColumn( const char *pszSQLCommand )
     853                 : 
     854                 : {
     855               2 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
     856                 : 
     857                 : /* -------------------------------------------------------------------- */
     858                 : /*      Do some general syntax checking.                                */
     859                 : /* -------------------------------------------------------------------- */
     860               2 :     const char* pszLayerName = NULL;
     861               2 :     const char* pszColumnName = NULL;
     862               2 :     char* pszType = NULL;
     863               2 :     int iTypeIndex = 0;
     864               2 :     int nTokens = CSLCount(papszTokens);
     865                 : 
     866              11 :     if( nTokens >= 7
     867               2 :         && EQUAL(papszTokens[0],"ALTER")
     868               2 :         && EQUAL(papszTokens[1],"TABLE")
     869               2 :         && EQUAL(papszTokens[3],"ADD")
     870               2 :         && EQUAL(papszTokens[4],"COLUMN"))
     871                 :     {
     872               1 :         pszLayerName = papszTokens[2];
     873               1 :         pszColumnName = papszTokens[5];
     874               1 :         iTypeIndex = 6;
     875                 :     }
     876               5 :     else if( nTokens >= 6
     877               1 :              && EQUAL(papszTokens[0],"ALTER")
     878               1 :              && EQUAL(papszTokens[1],"TABLE")
     879               1 :              && EQUAL(papszTokens[3],"ADD"))
     880                 :     {
     881               1 :         pszLayerName = papszTokens[2];
     882               1 :         pszColumnName = papszTokens[4];
     883               1 :         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               2 :     CPLString osType;
     901               6 :     for(int i=iTypeIndex;i<nTokens;i++)
     902                 :     {
     903               4 :         osType += papszTokens[i];
     904               4 :         CPLFree(papszTokens[i]);
     905                 :     }
     906               2 :     pszType = papszTokens[iTypeIndex] = CPLStrdup(osType);
     907               2 :     papszTokens[iTypeIndex + 1] = NULL;
     908                 : 
     909                 : /* -------------------------------------------------------------------- */
     910                 : /*      Find the named layer.                                           */
     911                 : /* -------------------------------------------------------------------- */
     912               2 :     OGRLayer *poLayer = GetLayerByName(pszLayerName);
     913               2 :     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               2 :     int nWidth = 0, nPrecision = 0;
     928               2 :     OGRFieldType eType = OGRDataSourceParseSQLType(pszType, nWidth, nPrecision);
     929               2 :     OGRFieldDefn oFieldDefn(pszColumnName, eType);
     930               2 :     oFieldDefn.SetWidth(nWidth);
     931               2 :     oFieldDefn.SetPrecision(nPrecision);
     932                 : 
     933               2 :     CSLDestroy( papszTokens );
     934                 : 
     935               2 :     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               2 : OGRErr OGRDataSource::ProcessSQLAlterTableDropColumn( const char *pszSQLCommand )
     948                 : 
     949                 : {
     950               2 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
     951                 : 
     952                 : /* -------------------------------------------------------------------- */
     953                 : /*      Do some general syntax checking.                                */
     954                 : /* -------------------------------------------------------------------- */
     955               2 :     const char* pszLayerName = NULL;
     956               2 :     const char* pszColumnName = NULL;
     957               6 :     if( CSLCount(papszTokens) == 6
     958               1 :         && EQUAL(papszTokens[0],"ALTER")
     959               1 :         && EQUAL(papszTokens[1],"TABLE")
     960               1 :         && EQUAL(papszTokens[3],"DROP")
     961               1 :         && EQUAL(papszTokens[4],"COLUMN"))
     962                 :     {
     963               1 :         pszLayerName = papszTokens[2];
     964               1 :         pszColumnName = papszTokens[5];
     965                 :     }
     966               4 :     else if( CSLCount(papszTokens) == 5
     967               1 :              && EQUAL(papszTokens[0],"ALTER")
     968               1 :              && EQUAL(papszTokens[1],"TABLE")
     969               1 :              && EQUAL(papszTokens[3],"DROP"))
     970                 :     {
     971               1 :         pszLayerName = papszTokens[2];
     972               1 :         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               2 :     OGRLayer *poLayer = GetLayerByName(pszLayerName);
     989               2 :     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               2 :     int nFieldIndex = poLayer->GetLayerDefn()->GetFieldIndex(pszColumnName);
    1004               2 :     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               2 :     CSLDestroy( papszTokens );
    1020                 : 
    1021               2 :     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               2 : OGRErr OGRDataSource::ProcessSQLAlterTableRenameColumn( const char *pszSQLCommand )
    1034                 : 
    1035                 : {
    1036               2 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
    1037                 : 
    1038                 : /* -------------------------------------------------------------------- */
    1039                 : /*      Do some general syntax checking.                                */
    1040                 : /* -------------------------------------------------------------------- */
    1041               2 :     const char* pszLayerName = NULL;
    1042               2 :     const char* pszOldColName = NULL;
    1043               2 :     const char* pszNewColName = NULL;
    1044               7 :     if( CSLCount(papszTokens) == 8
    1045               1 :         && EQUAL(papszTokens[0],"ALTER")
    1046               1 :         && EQUAL(papszTokens[1],"TABLE")
    1047               1 :         && EQUAL(papszTokens[3],"RENAME")
    1048               1 :         && EQUAL(papszTokens[4],"COLUMN")
    1049               1 :         && EQUAL(papszTokens[6],"TO"))
    1050                 :     {
    1051               1 :         pszLayerName = papszTokens[2];
    1052               1 :         pszOldColName = papszTokens[5];
    1053               1 :         pszNewColName = papszTokens[7];
    1054                 :     }
    1055               5 :     else if( CSLCount(papszTokens) == 7
    1056               1 :              && EQUAL(papszTokens[0],"ALTER")
    1057               1 :              && EQUAL(papszTokens[1],"TABLE")
    1058               1 :              && EQUAL(papszTokens[3],"RENAME")
    1059               1 :              && EQUAL(papszTokens[5],"TO"))
    1060                 :     {
    1061               1 :         pszLayerName = papszTokens[2];
    1062               1 :         pszOldColName = papszTokens[4];
    1063               1 :         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> <columntype>'",
    1072               0 :                   pszSQLCommand );
    1073               0 :         return OGRERR_FAILURE;
    1074                 :     }
    1075                 : 
    1076                 : /* -------------------------------------------------------------------- */
    1077                 : /*      Find the named layer.                                           */
    1078                 : /* -------------------------------------------------------------------- */
    1079               2 :     OGRLayer *poLayer = GetLayerByName(pszLayerName);
    1080               2 :     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               2 :     int nFieldIndex = poLayer->GetLayerDefn()->GetFieldIndex(pszOldColName);
    1095               2 :     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               2 :     OGRFieldDefn* poOldFieldDefn = poLayer->GetLayerDefn()->GetFieldDefn(nFieldIndex);
    1109               2 :     OGRFieldDefn oNewFieldDefn(poOldFieldDefn);
    1110               2 :     oNewFieldDefn.SetName(pszNewColName);
    1111                 : 
    1112               2 :     CSLDestroy( papszTokens );
    1113                 : 
    1114               2 :     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               4 : OGRErr OGRDataSource::ProcessSQLAlterTableAlterColumn( const char *pszSQLCommand )
    1127                 : 
    1128                 : {
    1129               4 :     char **papszTokens = CSLTokenizeString( pszSQLCommand );
    1130                 : 
    1131                 : /* -------------------------------------------------------------------- */
    1132                 : /*      Do some general syntax checking.                                */
    1133                 : /* -------------------------------------------------------------------- */
    1134               4 :     const char* pszLayerName = NULL;
    1135               4 :     const char* pszColumnName = NULL;
    1136               4 :     char* pszType = NULL;
    1137               4 :     int iTypeIndex = 0;
    1138               4 :     int nTokens = CSLCount(papszTokens);
    1139                 : 
    1140              16 :     if( nTokens >= 8
    1141               2 :         && EQUAL(papszTokens[0],"ALTER")
    1142               2 :         && EQUAL(papszTokens[1],"TABLE")
    1143               2 :         && EQUAL(papszTokens[3],"ALTER")
    1144               2 :         && EQUAL(papszTokens[4],"COLUMN")
    1145               2 :         && EQUAL(papszTokens[6],"TYPE"))
    1146                 :     {
    1147               2 :         pszLayerName = papszTokens[2];
    1148               2 :         pszColumnName = papszTokens[5];
    1149               2 :         iTypeIndex = 7;
    1150                 :     }
    1151              12 :     else if( nTokens >= 7
    1152               2 :              && EQUAL(papszTokens[0],"ALTER")
    1153               2 :              && EQUAL(papszTokens[1],"TABLE")
    1154               2 :              && EQUAL(papszTokens[3],"ALTER")
    1155               2 :              && EQUAL(papszTokens[5],"TYPE"))
    1156                 :     {
    1157               2 :         pszLayerName = papszTokens[2];
    1158               2 :         pszColumnName = papszTokens[4];
    1159               2 :         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               4 :     CPLString osType;
    1177               8 :     for(int i=iTypeIndex;i<nTokens;i++)
    1178                 :     {
    1179               4 :         osType += papszTokens[i];
    1180               4 :         CPLFree(papszTokens[i]);
    1181                 :     }
    1182               4 :     pszType = papszTokens[iTypeIndex] = CPLStrdup(osType);
    1183               4 :     papszTokens[iTypeIndex + 1] = NULL;
    1184                 : 
    1185                 : /* -------------------------------------------------------------------- */
    1186                 : /*      Find the named layer.                                           */
    1187                 : /* -------------------------------------------------------------------- */
    1188               4 :     OGRLayer *poLayer = GetLayerByName(pszLayerName);
    1189               4 :     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               4 :     int nFieldIndex = poLayer->GetLayerDefn()->GetFieldIndex(pszColumnName);
    1204               4 :     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               4 :     OGRFieldDefn* poOldFieldDefn = poLayer->GetLayerDefn()->GetFieldDefn(nFieldIndex);
    1219               4 :     OGRFieldDefn oNewFieldDefn(poOldFieldDefn);
    1220                 : 
    1221               4 :     int nWidth = 0, nPrecision = 0;
    1222               4 :     OGRFieldType eType = OGRDataSourceParseSQLType(pszType, nWidth, nPrecision);
    1223               4 :     oNewFieldDefn.SetType(eType);
    1224               4 :     oNewFieldDefn.SetWidth(nWidth);
    1225               4 :     oNewFieldDefn.SetPrecision(nPrecision);
    1226                 : 
    1227               4 :     int nFlags = 0;
    1228               4 :     if (poOldFieldDefn->GetType() != oNewFieldDefn.GetType())
    1229               2 :         nFlags |= ALTER_TYPE_FLAG;
    1230               4 :     if (poOldFieldDefn->GetWidth() != oNewFieldDefn.GetWidth() ||
    1231                 :         poOldFieldDefn->GetPrecision() != oNewFieldDefn.GetPrecision())
    1232               4 :         nFlags |= ALTER_WIDTH_PRECISION_FLAG;
    1233                 : 
    1234               4 :     CSLDestroy( papszTokens );
    1235                 : 
    1236               4 :     if (nFlags == 0)
    1237               0 :         return OGRERR_NONE;
    1238                 :     else
    1239               4 :         return poLayer->AlterFieldDefn( nFieldIndex, &oNewFieldDefn, nFlags );
    1240                 : }
    1241                 : 
    1242                 : /************************************************************************/
    1243                 : /*                             ExecuteSQL()                             */
    1244                 : /************************************************************************/
    1245                 : 
    1246             820 : OGRLayer * OGRDataSource::ExecuteSQL( const char *pszStatement,
    1247                 :                                       OGRGeometry *poSpatialFilter,
    1248                 :                                       const char *pszDialect )
    1249                 : 
    1250                 : {
    1251             820 :     swq_select *psSelectInfo = NULL;
    1252                 : 
    1253                 :     (void) pszDialect;
    1254                 : 
    1255                 :     swq_field_list sFieldList;
    1256             820 :     int            nFIDIndex = 0;
    1257             820 :     OGRGenSQLResultsLayer *poResults = NULL;
    1258             820 :     char *pszWHERE = NULL;
    1259                 : 
    1260             820 :     memset( &sFieldList, 0, sizeof(sFieldList) );
    1261                 : 
    1262                 : /* -------------------------------------------------------------------- */
    1263                 : /*      Handle CREATE INDEX statements specially.                       */
    1264                 : /* -------------------------------------------------------------------- */
    1265             820 :     if( EQUALN(pszStatement,"CREATE INDEX",12) )
    1266                 :     {
    1267               6 :         ProcessSQLCreateIndex( pszStatement );
    1268               6 :         return NULL;
    1269                 :     }
    1270                 :     
    1271                 : /* -------------------------------------------------------------------- */
    1272                 : /*      Handle DROP INDEX statements specially.                         */
    1273                 : /* -------------------------------------------------------------------- */
    1274             814 :     if( EQUALN(pszStatement,"DROP INDEX",10) )
    1275                 :     {
    1276               2 :         ProcessSQLDropIndex( pszStatement );
    1277               2 :         return NULL;
    1278                 :     }
    1279                 :     
    1280                 : /* -------------------------------------------------------------------- */
    1281                 : /*      Handle DROP TABLE statements specially.                         */
    1282                 : /* -------------------------------------------------------------------- */
    1283             812 :     if( EQUALN(pszStatement,"DROP TABLE",10) )
    1284                 :     {
    1285             500 :         ProcessSQLDropTable( pszStatement );
    1286             500 :         return NULL;
    1287                 :     }
    1288                 : 
    1289                 : /* -------------------------------------------------------------------- */
    1290                 : /*      Handle ALTER TABLE statements specially.                        */
    1291                 : /* -------------------------------------------------------------------- */
    1292             312 :     if( EQUALN(pszStatement,"ALTER TABLE",11) )
    1293                 :     {
    1294              10 :         char **papszTokens = CSLTokenizeString( pszStatement );
    1295              20 :         if( CSLCount(papszTokens) >= 4 &&
    1296              10 :             EQUAL(papszTokens[3],"ADD") )
    1297                 :         {
    1298               2 :             ProcessSQLAlterTableAddColumn( pszStatement );
    1299               2 :             CSLDestroy(papszTokens);
    1300               2 :             return NULL;
    1301                 :         }
    1302              16 :         else if( CSLCount(papszTokens) >= 4 &&
    1303               8 :                  EQUAL(papszTokens[3],"DROP") )
    1304                 :         {
    1305               2 :             ProcessSQLAlterTableDropColumn( pszStatement );
    1306               2 :             CSLDestroy(papszTokens);
    1307               2 :             return NULL;
    1308                 :         }
    1309              12 :         else if( CSLCount(papszTokens) >= 4 &&
    1310               6 :                  EQUAL(papszTokens[3],"RENAME") )
    1311                 :         {
    1312               2 :             ProcessSQLAlterTableRenameColumn( pszStatement );
    1313               2 :             CSLDestroy(papszTokens);
    1314               2 :             return NULL;
    1315                 :         }
    1316               8 :         else if( CSLCount(papszTokens) >= 4 &&
    1317               4 :                  EQUAL(papszTokens[3],"ALTER") )
    1318                 :         {
    1319               4 :             ProcessSQLAlterTableAlterColumn( pszStatement );
    1320               4 :             CSLDestroy(papszTokens);
    1321               4 :             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             302 :     psSelectInfo = new swq_select();
    1337             302 :     if( psSelectInfo->preparse( pszStatement ) != CPLE_None )
    1338                 :     {
    1339              90 :         delete psSelectInfo;
    1340              90 :         return NULL;
    1341                 :     }
    1342                 : 
    1343                 : /* -------------------------------------------------------------------- */
    1344                 : /*      Validate that all the source tables are recognised, count       */
    1345                 : /*      fields.                                                         */
    1346                 : /* -------------------------------------------------------------------- */
    1347             212 :     int  nFieldCount = 0, iTable, iField;
    1348                 :     int  iEDS;
    1349             212 :     int  nExtraDSCount = 0;
    1350             212 :     OGRDataSource** papoExtraDS = NULL;
    1351             212 :     OGRSFDriverRegistrar *poReg=OGRSFDriverRegistrar::GetRegistrar();
    1352                 : 
    1353             440 :     for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ )
    1354                 :     {
    1355             233 :         swq_table_def *psTableDef = psSelectInfo->table_defs + iTable;
    1356                 :         OGRLayer *poSrcLayer;
    1357             233 :         OGRDataSource *poTableDS = this;
    1358                 : 
    1359             233 :         if( psTableDef->data_source != NULL )
    1360                 :         {
    1361                 :             poTableDS = (OGRDataSource *) 
    1362               5 :                 OGROpenShared( psTableDef->data_source, FALSE, NULL );
    1363               5 :             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               5 :                                sizeof(OGRDataSource*) * (nExtraDSCount + 1));
    1378               5 :             papoExtraDS[nExtraDSCount++] = poTableDS;
    1379                 :         }
    1380                 : 
    1381             233 :         poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name );
    1382                 : 
    1383             233 :         if( poSrcLayer == NULL )
    1384                 :         {
    1385                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    1386                 :                       "SELECT from table %s failed, no such table/featureclass.",
    1387               5 :                       psTableDef->table_name );
    1388               5 :             delete psSelectInfo;
    1389               5 :             goto end;
    1390                 :         }
    1391                 : 
    1392             228 :         nFieldCount += poSrcLayer->GetLayerDefn()->GetFieldCount();
    1393                 :     }
    1394                 :     
    1395                 : /* -------------------------------------------------------------------- */
    1396                 : /*      Build the field list for all indicated tables.                  */
    1397                 : /* -------------------------------------------------------------------- */
    1398                 : 
    1399             207 :     sFieldList.table_count = psSelectInfo->table_count;
    1400             207 :     sFieldList.table_defs = psSelectInfo->table_defs;
    1401                 : 
    1402             207 :     sFieldList.count = 0;
    1403             207 :     sFieldList.names = (char **) CPLMalloc( sizeof(char *) * (nFieldCount+SPECIAL_FIELD_COUNT) );
    1404                 :     sFieldList.types = (swq_field_type *)  
    1405             207 :         CPLMalloc( sizeof(swq_field_type) * (nFieldCount+SPECIAL_FIELD_COUNT) );
    1406                 :     sFieldList.table_ids = (int *) 
    1407             207 :         CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) );
    1408                 :     sFieldList.ids = (int *) 
    1409             207 :         CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) );
    1410                 :     
    1411             434 :     for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ )
    1412                 :     {
    1413             227 :         swq_table_def *psTableDef = psSelectInfo->table_defs + iTable;
    1414             227 :         OGRDataSource *poTableDS = this;
    1415                 :         OGRLayer *poSrcLayer;
    1416                 :         
    1417             227 :         if( psTableDef->data_source != NULL )
    1418                 :         {
    1419                 :             poTableDS = (OGRDataSource *) 
    1420               5 :                 OGROpenShared( psTableDef->data_source, FALSE, NULL );
    1421               5 :             CPLAssert( poTableDS != NULL );
    1422               5 :             poTableDS->Dereference();
    1423                 :         }
    1424                 : 
    1425             227 :         poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name );
    1426                 : 
    1427            2526 :         for( iField = 0; 
    1428            1263 :              iField < poSrcLayer->GetLayerDefn()->GetFieldCount();
    1429                 :              iField++ )
    1430                 :         {
    1431            1036 :             OGRFieldDefn *poFDefn=poSrcLayer->GetLayerDefn()->GetFieldDefn(iField);
    1432            1036 :             int iOutField = sFieldList.count++;
    1433            1036 :             sFieldList.names[iOutField] = (char *) poFDefn->GetNameRef();
    1434            1036 :             if( poFDefn->GetType() == OFTInteger )
    1435             342 :                 sFieldList.types[iOutField] = SWQ_INTEGER;
    1436             694 :             else if( poFDefn->GetType() == OFTReal )
    1437             190 :                 sFieldList.types[iOutField] = SWQ_FLOAT;
    1438             504 :             else if( poFDefn->GetType() == OFTString )
    1439             468 :                 sFieldList.types[iOutField] = SWQ_STRING;
    1440                 :             else
    1441              36 :                 sFieldList.types[iOutField] = SWQ_OTHER;
    1442                 : 
    1443            1036 :             sFieldList.table_ids[iOutField] = iTable;
    1444            1036 :             sFieldList.ids[iOutField] = iField;
    1445                 :         }
    1446                 : 
    1447             227 :         if( iTable == 0 )
    1448             207 :             nFIDIndex = poSrcLayer->GetLayerDefn()->GetFieldCount();
    1449                 :     }
    1450                 : 
    1451                 : /* -------------------------------------------------------------------- */
    1452                 : /*      Expand '*' in 'SELECT *' now before we add the pseudo fields    */
    1453                 : /* -------------------------------------------------------------------- */
    1454             207 :     if( psSelectInfo->expand_wildcard( &sFieldList )  != CE_None )
    1455                 :     {
    1456               0 :         delete psSelectInfo;
    1457               0 :         goto end;
    1458                 :     }
    1459                 : 
    1460            1242 :     for (iField = 0; iField < SPECIAL_FIELD_COUNT; iField++)
    1461                 :     {
    1462            1035 :         sFieldList.names[sFieldList.count] = (char*) SpecialFieldNames[iField];
    1463            1035 :         sFieldList.types[sFieldList.count] = SpecialFieldTypes[iField];
    1464            1035 :         sFieldList.table_ids[sFieldList.count] = 0;
    1465            1035 :         sFieldList.ids[sFieldList.count] = nFIDIndex + iField;
    1466            1035 :         sFieldList.count++;
    1467                 :     }
    1468                 :     
    1469                 : /* -------------------------------------------------------------------- */
    1470                 : /*      Finish the parse operation.                                     */
    1471                 : /* -------------------------------------------------------------------- */
    1472             207 :     if( psSelectInfo->parse( &sFieldList, 0 ) != CE_None )
    1473                 :     {
    1474              24 :         delete psSelectInfo;
    1475              24 :         goto end;
    1476                 :     }
    1477                 : 
    1478                 : /* -------------------------------------------------------------------- */
    1479                 : /*      Extract the WHERE expression to use separately.                 */
    1480                 : /* -------------------------------------------------------------------- */
    1481             183 :     if( psSelectInfo->where_expr != NULL )
    1482                 :     {
    1483             156 :         if (m_poDriver && (
    1484              52 :                 EQUAL(m_poDriver->GetName(), "PostgreSQL") ||
    1485              52 :                 EQUAL(m_poDriver->GetName(), "FileGDB" )) )
    1486               0 :             pszWHERE = psSelectInfo->where_expr->Unparse( &sFieldList, '"' );
    1487                 :         else
    1488              52 :             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             183 :                                            pszDialect );
    1500                 : 
    1501             183 :     CPLFree( pszWHERE );
    1502                 : 
    1503                 :     // Eventually, we should keep track of layers to cleanup.
    1504                 : 
    1505                 : end:
    1506             212 :     CPLFree( sFieldList.names );
    1507             212 :     CPLFree( sFieldList.types );
    1508             212 :     CPLFree( sFieldList.table_ids );
    1509             212 :     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             217 :     for(iEDS = 0; iEDS < nExtraDSCount; iEDS++)
    1516               5 :         poReg->ReleaseDataSource( papoExtraDS[iEDS] );
    1517             212 :     CPLFree(papoExtraDS);
    1518                 : 
    1519             212 :     return poResults;
    1520                 : }
    1521                 : 
    1522                 : /************************************************************************/
    1523                 : /*                         OGR_DS_ExecuteSQL()                          */
    1524                 : /************************************************************************/
    1525                 : 
    1526            1399 : OGRLayerH OGR_DS_ExecuteSQL( OGRDataSourceH hDS, 
    1527                 :                              const char *pszStatement,
    1528                 :                              OGRGeometryH hSpatialFilter,
    1529                 :                              const char *pszDialect )
    1530                 : 
    1531                 : {
    1532            1399 :     VALIDATE_POINTER1( hDS, "OGR_DS_ExecuteSQL", NULL );
    1533                 : 
    1534                 :     return (OGRLayerH) 
    1535                 :         ((OGRDataSource *)hDS)->ExecuteSQL( pszStatement,
    1536                 :                                             (OGRGeometry *) hSpatialFilter,
    1537            1399 :                                             pszDialect );
    1538                 : }
    1539                 : 
    1540                 : /************************************************************************/
    1541                 : /*                          ReleaseResultSet()                          */
    1542                 : /************************************************************************/
    1543                 : 
    1544             179 : void OGRDataSource::ReleaseResultSet( OGRLayer * poResultsSet )
    1545                 : 
    1546                 : {
    1547             179 :     delete poResultsSet;
    1548             179 : }
    1549                 : 
    1550                 : /************************************************************************/
    1551                 : /*                      OGR_DS_ReleaseResultSet()                       */
    1552                 : /************************************************************************/
    1553                 : 
    1554             344 : void OGR_DS_ReleaseResultSet( OGRDataSourceH hDS, OGRLayerH hLayer )
    1555                 : 
    1556                 : {
    1557             344 :     VALIDATE_POINTER0( hDS, "OGR_DS_ReleaseResultSet" );
    1558                 : 
    1559             344 :     ((OGRDataSource *) hDS)->ReleaseResultSet( (OGRLayer *) hLayer );
    1560                 : }
    1561                 : 
    1562                 : /************************************************************************/
    1563                 : /*                       OGR_DS_TestCapability()                        */
    1564                 : /************************************************************************/
    1565                 : 
    1566              47 : int OGR_DS_TestCapability( OGRDataSourceH hDS, const char *pszCap )
    1567                 : 
    1568                 : {
    1569              47 :     VALIDATE_POINTER1( hDS, "OGR_DS_TestCapability", 0 );
    1570              47 :     VALIDATE_POINTER1( pszCap, "OGR_DS_TestCapability", 0 );
    1571                 : 
    1572              47 :     return ((OGRDataSource *) hDS)->TestCapability( pszCap );
    1573                 : }
    1574                 : 
    1575                 : /************************************************************************/
    1576                 : /*                        OGR_DS_GetLayerCount()                        */
    1577                 : /************************************************************************/
    1578                 : 
    1579             218 : int OGR_DS_GetLayerCount( OGRDataSourceH hDS )
    1580                 : 
    1581                 : {
    1582             218 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetLayerCount", 0 );
    1583                 : 
    1584             218 :     return ((OGRDataSource *)hDS)->GetLayerCount();
    1585                 : }
    1586                 : 
    1587                 : /************************************************************************/
    1588                 : /*                          OGR_DS_GetLayer()                           */
    1589                 : /************************************************************************/
    1590                 : 
    1591            2437 : OGRLayerH OGR_DS_GetLayer( OGRDataSourceH hDS, int iLayer )
    1592                 : 
    1593                 : {
    1594            2437 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetLayer", NULL );
    1595                 : 
    1596            2437 :     return (OGRLayerH) ((OGRDataSource*)hDS)->GetLayer( iLayer );
    1597                 : }
    1598                 : 
    1599                 : /************************************************************************/
    1600                 : /*                           OGR_DS_GetName()                           */
    1601                 : /************************************************************************/
    1602                 : 
    1603              29 : const char *OGR_DS_GetName( OGRDataSourceH hDS )
    1604                 : 
    1605                 : {
    1606              29 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetName", NULL );
    1607                 : 
    1608              29 :     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            2701 : OGRSFDriver *OGRDataSource::GetDriver() const
    1654                 : 
    1655                 : {
    1656            2701 :     return m_poDriver;
    1657                 : }
    1658                 : 
    1659                 : /************************************************************************/
    1660                 : /*                          OGR_DS_GetDriver()                          */
    1661                 : /************************************************************************/
    1662                 : 
    1663              22 : OGRSFDriverH OGR_DS_GetDriver( OGRDataSourceH hDS )
    1664                 : 
    1665                 : {
    1666              22 :     VALIDATE_POINTER1( hDS, "OGR_DS_GetDriver", NULL );
    1667                 : 
    1668              22 :     return (OGRSFDriverH) ((OGRDataSource *) hDS)->GetDriver();
    1669                 : }
    1670                 : 
    1671                 : /************************************************************************/
    1672                 : /*                             SetDriver()                              */
    1673                 : /************************************************************************/
    1674                 : 
    1675             358 : void OGRDataSource::SetDriver( OGRSFDriver *poDriver ) 
    1676                 : 
    1677                 : {
    1678             358 :     m_poDriver = poDriver;
    1679             358 : }
    1680                 : 
    1681                 : /************************************************************************/
    1682                 : /*                            GetStyleTable()                           */
    1683                 : /************************************************************************/
    1684                 : 
    1685              62 : OGRStyleTable *OGRDataSource::GetStyleTable()
    1686                 : {
    1687              62 :     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              62 : void OGRDataSource::SetStyleTable(OGRStyleTable *poStyleTable)
    1706                 : {
    1707              62 :     if ( m_poStyleTable )
    1708               0 :         delete m_poStyleTable;
    1709              62 :     if ( poStyleTable )
    1710               0 :         m_poStyleTable = poStyleTable->Clone();
    1711              62 : }
    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