- Main Page
- Related Pages
- Classes
- Files

- File List
- File Members

# swq.h

    00001 /******************************************************************************
    00002  *
    00003  * Component: OGDI Driver Support Library
    00004  * Purpose: Generic SQL WHERE Expression Evaluator Declarations.
    00005  * Author: Frank Warmerdam <warmerdam@pobox.com>
    00006  *
    00007  ******************************************************************************
    00008  * Copyright (C) 2001 Information Interoperability Institute (3i)
    00009  * Copyright (c) 2010-2013, Even Rouault <even dot rouault at mines-paris dot org>
    00010  * Permission to use, copy, modify and distribute this software and
    00011  * its documentation for any purpose and without fee is hereby granted,
    00012  * provided that the above copyright notice appear in all copies, that
    00013  * both the copyright notice and this permission notice appear in
    00014  * supporting documentation, and that the name of 3i not be used
    00015  * in advertising or publicity pertaining to distribution of the software
    00016  * without specific, written prior permission.  3i makes no
    00017  * representations about the suitability of this software for any purpose.
    00018  * It is provided "as is" without express or implied warranty.
    00019  ****************************************************************************/
    00020
    00021 #ifndef _SWQ_H_INCLUDED_
    00022 #define _SWQ_H_INCLUDED_
    00023
    00024 #include "cpl_conv.h"
    00025 #include "cpl_string.h"
    00026 #include "ogr_core.h"
    00027
    00028 #if defined(_WIN32) && !defined(_WIN32_WCE)
    00029 #  define strcasecmp stricmp
    00030 #elif defined(_WIN32_WCE)
    00031 #  define strcasecmp _stricmp
    00032 #endif
    00033
    00034 typedef enum {
    00035     SWQ_OR,
    00036     SWQ_AND,
    00037     SWQ_NOT,
    00038     SWQ_EQ,
    00039     SWQ_NE,
    00040     SWQ_GE,
    00041     SWQ_LE,
    00042     SWQ_LT,
    00043     SWQ_GT,
    00044     SWQ_LIKE,
    00045     SWQ_ISNULL,
    00046     SWQ_IN,
    00047     SWQ_BETWEEN,
    00048     SWQ_ADD,
    00049     SWQ_SUBTRACT,
    00050     SWQ_MULTIPLY,
    00051     SWQ_DIVIDE,
    00052     SWQ_MODULUS,
    00053     SWQ_CONCAT,
    00054     SWQ_SUBSTR,
    00055     SWQ_HSTORE_GET_VALUE,
    00056     SWQ_AVG,
    00057     SWQ_MIN,
    00058     SWQ_MAX,
    00059     SWQ_COUNT,
    00060     SWQ_SUM,
    00061     SWQ_CAST,
    00062     SWQ_CUSTOM_FUNC, /* only if parsing done in bAcceptCustomFuncs mode */
    00063     SWQ_ARGUMENT_LIST /* temporary value only set during parsing and replaced by something else at the end */
    00064 } swq_op;
    00065
    00066 typedef enum {
    00067     SWQ_INTEGER,
    00068     SWQ_INTEGER64,
    00069     SWQ_FLOAT,
    00070     SWQ_STRING,
    00071     SWQ_BOOLEAN,  // integer
    00072     SWQ_DATE,     // string
    00073     SWQ_TIME,     // string
    00074     SWQ_TIMESTAMP,// string
    00075     SWQ_GEOMETRY,
    00076     SWQ_NULL,
    00077     SWQ_OTHER,
    00078     SWQ_ERROR
    00079 } swq_field_type;
    00080
    00081 #define SWQ_IS_INTEGER(x) ((x) == SWQ_INTEGER || (x) == SWQ_INTEGER64)
    00082
    00083 typedef enum {
    00084     SNT_CONSTANT,
    00085     SNT_COLUMN,
    00086     SNT_OPERATION
    00087 } swq_node_type;
    00088
    00089
    00090 class swq_field_list;
    00091 class swq_expr_node;
    00092 class swq_select;
    00093 class OGRGeometry;
    00094
    00095 typedef swq_expr_node *(*swq_field_fetcher)( swq_expr_node *op,
    00096                                              void *record_handle );
    00097 typedef swq_expr_node *(*swq_op_evaluator)(swq_expr_node *op,
    00098                                            swq_expr_node **sub_field_values );
    00099 typedef swq_field_type (*swq_op_checker)( swq_expr_node *op,
    00100                                           int bAllowMismatchTypeOnFieldComparison );
    00101
    00102 class swq_custom_func_registrar;
    00103
    00104 class swq_expr_node {
    00105 public:
    00106     swq_expr_node();
    00107
    00108     swq_expr_node( const char * );
    00109     swq_expr_node( int );
    00110     swq_expr_node( GIntBig );
    00111     swq_expr_node( double );
    00112     swq_expr_node( OGRGeometry* );
    00113     swq_expr_node( swq_op );
    00114
    00115     ~swq_expr_node();
    00116
    00117     void           Initialize();
    00118     CPLString      UnparseOperationFromUnparsedSubExpr(char** apszSubExpr);
    00119     char          *Unparse( swq_field_list *, char chColumnQuote );
    00120     void           Dump( FILE *fp, int depth );
    00121     swq_field_type Check( swq_field_list *, int bAllowFieldsInSecondaryTables,
    00122                           int bAllowMismatchTypeOnFieldComparison,
    00123                           swq_custom_func_registrar* poCustomFuncRegistrar );
    00124     swq_expr_node* Evaluate( swq_field_fetcher pfnFetcher,
    00125                              void *record );
    00126     swq_expr_node* Clone();
    00127
    00128     void           ReplaceBetweenByGEAndLERecurse();
    00129
    00130     swq_node_type eNodeType;
    00131     swq_field_type field_type;
    00132
    00133     /* only for SNT_OPERATION */
    00134     void        PushSubExpression( swq_expr_node * );
    00135     void        ReverseSubExpressions();
    00136     int         nOperation;
    00137     int         nSubExprCount;
    00138     swq_expr_node **papoSubExpr;
    00139
    00140     /* only for SNT_COLUMN */
    00141     int         field_index;
    00142     int         table_index;
    00143     char        *table_name;
    00144
    00145     /* only for SNT_CONSTANT */
    00146     int         is_null;
    00147     GIntBig     int_value;
    00148     double      float_value;
    00149     OGRGeometry *geometry_value;
    00150
    00151     /* shared by SNT_COLUMN, SNT_CONSTANT and also possibly SNT_OPERATION when */
    00152     /* nOperation == SWQ_CUSTOM_FUNC */
    00153     char        *string_value; /* column name when SNT_COLUMN */
    00154
    00155
    00156     static CPLString   QuoteIfNecessary( const CPLString &, char chQuote = '\'' );
    00157     static CPLString   Quote( const CPLString &, char chQuote = '\'' );
    00158 };
    00159
    00160 typedef struct {
    00161     const char*      pszName;
    00162     swq_op           eOperation;
    00163     swq_op_evaluator pfnEvaluator;
    00164     swq_op_checker   pfnChecker;
    00165 } swq_operation;
    00166
    00167 class swq_op_registrar {
    00168 public:
    00169     static const swq_operation *GetOperator( const char * );
    00170     static const swq_operation *GetOperator( swq_op eOperation );
    00171 };
    00172
    00173 class swq_custom_func_registrar
    00174 {
    00175     public:
    00176         virtual ~swq_custom_func_registrar() {}
    00177         virtual const swq_operation *GetOperator( const char * ) = 0;
    00178 };
    00179
    00180
    00181 typedef struct {
    00182     char       *data_source;
    00183     char       *table_name;
    00184     char       *table_alias;
    00185 } swq_table_def;
    00186
    00187 class swq_field_list {
    00188 public:
    00189     int count;
    00190     char **names;
    00191     swq_field_type *types;
    00192     int *table_ids;
    00193     int *ids;
    00194
    00195     int table_count;
    00196     swq_table_def *table_defs;
    00197 };
    00198
    00199 class swq_parse_context {
    00200 public:
    00201     swq_parse_context() : nStartToken(0), pszInput(NULL), pszNext(NULL),
    00202                           pszLastValid(NULL), bAcceptCustomFuncs(FALSE),
    00203                           poRoot(NULL), poCurSelect(NULL) {}
    00204
    00205     int        nStartToken;
    00206     const char *pszInput;
    00207     const char *pszNext;
    00208     const char *pszLastValid;
    00209     int        bAcceptCustomFuncs;
    00210
    00211     swq_expr_node *poRoot;
    00212
    00213     swq_select    *poCurSelect;
    00214 };
    00215
    00216 /* Compile an SQL WHERE clause into an internal form.  The field_list is
    00217 ** the list of fields in the target 'table', used to render where into
    00218 ** field numbers instead of names.
    00219 */
    00220 int swqparse( swq_parse_context *context );
    00221 int swqlex( swq_expr_node **ppNode, swq_parse_context *context );
    00222 void swqerror( swq_parse_context *context, const char *msg );
    00223
    00224 int swq_identify_field( const char* table_name,
    00225                         const char *token, swq_field_list *field_list,
    00226                         swq_field_type *this_type, int *table_id );
    00227
    00228 CPLErr swq_expr_compile( const char *where_clause,
    00229                          int field_count,
    00230                          char **field_list,
    00231                          swq_field_type *field_types,
    00232                          int bCheck,
    00233                          swq_custom_func_registrar* poCustomFuncRegistrar,
    00234                          swq_expr_node **expr_root );
    00235
    00236 CPLErr swq_expr_compile2( const char *where_clause,
    00237                           swq_field_list *field_list,
    00238                           int bCheck,
    00239                           swq_custom_func_registrar* poCustomFuncRegistrar,
    00240                           swq_expr_node **expr_root );
    00241
    00242 /*
    00243 ** Evaluation related.
    00244 */
    00245 int swq_test_like( const char *input, const char *pattern );
    00246
    00247 swq_expr_node *SWQGeneralEvaluator( swq_expr_node *, swq_expr_node **);
    00248 swq_field_type SWQGeneralChecker( swq_expr_node *node, int bAllowMismatchTypeOnFieldComparison );
    00249 swq_expr_node *SWQCastEvaluator( swq_expr_node *, swq_expr_node **);
    00250 swq_field_type SWQCastChecker( swq_expr_node *node, int bAllowMismatchTypeOnFieldComparison );
    00251 const char*    SWQFieldTypeToString( swq_field_type field_type );
    00252
    00253 /****************************************************************************/
    00254
    00255 #define SWQP_ALLOW_UNDEFINED_COL_FUNCS 0x01
    00256
    00257 #define SWQM_SUMMARY_RECORD  1
    00258 #define SWQM_RECORDSET       2
    00259 #define SWQM_DISTINCT_LIST   3
    00260
    00261 typedef enum {
    00262     SWQCF_NONE = 0,
    00263     SWQCF_AVG = SWQ_AVG,
    00264     SWQCF_MIN = SWQ_MIN,
    00265     SWQCF_MAX = SWQ_MAX,
    00266     SWQCF_COUNT = SWQ_COUNT,
    00267     SWQCF_SUM = SWQ_SUM,
    00268     SWQCF_CUSTOM
    00269 } swq_col_func;
    00270
    00271 typedef struct {
    00272     swq_col_func col_func;
    00273     char         *table_name;
    00274     char         *field_name;
    00275     char         *field_alias;
    00276     int          table_index;
    00277     int          field_index;
    00278     swq_field_type field_type;
    00279     swq_field_type target_type;
    00280     OGRFieldSubType target_subtype;
    00281     int          field_length;
    00282     int          field_precision;
    00283     int          distinct_flag;
    00284     OGRwkbGeometryType eGeomType;
    00285     int          nSRID;
    00286     swq_expr_node *expr;
    00287 } swq_col_def;
    00288
    00289 typedef struct {
    00290     GIntBig     count;
    00291
    00292     char        **distinct_list; /* items of the list can be NULL */
    00293     double      sum;
    00294     double      min;
    00295     double      max;
    00296     char        szMin[32];
    00297     char        szMax[32];
    00298 } swq_summary;
    00299
    00300 typedef struct {
    00301     char *table_name;
    00302     char *field_name;
    00303     int   table_index;
    00304     int   field_index;
    00305     int   ascending_flag;
    00306 } swq_order_def;
    00307
    00308 typedef struct {
    00309     int        secondary_table;
    00310     swq_expr_node  *poExpr;
    00311 } swq_join_def;
    00312
    00313 class swq_select_parse_options
    00314 {
    00315 public:
    00316     swq_custom_func_registrar* poCustomFuncRegistrar;
    00317     int                        bAllowFieldsInSecondaryTablesInWhere;
    00318     int                        bAddSecondaryTablesGeometryFields;
    00319     int                        bAlwaysPrefixWithTableName;
    00320     int                        bAllowDistinctOnGeometryField;
    00321     int                        bAllowDistinctOnMultipleFields;
    00322
    00323                     swq_select_parse_options(): poCustomFuncRegistrar(NULL),
    00324                                                 bAllowFieldsInSecondaryTablesInWhere(FALSE),
    00325                                                 bAddSecondaryTablesGeometryFields(FALSE),
    00326                                                 bAlwaysPrefixWithTableName(FALSE),
    00327                                                 bAllowDistinctOnGeometryField(FALSE),
    00328                                                 bAllowDistinctOnMultipleFields(FALSE) {}
    00329 };
    00330
    00331 class swq_select
    00332 {
    00333     void        postpreparse();
    00334
    00335 public:
    00336     swq_select();
    00337     ~swq_select();
    00338
    00339     int         query_mode;
    00340
    00341     char        *raw_select;
    00342
    00343     int         PushField( swq_expr_node *poExpr, const char *pszAlias=NULL,
    00344                            int distinct_flag = FALSE );
    00345     int         result_columns;
    00346     swq_col_def *column_defs;
    00347     swq_summary *column_summary;
    00348
    00349     int         PushTableDef( const char *pszDataSource,
    00350                               const char *pszTableName,
    00351                               const char *pszAlias );
    00352     int         table_count;
    00353     swq_table_def *table_defs;
    00354
    00355     void        PushJoin( int iSecondaryTable, swq_expr_node* poExpr );
    00356     int         join_count;
    00357     swq_join_def *join_defs;
    00358
    00359     swq_expr_node *where_expr;
    00360
    00361     void        PushOrderBy( const char* pszTableName, const char *pszFieldName, int bAscending );
    00362     int         order_specs;
    00363     swq_order_def *order_defs;
    00364
    00365     swq_select *poOtherSelect;
    00366     void        PushUnionAll( swq_select* poOtherSelectIn );
    00367
    00368     CPLErr      preparse( const char *select_statement,
    00369                           int bAcceptCustomFuncs = FALSE );
    00370     CPLErr      expand_wildcard( swq_field_list *field_list,
    00371                                  int bAlwaysPrefixWithTableName );
    00372     CPLErr      parse( swq_field_list *field_list,
    00373                        swq_select_parse_options* poParseOptions );
    00374
    00375     char       *Unparse();
    00376     void        Dump( FILE * );
    00377 };
    00378
    00379 CPLErr swq_select_parse( swq_select *select_info,
    00380                          swq_field_list *field_list,
    00381                          int parse_flags );
    00382
    00383 const char *swq_select_finish_summarize( swq_select *select_info );
    00384 const char *swq_select_summarize( swq_select *select_info,
    00385                                   int dest_column,
    00386                                   const char *value );
    00387
    00388 int swq_is_reserved_keyword(const char* pszStr);
    00389
    00390 char* OGRHStoreGetValue(const char* pszHStore, const char* pszSearchedKey);
    00391
    00392 #endif /* def _SWQ_H_INCLUDED_ */

Generated for GDAL by 1.7.1.