| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- //
- // Copyright (c) 2017-2026, Manticore Software LTD (https://manticoresearch.com)
- // Copyright (c) 2001-2016, Andrew Aksyonoff
- // Copyright (c) 2008-2016, Sphinx Technologies Inc
- // All rights reserved
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License. You should have
- // received a copy of the GPL license along with this program; if you
- // did not, you can find it at http://www.gnu.org/
- //
- #ifndef _exprtraits_
- #define _exprtraits_
- #include "sphinxexpr.h"
- #include "sphinxfilter.h"
- #include "conversion.h"
- #include "match.h"
- #if _WIN32 && !defined(__clang__)
- #ifndef NDEBUG
- #define EXPR_CLASS_NAME(name) \
- {\
- const char * szFuncName = __FUNCTION__; \
- const char * szClassNameEnd = strstr ( szFuncName, "::" ); \
- assert ( szClassNameEnd ); \
- const char * szTemplateNameEnd = strstr ( szFuncName, "<" ); \
- if ( szTemplateNameEnd ) szClassNameEnd = szTemplateNameEnd; \
- size_t iLen = szClassNameEnd-szFuncName; \
- assert ( strlen(name)==iLen && "Wrong expression name specified in ::GetHash" ); \
- assert ( !strncmp(name, szFuncName, iLen) && "Wrong expression name specified in ::GetHash" ); \
- }\
- const char * szClassName = name; \
- uint64_t uHash = uPrevHash;
- #else
- #define EXPR_CLASS_NAME(name) \
- const char * szClassName = name; \
- uint64_t uHash = uPrevHash;
- #endif
- #else
- #define EXPR_CLASS_NAME(name) \
- const char * szClassName = name; \
- uint64_t uHash = uPrevHash;
- #endif
- #define EXPR_CLASS_NAME_NOCHECK(name) \
- const char * szClassName = name; \
- uint64_t uHash = uPrevHash;
- #define CALC_DEP_HASHES() sphCalcExprDepHash ( szClassName, this, tSorterSchema, uHash, bDisable );
- #define CALC_DEP_HASHES_EX(hash) sphCalcExprDepHash ( szClassName, this, tSorterSchema, uHash^hash, bDisable );
- #define CALC_PARENT_HASH() CalcHash ( szClassName, tSorterSchema, uHash, bDisable );
- #define CALC_PARENT_HASH_EX(hash) CalcHash ( szClassName, tSorterSchema, uHash^hash, bDisable );
- #define CALC_POD_HASH(value) uHash = sphFNV64 ( &value, sizeof(value), uHash );
- #define CALC_POD_HASHES(values) uHash = sphFNV64 ( values.Begin(), values.GetLength()*sizeof(values[0]), uHash );
- #define CALC_STR_HASH(str,len) uHash = sphFNV64 ( str.cstr(), len, uHash );
- #define CALC_CHILD_HASH(child) if (child) uHash = child->GetHash ( tSorterSchema, uHash, bDisable );
- #define CALC_CHILD_HASHES(children) ARRAY_FOREACH ( i, children ) if (children[i]) uHash = children[i]->GetHash ( tSorterSchema, uHash, bDisable );
- bool IsNumeric ( ESphAttr eType ); // check whether the type is numeric
- ESphAttr GetIntType ( int64_t iValue ); // check for type based on int value
- ESphAttr WidestType ( ESphAttr a, ESphAttr b ); // get the widest numeric type of the two
- uint64_t sphCalcLocatorHash ( const CSphAttrLocator & tLoc, uint64_t uPrevHash );
- uint64_t sphCalcExprDepHash ( const char * szTag, ISphExpr * pExpr, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable );
- uint64_t sphCalcExprDepHash ( ISphExpr * pExpr, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable );
- int GetConstStrOffset ( int64_t iValue );
- int GetConstStrLength ( int64_t iValue );
- /// list of constants
- class ConstList_c
- {
- public:
- CSphVector<int64_t> m_dInts; ///< dword/int64 storage
- CSphVector<float> m_dFloats; ///< float storage
- ESphAttr m_eRetType { SPH_ATTR_INTEGER }; ///< SPH_ATTR_INTEGER, SPH_ATTR_BIGINT, SPH_ATTR_STRING, or SPH_ATTR_FLOAT
- Str_t m_sExpr; ///< pointer to original whole expr. Not owned.
- bool m_bPackedStrings = false; // packed string are offset:len from m_dInts over m_sExpr
- void Add ( int64_t iValue );
- void Add ( float fValue );
- };
- /// arg-vs-set function (currently, IN or INTERVAL) evaluator traits
- template < typename T >
- class Expr_ArgVsSet_T : public ISphExpr
- {
- public:
- explicit Expr_ArgVsSet_T ( ISphExpr * pArg ) : m_pArg ( pArg ) { SafeAddRef ( pArg ); }
- float Eval ( const CSphMatch & tMatch ) const override { return (float) IntEval ( tMatch ); }
- int64_t Int64Eval ( const CSphMatch & tMatch ) const override { return IntEval ( tMatch ); }
- void FixupLocator ( const ISphSchema * pOldSchema, const ISphSchema * pNewSchema ) override
- {
- if ( m_pArg )
- m_pArg->FixupLocator ( pOldSchema, pNewSchema );
- }
- void Command ( ESphExprCommand eCmd, void * pArg ) override
- {
- if ( m_pArg )
- m_pArg->Command ( eCmd, pArg );
- }
- protected:
- CSphRefcountedPtr<ISphExpr> m_pArg; /* { nullptr }; */
- Expr_ArgVsSet_T ( const Expr_ArgVsSet_T & rhs ) : m_pArg ( SafeClone ( rhs.m_pArg ) ) {}
- T ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const;
- uint64_t CalcHash ( const char * szTag, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable )
- {
- EXPR_CLASS_NAME_NOCHECK(szTag);
- CALC_CHILD_HASH(m_pArg);
- return CALC_DEP_HASHES();
- }
- };
- template<> inline int Expr_ArgVsSet_T<int>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
- {
- return pArg->IntEval ( tMatch );
- }
- template<> inline DWORD Expr_ArgVsSet_T<DWORD>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
- {
- return (DWORD)pArg->IntEval ( tMatch );
- }
- template<> inline float Expr_ArgVsSet_T<float>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
- {
- return pArg->Eval ( tMatch );
- }
- template<> inline int64_t Expr_ArgVsSet_T<int64_t>::ExprEval ( ISphExpr * pArg, const CSphMatch & tMatch ) const
- {
- return pArg->Int64Eval ( tMatch );
- }
- /// arg-vs-constant-set
- template < typename T >
- class Expr_ArgVsConstSet_T : public Expr_ArgVsSet_T<T>
- {
- public:
- /// pre-evaluate and dismiss turn points
- Expr_ArgVsConstSet_T ( ISphExpr * pArg, const CSphVector<ISphExpr *> & dArgs, int iSkip )
- : Expr_ArgVsSet_T<T> ( pArg )
- , m_bFloat ( false )
- {
- CSphMatch tDummy;
- for ( int i=iSkip; i<dArgs.GetLength(); ++i )
- m_dValues.Add ( Expr_ArgVsSet_T<T>::ExprEval ( dArgs[i], tDummy ) );
- CalcValueHash();
- }
- /// copy that constlist
- Expr_ArgVsConstSet_T ( ISphExpr * pArg, ConstList_c * pConsts, bool bKeepFloat )
- : Expr_ArgVsSet_T<T> ( pArg )
- , m_bFloat ( false )
- {
- assert ( pConsts );
- if ( pConsts->m_eRetType==SPH_ATTR_FLOAT )
- {
- m_dValues.Reserve ( pConsts->m_dFloats.GetLength() );
- if ( !bKeepFloat )
- {
- for ( float fV : pConsts->m_dFloats )
- m_dValues.Add ( (T)fV );
- } else
- {
- m_bFloat = true;
- for ( float fV : pConsts->m_dFloats )
- m_dValues.Add ( (T) sphF2DW ( fV ) );
- }
- } else
- {
- m_dValues.Reserve ( pConsts->m_dInts.GetLength() );
- for ( auto iV : pConsts->m_dInts )
- m_dValues.Add ( (T)iV );
- }
- CalcValueHash();
- }
- /// copy that uservar
- Expr_ArgVsConstSet_T ( ISphExpr * pArg, const UservarIntSet_c & pUservar )
- : Expr_ArgVsSet_T<T> ( pArg )
- , m_bFloat ( false )
- {
- assert ( pUservar );
- m_dValues.Reserve ( pUservar->GetLength() );
- for ( auto iV : *pUservar )
- m_dValues.Add ( (T)iV );
- CalcValueHash();
- }
- Expr_ArgVsConstSet_T ( ISphExpr * pArg )
- : Expr_ArgVsSet_T<T> ( pArg )
- , m_bFloat ( false )
- {
- }
- uint64_t GetHash ( const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable ) override
- {
- EXPR_CLASS_NAME("Expr_ArgVsConstSet_T");
- return CALC_PARENT_HASH();
- }
- protected:
- CSphVector<T> m_dValues;
- uint64_t m_uValueHash=0;
- bool m_bFloat = false;
- Expr_ArgVsConstSet_T ( const Expr_ArgVsConstSet_T & rhs )
- : Expr_ArgVsSet_T<T> ( rhs )
- , m_dValues ( rhs.m_dValues )
- , m_uValueHash ( rhs.m_uValueHash )
- , m_bFloat ( rhs.m_bFloat )
- {}
- void CalcValueHash()
- {
- ARRAY_FOREACH ( i, m_dValues )
- m_uValueHash = sphFNV64 ( &m_dValues[i], sizeof(m_dValues[i]), i ? m_uValueHash : SPH_FNV64_SEED );
- }
- uint64_t CalcHash ( const char * szTag, const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable )
- {
- return Expr_ArgVsSet_T<T>::CalcHash ( szTag, tSorterSchema, uPrevHash^m_uValueHash, bDisable );
- }
- };
- class Expr_Unary_c : public ISphExpr
- {
- public:
- Expr_Unary_c ( const char * szClassName, ISphExpr * pFirst );
- void FixupLocator ( const ISphSchema * pOldSchema, const ISphSchema * pNewSchema ) override;
- void Command ( ESphExprCommand eCmd, void * pArg ) override;
- uint64_t GetHash ( const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable ) override;
- protected:
- CSphRefcountedPtr<ISphExpr> m_pFirst;
- Expr_Unary_c ( const Expr_Unary_c & rhs );
- private:
- const char * m_szExprName = nullptr;
- };
- class Expr_Binary_c : public ISphExpr
- {
- public:
- Expr_Binary_c ( const char * szClassName, ISphExpr * pFirst, ISphExpr * pSecond );
- void FixupLocator ( const ISphSchema * pOldSchema, const ISphSchema * pNewSchema ) override;
- void Command ( ESphExprCommand eCmd, void * pArg ) override;
- uint64_t GetHash ( const ISphSchema & tSorterSchema, uint64_t uPrevHash, bool & bDisable ) override;
- protected:
- CSphRefcountedPtr<ISphExpr> m_pFirst;
- CSphRefcountedPtr<ISphExpr> m_pSecond;
- Expr_Binary_c ( const Expr_Binary_c & rhs );
- private:
- const char * m_szExprName = nullptr;
- };
- #endif // _exprtraits_
|