NCBI C++ ToolKit
query_func_promote.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef GUI_OBJUTILS___QUERY_FUNC_PROMOTE_HPP
2 #define GUI_OBJUTILS___QUERY_FUNC_PROMOTE_HPP
3 /* $Id: query_func_promote.hpp 39115 2017-08-01 18:58:09Z asztalos $
4  * ===========================================================================
5  *
6  * PUBLIC DOMAIN NOTICE
7  * National Center for Biotechnology Information
8  *
9  * This software/database is a "United States Government Work" under the
10  * terms of the United States Copyright Act. It was written as part of
11  * the author's official duties as a United States Government employee and
12  * thus cannot be copyrighted. This software/database is freely available
13  * to the public for use. The National Library of Medicine and the U.S.
14  * Government have not placed any restriction on its use or reproduction.
15  *
16  * Although all reasonable efforts have been taken to ensure the accuracy
17  * and reliability of the software and data, the NLM and the U.S.
18  * Government do not and cannot warrant the performance or results that
19  * may be obtained by using this software or data. The NLM and the U.S.
20  * Government disclaim all warranties, express or implied, including
21  * warranties of performance, merchantability or fitness for any particular
22  * purpose.
23  *
24  * Please cite the author in any work or product based on this material.
25  *
26  * ===========================================================================
27  *
28  * Authors: Bob Falk
29  *
30  * File Description:
31  * Header file for classes needed to implement query execution using a
32  * type-promotion approach for comparisons
33  *
34  */
35 #include <corelib/ncbistl.hpp>
36 
37 #include <gui/gui_export.h>
38 
39 #include <objmgr/scope.hpp>
40 
45 
47 
48 ////////////////////////////////////////////////////////////////////////////////
49 /// class CQueryFuncPromoteBase
50 ///
51 /// Base class for query execution functions. The base class holds
52 /// the type-promotion rules needed to convert types appropriately to allow
53 /// for different kinds of comparisons.
55 {
56 public:
58 
60  : m_CaseSensitive(NStr::eCase)
61  , m_StringMatchAlgo(CStringMatching::ePlainSearch) {}
62 
63  /// Get/set case sensitivity for all string compares for this function
64  void SetCaseSensitive(NStr::ECase e) {m_CaseSensitive = e;}
65  NStr::ECase GetCaseSensitive() const { return m_CaseSensitive; }
66 
67  /// Get/set string matching algorithm
68  void SetStringMatching(CStringMatching::EStringMatching m) {m_StringMatchAlgo = m;}
69  CStringMatching::EStringMatching GetStringMatching() const { return m_StringMatchAlgo; }
70 
71  /// Get the user object for node 'qnode' or NULL if not created
72  TEvalResult* GetQueryNodeValue(CQueryParseTree::TNode& qnode);
73 
74  /// Get user object for 'qnode' or create a new object if it doesn't exist
75  TEvalResult* MakeQueryNodeValue(CQueryParseTree::TNode& qnode);
76 
77  /// Resolve, if possible, the data type for the query node tr and,
78  /// for operator nodes (e.g. ==, <), determine if possible types
79  /// to be used for comparison (not always possible for untyped data
80  /// from data source)
81  void PreProcess(CQueryParseTree::TNode& tr, objects::CScope* scope);
82 
83  /// For the operator in 'qnode', retrive from data source (if ncessary)
84  /// the data values arg1 and arg2 and promote the values, if needed, to
85  /// the required type needed for comparison.
87  ResolveAndPromote(size_t comparison_idx,
90  CQueryParseTree::TNode* arg2);
91 
92  /// Given data from two nodes and a comparison operator (e.g. <, ==, >..)
93  /// determine the best type for comparing them (e.g. if one is a string
94  /// and one is an integer should they be compared as strings, integers, or
95  /// not at all).
97  GetPromotedType(const CPromoteRule& pr);
98 
99  /// Get the value of a field from the data source and store the
100  /// result in the CQueryNodeValue object. Returns true on success.
101  bool ResolveFieldValue(TEvalResult& tree_val);
102 
103  /// Given data for a node, determine its underlying data type (e.g. if
104  /// its a string, can it also be converted to a bool? int? float?).
105  /// Returns false when field not present in data source.
106  bool SetCompareType(TEvalResult& tree_value);
107 
108  // functions which do not take 2 arguments (e.g. 'In', 'Not'), should
109  // override these functions.
110  virtual size_t GetArgCountMin(CQueryParseNode::EType /* t */) { return 2; }
111  virtual size_t GetArgCountMax(CQueryParseNode::EType /* t */) { return 2; }
112 
113 protected:
114 
115  /// Add the promtion rules for both 'type1 op type2' and 'type2 op type1'
116  void AddPromoteTypes(CQueryParseNode::EType op,
120 
121  /// Vector of sorted promotion rules
122  std::vector<CPromoteRule> m_PromoteRules;
123 
124  /// If true, all string comparisons by subclasses will use case-sensitive
125  /// comparisons, otherwise not.
127 
128  /// Determines how string equality comaparisons will be handled (wildcards, regex, exact..)
130 };
131 
132 ///////////////////////////////////////////////////////////////////////////////
133 /// Query execution function for run-time variables.
134 /// It represents variable which can be met in left and right side of expression.
135 ///
137 {
138 public:
139  /// Function is a placeholder for run-time variable processing
140  virtual void Evaluate(CQueryParseTree::TNode& qnode);
141 };
142 
143 ///////////////////////////////////////////////////////////////////////////////
144 /// Query execution function for assignment operator.
145 ///
147 {
148 public:
149  /// Function implements the assignment operator
150  virtual void Evaluate(CQueryParseTree::TNode& node);
151 };
152 
153 ///////////////////////////////////////////////////////////////////////////////
154 /// class CQueryFuncFunction
155 ///
156 /// Class implements functions calls in the do section of macro
158 {
159 public:
160  /// Function implements functions calls in the do section of macro
161  virtual void Evaluate(CQueryParseTree::TNode& qnode);
162 };
163 
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 /// class CQueryFuncPromoteValue
167 ///
168 /// Query execution function for simple atomic values. These are
169 /// 'leaf' nodes of the query tree.
171 {
172 public:
174 
175  ///
176  /// Create the user object for the node if it does not yet exist
177  /// and reset the boolean 'result' value for the node evaluation
178  virtual void Evaluate(CQueryParseTree::TNode& qnode);
179 
180  virtual size_t GetArgCountMin(CQueryParseNode::EType /* t */) { return 0; }
181  virtual size_t GetArgCountMax(CQueryParseNode::EType /* t */) { return 0; }
182 };
183 
184 ////////////////////////////////////////////////////////////////////////////////
185 /// class CQueryFuncPromoteIdentifier
186 ///
187 /// Query execution function for variables
189 {
190 public:
192 
193  ///
194  /// Create the user object for the node if it does not yet exist
195  /// and reset the boolean 'result' value for the node evaluation
196  virtual void Evaluate(CQueryParseTree::TNode& qnode);
197 
198  virtual size_t GetArgCountMin(CQueryParseNode::EType /* t */) { return 0; }
199  virtual size_t GetArgCountMax(CQueryParseNode::EType /* t */) { return 0; }
200 };
201 
202 
203 
204 ////////////////////////////////////////////////////////////////////////////////
205 /// class CQueryFuncPromoteAndOr
206 ///
207 /// Query execution function for logical operators like AND, OR, etc.
209 {
210 public:
212 
213  virtual bool EvaluateChildrenFirst() const { return false; }
214 
215  /// Try to convert the arguments into boolean values and, if successful,
216  /// apply the specified boolean operator to those values.
217  virtual void Evaluate(CQueryParseTree::TNode& qnode);
218 
219  virtual size_t GetArgCountMin(CQueryParseNode::EType t) { return 2; }
220 
221  /// Can string togeather multiple ands/ors into one combined and/or, e.g.
222  /// a or b or c or d==or:a,b,c,d. So we allow essentially unlimited operands
223  virtual size_t GetArgCountMax(CQueryParseNode::EType t) { return 65536; }
224 };
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// class CQueryFuncPromoteLogic
228 ///
229 /// Query execution function for logical operators like AND, OR, etc.
231 {
232 public:
234 
235  /// Try to convert the arguments into boolean values and, if successful,
236  /// apply the specified boolean operator to those values.
237  virtual void Evaluate(CQueryParseTree::TNode& qnode);
238 
240  {
241  return (t == CQueryParseNode::eNot ? 1 : 2);
242  }
243  /// xor, sub take 2 args, not takes 1
245  {
246  return (t == CQueryParseNode::eNot ? 1 : 2);
247  }
248 };
249 
250 
251 ////////////////////////////////////////////////////////////////////////////////
252 /// class CQueryFuncPromoteCompare
253 ///
254 /// Query execution function base class for all comparison classes including:
255 /// >, <, >=, <=, ==, 'In', 'Between', and Like.
257 {
258 public:
259  /// Ctors for compare must include op_type for loading promotion rules
263 
264  /// Subclass to create vector of promotion rules in m_PromoteRules
265  virtual void InitTypePromotionRules(CQueryParseNode::EType /*op_type*/) {}
266 };
267 
268 
269 ////////////////////////////////////////////////////////////////////////////////
270 /// class CQueryFuncEqualityCompares
271 ///
272 /// Base class for query execution functions that use comparison operators
273 /// (for now that is == and In). These functions both use the same type
274 /// promotion rules
276 {
277 public:
278  /// Ctor
282  : CQueryFuncPromoteCompare(op_type, c, matching) {}
283 
284  /// Initialize promotion table for eqaulity comparisons (e.g. == or In)
285  virtual void InitTypePromotionRules(CQueryParseNode::EType op_type);
286 };
287 
288 
289 ////////////////////////////////////////////////////////////////////////////////
290 /// class CQueryFuncPromoteEq
291 ///
292 /// Query execution function for equality comparison: ==
294 {
295 public:
296  /// Ctor
299 
300  /// Evaluate the node to see if '==' returns true
301  virtual void Evaluate(CQueryParseTree::TNode& qnode);
302 };
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 /// class CQueryFuncPromoteIn
306 ///
307 /// Query execution function for the 'In' comparison
309 {
310 public:
311  /// ctor
314 
315  /// Evaluate the node to see if 'In' returns true
316  virtual void Evaluate(CQueryParseTree::TNode& qnode);
317 
318  /// In can have just one argument (a in ()) or a very large number
319  /// a in (dog, cat, bird mouse......)
320  virtual size_t GetArgCountMin(CQueryParseNode::EType /* t */) { return 1; }
321  virtual size_t GetArgCountMax(CQueryParseNode::EType /* t */) { return 4096; }
322 };
323 
324 ////////////////////////////////////////////////////////////////////////////////
325 /// class CQueryFuncLike
326 ///
327 /// Query execution function for 'Like' comparison.
329 {
330 public:
331  /// Ctor
333 
334  /// Initialize promotion rules for 'Like' comparison
335  virtual void InitTypePromotionRules(CQueryParseNode::EType op_type);
336 
337  /// Evaluate the node to see if 'Like' returns true
338  virtual void Evaluate(CQueryParseTree::TNode& qnode);
339 };
340 
341 ////////////////////////////////////////////////////////////////////////////////
342 /// class CQueryFuncGtLtCompares
343 ///
344 /// Base class for query execution functions that use greater than/ less
345 /// than comparisons (for now that is >,<,>=,<= and Between). These functions
346 /// all use the same promotion rules.
348 {
349 public:
350  /// Ctor
353  : CQueryFuncPromoteCompare(op_type, c) {}
354 
355  /// Initialize promotion table for the comparisons.
356  virtual void InitTypePromotionRules(CQueryParseNode::EType op_type);
357 };
358 
359 ////////////////////////////////////////////////////////////////////////////////
360 /// class CQueryFuncPromoteGtLt
361 ///
362 /// Query execution function for the >,<,>= and <= operators
364 {
365 public:
366  /// Ctor includes op_type since we will create a separate
367  /// instance for each of >,<, >= and <=.
370 
371  /// Evaluate the node to see if 'greater than/less than' returns true
372  virtual void Evaluate(CQueryParseTree::TNode& qnode);
373 };
374 
375 ////////////////////////////////////////////////////////////////////////////////
376 /// class CQueryFuncPromoteBetween
377 ///
378 /// Query execution function for the 'Between' operator
380 {
381 public:
382  /// Ctor
384 
385  /// Evaluate the node to see if 'Between' returns true
386  virtual void Evaluate(CQueryParseTree::TNode& qnode);
387 
388  /// 27 between 10 and 30 => 3 arguments for between operator
389  virtual size_t GetArgCountMin(CQueryParseNode::EType /* t */) { return 3; }
390  virtual size_t GetArgCountMax(CQueryParseNode::EType /* t */) { return 3; }
391 };
392 
393 ////////////////////////////////////////////////////////////////////////////////
394 /// class CQueryExecPreProcessFunc
395 ///
396 /// This class applies a function to the query to do any needed optiminzation
397 /// or preprocessing of the query prior to execution.
399 {
400 public:
401  CQueryExecPreProcessFunc(objects::CScope* scope,
402  CQueryExec& exec)
403  : m_Exec(exec)
404  , m_Scope(scope)
405  {}
406 
409  {
410  CQueryParseNode& qnode = tr.GetValue();
411  if (delta == 0 || delta == 1) {
412  // If node has children, we skip it and process on the way back
413  if (!tr.IsLeaf()) {
414  return eTreeTraverse;
415  }
416  }
417  CQueryParseNode::EType func_type = qnode.GetType();
418  CQueryFuncPromoteBase* func = 0;
419 
420  func = dynamic_cast<CQueryFuncPromoteBase*>( m_Exec.GetFunc(func_type) );
421 
422  if (func == 0) { // function not registered
423  NCBI_THROW(CQueryParseException, eUnknownFunction,
424  "Query pre-processing faild. Unknown function:" + qnode.GetOrig());
425  }
426 
427  func->PreProcess(tr, m_Scope);
428 
429  return eTreeTraverse;
430  }
431 private:
432 
434  objects::CScope* m_Scope;
435 };
436 
437 
438 
440 
441 
442 #endif // GUI_OBJUTILS___QUERY_FUNC_PROMOTE_HPP
443 
class CPromoteRule
class CQueryExecPreProcessFunc
ETreeTraverseCode operator()(CTreeNode< CQueryParseNode > &tr, int delta)
CQueryExecPreProcessFunc(objects::CScope *scope, CQueryExec &exec)
Query execution environment holds the function registry and the execution context.
Definition: query_exec.hpp:144
Query execution function for assignment operator.
class CQueryFuncEqualityCompares
CQueryFuncEqualityCompares(CQueryParseNode::EType op_type, NStr::ECase c=NStr::eCase, CStringMatching::EStringMatching matching=CStringMatching::ePlainSearch)
Ctor.
class CQueryFuncFunction
class CQueryFuncGtLtCompares
CQueryFuncGtLtCompares(CQueryParseNode::EType op_type, NStr::ECase c=NStr::eCase)
Ctor.
class CQueryFuncLike
class CQueryFuncPromoteAndOr
virtual size_t GetArgCountMax(CQueryParseNode::EType t)
Can string togeather multiple ands/ors into one combined and/or, e.g.
virtual bool EvaluateChildrenFirst() const
Do we evaluate before visiting the nodes children or after.
virtual size_t GetArgCountMin(CQueryParseNode::EType t)
class CQueryFuncPromoteBase
void SetCaseSensitive(NStr::ECase e)
Get/set case sensitivity for all string compares for this function.
virtual size_t GetArgCountMax(CQueryParseNode::EType)
CStringMatching::EStringMatching m_StringMatchAlgo
Determines how string equality comaparisons will be handled (wildcards, regex, exact....
std::vector< CPromoteRule > m_PromoteRules
Vector of sorted promotion rules.
NStr::ECase m_CaseSensitive
If true, all string comparisons by subclasses will use case-sensitive comparisons,...
virtual size_t GetArgCountMin(CQueryParseNode::EType)
void SetStringMatching(CStringMatching::EStringMatching m)
Get/set string matching algorithm.
CStringMatching::EStringMatching GetStringMatching() const
NStr::ECase GetCaseSensitive() const
void PreProcess(CQueryParseTree::TNode &tr, objects::CScope *scope)
Resolve, if possible, the data type for the query node tr and, for operator nodes (e....
class CQueryFuncPromoteBetween
virtual size_t GetArgCountMin(CQueryParseNode::EType)
27 between 10 and 30 => 3 arguments for between operator
virtual size_t GetArgCountMax(CQueryParseNode::EType)
class CQueryFuncPromoteCompare
virtual void InitTypePromotionRules(CQueryParseNode::EType)
Subclass to create vector of promotion rules in m_PromoteRules.
class CQueryFuncPromoteEq
class CQueryFuncPromoteGtLt
class CQueryFuncPromoteIdentifier
virtual size_t GetArgCountMin(CQueryParseNode::EType)
virtual size_t GetArgCountMax(CQueryParseNode::EType)
class CQueryFuncPromoteIn
virtual size_t GetArgCountMin(CQueryParseNode::EType)
In can have just one argument (a in ()) or a very large number a in (dog, cat, bird mouse....
virtual size_t GetArgCountMax(CQueryParseNode::EType)
class CQueryFuncPromoteLogic
virtual size_t GetArgCountMax(CQueryParseNode::EType t)
xor, sub take 2 args, not takes 1
virtual size_t GetArgCountMin(CQueryParseNode::EType t)
class CQueryFuncPromoteValue
virtual size_t GetArgCountMax(CQueryParseNode::EType)
virtual size_t GetArgCountMin(CQueryParseNode::EType)
Query execution function for run-time variables.
Base class for evaluation functions.
Definition: query_exec.hpp:68
class CQueryNodeValue
Query parser exceptions.
Query node class.
Definition: query_parse.hpp:79
class CTextSearch
EStringMatching
String matching algorithms.
@ ePlainSearch
Plain search.
definition of a Culling tree
Definition: ncbi_tree.hpp:100
NStr –.
Definition: ncbistr.hpp:243
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
const string & GetOrig() const
CQueryFunctionBase * GetFunc(CQueryParseNode::EType func_type)
Return query function pointer (if registered).
Definition: query_exec.hpp:171
EType
Query node type.
Definition: query_parse.hpp:84
virtual void Evaluate(CQueryParseTree::TNode &qnode)=0
Query node evaluation function (performs actual programmed by the node action)
EType GetType() const
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
ECase
Which type of string comparison.
Definition: ncbistr.hpp:1204
@ eCase
Case sensitive compare.
Definition: ncbistr.hpp:1205
ETreeTraverseCode
Tree traverse code returned by the traverse predicate function.
Definition: ncbi_tree.hpp:51
bool IsLeaf() const
Report whether this is a leaf node.
Definition: ncbi_tree.hpp:296
const TValue & GetValue(void) const
Return node's value.
Definition: ncbi_tree.hpp:184
@ eTreeTraverse
Keep traversal.
Definition: ncbi_tree.hpp:52
#define NCBI_GUIOBJUTILS_EXPORT
Definition: gui_export.h:512
Defines to provide correct exporting from DLLs in Windows.
EBaseType
Set of all possible types for nodes.
EIPRangeType t
Definition: ncbi_localip.c:101
The NCBI C++/STL use hints.
Int4 delta(size_t dimension_, const Int4 *score_)
Query parser execution implementations.
Modified on Tue Dec 05 02:17:57 2023 by modify_doxy.py rev. 669887