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

Generated for GDAL by doxygen 1.8.8.