LCOV - code coverage report
Current view: directory - ogr - swq.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 294 266 90.5 %
Date: 2012-04-28 Functions: 11 10 90.9 %

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Component: OGDI Driver Support Library
       4                 :  * Purpose: Generic SQL WHERE Expression Implementation.
       5                 :  * Author: Frank Warmerdam <warmerdam@pobox.com>
       6                 :  * 
       7                 :  ******************************************************************************
       8                 :  * Copyright (C) 2001 Information Interoperability Institute (3i)
       9                 :  *
      10                 :  * Permission to use, copy, modify and distribute this software and
      11                 :  * its documentation for any purpose and without fee is hereby granted,
      12                 :  * provided that the above copyright notice appear in all copies, that
      13                 :  * both the copyright notice and this permission notice appear in
      14                 :  * supporting documentation, and that the name of 3i not be used 
      15                 :  * in advertising or publicity pertaining to distribution of the software 
      16                 :  * without specific, written prior permission.  3i makes no
      17                 :  * representations about the suitability of this software for any purpose.
      18                 :  * It is provided "as is" without express or implied warranty.
      19                 :  ****************************************************************************/
      20                 : 
      21                 : #include <ctype.h>
      22                 : 
      23                 : #include "cpl_conv.h"
      24                 : #include "cpl_multiproc.h"
      25                 : #include "swq.h"
      26                 : #include "swq_parser.hpp"
      27                 : 
      28                 : #define YYSTYPE  swq_expr_node*
      29                 : 
      30                 : /************************************************************************/
      31                 : /*                               swqlex()                               */
      32                 : /*                                                                      */
      33                 : /*      Read back a token from the input.                               */
      34                 : /************************************************************************/
      35                 : 
      36           22288 : int swqlex( YYSTYPE *ppNode, swq_parse_context *context )
      37                 : {
      38           22288 :     const char *pszInput = context->pszNext;
      39                 : 
      40           22288 :     *ppNode = NULL;
      41                 : 
      42                 : /* -------------------------------------------------------------------- */
      43                 : /*      Do we have a start symbol to return?                            */
      44                 : /* -------------------------------------------------------------------- */
      45           22288 :     if( context->nStartToken != 0 )
      46                 :     {
      47            1884 :         int nRet = context->nStartToken;
      48            1884 :         context->nStartToken = 0;
      49            1884 :         return nRet;
      50                 :     }
      51                 : 
      52                 : /* -------------------------------------------------------------------- */
      53                 : /*      Skip white space.                                               */
      54                 : /* -------------------------------------------------------------------- */
      55           49668 :     while( *pszInput == ' ' || *pszInput == '\t'
      56                 :            || *pszInput == 10 || *pszInput == 13 )
      57            8860 :         pszInput++;
      58                 : 
      59           20404 :     if( *pszInput == '\0' )
      60                 :     {
      61            1792 :         context->pszNext = pszInput;
      62            1792 :         return EOF; 
      63                 :     }
      64                 : 
      65                 : /* -------------------------------------------------------------------- */
      66                 : /*      Handle string constants.                                        */
      67                 : /* -------------------------------------------------------------------- */
      68           18612 :     if( *pszInput == '"' || *pszInput == '\'' )
      69                 :     {
      70                 :         char *token;
      71                 :         int i_token;
      72                 : 
      73             726 :         pszInput++;
      74                 : 
      75             726 :         token = (char *) CPLMalloc(strlen(pszInput)+1);
      76             726 :         i_token = 0;
      77                 : 
      78            5780 :         while( *pszInput != '\0' )
      79                 :         {
      80            5052 :             if( *pszInput == '\\' && pszInput[1] == '"' )
      81               0 :                 pszInput++;
      82            5052 :             else if( *pszInput == '\\' && pszInput[1] == '\'' )
      83               0 :                 pszInput++;
      84            5052 :             else if( *pszInput == '\'' && pszInput[1] == '\'' )
      85               0 :                 pszInput++;
      86            5052 :             else if( *pszInput == '"' )
      87                 :             {
      88              60 :                 pszInput++;
      89              60 :                 break;
      90                 :             }
      91            4992 :             else if( *pszInput == '\'' )
      92                 :             {
      93             664 :                 pszInput++;
      94             664 :                 break;
      95                 :             }
      96                 :             
      97            4328 :             token[i_token++] = *(pszInput++);
      98                 :         }
      99             726 :         token[i_token] = '\0';
     100                 : 
     101             726 :         *ppNode = new swq_expr_node( token );
     102             726 :         CPLFree( token );
     103                 : 
     104             726 :         context->pszNext = pszInput;
     105                 : 
     106             726 :         return SWQT_STRING;
     107                 :     }
     108                 : 
     109                 : /* -------------------------------------------------------------------- */
     110                 : /*      Handle numbers.                                                 */
     111                 : /* -------------------------------------------------------------------- */
     112           17886 :     else if( *pszInput >= '0' && *pszInput <= '9' )
     113                 :     {
     114            1910 :         CPLString osToken;
     115            1910 :         const char *pszNext = pszInput + 1;
     116                 : 
     117            1910 :         osToken += *pszInput;
     118                 : 
     119                 :         // collect non-decimal part of number
     120            4762 :         while( *pszNext >= '0' && *pszNext <= '9' )
     121             942 :             osToken += *(pszNext++);
     122                 : 
     123                 :         // collect decimal places.
     124            1910 :         if( *pszNext == '.' )
     125                 :         {
     126             578 :             osToken += *(pszNext++);
     127            1270 :             while( *pszNext >= '0' && *pszNext <= '9' )
     128             114 :                 osToken += *(pszNext++);
     129                 :         }
     130                 : 
     131                 :         // collect exponent
     132            1910 :         if( *pszNext == 'e' || *pszNext == 'E' )
     133                 :         {
     134               2 :             osToken += *(pszNext++);
     135               2 :             if( *pszNext == '-' || *pszNext == '+' )
     136               2 :                 osToken += *(pszNext++);
     137               6 :             while( *pszNext >= '0' && *pszNext <= '9' )
     138               2 :                 osToken += *(pszNext++);
     139                 :         }
     140                 : 
     141            1910 :         context->pszNext = pszNext;
     142                 : 
     143            1910 :         if( strstr(osToken,".") 
     144                 :             || strstr(osToken,"e") 
     145                 :             || strstr(osToken,"E") )
     146                 :         {
     147             580 :             *ppNode = new swq_expr_node( CPLAtof(osToken) );
     148                 :         }
     149                 :         else
     150                 :         {
     151            1330 :             *ppNode = new swq_expr_node( atoi(osToken) );
     152                 :         }
     153                 : 
     154            1910 :         return SWQT_NUMBER;
     155                 :     }
     156                 : 
     157                 : /* -------------------------------------------------------------------- */
     158                 : /*      Handle alpha-numerics.                                          */
     159                 : /* -------------------------------------------------------------------- */
     160           15976 :     else if( isalnum( *pszInput ) )
     161                 :     {
     162            8746 :         int nReturn = SWQT_IDENTIFIER;
     163            8746 :         CPLString osToken;
     164            8746 :         const char *pszNext = pszInput + 1;
     165                 : 
     166            8746 :         osToken += *pszInput;
     167                 : 
     168                 :         // collect text characters
     169           49468 :         while( isalnum( *pszNext ) || *pszNext == '_' 
     170                 :                || ((unsigned char) *pszNext) > 127 )
     171           31976 :             osToken += *(pszNext++);
     172                 : 
     173            8746 :         context->pszNext = pszNext;
     174                 : 
     175            8746 :         if( EQUAL(osToken,"IN") )
     176              96 :             nReturn = SWQT_IN;
     177            8650 :         else if( EQUAL(osToken,"LIKE") )
     178              22 :             nReturn = SWQT_LIKE;
     179            8628 :         else if( EQUAL(osToken,"ILIKE") )
     180               2 :             nReturn = SWQT_LIKE;
     181            8626 :         else if( EQUAL(osToken,"ESCAPE") )
     182               4 :             nReturn = SWQT_ESCAPE;
     183            8622 :         else if( EQUAL(osToken,"NULL") )
     184              28 :             nReturn = SWQT_NULL;
     185            8594 :         else if( EQUAL(osToken,"IS") )
     186              26 :             nReturn = SWQT_IS;
     187            8568 :         else if( EQUAL(osToken,"NOT") )
     188              30 :             nReturn = SWQT_NOT;
     189            8538 :         else if( EQUAL(osToken,"AND") )
     190             548 :             nReturn = SWQT_AND;
     191            7990 :         else if( EQUAL(osToken,"OR") )
     192              12 :             nReturn = SWQT_OR;
     193            7978 :         else if( EQUAL(osToken,"BETWEEN") )
     194              68 :             nReturn = SWQT_BETWEEN;
     195            7910 :         else if( EQUAL(osToken,"SELECT") )
     196             886 :             nReturn = SWQT_SELECT;
     197            7024 :         else if( EQUAL(osToken,"LEFT") )
     198              50 :             nReturn = SWQT_LEFT;
     199            6974 :         else if( EQUAL(osToken,"JOIN") )
     200              52 :             nReturn = SWQT_JOIN;
     201            6922 :         else if( EQUAL(osToken,"WHERE") )
     202             402 :             nReturn = SWQT_WHERE;
     203            6520 :         else if( EQUAL(osToken,"ON") )
     204              48 :             nReturn = SWQT_ON;
     205            6472 :         else if( EQUAL(osToken,"ORDER") )
     206              52 :             nReturn = SWQT_ORDER;
     207            6420 :         else if( EQUAL(osToken,"BY") )
     208              52 :             nReturn = SWQT_BY;
     209            6368 :         else if( EQUAL(osToken,"FROM") )
     210             816 :             nReturn = SWQT_FROM;
     211            5552 :         else if( EQUAL(osToken,"AS") )
     212             106 :             nReturn = SWQT_AS;
     213            5446 :         else if( EQUAL(osToken,"ASC") )
     214              22 :             nReturn = SWQT_ASC;
     215            5424 :         else if( EQUAL(osToken,"DESC") )
     216              18 :             nReturn = SWQT_DESC;
     217            5406 :         else if( EQUAL(osToken,"DISTINCT") )
     218              62 :             nReturn = SWQT_DISTINCT;
     219            5344 :         else if( EQUAL(osToken,"CAST") )
     220              86 :             nReturn = SWQT_CAST;
     221                 :         else
     222                 :         {
     223            5258 :             *ppNode = new swq_expr_node( osToken );
     224            5258 :             nReturn = SWQT_IDENTIFIER;
     225                 :         }
     226                 : 
     227            8746 :         return nReturn;
     228                 :     }
     229                 : 
     230                 : /* -------------------------------------------------------------------- */
     231                 : /*      Handle special tokens.                                          */
     232                 : /* -------------------------------------------------------------------- */
     233                 :     else
     234                 :     {
     235            7230 :         context->pszNext = pszInput+1;
     236            7230 :         return *pszInput;
     237                 :     }
     238                 : }
     239                 : 
     240                 : /************************************************************************/
     241                 : /*                        swq_select_summarize()                        */
     242                 : /************************************************************************/
     243                 : 
     244                 : const char *
     245             524 : swq_select_summarize( swq_select *select_info, 
     246                 :                       int dest_column, const char *value )
     247                 : 
     248                 : {
     249             524 :     swq_col_def *def = select_info->column_defs + dest_column;
     250                 :     swq_summary *summary;
     251                 : 
     252                 : /* -------------------------------------------------------------------- */
     253                 : /*      Do various checking.                                            */
     254                 : /* -------------------------------------------------------------------- */
     255             524 :     if( select_info->query_mode == SWQM_RECORDSET )
     256               0 :         return "swq_select_summarize() called on non-summary query.";
     257                 : 
     258             524 :     if( dest_column < 0 || dest_column >= select_info->result_columns )
     259               0 :         return "dest_column out of range in swq_select_summarize().";
     260                 : 
     261             524 :     if( def->col_func == SWQCF_NONE && !def->distinct_flag )
     262               0 :         return NULL;
     263                 : 
     264                 : /* -------------------------------------------------------------------- */
     265                 : /*      Create the summary information if this is the first row         */
     266                 : /*      being processed.                                                */
     267                 : /* -------------------------------------------------------------------- */
     268             524 :     if( select_info->column_summary == NULL && value != NULL )
     269                 :     {
     270                 :         int i;
     271                 : 
     272                 :         select_info->column_summary = (swq_summary *) 
     273              42 :             CPLMalloc(sizeof(swq_summary) * select_info->result_columns);
     274                 :         memset( select_info->column_summary, 0, 
     275              42 :                 sizeof(swq_summary) * select_info->result_columns );
     276                 : 
     277             100 :         for( i = 0; i < select_info->result_columns; i++ )
     278                 :         {
     279              58 :             select_info->column_summary[i].min = 1e20;
     280              58 :             select_info->column_summary[i].max = -1e20;
     281                 :         }
     282                 :     }
     283                 : 
     284             524 :     if( select_info->column_summary == NULL )
     285              16 :         return NULL;
     286                 : 
     287                 : /* -------------------------------------------------------------------- */
     288                 : /*      If distinct processing is on, process that now.                 */
     289                 : /* -------------------------------------------------------------------- */
     290             508 :     summary = select_info->column_summary + dest_column;
     291                 :     
     292             508 :     if( def->distinct_flag )
     293                 :     {
     294                 :         int  i;
     295                 : 
     296                 :         /* This should be implemented with a much more complicated
     297                 :            data structure to achieve any sort of efficiency. */
     298            1608 :         for( i = 0; i < summary->count; i++ )
     299                 :         {
     300            1472 :             if( value == NULL )
     301                 :             {
     302             186 :                 if (summary->distinct_list[i] == NULL)
     303              12 :                     break;
     304                 :             }
     305            2572 :             else if( summary->distinct_list[i] != NULL &&
     306            1286 :                      strcmp(value,summary->distinct_list[i]) == 0 )
     307             250 :                 break;
     308                 :         }
     309                 :         
     310             398 :         if( i == summary->count )
     311                 :         {
     312             136 :             char  **old_list = summary->distinct_list;
     313                 :             
     314                 :             summary->distinct_list = (char **) 
     315             136 :                 CPLMalloc(sizeof(char *) * (summary->count+1));
     316                 :             memcpy( summary->distinct_list, old_list, 
     317             136 :                     sizeof(char *) * summary->count );
     318             272 :             summary->distinct_list[(summary->count)++] = 
     319             136 :                 (value != NULL) ? CPLStrdup( value ) : NULL;
     320                 : 
     321             136 :             CPLFree(old_list);
     322                 :         }
     323                 :     }
     324                 : 
     325                 : /* -------------------------------------------------------------------- */
     326                 : /*      Process various options.                                        */
     327                 : /* -------------------------------------------------------------------- */
     328                 : 
     329             508 :     switch( def->col_func )
     330                 :     {
     331                 :       case SWQCF_MIN:
     332              20 :         if( value != NULL && value[0] != '\0' )
     333                 :         {
     334              20 :             double df_val = CPLAtof(value);
     335              20 :             if( df_val < summary->min )
     336               6 :                 summary->min = df_val;
     337                 :         }
     338              20 :         break;
     339                 :       case SWQCF_MAX:
     340              34 :         if( value != NULL && value[0] != '\0' )
     341                 :         {
     342              34 :             double df_val = CPLAtof(value);
     343              34 :             if( df_val > summary->max )
     344              14 :                 summary->max = df_val;
     345                 :         }
     346              34 :         break;
     347                 :       case SWQCF_AVG:
     348                 :       case SWQCF_SUM:
     349               0 :         if( value != NULL && value[0] != '\0' )
     350                 :         {
     351               0 :             summary->count++;
     352               0 :             summary->sum += CPLAtof(value);
     353                 :         }
     354               0 :         break;
     355                 : 
     356                 :       case SWQCF_COUNT:
     357              80 :         if( value != NULL && !def->distinct_flag )
     358              56 :             summary->count++;
     359              80 :         break;
     360                 : 
     361                 :       case SWQCF_NONE:
     362             374 :         break;
     363                 : 
     364                 :       case SWQCF_CUSTOM:
     365               0 :         return "swq_select_summarize() called on custom field function.";
     366                 : 
     367                 :       default:
     368               0 :         return "swq_select_summarize() - unexpected col_func";
     369                 :     }
     370                 : 
     371             508 :     return NULL;
     372                 : }
     373                 : /************************************************************************/
     374                 : /*                      sort comparison functions.                      */
     375                 : /************************************************************************/
     376                 : 
     377             104 : static int FORCE_CDECL swq_compare_int( const void *item1, const void *item2 )
     378                 : {
     379                 :     int  v1, v2;
     380                 : 
     381             104 :     const char* pszStr1 = *((const char **) item1);
     382             104 :     const char* pszStr2 = *((const char **) item2);
     383             104 :     if (pszStr1 == NULL)
     384               0 :         return (pszStr2 == NULL) ? 0 : -1;
     385             104 :     else if (pszStr2 == NULL)
     386              20 :         return 1;
     387                 : 
     388              84 :     v1 = atoi(pszStr1);
     389              84 :     v2 = atoi(pszStr2);
     390                 : 
     391              84 :     if( v1 < v2 )
     392              32 :         return -1;
     393              52 :     else if( v1 == v2 )
     394               0 :         return 0;
     395                 :     else
     396              52 :         return 1;
     397                 : }
     398                 : 
     399              50 : static int FORCE_CDECL swq_compare_real( const void *item1, const void *item2 )
     400                 : {
     401                 :     double  v1, v2;
     402                 : 
     403              50 :     const char* pszStr1 = *((const char **) item1);
     404              50 :     const char* pszStr2 = *((const char **) item2);
     405              50 :     if (pszStr1 == NULL)
     406               0 :         return (pszStr2 == NULL) ? 0 : -1;
     407              50 :     else if (pszStr2 == NULL)
     408               4 :         return 1;
     409                 : 
     410              46 :     v1 = CPLAtof(pszStr1);
     411              46 :     v2 = CPLAtof(pszStr2);
     412                 : 
     413              46 :     if( v1 < v2 )
     414              18 :         return -1;
     415              28 :     else if( v1 == v2 )
     416               0 :         return 0;
     417                 :     else
     418              28 :         return 1;
     419                 : }
     420                 : 
     421              28 : static int FORCE_CDECL swq_compare_string( const void *item1, const void *item2 )
     422                 : {
     423              28 :     const char* pszStr1 = *((const char **) item1);
     424              28 :     const char* pszStr2 = *((const char **) item2);
     425              28 :     if (pszStr1 == NULL)
     426               0 :         return (pszStr2 == NULL) ? 0 : -1;
     427              28 :     else if (pszStr2 == NULL)
     428               4 :         return 1;
     429                 : 
     430              24 :     return strcmp( pszStr1, pszStr2 );
     431                 : }
     432                 : 
     433                 : /************************************************************************/
     434                 : /*                    swq_select_finish_summarize()                     */
     435                 : /*                                                                      */
     436                 : /*      Call to complete summarize work.  Does stuff like ordering      */
     437                 : /*      the distinct list for instance.                                 */
     438                 : /************************************************************************/
     439                 : 
     440              54 : const char *swq_select_finish_summarize( swq_select *select_info )
     441                 : 
     442                 : {
     443                 :     int (FORCE_CDECL *compare_func)(const void *, const void*);
     444              54 :     int count = 0;
     445              54 :     char **distinct_list = NULL;
     446                 : 
     447              54 :     if( select_info->query_mode != SWQM_DISTINCT_LIST 
     448                 :         || select_info->order_specs == 0 )
     449              32 :         return NULL;
     450                 : 
     451              22 :     if( select_info->order_specs > 1 )
     452               0 :         return "Can't ORDER BY a DISTINCT list by more than one key.";
     453                 : 
     454              44 :     if( select_info->order_defs[0].field_index != 
     455              22 :         select_info->column_defs[0].field_index )
     456               0 :         return "Only selected DISTINCT field can be used for ORDER BY.";
     457                 : 
     458              22 :     if( select_info->column_summary == NULL )
     459               0 :         return NULL;
     460                 : 
     461              22 :     if( select_info->column_defs[0].field_type == SWQ_INTEGER )
     462               8 :         compare_func = swq_compare_int;
     463              14 :     else if( select_info->column_defs[0].field_type == SWQ_FLOAT )
     464               8 :         compare_func = swq_compare_real;
     465                 :     else
     466               6 :         compare_func = swq_compare_string;
     467                 : 
     468              22 :     distinct_list = select_info->column_summary[0].distinct_list;
     469              22 :     count = select_info->column_summary[0].count;
     470                 : 
     471              22 :     qsort( distinct_list, count, sizeof(char *), compare_func );
     472                 : 
     473                 : /* -------------------------------------------------------------------- */
     474                 : /*      Do we want the list ascending in stead of descending?           */
     475                 : /* -------------------------------------------------------------------- */
     476              22 :     if( !select_info->order_defs[0].ascending_flag )
     477                 :     {
     478                 :         char *saved;
     479                 :         int i;
     480                 : 
     481              42 :         for( i = 0; i < count/2; i++ )
     482                 :         {
     483              30 :             saved = distinct_list[i];
     484              30 :             distinct_list[i] = distinct_list[count-i-1];
     485              30 :             distinct_list[count-i-1] = saved;
     486                 :         }
     487                 :     }
     488                 : 
     489              22 :     return NULL;
     490                 : }
     491                 : 
     492                 : /************************************************************************/
     493                 : /*                          swq_select_free()                           */
     494                 : /************************************************************************/
     495                 : 
     496               0 : void swq_select_free( swq_select *select_info )
     497                 : 
     498                 : {
     499               0 :     delete select_info;
     500               0 : }
     501                 : 
     502                 : /************************************************************************/
     503                 : /*                         swq_identify_field()                         */
     504                 : /************************************************************************/
     505                 : 
     506            5788 : int swq_identify_field( const char *token, swq_field_list *field_list,
     507                 :                         swq_field_type *this_type, int *table_id )
     508                 : 
     509                 : {
     510                 :     int i;
     511                 :     char table_name[128];
     512            5788 :     const char *field_token = token;
     513                 :     int   tables_enabled;
     514                 : 
     515           10008 :     if( field_list->table_count > 0 && field_list->table_ids != NULL )
     516            4220 :         tables_enabled = TRUE;
     517                 :     else
     518            1568 :         tables_enabled = FALSE;
     519                 : 
     520                 : /* -------------------------------------------------------------------- */
     521                 : /*      Parse out table name if present, and table support enabled.     */
     522                 : /* -------------------------------------------------------------------- */
     523            5788 :     table_name[0] = '\0';
     524            5788 :     if( tables_enabled && strchr(token, '.') != NULL )
     525                 :     {
     526             194 :         int dot_offset = (int)(strchr(token,'.') - token);
     527                 : 
     528             194 :         if( dot_offset < (int) sizeof(table_name) )
     529                 :         {
     530             194 :             strncpy( table_name, token, dot_offset );
     531             194 :             table_name[dot_offset] = '\0';
     532             194 :             field_token = token + dot_offset + 1;
     533                 :         }
     534                 :     }
     535                 : 
     536                 : /* -------------------------------------------------------------------- */
     537                 : /*      Search for matching field.                                      */
     538                 : /* -------------------------------------------------------------------- */
     539           19484 :     for( i = 0; i < field_list->count; i++ )
     540                 :     {
     541           18602 :         int  t_id = 0;
     542                 : 
     543           18602 :         if( !EQUAL( field_list->names[i], field_token ) )
     544           13628 :             continue;
     545                 : 
     546                 :         /* Do the table specifications match? */
     547            4974 :         if( tables_enabled )
     548                 :         {
     549            3896 :             t_id = field_list->table_ids[i];
     550            4152 :             if( table_name[0] != '\0' 
     551             256 :                 && !EQUAL(table_name,field_list->table_defs[t_id].table_alias))
     552              68 :                 continue;
     553                 : 
     554                 : //            if( t_id != 0 && table_name[0] == '\0' )
     555                 : //                continue;
     556                 :         }
     557                 : 
     558                 :         /* We have a match, return various information */
     559            4906 :         if( this_type != NULL )
     560                 :         {
     561            4782 :             if( field_list->types != NULL )
     562            4782 :                 *this_type = field_list->types[i];
     563                 :             else
     564               0 :                 *this_type = SWQ_OTHER;
     565                 :         }
     566                 :         
     567            4906 :         if( table_id != NULL )
     568            4906 :             *table_id = t_id;
     569                 : 
     570            4906 :         if( field_list->ids == NULL )
     571            1078 :             return i;
     572                 :         else
     573            3828 :             return field_list->ids[i];
     574                 :     }
     575                 : 
     576                 : /* -------------------------------------------------------------------- */
     577                 : /*      No match, return failure.                                       */
     578                 : /* -------------------------------------------------------------------- */
     579             882 :     if( this_type != NULL )
     580             876 :         *this_type = SWQ_OTHER;
     581                 : 
     582             882 :     if( table_id != NULL )
     583             882 :         *table_id = 0;
     584                 : 
     585             882 :     return -1;
     586                 : }
     587                 : 
     588                 : /************************************************************************/
     589                 : /*                          swq_expr_compile()                          */
     590                 : /************************************************************************/
     591                 : 
     592             982 : CPLErr swq_expr_compile( const char *where_clause,
     593                 :                          int field_count,
     594                 :                          char **field_names, 
     595                 :                          swq_field_type *field_types, 
     596                 :                          swq_expr_node **expr_out )
     597                 : 
     598                 : {
     599                 :     swq_field_list  field_list;
     600                 : 
     601             982 :     field_list.count = field_count;
     602             982 :     field_list.names = field_names;
     603             982 :     field_list.types = field_types;
     604             982 :     field_list.table_ids = NULL;
     605             982 :     field_list.ids = NULL;
     606                 :     
     607             982 :     field_list.table_count = 0;
     608             982 :     field_list.table_defs = NULL;
     609                 : 
     610             982 :     return swq_expr_compile2( where_clause, &field_list, expr_out );
     611                 : }
     612                 : 
     613                 : 
     614                 : /************************************************************************/
     615                 : /*                         swq_expr_compile2()                          */
     616                 : /************************************************************************/
     617                 : 
     618             982 : CPLErr swq_expr_compile2( const char *where_clause, 
     619                 :                           swq_field_list *field_list,
     620                 :                           swq_expr_node **expr_out )
     621                 : 
     622                 : {
     623                 : 
     624             982 :     swq_parse_context context;
     625                 : 
     626             982 :     context.pszInput = where_clause;
     627             982 :     context.pszNext = where_clause;
     628             982 :     context.nStartToken = SWQT_LOGICAL_START;
     629                 :     
     630             982 :     if( swqparse( &context ) == 0 
     631                 :         && context.poRoot->Check( field_list ) != SWQ_ERROR )
     632                 :     {
     633             982 :         *expr_out = context.poRoot;
     634                 : 
     635             982 :         return CE_None;
     636                 :     }
     637                 :     else
     638                 :     {
     639               0 :         delete context.poRoot;
     640               0 :         *expr_out = NULL;
     641               0 :         return CE_Failure;
     642                 :     }
     643                 : }
     644                 : 
     645                 : /************************************************************************/
     646                 : /*                        swq_is_reserved_keyword()                     */
     647                 : /************************************************************************/
     648                 : 
     649                 : static const char* apszSQLReservedKeywords[] = {
     650                 :     "OR",
     651                 :     "AND",
     652                 :     "NOT",
     653                 :     "LIKE",
     654                 :     "IS",
     655                 :     "NULL",
     656                 :     "IN",
     657                 :     "BETWEEN",
     658                 :     "CAST",
     659                 :     "DISTINCT",
     660                 :     "ESCAPE",
     661                 :     "SELECT",
     662                 :     "LEFT",
     663                 :     "JOIN",
     664                 :     "WHERE",
     665                 :     "ON",
     666                 :     "ORDER",
     667                 :     "BY",
     668                 :     "FROM",
     669                 :     "AS",
     670                 :     "ASC",
     671                 :     "DESC"
     672                 : };
     673                 : 
     674             346 : int swq_is_reserved_keyword(const char* pszStr)
     675                 : {
     676            7958 :     for(int i = 0; i < (int)(sizeof(apszSQLReservedKeywords)/sizeof(char*)); i++)
     677                 :     {
     678            7612 :         if (EQUAL(pszStr, apszSQLReservedKeywords[i]))
     679               0 :             return TRUE;
     680                 :     }
     681             346 :     return FALSE;
     682                 : }

Generated by: LCOV version 1.7