OGR
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  * Permission to use, copy, modify and distribute this software and
00010  * its documentation for any purpose and without fee is hereby granted,
00011  * provided that the above copyright notice appear in all copies, that
00012  * both the copyright notice and this permission notice appear in
00013  * supporting documentation, and that the name of 3i not be used 
00014  * in advertising or publicity pertaining to distribution of the software 
00015  * without specific, written prior permission.  3i makes no
00016  * representations about the suitability of this software for any purpose.
00017  * It is provided "as is" without express or implied warranty.
00018  ****************************************************************************/
00019 
00020 #ifndef _SWQ_H_INCLUDED_
00021 #define _SWQ_H_INCLUDED_
00022 
00023 #include "cpl_conv.h"
00024 #include "cpl_string.h"
00025 
00026 #if defined(_WIN32) && !defined(_WIN32_WCE)
00027 #  define strcasecmp stricmp
00028 #elif defined(_WIN32_WCE)
00029 #  define strcasecmp _stricmp
00030 #endif
00031 
00032 typedef enum {
00033     SWQ_OR,
00034     SWQ_AND,
00035     SWQ_NOT,
00036     SWQ_EQ,
00037     SWQ_NE,
00038     SWQ_GE,
00039     SWQ_LE,
00040     SWQ_LT,
00041     SWQ_GT,
00042     SWQ_LIKE,
00043     SWQ_ISNULL,
00044     SWQ_IN,
00045     SWQ_BETWEEN,
00046     SWQ_ADD,
00047     SWQ_SUBTRACT,
00048     SWQ_MULTIPLY,
00049     SWQ_DIVIDE,
00050     SWQ_MODULUS,
00051     SWQ_CONCAT,
00052     SWQ_SUBSTR,
00053     SWQ_AVG,
00054     SWQ_MIN,
00055     SWQ_MAX,
00056     SWQ_COUNT,
00057     SWQ_SUM,
00058     SWQ_CAST,
00059     SWQ_FUNC_DEFINED,
00060     SWQ_UNKNOWN
00061 } swq_op;
00062 
00063 typedef enum {
00064     SWQ_INTEGER,
00065     SWQ_FLOAT,
00066     SWQ_STRING, 
00067     SWQ_BOOLEAN,  // integer
00068     SWQ_DATE,     // string
00069     SWQ_TIME,     // string
00070     SWQ_TIMESTAMP,// string
00071     SWQ_NULL,
00072     SWQ_OTHER,
00073     SWQ_ERROR
00074 } swq_field_type;
00075 
00076 typedef enum {
00077     SNT_CONSTANT,
00078     SNT_COLUMN, 
00079     SNT_OPERATION
00080 } swq_node_type;
00081 
00082 
00083 class swq_field_list;
00084 class swq_expr_node;
00085 class swq_select;
00086 
00087 typedef swq_expr_node *(*swq_field_fetcher)( swq_expr_node *op,
00088                                              void *record_handle );
00089 typedef swq_expr_node *(*swq_op_evaluator)(swq_expr_node *op,
00090                                            swq_expr_node **sub_field_values );
00091 typedef swq_field_type (*swq_op_checker)( swq_expr_node *op );
00092 
00093 class swq_expr_node {
00094     static void   Quote( CPLString & );
00095 public:
00096     swq_expr_node();
00097 
00098     swq_expr_node( const char * );
00099     swq_expr_node( int );
00100     swq_expr_node( double );
00101     swq_expr_node( swq_op );
00102 
00103     ~swq_expr_node();
00104 
00105     void           Initialize();
00106     char          *Unparse( swq_field_list * );
00107     void           Dump( FILE *fp, int depth );
00108     swq_field_type Check( swq_field_list * );
00109     swq_expr_node* Evaluate( swq_field_fetcher pfnFetcher, 
00110                              void *record );
00111 
00112     swq_node_type eNodeType;
00113     swq_field_type field_type;
00114 
00115     /* only for SNT_OPERATION */
00116     void        PushSubExpression( swq_expr_node * );
00117     void        ReverseSubExpressions();
00118     int         nOperation;
00119     int         nSubExprCount;
00120     swq_expr_node **papoSubExpr;
00121 
00122     /* only for SNT_COLUMN */
00123     int         field_index;
00124     int         table_index;
00125 
00126     /* only for SNT_CONSTANT */
00127     int         is_null;
00128     char        *string_value;
00129     int         int_value;
00130     double      float_value;
00131 };
00132 
00133 class swq_operation {
00134 public:
00135     swq_operation() {}
00136     ~swq_operation() {}
00137 
00138     swq_op           eOperation;
00139     CPLString        osName;
00140     swq_op_evaluator pfnEvaluator;
00141     swq_op_checker   pfnChecker;
00142 };
00143 
00144 class swq_op_registrar {
00145 public:
00146     static const swq_operation *GetOperator( const char * );
00147     static const swq_operation *GetOperator( swq_op eOperation );
00148     static void  Initialize();
00149     static void  DeInitialize();
00150     static void  AddOperator( const char *pszName, swq_op eOpCode,
00151                               swq_op_evaluator pfnEvaluator = NULL,
00152                               swq_op_checker pfnChecker = NULL );
00153 };
00154 
00155 typedef struct {
00156     char       *data_source;
00157     char       *table_name;
00158     char       *table_alias;
00159 } swq_table_def;
00160 
00161 class swq_field_list {
00162 public:
00163     int count;
00164     char **names;
00165     swq_field_type *types;
00166     int *table_ids;
00167     int *ids;
00168 
00169     int table_count;
00170     swq_table_def *table_defs;
00171 };
00172 
00173 class swq_parse_context {
00174 public:
00175     swq_parse_context() : nStartToken(0), poRoot(NULL), poSelect(NULL) {}
00176 
00177     int        nStartToken;
00178     const char *pszInput;
00179     const char *pszNext;
00180 
00181     swq_expr_node *poRoot;
00182 
00183     swq_select    *poSelect;
00184 };
00185 
00186 /* Compile an SQL WHERE clause into an internal form.  The field_list is
00187 ** the list of fields in the target 'table', used to render where into 
00188 ** field numbers instead of names. 
00189 */
00190 int swqparse( swq_parse_context *context );
00191 int swqlex( swq_expr_node **ppNode, swq_parse_context *context );
00192 
00193 int swq_identify_field( const char *token, swq_field_list *field_list,
00194                         swq_field_type *this_type, int *table_id );
00195 
00196 CPLErr swq_expr_compile( const char *where_clause, 
00197                          int field_count,
00198                          char **field_list,
00199                          swq_field_type *field_types,
00200                          swq_expr_node **expr_root );
00201 
00202 CPLErr swq_expr_compile2( const char *where_clause, 
00203                           swq_field_list *field_list, 
00204                           swq_expr_node **expr_root );
00205 
00206 /*
00207 ** Evaluation related.
00208 */
00209 int swq_test_like( const char *input, const char *pattern );
00210 
00211 swq_expr_node *SWQGeneralEvaluator( swq_expr_node *, swq_expr_node **);
00212 swq_field_type SWQGeneralChecker( swq_expr_node *node );
00213 swq_expr_node *SWQCastEvaluator( swq_expr_node *, swq_expr_node **);
00214 swq_field_type SWQCastChecker( swq_expr_node *node );
00215 
00216 /****************************************************************************/
00217 
00218 #define SWQP_ALLOW_UNDEFINED_COL_FUNCS 0x01
00219 
00220 #define SWQM_SUMMARY_RECORD  1
00221 #define SWQM_RECORDSET       2
00222 #define SWQM_DISTINCT_LIST   3
00223 
00224 typedef enum {
00225     SWQCF_NONE = 0,
00226     SWQCF_AVG = SWQ_AVG,
00227     SWQCF_MIN = SWQ_MIN,
00228     SWQCF_MAX = SWQ_MAX,
00229     SWQCF_COUNT = SWQ_COUNT,
00230     SWQCF_SUM = SWQ_SUM,
00231     SWQCF_CUSTOM
00232 } swq_col_func;
00233 
00234 typedef struct {
00235     swq_col_func col_func;
00236     char         *field_name;
00237     char         *field_alias;
00238     int          table_index;
00239     int          field_index;
00240     swq_field_type field_type;
00241     swq_field_type target_type;
00242     int          field_length;
00243     int          field_precision;
00244     int          distinct_flag;
00245     swq_expr_node *expr;
00246 } swq_col_def;
00247 
00248 typedef struct {
00249     int         count;
00250     
00251     char        **distinct_list;
00252     double      sum;
00253     double      min;
00254     double      max;
00255 } swq_summary;
00256 
00257 typedef struct {
00258     char *field_name;
00259     int   table_index;
00260     int   field_index;
00261     int   ascending_flag;
00262 } swq_order_def;
00263 
00264 typedef struct {
00265     int        secondary_table;
00266 
00267     char      *primary_field_name;
00268     int        primary_field;
00269 
00270     swq_op     op;
00271 
00272     char      *secondary_field_name;
00273     int        secondary_field;
00274 } swq_join_def;
00275 
00276 class swq_select
00277 {
00278 public:
00279     swq_select();
00280     ~swq_select();
00281 
00282     int         query_mode;
00283 
00284     char        *raw_select;
00285 
00286     int         PushField( swq_expr_node *poExpr, const char *pszAlias=NULL,
00287                            int distinct_flag = FALSE );
00288     int         result_columns;
00289     swq_col_def *column_defs;
00290     swq_summary *column_summary;
00291 
00292     int         PushTableDef( const char *pszDataSource,
00293                               const char *pszTableName,
00294                               const char *pszAlias );
00295     int         table_count;
00296     swq_table_def *table_defs;
00297 
00298     void        PushJoin( int iSecondaryTable,
00299                           const char *pszPrimaryField,
00300                           const char *pszSecondaryField );
00301     int         join_count;
00302     swq_join_def *join_defs;
00303 
00304     swq_expr_node *where_expr;
00305 
00306     void        PushOrderBy( const char *pszFieldName, int bAscending );
00307     int         order_specs;
00308     swq_order_def *order_defs;    
00309 
00310     CPLErr      preparse( const char *select_statement );
00311     CPLErr      expand_wildcard( swq_field_list *field_list );
00312     CPLErr      parse( swq_field_list *field_list, int parse_flags );
00313 
00314     void        Dump( FILE * );
00315 };
00316 
00317 CPLErr swq_select_parse( swq_select *select_info,
00318                          swq_field_list *field_list,
00319                          int parse_flags );
00320 
00321 const char *swq_select_finish_summarize( swq_select *select_info );
00322 const char *swq_select_summarize( swq_select *select_info, 
00323                                   int dest_column, 
00324                                   const char *value );
00325 
00326 #endif /* def _SWQ_H_INCLUDED_ */

Generated for GDAL by doxygen 1.7.6.1.