OGR
swq.h
1 /******************************************************************************
2  *
3  * Component: OGDI Driver Support Library
4  * Purpose: Generic SQL WHERE Expression Evaluator Declarations.
5  * Author: Frank Warmerdam <warmerdam@pobox.com>
6  *
7  ******************************************************************************
8  * Copyright (C) 2001 Information Interoperability Institute (3i)
9  * Copyright (c) 2010-2013, Even Rouault <even dot rouault at mines-paris dot org>
10  * Permission to use, copy, modify and distribute this software and
11  * its documentation for any purpose and without fee is hereby granted,
12  * provided that the above copyright notice appear in all copies, that
13  * both the copyright notice and this permission notice appear in
14  * supporting documentation, and that the name of 3i not be used
15  * in advertising or publicity pertaining to distribution of the software
16  * without specific, written prior permission. 3i makes no
17  * representations about the suitability of this software for any purpose.
18  * It is provided "as is" without express or implied warranty.
19  ****************************************************************************/
20 
21 #ifndef SWQ_H_INCLUDED_
22 #define SWQ_H_INCLUDED_
23 
24 #include "cpl_conv.h"
25 #include "cpl_string.h"
26 #include "ogr_core.h"
27 
28 #if defined(_WIN32) && !defined(strcasecmp)
29 # define strcasecmp stricmp
30 #endif
31 
32 typedef enum {
33  SWQ_OR,
34  SWQ_AND,
35  SWQ_NOT,
36  SWQ_EQ,
37  SWQ_NE,
38  SWQ_GE,
39  SWQ_LE,
40  SWQ_LT,
41  SWQ_GT,
42  SWQ_LIKE,
43  SWQ_ISNULL,
44  SWQ_IN,
45  SWQ_BETWEEN,
46  SWQ_ADD,
47  SWQ_SUBTRACT,
48  SWQ_MULTIPLY,
49  SWQ_DIVIDE,
50  SWQ_MODULUS,
51  SWQ_CONCAT,
52  SWQ_SUBSTR,
53  SWQ_HSTORE_GET_VALUE,
54  SWQ_AVG,
55  SWQ_MIN,
56  SWQ_MAX,
57  SWQ_COUNT,
58  SWQ_SUM,
59  SWQ_CAST,
60  SWQ_CUSTOM_FUNC, /* only if parsing done in bAcceptCustomFuncs mode */
61  SWQ_ARGUMENT_LIST /* temporary value only set during parsing and replaced by something else at the end */
62 } swq_op;
63 
64 typedef enum {
65  SWQ_INTEGER,
66  SWQ_INTEGER64,
67  SWQ_FLOAT,
68  SWQ_STRING,
69  SWQ_BOOLEAN, // integer
70  SWQ_DATE, // string
71  SWQ_TIME, // string
72  SWQ_TIMESTAMP,// string
73  SWQ_GEOMETRY,
74  SWQ_NULL,
75  SWQ_OTHER,
76  SWQ_ERROR
77 } swq_field_type;
78 
79 #define SWQ_IS_INTEGER(x) ((x) == SWQ_INTEGER || (x) == SWQ_INTEGER64)
80 
81 typedef enum {
82  SNT_CONSTANT,
83  SNT_COLUMN,
84  SNT_OPERATION
85 } swq_node_type;
86 
87 
88 class swq_field_list;
89 class swq_expr_node;
90 class swq_select;
91 class OGRGeometry;
92 
93 typedef swq_expr_node *(*swq_field_fetcher)( swq_expr_node *op,
94  void *record_handle );
95 typedef swq_expr_node *(*swq_op_evaluator)(swq_expr_node *op,
96  swq_expr_node **sub_field_values );
97 typedef swq_field_type (*swq_op_checker)( swq_expr_node *op,
98  int bAllowMismatchTypeOnFieldComparison );
99 
101 
103 public:
104  swq_expr_node();
105 
106  explicit swq_expr_node( const char * );
107  explicit swq_expr_node( int );
108  explicit swq_expr_node( GIntBig );
109  explicit swq_expr_node( double );
110  explicit swq_expr_node( OGRGeometry* );
111  explicit swq_expr_node( swq_op );
112 
113  ~swq_expr_node();
114 
115  void Initialize();
116  CPLString UnparseOperationFromUnparsedSubExpr(char** apszSubExpr);
117  char *Unparse( swq_field_list *, char chColumnQuote );
118  void Dump( FILE *fp, int depth );
119  swq_field_type Check( swq_field_list *, int bAllowFieldsInSecondaryTables,
120  int bAllowMismatchTypeOnFieldComparison,
121  swq_custom_func_registrar* poCustomFuncRegistrar );
122  swq_expr_node* Evaluate( swq_field_fetcher pfnFetcher,
123  void *record );
124  swq_expr_node* Clone();
125 
126  void ReplaceBetweenByGEAndLERecurse();
127 
128  swq_node_type eNodeType;
129  swq_field_type field_type;
130 
131  /* only for SNT_OPERATION */
132  void PushSubExpression( swq_expr_node * );
133  void ReverseSubExpressions();
134  int nOperation;
135  int nSubExprCount;
136  swq_expr_node **papoSubExpr;
137 
138  /* only for SNT_COLUMN */
139  int field_index;
140  int table_index;
141  char *table_name;
142 
143  /* only for SNT_CONSTANT */
144  int is_null;
145  GIntBig int_value;
146  double float_value;
147  OGRGeometry *geometry_value;
148 
149  /* shared by SNT_COLUMN, SNT_CONSTANT and also possibly SNT_OPERATION when */
150  /* nOperation == SWQ_CUSTOM_FUNC */
151  char *string_value; /* column name when SNT_COLUMN */
152 
153  static CPLString QuoteIfNecessary( const CPLString &, char chQuote = '\'' );
154  static CPLString Quote( const CPLString &, char chQuote = '\'' );
155 };
156 
157 typedef struct {
158  const char* pszName;
159  swq_op eOperation;
160  swq_op_evaluator pfnEvaluator;
161  swq_op_checker pfnChecker;
162 } swq_operation;
163 
165 public:
166  static const swq_operation *GetOperator( const char * );
167  static const swq_operation *GetOperator( swq_op eOperation );
168 };
169 
171 {
172  public:
173  virtual ~swq_custom_func_registrar() {}
174  virtual const swq_operation *GetOperator( const char * ) = 0;
175 };
176 
177 
178 typedef struct {
179  char *data_source;
180  char *table_name;
181  char *table_alias;
182 } swq_table_def;
183 
185 public:
186  int count;
187  char **names;
188  swq_field_type *types;
189  int *table_ids;
190  int *ids;
191 
192  int table_count;
193  swq_table_def *table_defs;
194 };
195 
197 public:
198  swq_parse_context() : nStartToken(0), pszInput(NULL), pszNext(NULL),
199  pszLastValid(NULL), bAcceptCustomFuncs(FALSE),
200  poRoot(NULL), poCurSelect(NULL) {}
201 
202  int nStartToken;
203  const char *pszInput;
204  const char *pszNext;
205  const char *pszLastValid;
206  int bAcceptCustomFuncs;
207 
208  swq_expr_node *poRoot;
209 
210  swq_select *poCurSelect;
211 };
212 
213 /* Compile an SQL WHERE clause into an internal form. The field_list is
214 ** the list of fields in the target 'table', used to render where into
215 ** field numbers instead of names.
216 */
217 int swqparse( swq_parse_context *context );
218 int swqlex( swq_expr_node **ppNode, swq_parse_context *context );
219 void swqerror( swq_parse_context *context, const char *msg );
220 
221 int swq_identify_field( const char* table_name,
222  const char *token, swq_field_list *field_list,
223  swq_field_type *this_type, int *table_id );
224 
225 CPLErr swq_expr_compile( const char *where_clause,
226  int field_count,
227  char **field_list,
228  swq_field_type *field_types,
229  int bCheck,
230  swq_custom_func_registrar* poCustomFuncRegistrar,
231  swq_expr_node **expr_root );
232 
233 CPLErr swq_expr_compile2( const char *where_clause,
234  swq_field_list *field_list,
235  int bCheck,
236  swq_custom_func_registrar* poCustomFuncRegistrar,
237  swq_expr_node **expr_root );
238 
239 /*
240 ** Evaluation related.
241 */
242 int swq_test_like( const char *input, const char *pattern );
243 
244 swq_expr_node *SWQGeneralEvaluator( swq_expr_node *, swq_expr_node **);
245 swq_field_type SWQGeneralChecker( swq_expr_node *node, int bAllowMismatchTypeOnFieldComparison );
246 swq_expr_node *SWQCastEvaluator( swq_expr_node *, swq_expr_node **);
247 swq_field_type SWQCastChecker( swq_expr_node *node, int bAllowMismatchTypeOnFieldComparison );
248 const char* SWQFieldTypeToString( swq_field_type field_type );
249 
250 /****************************************************************************/
251 
252 #define SWQP_ALLOW_UNDEFINED_COL_FUNCS 0x01
253 
254 #define SWQM_SUMMARY_RECORD 1
255 #define SWQM_RECORDSET 2
256 #define SWQM_DISTINCT_LIST 3
257 
258 typedef enum {
259  SWQCF_NONE = 0,
260  SWQCF_AVG = SWQ_AVG,
261  SWQCF_MIN = SWQ_MIN,
262  SWQCF_MAX = SWQ_MAX,
263  SWQCF_COUNT = SWQ_COUNT,
264  SWQCF_SUM = SWQ_SUM,
265  SWQCF_CUSTOM
266 } swq_col_func;
267 
268 typedef struct {
269  swq_col_func col_func;
270  char *table_name;
271  char *field_name;
272  char *field_alias;
273  int table_index;
274  int field_index;
275  swq_field_type field_type;
276  swq_field_type target_type;
277  OGRFieldSubType target_subtype;
278  int field_length;
279  int field_precision;
280  int distinct_flag;
281  OGRwkbGeometryType eGeomType;
282  int nSRID;
283  swq_expr_node *expr;
284 } swq_col_def;
285 
286 typedef struct {
287  GIntBig count;
288 
289  char **distinct_list; /* items of the list can be NULL */
290  double sum;
291  double min;
292  double max;
293  char szMin[32];
294  char szMax[32];
295 } swq_summary;
296 
297 typedef struct {
298  char *table_name;
299  char *field_name;
300  int table_index;
301  int field_index;
302  int ascending_flag;
303 } swq_order_def;
304 
305 typedef struct {
306  int secondary_table;
307  swq_expr_node *poExpr;
308 } swq_join_def;
309 
311 {
312 public:
313  swq_custom_func_registrar* poCustomFuncRegistrar;
314  int bAllowFieldsInSecondaryTablesInWhere;
315  int bAddSecondaryTablesGeometryFields;
316  int bAlwaysPrefixWithTableName;
317  int bAllowDistinctOnGeometryField;
318  int bAllowDistinctOnMultipleFields;
319 
320  swq_select_parse_options(): poCustomFuncRegistrar(NULL),
321  bAllowFieldsInSecondaryTablesInWhere(FALSE),
322  bAddSecondaryTablesGeometryFields(FALSE),
323  bAlwaysPrefixWithTableName(FALSE),
324  bAllowDistinctOnGeometryField(FALSE),
325  bAllowDistinctOnMultipleFields(FALSE) {}
326 };
327 
329 {
330  void postpreparse();
331 
332 public:
333  swq_select();
334  ~swq_select();
335 
336  int query_mode;
337 
338  char *raw_select;
339 
340  int PushField( swq_expr_node *poExpr, const char *pszAlias=NULL,
341  int distinct_flag = FALSE );
342  int result_columns;
343  swq_col_def *column_defs;
344  swq_summary *column_summary;
345 
346  int PushTableDef( const char *pszDataSource,
347  const char *pszTableName,
348  const char *pszAlias );
349  int table_count;
350  swq_table_def *table_defs;
351 
352  void PushJoin( int iSecondaryTable, swq_expr_node* poExpr );
353  int join_count;
354  swq_join_def *join_defs;
355 
356  swq_expr_node *where_expr;
357 
358  void PushOrderBy( const char* pszTableName, const char *pszFieldName, int bAscending );
359  int order_specs;
360  swq_order_def *order_defs;
361 
362  swq_select *poOtherSelect;
363  void PushUnionAll( swq_select* poOtherSelectIn );
364 
365  CPLErr preparse( const char *select_statement,
366  int bAcceptCustomFuncs = FALSE );
367  CPLErr expand_wildcard( swq_field_list *field_list,
368  int bAlwaysPrefixWithTableName );
369  CPLErr parse( swq_field_list *field_list,
370  swq_select_parse_options* poParseOptions );
371 
372  char *Unparse();
373  void Dump( FILE * );
374 };
375 
376 CPLErr swq_select_parse( swq_select *select_info,
377  swq_field_list *field_list,
378  int parse_flags );
379 
380 const char *swq_select_finish_summarize( swq_select *select_info );
381 const char *swq_select_summarize( swq_select *select_info,
382  int dest_column,
383  const char *value );
384 
385 int swq_is_reserved_keyword(const char* pszStr);
386 
387 char* OGRHStoreGetValue(const char* pszHStore, const char* pszSearchedKey);
388 
389 #endif /* def SWQ_H_INCLUDED_ */
Definition: swq.h:328
OGRFieldSubType
Definition: ogr_core.h:628
Definition: swq.h:157
Definition: swq.h:184
Convenient string class based on std::string.
Definition: cpl_string.h:283
Definition: swq.h:164
Definition: swq.h:268
OGRwkbGeometryType
Definition: ogr_core.h:333
Definition: ogr_geometry.h:104
Definition: swq.h:310
Definition: swq.h:305
Definition: swq.h:178
Definition: swq.h:286
Definition: swq.h:297
Definition: swq.h:170
Definition: swq.h:196
Definition: swq.h:102

Generated for GDAL by doxygen 1.8.12.