From 05e6ebd58ce29abc701c8091b75d2c2f11e707ce Mon Sep 17 00:00:00 2001 From: asfernandes Date: Tue, 6 Feb 2007 14:25:10 +0000 Subject: [PATCH] Check constraints when reading variables/parameters only if it's the first read and it's wasn't assigned yet --- src/jrd/cmp.cpp | 4 ++++ src/jrd/evl.cpp | 24 ++++++++++++++++++------ src/jrd/exe.cpp | 23 ++++++++++++++++++++++- src/jrd/exe.h | 15 ++++++++------- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/jrd/cmp.cpp b/src/jrd/cmp.cpp index b58d2d55ff..a7c826be2a 100644 --- a/src/jrd/cmp.cpp +++ b/src/jrd/cmp.cpp @@ -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; diff --git a/src/jrd/evl.cpp b/src/jrd/evl.cpp index e78a32f325..fbd7a1881e 100644 --- a/src/jrd/evl.cpp +++ b/src/jrd/evl.cpp @@ -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; } diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index 41e29666d2..9da3ff98c0 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -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; diff --git a/src/jrd/exe.h b/src/jrd/exe.h index 33d04bf91f..7a2d0163d9 100644 --- a/src/jrd/exe.h +++ b/src/jrd/exe.h @@ -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;