1 /*
2    Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #ifndef NDB_SCAN_FILTER_HPP
26 #define NDB_SCAN_FILTER_HPP
27 
28 #include <ndb_types.h>
29 #include "ndbapi_limits.h"
30 
31 #include "NdbInterpretedCode.hpp"
32 
33 /**
34  * @class NdbScanFilter
35  * @brief A simple way to specify filters for scan operations
36  *
37  * @note  This filter interface is under development and may change in
38  *        the future!
39  *
40  */
41 class NdbScanFilter {
42 public:
43   /**
44    * Constructor
45    * Using this constructor, a ScanFilter is created which will
46    * build and finalise a scan filter program using the
47    * NdbInterpretedCode object passed.
48    * Once defined, the generated NdbInterpretedCode object can
49    * be used to specify a scan filter for one or more NdbRecord defined
50    * ScanOperations on the supplied table.
51    * The NdbInterpretedCode object is passed to the ScanTable()
52    * or ScanIndex() call via the ScanOptions structure.
53    *
54    * @param code Pointer to the NdbInterpretedCode object to build
55    * the ScanFilter in.
56    */
57   NdbScanFilter(NdbInterpretedCode* code);
58 
59   /**
60    * Constructor
61    * This constructor is used to create an ScanFilter object
62    * for use with a non-NdbRecord defined ScanOperation.
63    *
64    * As part of the filter definition, it is automatically added
65    * to the supplied operation.
66    * ScanFilters defined this way can only be used with the passed
67    * Scan operation.
68    *
69    * @param op  The NdbOperation that the filter is applied to.
70    *            Note that this MUST be an NdbScanOperation or
71    *            NdbIndexScanOperation object created using the
72    *            NdbTransaction->getNdbScanOperation() or
73    *            NdbTransaciton->getNdbIndexScanOperation()
74    *            methods
75    */
76   NdbScanFilter(class NdbOperation * op);
77 
78   ~NdbScanFilter();
79 
80   /**
81    *  Group operators
82    */
83   enum Group {
84     AND  = 1,    ///< (x1 AND x2 AND x3)
85     OR   = 2,    ///< (x1 OR x2 OR X3)
86     NAND = 3,    ///< NOT (x1 AND x2 AND x3)
87     NOR  = 4     ///< NOT (x1 OR x2 OR x3)
88   };
89 
90   enum BinaryCondition
91   {
92     COND_LE = 0,           ///< lower bound
93     COND_LT = 1,           ///< lower bound, strict
94     COND_GE = 2,           ///< upper bound
95     COND_GT = 3,           ///< upper bound, strict
96     COND_EQ = 4,           ///< equality
97     COND_NE = 5,           ///< not equal
98     COND_LIKE = 6,         ///< like
99     COND_NOT_LIKE = 7,     ///< not like
100     COND_AND_EQ_MASK = 8,  ///< (bit & mask) == mask
101     COND_AND_NE_MASK = 9,  ///< (bit & mask) != mask (incl. NULL)
102     COND_AND_EQ_ZERO = 10, ///< (bit & mask) == 0
103     COND_AND_NE_ZERO = 11  ///< (bit & mask) != 0 (incl. NULL)
104   };
105 
106   /**
107    * @name Grouping
108    * @{
109    */
110 
111   /**
112    *  Begin of compound.
113    *  If no group type is passed, defaults to AND.
114    *  �return  0 if successful, -1 otherwise
115    */
116   int begin(Group group = AND);
117 
118   /**
119    *  End of compound.
120    *  �return  0 if successful, -1 otherwise
121    */
122   int end();
123 
124   /**
125    *  Reset the ScanFilter object, discarding any previous
126    *  filter definition and error state.
127    */
128   void reset();
129 
130   /** @} *********************************************************************/
131 
132   /**
133    *  Define one term of the current group as TRUE
134    *  �return  0 if successful, -1 otherwise
135    */
136   int istrue();
137 
138   /**
139    *  Define one term of the current group as FALSE
140    *  �return  0 if successful, -1 otherwise
141    */
142   int isfalse();
143 
144   /**
145    * Compare column <b>ColId</b> with <b>val</b>
146    *
147    * For all BinaryConditions except LIKE and NOT_LIKE, the value pointed
148    * to by val should be in normal column format as described in the
149    * documentation for NdbOperation::equal().
150    * For BinaryConditions LIKE and NOT_LIKE, the value pointed to by val
151    * should NOT include initial length bytes.
152    * For LIKE and NOT_LIKE, the % and ? wildcards are supported.
153    * For bitmask operations, see the bitmask format information against
154    * the branch_col_and_mask_eq_mask instruction in NdbInterpretedCode.hpp
155    *
156    *  �return  0 if successful, -1 otherwise
157    */
158   int cmp(BinaryCondition cond, int ColId, const void *val, Uint32 len = 0);
159 
160   /**
161    * Compare column <b>ColId1</b> with <b>ColId2</b>
162    *
163    * Compare two column which has to be of the exact same data type,
164    * including length, precision, scale etc, as relevant for each type.
165    * Only the comparison conditions EQ,NE,LT,LE,GT,GE are supported.
166    *
167    *  �return  0 if successful, -1 otherwise
168    */
169   int cmp(BinaryCondition cond, int ColId1, int ColId2);
170 
171   /**
172    * @name Integer Comparators
173    * @{
174    */
175   /** Compare column value with integer for equal
176    *  �return  0 if successful, -1 otherwise
177    */
eq(int ColId,Uint32 value)178   int eq(int ColId, Uint32 value) { return cmp(COND_EQ, ColId, &value, 4);}
179 
180   /** Compare column value with integer for not equal.
181    *  �return  0 if successful, -1 otherwise
182    */
ne(int ColId,Uint32 value)183   int ne(int ColId, Uint32 value) { return cmp(COND_NE, ColId, &value, 4);}
184   /** Compare column value with integer for less than.
185    *  �return  0 if successful, -1 otherwise
186    */
lt(int ColId,Uint32 value)187   int lt(int ColId, Uint32 value) { return cmp(COND_LT, ColId, &value, 4);}
188   /** Compare column value with integer for less than or equal.
189    *  �return  0 if successful, -1 otherwise
190    */
le(int ColId,Uint32 value)191   int le(int ColId, Uint32 value) { return cmp(COND_LE, ColId, &value, 4);}
192   /** Compare column value with integer for greater than.
193    *  �return  0 if successful, -1 otherwise
194    */
gt(int ColId,Uint32 value)195   int gt(int ColId, Uint32 value) { return cmp(COND_GT, ColId, &value, 4);}
196   /** Compare column value with integer for greater than or equal.
197    *  �return  0 if successful, -1 otherwise
198    */
ge(int ColId,Uint32 value)199   int ge(int ColId, Uint32 value) { return cmp(COND_GE, ColId, &value, 4);}
200 
201   /** Compare column value with integer for equal. 64-bit.
202    *  �return  0 if successful, -1 otherwise
203    */
eq(int ColId,Uint64 value)204   int eq(int ColId, Uint64 value) { return cmp(COND_EQ, ColId, &value, 8);}
205   /** Compare column value with integer for not equal. 64-bit.
206    *  �return  0 if successful, -1 otherwise
207    */
ne(int ColId,Uint64 value)208   int ne(int ColId, Uint64 value) { return cmp(COND_NE, ColId, &value, 8);}
209   /** Compare column value with integer for less than. 64-bit.
210    *  �return  0 if successful, -1 otherwise
211    */
lt(int ColId,Uint64 value)212   int lt(int ColId, Uint64 value) { return cmp(COND_LT, ColId, &value, 8);}
213   /** Compare column value with integer for less than or equal. 64-bit.
214    *  �return  0 if successful, -1 otherwise
215    */
le(int ColId,Uint64 value)216   int le(int ColId, Uint64 value) { return cmp(COND_LE, ColId, &value, 8);}
217   /** Compare column value with integer for greater than. 64-bit.
218    *  �return  0 if successful, -1 otherwise
219    */
gt(int ColId,Uint64 value)220   int gt(int ColId, Uint64 value) { return cmp(COND_GT, ColId, &value, 8);}
221   /** Compare column value with integer for greater than or equal. 64-bit.
222    *  �return  0 if successful, -1 otherwise
223    */
ge(int ColId,Uint64 value)224   int ge(int ColId, Uint64 value) { return cmp(COND_GE, ColId, &value, 8);}
225   /** @} *********************************************************************/
226 
227   /** Check if column value is NULL
228    *  �return  0 if successful, -1 otherwise
229    */
230   int isnull(int ColId);
231   /** Check if column value is non-NULL
232    *  �return  0 if successful, -1 otherwise
233    */
234   int isnotnull(int ColId);
235 
236   enum Error {
237     FilterTooLarge = 4294
238   };
239 
240   /**
241    * Get filter level error.
242    *
243    * Errors encountered when building a ScanFilter do not propagate
244    * to any involved NdbOperation object.  This method gives access
245    * to error information.
246    */
247   const struct NdbError & getNdbError() const;
248 
249   /**
250    * Get filter's associated InterpretedCode object.  For
251    * ScanFilters associated with a non-NdbRecord scan operation,
252    * this method always returns NULL.
253    */
254   const NdbInterpretedCode* getInterpretedCode() const;
255 
256   /**
257    * Get NdbScanFilter's associated NdbScanOperation
258    *
259    * Where the NdbScanFilter was constructed with an NdbOperation
260    * this method can be used to obtain a pointer to the NdbOperation
261    * object.
262    * For other NdbScanFilter objects it will return NULL
263    */
264   NdbOperation * getNdbOperation() const;
265 private:
266 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
267   friend class NdbScanFilterImpl;
268 #endif
269   class NdbScanFilterImpl & m_impl;
270   NdbScanFilter& operator=(const NdbScanFilter&); ///< Defined not implemented
271 };
272 
273 #endif
274