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

Generated for GDAL by doxygen 1.8.17.