GDAL
swq.h
00001 /******************************************************************************
00002  *
00003  * Component: OGDI Driver Support Library
00004  * Purpose: Generic SQL WHERE Expression Evaluator Declarations.
00005  * Author: Frank Warmerdam <warmerdam@pobox.com>
00006  *
00007  ******************************************************************************
00008  * Copyright (C) 2001 Information Interoperability Institute (3i)
00009  * Copyright (c) 2010-2013, Even Rouault <even dot rouault at mines-paris dot org>
00010  * Permission to use, copy, modify and distribute this software and
00011  * its documentation for any purpose and without fee is hereby granted,
00012  * provided that the above copyright notice appear in all copies, that
00013  * both the copyright notice and this permission notice appear in
00014  * supporting documentation, and that the name of 3i not be used
00015  * in advertising or publicity pertaining to distribution of the software
00016  * without specific, written prior permission.  3i makes no
00017  * representations about the suitability of this software for any purpose.
00018  * It is provided "as is" without express or implied warranty.
00019  ****************************************************************************/
00020 
00021 #ifndef SWQ_H_INCLUDED_
00022 #define SWQ_H_INCLUDED_
00023 
00024 #ifndef DOXYGEN_SKIP
00025 
00026 #include "cpl_conv.h"
00027 #include "cpl_string.h"
00028 #include "ogr_core.h"
00029 
00030 #include <vector>
00031 #include <set>
00032 
00033 #if defined(_WIN32) && !defined(strcasecmp)
00034 #  define strcasecmp stricmp
00035 #endif
00036 
00037 // Used for swq_summary.oSetDistinctValues and oVectorDistinctValues
00038 #define SZ_OGR_NULL  "__OGR_NULL__"
00039 
00040 typedef enum {
00041     SWQ_OR,
00042     SWQ_AND,
00043     SWQ_NOT,
00044     SWQ_EQ,
00045     SWQ_NE,
00046     SWQ_GE,
00047     SWQ_LE,
00048     SWQ_LT,
00049     SWQ_GT,
00050     SWQ_LIKE,
00051     SWQ_ISNULL,
00052     SWQ_IN,
00053     SWQ_BETWEEN,
00054     SWQ_ADD,
00055     SWQ_SUBTRACT,
00056     SWQ_MULTIPLY,
00057     SWQ_DIVIDE,
00058     SWQ_MODULUS,
00059     SWQ_CONCAT,
00060     SWQ_SUBSTR,
00061     SWQ_HSTORE_GET_VALUE,
00062     SWQ_AVG,
00063     SWQ_MIN,
00064     SWQ_MAX,
00065     SWQ_COUNT,
00066     SWQ_SUM,
00067     SWQ_CAST,
00068     SWQ_CUSTOM_FUNC, /* only if parsing done in bAcceptCustomFuncs mode */
00069     SWQ_ARGUMENT_LIST /* temporary value only set during parsing and replaced by something else at the end */
00070 } swq_op;
00071 
00072 typedef enum {
00073     SWQ_INTEGER,
00074     SWQ_INTEGER64,
00075     SWQ_FLOAT,
00076     SWQ_STRING,
00077     SWQ_BOOLEAN,  // integer
00078     SWQ_DATE,     // string
00079     SWQ_TIME,     // string
00080     SWQ_TIMESTAMP,// string
00081     SWQ_GEOMETRY,
00082     SWQ_NULL,
00083     SWQ_OTHER,
00084     SWQ_ERROR
00085 } swq_field_type;
00086 
00087 #define SWQ_IS_INTEGER(x) ((x) == SWQ_INTEGER || (x) == SWQ_INTEGER64)
00088 
00089 typedef enum {
00090     SNT_CONSTANT,
00091     SNT_COLUMN,
00092     SNT_OPERATION
00093 } swq_node_type;
00094 
00095 class swq_field_list;
00096 class swq_expr_node;
00097 class swq_select;
00098 class OGRGeometry;
00099 
00100 typedef swq_expr_node *(*swq_field_fetcher)( swq_expr_node *op,
00101                                              void *record_handle );
00102 typedef swq_expr_node *(*swq_op_evaluator)(swq_expr_node *op,
00103                                            swq_expr_node **sub_field_values );
00104 typedef swq_field_type (*swq_op_checker)( swq_expr_node *op,
00105                                           int bAllowMismatchTypeOnFieldComparison );
00106 
00107 class swq_custom_func_registrar;
00108 
00109 class swq_expr_node {
00110 public:
00111     swq_expr_node();
00112 
00113     explicit swq_expr_node( const char * );
00114     explicit swq_expr_node( int );
00115     explicit swq_expr_node( GIntBig );
00116     explicit swq_expr_node( double );
00117     explicit swq_expr_node( OGRGeometry* );
00118     explicit swq_expr_node( swq_op );
00119 
00120     ~swq_expr_node();
00121 
00122     void           Initialize();
00123     void           MarkAsTimestamp();
00124     CPLString      UnparseOperationFromUnparsedSubExpr(char** apszSubExpr);
00125     char          *Unparse( swq_field_list *, char chColumnQuote );
00126     void           Dump( FILE *fp, int depth );
00127     swq_field_type Check( swq_field_list *, int bAllowFieldsInSecondaryTables,
00128                           int bAllowMismatchTypeOnFieldComparison,
00129                           swq_custom_func_registrar* poCustomFuncRegistrar );
00130     swq_expr_node* Evaluate( swq_field_fetcher pfnFetcher,
00131                              void *record );
00132     swq_expr_node* Clone();
00133 
00134     void           ReplaceBetweenByGEAndLERecurse();
00135 
00136     swq_node_type eNodeType;
00137     swq_field_type field_type;
00138 
00139     /* only for SNT_OPERATION */
00140     void        PushSubExpression( swq_expr_node * );
00141     void        ReverseSubExpressions();
00142     int         nOperation;
00143     int         nSubExprCount;
00144     swq_expr_node **papoSubExpr;
00145 
00146     /* only for SNT_COLUMN */
00147     int         field_index;
00148     int         table_index;
00149     char        *table_name;
00150 
00151     /* only for SNT_CONSTANT */
00152     int         is_null;
00153     GIntBig     int_value;
00154     double      float_value;
00155     OGRGeometry *geometry_value;
00156 
00157     /* shared by SNT_COLUMN, SNT_CONSTANT and also possibly SNT_OPERATION when */
00158     /* nOperation == SWQ_CUSTOM_FUNC */
00159     char        *string_value; /* column name when SNT_COLUMN */
00160 
00161     static CPLString   QuoteIfNecessary( const CPLString &, char chQuote = '\'' );
00162     static CPLString   Quote( const CPLString &, char chQuote = '\'' );
00163 };
00164 
00165 typedef struct {
00166     const char*      pszName;
00167     swq_op           eOperation;
00168     swq_op_evaluator pfnEvaluator;
00169     swq_op_checker   pfnChecker;
00170 } swq_operation;
00171 
00172 class swq_op_registrar {
00173 public:
00174     static const swq_operation *GetOperator( const char * );
00175     static const swq_operation *GetOperator( swq_op eOperation );
00176 };
00177 
00178 class swq_custom_func_registrar
00179 {
00180     public:
00181         virtual ~swq_custom_func_registrar() {}
00182         virtual const swq_operation *GetOperator( const char * ) = 0;
00183 };
00184 
00185 typedef struct {
00186     char       *data_source;
00187     char       *table_name;
00188     char       *table_alias;
00189 } swq_table_def;
00190 
00191 class swq_field_list {
00192 public:
00193     int count;
00194     char **names;
00195     swq_field_type *types;
00196     int *table_ids;
00197     int *ids;
00198 
00199     int table_count;
00200     swq_table_def *table_defs;
00201 };
00202 
00203 class swq_parse_context {
00204 public:
00205     swq_parse_context() : nStartToken(0), pszInput(NULL), pszNext(NULL),
00206                           pszLastValid(NULL), bAcceptCustomFuncs(FALSE),
00207                           poRoot(NULL), poCurSelect(NULL) {}
00208 
00209     int        nStartToken;
00210     const char *pszInput;
00211     const char *pszNext;
00212     const char *pszLastValid;
00213     int        bAcceptCustomFuncs;
00214 
00215     swq_expr_node *poRoot;
00216 
00217     swq_select    *poCurSelect;
00218 };
00219 
00220 /* Compile an SQL WHERE clause into an internal form.  The field_list is
00221 ** the list of fields in the target 'table', used to render where into
00222 ** field numbers instead of names.
00223 */
00224 int swqparse( swq_parse_context *context );
00225 int swqlex( swq_expr_node **ppNode, swq_parse_context *context );
00226 void swqerror( swq_parse_context *context, const char *msg );
00227 
00228 int swq_identify_field( const char* table_name,
00229                         const char *token, swq_field_list *field_list,
00230                         swq_field_type *this_type, int *table_id );
00231 
00232 CPLErr swq_expr_compile( const char *where_clause,
00233                          int field_count,
00234                          char **field_list,
00235                          swq_field_type *field_types,
00236                          int bCheck,
00237                          swq_custom_func_registrar* poCustomFuncRegistrar,
00238                          swq_expr_node **expr_root );
00239 
00240 CPLErr swq_expr_compile2( const char *where_clause,
00241                           swq_field_list *field_list,
00242                           int bCheck,
00243                           swq_custom_func_registrar* poCustomFuncRegistrar,
00244                           swq_expr_node **expr_root );
00245 
00246 /*
00247 ** Evaluation related.
00248 */
00249 int swq_test_like( const char *input, const char *pattern );
00250 
00251 swq_expr_node *SWQGeneralEvaluator( swq_expr_node *, swq_expr_node **);
00252 swq_field_type SWQGeneralChecker( swq_expr_node *node, int bAllowMismatchTypeOnFieldComparison );
00253 swq_expr_node *SWQCastEvaluator( swq_expr_node *, swq_expr_node **);
00254 swq_field_type SWQCastChecker( swq_expr_node *node, int bAllowMismatchTypeOnFieldComparison );
00255 const char*    SWQFieldTypeToString( swq_field_type field_type );
00256 
00257 /****************************************************************************/
00258 
00259 #define SWQP_ALLOW_UNDEFINED_COL_FUNCS 0x01
00260 
00261 #define SWQM_SUMMARY_RECORD  1
00262 #define SWQM_RECORDSET       2
00263 #define SWQM_DISTINCT_LIST   3
00264 
00265 typedef enum {
00266     SWQCF_NONE = 0,
00267     SWQCF_AVG = SWQ_AVG,
00268     SWQCF_MIN = SWQ_MIN,
00269     SWQCF_MAX = SWQ_MAX,
00270     SWQCF_COUNT = SWQ_COUNT,
00271     SWQCF_SUM = SWQ_SUM,
00272     SWQCF_CUSTOM
00273 } swq_col_func;
00274 
00275 typedef struct {
00276     swq_col_func col_func;
00277     char         *table_name;
00278     char         *field_name;
00279     char         *field_alias;
00280     int          table_index;
00281     int          field_index;
00282     swq_field_type field_type;
00283     swq_field_type target_type;
00284     OGRFieldSubType target_subtype;
00285     int          field_length;
00286     int          field_precision;
00287     int          distinct_flag;
00288     OGRwkbGeometryType eGeomType;
00289     int          nSRID;
00290     swq_expr_node *expr;
00291 } swq_col_def;
00292 
00293 class swq_summary {
00294 public:
00295     struct Comparator
00296     {
00297         bool    bSortAsc;
00298         swq_field_type eType;
00299 
00300         Comparator() : bSortAsc(true), eType(SWQ_STRING) {}
00301 
00302         bool    operator() (const CPLString&, const CPLString &) const;
00303     };
00304 
00305     GIntBig     count;
00306 
00307     std::vector<CPLString>          oVectorDistinctValues;
00308     std::set<CPLString, Comparator> oSetDistinctValues;
00309     double      sum;
00310     double      min;
00311     double      max;
00312     CPLString   osMin;
00313     CPLString   osMax;
00314 
00315         swq_summary() : count(0), sum(0.0), min(0.0), max(0.0) {}
00316 };
00317 
00318 typedef struct {
00319     char *table_name;
00320     char *field_name;
00321     int   table_index;
00322     int   field_index;
00323     int   ascending_flag;
00324 } swq_order_def;
00325 
00326 typedef struct {
00327     int        secondary_table;
00328     swq_expr_node  *poExpr;
00329 } swq_join_def;
00330 
00331 class swq_select_parse_options
00332 {
00333 public:
00334     swq_custom_func_registrar* poCustomFuncRegistrar;
00335     int                        bAllowFieldsInSecondaryTablesInWhere;
00336     int                        bAddSecondaryTablesGeometryFields;
00337     int                        bAlwaysPrefixWithTableName;
00338     int                        bAllowDistinctOnGeometryField;
00339     int                        bAllowDistinctOnMultipleFields;
00340 
00341                     swq_select_parse_options(): poCustomFuncRegistrar(NULL),
00342                                                 bAllowFieldsInSecondaryTablesInWhere(FALSE),
00343                                                 bAddSecondaryTablesGeometryFields(FALSE),
00344                                                 bAlwaysPrefixWithTableName(FALSE),
00345                                                 bAllowDistinctOnGeometryField(FALSE),
00346                                                 bAllowDistinctOnMultipleFields(FALSE) {}
00347 };
00348 
00349 class swq_select
00350 {
00351     void        postpreparse();
00352 
00353 public:
00354     swq_select();
00355     ~swq_select();
00356 
00357     int         query_mode;
00358 
00359     char        *raw_select;
00360 
00361     int         PushField( swq_expr_node *poExpr, const char *pszAlias=NULL,
00362                            int distinct_flag = FALSE );
00363     int         result_columns;
00364     swq_col_def *column_defs;
00365     std::vector<swq_summary> column_summary;
00366 
00367     int         PushTableDef( const char *pszDataSource,
00368                               const char *pszTableName,
00369                               const char *pszAlias );
00370     int         table_count;
00371     swq_table_def *table_defs;
00372 
00373     void        PushJoin( int iSecondaryTable, swq_expr_node* poExpr );
00374     int         join_count;
00375     swq_join_def *join_defs;
00376 
00377     swq_expr_node *where_expr;
00378 
00379     void        PushOrderBy( const char* pszTableName, const char *pszFieldName, int bAscending );
00380     int         order_specs;
00381     swq_order_def *order_defs;
00382 
00383     void        SetLimit( GIntBig nLimit );
00384     GIntBig     limit;
00385 
00386     void        SetOffset( GIntBig nOffset );
00387     GIntBig     offset;
00388 
00389     swq_select *poOtherSelect;
00390     void        PushUnionAll( swq_select* poOtherSelectIn );
00391 
00392     CPLErr      preparse( const char *select_statement,
00393                           int bAcceptCustomFuncs = FALSE );
00394     CPLErr      expand_wildcard( swq_field_list *field_list,
00395                                  int bAlwaysPrefixWithTableName );
00396     CPLErr      parse( swq_field_list *field_list,
00397                        swq_select_parse_options* poParseOptions );
00398 
00399     char       *Unparse();
00400     void        Dump( FILE * );
00401 };
00402 
00403 CPLErr swq_select_parse( swq_select *select_info,
00404                          swq_field_list *field_list,
00405                          int parse_flags );
00406 
00407 const char *swq_select_summarize( swq_select *select_info,
00408                                   int dest_column,
00409                                   const char *value );
00410 
00411 int swq_is_reserved_keyword(const char* pszStr);
00412 
00413 char* OGRHStoreGetValue(const char* pszHStore, const char* pszSearchedKey);
00414 
00415 #endif /* #ifndef DOXYGEN_SKIP */
00416 
00417 #endif /* def SWQ_H_INCLUDED_ */

Generated for GDAL by doxygen 1.7.6.1.