GDAL
|
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_ */