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 
111  CPL_DISALLOW_COPY_ASSIGN(swq_expr_node)
112  swq_expr_node* Evaluate( swq_field_fetcher pfnFetcher,
113  void *record, int nRecLevel );
114 public:
115  swq_expr_node();
116 
117  explicit swq_expr_node( const char * );
118  explicit swq_expr_node( int );
119  explicit swq_expr_node( GIntBig );
120  explicit swq_expr_node( double );
121  explicit swq_expr_node( OGRGeometry* );
122  explicit swq_expr_node( swq_op );
123 
124  ~swq_expr_node();
125 
126  void MarkAsTimestamp();
127  CPLString UnparseOperationFromUnparsedSubExpr(char** apszSubExpr);
128  char *Unparse( swq_field_list *, char chColumnQuote );
129  void Dump( FILE *fp, int depth );
130  swq_field_type Check( swq_field_list *, int bAllowFieldsInSecondaryTables,
131  int bAllowMismatchTypeOnFieldComparison,
132  swq_custom_func_registrar* poCustomFuncRegistrar );
133  swq_expr_node* Evaluate( swq_field_fetcher pfnFetcher,
134  void *record );
135  swq_expr_node* Clone();
136 
137  void ReplaceBetweenByGEAndLERecurse();
138 
139  swq_node_type eNodeType = SNT_CONSTANT;
140  swq_field_type field_type = SWQ_INTEGER;
141 
142  /* only for SNT_OPERATION */
143  void PushSubExpression( swq_expr_node * );
144  void ReverseSubExpressions();
145  int nOperation = 0;
146  int nSubExprCount = 0;
147  swq_expr_node **papoSubExpr = nullptr;
148 
149  /* only for SNT_COLUMN */
150  int field_index = 0;
151  int table_index = 0;
152  char *table_name = nullptr;
153 
154  /* only for SNT_CONSTANT */
155  int is_null = false;
156  GIntBig int_value = 0;
157  double float_value = 0.0;
158  OGRGeometry *geometry_value = nullptr;
159 
160  /* shared by SNT_COLUMN, SNT_CONSTANT and also possibly SNT_OPERATION when */
161  /* nOperation == SWQ_CUSTOM_FUNC */
162  char *string_value = nullptr; /* column name when SNT_COLUMN */
163 
164  static CPLString QuoteIfNecessary( const CPLString &, char chQuote = '\'' );
165  static CPLString Quote( const CPLString &, char chQuote = '\'' );
166 };
167 
168 typedef struct {
169  const char* pszName;
170  swq_op eOperation;
171  swq_op_evaluator pfnEvaluator;
172  swq_op_checker pfnChecker;
173 } swq_operation;
174 
175 class swq_op_registrar {
176 public:
177  static const swq_operation *GetOperator( const char * );
178  static const swq_operation *GetOperator( swq_op eOperation );
179 };
180 
181 class swq_custom_func_registrar
182 {
183  public:
184  virtual ~swq_custom_func_registrar() {}
185  virtual const swq_operation *GetOperator( const char * ) = 0;
186 };
187 
188 typedef struct {
189  char *data_source;
190  char *table_name;
191  char *table_alias;
192 } swq_table_def;
193 
194 class swq_field_list {
195 public:
196  int count;
197  char **names;
198  swq_field_type *types;
199  int *table_ids;
200  int *ids;
201 
202  int table_count;
203  swq_table_def *table_defs;
204 };
205 
206 class swq_parse_context {
207 public:
208  swq_parse_context() : nStartToken(0), pszInput(nullptr), pszNext(nullptr),
209  pszLastValid(nullptr), bAcceptCustomFuncs(FALSE),
210  poRoot(nullptr), poCurSelect(nullptr) {}
211 
212  int nStartToken;
213  const char *pszInput;
214  const char *pszNext;
215  const char *pszLastValid;
216  int bAcceptCustomFuncs;
217 
218  swq_expr_node *poRoot;
219 
220  swq_select *poCurSelect;
221 };
222 
223 /* Compile an SQL WHERE clause into an internal form. The field_list is
224 ** the list of fields in the target 'table', used to render where into
225 ** field numbers instead of names.
226 */
227 int swqparse( swq_parse_context *context );
228 int swqlex( swq_expr_node **ppNode, swq_parse_context *context );
229 void swqerror( swq_parse_context *context, const char *msg );
230 
231 int swq_identify_field( const char* table_name,
232  const char *token, swq_field_list *field_list,
233  swq_field_type *this_type, int *table_id );
234 
235 CPLErr swq_expr_compile( const char *where_clause,
236  int field_count,
237  char **field_list,
238  swq_field_type *field_types,
239  int bCheck,
240  swq_custom_func_registrar* poCustomFuncRegistrar,
241  swq_expr_node **expr_root );
242 
243 CPLErr swq_expr_compile2( const char *where_clause,
244  swq_field_list *field_list,
245  int bCheck,
246  swq_custom_func_registrar* poCustomFuncRegistrar,
247  swq_expr_node **expr_root );
248 
249 /*
250 ** Evaluation related.
251 */
252 int swq_test_like( const char *input, const char *pattern );
253 
254 swq_expr_node *SWQGeneralEvaluator( swq_expr_node *, swq_expr_node **);
255 swq_field_type SWQGeneralChecker( swq_expr_node *node, int bAllowMismatchTypeOnFieldComparison );
256 swq_expr_node *SWQCastEvaluator( swq_expr_node *, swq_expr_node **);
257 swq_field_type SWQCastChecker( swq_expr_node *node, int bAllowMismatchTypeOnFieldComparison );
258 const char* SWQFieldTypeToString( swq_field_type field_type );
259 
260 /****************************************************************************/
261 
262 #define SWQP_ALLOW_UNDEFINED_COL_FUNCS 0x01
263 
264 #define SWQM_SUMMARY_RECORD 1
265 #define SWQM_RECORDSET 2
266 #define SWQM_DISTINCT_LIST 3
267 
268 typedef enum {
269  SWQCF_NONE = 0,
270  SWQCF_AVG = SWQ_AVG,
271  SWQCF_MIN = SWQ_MIN,
272  SWQCF_MAX = SWQ_MAX,
273  SWQCF_COUNT = SWQ_COUNT,
274  SWQCF_SUM = SWQ_SUM,
275  SWQCF_CUSTOM
276 } swq_col_func;
277 
278 typedef struct {
279  swq_col_func col_func;
280  char *table_name;
281  char *field_name;
282  char *field_alias;
283  int table_index;
284  int field_index;
285  swq_field_type field_type;
286  swq_field_type target_type;
287  OGRFieldSubType target_subtype;
288  int field_length;
289  int field_precision;
290  int distinct_flag;
291  OGRwkbGeometryType eGeomType;
292  int nSRID;
293  swq_expr_node *expr;
294 } swq_col_def;
295 
296 class swq_summary {
297 public:
298  struct Comparator
299  {
300  bool bSortAsc;
301  swq_field_type eType;
302 
303  Comparator() : bSortAsc(true), eType(SWQ_STRING) {}
304 
305  bool operator() (const CPLString&, const CPLString &) const;
306  };
307 
308  GIntBig count = 0;
309 
310  std::vector<CPLString> oVectorDistinctValues{};
311  std::set<CPLString, Comparator> oSetDistinctValues{};
312  double sum = 0.0;
313  double min = 0.0;
314  double max = 0.0;
315  CPLString osMin{};
316  CPLString osMax{};
317 };
318 
319 typedef struct {
320  char *table_name;
321  char *field_name;
322  int table_index;
323  int field_index;
324  int ascending_flag;
325 } swq_order_def;
326 
327 typedef struct {
328  int secondary_table;
329  swq_expr_node *poExpr;
330 } swq_join_def;
331 
332 class swq_select_parse_options
333 {
334 public:
335  swq_custom_func_registrar* poCustomFuncRegistrar;
336  int bAllowFieldsInSecondaryTablesInWhere;
337  int bAddSecondaryTablesGeometryFields;
338  int bAlwaysPrefixWithTableName;
339  int bAllowDistinctOnGeometryField;
340  int bAllowDistinctOnMultipleFields;
341 
342  swq_select_parse_options(): poCustomFuncRegistrar(nullptr),
343  bAllowFieldsInSecondaryTablesInWhere(FALSE),
344  bAddSecondaryTablesGeometryFields(FALSE),
345  bAlwaysPrefixWithTableName(FALSE),
346  bAllowDistinctOnGeometryField(FALSE),
347  bAllowDistinctOnMultipleFields(FALSE) {}
348 };
349 
350 class swq_select
351 {
352  void postpreparse();
353 
354  CPL_DISALLOW_COPY_ASSIGN(swq_select)
355 
356 public:
357  swq_select();
358  ~swq_select();
359 
360  int query_mode = 0;
361 
362  char *raw_select = nullptr;
363 
364  int PushField( swq_expr_node *poExpr, const char *pszAlias=nullptr,
365  int distinct_flag = FALSE );
366  int result_columns = 0;
367  swq_col_def *column_defs = nullptr;
368  std::vector<swq_summary> column_summary{};
369 
370  int PushTableDef( const char *pszDataSource,
371  const char *pszTableName,
372  const char *pszAlias );
373  int table_count = 0;
374  swq_table_def *table_defs = nullptr;
375 
376  void PushJoin( int iSecondaryTable, swq_expr_node* poExpr );
377  int join_count = 0;
378  swq_join_def *join_defs = nullptr;
379 
380  swq_expr_node *where_expr = nullptr;
381 
382  void PushOrderBy( const char* pszTableName, const char *pszFieldName, int bAscending );
383  int order_specs = 0;
384  swq_order_def *order_defs = nullptr;
385 
386  void SetLimit( GIntBig nLimit );
387  GIntBig limit = -1;
388 
389  void SetOffset( GIntBig nOffset );
390  GIntBig offset = 0;
391 
392  swq_select *poOtherSelect = nullptr;
393  void PushUnionAll( swq_select* poOtherSelectIn );
394 
395  CPLErr preparse( const char *select_statement,
396  int bAcceptCustomFuncs = FALSE );
397  CPLErr expand_wildcard( swq_field_list *field_list,
398  int bAlwaysPrefixWithTableName );
399  CPLErr parse( swq_field_list *field_list,
400  swq_select_parse_options* poParseOptions );
401 
402  char *Unparse();
403  void Dump( FILE * );
404 };
405 
406 CPLErr swq_select_parse( swq_select *select_info,
407  swq_field_list *field_list,
408  int parse_flags );
409 
410 const char *swq_select_summarize( swq_select *select_info,
411  int dest_column,
412  const char *value );
413 
414 int swq_is_reserved_keyword(const char* pszStr);
415 
416 char* OGRHStoreGetValue(const char* pszHStore, const char* pszSearchedKey);
417 
418 #endif /* #ifndef DOXYGEN_SKIP */
419 
420 #endif /* def SWQ_H_INCLUDED_ */
OGRFieldSubType
List of field subtypes.
Definition: ogr_core.h:622
Convenient string class based on std::string.
Definition: cpl_string.h:327
Various convenience functions for working with strings and string lists.
OGRwkbGeometryType
List of well known binary geometry types.
Definition: ogr_core.h:317
Abstract base class for all geometry classes.
Definition: ogr_geometry.h:286
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:248
CPLErr
Error category.
Definition: cpl_error.h:52
#define CPL_DISALLOW_COPY_ASSIGN(ClassName)
Helper to remove the copy and assignment constructors so that the compiler will not generate the defa...
Definition: cpl_port.h:989

Generated for GDAL by doxygen 1.8.8.