2008-05-19 15:47:48 +02:00
|
|
|
/*
|
|
|
|
* The contents of this file are subject to the Initial
|
|
|
|
* Developer's Public License Version 1.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the
|
|
|
|
* License. You may obtain a copy of the License at
|
|
|
|
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed AS IS,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing rights
|
|
|
|
* and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code was created by Adriano dos Santos Fernandes
|
|
|
|
* for the Firebird Open Source RDBMS project.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2008 Adriano dos Santos Fernandes <adrianosf@uol.com.br>
|
|
|
|
* and all contributors signed below.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef DSQL_NODES_H
|
|
|
|
#define DSQL_NODES_H
|
|
|
|
|
|
|
|
#include "../jrd/common.h"
|
|
|
|
#include "../dsql/dsql.h"
|
2010-02-13 21:29:29 +01:00
|
|
|
#include "../dsql/node.h"
|
|
|
|
#include "../dsql/Visitors.h"
|
|
|
|
#include "../common/classes/array.h"
|
2008-05-19 15:47:48 +02:00
|
|
|
|
|
|
|
namespace Jrd {
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
class AggregateSort;
|
2008-05-19 15:47:48 +02:00
|
|
|
class CompilerScratch;
|
2010-02-22 17:00:49 +01:00
|
|
|
class Cursor;
|
2010-02-13 21:29:29 +01:00
|
|
|
class dsql_nod;
|
|
|
|
class ExprNode;
|
|
|
|
class jrd_nod;
|
2010-02-22 17:00:49 +01:00
|
|
|
class RecordSelExpr;
|
2010-02-16 01:26:53 +01:00
|
|
|
class SlidingWindow;
|
2009-10-21 02:42:38 +02:00
|
|
|
class TypeClause;
|
2008-05-19 15:47:48 +02:00
|
|
|
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
template <typename T>
|
|
|
|
class RegisterNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit RegisterNode(UCHAR blr)
|
|
|
|
{
|
|
|
|
PAR_register(blr, T::parse);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
class Node : public Firebird::PermanentStorage
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit Node(MemoryPool& pool)
|
|
|
|
: PermanentStorage(pool),
|
2009-12-20 22:01:10 +01:00
|
|
|
dsqlScratch(NULL)
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~Node()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2009-12-20 22:01:10 +01:00
|
|
|
Node* dsqlPass(DsqlCompilerScratch* aDsqlScratch)
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
2009-12-20 22:01:10 +01:00
|
|
|
dsqlScratch = aDsqlScratch;
|
2009-10-21 02:42:38 +02:00
|
|
|
return internalDsqlPass();
|
2008-05-19 15:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const = 0;
|
|
|
|
|
|
|
|
protected:
|
2009-10-21 02:42:38 +02:00
|
|
|
virtual Node* internalDsqlPass()
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2009-12-20 22:01:10 +01:00
|
|
|
DsqlCompilerScratch* dsqlScratch;
|
2008-05-19 15:47:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class DdlNode : public Node
|
|
|
|
{
|
|
|
|
public:
|
2009-10-21 02:42:38 +02:00
|
|
|
explicit DdlNode(MemoryPool& pool, const Firebird::string& aSqlText)
|
|
|
|
: Node(pool),
|
|
|
|
sqlText(pool, aSqlText)
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
public:
|
|
|
|
const Firebird::string& getSqlText()
|
|
|
|
{
|
|
|
|
return sqlText;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum DdlTriggerWhen { DTW_BEFORE, DTW_AFTER };
|
|
|
|
static void executeDdlTrigger(thread_db* tdbb, jrd_tra* transaction,
|
|
|
|
DdlTriggerWhen when, int action, const Firebird::MetaName& objectName,
|
|
|
|
const Firebird::string& sqlText);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void executeDdlTrigger(thread_db* tdbb, jrd_tra* transaction,
|
|
|
|
DdlTriggerWhen when, int action, const Firebird::MetaName& objectName);
|
|
|
|
void putType(const TypeClause& type, bool useSubType);
|
|
|
|
void resetContextStack();
|
2009-12-21 18:23:07 +01:00
|
|
|
Firebird::MetaName storeGlobalField(thread_db* tdbb, jrd_tra* transaction,
|
|
|
|
const TypeClause& parameter);
|
2009-10-21 02:42:38 +02:00
|
|
|
|
2008-05-25 17:41:54 +02:00
|
|
|
protected:
|
2009-12-20 22:01:10 +01:00
|
|
|
virtual DdlNode* internalDsqlPass()
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
2009-12-23 01:57:08 +01:00
|
|
|
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
|
2008-05-25 17:41:54 +02:00
|
|
|
return this;
|
2008-05-19 15:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual void execute(thread_db* tdbb, jrd_tra* transaction) = 0;
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
Firebird::string sqlText;
|
2008-05-19 15:47:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class DmlNode : public Node
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit DmlNode(MemoryPool& pool)
|
2009-10-21 02:42:38 +02:00
|
|
|
: Node(pool),
|
|
|
|
node(NULL)
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2010-02-21 02:47:54 +01:00
|
|
|
virtual DmlNode* pass1(thread_db* tdbb, CompilerScratch* csb, jrd_nod* aNode);
|
2008-05-19 15:47:48 +02:00
|
|
|
virtual DmlNode* pass2(thread_db* tdbb, CompilerScratch* csb, jrd_nod* aNode);
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual void genBlr() = 0;
|
|
|
|
virtual DmlNode* pass1(thread_db* tdbb, CompilerScratch* csb) = 0;
|
|
|
|
virtual DmlNode* pass2(thread_db* tdbb, CompilerScratch* csb) = 0;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
jrd_nod* node;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
template <typename T, typename T::Type typeConst>
|
|
|
|
class TypedNode : public T
|
|
|
|
{
|
|
|
|
public:
|
2010-02-16 09:53:31 +01:00
|
|
|
explicit TypedNode(MemoryPool& pool)
|
2010-02-13 21:29:29 +01:00
|
|
|
: T(typeConst, pool)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
const static typename T::Type TYPE = typeConst;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ExprNode : public DmlNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum Type
|
|
|
|
{
|
|
|
|
TYPE_AGGREGATE,
|
|
|
|
TYPE_CONCATENATE,
|
2010-02-21 02:47:54 +01:00
|
|
|
TYPE_OVER,
|
|
|
|
TYPE_SUBSTRING_SIMILAR
|
2010-02-13 21:29:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
explicit ExprNode(Type aType, MemoryPool& pool)
|
|
|
|
: DmlNode(pool),
|
|
|
|
type(aType),
|
|
|
|
dsqlCompatDialectVerb(NULL),
|
|
|
|
dsqlChildNodes(pool),
|
|
|
|
jrdChildNodes(pool)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> T* as()
|
|
|
|
{
|
|
|
|
return type == T::TYPE ? (T*) this : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> const T* as() const
|
|
|
|
{
|
|
|
|
return type == T::TYPE ? (T*) this : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> bool is() const
|
|
|
|
{
|
|
|
|
return type == T::TYPE;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename LegacyType> static T* as(LegacyType* node)
|
|
|
|
{
|
|
|
|
ExprNode* obj = T::fromLegacy(node);
|
|
|
|
return obj ? obj->as<T>() : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename LegacyType> static const T* as(const LegacyType* node)
|
|
|
|
{
|
|
|
|
const ExprNode* obj = T::fromLegacy(const_cast<LegacyType*>(node));
|
|
|
|
return obj ? obj->as<T>() : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename LegacyType> static bool is(const LegacyType* node)
|
|
|
|
{
|
|
|
|
ExprNode* obj = T::fromLegacy(const_cast<LegacyType*>(node));
|
|
|
|
return obj ? obj->is<T>() : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ExprNode* fromLegacy(dsql_nod* node);
|
|
|
|
static ExprNode* fromLegacy(jrd_nod* node);
|
|
|
|
|
|
|
|
virtual bool dsqlAggregateFinder(AggregateFinder& visitor)
|
|
|
|
{
|
|
|
|
return dsqlVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool dsqlAggregate2Finder(Aggregate2Finder& visitor)
|
|
|
|
{
|
|
|
|
return dsqlVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool dsqlFieldFinder(FieldFinder& visitor)
|
|
|
|
{
|
|
|
|
return dsqlVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool dsqlInvalidReferenceFinder(InvalidReferenceFinder& visitor)
|
|
|
|
{
|
|
|
|
return dsqlVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool dsqlSubSelectFinder(SubSelectFinder& visitor)
|
|
|
|
{
|
|
|
|
return dsqlVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool dsqlFieldRemapper(FieldRemapper& visitor)
|
|
|
|
{
|
|
|
|
return dsqlVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool jrdPossibleUnknownFinder(PossibleUnknownFinder& visitor)
|
|
|
|
{
|
|
|
|
return jrdVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool jrdStreamFinder(StreamFinder& visitor)
|
|
|
|
{
|
|
|
|
return jrdVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool jrdStreamsCollector(StreamsCollector& visitor)
|
|
|
|
{
|
|
|
|
return jrdVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool jrdUnmappedNodeGetter(UnmappedNodeGetter& visitor)
|
|
|
|
{
|
|
|
|
visitor.nodeFound = node;
|
|
|
|
return jrdVisit(visitor);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool isArrayOrBlob(DsqlCompilerScratch* dsqlScratch) const;
|
|
|
|
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
|
|
|
virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const;
|
|
|
|
virtual ExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
|
|
|
virtual ExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
|
|
|
|
2010-02-16 09:53:31 +01:00
|
|
|
virtual bool setParameterType(DsqlCompilerScratch* /*dsqlScratch*/,
|
|
|
|
dsql_nod* /*node*/, bool /*forceVarChar*/) const
|
2010-02-13 21:29:29 +01:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void setParameterName(dsql_par* parameter) const = 0;
|
|
|
|
virtual void make(dsc* desc, dsql_nod* nullReplacement) = 0;
|
|
|
|
|
|
|
|
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc) = 0;
|
|
|
|
virtual ExprNode* copy(thread_db* tdbb, NodeCopier& copier) const = 0;
|
|
|
|
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const = 0;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual bool dsqlVisit(ConstDsqlNodeVisitor& visitor);
|
|
|
|
virtual bool dsqlVisit(NonConstDsqlNodeVisitor& visitor);
|
|
|
|
virtual bool jrdVisit(JrdNodeVisitor& visitor);
|
|
|
|
|
|
|
|
void addChildNode(dsql_nod*& dsqlNode, jrd_nod*& jrdNode)
|
|
|
|
{
|
|
|
|
dsqlChildNodes.add(&dsqlNode);
|
|
|
|
jrdChildNodes.add(&jrdNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
void addChildNode(dsql_nod*& dsqlNode)
|
|
|
|
{
|
|
|
|
dsqlChildNodes.add(&dsqlNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
const Type type;
|
|
|
|
const char* dsqlCompatDialectVerb;
|
|
|
|
Firebird::Array<dsql_nod**> dsqlChildNodes;
|
|
|
|
Firebird::Array<jrd_nod**> jrdChildNodes;
|
|
|
|
};
|
|
|
|
|
|
|
|
class AggNode : public TypedNode<ExprNode, ExprNode::TYPE_AGGREGATE>
|
|
|
|
{
|
2010-02-14 20:08:22 +01:00
|
|
|
protected:
|
2010-02-13 21:29:29 +01:00
|
|
|
struct AggInfo
|
|
|
|
{
|
2010-02-14 20:08:22 +01:00
|
|
|
AggInfo(const char* aName, UCHAR aBlr, UCHAR aDistinctBlr)
|
|
|
|
: name(aName),
|
|
|
|
blr(aBlr),
|
|
|
|
distinctBlr(aDistinctBlr)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-02-15 01:43:04 +01:00
|
|
|
const char* const name;
|
|
|
|
const UCHAR blr;
|
|
|
|
const UCHAR distinctBlr;
|
2010-02-13 21:29:29 +01:00
|
|
|
};
|
|
|
|
|
2010-02-14 20:08:22 +01:00
|
|
|
public:
|
|
|
|
template <typename T>
|
|
|
|
class Register : public AggInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit Register(const char* aName, UCHAR blr, UCHAR blrDistinct)
|
|
|
|
: AggInfo(aName, blr, blrDistinct),
|
|
|
|
registerNode1(blr),
|
|
|
|
registerNode2(blrDistinct)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
explicit Register(const char* aName, UCHAR blr)
|
|
|
|
: AggInfo(aName, blr, blr),
|
|
|
|
registerNode1(blr),
|
|
|
|
registerNode2(blr)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
RegisterNode<T> registerNode1, registerNode2;
|
|
|
|
};
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
explicit AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool aDialect1,
|
|
|
|
dsql_nod* aArg = NULL);
|
|
|
|
|
|
|
|
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
|
|
|
|
|
|
|
virtual bool dsqlAggregateFinder(AggregateFinder& visitor);
|
|
|
|
virtual bool dsqlAggregate2Finder(Aggregate2Finder& visitor);
|
|
|
|
virtual bool dsqlInvalidReferenceFinder(InvalidReferenceFinder& visitor);
|
|
|
|
virtual bool dsqlSubSelectFinder(SubSelectFinder& visitor);
|
|
|
|
virtual bool dsqlFieldRemapper(FieldRemapper& visitor);
|
|
|
|
|
|
|
|
virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const;
|
|
|
|
virtual void setParameterName(dsql_par* parameter) const;
|
|
|
|
virtual void genBlr();
|
|
|
|
|
|
|
|
virtual ExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
|
|
|
|
2010-02-16 09:53:31 +01:00
|
|
|
virtual bool jrdPossibleUnknownFinder(PossibleUnknownFinder& /*visitor*/)
|
2010-02-13 21:29:29 +01:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-02-16 09:53:31 +01:00
|
|
|
virtual bool jrdStreamFinder(StreamFinder& /*visitor*/)
|
2010-02-13 21:29:29 +01:00
|
|
|
{
|
|
|
|
// ASF: Although in v2.5 the visitor happens normally for the node childs, nod_count has
|
|
|
|
// been set to 0 in CMP_pass2, so that doesn't happens.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-02-16 09:53:31 +01:00
|
|
|
virtual bool jrdStreamsCollector(StreamsCollector& /*visitor*/)
|
2010-02-13 21:29:29 +01:00
|
|
|
{
|
|
|
|
// ASF: Although in v2.5 the visitor happens normally for the node childs, nod_count has
|
|
|
|
// been set to 0 in CMP_pass2, so that doesn't happens.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool jrdUnmappedNodeGetter(UnmappedNodeGetter& visitor)
|
|
|
|
{
|
|
|
|
visitor.invalid = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void checkOrderedWindowCapable() const
|
|
|
|
{
|
|
|
|
if (distinct)
|
|
|
|
{
|
|
|
|
Firebird::status_exception::raise(
|
|
|
|
Firebird::Arg::Gds(isc_wish_list) <<
|
|
|
|
Firebird::Arg::Gds(isc_random) <<
|
|
|
|
"DISTINCT is not supported in ordered windows");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-14 20:08:22 +01:00
|
|
|
virtual bool shouldCallWinPass() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-02-16 09:53:31 +01:00
|
|
|
virtual dsc* winPass(thread_db* /*tdbb*/, jrd_req* /*request*/, SlidingWindow* /*window*/) const
|
2010-02-14 20:08:22 +01:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
virtual void aggInit(thread_db* tdbb, jrd_req* request) const = 0; // pure, but defined
|
|
|
|
virtual void aggFinish(thread_db* tdbb, jrd_req* request) const;
|
|
|
|
virtual void aggPass(thread_db* tdbb, jrd_req* request) const;
|
|
|
|
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const;
|
|
|
|
|
|
|
|
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const = 0;
|
|
|
|
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const = 0;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual ExprNode* internalDsqlPass();
|
|
|
|
virtual AggNode* dsqlCopy() const = 0;
|
|
|
|
|
|
|
|
public:
|
|
|
|
const AggInfo& aggInfo;
|
|
|
|
bool distinct;
|
|
|
|
bool dialect1;
|
|
|
|
dsql_nod* dsqlArg;
|
|
|
|
jrd_nod* arg;
|
|
|
|
AggregateSort* asb;
|
|
|
|
bool indexed;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-02-15 01:43:04 +01:00
|
|
|
// Base class for window functions.
|
2010-02-14 20:08:22 +01:00
|
|
|
class WinFuncNode : public AggNode
|
|
|
|
{
|
|
|
|
private:
|
2010-02-15 01:43:04 +01:00
|
|
|
// Base factory to create instance of subclasses.
|
2010-02-14 20:08:22 +01:00
|
|
|
class Factory : public AggInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit Factory(const char* aName)
|
|
|
|
: AggInfo(aName, 0, 0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual WinFuncNode* newInstance(MemoryPool& pool) const = 0;
|
|
|
|
|
|
|
|
public:
|
|
|
|
const Factory* next;
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
2010-02-15 01:43:04 +01:00
|
|
|
// Concrete implementation of the factory.
|
2010-02-14 20:08:22 +01:00
|
|
|
template <typename T>
|
|
|
|
class Register : public Factory
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit Register(const char* aName)
|
|
|
|
: Factory(aName)
|
|
|
|
{
|
|
|
|
next = factories;
|
|
|
|
factories = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
WinFuncNode* newInstance(MemoryPool& pool) const
|
|
|
|
{
|
|
|
|
return new T(pool);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
explicit WinFuncNode(MemoryPool& pool, const AggInfo& aAggInfo, dsql_nod* aArg = NULL);
|
|
|
|
|
|
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp);
|
|
|
|
|
|
|
|
private:
|
|
|
|
static Factory* factories;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
class StmtNode : public DmlNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit StmtNode(MemoryPool& pool)
|
|
|
|
: DmlNode(pool)
|
|
|
|
{
|
|
|
|
}
|
2010-02-13 21:29:29 +01:00
|
|
|
|
|
|
|
public:
|
2010-02-22 17:00:49 +01:00
|
|
|
virtual void pass2Cursor(RecordSelExpr*& rsePtr, Cursor**& cursorPtr)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
virtual jrd_nod* execute(thread_db* tdbb, jrd_req* request) const = 0;
|
2008-05-19 15:47:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-10-31 04:33:45 +01:00
|
|
|
// Used to represent nodes that don't have a specific BLR verb, i.e.,
|
|
|
|
// do not use RegisterNode.
|
2009-10-24 19:45:33 +02:00
|
|
|
class DsqlOnlyStmtNode : public StmtNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit DsqlOnlyStmtNode(MemoryPool& pool)
|
|
|
|
: StmtNode(pool)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2009-10-30 11:43:42 +01:00
|
|
|
DsqlOnlyStmtNode* pass1(thread_db* /*tdbb*/, CompilerScratch* /*csb*/)
|
2009-10-24 19:45:33 +02:00
|
|
|
{
|
|
|
|
fb_assert(false);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2009-10-30 11:43:42 +01:00
|
|
|
DsqlOnlyStmtNode* pass2(thread_db* /*tdbb*/, CompilerScratch* /*csb*/)
|
2009-10-24 19:45:33 +02:00
|
|
|
{
|
|
|
|
fb_assert(false);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2009-12-23 01:57:08 +01:00
|
|
|
jrd_nod* execute(thread_db* /*tdbb*/, jrd_req* /*request*/) const
|
2009-10-24 19:45:33 +02:00
|
|
|
{
|
|
|
|
fb_assert(false);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-01-05 18:32:42 +01:00
|
|
|
// This class (via the make method) does the job that pass1_savepoint does for the legacy nodes.
|
|
|
|
class SavepointEncloseNode : public DsqlOnlyStmtNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit SavepointEncloseNode(MemoryPool& pool, StmtNode* aStmt)
|
|
|
|
: DsqlOnlyStmtNode(pool),
|
|
|
|
stmt(aStmt)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
static StmtNode* make(MemoryPool& pool, DsqlCompilerScratch* dsqlScratch, StmtNode* node);
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
|
|
|
virtual void genBlr();
|
|
|
|
|
|
|
|
private:
|
|
|
|
StmtNode* stmt;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
// Common node for all "code blocks" (i.e.: procedures, triggers and execute block)
|
|
|
|
class BlockNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ~BlockNode()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual void genReturn() = 0;
|
|
|
|
virtual dsql_nod* resolveVariable(const dsql_str* varName) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
#endif // DSQL_NODES_H
|