~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to ogr/ogrfeaturequery.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: ogrfeaturequery.cpp 20485 2010-08-29 19:59:58Z rouault $
 
2
 * $Id: ogrfeaturequery.cpp 23309 2011-11-03 20:58:33Z rouault $
3
3
 * 
4
4
 * Project:  OpenGIS Simple Features Reference Implementation
5
5
 * Purpose:  Implementation of simple SQL WHERE style attributes queries
29
29
 ****************************************************************************/
30
30
 
31
31
#include <assert.h>
 
32
#include "swq.h"
32
33
#include "ogr_feature.h"
33
34
#include "ogr_p.h"
34
35
#include "ogr_attrind.h"
35
36
 
36
 
CPL_CVSID("$Id: ogrfeaturequery.cpp 20485 2010-08-29 19:59:58Z rouault $");
 
37
CPL_CVSID("$Id: ogrfeaturequery.cpp 23309 2011-11-03 20:58:33Z rouault $");
37
38
 
38
39
/************************************************************************/
39
40
/*     Support for special attributes (feature query and selection)     */
62
63
OGRFeatureQuery::~OGRFeatureQuery()
63
64
 
64
65
{
65
 
    if( pSWQExpr != NULL )
66
 
        swq_expr_free( (swq_expr *) pSWQExpr );
 
66
    delete (swq_expr_node *) pSWQExpr;
67
67
}
68
68
 
69
69
/************************************************************************/
78
78
/*      Clear any existing expression.                                  */
79
79
/* -------------------------------------------------------------------- */
80
80
    if( pSWQExpr != NULL )
81
 
        swq_expr_free( (swq_expr *) pSWQExpr );
 
81
    {
 
82
        delete (swq_expr_node *) pSWQExpr;
 
83
        pSWQExpr = NULL;
 
84
    }
82
85
 
83
86
/* -------------------------------------------------------------------- */
84
87
/*      Build list of fields.                                           */
113
116
            paeFieldTypes[iField] = SWQ_STRING;
114
117
            break;
115
118
 
 
119
          case OFTDate:
 
120
          case OFTTime:
 
121
          case OFTDateTime:
 
122
            paeFieldTypes[iField] = SWQ_TIMESTAMP;
 
123
            break;
 
124
 
116
125
          default:
117
126
            paeFieldTypes[iField] = SWQ_OTHER;
118
127
            break;
130
139
/* -------------------------------------------------------------------- */
131
140
/*      Try to parse.                                                   */
132
141
/* -------------------------------------------------------------------- */
133
 
    const char  *pszError;
134
142
    OGRErr      eErr = OGRERR_NONE;
 
143
    CPLErr      eCPLErr;
135
144
 
136
145
    poTargetDefn = poDefn;
137
 
    pszError = swq_expr_compile( pszExpression, nFieldCount,
138
 
                                 papszFieldNames, paeFieldTypes, 
139
 
                                 (swq_expr **) &pSWQExpr );
140
 
    if( pszError != NULL )
 
146
    eCPLErr = swq_expr_compile( pszExpression, nFieldCount,
 
147
                                papszFieldNames, paeFieldTypes, 
 
148
                                (swq_expr_node **) &pSWQExpr );
 
149
    if( eCPLErr != CE_None )
141
150
    {
142
 
        CPLError( CE_Failure, CPLE_AppDefined, 
143
 
                  "%s", pszError );
144
151
        eErr = OGRERR_CORRUPT_DATA;
145
152
        pSWQExpr = NULL;
146
153
    }
153
160
}
154
161
 
155
162
/************************************************************************/
156
 
/*                      OGRFeatureQueryEvaluator()                      */
 
163
/*                         OGRFeatureFetcher()                          */
157
164
/************************************************************************/
158
165
 
159
 
static int OGRFeatureQueryEvaluator( swq_field_op *op, OGRFeature *poFeature )
 
166
static swq_expr_node *OGRFeatureFetcher( swq_expr_node *op, void *pFeatureIn )
160
167
 
