mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 15:23:02 +01:00
Check constraints when reading variables/parameters only if it's the first read and it's wasn't assigned yet
This commit is contained in:
parent
57291f67f8
commit
05e6ebd58c
@ -2892,6 +2892,7 @@ static jrd_nod* copy(thread_db* tdbb,
|
||||
node->nod_count = input->nod_count;
|
||||
node->nod_arg[e_msg_number] = input->nod_arg[e_msg_number];
|
||||
node->nod_arg[e_msg_format] = input->nod_arg[e_msg_format];
|
||||
node->nod_arg[e_msg_impure_flags] = input->nod_arg[e_msg_impure_flags];
|
||||
// dimitr: hmmm, cannot find where the following one is used...
|
||||
node->nod_arg[e_msg_next] =
|
||||
copy(tdbb, csb, input->nod_arg[e_msg_next], remap, field_id,
|
||||
@ -4955,6 +4956,9 @@ static jrd_nod* pass2(thread_db* tdbb, CompilerScratch* csb, jrd_nod* const node
|
||||
const Format* format = (Format*) node->nod_arg[e_msg_format];
|
||||
if (!((tdbb->tdbb_flags & TDBB_prc_being_dropped) && !format)) {
|
||||
csb->csb_impure += FB_ALIGN(format->fmt_length, 2);
|
||||
|
||||
node->nod_arg[e_msg_impure_flags] = (jrd_nod*)(IPTR) CMP_impure(csb, 0);
|
||||
csb->csb_impure += sizeof(USHORT) * format->fmt_count;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -860,10 +860,18 @@ dsc* EVL_expr(thread_db* tdbb, jrd_nod* const node)
|
||||
if (impure->vlu_desc.dsc_dtype == dtype_text)
|
||||
adjust_text_descriptor(tdbb, &impure->vlu_desc);
|
||||
|
||||
EVL_validate(tdbb,
|
||||
Item(nod_argument, (IPTR) node->nod_arg[e_arg_message]->nod_arg[e_msg_number],
|
||||
(IPTR) node->nod_arg[e_arg_number]),
|
||||
&impure->vlu_desc, request->req_flags & req_null);
|
||||
USHORT* impure_flags = (USHORT*) ((UCHAR *) request +
|
||||
(IPTR) message->nod_arg[e_msg_impure_flags] +
|
||||
(sizeof(USHORT) * (IPTR) node->nod_arg[e_arg_number]));
|
||||
|
||||
if (!(*impure_flags & VLU_checked))
|
||||
{
|
||||
EVL_validate(tdbb,
|
||||
Item(nod_argument, (IPTR) node->nod_arg[e_arg_message]->nod_arg[e_msg_number],
|
||||
(IPTR) node->nod_arg[e_arg_number]),
|
||||
&impure->vlu_desc, request->req_flags & req_null);
|
||||
*impure_flags |= VLU_checked;
|
||||
}
|
||||
|
||||
return &impure->vlu_desc;
|
||||
}
|
||||
@ -1037,8 +1045,12 @@ dsc* EVL_expr(thread_db* tdbb, jrd_nod* const node)
|
||||
if (impure->vlu_desc.dsc_dtype == dtype_text)
|
||||
adjust_text_descriptor(tdbb, &impure->vlu_desc);
|
||||
|
||||
EVL_validate(tdbb, Item(nod_variable, (IPTR) node->nod_arg[e_var_id]),
|
||||
&impure->vlu_desc, impure->vlu_desc.dsc_flags & DSC_null);
|
||||
if (!(impure2->vlu_flags & VLU_checked))
|
||||
{
|
||||
EVL_validate(tdbb, Item(nod_variable, (IPTR) node->nod_arg[e_var_id]),
|
||||
&impure->vlu_desc, impure->vlu_desc.dsc_flags & DSC_null);
|
||||
impure2->vlu_flags |= VLU_checked;
|
||||
}
|
||||
|
||||
return &impure->vlu_desc;
|
||||
}
|
||||
|
@ -291,11 +291,15 @@ void EXE_assignment(thread_db* tdbb, jrd_nod* node)
|
||||
null = -1;
|
||||
}
|
||||
|
||||
USHORT* impure_flags = NULL;
|
||||
|
||||
switch (to->nod_type)
|
||||
{
|
||||
case nod_variable:
|
||||
EVL_validate(tdbb, Item(nod_variable, (IPTR) to->nod_arg[e_var_id]),
|
||||
from_desc, null == -1);
|
||||
impure_flags = &((impure_value*) ((SCHAR *) request +
|
||||
to->nod_arg[e_var_variable]->nod_impure))->vlu_flags;
|
||||
break;
|
||||
|
||||
case nod_argument:
|
||||
@ -303,9 +307,15 @@ void EXE_assignment(thread_db* tdbb, jrd_nod* node)
|
||||
Item(nod_argument, (IPTR) to->nod_arg[e_arg_message]->nod_arg[e_msg_number],
|
||||
(IPTR) to->nod_arg[e_arg_number]),
|
||||
from_desc, null == -1);
|
||||
impure_flags = (USHORT*) ((UCHAR *) request +
|
||||
(IPTR) to->nod_arg[e_arg_message]->nod_arg[e_msg_impure_flags] +
|
||||
(sizeof(USHORT) * (IPTR) to->nod_arg[e_arg_number]));
|
||||
break;
|
||||
}
|
||||
|
||||
if (impure_flags != NULL)
|
||||
*impure_flags |= VLU_checked;
|
||||
|
||||
/* If the value is non-missing, move/convert it. Otherwise fill the
|
||||
field with appropriate nulls. */
|
||||
dsc temp;
|
||||
@ -2501,12 +2511,23 @@ static jrd_nod* looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
|
||||
|
||||
if (transaction->tra_flags & TRA_autocommit)
|
||||
transaction->tra_flags |= TRA_perform_autocommit;
|
||||
case nod_message:
|
||||
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
request->req_operation = jrd_req::req_return;
|
||||
node = node->nod_parent;
|
||||
break;
|
||||
|
||||
case nod_message:
|
||||
if (request->req_operation == jrd_req::req_evaluate)
|
||||
{
|
||||
const Format* format = (Format*) node->nod_arg[e_msg_format];
|
||||
USHORT* impure_flags = (USHORT*) ((UCHAR *) request + (IPTR) node->nod_arg[e_msg_impure_flags]);
|
||||
memset(impure_flags, 0, sizeof(USHORT) * format->fmt_count);
|
||||
request->req_operation = jrd_req::req_return;
|
||||
}
|
||||
node = node->nod_parent;
|
||||
break;
|
||||
|
||||
case nod_stall:
|
||||
node = stall(tdbb, node);
|
||||
break;
|
||||
|
@ -226,9 +226,9 @@ struct impure_value_ex : public impure_value {
|
||||
};
|
||||
|
||||
|
||||
const int VLU_computed = 1; /* An invariant sub-query has been computed */
|
||||
const int VLU_null = 2; /* An invariant sub-query computed to null */
|
||||
|
||||
const int VLU_computed = 1; // An invariant sub-query has been computed
|
||||
const int VLU_null = 2; // An invariant sub-query computed to null
|
||||
const int VLU_checked = 4; // Constraint already checked in first read or assignment to argument/variable
|
||||
|
||||
/* Inversion (i.e. nod_index) impure area */
|
||||
|
||||
@ -258,10 +258,11 @@ const int e_arg_message = 2;
|
||||
const int e_arg_number = 3;
|
||||
const int e_arg_length = 4;
|
||||
|
||||
const int e_msg_number = 0;
|
||||
const int e_msg_format = 1;
|
||||
const int e_msg_next = 2;
|
||||
const int e_msg_length = 3;
|
||||
const int e_msg_number = 0;
|
||||
const int e_msg_format = 1;
|
||||
const int e_msg_next = 2;
|
||||
const int e_msg_impure_flags = 3;
|
||||
const int e_msg_length = 4;
|
||||
|
||||
const int e_fld_stream = 0;
|
||||
const int e_fld_id = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user