exprtraits.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. //
  2. // Copyright (c) 2017-2026, Manticore Software LTD (https://manticoresearch.com)
  3. // Copyright (c) 2001-2016, Andrew Aksyonoff
  4. // Copyright (c) 2008-2016, Sphinx Technologies Inc
  5. // All rights reserved
  6. //
  7. // This program is free software; you can redistribute it and/or modify
  8. // it under the terms of the GNU General Public License. You should have
  9. // received a copy of the GPL license along with this program; if you
  10. // did not, you can find it at http://www.gnu.org/
  11. //
  12. #ifndef _exprtraits_
  13. #define _exprtraits_
  14. #include "sphinxexpr.h"
  15. #include "sphinxfilter.h"
  16. #include "conversion.h"
  17. #include "match.h"
  18. #if _WIN32 && !defined(__clang__)
  19. #ifndef NDEBUG
  20. #define EXPR_CLASS_NAME(name) \
  21. {\
  22. const char * szFuncName = __FUNCTION__; \
  23. const char * szClassNameEnd = strstr ( szFuncName, "::" ); \
  24. assert ( szClassNameEnd ); \
  25. const char * szTemplateNameEnd = strstr ( szFuncName, "<" ); \
  26. if ( szTemplateNameEnd ) szClassNameEnd = szTemplateNameEnd; \
  27. size_t iLen = szClassNameEnd-szFuncName; \
  28. assert ( strlen(name)==iLen && "Wrong expression name specified in ::GetHash" ); \
  29. assert ( !strncmp(name, szFuncName, iLen) && "Wrong expression name specified in ::GetHash" ); \
  30. }\
  31. const char * szClassName = name; \
  32. uint64_t uHash = uPrevHash;
  33. #else
  34. #define EXPR_CLASS_NAME(name) \
  35. const char * szClassName = name; \
  36. uint64_t uHash = uPrevHash;
  37. #endif
  38. #else
  39. #define EXPR_CLASS_NAME(name) \
  40. const char * szClassName = name; \
  41. uint64_t uHash = uPrevHash;
  42. #endif
  43. #define EXPR_CLASS_NAME_NOCHECK(name) \
  44. const char * szClassName = name; \
  45. uint64_t uHash = uPrevHash;
  46. #define CALC_DEP_HASHES() sphCalcExprDepHash ( szClassName, this, tSorterSchema, uHash, bDisable );
  47. #define CALC_DEP_HASHES_EX(hash) sphCalcExprDepHash ( szClassName, this, tSorterSchema, uHash^hash, bDisable );
  48. #define CALC_PARENT_HASH() CalcHash ( szClassName, tSorterSchema, uHash, bDisable );
  49. #define CALC_PARENT_HASH_EX(hash) CalcHash ( szClassName, tSorterSchema, uHash^hash, bDisable );
  50. #define CALC_POD_HASH(value) uHash = sphFNV64 ( &value, sizeof(value), uHash );
  51. #define CALC_POD_HASHES(values) uHash = sphFNV64 ( values.Begin(), values.GetLength()*sizeof(values[0]), uHash );
  52. #define CALC_STR_HASH(str,len) uHash = sphFNV64 ( str.cstr(), len, uHash );
  53. #define CALC_CHILD_HASH(child) if (child) uHash = child->GetHash ( tSorterSchema, uHash, bDisable );
  54. #define CALC_CHILD_HASHES(children) ARRAY_FOREACH ( i, children ) if (children[i]) uHash = children[i]->GetHash ( tSorterSchema, uHash, bDisable );
  55. bool IsNumeric ( ESphAttr eType ); // check whether the type is numeric
  56. ESphAttr GetIntType ( int64_t iValue ); // check for type based on int value
  57. ESphAttr WidestType ( ESphAttr a, ESphAttr b ); // get the widest numeric type of the two
  58. uint64_t sphCalcLocatorHash ( const CSphAttrLocator & tLoc, uint64_t uPrevHash );
  59. uint64_t sphCalcExprDepHash ( const char * szTag, ISphExpr * pExpr, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable );
  60. uint64_t sphCalcExprDepHash ( ISphExpr * pExpr, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable );
  61. int GetConstStrOffset ( int64_t iValue );
  62. int GetConstStrLength ( int64_t iValue );
  63. /// list of constants
  64. class ConstList_c
  65. {
  66. public:
  67. CSphVector<int64_t> m_dInts; ///< dword/int64 storage
  68. CSphVector<float> m_dFloats; ///< float storage
  69. ESphAttr m_eRetType { SPH_ATTR_INTEGER }; ///< SPH_ATTR_INTEGER, SPH_ATTR_BIGINT, SPH_ATTR_STRING, or SPH_ATTR_FLOAT
  70. Str_t m_sExpr; ///< pointer to original whole expr. Not owned.
  71. bool m_bPackedStrings = false; // packed string are offset:len from m_dInts over m_sExpr
  72. void Add ( int64_t iValue );
  73. void Add ( float fValue );
  74. };
  75. /// arg-vs-set function (currently, IN or INTERVAL) evaluator traits
  76. template < typename T >
  77. class Expr_ArgVsSet_T : public ISphExpr
  78. {
  79. public:
  80. explicit Expr_ArgVsSet_T ( ISphExpr * pArg ) : m_pArg ( pArg ) { SafeAddRef ( pArg ); }
  81. float Eval ( const CSphMatch & tMatch ) const override { return (float) IntEval ( tMatch ); }
  82. int64_t Int64Eval ( const CSphMatch & tMatch ) const override { return IntEval ( tMatch ); }
  83. void FixupLocator ( const ISphSchema * pOldSchema, const ISphSchema * pNewSchema ) override
  84. {
  85. if ( m_pArg )
  86. m_pArg->FixupLocator ( pOldSchema, pNewSchema );
  87. }
  88. void Command ( ESphExprCommand eCmd, void * pArg ) override
  89. {
  90. if ( m_pArg )
  91. m_pArg->Command ( eCmd, pArg );
  92. }
  93. protected:
  94. CSphRefcountedPtr<ISphExpr> m_pArg; /* { nullptr }; */
  95. Expr_ArgVsSet_T ( const Expr_ArgVsSet_T & rhs ) : m_pArg ( SafeClone ( rhs.m_pArg ) ) {}
  96. T ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const;
  97. uint64_t CalcHash ( const char * szTag, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable )
  98. {
  99. EXPR_CLASS_NAME_NOCHECK(szTag);
  100. CALC_CHILD_HASH(m_pArg);
  101. return CALC_DEP_HASHES();
  102. }
  103. };
  104. template<> inline int Expr_ArgVsSet_T<int>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
  105. {
  106. return pArg->IntEval ( tMatch );
  107. }
  108. template<> inline DWORD Expr_ArgVsSet_T<DWORD>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
  109. {
  110. return (DWORD)pArg->IntEval ( tMatch );
  111. }
  112. template<> inline float Expr_ArgVsSet_T<float>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
  113. {
  114. return pArg->Eval ( tMatch );
  115. }
  116. template<> inline int64_t Expr_ArgVsSet_T<int64_t>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
  117. {
  118. return pArg->Int64Eval ( tMatch );
  119. }
  120. /// arg-vs-constant-set
  121. template < typename T >
  122. class Expr_ArgVsConstSet_T : public Expr_ArgVsSet_T<T>
  123. {
  124. public:
  125. /// pre-evaluate and dismiss turn points
  126. Expr_ArgVsConstSet_T ( ISphExpr * pArg, const CSphVector<ISphExpr *> & dArgs, int iSkip )
  127. : Expr_ArgVsSet_T<T> ( pArg )
  128. , m_bFloat ( false )
  129. {
  130. CSphMatch tDummy;
  131. for ( int i=iSkip; i<dArgs.GetLength(); ++i )
  132. m_dValues.Add ( Expr_ArgVsSet_T<T>::ExprEval ( dArgs[i], tDummy ) );
  133. CalcValueHash();
  134. }
  135. /// copy that constlist
  136. Expr_ArgVsConstSet_T ( ISphExpr * pArg, ConstList_c * pConsts, bool bKeepFloat )
  137. : Expr_ArgVsSet_T<T> ( pArg )
  138. , m_bFloat ( false )
  139. {
  140. assert ( pConsts );
  141. if ( pConsts->m_eRetType==SPH_ATTR_FLOAT )
  142. {
  143. m_dValues.Reserve ( pConsts->m_dFloats.GetLength() );
  144. if ( !bKeepFloat )
  145. {
  146. for ( float fV : pConsts->m_dFloats )
  147. m_dValues.Add ( (T)fV );
  148. } else
  149. {
  150. m_bFloat = true;
  151. for ( float fV : pConsts->m_dFloats )
  152. m_dValues.Add ( (T) sphF2DW ( fV ) );
  153. }
  154. } else
  155. {
  156. m_dValues.Reserve ( pConsts->m_dInts.GetLength() );
  157. for ( auto iV : pConsts->m_dInts )
  158. m_dValues.Add ( (T)iV );
  159. }
  160. CalcValueHash();
  161. }
  162. /// copy that uservar
  163. Expr_ArgVsConstSet_T ( ISphExpr * pArg, const UservarIntSet_c & pUservar )
  164. : Expr_ArgVsSet_T<T> ( pArg )
  165. , m_bFloat ( false )
  166. {
  167. assert ( pUservar );
  168. m_dValues.Reserve ( pUservar->GetLength() );
  169. for ( auto iV : *pUservar )
  170. m_dValues.Add ( (T)iV );
  171. CalcValueHash();
  172. }
  173. Expr_ArgVsConstSet_T ( ISphExpr * pArg )
  174. : Expr_ArgVsSet_T<T> ( pArg )
  175. , m_bFloat ( false )
  176. {
  177. }
  178. uint64_t GetHash ( const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable ) override
  179. {
  180. EXPR_CLASS_NAME("Expr_ArgVsConstSet_T");
  181. return CALC_PARENT_HASH();
  182. }
  183. protected:
  184. CSphVector<T> m_dValues;
  185. uint64_t m_uValueHash=0;
  186. bool m_bFloat = false;
  187. Expr_ArgVsConstSet_T ( const Expr_ArgVsConstSet_T & rhs )
  188. : Expr_ArgVsSet_T<T> ( rhs )
  189. , m_dValues ( rhs.m_dValues )
  190. , m_uValueHash ( rhs.m_uValueHash )
  191. , m_bFloat ( rhs.m_bFloat )
  192. {}
  193. void CalcValueHash()
  194. {
  195. ARRAY_FOREACH ( i, m_dValues )
  196. m_uValueHash = sphFNV64 ( &m_dValues[i], sizeof(m_dValues[i]), i ? m_uValueHash : SPH_FNV64_SEED );
  197. }
  198. uint64_t CalcHash ( const char * szTag, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable )
  199. {
  200. return Expr_ArgVsSet_T<T>::CalcHash ( szTag, tSorterSchema, uPrevHash^m_uValueHash, bDisable );
  201. }
  202. };
  203. class Expr_Unary_c : public ISphExpr
  204. {
  205. public:
  206. Expr_Unary_c ( const char * szClassName, ISphExpr * pFirst );
  207. void FixupLocator ( const ISphSchema * pOldSchema, const ISphSchema * pNewSchema ) override;
  208. void Command ( ESphExprCommand eCmd, void * pArg ) override;
  209. uint64_t GetHash ( const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable ) override;
  210. protected:
  211. CSphRefcountedPtr<ISphExpr> m_pFirst;
  212. Expr_Unary_c ( const Expr_Unary_c & rhs );
  213. private:
  214. const char * m_szExprName = nullptr;
  215. };
  216. class Expr_Binary_c : public ISphExpr
  217. {
  218. public:
  219. Expr_Binary_c ( const char * szClassName, ISphExpr * pFirst, ISphExpr * pSecond );
  220. void FixupLocator ( const ISphSchema * pOldSchema, const ISphSchema * pNewSchema ) override;
  221. void Command ( ESphExprCommand eCmd, void * pArg ) override;
  222. uint64_t GetHash ( const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable ) override;
  223. protected:
  224. CSphRefcountedPtr<ISphExpr> m_pFirst;
  225. CSphRefcountedPtr<ISphExpr> m_pSecond;
  226. Expr_Binary_c ( const Expr_Binary_c & rhs );
  227. private:
  228. const char * m_szExprName = nullptr;
  229. };
  230. #endif // _exprtraits_