161
168
{
162
 
    OGRField sField;
163
 
    OGRField *psField;
164
 
 
165
 
    int iSpecialField = op->field_index - poFeature->GetDefnRef()->GetFieldCount();
166
 
    if( iSpecialField >= 0 )
167
 
    {
168
 
        if ( iSpecialField < SPECIAL_FIELD_COUNT )
169
 
        {
170
 
            switch ( SpecialFieldTypes[iSpecialField] )
171
 
            {
172
 
              case SWQ_INTEGER:
173
 
                sField.Integer = poFeature->GetFieldAsInteger(op->field_index);
174
 
                break;
175
 
                
176
 
              case SWQ_FLOAT:
177
 
                sField.Real = poFeature->GetFieldAsDouble(op->field_index);
178
 
                break;
179
 
                
180
 
              case SWQ_STRING:
181
 
                sField.String = (char*) 
182
 
                    poFeature->GetFieldAsString( op->field_index );
183
 
                break;
184
 
 
185
 
              default:
186
 
                CPLAssert( FALSE );
187
 
                break;
188
 
            }      
189
 
        }
190
 
        else
191
 
        {
192
 
            CPLDebug( "OGRFeatureQuery", "Illegal special field index.");
193
 
            return FALSE;
194
 
        }
195
 
        psField = &sField;
196
 
    }
197
 
    else
198
 
        psField = poFeature->GetRawFieldRef( op->field_index );
 
169
    OGRFeature *poFeature = (OGRFeature *) pFeatureIn;
 
170
    swq_expr_node *poRetNode = NULL;
199
171
 
200
172
    switch( op->field_type )
201
173
    {
202
174
      case SWQ_INTEGER:
203
 
        switch( op->operation )
204
 
        {
205
 
          case SWQ_EQ:
206
 
            return psField->Integer == op->int_value;
207
 
          case SWQ_NE:
208
 
            return psField->Integer != op->int_value;
209
 
          case SWQ_LT:
210
 
            return psField->Integer < op->int_value;
211
 
          case SWQ_GT:
212
 
            return psField->Integer > op->int_value;
213
 
          case SWQ_LE:
214
 
            return psField->Integer <= op->int_value;
215
 
          case SWQ_GE:
216
 
            return psField->Integer >= op->int_value;
217
 
          case SWQ_ISNULL:
218
 
            return !poFeature->IsFieldSet( op->field_index );
219
 
 
220
 
          case SWQ_IN:
221
 
          {
222
 
              const char *pszSrc;
223
 
              
224
 
              pszSrc = op->string_value;
225
 
              while( *pszSrc != '\0' )
226
 
              {
227
 
                  if( atoi(pszSrc) == psField->Integer )
228
 
                      return TRUE;
229
 
                  pszSrc += strlen(pszSrc) + 1;
230
 
              }
231
 
 
232
 
              return FALSE;
233
 
          }
234
 
 
235
 
          default:
236
 
            CPLDebug( "OGRFeatureQuery", 
237
 
                      "Illegal operation (%d) on integer field.",
238
 
                      op->operation );
239
 
            return FALSE;
240
 
        }
 
175
      case SWQ_BOOLEAN:
 
176
        poRetNode = new swq_expr_node( 
 
177
            poFeature->GetFieldAsInteger(op->field_index) );
 
178
        break;
241
179
 
242
180
      case SWQ_FLOAT:
243
 
        switch( op->operation )
244
 
        {
245
 
          case SWQ_EQ:
246
 
            return psField->Real == op->float_value;
247
 
          case SWQ_NE:
248
 
            return psField->Real != op->float_value;
249
 
          case SWQ_LT:
250
 
            return psField->Real < op->float_value;
251
 
          case SWQ_GT:
252
 
            return psField->Real > op->float_value;
253
 
          case SWQ_LE:
254
 
            return psField->Real <= op->float_value;
255
 
          case SWQ_GE:
256
 
            return psField->Real >= op->float_value;
257
 
          case SWQ_ISNULL:
258
 
            return !poFeature->IsFieldSet( op->field_index );
259
 
          case SWQ_IN:
260
 
          {
261
 
              const char *pszSrc;
262
 
              
263
 
              pszSrc = op->string_value;
264
 
              while( *pszSrc != '\0' )
265
 
              {
266
 
                  if( atof(pszSrc) == psField->Real )
267
 
                      return TRUE;
268
 
                  pszSrc += strlen(pszSrc) + 1;
269
 
              }
270
 
 
271
 
              return FALSE;
272
 
          }
273
 
 
274
 
          default:
275
 
            CPLDebug( "OGRFeatureQuery", 
276
 
                      "Illegal operation (%d) on float field.",
277
 
                      op->operation );
278
 
            return FALSE;
279
 
        }
280
 
 
281
 
      case SWQ_STRING:
282
 
        switch( op->operation )
283
 
        {
284
 
          case SWQ_EQ:
285
 
            if (psField->Set.nMarker1 == OGRUnsetMarker
286
 
                && psField->Set.nMarker2 == OGRUnsetMarker )
287
 
            {
288
 
                return (op->string_value[0] == '\0');
289
 
            }
290
 
            else
291
 
            {
292
 
                return EQUAL(psField->String,op->string_value);
293
 
            }
294
 
          case SWQ_NE:
295
 
            if (psField->Set.nMarker1 == OGRUnsetMarker
296
 
                && psField->Set.nMarker2 == OGRUnsetMarker )
297
 
            {
298
 
                return (op->string_value[0] != '\0');
299
 
            }
300
 
            else
301
 
            {
302
 
                return !EQUAL(psField->String,op->string_value);
303
 
            }
304
 
 
305
 
          case SWQ_LT:
306
 
            if (psField->Set.nMarker1 == OGRUnsetMarker
307
 
                && psField->Set.nMarker2 == OGRUnsetMarker )
308
 
            {
309
 
                return (op->string_value[0] != '\0');
310
 
            }
311
 
            else
312
 
            {
313
 
                return strcmp(psField->String,op->string_value) < 0;
314
 
            }
315
 
          case SWQ_GT:
316
 
            if (psField->Set.nMarker1 == OGRUnsetMarker
317
 
                && psField->Set.nMarker2 == OGRUnsetMarker )
318
 
            {
319
 
                return (op->string_value[0] != '\0');
320
 
            }
321
 
            else
322
 
            {
323
 
                return strcmp(psField->String,op->string_value) > 0;
324
 
            }
325
 
          case SWQ_LE:
326
 
            if (psField->Set.nMarker1 == OGRUnsetMarker
327
 
                && psField->Set.nMarker2 == OGRUnsetMarker )
328
 
            {
329
 
                return (op->string_value[0] != '\0');
330
 
            }
331
 
            else
332
 
            {
333
 
                return strcmp(psField->String,op->string_value) <= 0;
334
 
            }
335
 
          case SWQ_GE:
336
 
            if (psField->Set.nMarker1 == OGRUnsetMarker
337
 
                && psField->Set.nMarker2 == OGRUnsetMarker )
338
 
            {
339
 
                return (op->string_value[0] != '\0');
340
 
            }
341
 
            else
342
 
            {
343
 
                return strcmp(psField->String,op->string_value) >= 0;
344
 
            }
345
 
 
346
 
          case SWQ_ISNULL:
347
 
            return !poFeature->IsFieldSet( op->field_index );
348
 
 
349
 
          case SWQ_LIKE:
350
 
            if (psField->Set.nMarker1 != OGRUnsetMarker
351
 
                || psField->Set.nMarker2 != OGRUnsetMarker )
352
 
                return swq_test_like(psField->String, op->string_value);
353
 
            else
354
 
                return FALSE;
355
 
 
356
 
          case SWQ_IN:
357
 
          {
358
 
              const char *pszSrc;
359
 
 
360
 
              if( !poFeature->IsFieldSet(op->field_index) )
361
 
                  return FALSE;
362
 
              
363
 
              pszSrc = op->string_value;
364
 
              while( *pszSrc != '\0' )
365
 
              {
366
 
                  if( EQUAL(pszSrc,psField->String) )
367
 
                      return TRUE;
368
 
                  pszSrc += strlen(pszSrc) + 1;
369
 
              }
370
 
 
371
 
              return FALSE;
372
 
          }
373
 
 
374
 
          default:
375
 
            CPLDebug( "OGRFeatureQuery", 
376
 
                      "Illegal operation (%d) on string field.",
377
 
                      op->operation );
378
 
            return FALSE;
379
 
        }
380
 
 
381
 
      case SWQ_OTHER:
382
 
        switch( op->operation )
383
 
        {
384
 
          case SWQ_ISNULL:
385
 
            return !poFeature->IsFieldSet( op->field_index );
386
 
 
387
 
          default:
388
 
            CPLDebug( "OGRFeatureQuery", 
389
 
                      "Illegal operation (%d) on list or binary field.",
390
 
                      op->operation );
391
 
            return FALSE;
392
 
        }
393
 
 
 
181
        poRetNode = new swq_expr_node( 
 
182
            poFeature->GetFieldAsDouble(op->field_index) );
 
183
        break;
 
184
        
394
185
      default:
395
 
        assert( FALSE );
396
 
        return FALSE;
 
186
        poRetNode = new swq_expr_node( 
 
187
            poFeature->GetFieldAsString(op->field_index) );
 
188
        break;
397
189
    }
 
190
 
 
191
    poRetNode->is_null = !(poFeature->IsFieldSet(op->field_index));
 
192
 
 
193
    return poRetNode;
398
194
}
399
195
 
