2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD Access Method
|
|
|
|
* MODULE: exe.h
|
|
|
|
* DESCRIPTION: Execution block definitions
|
|
|
|
*
|
|
|
|
* 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 15:03:13 +02:00
|
|
|
*
|
2004-03-28 11:10:30 +02:00
|
|
|
* 2001.07.28: Added rse_skip to class RecordSelExpr to support LIMIT.
|
2002-09-28 16:04:35 +02:00
|
|
|
* 2002.09.28 Dmitry Yemanov: Reworked internal_info stuff, enhanced
|
|
|
|
* exception handling in SPs/triggers,
|
|
|
|
* implemented ROWS_AFFECTED system variable
|
2002-10-29 21:20:44 +01:00
|
|
|
* 2002.10.21 Nickolay Samofatov: Added support for explicit pessimistic locks
|
|
|
|
* 2002.10.29 Nickolay Samofatov: Added support for savepoints
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
|
2003-10-03 03:53:34 +02:00
|
|
|
#ifndef JRD_EXE_H
|
|
|
|
#define JRD_EXE_H
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
#include "../jrd/jrd_blks.h"
|
2003-09-28 23:36:05 +02:00
|
|
|
#include "../common/classes/array.h"
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2004-03-07 10:48:56 +01:00
|
|
|
#include "gen/iberror.h"
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#define NODE(type, name, keyword) type,
|
|
|
|
|
2003-08-22 12:56:55 +02:00
|
|
|
typedef enum nod_t {
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/nod.h"
|
|
|
|
nod_MAX
|
|
|
|
#undef NODE
|
|
|
|
} NOD_T;
|
|
|
|
|
|
|
|
#include "../jrd/dsc.h"
|
2003-11-04 12:35:51 +01:00
|
|
|
#include "../jrd/rse.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-07 10:48:56 +01:00
|
|
|
#include "../jrd/err_proto.h"
|
|
|
|
|
2003-09-28 23:36:05 +02:00
|
|
|
// This macro enables DSQL tracing code
|
|
|
|
//#define CMP_DEBUG
|
|
|
|
|
|
|
|
#ifdef CMP_DEBUG
|
|
|
|
DEFINE_TRACE_ROUTINE(cmp_trace);
|
|
|
|
#define CMP_TRACE(args) cmp_trace args
|
|
|
|
#else
|
|
|
|
#define CMP_TRACE(args) /* nothing */
|
|
|
|
#endif
|
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
class str;
|
2004-03-28 11:10:30 +02:00
|
|
|
struct dsc;
|
2004-03-20 15:57:40 +01:00
|
|
|
|
|
|
|
namespace Jrd {
|
|
|
|
|
2004-03-11 06:04:26 +01:00
|
|
|
class jrd_rel;
|
|
|
|
class jrd_nod;
|
|
|
|
struct sort_key_def;
|
2004-03-18 06:56:06 +01:00
|
|
|
class SparseBitmap;
|
|
|
|
class vec;
|
2004-03-28 11:10:30 +02:00
|
|
|
class jrd_prc;
|
|
|
|
struct index_desc;
|
2004-04-04 10:25:40 +02:00
|
|
|
struct IndexDescAlloc;
|
2004-03-30 06:10:52 +02:00
|
|
|
class Format;
|
2004-03-11 06:04:26 +01:00
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
// NOTE: The definition of structures RecordSelExpr and lit must be defined in
|
2003-12-31 06:36:12 +01:00
|
|
|
// exactly the same way as structure jrd_nod through item nod_count.
|
|
|
|
// Now, inheritance takes care of those common data members.
|
2004-03-11 06:04:26 +01:00
|
|
|
class jrd_node_base : public pool_alloc_rpt<jrd_nod*, type_nod>
|
2003-12-27 05:37:23 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
jrd_nod* nod_parent;
|
|
|
|
SLONG nod_impure; /* Inpure offset from request block */
|
|
|
|
NOD_T nod_type; /* Type of node */
|
|
|
|
UCHAR nod_flags;
|
|
|
|
SCHAR nod_scale; /* Target scale factor */
|
|
|
|
USHORT nod_count; /* Number of arguments */
|
|
|
|
Firebird::Array<jrd_nod*> *nod_variables; /* Variables and arguments this node depends on */
|
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-12-27 05:37:23 +01:00
|
|
|
|
|
|
|
class jrd_nod : public jrd_node_base
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
|
|
|
public:
|
2003-01-16 18:47:10 +01:00
|
|
|
/* jrd_nod()
|
2001-12-24 03:51:06 +01:00
|
|
|
: nod_parent(0),
|
|
|
|
nod_impure(0),
|
|
|
|
nod_type(nod_nop),
|
|
|
|
nod_flags(0),
|
|
|
|
nod_scale(0),
|
|
|
|
nod_count(0)
|
|
|
|
{
|
|
|
|
nod_arg[0] = 0;
|
2003-01-16 18:47:10 +01:00
|
|
|
}*/
|
2002-11-21 00:18:16 +01:00
|
|
|
jrd_nod* nod_arg[1];
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#define nod_comparison 1
|
|
|
|
#define nod_id 1 /* marks a field node as a blr_fid guy */
|
|
|
|
#define nod_quad 2 /* compute in quad (default is long) */
|
|
|
|
#define nod_any_and 2 /* and node is mapping of quantified predicate */
|
|
|
|
#define nod_double 4
|
|
|
|
#define nod_date 8
|
|
|
|
#define nod_value 16 /* full value area required in impure space */
|
|
|
|
#define nod_evaluate 32 /* (Gateway only) */
|
|
|
|
#define nod_agg_dbkey 64 /* dbkey of an aggregate */
|
|
|
|
#define nod_invariant 128 /* node is recognized as being invariant */
|
|
|
|
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
/* Special RecordSelExpr node */
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
class RecordSelExpr : public jrd_node_base
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
|
|
|
public:
|
2004-03-18 06:56:06 +01:00
|
|
|
USHORT rse_count;
|
|
|
|
USHORT rse_jointype; /* inner, left, full */
|
2004-02-20 07:43:27 +01:00
|
|
|
bool rse_writelock;
|
2004-03-28 11:10:30 +02:00
|
|
|
RecordSource* rse_rsb;
|
2002-11-21 00:18:16 +01:00
|
|
|
jrd_nod* rse_first;
|
|
|
|
jrd_nod* rse_skip;
|
|
|
|
jrd_nod* rse_boolean;
|
|
|
|
jrd_nod* rse_sorted;
|
|
|
|
jrd_nod* rse_projection;
|
|
|
|
jrd_nod* rse_aggregate; /* singleton aggregate for optimizing to index */
|
|
|
|
jrd_nod* rse_plan; /* user-specified access plan */
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef SCROLLABLE_CURSORS
|
2002-11-21 00:18:16 +01:00
|
|
|
jrd_nod* rse_async_message; /* asynchronous message to send for scrolling */
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
2002-11-21 00:18:16 +01:00
|
|
|
jrd_nod* rse_relation[1];
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
|
|
|
|
#define rse_stream 1 /* flags RecordSelExpr-type node as a blr_stream type */
|
|
|
|
#define rse_singular 2 /* flags RecordSelExpr-type node as from a singleton select */
|
|
|
|
#define rse_variant 4 /* flags RecordSelExpr as variant (not invariant?) */
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-12 08:00:52 +01:00
|
|
|
// Number of nodes may fit into nod_arg of normal node to get to rse_relation
|
2004-03-28 11:10:30 +02:00
|
|
|
const size_t rse_delta = (sizeof(RecordSelExpr) - sizeof(jrd_nod)) / sizeof(jrd_nod::blk_repeat_type);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-12-21 03:34:34 +01:00
|
|
|
// Types of nulls placement for each column in sort order
|
|
|
|
#define rse_nulls_default 0
|
|
|
|
#define rse_nulls_first 1
|
|
|
|
#define rse_nulls_last 2
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Literal value */
|
|
|
|
|
2004-03-18 06:56:06 +01:00
|
|
|
class Literal : public jrd_node_base
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
dsc lit_desc;
|
2003-10-11 01:56:57 +02:00
|
|
|
SINT64 lit_data[1]; // Defined this way to prevent SIGBUS error in 64-bit ports
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-18 06:56:06 +01:00
|
|
|
#define lit_delta ((sizeof(Literal) - sizeof(jrd_nod) - sizeof(SINT64)) / sizeof(jrd_nod**))
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Aggregate Sort Block (for DISTINCT aggregates) */
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
class AggregateSort : public pool_alloc<type_asb>
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
|
|
|
public:
|
2002-11-21 00:18:16 +01:00
|
|
|
jrd_nod* nod_parent;
|
2001-12-24 03:51:06 +01:00
|
|
|
SLONG nod_impure; /* Impure offset from request block */
|
|
|
|
NOD_T nod_type; /* Type of node */
|
|
|
|
UCHAR nod_flags;
|
|
|
|
SCHAR nod_scale;
|
|
|
|
USHORT nod_count;
|
|
|
|
dsc asb_desc;
|
2004-03-11 06:04:26 +01:00
|
|
|
sort_key_def* asb_key_desc; /* for the aggregate */
|
2001-12-24 03:51:06 +01:00
|
|
|
UCHAR asb_key_data[1];
|
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
#define asb_delta ((sizeof(AggregateSort) - sizeof(jrd_nod)) / sizeof (jrd_nod**))
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Various structures in the impure area */
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
struct impure_state {
|
2001-05-23 15:26:42 +02:00
|
|
|
SSHORT sta_state;
|
2004-03-28 11:10:30 +02:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
struct impure_value {
|
|
|
|
dsc vlu_desc;
|
2002-11-24 14:47:17 +01:00
|
|
|
USHORT vlu_flags; // Computed/invariant flags
|
2004-03-18 06:56:06 +01:00
|
|
|
str* vlu_string;
|
2001-05-23 15:26:42 +02:00
|
|
|
union {
|
|
|
|
SSHORT vlu_short;
|
|
|
|
SLONG vlu_long;
|
|
|
|
SINT64 vlu_int64;
|
|
|
|
SQUAD vlu_quad;
|
|
|
|
SLONG vlu_dbkey[2];
|
|
|
|
float vlu_float;
|
|
|
|
double vlu_double;
|
|
|
|
GDS_TIMESTAMP vlu_timestamp;
|
|
|
|
GDS_TIME vlu_sql_time;
|
|
|
|
GDS_DATE vlu_sql_date;
|
2003-12-27 05:37:23 +01:00
|
|
|
void* vlu_invariant; // Pre-compiled invariant object for nod_like and other string functions
|
2001-05-23 15:26:42 +02:00
|
|
|
} vlu_misc;
|
2004-03-28 11:10:30 +02:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
struct impure_value_ex : public impure_value {
|
2001-05-23 15:26:42 +02:00
|
|
|
SLONG vlux_count;
|
2004-01-13 10:52:19 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
#define VLU_computed 1 /* An invariant sub-query has been computed */
|
|
|
|
#define VLU_null 2 /* An invariant sub-query computed to null */
|
|
|
|
|
|
|
|
|
|
|
|
/* Inversion (i.e. nod_index) impure area */
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
struct impure_inversion {
|
2004-03-18 06:56:06 +01:00
|
|
|
SparseBitmap* inv_bitmap;
|
2004-03-28 11:10:30 +02:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
/* AggregateSort impure area */
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
struct impure_agg_sort {
|
2004-03-19 07:14:53 +01:00
|
|
|
sort_context* iasb_sort_handle;
|
2004-01-13 10:52:19 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Various field positions */
|
|
|
|
|
|
|
|
#define e_for_re 0
|
|
|
|
#define e_for_statement 1
|
|
|
|
#define e_for_stall 2
|
|
|
|
#define e_for_rsb 3
|
|
|
|
#define e_for_length 4
|
|
|
|
|
|
|
|
#define e_arg_flag 0
|
|
|
|
#define e_arg_indicator 1
|
|
|
|
#define e_arg_message 2
|
|
|
|
#define e_arg_number 3
|
|
|
|
#define e_arg_length 4
|
|
|
|
|
|
|
|
#define e_msg_number 0
|
|
|
|
#define e_msg_format 1
|
2003-11-23 21:17:30 +01:00
|
|
|
#define e_msg_invariants 2
|
|
|
|
#define e_msg_next 3
|
|
|
|
#define e_msg_length 4
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#define e_fld_stream 0
|
|
|
|
#define e_fld_id 1
|
|
|
|
#define e_fld_default_value 2 /* hold column default value info if any,
|
2004-03-18 06:56:06 +01:00
|
|
|
(Literal*) */
|
2001-05-23 15:26:42 +02:00
|
|
|
#define e_fld_length 3
|
|
|
|
|
|
|
|
#define e_sto_statement 0
|
|
|
|
#define e_sto_statement2 1
|
|
|
|
#define e_sto_sub_store 2
|
|
|
|
#define e_sto_validate 3
|
|
|
|
#define e_sto_relation 4
|
|
|
|
#define e_sto_stream 5
|
|
|
|
#define e_sto_length 6
|
|
|
|
|
|
|
|
#define e_erase_statement 0
|
|
|
|
#define e_erase_sub_erase 1
|
|
|
|
#define e_erase_stream 2
|
|
|
|
#define e_erase_rsb 3
|
|
|
|
#define e_erase_length 4
|
|
|
|
|
2003-06-10 15:40:19 +02:00
|
|
|
#define e_sav_operation 0
|
|
|
|
#define e_sav_name 1
|
|
|
|
#define e_sav_length 2
|
2002-10-29 21:20:44 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#define e_mod_statement 0
|
|
|
|
#define e_mod_sub_mod 1
|
|
|
|
#define e_mod_validate 2
|
|
|
|
#define e_mod_map_view 3
|
|
|
|
#define e_mod_org_stream 4
|
|
|
|
#define e_mod_new_stream 5
|
|
|
|
#define e_mod_rsb 6
|
|
|
|
#define e_mod_length 7
|
|
|
|
|
|
|
|
#define e_send_statement 0
|
|
|
|
#define e_send_message 1
|
|
|
|
#define e_send_length 2
|
|
|
|
|
|
|
|
#define e_asgn_from 0
|
|
|
|
#define e_asgn_to 1
|
|
|
|
#define e_asgn_missing 2 /* Value for comparison for missing */
|
|
|
|
#define e_asgn_missing2 3 /* Value for substitute for missing */
|
|
|
|
#define e_asgn_length 4
|
|
|
|
|
|
|
|
#define e_rel_stream 0
|
|
|
|
#define e_rel_relation 1
|
|
|
|
#define e_rel_view 2 /* parent view for posting access */
|
|
|
|
#define e_rel_alias 3 /* SQL alias for the relation */
|
|
|
|
#define e_rel_context 4 /* user-specified context number for the relation reference */
|
|
|
|
#define e_rel_length 5
|
|
|
|
|
|
|
|
#define e_idx_retrieval 0
|
|
|
|
#define e_idx_length 1
|
|
|
|
|
|
|
|
#define e_lbl_statement 0
|
|
|
|
#define e_lbl_label 1
|
|
|
|
#define e_lbl_length 2
|
|
|
|
|
|
|
|
#define e_any_rse 0
|
|
|
|
#define e_any_rsb 1
|
|
|
|
#define e_any_length 2
|
|
|
|
|
|
|
|
#define e_if_boolean 0
|
|
|
|
#define e_if_true 1
|
|
|
|
#define e_if_false 2
|
|
|
|
#define e_if_length 3
|
|
|
|
|
|
|
|
#define e_hnd_statement 0
|
|
|
|
#define e_hnd_length 1
|
|
|
|
|
|
|
|
#define e_val_boolean 0
|
|
|
|
#define e_val_value 1
|
|
|
|
#define e_val_length 2
|
|
|
|
|
|
|
|
#define e_uni_stream 0 /* Stream for union */
|
2004-03-28 11:10:30 +02:00
|
|
|
#define e_uni_clauses 1 /* RecordSelExpr's for union */
|
2001-05-23 15:26:42 +02:00
|
|
|
#define e_uni_length 2
|
|
|
|
|
|
|
|
#define e_agg_stream 0
|
|
|
|
#define e_agg_rse 1
|
|
|
|
#define e_agg_group 2
|
|
|
|
#define e_agg_map 3
|
|
|
|
#define e_agg_length 4
|
|
|
|
|
|
|
|
/* Statistical expressions */
|
|
|
|
|
|
|
|
#define e_stat_rse 0
|
|
|
|
#define e_stat_value 1
|
|
|
|
#define e_stat_default 2
|
|
|
|
#define e_stat_rsb 3
|
|
|
|
#define e_stat_length 4
|
|
|
|
|
|
|
|
/* Execute stored procedure */
|
|
|
|
|
|
|
|
#define e_esp_inputs 0
|
|
|
|
#define e_esp_in_msg 1
|
|
|
|
#define e_esp_outputs 2
|
|
|
|
#define e_esp_out_msg 3
|
|
|
|
#define e_esp_procedure 4
|
|
|
|
#define e_esp_length 5
|
|
|
|
|
|
|
|
/* Stored procedure view */
|
|
|
|
|
|
|
|
#define e_prc_inputs 0
|
|
|
|
#define e_prc_in_msg 1
|
|
|
|
#define e_prc_stream 2
|
|
|
|
#define e_prc_procedure 3
|
|
|
|
#define e_prc_length 4
|
|
|
|
|
|
|
|
/* Function expression */
|
|
|
|
|
|
|
|
#define e_fun_args 0
|
|
|
|
#define e_fun_function 1
|
|
|
|
#define e_fun_length 2
|
|
|
|
|
|
|
|
/* Generate id */
|
|
|
|
|
|
|
|
#define e_gen_value 0
|
|
|
|
#define e_gen_relation 1
|
|
|
|
#define e_gen_id 1 /* Generator id (replaces e_gen_relation) */
|
|
|
|
#define e_gen_length 2
|
|
|
|
|
|
|
|
/* Protection mask */
|
|
|
|
|
|
|
|
#define e_pro_class 0
|
|
|
|
#define e_pro_relation 1
|
|
|
|
#define e_pro_length 2
|
|
|
|
|
2003-03-05 13:50:44 +01:00
|
|
|
/* Exception */
|
|
|
|
|
|
|
|
#define e_xcp_desc 0
|
|
|
|
#define e_xcp_msg 1
|
|
|
|
#define e_xcp_length 2
|
|
|
|
|
|
|
|
/* Variable declaration */
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#define e_var_id 0
|
|
|
|
#define e_var_variable 1
|
|
|
|
#define e_var_length 2
|
|
|
|
|
|
|
|
#define e_dcl_id 0
|
2003-11-23 21:17:30 +01:00
|
|
|
#define e_dcl_invariants 1
|
|
|
|
#define e_dcl_desc 2
|
2004-03-31 20:03:51 +02:00
|
|
|
#define e_dcl_length (2 + sizeof (DSC)/sizeof (::Jrd::jrd_nod*)) /* Room for descriptor */
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#define e_dep_object 0 /* node for registering dependencies */
|
|
|
|
#define e_dep_object_type 1
|
|
|
|
#define e_dep_field 2
|
|
|
|
#define e_dep_length 3
|
|
|
|
|
|
|
|
#define e_scl_field 0 /* Scalar expression (blr_index) */
|
|
|
|
#define e_scl_subscripts 1
|
|
|
|
#define e_scl_length 2
|
|
|
|
|
|
|
|
#define e_blk_action 0
|
|
|
|
#define e_blk_handlers 1
|
|
|
|
#define e_blk_length 2
|
|
|
|
|
|
|
|
#define e_err_action 0
|
|
|
|
#define e_err_conditions 1
|
|
|
|
#define e_err_length 2
|
|
|
|
|
|
|
|
/* Datatype cast operator */
|
|
|
|
|
|
|
|
#define e_cast_source 0
|
|
|
|
#define e_cast_fmt 1
|
|
|
|
#define e_cast_length 2
|
|
|
|
|
|
|
|
/* IDAPI semantics nodes */
|
|
|
|
|
|
|
|
#define e_index_index 0 /* set current index (blr_set_index) */
|
|
|
|
#define e_index_stream 1
|
|
|
|
#define e_index_rsb 2
|
|
|
|
#define e_index_length 3
|
|
|
|
|
|
|
|
#define e_seek_offset 0 /* for seeking through a stream */
|
|
|
|
#define e_seek_direction 1
|
|
|
|
#define e_seek_rse 2
|
|
|
|
#define e_seek_length 3
|
|
|
|
|
|
|
|
#define e_find_args 0 /* for finding a key value in a stream */
|
|
|
|
#define e_find_operator 1
|
|
|
|
#define e_find_direction 2
|
|
|
|
#define e_find_stream 3
|
|
|
|
#define e_find_rsb 4
|
|
|
|
#define e_find_length 5
|
|
|
|
|
|
|
|
#define e_bookmark_id 0 /* nod_bookmark */
|
|
|
|
#define e_bookmark_length 1
|
|
|
|
|
|
|
|
#define e_setmark_id 0 /* nod_set_bookmark */
|
|
|
|
#define e_setmark_stream 1
|
|
|
|
#define e_setmark_rsb 2
|
|
|
|
#define e_setmark_length 3
|
|
|
|
|
|
|
|
#define e_getmark_stream 0 /* nod_get_bookmark */
|
|
|
|
#define e_getmark_rsb 1
|
|
|
|
#define e_getmark_length 2
|
|
|
|
|
|
|
|
#define e_relmark_id 0 /* nod_release_bookmark */
|
|
|
|
#define e_relmark_length 1
|
|
|
|
|
|
|
|
#define e_lockrel_relation 0 /* nod_lock_relation */
|
|
|
|
#define e_lockrel_level 1
|
|
|
|
#define e_lockrel_length 2
|
|
|
|
|
|
|
|
#define e_lockrec_level 0 /* nod_lock_record */
|
|
|
|
#define e_lockrec_stream 1
|
|
|
|
#define e_lockrec_rsb 2
|
|
|
|
#define e_lockrec_length 3
|
|
|
|
|
|
|
|
#define e_brange_number 0 /* nod_begin_range */
|
|
|
|
#define e_brange_length 1
|
|
|
|
|
|
|
|
#define e_erange_number 0 /* nod_end_range */
|
|
|
|
#define e_erange_length 1
|
|
|
|
|
|
|
|
#define e_drange_number 0 /* nod_delete_range */
|
|
|
|
#define e_drange_length 1
|
|
|
|
|
|
|
|
#define e_rellock_lock 0 /* nod_release_lock */
|
|
|
|
#define e_rellock_length 1
|
|
|
|
|
|
|
|
#define e_find_dbkey_dbkey 0 /* double duty for nod_find_dbkey and nod_find_dbkey_version */
|
|
|
|
#define e_find_dbkey_version 1
|
|
|
|
#define e_find_dbkey_stream 2
|
|
|
|
#define e_find_dbkey_rsb 3
|
|
|
|
#define e_find_dbkey_length 4
|
|
|
|
|
|
|
|
#define e_range_relation_number 0 /* nod_range_relation */
|
|
|
|
#define e_range_relation_relation 1
|
|
|
|
#define e_range_relation_length 2
|
|
|
|
|
|
|
|
#define e_retrieve_relation 0
|
|
|
|
#define e_retrieve_access_type 1
|
|
|
|
#define e_retrieve_length 2
|
|
|
|
|
|
|
|
#define e_reset_from_stream 0
|
|
|
|
#define e_reset_to_stream 1
|
|
|
|
#define e_reset_from_rsb 2
|
|
|
|
#define e_reset_length 3
|
|
|
|
|
|
|
|
#define e_card_stream 0
|
|
|
|
#define e_card_rsb 1
|
|
|
|
#define e_card_length 2
|
|
|
|
|
|
|
|
/* SQL Date supporting nodes */
|
|
|
|
#define e_extract_value 0 /* Node */
|
|
|
|
#define e_extract_part 1 /* Integer */
|
|
|
|
#define e_extract_count 1 /* Number of nodes */
|
|
|
|
#define e_extract_length 2 /* Number of entries in nod_args */
|
|
|
|
|
|
|
|
#define e_current_date_length 1
|
|
|
|
#define e_current_time_length 1
|
|
|
|
#define e_current_timestamp_length 1
|
|
|
|
|
2003-11-02 12:55:17 +01:00
|
|
|
#define e_dcl_cursor_number 0
|
|
|
|
#define e_dcl_cursor_rse 1
|
|
|
|
#define e_dcl_cursor_rsb 2
|
|
|
|
#define e_dcl_cursor_length 3
|
|
|
|
|
|
|
|
#define e_cursor_stmt_op 0
|
|
|
|
#define e_cursor_stmt_number 1
|
|
|
|
#define e_cursor_stmt_seek 2
|
|
|
|
#define e_cursor_stmt_into 3
|
|
|
|
#define e_cursor_stmt_length 4
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-18 04:50:38 +02:00
|
|
|
// Request resources
|
|
|
|
|
|
|
|
struct Resource
|
|
|
|
{
|
|
|
|
enum rsc_s
|
|
|
|
{
|
|
|
|
rsc_relation,
|
|
|
|
rsc_procedure,
|
|
|
|
rsc_index
|
|
|
|
};
|
|
|
|
|
|
|
|
enum rsc_s rsc_type;
|
|
|
|
USHORT rsc_id; /* Id of the resource */
|
|
|
|
jrd_rel* rsc_rel; /* Relation block */
|
|
|
|
jrd_prc* rsc_prc; /* Procedure block */
|
|
|
|
|
|
|
|
static bool greaterThan(const Resource& i1, const Resource& i2) {
|
|
|
|
// A few places of the engine depend on fact that rsc_type
|
|
|
|
// is the first field in ResourceList ordering
|
|
|
|
if (i1.rsc_type != i2.rsc_type)
|
|
|
|
return i1.rsc_type > i2.rsc_type;
|
|
|
|
if (i1.rsc_type == rsc_index) {
|
|
|
|
// Sort by relation ID for now
|
|
|
|
if (i1.rsc_rel->rel_id != i2.rsc_rel->rel_id)
|
|
|
|
return i1.rsc_rel->rel_id > i2.rsc_rel->rel_id;
|
|
|
|
}
|
|
|
|
return i1.rsc_id > i2.rsc_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
Resource(rsc_s type, USHORT id, jrd_rel* rel, jrd_prc* prc) :
|
|
|
|
rsc_type(type), rsc_id(id), rsc_rel(rel), rsc_prc(prc) { }
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef Firebird::SortedArray<Resource, Firebird::EmptyStorage<Resource>,
|
|
|
|
Resource, Firebird::DefaultKeyValue<Resource>, Resource> ResourceList;
|
|
|
|
|
|
|
|
/* Access items */
|
|
|
|
|
|
|
|
struct AccessItem
|
|
|
|
{
|
|
|
|
const TEXT* acc_security_name;
|
|
|
|
SLONG acc_view_id;
|
|
|
|
const TEXT* acc_name;
|
|
|
|
const TEXT* acc_type;
|
|
|
|
USHORT acc_mask;
|
|
|
|
|
|
|
|
static int strcmp_null(const char* s1, const char* s2) {
|
|
|
|
return s1 == NULL ? s2 != NULL : s2 == NULL ? -1 : strcmp(s1, s2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool greaterThan(const AccessItem& i1, const AccessItem& i2) {
|
|
|
|
int v;
|
|
|
|
if ((v = strcmp_null(i1.acc_security_name, i2.acc_security_name)) != 0)
|
|
|
|
return v > 0;
|
|
|
|
|
|
|
|
if (i1.acc_view_id != i2.acc_view_id)
|
|
|
|
return i1.acc_view_id > i2.acc_view_id;
|
|
|
|
|
|
|
|
if (i1.acc_mask != i2.acc_mask)
|
|
|
|
return i1.acc_mask > i2.acc_mask;
|
|
|
|
|
|
|
|
if ((v = strcmp(i1.acc_type, i2.acc_type)) != 0)
|
|
|
|
return v > 0;
|
|
|
|
|
|
|
|
if ((v = strcmp(i1.acc_name, i2.acc_name)) != 0)
|
|
|
|
return v > 0;
|
|
|
|
|
|
|
|
return false; // Equal
|
|
|
|
}
|
|
|
|
|
|
|
|
AccessItem(const TEXT* security_name, SLONG view_id, const TEXT* name,
|
|
|
|
const TEXT* type, USHORT mask)
|
|
|
|
: acc_security_name(security_name), acc_view_id(view_id), acc_name(name),
|
|
|
|
acc_type(type), acc_mask(mask)
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef Firebird::SortedArray<AccessItem, Firebird::EmptyStorage<AccessItem>,
|
|
|
|
AccessItem, Firebird::DefaultKeyValue<AccessItem>, AccessItem> AccessItemList;
|
|
|
|
|
|
|
|
// Triggers and procedures the request accesses
|
|
|
|
struct ExternalAccess
|
|
|
|
{
|
|
|
|
enum exa_act {
|
|
|
|
exa_procedure,
|
|
|
|
exa_insert,
|
|
|
|
exa_update,
|
|
|
|
exa_delete
|
|
|
|
};
|
|
|
|
exa_act exa_action;
|
|
|
|
USHORT exa_prc_id;
|
|
|
|
USHORT exa_rel_id;
|
|
|
|
USHORT exa_view_id;
|
|
|
|
|
|
|
|
// Procedure
|
|
|
|
ExternalAccess(USHORT prc_id) :
|
|
|
|
exa_action(exa_procedure), exa_prc_id(prc_id), exa_rel_id(0), exa_view_id(0)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
// Trigger
|
|
|
|
ExternalAccess(exa_act action, USHORT rel_id, USHORT view_id) :
|
|
|
|
exa_action(action), exa_prc_id(0), exa_rel_id(rel_id), exa_view_id(view_id)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
static bool greaterThan(const ExternalAccess& i1, const ExternalAccess& i2) {
|
|
|
|
if (i1.exa_action != i2.exa_action) return i1.exa_action > i2.exa_action;
|
|
|
|
if (i1.exa_prc_id != i2.exa_prc_id) return i1.exa_prc_id > i2.exa_prc_id;
|
|
|
|
if (i1.exa_rel_id != i2.exa_rel_id) return i1.exa_rel_id > i2.exa_rel_id;
|
|
|
|
if (i1.exa_view_id != i2.exa_view_id) return i1.exa_view_id > i2.exa_view_id;
|
|
|
|
return false; // Equal
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef Firebird::SortedArray<ExternalAccess, Firebird::EmptyStorage<ExternalAccess>,
|
|
|
|
ExternalAccess, Firebird::DefaultKeyValue<ExternalAccess>, ExternalAccess> ExternalAccessList;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
/* Compile scratch block */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TMN: I had to move the enclosed csb_repeat outside this class,
|
|
|
|
* since it's part of the C API. Compiling as C++ would enclose it.
|
|
|
|
*/
|
2004-03-18 06:56:06 +01:00
|
|
|
// CVC: Mike comment seems to apply only when the conversion to C++
|
|
|
|
// was being done. It's almost impossible that a repeating structure of
|
2004-03-28 11:10:30 +02:00
|
|
|
// the compiler scratch block be available to outsiders.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-23 21:17:30 +01:00
|
|
|
typedef Firebird::SortedArray<SLONG> VarInvariantArray;
|
|
|
|
typedef Firebird::Array<VarInvariantArray*> MsgInvariantArray;
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
class CompilerScratch : public pool_alloc<type_csb>
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
|
|
|
public:
|
2004-03-28 11:10:30 +02:00
|
|
|
CompilerScratch(MemoryPool& p, size_t len)
|
2003-01-16 18:47:10 +01:00
|
|
|
: /*csb_blr(0),
|
2001-12-24 03:51:06 +01:00
|
|
|
csb_running(0),
|
|
|
|
csb_node(0),
|
|
|
|
csb_variables(0),
|
|
|
|
csb_dependencies(0),
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef SCROLLABLE_CURSORS
|
2001-12-24 03:51:06 +01:00
|
|
|
csb_current_rse(0),
|
|
|
|
#endif
|
|
|
|
csb_async_message(0),
|
|
|
|
csb_count(0),
|
|
|
|
csb_n_stream(0),
|
|
|
|
csb_msg_number(0),
|
|
|
|
csb_impure(0),
|
2003-01-16 18:47:10 +01:00
|
|
|
csb_g_flags(0),*/
|
2004-04-18 04:50:38 +02:00
|
|
|
csb_external(p),
|
|
|
|
csb_access(p),
|
|
|
|
csb_resources(p),
|
2004-04-18 16:22:27 +02:00
|
|
|
csb_dependencies(p),
|
2004-03-14 14:40:14 +01:00
|
|
|
csb_fors(p),
|
|
|
|
csb_invariants(p),
|
|
|
|
csb_current_nodes(p),
|
2004-03-31 20:03:51 +02:00
|
|
|
csb_pool(p),
|
2004-03-14 14:40:14 +01:00
|
|
|
csb_rpt(p, len)
|
2001-12-24 03:51:06 +01:00
|
|
|
{}
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
static CompilerScratch* newCsb(MemoryPool& p, size_t len)
|
|
|
|
{ return FB_NEW(p) CompilerScratch(p, len); }
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2004-03-07 10:48:56 +01:00
|
|
|
int nextStream(bool check = true)
|
|
|
|
{
|
|
|
|
if (csb_n_stream >= MAX_STREAMS && check)
|
|
|
|
{
|
|
|
|
ERR_post(isc_too_many_contexts, 0);
|
|
|
|
}
|
|
|
|
return csb_n_stream++;
|
|
|
|
}
|
|
|
|
|
2004-03-18 06:56:06 +01:00
|
|
|
const UCHAR* csb_blr;
|
|
|
|
const UCHAR* csb_running;
|
2002-11-21 00:18:16 +01:00
|
|
|
jrd_nod* csb_node;
|
2004-04-18 04:50:38 +02:00
|
|
|
ExternalAccessList csb_external; /* Access to outside procedures/triggers to be checked */
|
|
|
|
AccessItemList csb_access; /* Access items to be checked */
|
2004-03-18 06:56:06 +01:00
|
|
|
vec* csb_variables; /* Vector of variables, if any */
|
2004-04-18 04:50:38 +02:00
|
|
|
ResourceList csb_resources; /* Resources (relations and indexes) */
|
2004-04-18 16:22:27 +02:00
|
|
|
NodeStack csb_dependencies; /* objects this request depends upon */
|
|
|
|
Firebird::Array<RecordSource*> csb_fors; /* stack of fors */
|
2004-02-20 07:43:27 +01:00
|
|
|
Firebird::Array<jrd_nod*> csb_invariants; /* stack of invariant nodes */
|
2004-03-28 11:10:30 +02:00
|
|
|
Firebird::Array<jrd_node_base*> csb_current_nodes; /* RecordSelExpr's and other invariant candidates within whose scope we are */
|
2001-12-24 03:51:06 +01:00
|
|
|
#ifdef SCROLLABLE_CURSORS
|
2004-03-28 11:10:30 +02:00
|
|
|
RecordSelExpr* csb_current_rse; /* this holds the RecordSelExpr currently being processed;
|
|
|
|
unlike the current_rses stack, it references any expanded view RecordSelExpr */
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
2002-11-21 00:18:16 +01:00
|
|
|
jrd_nod* csb_async_message; /* asynchronous message to send to request */
|
2004-03-18 06:56:06 +01:00
|
|
|
USHORT csb_n_stream; /* Next available stream */
|
|
|
|
USHORT csb_msg_number; /* Highest used message number */
|
|
|
|
SLONG csb_impure; /* Next offset into impure area */
|
|
|
|
USHORT csb_g_flags;
|
2004-03-31 20:03:51 +02:00
|
|
|
MemoryPool& csb_pool; /* Memory pool to be used by csb */
|
2003-09-28 23:36:05 +02:00
|
|
|
|
2004-03-18 06:56:06 +01:00
|
|
|
struct csb_repeat
|
|
|
|
{
|
|
|
|
// We must zero-initialize this one
|
|
|
|
csb_repeat()
|
|
|
|
: csb_stream(0),
|
|
|
|
csb_view_stream(0),
|
|
|
|
csb_flags(0),
|
|
|
|
csb_indices(0),
|
|
|
|
csb_relation(0),
|
|
|
|
csb_alias(0),
|
|
|
|
csb_procedure(0),
|
|
|
|
csb_view(0),
|
|
|
|
csb_idx(0),
|
|
|
|
csb_message(0),
|
|
|
|
csb_format(0),
|
|
|
|
csb_fields(0),
|
|
|
|
csb_cardinality(0.0f), // TMN: Non-natural cardinality?!
|
|
|
|
csb_plan(0),
|
|
|
|
csb_map(0),
|
|
|
|
csb_rsb_ptr(0)
|
|
|
|
{}
|
|
|
|
|
|
|
|
UCHAR csb_stream; /* Map user context to internal stream */
|
|
|
|
UCHAR csb_view_stream; /* stream number for view relation, below */
|
|
|
|
USHORT csb_flags;
|
|
|
|
USHORT csb_indices; /* Number of indices */
|
|
|
|
|
|
|
|
jrd_rel* csb_relation;
|
2004-03-31 20:03:51 +02:00
|
|
|
Firebird::string* csb_alias; /* SQL alias name for this instance of relation */
|
2004-03-20 15:57:40 +01:00
|
|
|
jrd_prc* csb_procedure;
|
2004-03-18 06:56:06 +01:00
|
|
|
jrd_rel* csb_view; /* parent view */
|
|
|
|
|
2004-04-18 16:22:27 +02:00
|
|
|
IndexDescAlloc* csb_idx; /* Packed description of indices */
|
2004-03-18 06:56:06 +01:00
|
|
|
jrd_nod* csb_message; /* Msg for send/receive */
|
2004-03-30 06:10:52 +02:00
|
|
|
Format* csb_format; /* Default Format for stream */
|
2004-03-18 06:56:06 +01:00
|
|
|
SparseBitmap* csb_fields; /* Fields referenced */
|
|
|
|
float csb_cardinality; /* Cardinality of relation */
|
|
|
|
jrd_nod* csb_plan; /* user-specified plan for this relation */
|
|
|
|
UCHAR* csb_map; /* Stream map for views */
|
2004-03-28 11:10:30 +02:00
|
|
|
RecordSource** csb_rsb_ptr; /* point to rsb for nod_stream */
|
2004-03-18 06:56:06 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef csb_repeat* rpt_itr;
|
2004-03-20 04:07:21 +01:00
|
|
|
typedef const csb_repeat* rpt_const_itr;
|
2004-03-31 20:03:51 +02:00
|
|
|
Firebird::HalfStaticArray<csb_repeat, 5> csb_rpt;
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#define csb_internal 0x1 /* "csb_g_flag" switch */
|
|
|
|
#define csb_get_dependencies 0x2
|
|
|
|
#define csb_ignore_perm 0x4 /* ignore permissions checks */
|
|
|
|
#define csb_blr_version4 0x8 /* The blr is of version 4 */
|
|
|
|
|
|
|
|
#define csb_active 1
|
2003-09-29 14:43:14 +02:00
|
|
|
#define csb_used 2 /* Context has already been defined (BLR parsing only) */
|
2001-05-23 15:26:42 +02:00
|
|
|
#define csb_view_update 4 /* View update w/wo trigger is in progress */
|
|
|
|
#define csb_trigger 8 /* NEW or OLD context in trigger */
|
|
|
|
#define csb_no_dbkey 16 /* Stream doesn't have a dbkey */
|
|
|
|
#define csb_validation 32 /* We're in a validation expression (RDB hack) */
|
|
|
|
#define csb_store 64 /* we are processing a store statement */
|
|
|
|
#define csb_modify 128 /* we are processing a modify */
|
|
|
|
#define csb_compute 256 /* compute cardinality for this stream */
|
|
|
|
#define csb_erase 512 /* we are processing an erase */
|
|
|
|
#define csb_unmatched 1024 /* stream has conjuncts unmatched by any index */
|
|
|
|
|
|
|
|
#define csb_dbkey 8192 /* Dbkey as been requested (Gateway only) */
|
|
|
|
#define csb_update 16384 /* Erase or modify for relation */
|
|
|
|
#define csb_made_river 32768 /* stream has been included in a river */
|
|
|
|
|
|
|
|
/* Exception condition list */
|
2002-09-28 16:04:35 +02:00
|
|
|
|
|
|
|
struct xcp_repeat {
|
|
|
|
SSHORT xcp_type;
|
|
|
|
SLONG xcp_code;
|
|
|
|
};
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
class PsqlException : public pool_alloc_rpt<xcp_repeat, type_xcp>
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
SLONG xcp_count;
|
|
|
|
xcp_repeat xcp_rpt[1];
|
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#define xcp_sql_code 1
|
|
|
|
#define xcp_gds_code 2
|
|
|
|
#define xcp_xcp_code 3
|
|
|
|
#define xcp_default 4
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
class StatusXcp {
|
2003-11-02 12:55:17 +01:00
|
|
|
ISC_STATUS_ARRAY status;
|
|
|
|
|
|
|
|
public:
|
2004-03-28 11:10:30 +02:00
|
|
|
StatusXcp();
|
2003-11-02 12:55:17 +01:00
|
|
|
|
|
|
|
void clear();
|
|
|
|
void init(const ISC_STATUS*);
|
2003-11-05 10:02:33 +01:00
|
|
|
void copyTo(ISC_STATUS*) const;
|
2003-11-02 12:55:17 +01:00
|
|
|
bool success() const;
|
|
|
|
SLONG as_gdscode() const;
|
|
|
|
SLONG as_sqlcode() const;
|
|
|
|
};
|
|
|
|
|
2002-11-14 08:35:44 +01:00
|
|
|
#define XCP_MESSAGE_LENGTH 78 // must correspond to the size of
|
|
|
|
// RDB$EXCEPTIONS.RDB$MESSAGE
|
2004-03-20 15:57:40 +01:00
|
|
|
} //namespace Jrd
|
2002-11-14 08:35:44 +01:00
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
#endif // JRD_EXE_H
|
2003-11-07 09:06:35 +01:00
|
|
|
|