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
|
|
|
|
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
#include "../jrd/jrd.h"
|
2010-08-27 04:18:00 +02:00
|
|
|
#include "../dsql/DsqlCompilerScratch.h"
|
2010-02-13 21:29:29 +01:00
|
|
|
#include "../dsql/node.h"
|
|
|
|
#include "../dsql/Visitors.h"
|
|
|
|
#include "../common/classes/array.h"
|
2010-08-09 17:48:51 +02:00
|
|
|
#include "../common/classes/NestConst.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;
|
2010-09-20 18:07:50 +02:00
|
|
|
class OptimizerRetrieval;
|
2010-08-24 05:25:01 +02:00
|
|
|
class RseNode;
|
2010-02-16 01:26:53 +01:00
|
|
|
class SlidingWindow;
|
2009-10-21 02:42:38 +02:00
|
|
|
class TypeClause;
|
2010-11-21 04:47:29 +01:00
|
|
|
class ValueExprNode;
|
2008-05-19 15:47:48 +02:00
|
|
|
|
|
|
|
|
2010-09-20 18:07:50 +02:00
|
|
|
// Must be less then MAX_SSHORT. Not used for static arrays.
|
|
|
|
const int MAX_CONJUNCTS = 32000;
|
|
|
|
|
|
|
|
// Note that MAX_STREAMS currently MUST be <= MAX_UCHAR.
|
|
|
|
// Here we should really have a compile-time fb_assert, since this hard-coded
|
|
|
|
// limit is NOT negotiable so long as we use an array of UCHAR, where index 0
|
|
|
|
// tells how many streams are in the array (and the streams themselves are
|
|
|
|
// identified by a UCHAR).
|
2011-01-21 18:16:13 +01:00
|
|
|
const unsigned int MAX_STREAMS = 255;
|
2010-09-20 18:07:50 +02:00
|
|
|
|
|
|
|
// This is number of ULONG's needed to store bit-mapped flags for all streams
|
2012-02-22 02:29:35 +01:00
|
|
|
// OPT_STREAM_BITS = (MAX_STREAMS + 1) / BITS_PER_LONG
|
2010-09-20 18:07:50 +02:00
|
|
|
// This value cannot be increased simple way. Decrease is possible, but it is also
|
|
|
|
// hardcoded in several places such as TEST_DEP_ARRAYS macro
|
|
|
|
const int OPT_STREAM_BITS = 8;
|
|
|
|
|
|
|
|
// Number of streams, conjuncts, indices that will be statically allocated
|
|
|
|
// in various arrays. Larger numbers will have to be allocated dynamically
|
|
|
|
const int OPT_STATIC_ITEMS = 16;
|
|
|
|
|
|
|
|
|
2012-02-23 08:17:12 +01:00
|
|
|
typedef USHORT StreamType; // for now
|
|
|
|
|
2011-02-20 16:34:08 +01:00
|
|
|
typedef Firebird::HalfStaticArray<UCHAR, OPT_STATIC_ITEMS> StreamList;
|
2010-09-20 18:07:50 +02:00
|
|
|
typedef Firebird::SortedArray<int> SortedStreamList;
|
|
|
|
typedef UCHAR stream_array_t[MAX_STREAMS + 1];
|
|
|
|
|
2010-11-21 04:47:29 +01:00
|
|
|
typedef Firebird::Array<NestConst<ValueExprNode> > NestValueArray;
|
|
|
|
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
template <typename T>
|
|
|
|
class RegisterNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit RegisterNode(UCHAR blr)
|
|
|
|
{
|
|
|
|
PAR_register(blr, T::parse);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2010-09-20 18:07:50 +02:00
|
|
|
template <typename T>
|
|
|
|
class RegisterBoolNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit RegisterBoolNode(UCHAR blr)
|
|
|
|
{
|
|
|
|
PAR_register(blr, T::parse);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
class Node : public Firebird::PermanentStorage
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit Node(MemoryPool& pool)
|
2012-03-25 03:08:55 +02:00
|
|
|
: PermanentStorage(pool),
|
|
|
|
line(0),
|
|
|
|
column(0)
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~Node()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-02-20 03:02:04 +01:00
|
|
|
// Compile a parsed statement into something more interesting.
|
|
|
|
template <typename T>
|
|
|
|
static T* doDsqlPass(DsqlCompilerScratch* dsqlScratch, T* node)
|
|
|
|
{
|
|
|
|
if (!node)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return node->dsqlPass(dsqlScratch);
|
|
|
|
}
|
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const = 0;
|
|
|
|
|
2010-09-24 11:53:51 +02:00
|
|
|
virtual Node* dsqlPass(DsqlCompilerScratch* /*dsqlScratch*/)
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
2012-03-25 03:08:55 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
USHORT line;
|
|
|
|
USHORT column;
|
2008-05-19 15:47:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class DdlNode : public Node
|
|
|
|
{
|
|
|
|
public:
|
2010-08-05 02:47:06 +02:00
|
|
|
explicit DdlNode(MemoryPool& pool)
|
|
|
|
: Node(pool)
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
static bool deleteSecurityClass(thread_db* tdbb, jrd_tra* transaction,
|
|
|
|
const Firebird::MetaName& secClass);
|
|
|
|
|
2012-01-09 10:48:14 +01:00
|
|
|
static void storePrivileges(thread_db* tdbb, jrd_tra* transaction,
|
|
|
|
const Firebird::MetaName& name, int type, const char* privileges);
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
public:
|
2010-03-06 20:10:48 +01:00
|
|
|
// Set the scratch's transaction when executing a node. Fact of accessing the scratch during
|
|
|
|
// execution is a hack.
|
2010-09-17 05:15:32 +02:00
|
|
|
void executeDdl(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
|
2010-03-06 20:10:48 +01:00
|
|
|
{
|
2010-07-26 04:37:57 +02:00
|
|
|
using namespace Firebird;
|
|
|
|
|
2011-11-22 17:33:25 +01:00
|
|
|
// dsqlScratch should be NULL with CREATE DATABASE.
|
|
|
|
if (dsqlScratch)
|
|
|
|
dsqlScratch->setTransaction(transaction);
|
2010-07-26 04:37:57 +02:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2010-09-17 05:15:32 +02:00
|
|
|
execute(tdbb, dsqlScratch, transaction);
|
2010-07-26 04:37:57 +02:00
|
|
|
}
|
|
|
|
catch (status_exception& ex)
|
|
|
|
{
|
|
|
|
// Rethrow an exception with isc_no_meta_update and prefix codes.
|
|
|
|
|
|
|
|
Arg::StatusVector newVector;
|
|
|
|
newVector << Arg::Gds(isc_no_meta_update);
|
|
|
|
putErrorPrefix(newVector);
|
|
|
|
|
|
|
|
const ISC_STATUS* status = ex.value();
|
|
|
|
|
|
|
|
if (status[1] == isc_no_meta_update)
|
|
|
|
status += 2;
|
|
|
|
|
|
|
|
newVector.append(Arg::StatusVector(status));
|
|
|
|
|
|
|
|
status_exception::raise(newVector);
|
|
|
|
}
|
2010-03-06 20:10:48 +01:00
|
|
|
}
|
|
|
|
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
|
|
|
{
|
|
|
|
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
public:
|
|
|
|
enum DdlTriggerWhen { DTW_BEFORE, DTW_AFTER };
|
2010-07-26 04:37:57 +02:00
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
static void executeDdlTrigger(thread_db* tdbb, jrd_tra* transaction,
|
|
|
|
DdlTriggerWhen when, int action, const Firebird::MetaName& objectName,
|
|
|
|
const Firebird::string& sqlText);
|
|
|
|
|
|
|
|
protected:
|
2011-07-14 17:27:25 +02:00
|
|
|
typedef Firebird::Pair<Firebird::Left<Firebird::MetaName, bid> > MetaNameBidPair;
|
|
|
|
typedef Firebird::GenericMap<MetaNameBidPair> MetaNameBidMap;
|
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
// Return exception code based on combination of create and alter clauses.
|
|
|
|
static ISC_STATUS createAlterCode(bool create, bool alter, ISC_STATUS createCode,
|
|
|
|
ISC_STATUS alterCode, ISC_STATUS createOrAlterCode)
|
|
|
|
{
|
|
|
|
if (create && alter)
|
|
|
|
return createOrAlterCode;
|
2010-08-09 13:50:12 +02:00
|
|
|
|
|
|
|
if (create)
|
2010-07-26 04:37:57 +02:00
|
|
|
return createCode;
|
2010-08-09 13:50:12 +02:00
|
|
|
|
|
|
|
if (alter)
|
2010-07-26 04:37:57 +02:00
|
|
|
return alterCode;
|
2010-08-09 13:50:12 +02:00
|
|
|
|
|
|
|
fb_assert(false);
|
|
|
|
return 0;
|
2010-07-26 04:37:57 +02:00
|
|
|
}
|
|
|
|
|
2010-09-17 05:15:32 +02:00
|
|
|
void executeDdlTrigger(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction,
|
2009-10-21 02:42:38 +02:00
|
|
|
DdlTriggerWhen when, int action, const Firebird::MetaName& objectName);
|
2010-07-26 04:37:57 +02:00
|
|
|
void storeGlobalField(thread_db* tdbb, jrd_tra* transaction, Firebird::MetaName& name,
|
|
|
|
const TypeClause& field,
|
|
|
|
const Firebird::string& computedSource = "",
|
|
|
|
const BlrWriter::BlrData& computedValue = BlrWriter::BlrData());
|
2009-10-21 02:42:38 +02:00
|
|
|
|
2008-05-25 17:41:54 +02:00
|
|
|
protected:
|
2010-07-26 04:37:57 +02:00
|
|
|
// Prefix DDL exceptions. To be implemented in each command.
|
|
|
|
virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) = 0;
|
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
public:
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) = 0;
|
2008-05-19 15:47:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-02-25 20:56:37 +01:00
|
|
|
class TransactionNode : public Node
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit TransactionNode(MemoryPool& pool)
|
|
|
|
: Node(pool)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual TransactionNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
|
|
|
{
|
|
|
|
Node::dsqlPass(dsqlScratch);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
class DmlNode : public Node
|
|
|
|
{
|
|
|
|
public:
|
2010-12-04 23:15:03 +01:00
|
|
|
// DML node kinds
|
|
|
|
enum Kind
|
|
|
|
{
|
|
|
|
KIND_STATEMENT,
|
|
|
|
KIND_VALUE,
|
|
|
|
KIND_BOOLEAN,
|
|
|
|
KIND_REC_SOURCE
|
|
|
|
};
|
|
|
|
|
|
|
|
explicit DmlNode(MemoryPool& pool, Kind aKind)
|
|
|
|
: Node(pool),
|
2012-02-25 20:56:37 +01:00
|
|
|
kind(aKind)
|
2010-09-17 05:15:32 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
// Merge missing values, computed values, validation expressions, and views into a parsed request.
|
|
|
|
template <typename T> static void doPass1(thread_db* tdbb, CompilerScratch* csb, T** node)
|
|
|
|
{
|
|
|
|
if (!*node)
|
|
|
|
return;
|
|
|
|
|
|
|
|
*node = (*node)->pass1(tdbb, csb);
|
|
|
|
}
|
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
public:
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch) = 0;
|
2008-05-19 15:47:48 +02:00
|
|
|
virtual DmlNode* pass1(thread_db* tdbb, CompilerScratch* csb) = 0;
|
|
|
|
virtual DmlNode* pass2(thread_db* tdbb, CompilerScratch* csb) = 0;
|
2011-02-06 22:59:20 +01:00
|
|
|
virtual DmlNode* copy(thread_db* tdbb, NodeCopier& copier) const = 0;
|
2010-12-04 23:15:03 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
const Kind kind;
|
2008-05-19 15:47:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
// Stores a reference to a specialized ExprNode.
|
2011-04-02 06:24:20 +02:00
|
|
|
// This class and NodeRefImpl exists for nodes to replace themselves (eg. pass1) in a type-safe way.
|
2010-12-04 23:15:03 +01:00
|
|
|
class NodeRef
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ~NodeRef()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator !() const
|
|
|
|
{
|
|
|
|
return !getExpr();
|
|
|
|
}
|
|
|
|
|
|
|
|
operator bool() const
|
|
|
|
{
|
|
|
|
return getExpr() != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ExprNode* getExpr() = 0;
|
|
|
|
virtual const ExprNode* getExpr() const = 0;
|
|
|
|
|
|
|
|
virtual void pass1(thread_db* tdbb, CompilerScratch* csb) = 0;
|
|
|
|
void pass2(thread_db* tdbb, CompilerScratch* csb);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void internalPass2(thread_db* tdbb, CompilerScratch* csb) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T> class NodeRefImpl : public NodeRef
|
|
|
|
{
|
|
|
|
public:
|
2011-04-02 06:24:20 +02:00
|
|
|
explicit NodeRefImpl(T** aPtr)
|
2010-12-04 23:15:03 +01:00
|
|
|
: ptr(aPtr)
|
|
|
|
{
|
|
|
|
fb_assert(aPtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ExprNode* getExpr()
|
|
|
|
{
|
|
|
|
return *ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const ExprNode* getExpr() const
|
|
|
|
{
|
|
|
|
return *ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void pass1(thread_db* tdbb, CompilerScratch* csb)
|
|
|
|
{
|
|
|
|
DmlNode::doPass1(tdbb, csb, ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual inline void internalPass2(thread_db* tdbb, CompilerScratch* csb);
|
|
|
|
|
|
|
|
private:
|
|
|
|
T** ptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
class ExprNode : public DmlNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum Type
|
|
|
|
{
|
2010-11-21 04:47:29 +01:00
|
|
|
// Value types
|
2010-02-13 21:29:29 +01:00
|
|
|
TYPE_AGGREGATE,
|
2011-02-17 15:25:56 +01:00
|
|
|
TYPE_ALIAS,
|
Refactor a number of expression nodes: nod_add, nod_divide, nod_multiply, nod_negate, nod_user_name, nod_subtract, nod_current_date, nod_current_time, nod_current_timestamp, nod_add2, nod_subtract2, nod_multiply2, nod_divide2, nod_current_role, nod_internal_info
2010-09-04 23:36:41 +02:00
|
|
|
TYPE_ARITHMETIC,
|
2012-03-25 03:08:55 +02:00
|
|
|
TYPE_ARRAY,
|
2010-12-18 03:17:06 +01:00
|
|
|
TYPE_BOOL_AS_VALUE,
|
2010-11-02 00:57:31 +01:00
|
|
|
TYPE_CAST,
|
2011-02-06 19:13:12 +01:00
|
|
|
TYPE_COALESCE,
|
2012-03-25 03:08:55 +02:00
|
|
|
TYPE_COLLATE,
|
2010-02-13 21:29:29 +01:00
|
|
|
TYPE_CONCATENATE,
|
Refactor a number of expression nodes: nod_add, nod_divide, nod_multiply, nod_negate, nod_user_name, nod_subtract, nod_current_date, nod_current_time, nod_current_timestamp, nod_add2, nod_subtract2, nod_multiply2, nod_divide2, nod_current_role, nod_internal_info
2010-09-04 23:36:41 +02:00
|
|
|
TYPE_CURRENT_DATE,
|
|
|
|
TYPE_CURRENT_TIME,
|
|
|
|
TYPE_CURRENT_TIMESTAMP,
|
|
|
|
TYPE_CURRENT_ROLE,
|
|
|
|
TYPE_CURRENT_USER,
|
2010-11-07 23:12:14 +01:00
|
|
|
TYPE_DERIVED_EXPR,
|
2011-02-06 19:13:12 +01:00
|
|
|
TYPE_DECODE,
|
2010-11-14 18:25:48 +01:00
|
|
|
TYPE_DERIVED_FIELD,
|
2010-11-07 21:26:11 +01:00
|
|
|
TYPE_DOMAIN_VALIDATION,
|
2010-10-16 20:53:25 +02:00
|
|
|
TYPE_EXTRACT,
|
2010-11-14 18:25:48 +01:00
|
|
|
TYPE_FIELD,
|
2010-10-09 03:57:37 +02:00
|
|
|
TYPE_GEN_ID,
|
Refactor a number of expression nodes: nod_add, nod_divide, nod_multiply, nod_negate, nod_user_name, nod_subtract, nod_current_date, nod_current_time, nod_current_timestamp, nod_add2, nod_subtract2, nod_multiply2, nod_divide2, nod_current_role, nod_internal_info
2010-09-04 23:36:41 +02:00
|
|
|
TYPE_INTERNAL_INFO,
|
2010-10-24 02:26:00 +02:00
|
|
|
TYPE_LITERAL,
|
2010-11-14 18:25:48 +01:00
|
|
|
TYPE_MAP,
|
Refactor a number of expression nodes: nod_add, nod_divide, nod_multiply, nod_negate, nod_user_name, nod_subtract, nod_current_date, nod_current_time, nod_current_timestamp, nod_add2, nod_subtract2, nod_multiply2, nod_divide2, nod_current_role, nod_internal_info
2010-09-04 23:36:41 +02:00
|
|
|
TYPE_NEGATE,
|
2010-10-22 17:00:22 +02:00
|
|
|
TYPE_NULL,
|
2010-02-21 02:47:54 +01:00
|
|
|
TYPE_OVER,
|
2010-10-09 03:57:37 +02:00
|
|
|
TYPE_PARAMETER,
|
2010-11-14 18:25:48 +01:00
|
|
|
TYPE_RECORD_KEY,
|
2010-11-09 00:17:01 +01:00
|
|
|
TYPE_SCALAR,
|
2010-11-14 18:25:48 +01:00
|
|
|
TYPE_STMT_EXPR,
|
2010-10-09 20:39:45 +02:00
|
|
|
TYPE_STR_CASE,
|
2010-10-16 20:17:00 +02:00
|
|
|
TYPE_STR_LEN,
|
2010-11-07 03:18:58 +01:00
|
|
|
TYPE_SUBQUERY,
|
2010-10-16 19:42:04 +02:00
|
|
|
TYPE_SUBSTRING,
|
2010-04-05 20:43:11 +02:00
|
|
|
TYPE_SUBSTRING_SIMILAR,
|
|
|
|
TYPE_SYSFUNC_CALL,
|
2010-10-09 20:39:45 +02:00
|
|
|
TYPE_TRIM,
|
2010-09-20 18:07:50 +02:00
|
|
|
TYPE_UDF_CALL,
|
2010-11-02 18:05:01 +01:00
|
|
|
TYPE_VALUE_IF,
|
2010-11-21 04:47:29 +01:00
|
|
|
TYPE_VALUE_LIST,
|
|
|
|
TYPE_VARIABLE,
|
|
|
|
|
|
|
|
// Bool types
|
|
|
|
TYPE_BINARY_BOOL,
|
|
|
|
TYPE_COMPARATIVE_BOOL,
|
|
|
|
TYPE_MISSING_BOOL,
|
|
|
|
TYPE_NOT_BOOL,
|
|
|
|
TYPE_RSE_BOOL,
|
|
|
|
|
|
|
|
// RecordSource types
|
|
|
|
TYPE_AGGREGATE_SOURCE,
|
|
|
|
TYPE_PROCEDURE,
|
|
|
|
TYPE_RELATION,
|
|
|
|
TYPE_RSE,
|
2012-04-07 05:03:28 +02:00
|
|
|
TYPE_SELECT_EXPR,
|
2010-11-21 04:47:29 +01:00
|
|
|
TYPE_UNION,
|
|
|
|
TYPE_WINDOW
|
2010-02-13 21:29:29 +01:00
|
|
|
};
|
|
|
|
|
2010-11-14 23:31:42 +01:00
|
|
|
// Generic flags.
|
|
|
|
static const unsigned FLAG_INVARIANT = 0x01; // Node is recognized as being invariant.
|
|
|
|
|
|
|
|
// Boolean flags.
|
|
|
|
static const unsigned FLAG_DEOPTIMIZE = 0x02; // Boolean which requires deoptimization.
|
2011-02-26 10:31:46 +01:00
|
|
|
static const unsigned FLAG_RESIDUAL = 0x04; // Boolean which must remain residual.
|
|
|
|
static const unsigned FLAG_ANSI_NOT = 0x08; // ANY/ALL predicate is prefixed with a NOT one.
|
2010-11-14 23:31:42 +01:00
|
|
|
|
|
|
|
// Value flags.
|
2011-02-26 10:31:46 +01:00
|
|
|
static const unsigned FLAG_QUAD = 0x10; // Compute in quad (default is long).
|
|
|
|
static const unsigned FLAG_DOUBLE = 0x20;
|
|
|
|
static const unsigned FLAG_DATE = 0x40;
|
|
|
|
static const unsigned FLAG_VALUE = 0x80; // Full value area required in impure space.
|
2010-11-14 23:31:42 +01:00
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
explicit ExprNode(Type aType, MemoryPool& pool, Kind aKind)
|
|
|
|
: DmlNode(pool, aKind),
|
2010-02-13 21:29:29 +01:00
|
|
|
type(aType),
|
2010-11-14 23:31:42 +01:00
|
|
|
nodFlags(0),
|
|
|
|
impureOffset(0),
|
2010-02-13 21:29:29 +01:00
|
|
|
dsqlCompatDialectVerb(NULL),
|
|
|
|
dsqlChildNodes(pool),
|
|
|
|
jrdChildNodes(pool)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> T* as()
|
|
|
|
{
|
2010-11-21 04:47:29 +01:00
|
|
|
return type == T::TYPE ? static_cast<T*>(this) : NULL;
|
2010-02-13 21:29:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> const T* as() const
|
|
|
|
{
|
2010-11-21 04:47:29 +01:00
|
|
|
return type == T::TYPE ? static_cast<const T*>(this) : NULL;
|
2010-02-13 21:29:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2010-03-21 23:06:17 +01:00
|
|
|
const ExprNode* obj = T::fromLegacy(node);
|
|
|
|
return obj ? obj->as<T>() : NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
template <typename T, typename LegacyType> static bool is(const LegacyType* node)
|
|
|
|
{
|
2010-03-22 00:01:30 +01:00
|
|
|
const ExprNode* obj = T::fromLegacy(node);
|
2010-02-13 21:29:29 +01:00
|
|
|
return obj ? obj->is<T>() : false;
|
|
|
|
}
|
|
|
|
|
2010-11-21 04:47:29 +01:00
|
|
|
static const ExprNode* fromLegacy(const ExprNode* node)
|
|
|
|
{
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ExprNode* fromLegacy(ExprNode* node)
|
|
|
|
{
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
2010-03-21 23:06:17 +01:00
|
|
|
static ExprNode* fromLegacy(const dsql_nod* node);
|
2010-12-04 23:15:03 +01:00
|
|
|
|
|
|
|
// Allocate and assign impure space for various nodes.
|
|
|
|
template <typename T> static void doPass2(thread_db* tdbb, CompilerScratch* csb, T** node)
|
|
|
|
{
|
|
|
|
if (!*node)
|
|
|
|
return;
|
|
|
|
|
|
|
|
*node = (*node)->pass2(tdbb, csb);
|
|
|
|
}
|
2010-02-13 21:29:29 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2010-11-21 04:47:29 +01:00
|
|
|
virtual bool jrdPossibleUnknownFinder();
|
2011-03-10 09:13:02 +01:00
|
|
|
virtual bool jrdStreamFinder(USHORT findStream);
|
|
|
|
virtual void jrdStreamsCollector(SortedStreamList& streamList);
|
2010-11-21 04:47:29 +01:00
|
|
|
virtual bool jrdUnmappableNode(const MapNode* mapNode, UCHAR shellStream);
|
2010-02-13 21:29:29 +01:00
|
|
|
|
|
|
|
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
|
|
|
virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const;
|
|
|
|
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual ExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
2010-02-13 21:29:29 +01:00
|
|
|
{
|
2010-09-17 05:15:32 +02:00
|
|
|
DmlNode::dsqlPass(dsqlScratch);
|
|
|
|
return this;
|
2010-02-13 21:29:29 +01:00
|
|
|
}
|
|
|
|
|
2011-02-12 19:11:43 +01:00
|
|
|
// Determine if two expression trees are the same.
|
2011-02-12 15:01:36 +01:00
|
|
|
virtual bool sameAs(thread_db* tdbb, CompilerScratch* csb, /*const*/ ExprNode* other) /*const*/;
|
2010-11-21 04:47:29 +01:00
|
|
|
|
|
|
|
// See if node is presently computable.
|
2011-02-12 18:26:17 +01:00
|
|
|
// A node is said to be computable, if all the streams involved
|
2011-02-12 15:13:40 +01:00
|
|
|
// in that node are csb_active. The csb_active flag defines
|
|
|
|
// all the streams available in the current scope of the query.
|
|
|
|
virtual bool computable(CompilerScratch* csb, SSHORT stream,
|
2010-11-21 04:47:29 +01:00
|
|
|
bool allowOnlyCurrentStream, ValueExprNode* value = NULL);
|
|
|
|
|
2010-09-20 18:07:50 +02:00
|
|
|
virtual void findDependentFromStreams(const OptimizerRetrieval* optRet,
|
|
|
|
SortedStreamList* streamList);
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual ExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
|
|
|
virtual ExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
2011-02-06 22:59:20 +01:00
|
|
|
virtual ExprNode* copy(thread_db* tdbb, NodeCopier& copier) const = 0;
|
2010-02-13 21:29:29 +01:00
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual bool dsqlVisit(ConstDsqlNodeVisitor& visitor);
|
|
|
|
virtual bool dsqlVisit(NonConstDsqlNodeVisitor& visitor);
|
|
|
|
|
2010-11-21 04:47:29 +01:00
|
|
|
template <typename T>
|
|
|
|
void addChildNode(dsql_nod*& dsqlNode, NestConst<T>& jrdNode)
|
2010-02-13 21:29:29 +01:00
|
|
|
{
|
|
|
|
dsqlChildNodes.add(&dsqlNode);
|
2010-11-21 04:47:29 +01:00
|
|
|
jrdChildNodes.add(FB_NEW(getPool()) NodeRefImpl<T>(jrdNode.getAddress()));
|
2010-02-13 21:29:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void addChildNode(dsql_nod*& dsqlNode)
|
|
|
|
{
|
|
|
|
dsqlChildNodes.add(&dsqlNode);
|
|
|
|
}
|
|
|
|
|
2010-11-21 04:47:29 +01:00
|
|
|
template <typename T>
|
|
|
|
void addChildNode(NestConst<T>& jrdNode)
|
2010-10-09 03:57:37 +02:00
|
|
|
{
|
2010-11-21 04:47:29 +01:00
|
|
|
jrdChildNodes.add(FB_NEW(getPool()) NodeRefImpl<T>(jrdNode.getAddress()));
|
2010-10-09 03:57:37 +02:00
|
|
|
}
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
public:
|
|
|
|
const Type type;
|
2010-11-14 23:31:42 +01:00
|
|
|
unsigned nodFlags;
|
|
|
|
ULONG impureOffset;
|
2010-02-13 21:29:29 +01:00
|
|
|
const char* dsqlCompatDialectVerb;
|
|
|
|
Firebird::Array<dsql_nod**> dsqlChildNodes;
|
2010-11-21 04:47:29 +01:00
|
|
|
Firebird::Array<NodeRef*> jrdChildNodes;
|
2010-02-13 21:29:29 +01:00
|
|
|
};
|
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
inline void NodeRefImpl<T>::internalPass2(thread_db* tdbb, CompilerScratch* csb)
|
|
|
|
{
|
|
|
|
ExprNode::doPass2(tdbb, csb, ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-17 05:15:32 +02:00
|
|
|
class BoolExprNode : public ExprNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
BoolExprNode(Type aType, MemoryPool& pool)
|
2010-12-04 23:15:03 +01:00
|
|
|
: ExprNode(aType, pool, KIND_BOOLEAN)
|
2010-09-17 05:15:32 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual BoolExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
|
|
|
{
|
|
|
|
ExprNode::dsqlPass(dsqlScratch);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2011-02-12 15:13:40 +01:00
|
|
|
virtual bool computable(CompilerScratch* csb, SSHORT stream,
|
2010-11-21 04:47:29 +01:00
|
|
|
bool allowOnlyCurrentStream, ValueExprNode* value = NULL);
|
2010-09-20 18:07:50 +02:00
|
|
|
|
|
|
|
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb)
|
|
|
|
{
|
|
|
|
ExprNode::pass1(tdbb, csb);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual BoolExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
|
|
|
|
2010-09-24 11:53:51 +02:00
|
|
|
virtual void pass2Boolean1(thread_db* /*tdbb*/, CompilerScratch* /*csb*/)
|
2010-09-20 18:07:50 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-09-24 11:53:51 +02:00
|
|
|
virtual void pass2Boolean2(thread_db* /*tdbb*/, CompilerScratch* /*csb*/)
|
2010-09-20 18:07:50 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-02-06 22:59:20 +01:00
|
|
|
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const = 0;
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual bool execute(thread_db* tdbb, jrd_req* request) const = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ValueExprNode : public ExprNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ValueExprNode(Type aType, MemoryPool& pool)
|
2010-12-04 23:15:03 +01:00
|
|
|
: ExprNode(aType, pool, KIND_VALUE),
|
2010-11-14 23:31:42 +01:00
|
|
|
nodScale(0)
|
2010-09-17 05:15:32 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
|
|
|
{
|
|
|
|
ExprNode::dsqlPass(dsqlScratch);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-11-07 04:03:41 +01:00
|
|
|
virtual bool setParameterType(DsqlCompilerScratch* /*dsqlScratch*/,
|
2010-10-09 03:57:37 +02:00
|
|
|
dsql_nod* /*node*/, bool /*forceVarChar*/)
|
2010-09-17 05:15:32 +02:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void setParameterName(dsql_par* parameter) const = 0;
|
2010-11-07 04:03:41 +01:00
|
|
|
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc) = 0;
|
2010-09-17 05:15:32 +02:00
|
|
|
|
2010-11-21 04:47:29 +01:00
|
|
|
virtual ValueExprNode* pass1(thread_db* tdbb, CompilerScratch* csb)
|
|
|
|
{
|
|
|
|
ExprNode::pass1(tdbb, csb);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb)
|
|
|
|
{
|
|
|
|
ExprNode::pass2(tdbb, csb);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
// Compute descriptor for value expression.
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc) = 0;
|
2010-12-04 23:15:03 +01:00
|
|
|
|
2011-02-06 22:59:20 +01:00
|
|
|
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const = 0;
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const = 0;
|
2010-11-14 23:31:42 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
SCHAR nodScale;
|
2010-09-17 05:15:32 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class AggNode : public TypedNode<ValueExprNode, ExprNode::TYPE_AGGREGATE>
|
2010-02-13 21:29:29 +01:00
|
|
|
{
|
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;
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
2010-02-13 21:29:29 +01:00
|
|
|
|
2010-11-21 04:47:29 +01:00
|
|
|
virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
2010-02-13 21:29:29 +01:00
|
|
|
|
2010-11-21 04:47:29 +01:00
|
|
|
virtual bool jrdPossibleUnknownFinder()
|
2010-02-13 21:29:29 +01:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-01-24 04:37:43 +01:00
|
|
|
virtual bool jrdStreamFinder(USHORT /*findStream*/)
|
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;
|
|
|
|
}
|
|
|
|
|
2011-03-10 09:13:02 +01:00
|
|
|
virtual void jrdStreamsCollector(SortedStreamList& /*streamList*/)
|
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.
|
2010-11-21 04:47:29 +01:00
|
|
|
return;
|
2010-02-13 21:29:29 +01:00
|
|
|
}
|
|
|
|
|
2012-01-24 04:37:43 +01:00
|
|
|
virtual bool jrdUnmappableNode(const MapNode* /*mapNode*/, UCHAR /*shellStream*/)
|
2010-02-13 21:29:29 +01:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-12-04 19:36:26 +01:00
|
|
|
// Used to allocate aggregate impure inside the impure area of recursive CTEs.
|
|
|
|
virtual void aggPostRse(thread_db* tdbb, CompilerScratch* csb);
|
|
|
|
|
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;
|
2011-03-05 18:28:37 +01:00
|
|
|
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const;
|
2010-02-13 21:29:29 +01:00
|
|
|
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;
|
|
|
|
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual AggNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
|
2010-02-13 21:29:29 +01:00
|
|
|
protected:
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) const = 0;
|
2010-02-13 21:29:29 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
const AggInfo& aggInfo;
|
|
|
|
bool distinct;
|
|
|
|
bool dialect1;
|
|
|
|
dsql_nod* dsqlArg;
|
2010-11-21 04:47:29 +01:00
|
|
|
NestConst<ValueExprNode> arg;
|
2010-04-07 17:31:32 +02:00
|
|
|
const AggregateSort* asb;
|
2010-02-13 21:29:29 +01:00
|
|
|
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);
|
|
|
|
|
2010-11-21 04:47:29 +01:00
|
|
|
protected:
|
2012-01-24 04:37:43 +01:00
|
|
|
virtual void parseArgs(thread_db* /*tdbb*/, CompilerScratch* /*csb*/, unsigned count)
|
2010-11-21 04:47:29 +01:00
|
|
|
{
|
|
|
|
fb_assert(count == 0);
|
|
|
|
}
|
|
|
|
|
2010-02-14 20:08:22 +01:00
|
|
|
private:
|
|
|
|
static Factory* factories;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
class StmtNode : public DmlNode
|
|
|
|
{
|
|
|
|
public:
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
enum Type
|
|
|
|
{
|
2010-12-04 23:15:03 +01:00
|
|
|
TYPE_ASSIGNMENT,
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
TYPE_BLOCK,
|
2010-12-04 23:15:03 +01:00
|
|
|
TYPE_COMPOUND_STMT,
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
TYPE_CONTINUE_LEAVE,
|
|
|
|
TYPE_CURSOR_STMT,
|
|
|
|
TYPE_DECLARE_CURSOR,
|
2011-10-16 22:36:07 +02:00
|
|
|
TYPE_DECLARE_SUBFUNC,
|
2011-10-03 00:11:41 +02:00
|
|
|
TYPE_DECLARE_SUBPROC,
|
2010-12-04 23:15:03 +01:00
|
|
|
TYPE_DECLARE_VARIABLE,
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
TYPE_ERASE,
|
|
|
|
TYPE_ERROR_HANDLER,
|
|
|
|
TYPE_EXCEPTION,
|
|
|
|
TYPE_EXEC_BLOCK,
|
|
|
|
TYPE_EXEC_PROCEDURE,
|
|
|
|
TYPE_EXEC_STATEMENT,
|
|
|
|
TYPE_EXIT,
|
|
|
|
TYPE_IF,
|
|
|
|
TYPE_IN_AUTO_TRANS,
|
2010-12-04 23:15:03 +01:00
|
|
|
TYPE_INIT_VARIABLE,
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
TYPE_FOR,
|
|
|
|
TYPE_HANDLER,
|
|
|
|
TYPE_LABEL,
|
2011-03-05 03:47:22 +01:00
|
|
|
TYPE_LINE_COLUMN,
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
TYPE_LOOP,
|
|
|
|
TYPE_MERGE,
|
2011-03-04 02:47:49 +01:00
|
|
|
TYPE_MERGE_SEND,
|
2010-12-04 23:15:03 +01:00
|
|
|
TYPE_MESSAGE,
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
TYPE_MODIFY,
|
|
|
|
TYPE_POST_EVENT,
|
|
|
|
TYPE_RECEIVE,
|
|
|
|
TYPE_RETURN,
|
|
|
|
TYPE_SAVEPOINT,
|
|
|
|
TYPE_SAVEPOINT_ENCLOSE,
|
|
|
|
TYPE_SELECT,
|
|
|
|
TYPE_SET_GENERATOR,
|
|
|
|
TYPE_STALL,
|
|
|
|
TYPE_STORE,
|
|
|
|
TYPE_SUSPEND,
|
2011-03-04 02:47:49 +01:00
|
|
|
TYPE_UPDATE_OR_INSERT,
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
TYPE_USER_SAVEPOINT
|
|
|
|
};
|
|
|
|
|
|
|
|
enum WhichTrigger
|
|
|
|
{
|
|
|
|
ALL_TRIGS = 0,
|
|
|
|
PRE_TRIG = 1,
|
|
|
|
POST_TRIG = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ExeState
|
|
|
|
{
|
2011-04-02 06:24:20 +02:00
|
|
|
explicit ExeState(thread_db* tdbb)
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
: oldPool(tdbb->getDefaultPool()),
|
|
|
|
oldRequest(tdbb->getRequest()),
|
2011-02-09 11:59:24 +01:00
|
|
|
oldTransaction(tdbb->getTransaction()),
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
errorPending(false),
|
|
|
|
catchDisabled(false),
|
|
|
|
whichEraseTrig(ALL_TRIGS),
|
|
|
|
whichStoTrig(ALL_TRIGS),
|
|
|
|
whichModTrig(ALL_TRIGS),
|
|
|
|
topNode(NULL),
|
2011-02-09 22:26:18 +01:00
|
|
|
prevNode(NULL),
|
|
|
|
exit(false)
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-02-09 11:59:24 +01:00
|
|
|
MemoryPool* oldPool; // Save the old pool to restore on exit.
|
|
|
|
jrd_req* oldRequest; // Save the old request to restore on exit.
|
|
|
|
jrd_tra* oldTransaction; // Save the old transcation to restore on exit.
|
|
|
|
bool errorPending; // Is there an error pending to be handled?
|
|
|
|
bool catchDisabled; // Catch errors so we can unwind cleanly.
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
WhichTrigger whichEraseTrig;
|
|
|
|
WhichTrigger whichStoTrig;
|
|
|
|
WhichTrigger whichModTrig;
|
2010-12-04 23:15:03 +01:00
|
|
|
const StmtNode* topNode;
|
|
|
|
const StmtNode* prevNode;
|
2011-02-12 18:26:17 +01:00
|
|
|
bool exit; // Exit the looper when true.
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit StmtNode(Type aType, MemoryPool& pool)
|
2010-12-04 23:15:03 +01:00
|
|
|
: DmlNode(pool, KIND_STATEMENT),
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
type(aType),
|
2010-12-04 23:15:03 +01:00
|
|
|
parentStmt(NULL),
|
2010-12-05 01:55:54 +01:00
|
|
|
impureOffset(0),
|
2012-03-25 03:08:55 +02:00
|
|
|
hasLineColumn(false)
|
2008-05-19 15:47:48 +02:00
|
|
|
{
|
|
|
|
}
|
2010-02-13 21:29:29 +01:00
|
|
|
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
template <typename T> T* as()
|
|
|
|
{
|
|
|
|
return type == T::TYPE ? static_cast<T*>(this) : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> const T* as() const
|
|
|
|
{
|
|
|
|
return type == T::TYPE ? static_cast<const T*>(this) : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> bool is() const
|
|
|
|
{
|
|
|
|
return type == T::TYPE;
|
|
|
|
}
|
|
|
|
|
2012-02-20 03:02:04 +01:00
|
|
|
template <typename T, typename T2> static T* as(T2* node)
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
{
|
2012-02-20 03:02:04 +01:00
|
|
|
return node ? node->as<T>() : NULL;
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
}
|
|
|
|
|
2012-02-20 03:02:04 +01:00
|
|
|
template <typename T, typename T2> static const T* as(const T2* node)
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
{
|
2012-02-20 03:02:04 +01:00
|
|
|
return node ? node->as<T>() : NULL;
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
}
|
|
|
|
|
2012-02-20 03:02:04 +01:00
|
|
|
template <typename T, typename T2> static bool is(const T2* node)
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
{
|
2012-02-20 03:02:04 +01:00
|
|
|
return node && node->is<T>();
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
}
|
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
// Allocate and assign impure space for various nodes.
|
|
|
|
template <typename T> static void doPass2(thread_db* tdbb, CompilerScratch* csb, T** node,
|
|
|
|
StmtNode* parentStmt)
|
2010-11-14 23:31:42 +01:00
|
|
|
{
|
2010-12-04 23:15:03 +01:00
|
|
|
if (!*node)
|
|
|
|
return;
|
2010-11-14 23:31:42 +01:00
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
if (parentStmt)
|
|
|
|
(*node)->parentStmt = parentStmt;
|
|
|
|
|
|
|
|
*node = (*node)->pass2(tdbb, csb);
|
2010-11-14 23:31:42 +01:00
|
|
|
}
|
|
|
|
|
2011-02-22 01:51:56 +01:00
|
|
|
virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
|
|
|
{
|
|
|
|
DmlNode::dsqlPass(dsqlScratch);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
virtual StmtNode* pass1(thread_db* tdbb, CompilerScratch* csb) = 0;
|
|
|
|
virtual StmtNode* pass2(thread_db* tdbb, CompilerScratch* csb) = 0;
|
|
|
|
|
2012-01-24 04:37:43 +01:00
|
|
|
virtual StmtNode* copy(thread_db* /*tdbb*/, NodeCopier& /*copier*/) const
|
2010-02-22 17:00:49 +01:00
|
|
|
{
|
2010-12-04 23:15:03 +01:00
|
|
|
fb_assert(false);
|
|
|
|
Firebird::status_exception::raise(
|
|
|
|
Firebird::Arg::Gds(isc_cannot_copy_stmt) <<
|
|
|
|
Firebird::Arg::Num(int(type)));
|
|
|
|
|
|
|
|
return NULL;
|
2010-02-22 17:00:49 +01:00
|
|
|
}
|
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const = 0;
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
const Type type;
|
2010-12-04 23:15:03 +01:00
|
|
|
NestConst<StmtNode> parentStmt;
|
|
|
|
ULONG impureOffset; // Inpure offset from request block.
|
2010-12-05 01:55:54 +01:00
|
|
|
bool hasLineColumn;
|
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:
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
explicit DsqlOnlyStmtNode(Type aType, MemoryPool& pool)
|
|
|
|
: StmtNode(aType, pool)
|
2009-10-24 19:45:33 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2010-12-04 23:15:03 +01:00
|
|
|
virtual DsqlOnlyStmtNode* pass1(thread_db* /*tdbb*/, CompilerScratch* /*csb*/)
|
|
|
|
{
|
|
|
|
fb_assert(false);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual DsqlOnlyStmtNode* pass2(thread_db* /*tdbb*/, CompilerScratch* /*csb*/)
|
2009-10-24 19:45:33 +02:00
|
|
|
{
|
|
|
|
fb_assert(false);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2011-02-06 22:59:20 +01:00
|
|
|
virtual DsqlOnlyStmtNode* copy(thread_db* /*tdbb*/, NodeCopier& /*copier*/) const
|
2009-10-24 19:45:33 +02:00
|
|
|
{
|
|
|
|
fb_assert(false);
|
2011-02-06 22:59:20 +01:00
|
|
|
return NULL;
|
2009-10-24 19:45:33 +02:00
|
|
|
}
|
|
|
|
|
2010-12-04 23:15:03 +01:00
|
|
|
const StmtNode* execute(thread_db* /*tdbb*/, jrd_req* /*request*/, ExeState* /*exeState*/) const
|
2009-10-24 19:45:33 +02:00
|
|
|
{
|
|
|
|
fb_assert(false);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-03-04 02:47:49 +01:00
|
|
|
// Add savepoint pair of nodes to statement having error handlers.
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
class SavepointEncloseNode : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_SAVEPOINT_ENCLOSE>
|
2010-01-05 18:32:42 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit SavepointEncloseNode(MemoryPool& pool, StmtNode* aStmt)
|
Refactored the support for blr_handler, blr_loop, blr_exec_sql, blr_exec_into, blr_exec_stmt,
blr_start_savepoint, blr_end_savepoint, blr_store, blr_store2, blr_erase, blr_modify,
blr_modify2, blr_exec_proc, blr_exec_proc2, blr_exec_pid, blr_dcl_cursor, blr_cursor_stmt,
blr_set_generator, blr_receive, blr_stall, blr_select, blr_block, blr_error_handler,
blr_label, blr_leave, blr_continue and the source info node.
2010-11-29 03:17:04 +01:00
|
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_SAVEPOINT_ENCLOSE>(pool),
|
2010-01-05 18:32:42 +01:00
|
|
|
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;
|
2010-09-17 05:15:32 +02:00
|
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
2010-01-05 18:32:42 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
StmtNode* stmt;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-04-07 06:21:46 +02:00
|
|
|
class RowsClause : public Firebird::PermanentStorage
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit RowsClause(MemoryPool& pool)
|
|
|
|
: PermanentStorage(pool),
|
|
|
|
length(NULL),
|
|
|
|
skip(NULL)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
dsql_nod* length;
|
|
|
|
dsql_nod* skip;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-05-19 15:47:48 +02:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
#endif // DSQL_NODES_H
|