400
196
/************************************************************************/
407
203
    if( pSWQExpr == NULL )
408
204
        return FALSE;
409
205
 
410
 
    return swq_expr_evaluate( (swq_expr *) pSWQExpr, 
411
 
                              (swq_op_evaluator) OGRFeatureQueryEvaluator, 
412
 
                              (void *) poFeature );
 
206
    swq_expr_node *poResult;
 
207
 
 
208
    poResult = ((swq_expr_node *) pSWQExpr)->Evaluate( OGRFeatureFetcher,
 
209
                                                       (void *) poFeature );
 
210
 
 
211
    if( poResult == NULL )
 
212
        return FALSE;
 
213
 
 
214
    CPLAssert( poResult->field_type == SWQ_BOOLEAN );
 
215
 
 
216
    int bLogicalResult = poResult->int_value;
 
217
 
 
218
    delete poResult;
 
219
 
 
220
    return bLogicalResult;
413
221
}
414
222
 
415
223
/************************************************************************/
428
236
 
429
237
static int CompareLong(const void *a, const void *b)
430
238
{
431
 
    return (*(const long *)a) - (*(const long *)b);
 
239
        return (*(const long *)a) - (*(const long *)b);
432
240
}
433
241
 
434
242
long *OGRFeatureQuery::EvaluateAgainstIndices( OGRLayer *poLayer, 
435
243
                                               OGRErr *peErr )
