1 /*
2    Copyright (c) 2004, 2021, Oracle and/or its affiliates.
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_QUERY_TREE_HPP
26 #define NDB_QUERY_TREE_HPP
27 
28 #include <ndb_global.h>
29 #include <ndb_types.h>
30 
31 #define JAM_FILE_ID 129
32 
33 
34 struct QueryNode  // Effectively used as a base class for QN_xxxNode
35 {
36   Uint32 len;
37   Uint32 requestInfo;
38   Uint32 tableId;      // 16-bit
39   Uint32 tableVersion;
40 
41   enum OpType
42   {
43     QN_LOOKUP     = 0x1,
44     QN_SCAN_FRAG  = 0x2,
45     QN_SCAN_INDEX = 0x3,
46     QN_END = 0
47   };
48 
getOpTypeQueryNode49   static Uint32 getOpType(Uint32 op_len) { return op_len & 0xFFFF;}
getLengthQueryNode50   static Uint32 getLength(Uint32 op_len) { return op_len >> 16;}
51 
setOpLenQueryNode52   static void setOpLen(Uint32 &d, Uint32 o, Uint32 l) { d = (l << 16) | o;}
53 
54   // If possible we should change the above static methods to non-static:
55 //Uint32 getOpType() const { return len & 0xFFFF;}
56 //Uint32 getLength() const { return len >> 16;}
57 //void setOpLen(Uint32 o, Uint32 l) { len = (l << 16) | o;}
58 };
59 
60 struct QueryNodeParameters  // Effectively used as a base class for QN_xxxParameters
61 {
62   Uint32 len;
63   Uint32 requestInfo;
64   Uint32 resultData;   // Api connect ptr
65 
66   enum OpType
67   {
68     QN_LOOKUP     = 0x1,
69     QN_SCAN_FRAG  = 0x2,
70     QN_SCAN_INDEX = 0x3,
71     QN_END = 0
72   };
73 
getOpTypeQueryNodeParameters74   static Uint32 getOpType(Uint32 op_len) { return op_len & 0xFFFF;}
getLengthQueryNodeParameters75   static Uint32 getLength(Uint32 op_len) { return op_len >> 16;}
76 
setOpLenQueryNodeParameters77   static void setOpLen(Uint32 &d, Uint32 o, Uint32 l) { d = (l << 16) | o;}
78 
79   // If possible we should change the above static methods to non-static:
80 //Uint32 getOpType() const { return len & 0xFFFF;}
81 //Uint32 getLength() const { return len >> 16;}
82 //void setOpLen(Uint32 o, Uint32 l) { len = (l << 16) | o;}
83 };
84 
85 struct DABits
86 {
87   /**
88    * List of requestInfo bits shared for QN_LookupNode,
89    * QN_ScanFragNode & QN_ScanIndexNode
90    */
91   enum NodeInfoBits
92   {
93     NI_HAS_PARENT     = 0x01,
94 
95     NI_KEY_LINKED     = 0x02,  // Does keyinfo contain linked values
96     NI_KEY_PARAMS     = 0x04,  // Does keyinfo contain parameters
97     NI_KEY_CONSTS     = 0x08,  // Does keyinfo contain const values
98 
99     NI_LINKED_ATTR    = 0x10,  // List of attributes to be used by children
100 
101     NI_ATTR_INTERPRET = 0x20,  // Is attr-info a interpreted program
102     NI_ATTR_PARAMS    = 0x40,  // Does attrinfo contain parameters
103     NI_ATTR_LINKED    = 0x80,  // Does attrinfo contain linked values
104 
105     /**
106      * Iff this flag is set, then this operation has a child operation with a
107      * linked value that refes to a disk column of this operation. For example
108      * SELECT * FROM t1, t2 WHERE t1.disk_att = t2.primary_key;
109      */
110     NI_LINKED_DISK    = 0x100,
111 
112     /**
113      * If REPEAT_SCAN_RESULT is set, multiple star-joined (or bushy, or X)
114      * scan results are handled by repeating the other scans result
115      * when we advance to the next batch chunk for the current 'active'
116      * result set.
117      * This removes the requirement for the API client to being able
118      * buffer an (possible huge) amount of scan result relating to
119      * the same parent scan.
120      */
121     NI_REPEAT_SCAN_RESULT = 0x200,
122 
123     NI_END = 0
124   };
125 
126   /**
127    * List of requestInfo bits shared for QN_LookupParameters,
128    * QN_ScanFragParameters & QN_ScanIndexParameters
129    */
130   enum ParamInfoBits
131   {
132     PI_ATTR_LIST   = 0x1, // "user" projection list
133 
134     /**
135      * These 2 must match their resp. QueryNode-definitions
136      */
137     PI_ATTR_PARAMS = 0x2, // attr-info parameters (NI_ATTR_PARAMS)
138     PI_KEY_PARAMS  = 0x4, // key-info parameters  (NI_KEY_PARAMS)
139 
140     /**
141      * The parameter object contains a program that will be interpreted
142      * before reading the attributes (i.e. a scan filter).
143      * NOTE: Can/should not be used if QueryNode contains interpreted program
144      */
145     PI_ATTR_INTERPRET = 0x8,
146 
147     /**
148      * Iff this flag is set, then the user projection for this operation
149      * contains at least one disk column.
150      */
151     PI_DISK_ATTR = 0x10,
152     PI_END = 0
153   };
154 };
155 
156 
157 /**
158  * This node describes a pk-lookup
159  */
160 struct QN_LookupNode // Is a QueryNode subclass
161 {
162   Uint32 len;
163   Uint32 requestInfo;
164   Uint32 tableId;      // 16-bit
165   Uint32 tableVersion;
166   STATIC_CONST ( NodeSize = 4 );
167 
168   /**
169    * See DABits::NodeInfoBits
170    */
171   Uint32 optional[1];
172 
173   enum LookupBits
174   {
175     /**
176      * This is lookup on index table,
177      */
178     L_UNIQUE_INDEX = 0x10000,
179 
180     L_END = 0
181   };
182 
183 //Uint32 getLength() const { return len >> 16;}
184 //void setOpLen(Uint32 o, Uint32 l) { len = (l << 16) | o;}
185 };
186 
187 /**
188  * This struct describes parameters that are associated with
189  *  a QN_LookupNode
190  */
191 struct QN_LookupParameters // Is a QueryNodeParameters subclass
192 {
193   Uint32 len;
194   Uint32 requestInfo;
195   Uint32 resultData;   // Api connect ptr
196   STATIC_CONST ( NodeSize = 3 );
197 
198   /**
199    * See DABits::ParamInfoBits
200    */
201   Uint32 optional[1];
202 };
203 
204 /**
205  * This node describes a table/index-fragment scan
206  */
207 struct QN_ScanFragNode // Is a QueryNode subclass
208 {
209   Uint32 len;
210   Uint32 requestInfo;
211   Uint32 tableId;      // 16-bit
212   Uint32 tableVersion;
213   STATIC_CONST ( NodeSize = 4 );
214 
215   /**
216    * See DABits::NodeInfoBits
217    */
218   Uint32 optional[1];
219 };
220 
221 /**
222  * This struct describes parameters that are associated with
223  *  a QN_ScanFragNode
224  */
225 struct QN_ScanFragParameters // Is a QueryNodeParameters subclass
226 {
227   Uint32 len;
228   Uint32 requestInfo;
229   Uint32 resultData;   // Api connect ptr
230   STATIC_CONST ( NodeSize = 3 );
231 
232   /**
233    * See DABits::ParamInfoBits
234    */
235   Uint32 optional[1];
236 };
237 
238 /**
239  * This node describes a IndexScan
240  */
241 struct QN_ScanIndexNode
242 {
243   Uint32 len;
244   Uint32 requestInfo;
245   Uint32 tableId;      // 16-bit
246   Uint32 tableVersion;
247   STATIC_CONST( NodeSize = 4 );
248 
249   enum ScanIndexBits
250   {
251     /**
252      * If doing equality search that can be pruned
253      *   a pattern that creates the key to hash with is stored before
254      *   the DA optional part
255      */
256     SI_PRUNE_PATTERN = 0x10000,
257 
258     // Do pattern contain parameters
259     SI_PRUNE_PARAMS = 0x20000,
260 
261     // Is prune pattern dependant on parent key (or only on parameters / constants)
262     SI_PRUNE_LINKED = 0x40000,
263 
264     // Should it be parallel scan (can also be set as in parameters)
265     SI_PARALLEL = 0x80000,
266 
267     SI_END = 0
268   };
269 
270   /**
271    * See DABits::NodeInfoBits
272    */
273   Uint32 optional[1];
274 };
275 
276 /**
277  * This struct describes parameters that are associated with
278  *  a QN_ScanIndexNode
279  */
280 struct QN_ScanIndexParameters
281 {
282   Uint32 len;
283   Uint32 requestInfo;
284   Uint32 batchSize;    // (bytes << 11) | (rows)
285   Uint32 resultData;   // Api connect ptr
286   STATIC_CONST ( NodeSize = 4 );
287   // Number of bits for representing row count in 'batchSize'.
288   STATIC_CONST ( BatchRowBits = 11 );
289 
290   enum ScanIndexParamBits
291   {
292     /**
293      * Do arguments contain parameters for prune-pattern
294      */
295     SIP_PRUNE_PARAMS = 0x10000,
296 
297     /**
298      * Should it scan index in parallel
299      *   This is needed for "multi-cursor" semantics
300      *   with (partial) ordering
301      */
302     SIP_PARALLEL = 0x20000,
303 
304     SIP_END = 0
305   };
306 
307   /**
308    * See DABits::ParamInfoBits
309    */
310   Uint32 optional[1];
311 };
312 
313 /**
314  * This is the definition of a QueryTree
315  */
316 struct QueryTree
317 {
318   Uint32 cnt_len;  // Length in words describing full tree + #nodes
319   Uint32 nodes[1]; // The nodes
320 
getNodeCntQueryTree321   static Uint32 getNodeCnt(Uint32 cnt_len) { return cnt_len & 0xFFFF;}
getLengthQueryTree322   static Uint32 getLength(Uint32 cnt_len) { return cnt_len >> 16;}
setCntLenQueryTree323   static void setCntLen(Uint32 &d, Uint32 c, Uint32 l) { d=(l << 16) | c;}
324 };
325 
326 /**
327  * This is description of *one* entry in a QueryPattern
328  *   (used by various QueryNodes)
329  */
330 struct QueryPattern
331 {
332   Uint32 m_info;
333   enum
334   {
335     P_DATA   = 0x1,  // Raw data of len-words (constants)
336     P_COL    = 0x2,  // Get column value from RowRef
337     P_UNQ_PK = 0x3,  // NDB$PK column from a unique index
338     P_PARAM  = 0x4,  // User specified parameter value
339     P_PARENT = 0x5,  // Move up in tree
340     P_PARAM_HEADER = 0x6, // User specified param val including AttributeHeader
341     P_ATTRINFO = 0x7,// Get column including header from RowRef
342     P_END    = 0
343   };
344 
getTypeQueryPattern345   static Uint32 getType(const Uint32 info) { return info >> 16;}
346 
347   /**
348    * If type == DATA, get len here
349    */
getLengthQueryPattern350   static Uint32 getLength(Uint32 info) { return info & 0xFFFF;}
dataQueryPattern351   static Uint32 data(Uint32 length)
352   {
353     assert(length <= 0xFFFF);
354     return (P_DATA << 16) | length;
355   }
356 
357   /**
358    * If type == COL, get col-no here (index in row)
359    */
getColNoQueryPattern360   static Uint32 getColNo(Uint32 info) { return info & 0xFFFF;}
colQueryPattern361   static Uint32 col(Uint32 no) { return (P_COL << 16) | no; }
362 
363   /**
364    * If type == P_UNQ_PK, get PK value from composite NDB$PK col.
365    */
colPkQueryPattern366   static Uint32 colPk(Uint32 no) {  return (P_UNQ_PK << 16) | no; }
367 
368   /**
369    * If type == PARAM, get param-no here (index in param list)
370    */
getParamNoQueryPattern371   static Uint32 getParamNo(Uint32 info) { return info & 0xFFFF;}
paramQueryPattern372   static Uint32 param(Uint32 no) { return (P_PARAM << 16) | no; }
373 
paramHeaderQueryPattern374   static Uint32 paramHeader(Uint32 no) { return (P_PARAM_HEADER << 16) | no; }
375 
376   /**
377    * get col including header
378    */
attrInfoQueryPattern379   static Uint32 attrInfo(Uint32 no) { return (P_ATTRINFO << 16) | no;}
380 
381   /**
382    * Move to grand-parent no
383    * (0 == imediate parent)
384    */
parentQueryPattern385   static Uint32 parent(Uint32 no) { return (P_PARENT << 16) | no;}
386 };
387 
388 
389 #undef JAM_FILE_ID
390 
391 #endif
392