mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:03:03 +01:00
1) Fixed check constraints
2) A bit simplified generation of check option triggers 3) Cleanup of unused parser stuff
This commit is contained in:
parent
250f9cd0dd
commit
85388cd3c7
171
src/dsql/ddl.cpp
171
src/dsql/ddl.cpp
@ -844,28 +844,21 @@ static void check_constraint( dsql_req* request,
|
||||
|
||||
// specify that the trigger should abort if the condition is not met
|
||||
|
||||
dsql_nod* list_node = MAKE_node(nod_list, (int) 1);
|
||||
dsql_nod* list_node = MAKE_node(nod_list, 1);
|
||||
element->nod_arg[e_cnstr_actions] = list_node;
|
||||
list_node->nod_arg[0] = MAKE_node(nod_gdscode, (int) 1);
|
||||
list_node->nod_arg[0] = MAKE_node(nod_gdscode, 1);
|
||||
|
||||
dsql_nod** errorcode_node = &list_node->nod_arg[0]->nod_arg[0];
|
||||
*errorcode_node = (dsql_nod*) MAKE_cstring("check_constraint");
|
||||
element->nod_arg[e_cnstr_message] = NULL;
|
||||
|
||||
// create the INSERT trigger
|
||||
|
||||
// element->nod_arg[e_cnstr_message] =
|
||||
// (dsql_nod*) MAKE_cstring ("insert violates CHECK constraint on table");
|
||||
|
||||
element->nod_arg[e_cnstr_type] =
|
||||
MAKE_constant((dsql_str*) PRE_STORE_TRIGGER, CONSTANT_SLONG);
|
||||
define_constraint_trigger(request, element);
|
||||
|
||||
// create the UPDATE trigger
|
||||
|
||||
// element->nod_arg[e_cnstr_message] =
|
||||
// (dsql_nod*) MAKE_cstring ("update violates CHECK constraint on table");
|
||||
|
||||
element->nod_arg[e_cnstr_type] =
|
||||
MAKE_constant((dsql_str*) PRE_MODIFY_TRIGGER, CONSTANT_SLONG);
|
||||
define_constraint_trigger(request, element);
|
||||
@ -873,10 +866,6 @@ static void check_constraint( dsql_req* request,
|
||||
// create the DELETE trigger, if required
|
||||
if (delete_trigger_required)
|
||||
{
|
||||
//
|
||||
// element->nod_arg[e_cnstr_message] =
|
||||
// (dsql_nod*) MAKE_cstring ("delete violates CHECK constraint on table");
|
||||
//
|
||||
element->nod_arg[e_cnstr_type] =
|
||||
MAKE_constant((dsql_str*) PRE_ERASE_TRIGGER, CONSTANT_SLONG);
|
||||
define_constraint_trigger(request, element);
|
||||
@ -934,19 +923,15 @@ static void create_view_triggers(dsql_req* request, dsql_nod* element,
|
||||
|
||||
// specify that the trigger should abort if the condition is not met
|
||||
|
||||
dsql_nod* list_node = MAKE_node(nod_list, (int) 1);
|
||||
dsql_nod* list_node = MAKE_node(nod_list, 1);
|
||||
element->nod_arg[e_cnstr_actions] = list_node;
|
||||
list_node->nod_arg[0] = MAKE_node(nod_gdscode, (int) 1);
|
||||
list_node->nod_arg[0] = MAKE_node(nod_gdscode, 1);
|
||||
|
||||
dsql_nod** errorcode_node = &list_node->nod_arg[0]->nod_arg[0];
|
||||
*errorcode_node = (dsql_nod*) MAKE_cstring("check_constraint");
|
||||
element->nod_arg[e_cnstr_message] = NULL;
|
||||
|
||||
// create the UPDATE trigger
|
||||
|
||||
// element->nod_arg[e_cnstr_message] =
|
||||
// (dsql_nod*) MAKE_cstring ("update violates CHECK constraint on view");
|
||||
|
||||
element->nod_arg[e_cnstr_type] =
|
||||
MAKE_constant((dsql_str*) PRE_MODIFY_TRIGGER, CONSTANT_SLONG);
|
||||
|
||||
@ -963,9 +948,6 @@ static void create_view_triggers(dsql_req* request, dsql_nod* element,
|
||||
|
||||
// create the INSERT trigger
|
||||
|
||||
// element->nod_arg[e_cnstr_message] =
|
||||
// (dsql_nod*) MAKE_cstring ("insert violates CHECK constraint on view");
|
||||
|
||||
element->nod_arg[e_cnstr_type] =
|
||||
MAKE_constant((dsql_str*) PRE_STORE_TRIGGER, CONSTANT_SLONG);
|
||||
define_view_trigger(request, element, NULL, items);
|
||||
@ -1110,19 +1092,11 @@ static void define_constraint_trigger(dsql_req* request, dsql_nod* node)
|
||||
return;
|
||||
}
|
||||
|
||||
const dsql_str* trigger_name = (dsql_str*) node->nod_arg[e_cnstr_name];
|
||||
|
||||
fb_assert(trigger_name->str_length <= MAX_USHORT);
|
||||
|
||||
request->append_string( isc_dyn_def_trigger,
|
||||
trigger_name->str_data,
|
||||
(USHORT) trigger_name->str_length);
|
||||
request->append_string(isc_dyn_def_trigger, "", 0);
|
||||
|
||||
dsql_nod* relation_node = node->nod_arg[e_cnstr_table];
|
||||
const dsql_str* relation_name = (dsql_str*) relation_node->nod_arg[e_rln_name];
|
||||
|
||||
fb_assert(trigger_name->str_length <= MAX_USHORT);
|
||||
|
||||
request->append_string( isc_dyn_rel_name,
|
||||
relation_name->str_data,
|
||||
(USHORT) relation_name->str_length);
|
||||
@ -1136,15 +1110,10 @@ static void define_constraint_trigger(dsql_req* request, dsql_nod* node)
|
||||
(USHORT) source->str_length);
|
||||
}
|
||||
|
||||
const dsql_nod* constant = node->nod_arg[e_cnstr_position];
|
||||
if (constant)
|
||||
{
|
||||
request->append_number(isc_dyn_trg_sequence,
|
||||
(SSHORT) (constant ? (IPTR) constant->nod_arg[0] : 0));
|
||||
}
|
||||
request->append_number(isc_dyn_trg_sequence, 0);
|
||||
|
||||
constant = node->nod_arg[e_cnstr_type];
|
||||
if (constant != NULL)
|
||||
const dsql_nod* constant = node->nod_arg[e_cnstr_type];
|
||||
if (constant)
|
||||
{
|
||||
const SSHORT type = (SSHORT)(IPTR) constant->nod_arg[0];
|
||||
request->append_number(isc_dyn_trg_type, type);
|
||||
@ -1152,17 +1121,6 @@ static void define_constraint_trigger(dsql_req* request, dsql_nod* node)
|
||||
|
||||
request->append_uchar(isc_dyn_sql_object);
|
||||
|
||||
const dsql_str* message = (dsql_str*) node->nod_arg[e_cnstr_message];
|
||||
if (message)
|
||||
{
|
||||
request->append_number(isc_dyn_def_trigger_msg, 0);
|
||||
fb_assert(message->str_length <= MAX_USHORT);
|
||||
request->append_string( isc_dyn_trg_msg,
|
||||
message->str_data,
|
||||
(USHORT) message->str_length);
|
||||
request->append_uchar(isc_dyn_end);
|
||||
}
|
||||
|
||||
// generate the trigger blr
|
||||
|
||||
if (node->nod_arg[e_cnstr_condition] && node->nod_arg[e_cnstr_actions])
|
||||
@ -1197,14 +1155,15 @@ static void define_constraint_trigger(dsql_req* request, dsql_nod* node)
|
||||
// generate the condition for firing the trigger
|
||||
|
||||
request->append_uchar(blr_if);
|
||||
GEN_expr(request,
|
||||
PASS1_node(request, node->nod_arg[e_cnstr_condition], false));
|
||||
|
||||
request->append_uchar(blr_begin);
|
||||
request->append_uchar(blr_end); // of begin
|
||||
dsql_nod* condition = MAKE_node(nod_not, 1);
|
||||
condition->nod_arg[0] = node->nod_arg[e_cnstr_condition];
|
||||
|
||||
GEN_expr(request, PASS1_node(request, condition, false));
|
||||
|
||||
// generate the action statements for the trigger
|
||||
dsql_nod* actions = node->nod_arg[e_cnstr_actions];
|
||||
|
||||
dsql_nod* actions = node->nod_arg[e_cnstr_actions];
|
||||
dsql_nod** ptr = actions->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + actions->nod_count;
|
||||
ptr < end; ptr++)
|
||||
@ -1212,23 +1171,8 @@ static void define_constraint_trigger(dsql_req* request, dsql_nod* node)
|
||||
GEN_statement(request, PASS1_statement(request, *ptr, false));
|
||||
}
|
||||
|
||||
// generate the action statements for the trigger
|
||||
|
||||
if ((actions = node->nod_arg[e_cnstr_else]) != NULL)
|
||||
{
|
||||
request->append_uchar(blr_begin);
|
||||
ptr = actions->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + actions->nod_count;
|
||||
ptr < end; ptr++)
|
||||
{
|
||||
GEN_statement(request, PASS1_statement(request, *ptr, false));
|
||||
}
|
||||
request->append_uchar(blr_end); // of begin
|
||||
}
|
||||
else
|
||||
{
|
||||
request->append_uchar(blr_end); // of if
|
||||
}
|
||||
request->append_uchar(blr_end); // of if (as there's no ELSE branch)
|
||||
request->append_uchar(blr_end); // of begin
|
||||
|
||||
request->end_blr();
|
||||
}
|
||||
@ -1360,7 +1304,7 @@ static void define_del_cascade_trg( dsql_req* request,
|
||||
}
|
||||
|
||||
// stuff a trigger_name of size 0. So the dyn-parser will make one up.
|
||||
request->append_string( isc_dyn_def_trigger, "", 0);
|
||||
request->append_string(isc_dyn_def_trigger, "", 0);
|
||||
|
||||
request->append_number(isc_dyn_trg_type, (SSHORT) POST_ERASE_TRIGGER);
|
||||
|
||||
@ -3954,15 +3898,11 @@ static void define_view_trigger( dsql_req* request, dsql_nod* node, dsql_nod* rs
|
||||
|
||||
request->req_ddl_node = node;
|
||||
|
||||
const dsql_str* trigger_name = (dsql_str*) node->nod_arg[e_cnstr_name];
|
||||
dsql_nod* relation_node = NULL;
|
||||
|
||||
if (node->nod_type == nod_def_constraint)
|
||||
{
|
||||
fb_assert(trigger_name->str_length <= MAX_USHORT);
|
||||
request->append_string( isc_dyn_def_trigger,
|
||||
trigger_name->str_data,
|
||||
trigger_name->str_length);
|
||||
request->append_string(isc_dyn_def_trigger, "", 0);
|
||||
relation_node = node->nod_arg[e_cnstr_table];
|
||||
const dsql_str* relation_name = (dsql_str*) relation_node->nod_arg[e_rln_name];
|
||||
fb_assert(relation_name->str_length <= MAX_USHORT);
|
||||
@ -3975,14 +3915,9 @@ static void define_view_trigger( dsql_req* request, dsql_nod* node, dsql_nod* rs
|
||||
return;
|
||||
}
|
||||
|
||||
dsql_nod* constant = node->nod_arg[e_cnstr_position];
|
||||
if (constant)
|
||||
{
|
||||
request->append_number(isc_dyn_trg_sequence,
|
||||
(SSHORT)(IPTR) (constant ? constant->nod_arg[0] : 0));
|
||||
}
|
||||
request->append_number(isc_dyn_trg_sequence, 0);
|
||||
|
||||
constant = node->nod_arg[e_cnstr_type];
|
||||
const dsql_nod* constant = node->nod_arg[e_cnstr_type];
|
||||
USHORT trig_type;
|
||||
if (constant)
|
||||
{
|
||||
@ -3999,17 +3934,6 @@ static void define_view_trigger( dsql_req* request, dsql_nod* node, dsql_nod* rs
|
||||
|
||||
request->append_uchar(isc_dyn_sql_object);
|
||||
|
||||
const dsql_str* message = (dsql_str*) node->nod_arg[e_cnstr_message];
|
||||
if (message)
|
||||
{
|
||||
request->append_number(isc_dyn_def_trigger_msg, 0);
|
||||
fb_assert(message->str_length <= MAX_USHORT);
|
||||
request->append_string( isc_dyn_trg_msg,
|
||||
message->str_data,
|
||||
message->str_length);
|
||||
request->append_uchar(isc_dyn_end);
|
||||
}
|
||||
|
||||
// generate the trigger blr
|
||||
|
||||
if (node->nod_arg[e_cnstr_condition] && node->nod_arg[e_cnstr_actions])
|
||||
@ -4058,28 +3982,17 @@ static void define_view_trigger( dsql_req* request, dsql_nod* node, dsql_nod* rs
|
||||
temp = rse->nod_arg[e_rse_boolean];
|
||||
rse->nod_arg[e_rse_boolean] = PASS1_node(request, temp, false);
|
||||
GEN_expr(request, rse);
|
||||
|
||||
dsql_nod* condition = MAKE_node(nod_not, 1);
|
||||
condition->nod_arg[0] =
|
||||
replace_field_names(select_expr->nod_arg[e_qry_where], items,
|
||||
view_fields, false, NEW_CONTEXT);
|
||||
request->append_uchar(blr_begin);
|
||||
request->append_uchar(blr_if);
|
||||
GEN_expr(request, PASS1_node(request, condition->nod_arg[0], false));
|
||||
request->append_uchar(blr_begin);
|
||||
request->append_uchar(blr_end);
|
||||
}
|
||||
|
||||
if (trig_type == PRE_STORE_TRIGGER) {
|
||||
dsql_nod* condition = MAKE_node(nod_not, 1);
|
||||
condition->nod_arg[0] =
|
||||
replace_field_names(select_expr->nod_arg[e_qry_where], items,
|
||||
view_fields, true, NEW_CONTEXT);
|
||||
request->append_uchar(blr_if);
|
||||
GEN_expr(request, PASS1_node(request, condition->nod_arg[0], false));
|
||||
request->append_uchar(blr_begin);
|
||||
request->append_uchar(blr_end);
|
||||
}
|
||||
// generate the condition for firing the trigger
|
||||
|
||||
dsql_nod* condition =
|
||||
replace_field_names(select_expr->nod_arg[e_qry_where], items,
|
||||
view_fields, false, NEW_CONTEXT);
|
||||
request->append_uchar(blr_if);
|
||||
GEN_expr(request, PASS1_node(request, condition, false));
|
||||
request->append_uchar(blr_begin);
|
||||
request->append_uchar(blr_end);
|
||||
|
||||
// generate the action statements for the trigger
|
||||
|
||||
@ -4091,32 +4004,8 @@ static void define_view_trigger( dsql_req* request, dsql_nod* node, dsql_nod* rs
|
||||
GEN_statement(request, PASS1_statement(request, *ptr, false));
|
||||
}
|
||||
|
||||
// generate the action statements for the trigger
|
||||
request->append_uchar(blr_end); // of begin
|
||||
|
||||
actions = node->nod_arg[e_cnstr_else];
|
||||
if (actions)
|
||||
{
|
||||
request->append_uchar(blr_begin);
|
||||
dsql_nod** ptr2 = actions->nod_arg;
|
||||
for (const dsql_nod* const* const end2 = ptr2 + actions->nod_count;
|
||||
ptr2 < end2; ptr++)
|
||||
{
|
||||
dsql_nod* action_node = PASS1_statement(request, *ptr2, false);
|
||||
if (action_node->nod_type == nod_modify)
|
||||
{
|
||||
dsql_nod* temp_rse = action_node->nod_arg[e_mod_rse];
|
||||
temp_rse->nod_arg[e_rse_first] =
|
||||
MAKE_constant((dsql_str*) 1, CONSTANT_SLONG);
|
||||
}
|
||||
GEN_statement(request, action_node);
|
||||
}
|
||||
request->append_uchar(blr_end); // of begin
|
||||
}
|
||||
|
||||
request->append_uchar(blr_end); // of if
|
||||
if (trig_type == PRE_MODIFY_TRIGGER) {
|
||||
request->append_uchar(blr_end); // of for
|
||||
}
|
||||
request->end_blr();
|
||||
}
|
||||
request->append_number(isc_dyn_system_flag, fb_sysflag_view_check);
|
||||
|
@ -739,15 +739,11 @@ enum node_args {
|
||||
|
||||
e_ref_trig_action_count = 0, //
|
||||
|
||||
e_cnstr_name = 0, // nod_def_constraint
|
||||
e_cnstr_table, // NOTE: IF ADDING AN ARG IT MUST BE
|
||||
e_cnstr_type, // NULLED OUT WHEN THE NODE IS
|
||||
e_cnstr_position, // DEFINED IN parse.y
|
||||
e_cnstr_table = 0, // nod_def_constraint
|
||||
e_cnstr_type,
|
||||
e_cnstr_condition,
|
||||
e_cnstr_actions,
|
||||
e_cnstr_source,
|
||||
e_cnstr_message,
|
||||
e_cnstr_else,
|
||||
e_cnstr_count,
|
||||
|
||||
e_trg_name = 0, // nod_mod_trigger and nod_def trigger
|
||||
|
@ -7898,9 +7898,8 @@ case 159:
|
||||
{ yyval = make_node (nod_null, (int) 0, NULL); }
|
||||
break;
|
||||
case 160:
|
||||
{ yyval = make_node (nod_def_constraint,
|
||||
(int) e_cnstr_count, MAKE_string(NULL_STRING, 0), NULL,
|
||||
NULL, NULL, yyvsp[-2], NULL, yyvsp[0], NULL, NULL); }
|
||||
{ yyval = make_node (nod_def_constraint, (int) e_cnstr_count,
|
||||
NULL, NULL, yyvsp[-2], NULL, yyvsp[0]); }
|
||||
break;
|
||||
case 161:
|
||||
{ yyval = make_node (nod_def_generator, (int) e_gen_count, yyvsp[0]); }
|
||||
@ -8385,7 +8384,6 @@ case 378:
|
||||
break;
|
||||
case 379:
|
||||
{ yyval = make_node (nod_def_constraint, (int) e_cnstr_count,
|
||||
MAKE_string(NULL_STRING, 0), NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL); }
|
||||
break;
|
||||
case 380:
|
||||
|
@ -1039,9 +1039,8 @@ null_constraint : NOT KW_NULL
|
||||
;
|
||||
|
||||
check_constraint : CHECK begin_trigger '(' search_condition ')' end_trigger
|
||||
{ $$ = make_node (nod_def_constraint,
|
||||
(int) e_cnstr_count, MAKE_string(NULL_STRING, 0), NULL,
|
||||
NULL, NULL, $4, NULL, $6, NULL, NULL); }
|
||||
{ $$ = make_node (nod_def_constraint, (int) e_cnstr_count,
|
||||
NULL, NULL, $4, NULL, $6); }
|
||||
;
|
||||
|
||||
|
||||
@ -1871,7 +1870,6 @@ end_trigger :
|
||||
|
||||
check_opt : WITH CHECK OPTION
|
||||
{ $$ = make_node (nod_def_constraint, (int) e_cnstr_count,
|
||||
MAKE_string(NULL_STRING, 0), NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL); }
|
||||
|
|
||||
{ $$ = 0; }
|
||||
|
Loading…
Reference in New Issue
Block a user