436
244
 
437
245
{
438
 
    swq_expr *psExpr = (swq_expr *) pSWQExpr;
 
246
    swq_expr_node *psExpr = (swq_expr_node *) pSWQExpr;
439
247
    OGRAttrIndex *poIndex;
440
248
 
441
249
    if( peErr != NULL )
445
253
/*      Does the expression meet our requirements?  Do we have an       */
446
254
/*      index on the targetted field?                                   */
447
255
/* -------------------------------------------------------------------- */
448
 
    if( psExpr == NULL || psExpr->operation != SWQ_EQ 
449
 
        || poLayer->GetIndex() == NULL )
450
 
        return NULL;
451
 
 
452
 
    poIndex = poLayer->GetIndex()->GetFieldIndex( psExpr->field_index );
 
256
    if( psExpr == NULL 
 
257
        || psExpr->eNodeType != SNT_OPERATION
 
258
        || !(psExpr->nOperation == SWQ_EQ || psExpr->nOperation == SWQ_IN) 
 
259
        || poLayer->GetIndex() == NULL
 
260
        || psExpr->nSubExprCount < 2 )
 
261
        return NULL;
 
262
 
 
263
    swq_expr_node *poColumn = psExpr->papoSubExpr[0];
 
264
    swq_expr_node *poValue = psExpr->papoSubExpr[1];
 
265
    
 
266
    if( poColumn->eNodeType != SNT_COLUMN
 
267
        || poValue->eNodeType != SNT_CONSTANT )
 
268
        return NULL;
 
269
 
 
270
    poIndex = poLayer->GetIndex()->GetFieldIndex( poColumn->field_index );
453
271
    if( poIndex == NULL )
454
272
        return NULL;
455
273
 
459
277
    OGRField sValue;
460
278
    OGRFieldDefn *poFieldDefn;
461
279
 
462
 
    poFieldDefn = poLayer->GetLayerDefn()->GetFieldDefn(psExpr->field_index);
463
 
 
 
280
    poFieldDefn = poLayer->GetLayerDefn()->GetFieldDefn(poColumn->field_index);
 
281
 
 
282
/* -------------------------------------------------------------------- */
 
283
/*      Handle the case of an IN operation.                             */
 
284
/* -------------------------------------------------------------------- */
 
285
    if (psExpr->nOperation == SWQ_IN)
 
286
    {
 
287
        int nFIDCount = 0, nLength;
 
288
        long *panFIDs = NULL;
 
289
        int iIN;
 
290
 
 
291
        for( iIN = 1; iIN < psExpr->nSubExprCount; iIN++ )
 
292
        {
 
293
            switch( poFieldDefn->GetType() )
 
294
            {
 
295
              case OFTInteger:
 
296
                if (psExpr->papoSubExpr[iIN]->field_type == SWQ_FLOAT)
 
297
                    sValue.Integer = (int) psExpr->papoSubExpr[iIN]->float_value;
 
298
                else
 
299
                    sValue.Integer = psExpr->papoSubExpr[iIN]->int_value;
 
300
                break;
 
301
 
 
302
              case OFTReal:
 
303
                sValue.Real = psExpr->papoSubExpr[iIN]->float_value;
 
304
                break;
 
305
 
 
306
              case OFTString:
 
307
                sValue.String = psExpr->papoSubExpr[iIN]->string_value;
 
308
                break;
 
309
 
 
310
              default:
 
311
                CPLAssert( FALSE );
 
312
                return NULL;
 
313
            }
 
314
 
 
315
            panFIDs = poIndex->GetAllMatches( &sValue, panFIDs, &nFIDCount, &nLength );
 
316
        }
 
317
 
 
318
        if (nFIDCount > 1)
 
319
        {
 
320
            /* the returned FIDs are expected to be in sorted order */
 
321
            qsort(panFIDs, nFIDCount, sizeof(long), CompareLong);
 
322
        }
 
323
        return panFIDs;
 
324
    }
 
325
 
 
326
/* -------------------------------------------------------------------- */
 
327
/*      Handle equality test.                                           */
 
328
/* -------------------------------------------------------------------- */
464
329
    switch( poFieldDefn->GetType() )
465
330
    {
466
331
      case OFTInteger:
467
 
        sValue.Integer = psExpr->int_value;
 
332
        if (poValue->field_type == SWQ_FLOAT)
 
333
            sValue.Integer = (int) poValue->float_value;
 
334
        else
 
335
            sValue.Integer = poValue->int_value;
468
336
        break;
469
 
 
 
337
        
470
338
      case OFTReal:
471
 
        sValue.Real = psExpr->float_value;
 
339
        sValue.Real = poValue->float_value;
472
340
        break;
473
 
 
 
341
        
474
342
      case OFTString:
475
 
        sValue.String = psExpr->string_value;
 
343
        sValue.String = poValue->string_value;
476
344
        break;
477
345
 
478
346
      default:
480
348
        return NULL;
481
349
    }
482
350
 
483
 
    long *panFIDs = poIndex->GetAllMatches( &sValue );
484
 
    int nFIDCount = 0;
485
 
    for( nFIDCount = 0; panFIDs[nFIDCount] != OGRNullFID; nFIDCount++ )
486
 
    {
487
 
        ;
488
 
    }
 
351
    int nFIDCount = 0, nLength = 0;
 
352
    long *panFIDs = poIndex->GetAllMatches( &sValue, NULL, &nFIDCount, &nLength );
489
353
    if (nFIDCount > 1)
490
354
    {
491
355
        /* the returned FIDs are expected to be in sorted order */
505
369
                                        char **papszList )
506
370
 
507
371
{
508
 
    swq_field_op *op = (swq_field_op *) pBareOp;
 
372
    swq_expr_node *op = (swq_expr_node *) pBareOp;
509
373
 
510
374
/* -------------------------------------------------------------------- */
511
375
/*      References to tables other than the primarily are currently     */
512
376
/*      unsupported. Error out.                                         */
513
377
/* -------------------------------------------------------------------- */
514
 
    if( op->table_index != 0 )
 
378
    if( op->eNodeType == SNT_COLUMN )
515
379
    {
516
 
        CSLDestroy( papszList );
517
 
        return NULL;
518
 
    }
 
380
        if( op->table_index != 0 )
 
381
        {
 
382
            CSLDestroy( papszList );
 
383
            return NULL;
 
384
        }
519
385
 
520
386
/* -------------------------------------------------------------------- */
521
387
/*      Add the field name into our list if it is not already there.    */
522
388
/* -------------------------------------------------------------------- */
523
 
    const char *pszFieldName;
 
389
        const char *pszFieldName;
524
390
 
525
 
    if( op->field_index >= poTargetDefn->GetFieldCount()
526
 
        && op->field_index < poTargetDefn->GetFieldCount() + SPECIAL_FIELD_COUNT) 
527
 
        pszFieldName = SpecialFieldNames[op->field_index];
528
 
    else if( op->field_index >= 0 
529
 
             && op->field_index < poTargetDefn->GetFieldCount() )
530
 
        pszFieldName = 
531
 
            poTargetDefn->GetFieldDefn(op->field_index)->GetNameRef();
532
 
    else
533
 
    {
534
 
        CSLDestroy( papszList );
535
 
        return NULL;
 
391
        if( op->field_index >= poTargetDefn->GetFieldCount()
 
392
            && op->field_index < poTargetDefn->GetFieldCount() + SPECIAL_FIELD_COUNT) 
 
393
            pszFieldName = SpecialFieldNames[op->field_index];
 
394
        else if( op->field_index >= 0 
 
395
                 && op->field_index < poTargetDefn->GetFieldCount() )
 
396
            pszFieldName = 
 
397
                poTargetDefn->GetFieldDefn(op->field_index)->GetNameRef();
 
398
        else
 
399
        {
 
400
            CSLDestroy( papszList );
 
401
            return NULL;
 
402
        }
 
403
        
 
404
        if( CSLFindString( papszList, pszFieldName ) == -1 )
 
405
            papszList = CSLAddString( papszList, pszFieldName );
536
406
    }
537
407
 
538
 
    if( CSLFindString( papszList, pszFieldName ) == -1 )
539
 
        papszList = CSLAddString( papszList, pszFieldName );
540
 
 
541
408
/* -------------------------------------------------------------------- */
542
409
/*      Add in fields from subexpressions.                              */
543
410
/* -------------------------------------------------------------------- */
544
 
    if( op->first_sub_expr != NULL )
545
 
        papszList = FieldCollector( op->first_sub_expr, papszList );
546
 
    if( op->second_sub_expr != NULL )
547
 
        papszList = FieldCollector( op->second_sub_expr, papszList );
 
411
    if( op->eNodeType == SNT_OPERATION )
 
412
    {
 
413
        for( int iSubExpr = 0; iSubExpr < op->nSubExprCount; iSubExpr++ )
 
414
        {
 
415
            papszList = FieldCollector( op->papoSubExpr[iSubExpr], papszList );
 
416
        }
 
417
    }
548
418
 
549
419
    return papszList;
550
420
}