/*############################################################################## Copyright (C) 2011 HPCC Systems. All rights reserved. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ############################################################################## */ #ifndef __HQLINLINE_HPP_ #define __HQLINLINE_HPP_ class ActivityInstance; class SerializationRow; class EvalContext; // A parent extract represents the set of fields etc. which are used from the parent activity, // which are local to the point that the executeChildActivity() is called. The type indicates // the reason it is being created. // There should always an EvalContext associated with a ParentExtract class ParentExtract : public HqlExprAssociation { public: ParentExtract(HqlCppTranslator & _translator, PEtype _type, IHqlExpression * _graphId, GraphLocalisation _localisation, EvalContext * _container); ~ParentExtract(); //HqlExprAssociation virtual AssocKind getKind() { return AssocExtract; } void beginCreateExtract(BuildCtx & buildctx, bool doDeclare); void beginNestedExtract(BuildCtx & clonectx); void beginReuseExtract(); void endCreateExtract(CHqlBoundExpr & boundExtract); void endUseExtract(BuildCtx & ctx); IHqlExpression * queryExtractName() { return boundExtract.expr; } bool canEvaluate(IHqlExpression * expr); bool canSerializeFields() const { return buildctx != NULL; } void associateCursors(BuildCtx & declarectx, BuildCtx & evalctx, GraphLocalisation childLocalisation); void beginChildActivity(BuildCtx & declareCtx, BuildCtx & startCtx, GraphLocalisation childLocalisation, IHqlExpression * colocal, bool nested, bool ignoreSelf, ActivityInstance * activityRequiringCast); void endChildActivity(); void addSerializedExpression(IHqlExpression * value, ITypeInfo * type); void buildAssign(IHqlExpression * serializedTarget, IHqlExpression * originalValue); AliasKind evaluateExpression(BuildCtx & ctx, IHqlExpression * value, CHqlBoundExpr & tgt, IHqlExpression * colocal, bool evaluateLocally); void setAllowDestructor() { canDestroyExtract = true; } inline GraphLocalisation queryLocalisation() { return localisation; } bool requiresOnStart() const; bool insideChildQuery() const; bool areGraphResultsAccessible(IHqlExpression * searchGraphId) const; protected: void ensureAccessible(BuildCtx & ctx, IHqlExpression * expr, const CHqlBoundExpr & bound, CHqlBoundExpr & tgt, IHqlExpression * colocal); void gatherActiveRows(BuildCtx & ctx); protected: HqlCppTranslator & translator; EvalContext * container; SerializationRow * serialization; // fields that are serialized to the children SerializationRow * childSerialization; // same serialization, but as it is bound in the child. CursorArray colocalBoundCursors; // what rows/cursors are available at the point of executeChildGraph() CursorArray nonlocalBoundCursors; // what rows/cursors are available at the point of executeChildGraph() GraphLocalisation localisation; // what kind of localisation do ALL the children have? CursorArray inheritedCursors; CursorArray localCursors; // does not include colocal CursorArray cursorToBind; CHqlBoundExpr boundBuilder; // may have wrapper, or be a char[n] CHqlBoundExpr boundExtract; // always a reference to a row. for "extract" Owned buildctx; // may be null if nested extract PEtype type; IHqlExpression * graphId; bool canDestroyExtract; }; class CtxCollection : public CInterface { public: CtxCollection(BuildCtx & _declareCtx) : clonectx(_declareCtx), childctx(_declareCtx), declarectx(_declareCtx) {} void createFunctionStructure(HqlCppTranslator & translator, BuildCtx & ctx, bool canEvaluate, const char * serializeFunc); public: BuildCtx clonectx; BuildCtx childctx; // child.onCreate() is called from here.. BuildCtx declarectx; //following are always null for nested classes, always created for others. Owned evalctx; Owned serializectx; Owned deserializectx; }; //A potential location for an extract to be created... class EvalContext : public HqlExprAssociation { public: EvalContext(HqlCppTranslator & _translator, ParentExtract * _parentExtract, EvalContext * _parent); virtual AssocKind getKind() { return AssocExtractContext; } virtual IHqlExpression * createGraphLookup(unique_id_t id, bool isChild); virtual AliasKind evaluateExpression(BuildCtx & ctx, IHqlExpression * value, CHqlBoundExpr & tgt, bool evaluateLocally) = 0; virtual bool isColocal() { return true; } virtual ActivityInstance * queryActivity(); virtual bool isLibraryContext() { return false; } virtual void tempCompatiablityEnsureSerialized(const CHqlBoundTarget & tgt) = 0; virtual bool getInvariantMemberContext(BuildCtx * ctx, BuildCtx * * declarectx, BuildCtx * * initctx, bool isIndependentMaybeShared, bool invariantEachStart) { return false; } void ensureContextAvailable() { ensureHelpersExist(); } virtual bool evaluateInParent(BuildCtx & ctx, IHqlExpression * expr, bool hasOnStart); bool hasParent() { return parent != NULL; } bool needToEvaluateLocally(BuildCtx & ctx, IHqlExpression * expr); public://only used by friends virtual void callNestedHelpers(const char * memberName) = 0; virtual void ensureHelpersExist() = 0; virtual bool isRowInvariant(IHqlExpression * expr) { return false; } bool requiresOnStart() const; bool insideChildQuery() const; bool areGraphResultsAccessible(IHqlExpression * graphId) const; protected: Owned parentExtract; // extract of the parent EvalContext HqlCppTranslator & translator; EvalContext * parent; OwnedHqlExpr colocalMember; }; class ClassEvalContext : public EvalContext { friend class ActivityInstance; friend class GlobalClassBuilder; public: ClassEvalContext(HqlCppTranslator & _translator, ParentExtract * _parentExtract, EvalContext * _parent, BuildCtx & createctx, BuildCtx & startctx); virtual AliasKind evaluateExpression(BuildCtx & ctx, IHqlExpression * value, CHqlBoundExpr & tgt, bool evaluateLocally); virtual bool isRowInvariant(IHqlExpression * expr); virtual void tempCompatiablityEnsureSerialized(const CHqlBoundTarget & tgt); virtual bool getInvariantMemberContext(BuildCtx * ctx, BuildCtx * * declarectx, BuildCtx * * initctx, bool isIndependentMaybeShared, bool invariantEachStart); protected: void cloneAliasInClass(CtxCollection & ctxs, const CHqlBoundExpr & bound, CHqlBoundExpr & tgt); IHqlExpression * cloneExprInClass(CtxCollection & ctxs, IHqlExpression * expr); void createMemberAlias(CtxCollection & ctxs, BuildCtx & ctx, IHqlExpression * value, CHqlBoundExpr & tgt); void doCallNestedHelpers(const char * member, const char * acticity); void ensureSerialized(CtxCollection & ctxs, const CHqlBoundTarget & tgt); protected: CtxCollection onCreate; CtxCollection onStart; }; class GlobalClassEvalContext : public ClassEvalContext { public: GlobalClassEvalContext(HqlCppTranslator & _translator, ParentExtract * _parentExtract, EvalContext * _parent, BuildCtx & createctx, BuildCtx & startctx); virtual void callNestedHelpers(const char * memberName); virtual IHqlExpression * createGraphLookup(unique_id_t id, bool isChild) { throwUnexpected(); } virtual void ensureHelpersExist(); virtual bool isColocal() { return false; } }; class ActivityEvalContext : public ClassEvalContext { friend class ActivityInstance; public: ActivityEvalContext(HqlCppTranslator & _translator, ActivityInstance * _activity, ParentExtract * _parentExtract, EvalContext * _parent, IHqlExpression * _colocal, BuildCtx & createctx, BuildCtx & startctx); virtual void callNestedHelpers(const char * memberName); virtual IHqlExpression * createGraphLookup(unique_id_t id, bool isChild); virtual void ensureHelpersExist(); virtual bool isColocal() { return (colocalMember != NULL); } virtual ActivityInstance * queryActivity(); void createMemberAlias(CtxCollection & ctxs, BuildCtx & ctx, IHqlExpression * value, CHqlBoundExpr & tgt); protected: ActivityInstance * activity; }; class NestedEvalContext : public ClassEvalContext { public: NestedEvalContext(HqlCppTranslator & _translator, const char * _memberName, ParentExtract * _parentExtract, EvalContext * _parent, IHqlExpression * _colocal, BuildCtx & createctx, BuildCtx & startctx); virtual void callNestedHelpers(const char * memberName); virtual IHqlExpression * createGraphLookup(unique_id_t id, bool isChild); virtual void ensureHelpersExist(); void initContext(); virtual bool evaluateInParent(BuildCtx & ctx, IHqlExpression * expr, bool hasOnStart); protected: bool helpersExist; protected: StringAttr memberName; }; class MemberEvalContext : public EvalContext { public: MemberEvalContext(HqlCppTranslator & _translator, ParentExtract * _parentExtract, EvalContext * _parent, BuildCtx & _ctx); virtual void callNestedHelpers(const char * memberName); virtual void ensureHelpersExist(); virtual bool isRowInvariant(IHqlExpression * expr); virtual IHqlExpression * createGraphLookup(unique_id_t id, bool isChild); virtual AliasKind evaluateExpression(BuildCtx & ctx, IHqlExpression * value, CHqlBoundExpr & tgt, bool evaluateLocally); virtual bool getInvariantMemberContext(BuildCtx * ctx, BuildCtx * * declarectx, BuildCtx * * initctx, bool isIndependentMaybeShared, bool invariantEachStart); virtual void tempCompatiablityEnsureSerialized(const CHqlBoundTarget & tgt); void initContext(); protected: BuildCtx ctx; }; class LibraryEvalContext : public EvalContext { public: LibraryEvalContext(HqlCppTranslator & _translator); virtual AliasKind evaluateExpression(BuildCtx & ctx, IHqlExpression * value, CHqlBoundExpr & tgt, bool evaluateLocally); virtual bool isColocal() { return false; } virtual bool isLibraryContext() { return true; } virtual void tempCompatiablityEnsureSerialized(const CHqlBoundTarget & tgt); void associateExpression(BuildCtx & ctx, IHqlExpression * value); void ensureContextAvailable() { } public: virtual void callNestedHelpers(const char * memberName) {} virtual void ensureHelpersExist() {} protected: HqlExprArray values; HqlExprArray bound; }; #endif