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

Go to the SVN repository for this file.

1 #ifndef GUI_OBJUTILS___QUERY_NODE_VALUE_HPP
2 #define GUI_OBJUTILS___QUERY_NODE_VALUE_HPP
3 /* $Id: query_node_value.hpp 43436 2019-06-28 16:26:08Z katargir $
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 
43 
45 
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// class CQueryExecException
49 ///
50 /// The different types of errors that can occur after the query is parsed while
51 /// it is being executed.
53 {
54 public:
55  enum EErrCode {
56  eNotPromotable, // Used if a type can't be promoted to another
57  // type, e.g. 'dog' can't be prmoted to float.
58  eIncompatibleType, // types which can't be compared, e.g. true AND "cat"
59  eWrongArgumentCount, // Number of arguments for an operand are incorrect,
60  // e.g. '==' has 3 operands. The initial parser
61  // should catch all of these.
62  eExecParseError, // If there are strings with multiple tokens during
63  // execution, those may be parsed and evaluted, e.g.
64  // in "dist>(2.0 * OtherDist)", (2 * OtherDist)
65  // may be further parsed and found to be valid,
66  // or it may throw this error if not.
67  eObjManagerError, // Error when looking up/comparing seq-ids
68  // during query execution
69  eUnableToResolveData, // Unable to retrieve a field value from the data
70  // source for a particular entry
71  eFunctionExedError // Called a function but function execution failed
72  };
73 
74  virtual const char* GetErrCodeString(void) const override
75  {
76  switch (GetErrCode())
77  {
78  case eNotPromotable: return "eNotPromotable";
79  case eIncompatibleType: return "eIncompatibleType";
80  case eWrongArgumentCount: return "eWrongArgumentCount";
81  case eExecParseError: return "eExecParseError";
82  case eObjManagerError: return "eObjManagerError";
83  case eUnableToResolveData: return "eUnableToResolveData";
84  case eFunctionExedError: return "eFunctionExedError";
85 
86  default: return CException::GetErrCodeString();
87  }
88  }
89 
91 };
92 
93 namespace QueryValueType {
94 
95  /// Set of all possible types for nodes. Basic types are repeated based
96  /// on their source to allow us to include the source of the data when
97  /// deciding on how to promote something (e.g. did an int get parsed from
98  /// a string in the query (e.g. the number "27" in (a=="27")), or was the
99  /// int retrieved from a data field (e.g. in dist>0.4, the value
100  /// for 'dist' comes from the current record/node being evaluated).
101  enum EBaseType {
102  eBoolResult, // result value from computing results in query sub-tree
103  eBool, // boolean const
104  eInt, // int const
105  eFloat, // float const
106  eString, // string which cannot be converted to another type
107  eSeqID, // possible seq-id identifier
108  eStringBool, // bool converted from a string in the query
109  eStringInt, // integer converted form a string in the query
110  eStringFloat, // float converted from a string in the query
111  eFieldSeqID, // possible seq-id field value
112  eFieldString, // string field value
113  eFieldBool, // boolean field value
114  eFieldFloat, // float field value
115  eFieldInt, // integer field value
116  eRef, // reference type to a similar object
117  eUndefined // incompatible types or other error
118  };
119 
121 };
122 
123 
124 ////////////////////////////////////////////////////////////////////////////////
125 /// class CPromoteRule
126 ///
127 /// This is a simple class meant to be an entry in a table representing
128 /// promotion rules. Given the table, you can determine for any two types
129 /// (and type information incldudes the source of the data such as whether it
130 /// was a constant in the query or comes from the data source) and their
131 /// operator which type should be used as the basis for comparison, or if the
132 /// comparison does not make any sense. (An example of a non-promotable pair
133 /// would be a boolean and a string where that string is not converible to a
134 /// boolean or numeric value).
136 public:
137  /// Default ctor initializes to undefined values
139  : m_CompareOperator(CQueryParseNode::eNotSet)
140  , m_Type1(QueryValueType::eUndefined)
141  , m_Type2(QueryValueType::eUndefined)
142  , m_PromotedType(QueryValueType::eUndefined) {}
143 
144  /// Set the values for the type and their comparison operator
149  : m_CompareOperator(op)
150  , m_Type1(type1)
151  , m_Type2(type2)
152  , m_PromotedType(ptype) {}
153 
154 
155  /// Allow table to be sorted for faster lookup
156  bool operator<(const CPromoteRule& rhs) const
157  {
158  if (m_Type1 < rhs.m_Type1)
159  return true;
160  else if (m_Type1 == rhs.m_Type1 &&
161  m_Type2 < rhs.m_Type2)
162  return true;
163  else if (m_Type1 == rhs.m_Type1 &&
164  m_Type2 == rhs.m_Type2 &&
165  m_CompareOperator < rhs.m_CompareOperator)
166  return true;
167 
168  return false;
169  }
170 
171  /// Allows us to check to see if we found requested table entry
172  bool operator==(const CPromoteRule& rhs) const
173  {
174  return ((m_Type1 == rhs.m_Type1) &&
175  (m_Type2 == rhs.m_Type2) &&
176  (m_CompareOperator == rhs.m_CompareOperator));
177  }
178 
179  /// The comparison operator applied to the two values, e.g. ==, <, ...
181  /// The extended type for the first element to compare
183  /// The extended type for the second element to compare
185 
186  /// The type to be used for the comparison. This is the type from the
187  /// CQueryParseNode class since it does not care where the data came from
189 };
190 
191 
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 /// class CQueryNodeValue
195 ///
196 /// Subclass of the IQueryParseUserObject which is held as the user-defined object
197 /// in each CQueryParseNode. Holds a boolean value that tells us if the
198 /// subexpression evaluted to true or not, so that value can be passed up the
199 /// tree. Also keeps track of whether that value has been set.
200 ///
201 /// This class also holds data similar to CQueryParseNode, but with more information
202 /// about the type (includes both the underlying type and source of the data).
203 /// More than one data element may be valid, e.g. if the data is an integer
204 /// parsed from a string (eStringInt), both the string and integer fields will
205 /// be set.
207 {
208 public:
210 
211 public:
213  : m_Node(NULL)
214  , m_DataType(QueryValueType::eUndefined)
215  , m_IsField(false)
216  , m_FieldID(TFieldIDType(-1))
217  , m_Scope(NULL)
218  , m_Value(false)
219  , m_NodeBranchDepth(0)
220  , m_NodeMaxChildBranchDepth(-1)
221  {}
223  : m_Node(n)
224  , m_DataType(QueryValueType::eUndefined)
225  , m_IsField(false)
226  , m_FieldID(TFieldIDType(-1))
227  , m_Scope(NULL)
228  , m_Value(false)
229  , m_NodeBranchDepth(0)
230  , m_NodeMaxChildBranchDepth(-1)
231  {}
232 
233  // specifically does not reset m_IsField - that sticks between evaluations
234  virtual void Reset() { m_Value = false; }
235  virtual string GetVisibleValue() const;
236 
237  /// Set boolean result value (result of (sub)expression).
238  bool GetValue() const { return m_Value; }
239  void SetValue(int v) { m_Value = v; }
240 
241  /// Set/Get number of branches between node and root
242  void SetBranchDepth(int bd) { m_NodeBranchDepth = bd; }
243  int GetBranchDepth() const { return m_NodeBranchDepth; }
244 
245  /// Set/Get number of branches between node and most distant child
246  void SetMaxChildBranchDepth(int cbd) { m_NodeMaxChildBranchDepth = cbd; }
247  int GetMaxChildBranchDepth() const { return m_NodeMaxChildBranchDepth; }
248 
249  /// Convert current value to the type 'pt'. Does not update m_DataType
250  void PromoteTo(QueryValueType::EBaseType pt);
251 
252  /// Get corresponding query node
253  CQueryParseTree::TNode* GetQueryNode() { return m_Node; }
254 
255  /// Set/get underlying data type
256  void SetDataType(QueryValueType::EBaseType dt) {m_DataType = dt; }
257  QueryValueType::EBaseType GetDataType() const { return m_DataType; }
258 
259  /// Set/Get to indicate if this is a field from the data source or simple
260  /// string. The type of field may not yet be avialable (if it has to be
261  /// determined for each separate data element)
262  void SetIsDataField(bool b) { m_IsField = b; }
263  bool IsDataField() const { return m_IsField; }
264 
265  // Set/Get biotree feature ID if m_IsField is true (makes looking up
266  // feature values within nodes faster).
267  void SetFieldID(TFieldIDType fid) { m_FieldID = fid; }
268  TFieldIDType GetFieldID() const { return m_FieldID; }
269 
270  /// Set/Get CScope used for comparing seq-ids
271  void SetScope(objects::CScope* s) {m_Scope = s;}
272  objects::CScope* GetScope() { return m_Scope; }
273 
274  /// Return promotion rule(s) defined for this operator.
275  vector<CPromoteRule>& GetPromoteRules() { return m_PromoteRules; }
276  /// Get the promotion type for a specific argument pair, or eUndefined
277  /// if no rule is available.
278  QueryValueType::EBaseType GetPromoteType(size_t arg_idx);
279  /// Return true if there is a promote entry defined for the specified
280  /// argument pair at 'idx' only if the types for the rule match t1 and t2.
281  bool HasPromoteType(size_t arg_idx,
284  /// Append a new promote rule
285  void AddPromotedType(const CPromoteRule& pr) { m_PromoteRules.push_back(pr); }
286 
287  void Dereference();
288 
289  /// String data, if data came from a string or data field in the tree
290  string m_String;
291 
292  /// Bool data, if data base a constant boolean or converted into one
293  bool m_Bool;
294 
295  /// Int data, if data was an integer or converted into one
297 
298  /// Floating point data, if data was a double or converted into one
299  double m_Double;
300 
301  /// Reference to similar object
303 
304  /// Set/get underlying data type
305  virtual void SetString(const string& data);
306  virtual void SetBool(bool data);
307  virtual void SetDouble(double data);
308  virtual void SetInt(Int8 data);
309  void SetRef(CRef<CQueryNodeValue> node);
310  bool AssignToRef(const CQueryNodeValue& source);
311 
312  virtual const string& GetString() const { return m_String; }
313  virtual bool GetBool() const { return m_Bool; }
314  virtual double GetDouble() const { return m_Double; }
315  virtual Int8 GetInt() const { return m_Int; }
316 
317 protected:
318  /// Node from parsed query tree
320 
321  /// Data type, including source of the data (const, string field, or tree)
323 
324  /// True if the data comes from field in the tree
325  bool m_IsField;
326 
327  /// If it is a field, this is the ID to look it up (efficiently)
329 
330  /// Used for comparing seq-ids
331  objects::CScope* m_Scope;
332 
333  /// The promote rules defined for the current operator. This will be empty
334  /// for atomic types. For operator type query nodes (e.g. ==, <, etc) this
335  /// will have the comparison (promotion) type for each pair of operands. If
336  /// one or more types will be defined at runtime, e.g. an untyped field
337  /// from the data source, this will be empty
338  vector<CPromoteRule> m_PromoteRules;
339 
340  /// Boolean result of the (sub)expression attached to the corresponding
341  /// query node.
342  bool m_Value;
343 
344  /// Mechanism to pass current position of node within the tree in
345  /// terms of the number of branches between the node and the parent
346  /// and between the node and it's most distant (by branch count)
347  /// child
350 };
351 
353 
354 #endif // GUI_OBJUTILS___QUERY_NODE_VALUE_HPP
355 
static CRef< CScope > m_Scope
class CPromoteRule
QueryValueType::EBaseType m_Type1
The extended type for the first element to compare.
CPromoteRule()
Default ctor initializes to undefined values.
bool operator==(const CPromoteRule &rhs) const
Allows us to check to see if we found requested table entry.
CPromoteRule(CQueryParseNode::EType op, QueryValueType::EBaseType type1, QueryValueType::EBaseType type2, QueryValueType::EBaseType ptype)
Set the values for the type and their comparison operator.
QueryValueType::EBaseType m_Type2
The extended type for the second element to compare.
CQueryParseNode::EType m_CompareOperator
The comparison operator applied to the two values, e.g. ==, <, ...
QueryValueType::EBaseType m_PromotedType
The type to be used for the comparison.
bool operator<(const CPromoteRule &rhs) const
Allow table to be sorted for faster lookup.
class CQueryExecException
NCBI_EXCEPTION_DEFAULT(CQueryExecException, CException)
virtual const char * GetErrCodeString(void) const override
Get error code interpreted as text.
class CQueryNodeValue
Int8 m_Int
Int data, if data was an integer or converted into one.
vector< CPromoteRule > & GetPromoteRules()
Return promotion rule(s) defined for this operator.
CQueryNodeValue(CQueryParseTree::TNode *n)
QueryValueType::EBaseType m_DataType
Data type, including source of the data (const, string field, or tree)
bool IsDataField() const
int GetMaxChildBranchDepth() const
objects::CScope * m_Scope
Used for comparing seq-ids.
void SetBranchDepth(int bd)
Set/Get number of branches between node and root.
CQueryParseTree::TNode * m_Node
Node from parsed query tree.
bool m_Value
Boolean result of the (sub)expression attached to the corresponding query node.
CRef< CQueryNodeValue > m_Ref
Reference to similar object.
void SetFieldID(TFieldIDType fid)
virtual bool GetBool() const
bool m_IsField
True if the data comes from field in the tree.
TFieldIDType m_FieldID
If it is a field, this is the ID to look it up (efficiently)
int GetBranchDepth() const
CQueryParseTree::TNode * GetQueryNode()
Get corresponding query node.
bool m_Bool
Bool data, if data base a constant boolean or converted into one.
virtual void Reset()
Reset user object (for reuse without reallocation)
int m_NodeBranchDepth
Mechanism to pass current position of node within the tree in terms of the number of branches between...
string m_String
String data, if data came from a string or data field in the tree.
CQueryExec::TFieldID TFieldIDType
void SetIsDataField(bool b)
Set/Get to indicate if this is a field from the data source or simple string.
double m_Double
Floating point data, if data was a double or converted into one.
vector< CPromoteRule > m_PromoteRules
The promote rules defined for the current operator.
void SetDataType(QueryValueType::EBaseType dt)
Set/get underlying data type.
virtual Int8 GetInt() const
virtual double GetDouble() const
objects::CScope * GetScope()
void AddPromotedType(const CPromoteRule &pr)
Append a new promote rule.
bool GetValue() const
Set boolean result value (result of (sub)expression).
TFieldIDType GetFieldID() const
virtual const string & GetString() const
void SetScope(objects::CScope *s)
Set/Get CScope used for comparing seq-ids.
void SetMaxChildBranchDepth(int cbd)
Set/Get number of branches between node and most distant child.
QueryValueType::EBaseType GetDataType() const
Query node class.
Definition: query_parse.hpp:79
definition of a Culling tree
Definition: ncbi_tree.hpp:100
class IQueryMacroUserObject
#define false
Definition: bool.h:36
char data[12]
Definition: iconv.c:80
#define NULL
Definition: ncbistd.hpp:225
TErrCode GetErrCode(void) const
Get error code.
Definition: ncbiexpt.cpp:453
EErrCode
Error types that an application can generate.
Definition: ncbiexpt.hpp:884
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
Definition: ncbiexpt.cpp:444
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
unsigned int TFieldID
Definition: query_exec.hpp:148
EType
Query node type.
Definition: query_parse.hpp:84
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define NCBI_GUIOBJUTILS_EXPORT
Definition: gui_export.h:512
Defines to provide correct exporting from DLLs in Windows.
yy_size_t n
EBaseType
Set of all possible types for nodes.
string GetTypeAsString(EBaseType et)
const CharType(& source)[N]
Definition: pointer.h:1149
The NCBI C++/STL use hints.
Query parser execution implementations.
Modified on Wed Sep 04 15:05:08 2024 by modify_doxy.py rev. 669887