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

Generated for GDAL by doxygen 1.8.11.