OGR
|
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 &, char chQuote = '\'' ); 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 *, char chColumnQuote ); 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; /* items of the list can be NULL */ 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 int swq_is_reserved_keyword(const char* pszStr); 00327 00328 #endif /* def _SWQ_H_INCLUDED_ */