mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 06:43:04 +01:00
Refactor blr_index (nod_scalar)
This commit is contained in:
parent
de453fcfd3
commit
0d19fe7688
@ -3512,15 +3512,6 @@ ValueExprNode* CurrentUserNode::dsqlPass(DsqlCompilerScratch* /*dsqlScratch*/)
|
||||
|
||||
static RegisterNode<DerivedExprNode> regDerivedExprNode(blr_derived_expr);
|
||||
|
||||
DerivedExprNode::DerivedExprNode(MemoryPool& pool, dsql_nod* aArg)
|
||||
: TypedNode<ValueExprNode, ExprNode::TYPE_DERIVED_EXPR>(pool),
|
||||
dsqlArg(aArg),
|
||||
arg(NULL),
|
||||
streamList(pool)
|
||||
{
|
||||
addChildNode(dsqlArg, arg);
|
||||
}
|
||||
|
||||
DmlNode* DerivedExprNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR /*blrOp*/)
|
||||
{
|
||||
DerivedExprNode* node = FB_NEW(pool) DerivedExprNode(pool);
|
||||
@ -5666,6 +5657,90 @@ dsc* ParameterNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
//--------------------
|
||||
|
||||
|
||||
static RegisterNode<ScalarNode> regScalarNode1(blr_index);
|
||||
|
||||
DmlNode* ScalarNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR /*blrOp*/)
|
||||
{
|
||||
ScalarNode* node = FB_NEW(pool) ScalarNode(pool);
|
||||
node->field = PAR_parse_node(tdbb, csb, VALUE);
|
||||
node->subscripts = PAR_args(tdbb, csb, VALUE);
|
||||
return node;
|
||||
}
|
||||
|
||||
void ScalarNode::getDesc(thread_db* /*tdbb*/, CompilerScratch* csb, dsc* desc)
|
||||
{
|
||||
jrd_rel* relation = csb->csb_rpt[(USHORT)(IPTR) field->nod_arg[e_fld_stream]].csb_relation;
|
||||
const USHORT id = (USHORT)(IPTR) field->nod_arg[e_fld_id];
|
||||
const jrd_fld* field = MET_get_field(relation, id);
|
||||
const ArrayField* array;
|
||||
|
||||
if (!field || !(array = field->fld_array))
|
||||
IBERROR(223); // msg 223 argument of scalar operation must be an array
|
||||
|
||||
*desc = array->arr_desc.iad_rpt[0].iad_desc;
|
||||
|
||||
if (array->arr_desc.iad_dimensions > MAX_ARRAY_DIMENSIONS)
|
||||
IBERROR(306); // Found array data type with more than 16 dimensions
|
||||
}
|
||||
|
||||
ValueExprNode* ScalarNode::copy(thread_db* tdbb, NodeCopier& copier)
|
||||
{
|
||||
ScalarNode* node = FB_NEW(*tdbb->getDefaultPool()) ScalarNode(*tdbb->getDefaultPool());
|
||||
node->field = copier.copy(tdbb, field);
|
||||
node->subscripts = copier.copy(tdbb, subscripts);
|
||||
return node;
|
||||
}
|
||||
|
||||
ExprNode* ScalarNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
||||
{
|
||||
ExprNode::pass2(tdbb, csb);
|
||||
|
||||
dsc desc;
|
||||
getDesc(tdbb, csb, &desc);
|
||||
node->nod_impure = CMP_impure(csb, sizeof(impure_value));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Evaluate a scalar item from an array.
|
||||
dsc* ScalarNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
{
|
||||
impure_value* const impure = request->getImpure<impure_value>(node->nod_impure);
|
||||
const dsc* desc = EVL_expr(tdbb, field);
|
||||
|
||||
if (request->req_flags & req_null)
|
||||
return NULL;
|
||||
|
||||
if (desc->dsc_dtype != dtype_array)
|
||||
IBERROR(261); // msg 261 scalar operator used on field which is not an array
|
||||
|
||||
if (subscripts->nod_count > MAX_ARRAY_DIMENSIONS)
|
||||
ERR_post(Arg::Gds(isc_array_max_dimensions) << Arg::Num(MAX_ARRAY_DIMENSIONS));
|
||||
|
||||
SLONG numSubscripts[MAX_ARRAY_DIMENSIONS];
|
||||
int iter = 0;
|
||||
const jrd_nod* const* ptr = subscripts->nod_arg;
|
||||
|
||||
for (const jrd_nod* const* const end = ptr + subscripts->nod_count; ptr < end;)
|
||||
{
|
||||
const dsc* temp = EVL_expr(tdbb, *ptr++);
|
||||
|
||||
if (temp && !(request->req_flags & req_null))
|
||||
numSubscripts[iter++] = MOV_get_long(temp, 0);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLB_scalar(tdbb, request->req_transaction, reinterpret_cast<bid*>(desc->dsc_address),
|
||||
subscripts->nod_count, numSubscripts, impure);
|
||||
|
||||
return &impure->vlu_desc;
|
||||
}
|
||||
|
||||
|
||||
//--------------------
|
||||
|
||||
|
||||
static RegisterNode<StrCaseNode> regStrCaseNodeLower(blr_lowcase);
|
||||
static RegisterNode<StrCaseNode> regStrCaseNodeUpper(blr_upcase);
|
||||
|
||||
|
@ -277,7 +277,13 @@ public:
|
||||
class DerivedExprNode : public TypedNode<ValueExprNode, ExprNode::TYPE_DERIVED_EXPR>
|
||||
{
|
||||
public:
|
||||
DerivedExprNode(MemoryPool& pool, dsql_nod* aArg = NULL);
|
||||
DerivedExprNode(MemoryPool& pool)
|
||||
: TypedNode<ValueExprNode, ExprNode::TYPE_DERIVED_EXPR>(pool),
|
||||
arg(NULL),
|
||||
streamList(pool)
|
||||
{
|
||||
addChildNode(arg);
|
||||
}
|
||||
|
||||
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp);
|
||||
|
||||
@ -316,7 +322,6 @@ public:
|
||||
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const;
|
||||
|
||||
public:
|
||||
dsql_nod* dsqlArg;
|
||||
NestConst<jrd_nod> arg;
|
||||
Firebird::Array<USHORT> streamList;
|
||||
};
|
||||
@ -649,6 +654,53 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class ScalarNode : public TypedNode<ValueExprNode, ExprNode::TYPE_SCALAR>
|
||||
{
|
||||
public:
|
||||
explicit ScalarNode(MemoryPool& pool)
|
||||
: TypedNode<ValueExprNode, ExprNode::TYPE_SCALAR>(pool),
|
||||
field(NULL),
|
||||
subscripts(NULL)
|
||||
{
|
||||
addChildNode(field);
|
||||
addChildNode(subscripts);
|
||||
}
|
||||
|
||||
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp);
|
||||
|
||||
// This is a non-DSQL node.
|
||||
|
||||
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const
|
||||
{
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
virtual void setParameterName(dsql_par* parameter) const
|
||||
{
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
virtual void genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
||||
{
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier);
|
||||
virtual ExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const;
|
||||
|
||||
public:
|
||||
NestConst<jrd_nod> field;
|
||||
NestConst<jrd_nod> subscripts;
|
||||
};
|
||||
|
||||
|
||||
class StrCaseNode : public TypedNode<ValueExprNode, ExprNode::TYPE_STR_CASE>
|
||||
{
|
||||
public:
|
||||
|
@ -278,6 +278,7 @@ public:
|
||||
TYPE_OVER,
|
||||
TYPE_PARAMETER,
|
||||
TYPE_RSE_BOOL,
|
||||
TYPE_SCALAR,
|
||||
TYPE_STR_CASE,
|
||||
TYPE_STR_LEN,
|
||||
TYPE_SUBQUERY,
|
||||
|
@ -449,22 +449,6 @@ void CMP_get_desc(thread_db* tdbb, CompilerScratch* csb, jrd_nod* node, DSC* des
|
||||
return;
|
||||
}
|
||||
|
||||
case nod_scalar:
|
||||
{
|
||||
jrd_nod* sub = node->nod_arg[e_scl_field];
|
||||
jrd_rel* relation = csb->csb_rpt[(USHORT)(IPTR) sub->nod_arg[e_fld_stream]].csb_relation;
|
||||
const USHORT id = (USHORT)(IPTR) sub->nod_arg[e_fld_id];
|
||||
const jrd_fld* field = MET_get_field(relation, id);
|
||||
const ArrayField* array;
|
||||
if (!field || !(array = field->fld_array)) {
|
||||
IBERROR(223); // msg 223 argument of scalar operation must be an array
|
||||
}
|
||||
*desc = array->arr_desc.iad_rpt[0].iad_desc;
|
||||
if (array->arr_desc.iad_dimensions > MAX_ARRAY_DIMENSIONS)
|
||||
IBERROR(306); // Found array data type with more than 16 dimensions
|
||||
return;
|
||||
}
|
||||
|
||||
case nod_class_exprnode_jrd:
|
||||
{
|
||||
ValueExprNode* exprNode = reinterpret_cast<ValueExprNode*>(node->nod_arg[0]);
|
||||
@ -2671,7 +2655,6 @@ jrd_nod* CMP_pass2(thread_db* tdbb, CompilerScratch* csb, jrd_nod* const node, j
|
||||
|
||||
case nod_dbkey:
|
||||
case nod_rec_version:
|
||||
case nod_scalar:
|
||||
{
|
||||
dsc descriptor_a;
|
||||
CMP_get_desc(tdbb, csb, node, &descriptor_a);
|
||||
|
@ -120,7 +120,6 @@ using namespace Firebird;
|
||||
|
||||
static dsc* dbkey(thread_db*, const jrd_nod*, impure_value*);
|
||||
static dsc* record_version(thread_db*, const jrd_nod*, impure_value*);
|
||||
static dsc* scalar(thread_db*, const jrd_nod*, impure_value*);
|
||||
|
||||
|
||||
dsc* EVL_assign_to(thread_db* tdbb, const jrd_nod* node)
|
||||
@ -446,9 +445,6 @@ dsc* EVL_expr(thread_db* tdbb, const jrd_nod* node)
|
||||
return &impure->vlu_desc;
|
||||
}
|
||||
|
||||
case nod_scalar:
|
||||
return scalar(tdbb, node, impure);
|
||||
|
||||
case nod_stmt_expr:
|
||||
EXE_looper(tdbb, request, node);
|
||||
return EVL_expr(tdbb, node->nod_arg[e_stmt_expr_expr]);
|
||||
@ -891,57 +887,3 @@ static dsc* record_version(thread_db* tdbb, const jrd_nod* node, impure_value* i
|
||||
|
||||
return &impure->vlu_desc;
|
||||
}
|
||||
|
||||
|
||||
static dsc* scalar(thread_db* tdbb, const jrd_nod* node, impure_value* impure)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* s c a l a r
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Evaluate a scalar item from an array.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
DEV_BLKCHK(node, type_nod);
|
||||
|
||||
const dsc* desc = EVL_expr(tdbb, node->nod_arg[e_scl_field]);
|
||||
jrd_req* request = tdbb->getRequest();
|
||||
|
||||
if (request->req_flags & req_null)
|
||||
return NULL;
|
||||
|
||||
if (desc->dsc_dtype != dtype_array)
|
||||
IBERROR(261); // msg 261 scalar operator used on field which is not an array
|
||||
|
||||
const jrd_nod* list = node->nod_arg[e_scl_subscripts];
|
||||
if (list->nod_count > MAX_ARRAY_DIMENSIONS)
|
||||
ERR_post(Arg::Gds(isc_array_max_dimensions) << Arg::Num(MAX_ARRAY_DIMENSIONS));
|
||||
|
||||
SLONG subscripts[MAX_ARRAY_DIMENSIONS];
|
||||
int iter = 0;
|
||||
const jrd_nod* const* ptr = list->nod_arg;
|
||||
for (const jrd_nod* const* const end = ptr + list->nod_count; ptr < end;)
|
||||
{
|
||||
const dsc* temp = EVL_expr(tdbb, *ptr++);
|
||||
if (temp && !(request->req_flags & req_null))
|
||||
subscripts[iter++] = MOV_get_long(temp, 0);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BLB_scalar(tdbb,
|
||||
request->req_transaction,
|
||||
reinterpret_cast<bid*>(desc->dsc_address),
|
||||
list->nod_count,
|
||||
subscripts, impure);
|
||||
// It was subscripts, reinterpret_cast<impure_value*>(&impure->vlu_desc));
|
||||
// but vlu_desc is the first member of impure_value and impure is already
|
||||
// of type impure_value*, so this cast seems nonsense.
|
||||
|
||||
return &impure->vlu_desc;
|
||||
}
|
||||
|
@ -249,10 +249,6 @@ const int e_dcl_id = 0;
|
||||
const int e_dcl_desc = 1;
|
||||
const int e_dcl_length = (1 + sizeof (DSC) / sizeof(::Jrd::jrd_nod*)); // Room for descriptor
|
||||
|
||||
const int e_scl_field = 0; // Scalar expression (blr_index)
|
||||
const int e_scl_subscripts = 1;
|
||||
const int e_scl_length = 2;
|
||||
|
||||
const int e_blk_action = 0;
|
||||
const int e_blk_handlers = 1;
|
||||
const int e_blk_length = 2;
|
||||
|
@ -59,7 +59,6 @@ NODE(nod_set_generator2, set_generator, "")
|
||||
|
||||
NODE(nod_dbkey, dbkey, "ROWID")
|
||||
NODE(nod_field, field, "")
|
||||
NODE(nod_scalar, scalar, "")
|
||||
NODE(nod_rec_version, record_version, "RECORD VERSION")
|
||||
|
||||
NODE(nod_stmt_expr, stmt_expr, "stmt_expr")
|
||||
|
@ -2371,11 +2371,6 @@ jrd_nod* PAR_parse_node(thread_db* tdbb, CompilerScratch* csb, USHORT expected)
|
||||
node->nod_arg[0] = (jrd_nod*) ProcedureSourceNode::parse(tdbb, csb, blr_operator);
|
||||
break;
|
||||
|
||||
case blr_index:
|
||||
node->nod_arg[0] = PAR_parse_node(tdbb, csb, sub_type);
|
||||
node->nod_arg[1] = PAR_args(tdbb, csb, sub_type);
|
||||
break;
|
||||
|
||||
case blr_dcl_cursor:
|
||||
{
|
||||
node->nod_arg[e_dcl_cur_number] = (jrd_nod*) (IPTR) csb->csb_blr_reader.getWord();
|
||||
|
@ -126,7 +126,7 @@ static const VERB verbs[] =
|
||||
PAIR(nod_class_exprnode_jrd, blr_from, 1, 0, VALUE, OTHER),
|
||||
PAIR(nod_class_exprnode_jrd, blr_function, 1, 0, VALUE, VALUE),
|
||||
PAIR(nod_class_exprnode_jrd, blr_literal, 1, 0, VALUE, OTHER),
|
||||
PAIR(nod_scalar, blr_index, 2, 2, VALUE, VALUE),
|
||||
PAIR(nod_class_exprnode_jrd, blr_index, 1, 0, VALUE, VALUE),
|
||||
PAIR(nod_class_exprnode_jrd, blr_maximum, 1, 0, VALUE, VALUE),
|
||||
PAIR(nod_class_exprnode_jrd, blr_minimum, 1, 0, VALUE, VALUE),
|
||||
PAIR(nod_class_exprnode_jrd, blr_null, 1, 0, VALUE, VALUE),
|
||||
|
Loading…
Reference in New Issue
Block a user