1 /******************************************************************************
2 *
3 * Component: OGR SQL Engine
4 * Purpose: Implementation of the swq_op_registrar class used to
5 * represent operations possible in an SQL expression.
6 * Author: Frank Warmerdam <warmerdam@pobox.com>
7 *
8 ******************************************************************************
9 * Copyright (C) 2010 Frank Warmerdam <warmerdam@pobox.com>
10 * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
29 ****************************************************************************/
30
31 #include "cpl_port.h"
32 #include "ogr_swq.h"
33
34 #include <cstddef>
35
36 #include "cpl_conv.h"
37 #include "cpl_error.h"
38
39 CPL_CVSID("$Id: swq_op_registrar.cpp ffd62ee1bdeed41a9301102c35b3c0eb30a36dc2 2019-11-28 16:56:51 +0100 Even Rouault $")
40
41 //! @cond Doxygen_Suppress
42 static swq_field_type SWQColumnFuncChecker(
43 swq_expr_node *poNode, int bAllowMismatchTypeOnFieldComparison );
44
45 static const swq_operation swq_apsOperations[] =
46 {
47 { "OR", SWQ_OR, SWQGeneralEvaluator, SWQGeneralChecker },
48 { "AND", SWQ_AND, SWQGeneralEvaluator, SWQGeneralChecker },
49 { "NOT", SWQ_NOT , SWQGeneralEvaluator, SWQGeneralChecker },
50 { "=", SWQ_EQ , SWQGeneralEvaluator, SWQGeneralChecker },
51 { "<>", SWQ_NE , SWQGeneralEvaluator, SWQGeneralChecker },
52 { ">=", SWQ_GE , SWQGeneralEvaluator, SWQGeneralChecker },
53 { "<=", SWQ_LE , SWQGeneralEvaluator, SWQGeneralChecker },
54 { "<", SWQ_LT , SWQGeneralEvaluator, SWQGeneralChecker },
55 { ">", SWQ_GT , SWQGeneralEvaluator, SWQGeneralChecker },
56 { "LIKE", SWQ_LIKE , SWQGeneralEvaluator, SWQGeneralChecker },
57 { "ILIKE", SWQ_ILIKE , SWQGeneralEvaluator, SWQGeneralChecker },
58 { "IS NULL", SWQ_ISNULL , SWQGeneralEvaluator, SWQGeneralChecker },
59 { "IN", SWQ_IN , SWQGeneralEvaluator, SWQGeneralChecker },
60 { "BETWEEN", SWQ_BETWEEN , SWQGeneralEvaluator, SWQGeneralChecker },
61 { "+", SWQ_ADD , SWQGeneralEvaluator, SWQGeneralChecker },
62 { "-", SWQ_SUBTRACT , SWQGeneralEvaluator, SWQGeneralChecker },
63 { "*", SWQ_MULTIPLY , SWQGeneralEvaluator, SWQGeneralChecker },
64 { "/", SWQ_DIVIDE , SWQGeneralEvaluator, SWQGeneralChecker },
65 { "%", SWQ_MODULUS , SWQGeneralEvaluator, SWQGeneralChecker },
66 { "CONCAT", SWQ_CONCAT , SWQGeneralEvaluator, SWQGeneralChecker },
67 { "SUBSTR", SWQ_SUBSTR , SWQGeneralEvaluator, SWQGeneralChecker },
68 { "HSTORE_GET_VALUE", SWQ_HSTORE_GET_VALUE , SWQGeneralEvaluator,
69 SWQGeneralChecker },
70
71 { "AVG", SWQ_AVG, SWQGeneralEvaluator, SWQColumnFuncChecker },
72 { "MIN", SWQ_MIN, SWQGeneralEvaluator, SWQColumnFuncChecker },
73 { "MAX", SWQ_MAX, SWQGeneralEvaluator, SWQColumnFuncChecker },
74 { "COUNT", SWQ_COUNT, SWQGeneralEvaluator, SWQColumnFuncChecker },
75 { "SUM", SWQ_SUM, SWQGeneralEvaluator, SWQColumnFuncChecker },
76
77 { "CAST", SWQ_CAST, SWQCastEvaluator, SWQCastChecker }
78 };
79
80 /************************************************************************/
81 /* GetOperator() */
82 /************************************************************************/
83
GetOperator(const char * pszName)84 const swq_operation *swq_op_registrar::GetOperator( const char *pszName )
85
86 {
87 for( const auto& op: swq_apsOperations )
88 {
89 if( EQUAL(pszName, op.pszName) )
90 return &op;
91 }
92
93 return nullptr;
94 }
95
96 /************************************************************************/
97 /* GetOperator() */
98 /************************************************************************/
99
GetOperator(swq_op eOperator)100 const swq_operation *swq_op_registrar::GetOperator( swq_op eOperator )
101
102 {
103 for( const auto& op: swq_apsOperations )
104 {
105 if( eOperator == op.eOperation )
106 return &op;
107 }
108
109 return nullptr;
110 }
111
112 /************************************************************************/
113 /* SWQColumnFuncChecker() */
114 /* */
115 /* Column summary functions are not legal in any context except */
116 /* as a root operator on column definitions. They are removed */
117 /* from this tree before checking so we just need to issue an */
118 /* error if they are used in any other context. */
119 /************************************************************************/
120
SWQColumnFuncChecker(swq_expr_node * poNode,int)121 static swq_field_type SWQColumnFuncChecker(
122 swq_expr_node *poNode, int /* bAllowMismatchTypeOnFieldComparison */ )
123 {
124 const swq_operation *poOp =
125 swq_op_registrar::GetOperator(static_cast<swq_op>(poNode->nOperation));
126 CPLError( CE_Failure, CPLE_AppDefined,
127 "Column Summary Function '%s' found in an inappropriate context.",
128 poOp != nullptr ? poOp->pszName : "" );
129 return SWQ_ERROR;
130 }
131 //! @endcond
132