GDAL
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 doxygen 1.7.6.1.