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