8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-31 22:43:04 +01:00
firebird-mirror/src/dsql/dsql.h

1027 lines
30 KiB
C
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: Dynamic SQL runtime support
* MODULE: dsql.h
* DESCRIPTION: General Definitions for V4 DSQL module
*
*
* The contents of this file are subject to the Interbase 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.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, 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 Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
2002-06-29 08:56:51 +02:00
*
* 2001.11.26 Claudio Valderrama: include udf_arguments and udf_flags
* in the udf struct, so we can load the arguments and check for
* collisions between dropping and redefining the udf concurrently.
* This closes SF Bug# 409769.
* 2002.10.29 Nickolay Samofatov: Added support for savepoints
2008-12-05 01:56:15 +01:00
* 2004.01.16 Vlad Horsun: added support for default parameters and
* EXECUTE BLOCK statement
* Adriano dos Santos Fernandes
2001-05-23 15:26:42 +02:00
*/
#ifndef DSQL_DSQL_H
#define DSQL_DSQL_H
2001-05-23 15:26:42 +02:00
#include "../jrd/common.h"
2009-02-01 23:10:12 +01:00
#include "../jrd/RuntimeStatistics.h"
2008-02-28 14:48:16 +01:00
#include "../jrd/val.h" // Get rid of duplicated FUN_T enum.
#include "../jrd/Database.h"
#include "../common/classes/array.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/MetaName.h"
#include "../common/classes/stack.h"
2009-02-01 23:10:12 +01:00
#include "../common/classes/auto.h"
2001-05-23 15:26:42 +02:00
#ifdef DEV_BUILD
// This macro enables DSQL tracing code
#define DSQL_DEBUG
#endif
#ifdef DSQL_DEBUG
DEFINE_TRACE_ROUTINE(dsql_trace);
#endif
2001-12-24 03:51:06 +01:00
// generic block used as header to all allocated structures
2001-05-23 15:26:42 +02:00
#include "../include/fb_blk.h"
#include "../dsql/sym.h"
// Context aliases used in triggers
const char* const OLD_CONTEXT = "OLD";
const char* const NEW_CONTEXT = "NEW";
const char* const TEMP_CONTEXT = "TEMP";
2008-02-28 14:48:16 +01:00
namespace Jrd
{
class Database;
class Attachment;
class jrd_tra;
class jrd_req;
class blb;
struct bid;
class BlockNode;
2009-12-19 16:00:18 +01:00
class dsql_blb;
2008-02-28 14:48:16 +01:00
class dsql_ctx;
2009-12-19 16:00:18 +01:00
class dsql_msg;
class dsql_par;
2008-02-28 14:48:16 +01:00
class dsql_str;
class dsql_map;
2008-02-28 14:48:16 +01:00
class dsql_nod;
class dsql_intlsym;
typedef Firebird::Stack<dsql_ctx*> DsqlContextStack;
typedef Firebird::Stack<const dsql_str*> DsqlStrStack;
2008-02-28 14:48:16 +01:00
typedef Firebird::Stack<dsql_nod*> DsqlNodStack;
2008-11-05 02:08:20 +01:00
}
2008-02-28 14:48:16 +01:00
2008-11-05 02:08:20 +01:00
namespace Firebird
{
class MetaName;
}
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
//======================================================================
// remaining node definitions for local processing
//
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
/// Include definition of descriptor
2001-05-23 15:26:42 +02:00
#include "../jrd/dsc.h"
2008-02-28 14:48:16 +01:00
namespace Jrd {
//! generic data type used to store strings
class dsql_str : public pool_alloc_rpt<char, dsql_type_str>
{
public:
enum Type
{
TYPE_SIMPLE = 0, // '...'
TYPE_ALTERNATE, // q'{...}'
TYPE_HEXA, // x'...'
TYPE_DELIMITED // "..."
};
2008-02-28 14:48:16 +01:00
public:
2009-07-05 04:15:43 +02:00
const char* str_charset; // ASCIIZ Character set identifier for string
Type type;
ULONG str_length; // length of string in BYTES
char str_data[2]; // one for ALLOC and one for the NULL
2001-05-23 15:26:42 +02:00
};
2001-12-24 03:51:06 +01:00
// blocks used to cache metadata
2001-05-23 15:26:42 +02:00
// Database Block
2004-02-02 12:02:12 +01:00
class dsql_dbb : public pool_alloc<dsql_type_dbb>
2001-12-24 03:51:06 +01:00
{
public:
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
Firebird::MetaName, class dsql_rel*> > > dbb_relations; // known relations in database
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
Firebird::QualifiedName, class dsql_prc*> > > dbb_procedures; // known procedures in database
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
Firebird::QualifiedName, class dsql_udf*> > > dbb_functions; // known functions in database
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
Firebird::MetaName, class dsql_intlsym*> > > dbb_charsets; // known charsets in database
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
Firebird::MetaName, class dsql_intlsym*> > > dbb_collations; // known collations in database
Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<
SSHORT, dsql_intlsym*> > > dbb_charsets_by_id; // charsets sorted by charset_id
2009-07-05 04:15:43 +02:00
MemoryPool& dbb_pool; // The current pool for the dbb
2008-02-28 14:48:16 +01:00
Database* dbb_database;
Attachment* dbb_attachment;
2004-02-02 12:02:12 +01:00
dsql_str* dbb_dfl_charset;
2008-02-28 14:48:16 +01:00
bool dbb_no_charset;
bool dbb_read_only;
2001-12-24 03:51:06 +01:00
USHORT dbb_db_SQL_dialect;
USHORT dbb_ods_version; // major ODS version number
USHORT dbb_minor_version; // minor ODS version number
explicit dsql_dbb(MemoryPool& p)
: dbb_relations(p),
dbb_procedures(p),
dbb_functions(p),
dbb_charsets(p),
dbb_collations(p),
dbb_charsets_by_id(p),
dbb_pool(p)
2008-02-28 14:48:16 +01:00
{}
2008-02-01 21:18:11 +01:00
2008-02-28 14:48:16 +01:00
~dsql_dbb();
MemoryPool* createPool()
2008-02-01 21:18:11 +01:00
{
2008-02-28 14:48:16 +01:00
return dbb_database->createPool();
2008-02-01 21:18:11 +01:00
}
2008-02-28 14:48:16 +01:00
void deletePool(MemoryPool* pool)
2008-02-01 21:18:11 +01:00
{
2008-02-28 14:48:16 +01:00
dbb_database->deletePool(pool);
2008-02-01 21:18:11 +01:00
}
2003-10-01 20:11:23 +02:00
};
2001-05-23 15:26:42 +02:00
//! Relation block
class dsql_rel : public pool_alloc<dsql_type_rel>
2001-05-23 15:26:42 +02:00
{
2001-12-24 03:51:06 +01:00
public:
2008-02-21 14:11:32 +01:00
explicit dsql_rel(MemoryPool& p)
2008-01-16 07:52:43 +01:00
: rel_name(p),
rel_owner(p)
{
}
2009-07-05 04:15:43 +02:00
class dsql_fld* rel_fields; // Field block
//dsql_rel* rel_base_relation; // base relation for an updatable view
Firebird::MetaName rel_name; // Name of relation
Firebird::MetaName rel_owner; // Owner of relation
USHORT rel_id; // Relation id
2001-12-24 03:51:06 +01:00
USHORT rel_dbkey_length;
USHORT rel_flags;
};
// rel_flags bits
2003-10-01 20:11:23 +02:00
enum rel_flags_vals {
2009-07-05 04:15:43 +02:00
REL_new_relation = 1, // relation exists in sys tables, not committed yet
REL_dropped = 2, // relation has been dropped
REL_view = 4, // relation is a view
REL_external = 8, // relation is an external table
REL_creating = 16 // we are creating the bare relation in memory
2003-10-01 20:11:23 +02:00
};
2001-12-24 03:51:06 +01:00
2008-01-16 07:52:43 +01:00
class dsql_fld : public pool_alloc<dsql_type_fld>
2001-05-23 15:26:42 +02:00
{
2001-12-24 03:51:06 +01:00
public:
2008-02-21 14:11:32 +01:00
explicit dsql_fld(MemoryPool& p)
2008-01-16 07:52:43 +01:00
: fld_type_of_name(p),
fld_name(p),
fld_source(p)
{
}
2009-07-05 04:15:43 +02:00
dsql_fld* fld_next; // Next field in relation
dsql_rel* fld_relation; // Parent relation
class dsql_prc* fld_procedure; // Parent procedure
dsql_nod* fld_ranges; // ranges for multi dimension array
dsql_nod* fld_character_set; // null means not specified
dsql_nod* fld_sub_type_name; // Subtype name for later resolution
2001-12-24 03:51:06 +01:00
USHORT fld_flags;
2009-07-05 04:15:43 +02:00
USHORT fld_id; // Field in in database
USHORT fld_dtype; // Data type of field
FLD_LENGTH fld_length; // Length of field
USHORT fld_element_dtype; // Data type of array element
USHORT fld_element_length; // Length of array element
SSHORT fld_scale; // Scale factor of field
SSHORT fld_sub_type; // Subtype for text & blob fields
USHORT fld_precision; // Precision for exact numeric types
USHORT fld_character_length; // length of field in characters
USHORT fld_seg_length; // Segment length for blobs
SSHORT fld_dimensions; // Non-zero means array
SSHORT fld_character_set_id; // ID of field's character set
SSHORT fld_collation_id; // ID of field's collation
SSHORT fld_ttype; // ID of field's language_driver
Firebird::string fld_type_of_name; // TYPE OF
dsql_str* fld_type_of_table; // TYPE OF table name
bool fld_explicit_collation; // COLLATE was explicit specified
bool fld_not_nullable; // NOT NULL was explicit specified
bool fld_full_domain; // Domain name without TYPE OF prefix
Firebird::string fld_name;
2008-01-16 07:52:43 +01:00
Firebird::MetaName fld_source;
2001-12-24 03:51:06 +01:00
};
// values used in fld_flags
2001-05-23 15:26:42 +02:00
2003-10-01 20:11:23 +02:00
enum fld_flags_vals {
FLD_computed = 1,
2009-07-05 04:15:43 +02:00
FLD_national = 2, // field uses NATIONAL character set
FLD_nullable = 4,
FLD_system = 8
2003-10-01 20:11:23 +02:00
};
2001-05-23 15:26:42 +02:00
//! database/log/cache file block
2003-11-10 10:16:38 +01:00
class dsql_fil : public pool_alloc<dsql_type_fil>
2001-12-24 03:51:06 +01:00
{
public:
2009-07-05 04:15:43 +02:00
SLONG fil_length; // File length in pages
SLONG fil_start; // Starting page
dsql_str* fil_name; // File name
//dsql_fil* fil_next; // next file
//SSHORT fil_shadow_number; // shadow number if part of shadow
//SSHORT fil_manual; // flag to indicate manual shadow
//SSHORT fil_partitions; // number of log file partitions
2008-05-10 05:44:57 +02:00
//USHORT fil_flags;
2001-12-24 03:51:06 +01:00
};
//! Stored Procedure block
2008-01-16 07:52:43 +01:00
class dsql_prc : public pool_alloc<dsql_type_prc>
2001-12-24 03:51:06 +01:00
{
public:
2008-02-21 14:11:32 +01:00
explicit dsql_prc(MemoryPool& p)
2008-01-16 07:52:43 +01:00
: prc_name(p),
prc_owner(p)
{
}
2009-07-05 04:15:43 +02:00
dsql_fld* prc_inputs; // Input parameters
dsql_fld* prc_outputs; // Output parameters
Firebird::QualifiedName prc_name; // Name of procedure
2009-07-05 04:15:43 +02:00
Firebird::MetaName prc_owner; // Owner of procedure
2001-12-24 03:51:06 +01:00
SSHORT prc_in_count;
2009-07-05 04:15:43 +02:00
SSHORT prc_def_count; // number of inputs with default values
2001-12-24 03:51:06 +01:00
SSHORT prc_out_count;
2009-07-05 04:15:43 +02:00
USHORT prc_id; // Procedure id
2001-12-24 03:51:06 +01:00
USHORT prc_flags;
bool prc_private; // Packaged private procedure
2001-12-24 03:51:06 +01:00
};
// prc_flags bits
2003-10-01 20:11:23 +02:00
enum prc_flags_vals {
2009-07-05 04:15:43 +02:00
PRC_new_procedure = 1, // procedure is newly defined, not committed yet
PRC_dropped = 2 // procedure has been dropped
2003-10-01 20:11:23 +02:00
};
2001-12-24 03:51:06 +01:00
//! User defined function block
2008-01-16 07:52:43 +01:00
class dsql_udf : public pool_alloc<dsql_type_udf>
2001-12-24 03:51:06 +01:00
{
public:
2008-02-21 14:11:32 +01:00
explicit dsql_udf(MemoryPool& p)
2008-02-28 14:48:16 +01:00
: udf_name(p), udf_arguments(p)
2008-01-16 07:52:43 +01:00
{
}
2001-12-24 03:51:06 +01:00
USHORT udf_dtype;
SSHORT udf_scale;
SSHORT udf_sub_type;
USHORT udf_length;
SSHORT udf_character_set_id;
2008-05-10 05:44:57 +02:00
//USHORT udf_character_length;
2002-06-29 08:56:51 +02:00
USHORT udf_flags;
Firebird::QualifiedName udf_name;
Firebird::Array<dsc> udf_arguments;
bool udf_private; // Packaged private function
2001-12-24 03:51:06 +01:00
};
// udf_flags bits
2002-06-29 08:56:51 +02:00
2003-10-01 20:11:23 +02:00
enum udf_flags_vals {
2009-07-05 04:15:43 +02:00
UDF_new_udf = 1, // udf is newly declared, not committed yet
UDF_dropped = 2 // udf has been dropped
2003-10-01 20:11:23 +02:00
};
2002-06-29 08:56:51 +02:00
2001-12-24 03:51:06 +01:00
// Variables - input, output & local
//! Variable block
2004-02-02 12:02:12 +01:00
class dsql_var : public pool_alloc_rpt<SCHAR, dsql_type_var>
2001-12-24 03:51:06 +01:00
{
public:
2009-07-05 04:15:43 +02:00
dsql_fld* var_field; // Field on which variable is based
int var_type; // Input, output or local var.
2009-07-05 04:15:43 +02:00
USHORT var_msg_number; // Message number containing variable
USHORT var_msg_item; // Item number in message
USHORT var_variable_number; // Local variable number
2001-12-24 03:51:06 +01:00
TEXT var_name[2];
};
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
// Symbolic names for international text types
// (either collation or character set name)
2001-05-23 15:26:42 +02:00
//! International symbol
class dsql_intlsym : public pool_alloc<dsql_type_intlsym>
2001-12-24 03:51:06 +01:00
{
public:
explicit dsql_intlsym(MemoryPool& p)
: intlsym_name(p)
{
}
Firebird::MetaName intlsym_name;
2009-07-05 04:15:43 +02:00
USHORT intlsym_type; // what type of name
2001-12-24 03:51:06 +01:00
USHORT intlsym_flags;
2009-07-05 04:15:43 +02:00
SSHORT intlsym_ttype; // id of implementation
2001-12-24 03:51:06 +01:00
SSHORT intlsym_charset_id;
SSHORT intlsym_collate_id;
USHORT intlsym_bytes_per_char;
};
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
// values used in intlsym_flags
2001-05-23 15:26:42 +02:00
enum intlsym_flags_vals {
2009-07-05 04:15:43 +02:00
INTLSYM_dropped = 1 // intlsym has been dropped
};
2001-05-23 15:26:42 +02:00
// Compiled statement - shared by multiple requests.
class DsqlCompiledStatement : public Firebird::PermanentStorage
{
public:
enum Type // statement type
{
TYPE_SELECT, TYPE_SELECT_UPD, TYPE_INSERT, TYPE_DELETE, TYPE_UPDATE, TYPE_UPDATE_CURSOR,
TYPE_DELETE_CURSOR, TYPE_COMMIT, TYPE_ROLLBACK, TYPE_CREATE_DB, TYPE_DDL, TYPE_START_TRANS,
TYPE_GET_SEGMENT, TYPE_PUT_SEGMENT, TYPE_EXEC_PROCEDURE, TYPE_COMMIT_RETAIN,
TYPE_ROLLBACK_RETAIN, TYPE_SET_GENERATOR, TYPE_SAVEPOINT, TYPE_EXEC_BLOCK, TYPE_SELECT_BLOCK
};
// Statement flags.
static const unsigned FLAG_ORPHAN = 0x01;
static const unsigned FLAG_NO_BATCH = 0x02;
static const unsigned FLAG_BLR_VERSION4 = 0x04;
static const unsigned FLAG_BLR_VERSION5 = 0x08;
static const unsigned FLAG_SELECTABLE = 0x10;
public:
2009-12-24 11:42:32 +01:00
explicit DsqlCompiledStatement(MemoryPool& p)
: PermanentStorage(p),
type(TYPE_SELECT),
baseOffset(0),
flags(0),
blrData(p),
debugData(p),
blockNode(NULL),
ddlNode(NULL),
blob(NULL),
sendMsg(NULL),
receiveMsg(NULL),
eof(NULL),
dbKey(NULL),
recVersion(NULL),
parentRecVersion(NULL),
parentDbKey(NULL),
parentRequest(NULL)
{
}
public:
MemoryPool& getPool() { return PermanentStorage::getPool(); }
Type getType() const { return type; }
void setType(Type value) { type = value; }
ULONG getBaseOffset() const { return baseOffset; }
void setBaseOffset(ULONG value) { baseOffset = value; }
ULONG getFlags() const { return flags; }
void setFlags(ULONG value) { flags = value; }
2009-12-24 13:56:31 +01:00
void addFlags(ULONG value) { flags |= value; }
Firebird::RefStrPtr& getSqlText() { return sqlText; }
const Firebird::RefStrPtr& getSqlText() const { return sqlText; }
void setSqlText(Firebird::RefString* value) { sqlText = value; }
Firebird::HalfStaticArray<UCHAR, 1024>& getBlrData() { return blrData; }
const Firebird::HalfStaticArray<UCHAR, 1024>& getBlrData() const { return blrData; }
Firebird::HalfStaticArray<UCHAR, 128>& getDebugData() { return debugData; }
const Firebird::HalfStaticArray<UCHAR, 128>& getDebugData() const { return debugData; }
BlockNode* getBlockNode() { return blockNode; }
const BlockNode* getBlockNode() const { return blockNode; }
void setBlockNode(BlockNode* value) { blockNode = value; }
dsql_nod* getDdlNode() { return ddlNode; }
const dsql_nod* getDdlNode() const { return ddlNode; }
void setDdlNode(dsql_nod* value) { ddlNode = value; }
dsql_blb* getBlob() { return blob; }
const dsql_blb* getBlob() const { return blob; }
void setBlob(dsql_blb* value) { blob = value; }
dsql_msg* getSendMsg() { return sendMsg; }
const dsql_msg* getSendMsg() const { return sendMsg; }
void setSendMsg(dsql_msg* value) { sendMsg = value; }
dsql_msg* getReceiveMsg() { return receiveMsg; }
const dsql_msg* getReceiveMsg() const { return receiveMsg; }
void setReceiveMsg(dsql_msg* value) { receiveMsg = value; }
dsql_par* getEof() { return eof; }
const dsql_par* getEof() const { return eof; }
void setEof(dsql_par* value) { eof = value; }
dsql_par* getDbKey() { return dbKey; }
const dsql_par* getDbKey() const { return dbKey; }
void setDbKey(dsql_par* value) { dbKey = value; }
dsql_par* getRecVersion() { return recVersion; }
const dsql_par* getRecVersion() const { return recVersion; }
void setRecVersion(dsql_par* value) { recVersion = value; }
dsql_par* getParentRecVersion() { return parentRecVersion; }
const dsql_par* getParentRecVersion() const { return parentRecVersion; }
void setParentRecVersion(dsql_par* value) { parentRecVersion = value; }
dsql_par* getParentDbKey() { return parentDbKey; }
const dsql_par* getParentDbKey() const { return parentDbKey; }
void setParentDbKey(dsql_par* value) { parentDbKey = value; }
dsql_req* getParentRequest() const { return parentRequest; }
void setParentRequest(dsql_req* value) { parentRequest = value; }
public:
void append_uchar(UCHAR byte)
{
blrData.add(byte);
}
void append_ushort(USHORT val)
{
append_uchar(val);
append_uchar(val >> 8);
}
void append_ulong(ULONG val)
{
append_ushort(val);
append_ushort(val >> 16);
}
void append_cstring(UCHAR verb, const char* string);
void append_meta_string(const char* string);
void append_raw_string(const char* string, USHORT len);
void append_raw_string(const UCHAR* string, USHORT len);
void append_string(UCHAR verb, const char* string, USHORT len);
void append_string(UCHAR verb, const Firebird::MetaName& name);
void append_string(UCHAR verb, const Firebird::string& name);
void append_number(UCHAR verb, SSHORT number);
void begin_blr(UCHAR verb);
void end_blr();
void append_uchars(UCHAR byte, int count);
void append_ushort_with_length(USHORT val);
void append_ulong_with_length(ULONG val);
void append_file_length(ULONG length);
void append_file_start(ULONG start);
void generate_unnamed_trigger_beginning(bool on_update_trigger, const char* prim_rel_name,
const dsql_nod* prim_columns, const char* for_rel_name, const dsql_nod* for_columns);
2009-12-24 11:42:32 +01:00
void beginDebug();
void endDebug();
void put_debug_src_info(USHORT, USHORT);
void put_debug_variable(USHORT, const TEXT*);
void put_debug_argument(UCHAR, USHORT, const TEXT*);
void append_debug_info();
private:
Type type; // Type of statement
ULONG baseOffset; // place to go back and stuff in blr length
ULONG flags; // generic flag
Firebird::RefStrPtr sqlText;
Firebird::HalfStaticArray<UCHAR, 1024> blrData;
Firebird::HalfStaticArray<UCHAR, 128> debugData;
BlockNode* blockNode; // Defining block
dsql_nod* ddlNode; // Store metadata statement
dsql_blb* blob; // Blob info for blob statements
dsql_msg* sendMsg; // Message to be sent to start request
dsql_msg* receiveMsg; // Per record message to be received
dsql_par* eof; // End of file parameter
dsql_par* dbKey; // Database key for current of
dsql_par* recVersion; // Record Version for current of
dsql_par* parentRecVersion; // parent record version
dsql_par* parentDbKey; // Parent database key for current of
dsql_req* parentRequest; // Source request, if cursor update
};
class dsql_req : public pool_alloc<dsql_type_req>
2001-12-24 03:51:06 +01:00
{
public:
static const unsigned FLAG_OPENED_CURSOR = 0x01;
2009-12-21 15:56:12 +01:00
static const unsigned FLAG_EMBEDDED = 0x02;
2001-12-24 03:51:06 +01:00
public:
explicit dsql_req(DsqlCompiledStatement* aStatement)
: req_pool(aStatement->getPool()),
statement(aStatement),
cursors(req_pool),
req_msg_buffers(req_pool),
req_user_descs(req_pool)
{
}
public:
2009-12-21 15:56:12 +01:00
MemoryPool& getPool()
{
2009-12-21 15:56:12 +01:00
return req_pool;
}
2009-12-21 15:56:12 +01:00
jrd_tra* getTransaction()
{
2009-12-21 15:56:12 +01:00
return req_transaction;
}
const DsqlCompiledStatement* getStatement() const
{
return statement;
}
2009-12-21 15:56:12 +01:00
private:
MemoryPool& req_pool;
2009-12-21 15:56:12 +01:00
const DsqlCompiledStatement* statement;
public:
Firebird::Array<DsqlCompiledStatement*> cursors; // Cursor update statements
2009-12-19 16:39:23 +01:00
2009-07-05 04:15:43 +02:00
dsql_dbb* req_dbb; // DSQL attachment
jrd_tra* req_transaction; // JRD transaction
2009-12-19 16:39:23 +01:00
jrd_req* req_request; // JRD request
unsigned req_flags; // flags
Firebird::Array<UCHAR*> req_msg_buffers;
dsql_sym* req_cursor; // Cursor symbol, if any
blb* req_blb; // JRD blob
2009-12-19 23:52:17 +01:00
Firebird::GenericMap<Firebird::NonPooled<const dsql_par*, dsc> > req_user_descs; // SQLDA data type
2009-12-19 16:39:23 +01:00
ULONG req_inserts; // records processed in request
ULONG req_deletes;
ULONG req_updates;
ULONG req_selects;
2009-07-05 04:15:43 +02:00
Firebird::AutoPtr<Jrd::RuntimeStatistics> req_fetch_baseline; // State of request performance counters when we reported it last time
SINT64 req_fetch_elapsed; // Number of clock ticks spent while fetching rows for this request since we reported it last time
SINT64 req_fetch_rowcount; // Total number of rows returned by this request
bool req_traced; // request is traced via TraceAPI
2009-02-01 23:10:12 +01:00
protected:
// Request should never be destroyed using delete.
// It dies together with it's pool in release_request().
~dsql_req();
2008-12-05 01:56:15 +01:00
// To avoid posix warning about missing public destructor declare
// MemoryPool as friend class. In fact IT releases request memory!
2008-07-04 12:35:33 +02:00
friend class Firebird::MemoryPool;
};
// DSQL Compiler scratch block - may be discarded after compilation in the future.
class DsqlCompilerScratch : public Firebird::PermanentStorage
{
public:
2009-12-22 01:08:49 +01:00
static const unsigned FLAG_IN_AUTO_TRANS_BLOCK = 0x001;
static const unsigned FLAG_RETURNING_INTO = 0x002;
static const unsigned FLAG_METADATA_SAVED = 0x004;
static const unsigned FLAG_PROCEDURE = 0x008;
static const unsigned FLAG_TRIGGER = 0x010;
static const unsigned FLAG_BLOCK = 0x020;
static const unsigned FLAG_RECURSIVE_CTE = 0x040;
static const unsigned FLAG_UPDATE_OR_INSERT = 0x080;
static const unsigned FLAG_FUNCTION = 0x100;
public:
explicit DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction,
DsqlCompiledStatement* aStatement)
: PermanentStorage(p),
dbb(aDbb),
transaction(aTransaction),
statement(aStatement),
flags(0),
ports(p),
relation(NULL),
procedure(NULL),
mainContext(p),
context(&mainContext),
unionContext(p),
derivedContext(p),
outerAggContext(NULL),
contextNumber(0),
derivedContextNumber(0),
scopeLevel(0),
loopLevel(0),
labels(p),
cursorNumber(0),
cursors(p),
inSelectList(0),
inWhereClause(0),
inGroupByClause(0),
inHavingClause(0),
inOrderByClause(0),
errorHandlers(0),
clientDialect(0),
inOuterJoin(0),
aliasRelationPrefix(NULL),
hiddenVars(p),
hiddenVarsNumber(0),
package(p),
currCtes(p),
recursiveCtx(0),
recursiveCtxId(0),
processingWindow(false),
ctes(p),
cteAliases(p),
currCteAlias(NULL),
psql(false)
{
}
protected:
// DsqlCompilerScratch should never be destroyed using delete.
// It dies together with it's pool in release_request().
~DsqlCompilerScratch();
public:
MemoryPool& getPool()
2008-08-27 13:06:11 +02:00
{
return PermanentStorage::getPool();
2008-08-27 13:06:11 +02:00
}
dsql_dbb* getAttachment()
2008-08-27 13:06:11 +02:00
{
return dbb;
2008-08-27 13:06:11 +02:00
}
jrd_tra* getTransaction()
2008-08-27 13:06:11 +02:00
{
return transaction;
2008-08-27 13:06:11 +02:00
}
DsqlCompiledStatement* getStatement()
{
return statement;
}
DsqlCompiledStatement* getStatement() const
{
return statement;
}
void addCTEs(dsql_nod* list);
dsql_nod* findCTE(const dsql_str* name);
void clearCTEs();
2008-03-18 14:02:21 +01:00
void checkUnusedCTEs() const;
2008-12-05 01:56:15 +01:00
// hvlad: each member of recursive CTE can refer to CTE itself (only once) via
// CTE name or via alias. We need to substitute this aliases when processing CTE
// member to resolve field names. Therefore we store all aliases in order of
2009-06-07 11:49:58 +02:00
// occurrence and later use it in backward order (since our parser is right-to-left).
2008-12-05 01:56:15 +01:00
// We also need to repeat this process if main select expression contains union with
// recursive CTE
2008-12-05 01:56:15 +01:00
void addCTEAlias(const dsql_str* alias)
{
cteAliases.add(alias);
}
const dsql_str* getNextCTEAlias()
{
return *(--currCteAlias);
}
void resetCTEAlias()
{
currCteAlias = cteAliases.end();
}
2008-05-21 14:41:58 +02:00
bool isPsql() const
{
return psql;
}
void setPsql(bool value)
{
psql = value;
}
private:
dsql_dbb* dbb; // DSQL attachment
jrd_tra* transaction; // Transaction
DsqlCompiledStatement* statement; // Compiled statement
public:
unsigned flags; // flags
Firebird::Array<dsql_msg*> ports; // Port messages
dsql_rel* relation; // relation created by this request (for DDL)
dsql_prc* procedure; // procedure created by this request (for DDL)
DsqlContextStack mainContext;
DsqlContextStack* context;
DsqlContextStack unionContext; // Save contexts for views of unions
DsqlContextStack derivedContext; // Save contexts for views of derived tables
dsql_ctx* outerAggContext; // agg context for outer ref
USHORT contextNumber; // Next available context number
USHORT derivedContextNumber; // Next available context number for derived tables
USHORT scopeLevel; // Scope level for parsing aliases in subqueries
USHORT loopLevel; // Loop level
DsqlStrStack labels; // Loop labels
USHORT cursorNumber; // Cursor number
DsqlNodStack cursors; // Cursors
USHORT inSelectList; // now processing "select list"
USHORT inWhereClause; // processing "where clause"
USHORT inGroupByClause; // processing "group by clause"
USHORT inHavingClause; // processing "having clause"
USHORT inOrderByClause; // processing "order by clause"
USHORT errorHandlers; // count of active error handlers
USHORT clientDialect; // dialect passed into the API call
USHORT inOuterJoin; // processing inside outer-join part
dsql_str* aliasRelationPrefix; // prefix for every relation-alias.
DsqlNodStack hiddenVars; // hidden variables
USHORT hiddenVarsNumber; // next hidden variable number
Firebird::MetaName package; // package being defined
DsqlNodStack currCtes; // current processing CTE's
class dsql_ctx* recursiveCtx; // context of recursive CTE
USHORT recursiveCtxId; // id of recursive union stream context
bool processingWindow; // processing window functions
private:
Firebird::HalfStaticArray<dsql_nod*, 4> ctes; // common table expressions
Firebird::HalfStaticArray<const dsql_str*, 4> cteAliases; // CTE aliases in recursive members
const dsql_str* const* currCteAlias;
bool psql;
2001-12-24 03:51:06 +01:00
};
class PsqlChanger
{
public:
PsqlChanger(DsqlCompilerScratch* aStatement, bool value)
2009-01-06 18:46:08 +01:00
: statement(aStatement),
oldValue(statement->isPsql())
{
statement->setPsql(value);
}
~PsqlChanger()
{
statement->setPsql(oldValue);
}
private:
// copying is prohibited
PsqlChanger(const PsqlChanger&);
PsqlChanger& operator =(const PsqlChanger&);
DsqlCompilerScratch* statement;
2009-01-05 09:48:32 +01:00
const bool oldValue;
};
// Blob
2003-11-10 10:16:38 +01:00
class dsql_blb : public pool_alloc<dsql_type_blb>
2001-12-24 03:51:06 +01:00
{
public:
2009-07-05 04:15:43 +02:00
dsql_par* blb_blob_id; // Parameter to hold blob id
dsql_par* blb_segment; // Parameter for segments
2008-02-28 14:48:16 +01:00
dsql_nod* blb_from;
dsql_nod* blb_to;
2009-07-05 04:15:43 +02:00
dsql_msg* blb_open_in_msg; // Input message to open cursor
dsql_msg* blb_open_out_msg; // Output message from open cursor
dsql_msg* blb_segment_msg; // Segment message
2001-12-24 03:51:06 +01:00
};
2001-05-23 15:26:42 +02:00
//! Implicit (NATURAL and USING) joins
class ImplicitJoin : public pool_alloc<dsql_type_imp_join>
{
public:
dsql_nod* value;
dsql_ctx* visibleInContext;
};
2001-05-23 15:26:42 +02:00
struct PartitionMap
{
PartitionMap(dsql_nod* aPartition, dsql_nod* aOrder)
: partition(aPartition),
partitionRemapped(NULL),
order(aOrder),
map(NULL),
context(0)
{
}
dsql_nod* partition;
dsql_nod* partitionRemapped;
dsql_nod* order;
dsql_map* map;
USHORT context;
};
//! Context block used to create an instance of a relation reference
class dsql_ctx : public pool_alloc<dsql_type_ctx>
2001-12-24 03:51:06 +01:00
{
public:
explicit dsql_ctx(MemoryPool& p)
: ctx_main_derived_contexts(p),
ctx_childs_derived_table(p),
ctx_imp_join(p),
ctx_win_maps(p)
{
}
2009-07-05 04:15:43 +02:00
dsql_rel* ctx_relation; // Relation for context
dsql_prc* ctx_procedure; // Procedure for context
dsql_nod* ctx_proc_inputs; // Procedure input parameters
dsql_map* ctx_map; // Maps for aggregates and unions
2009-07-05 04:15:43 +02:00
dsql_nod* ctx_rse; // Sub-rse for aggregates
dsql_ctx* ctx_parent; // Parent context for aggregates
const TEXT* ctx_alias; // Context alias (can include concatenated derived table alias)
const TEXT* ctx_internal_alias; // Alias as specified in query
USHORT ctx_context; // Context id
USHORT ctx_recursive; // Secondary context id for recursive UNION (nobody referred to this context)
USHORT ctx_scope_level; // Subquery level within this request
USHORT ctx_flags; // Various flag values
USHORT ctx_in_outer_join; // inOuterJoin when context was created
DsqlContextStack ctx_main_derived_contexts; // contexts used for blr_derived_expr
2009-07-05 04:15:43 +02:00
DsqlContextStack ctx_childs_derived_table; // Childs derived table context
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
Firebird::MetaName, ImplicitJoin*> > > ctx_imp_join; // Map of USING fieldname to ImplicitJoin
Firebird::Array<PartitionMap*> ctx_win_maps; // Maps for window functions
dsql_ctx& operator=(dsql_ctx& v)
{
ctx_relation = v.ctx_relation;
ctx_procedure = v.ctx_procedure;
ctx_proc_inputs = v.ctx_proc_inputs;
ctx_map = v.ctx_map;
ctx_rse = v.ctx_rse;
ctx_parent = v.ctx_parent;
ctx_alias = v.ctx_alias;
ctx_context = v.ctx_context;
ctx_recursive = v.ctx_recursive;
ctx_scope_level = v.ctx_scope_level;
ctx_flags = v.ctx_flags;
ctx_in_outer_join = v.ctx_in_outer_join;
ctx_main_derived_contexts.assign(v.ctx_main_derived_contexts);
ctx_childs_derived_table.assign(v.ctx_childs_derived_table);
ctx_imp_join.assign(v.ctx_imp_join);
ctx_win_maps.assign(v.ctx_win_maps);
return *this;
}
2008-01-16 07:52:43 +01:00
bool getImplicitJoinField(const Firebird::MetaName& name, dsql_nod*& node);
PartitionMap* getPartitionMap(DsqlCompilerScratch* dsqlScratch, dsql_nod* partitionNode, dsql_nod* orderNode);
2001-12-24 03:51:06 +01:00
};
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
// Flag values for ctx_flags
2001-05-23 15:26:42 +02:00
const USHORT CTX_outer_join = 0x01; // reference is part of an outer join
const USHORT CTX_system = 0x02; // Context generated by system (NEW/OLD in triggers, check-constraint, RETURNING)
const USHORT CTX_null = 0x04; // Fields of the context should be resolved to NULL constant
const USHORT CTX_returning = 0x08; // Context generated by RETURNING
2007-07-22 11:05:05 +02:00
const USHORT CTX_recursive = 0x10; // Context has secondary number (ctx_recursive) generated for recursive UNION
2001-05-23 15:26:42 +02:00
//! Aggregate/union map block to map virtual fields to their base
//! TMN: NOTE! This datatype should definitely be renamed!
class dsql_map : public pool_alloc<dsql_type_map>
2001-12-24 03:51:06 +01:00
{
public:
dsql_map* map_next; // Next map in item
dsql_nod* map_node; // Value for map item
USHORT map_position; // Position in map
PartitionMap* map_partition; // Partition
2001-12-24 03:51:06 +01:00
};
2001-05-23 15:26:42 +02:00
// Message block used in communicating with a running request
class dsql_msg : public Firebird::PermanentStorage
2001-12-24 03:51:06 +01:00
{
public:
2009-12-20 10:19:15 +01:00
explicit dsql_msg(MemoryPool& p)
: PermanentStorage(p),
msg_parameters(p),
msg_number(0),
msg_buffer_number(0),
msg_length(0),
msg_parameter(0),
msg_index(0)
{
}
Firebird::Array<dsql_par*> msg_parameters; // Parameter list
2009-07-05 04:15:43 +02:00
USHORT msg_number; // Message number
USHORT msg_buffer_number; // Message buffer number (used instead of msg_number for blob msgs)
2009-07-05 04:15:43 +02:00
USHORT msg_length; // Message length
USHORT msg_parameter; // Next parameter number
USHORT msg_index; // Next index into SQLDA
2001-12-24 03:51:06 +01:00
};
2002-11-19 13:35:28 +01:00
// Parameter block used to describe a parameter of a message
class dsql_par : public Firebird::PermanentStorage
2001-12-24 03:51:06 +01:00
{
public:
explicit dsql_par(MemoryPool& p)
: PermanentStorage(p),
par_message(NULL),
par_null(NULL),
par_node(NULL),
par_dbkey_relname(p),
par_rec_version_relname(p),
par_name(NULL),
par_rel_name(NULL),
par_owner_name(NULL),
par_rel_alias(NULL),
par_alias(NULL),
par_parameter(0),
par_index(0)
{
par_desc.clear();
}
2009-07-05 04:15:43 +02:00
dsql_msg* par_message; // Parent message
dsql_par* par_null; // Null parameter, if used
dsql_nod* par_node; // Associated value node, if any
Firebird::MetaName par_dbkey_relname; // Context of internally requested dbkey
Firebird::MetaName par_rec_version_relname; // Context of internally requested rec. version
2009-07-05 04:15:43 +02:00
const TEXT* par_name; // Parameter name, if any
const TEXT* par_rel_name; // Relation name, if any
const TEXT* par_owner_name; // Owner name, if any
const TEXT* par_rel_alias; // Relation alias, if any
const TEXT* par_alias; // Alias, if any
dsc par_desc; // Field data type
2009-07-05 04:15:43 +02:00
USHORT par_parameter; // BLR parameter number
USHORT par_index; // Index into SQLDA, if appropriate
2001-12-24 03:51:06 +01:00
};
2001-05-23 15:26:42 +02:00
// CVC: Enumeration used for the COMMENT command.
enum
{
ddl_database, ddl_domain, ddl_relation, ddl_view, ddl_procedure, ddl_trigger,
ddl_udf, ddl_blob_filter, ddl_exception, ddl_generator, ddl_index, ddl_role,
ddl_charset, ddl_collation, ddl_package, ddl_schema,
//, ddl_sec_class
};
class CStrCmp
{
public:
static int greaterThan(const char* s1, const char* s2)
{
return strcmp(s1, s2) > 0;
}
};
typedef Firebird::SortedArray<const char*,
Firebird::EmptyStorage<const char*>, const char*,
Firebird::DefaultKeyValue<const char*>,
CStrCmp>
StrArray;
2008-02-29 09:45:02 +01:00
} // namespace
2008-02-28 14:48:16 +01:00
2009-12-25 20:29:58 +01:00
/*! \var unsigned DSQL_debug
\brief Debug level
0 No output
1 Display output tree in PASS1_statment
2 Display input tree in PASS1_statment
4 Display ddl BLR
8 Display BLR
16 Display PASS1_rse input tree
32 Display SQL input string
64 Display BLR in dsql/prepare
> 256 Display yacc parser output level = DSQL_level>>8
*/
2008-02-28 14:48:16 +01:00
#ifdef DSQL_DEBUG
extern unsigned DSQL_debug;
#endif
#endif // DSQL_DSQL_H