From: Claudio V. C. <ro...@us...> - 2001-06-29 08:42:32
|
Update of /cvsroot/firebird/interbase/dsql In directory usw-pr-cvs1:/tmp/cvs-serv24964 Modified Files: ddl.c dsql.c gen.c pass1.c Log Message: no message Index: ddl.c =================================================================== RCS file: /cvsroot/firebird/interbase/dsql/ddl.c,v retrieving revision 1.7 retrieving revision 1.8 diff -U3 -r1.7 -r1.8 --- ddl.c 2001/06/26 07:54:53 1.7 +++ ddl.c 2001/06/29 08:42:29 1.8 @@ -29,6 +29,14 @@ * accident and vice-versa. * 2001.5.30 Claudio Valderrama: alter column should use 1..N for the * position argument since the call comes from SQL DDL. + * 2001.6.27 Claudio Valderrama: DDL_resolve_intl_type() was adding 2 to the + * length of varchars instead of just checking that len+2<=MAX_COLUMN_SIZE. + * It required a minor change to put_field() where it was decremented, too. + * 2001.6.27 Claudio Valderrama: Finally stop users from invoking the same option + * several times when altering a domain. Specially dangerous with text data types. + * Ex: alter domain d type char(5) type varchar(5) default 'x' default 'y'; + * Bear in mind that if DYN functions are addressed directly, this protection + * becomes a moot point. */ #include "../jrd/ib_stdio.h" @@ -56,6 +64,7 @@ static void begin_blr (REQ, UCHAR); static USHORT check_array_or_blob (NOD); static void check_constraint (REQ, NOD, SSHORT); +static void check_one_call (BOOLEAN *, SSHORT, TEXT *); static void create_view_triggers (REQ, NOD, NOD); static void define_computed (REQ, NOD, FLD, NOD); static void define_constraint_trigger (REQ, NOD); @@ -369,7 +378,6 @@ INTLSYM resolved_collation; STR dfl_charset; SSHORT blob_sub_type; -ULONG field_length; if ((field->fld_dtype > dtype_any_text) && field->fld_dtype != dtype_blob) { @@ -432,7 +440,7 @@ if (dfl_charset = METD_get_default_charset (request)) { - field->fld_character_set = (NOD) dfl_charset; + field->fld_character_set = (NOD) dfl_charset; } else { @@ -441,20 +449,24 @@ */ if (field->fld_character_length) { - field_length = field->fld_character_length; - if (field->fld_dtype == dtype_varying) - field_length += sizeof (USHORT); - if (field_length > (ULONG) MAX_COLUMN_SIZE) - ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -204, - gds_arg_gds, gds__dsql_datatype_err, - gds_arg_gds, gds__imp_exc, - gds_arg_gds, gds__field_name, gds_arg_string, field->fld_name, - 0); - field->fld_length = (USHORT) field_length; + ULONG field_length = field->fld_character_length, extra_len = 0; + /* CVC: Can't understand why some developer added to the size. This is a + low level difference that only matters EXE, CVT, MOV, VIO and the like. + Now the comparison is done without altering the field's length itself. */ + if (field->fld_dtype == dtype_varying) + extra_len = sizeof (USHORT); + /* field_length += sizeof (USHORT); */ + if (field_length + extra_len > (ULONG) MAX_COLUMN_SIZE) + ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -204, + gds_arg_gds, gds__dsql_datatype_err, + gds_arg_gds, gds__imp_exc, + gds_arg_gds, gds__field_name, gds_arg_string, field->fld_name, + 0); + field->fld_length = (USHORT) field_length; }; field->fld_ttype = 0; - if (!collation_name) - return; + if (!collation_name) + return; } } @@ -509,20 +521,23 @@ if (field->fld_character_length) - { - field_length = (ULONG) resolved_type->intlsym_bytes_per_char * - field->fld_character_length; +{ + ULONG field_length = (ULONG) resolved_type->intlsym_bytes_per_char * + field->fld_character_length, extra_len = 0; + /* CVC: Same error again: the size of the length indicator shouldn't be + made a permanent addition to the field's length. */ if (field->fld_dtype == dtype_varying) - field_length += sizeof (USHORT); - if (field_length > (ULONG) MAX_COLUMN_SIZE) + extra_len = sizeof (USHORT); + /* field_length += sizeof (USHORT); */ + if (field_length + extra_len > (ULONG) MAX_COLUMN_SIZE) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -204, gds_arg_gds, gds__dsql_datatype_err, gds_arg_gds, gds__imp_exc, gds_arg_gds, gds__field_name, gds_arg_string, field->fld_name, 0); field->fld_length = (USHORT) field_length; - }; +}; field->fld_ttype = resolved_type->intlsym_ttype; field->fld_character_set_id = resolved_type->intlsym_charset_id; @@ -725,13 +740,36 @@ STUFF (gds__dyn_end); /* For CHECK constraint definition */ } - + +static void check_one_call ( + BOOLEAN *repetition_count, + SSHORT pos, + TEXT *error_msg) +{ +/************************************** + * + * c h e c k _ o n e _ c a l l + * + ************************************** + * + * Function + * Ensure that each option in modify_domain() is called only once. + * This restriction cannot be enforced by the DSQL parser. + * + **************************************/ + if (++repetition_count [pos] > 1) + ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -637, + gds_arg_gds, gds__dsql_duplicate_spec, + gds_arg_string, error_msg, + 0); +} + static void create_view_triggers ( REQ request, NOD element, NOD items) /* Fields in the VIEW actually */ { -/* ************************************* +/************************************** * * c r e a t e _ v i e w _ t r i g g e r s * @@ -3590,7 +3628,7 @@ make_index_trg_ref_int (request, element, columns1, element->nod_arg [e_for_refcolumns], relation2->str_data); } - + static void generate_dyn ( REQ request, NOD node) @@ -3609,160 +3647,160 @@ STR string; request->req_ddl_node = node; - -switch (node->nod_type) - { - case nod_def_domain: - define_domain (request); - break; - - case nod_mod_domain: - modify_domain (request); - break; - - case nod_def_index: - define_index (request); - break; - case nod_def_relation: - define_relation (request); - break; - - case nod_def_view: - define_view (request); - break; - - case nod_def_exception: - case nod_mod_exception: - case nod_del_exception: - define_exception (request, node->nod_type); - break; - - case nod_def_procedure: - case nod_mod_procedure: - define_procedure (request, node->nod_type); - break; - - case nod_def_constraint: - define_constraint_trigger (request, node); - break; - - case nod_def_trigger: - case nod_mod_trigger: - define_trigger (request, node); - break; - - case nod_mod_relation: - modify_relation (request); - break; - - case nod_del_domain: - string = (STR) node->nod_arg [0]; - put_cstring (request, gds__dyn_delete_global_fld, string->str_data); - STUFF (gds__dyn_end); - break; - - case nod_del_index: - string = (STR) node->nod_arg [0]; - put_cstring (request, gds__dyn_delete_idx, string->str_data); - STUFF (gds__dyn_end); - break; - + switch (node->nod_type) + { + case nod_def_domain: + define_domain (request); + break; + + case nod_mod_domain: + modify_domain (request); + break; + + case nod_def_index: + define_index (request); + break; + + case nod_def_relation: + define_relation (request); + break; + + case nod_def_view: + define_view (request); + break; + + case nod_def_exception: + case nod_mod_exception: + case nod_del_exception: + define_exception (request, node->nod_type); + break; + + case nod_def_procedure: + case nod_mod_procedure: + define_procedure (request, node->nod_type); + break; + + case nod_def_constraint: + define_constraint_trigger (request, node); + break; + + case nod_def_trigger: + case nod_mod_trigger: + define_trigger (request, node); + break; + + case nod_mod_relation: + modify_relation (request); + break; + + case nod_del_domain: + string = (STR) node->nod_arg [0]; + put_cstring (request, gds__dyn_delete_global_fld, string->str_data); + STUFF (gds__dyn_end); + break; + + case nod_del_index: + string = (STR) node->nod_arg [0]; + put_cstring (request, gds__dyn_delete_idx, string->str_data); + STUFF (gds__dyn_end); + break; + /* CVC: Handling drop table and drop view properly. */ - case nod_del_relation: + case nod_del_relation: case nod_del_view: delete_relation_view (request, node); - break; - - case nod_del_procedure: - string = (STR) node->nod_arg [0]; - put_cstring (request, gds__dyn_delete_procedure, string->str_data); - STUFF (gds__dyn_end); - break; - - case nod_del_trigger: - string = (STR) node->nod_arg [0]; - put_cstring (request, gds__dyn_delete_trigger, string->str_data); - STUFF (gds__dyn_end); - break; - - case nod_del_role: - string = (STR) node->nod_arg [0]; - put_cstring (request, isc_dyn_del_sql_role, string->str_data); - STUFF (gds__dyn_end); - break; - - case nod_grant: - case nod_revoke: - grant_revoke (request); - break; - - case nod_def_generator: - define_generator (request); - break; - - case nod_def_role: - define_role (request); - break; - - case nod_def_filter: - define_filter (request); - break; - - case nod_del_generator: - string = (STR) node->nod_arg [0]; - /**********FIX -- nothing like delete_generator exists as yet - put_cstring (request, gds__dyn_def_generator, string->str_data); - STUFF (gds__dyn_end); */ - break; - - case nod_del_filter: - string = (STR) node->nod_arg [0]; - put_cstring (request, gds__dyn_delete_filter, string->str_data); - STUFF (gds__dyn_end); - break; - - case nod_def_udf: - define_udf (request); - break; - - case nod_del_udf: - string = (STR) node->nod_arg [0]; - put_cstring (request, gds__dyn_delete_function, string->str_data); - STUFF (gds__dyn_end); - break; - - case nod_def_shadow: - define_shadow (request); - break; - - case nod_del_shadow: - put_number (request, gds__dyn_delete_shadow, + break; + + case nod_del_procedure: + string = (STR) node->nod_arg [0]; + put_cstring (request, gds__dyn_delete_procedure, string->str_data); + STUFF (gds__dyn_end); + break; + + case nod_del_trigger: + string = (STR) node->nod_arg [0]; + put_cstring (request, gds__dyn_delete_trigger, string->str_data); + STUFF (gds__dyn_end); + break; + + case nod_del_role: + string = (STR) node->nod_arg [0]; + put_cstring (request, isc_dyn_del_sql_role, string->str_data); + STUFF (gds__dyn_end); + break; + + case nod_grant: + case nod_revoke: + grant_revoke (request); + break; + + case nod_def_generator: + define_generator (request); + break; + + case nod_def_role: + define_role (request); + break; + + case nod_def_filter: + define_filter (request); + break; + + case nod_del_generator: + string = (STR) node->nod_arg [0]; + /**********FIX -- nothing like delete_generator exists as yet + put_cstring (request, gds__dyn_def_generator, string->str_data); + STUFF (gds__dyn_end); */ + break; + + case nod_del_filter: + string = (STR) node->nod_arg [0]; + put_cstring (request, gds__dyn_delete_filter, string->str_data); + STUFF (gds__dyn_end); + break; + + case nod_def_udf: + define_udf (request); + break; + + case nod_del_udf: + string = (STR) node->nod_arg [0]; + put_cstring (request, gds__dyn_delete_function, string->str_data); + STUFF (gds__dyn_end); + break; + + case nod_def_shadow: + define_shadow (request); + break; + + case nod_del_shadow: + put_number (request, gds__dyn_delete_shadow, (SSHORT) (node->nod_arg[0])); - STUFF (gds__dyn_end); - break; - - case nod_mod_database: - modify_database (request); - break; - - case nod_def_database: - define_database (request); - break; - - case nod_mod_index: - modify_index (request); - break; - - case nod_set_statistics: - set_statistics (request); - break; - + STUFF (gds__dyn_end); + break; + + case nod_mod_database: + modify_database (request); + break; + + case nod_def_database: + define_database (request); + break; + + case nod_mod_index: + modify_index (request); + break; + + case nod_set_statistics: + set_statistics (request); + break; + default: break; } } - + static void grant_revoke ( REQ request) { @@ -4190,6 +4228,9 @@ STR string, domain_name; FLD field; struct fld local_field; +/* CVC: This array used with check_one_call to ensure each modification option +is called only once. Enlarge it if the switch() below gets more cases. */ +BOOLEAN repetition_count [6]; ddl_node = request->req_ddl_node; @@ -4198,6 +4239,15 @@ put_cstring (request, gds__dyn_mod_global_fld, domain_name->str_data); +{ + /* Is MOVE_CLEAR enough for all platforms? + MOVE_CLEAR (repetition_count, sizeof (repetition_count)); */ + USHORT rtop = sizeof (repetition_count) / sizeof (repetition_count [0]); + BOOLEAN *p = repetition_count; + while (p < repetition_count + rtop) + *p++ = 0; +} + ops = ddl_node->nod_arg [e_alt_dom_ops]; for (ptr = ops->nod_arg, end = ptr + ops->nod_count; ptr < end; ptr++) { @@ -4205,91 +4255,97 @@ switch (element->nod_type) { case nod_def_default: - /* CVC: So do you want to crash me with ALTER DOMAIN dom SET; ??? */ - if (!element->nod_arg[e_dft_default]) - { - ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, + check_one_call (repetition_count, 0, "DOMAIN DEFAULT"); + /* CVC: So do you want to crash me with ALTER DOMAIN dom SET; ??? */ + if (!element->nod_arg[e_dft_default]) + { + ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__command_end_err, /* Unexpected end of command */ 0); - } - /* CVC End modification. */ - element->nod_arg[e_dft_default] = PASS1_node (request, element->nod_arg[e_dft_default],0); - begin_blr (request, gds__dyn_fld_default_value); - GEN_expr (request, element->nod_arg[e_dft_default]); - end_blr (request); - if ((string = (STR) element->nod_arg [e_dft_default_source]) != NULL) - { - assert(string->str_length <= MAX_USHORT); - put_string (request, gds__dyn_fld_default_source, string->str_data, - (USHORT)string->str_length); - } - break; - + } + /* CVC End modification. */ + element->nod_arg[e_dft_default] = PASS1_node (request, element->nod_arg[e_dft_default],0); + begin_blr (request, gds__dyn_fld_default_value); + GEN_expr (request, element->nod_arg[e_dft_default]); + end_blr (request); + if ((string = (STR) element->nod_arg [e_dft_default_source]) != NULL) + { + assert(string->str_length <= MAX_USHORT); + put_string (request, gds__dyn_fld_default_source, string->str_data, + (USHORT)string->str_length); + } + break; + case nod_def_constraint: - STUFF (gds__dyn_single_validation); - begin_blr (request, gds__dyn_fld_validation_blr); - - /* Get the attributes of the domain, and set any occurances of + check_one_call (repetition_count, 1, "DOMAIN CONSTRAINT"); + STUFF (gds__dyn_single_validation); + begin_blr (request, gds__dyn_fld_validation_blr); + + /* Get the attributes of the domain, and set any occurances of nod_dom_value (corresponding to the keyword VALUE) to the correct type, length, scale, etc. */ - if (! METD_get_domain (request, &local_field, - domain_name->str_data)) - ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -607, - gds_arg_gds, gds__dsql_command_err, - gds_arg_gds, gds__dsql_domain_not_found, - gds_arg_string, ERR_cstring (domain_name->str_data), - /* Specified domain or source field does not exist */ - 0); - if(element->nod_arg [e_cnstr_condition]) - set_nod_value_attributes (element->nod_arg [e_cnstr_condition], - &local_field); - - /* Increment the context level for this request, so that - the context number for any RSE generated for a SELECT - within the CHECK clause will be greater than 0. In the - environment of a domain check constraint, context - number 0 is reserved for the "blr_fid, 0, 0,0," which - is emitted for a nod_dom_value, corresponding to an - occurance of the VALUE keyword in the body of the check + if (! METD_get_domain (request, &local_field, + domain_name->str_data)) + ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -607, + gds_arg_gds, gds__dsql_command_err, + gds_arg_gds, gds__dsql_domain_not_found, + gds_arg_string, ERR_cstring (domain_name->str_data), + /* Specified domain or source field does not exist */ + 0); + if(element->nod_arg [e_cnstr_condition]) + set_nod_value_attributes (element->nod_arg [e_cnstr_condition], + &local_field); + + /* Increment the context level for this request, so that + the context number for any RSE generated for a SELECT + within the CHECK clause will be greater than 0. In the + environment of a domain check constraint, context + number 0 is reserved for the "blr_fid, 0, 0,0," which + is emitted for a nod_dom_value, corresponding to an + occurance of the VALUE keyword in the body of the check constraint. -- chrisj 1999-08-20 */ - - request->req_context_number++; - - GEN_expr (request, + + request->req_context_number++; + + GEN_expr (request, PASS1_node (request, element->nod_arg [e_cnstr_condition], 0)); - - end_blr (request); - if ((string = (STR) element->nod_arg [e_cnstr_source]) != NULL) - { - assert(string->str_length <= MAX_USHORT); - put_string (request, gds__dyn_fld_validation_source, - string->str_data, (USHORT)string->str_length); - } - break; - + + end_blr (request); + if ((string = (STR) element->nod_arg [e_cnstr_source]) != NULL) + { + assert(string->str_length <= MAX_USHORT); + put_string (request, gds__dyn_fld_validation_source, + string->str_data, (USHORT)string->str_length); + } + break; + case nod_mod_domain_type: - field = (FLD) element->nod_arg[e_mod_dom_new_dom_type]; - DDL_resolve_intl_type (request, field, NULL); - put_field (request, field, FALSE); - break; - + check_one_call (repetition_count, 2, "DOMAIN DATA TYPE"); + field = (FLD) element->nod_arg[e_mod_dom_new_dom_type]; + DDL_resolve_intl_type (request, field, NULL); + put_field (request, field, FALSE); + break; + case nod_field_name: - { - STR new_dom_name; - - new_dom_name = (STR) element->nod_arg [e_fln_name]; - put_cstring (request, gds__dyn_fld_name, new_dom_name->str_data); - break; - } - + check_one_call (repetition_count, 3, "DOMAIN NAME"); + { + STR new_dom_name; + + new_dom_name = (STR) element->nod_arg [e_fln_name]; + put_cstring (request, gds__dyn_fld_name, new_dom_name->str_data); + break; + } + case nod_delete_rel_constraint: - STUFF (gds__dyn_del_validation); - break; - + check_one_call (repetition_count, 4, "DOMAIN DROP CONSTRAINT"); + STUFF (gds__dyn_del_validation); + break; + case nod_del_default: - STUFF (gds__dyn_del_default); - break; - + check_one_call (repetition_count, 5, "DOMAIN DROP DEFAULT"); + STUFF (gds__dyn_del_default); + break; + default: break; } @@ -4782,52 +4838,57 @@ put_number (request, gds__dyn_fld_type, blr_dtypes [field->fld_dtype]); if (field->fld_dtype == dtype_blob) - { +{ put_number (request, gds__dyn_fld_sub_type, field->fld_sub_type); put_number (request, gds__dyn_fld_scale, 0); if (!udf_flag) { - if (!field->fld_seg_length) - field->fld_seg_length = DEFAULT_BLOB_SEGMENT_SIZE; - put_number (request, gds__dyn_fld_segment_length, field->fld_seg_length); + if (!field->fld_seg_length) + field->fld_seg_length = DEFAULT_BLOB_SEGMENT_SIZE; + put_number (request, gds__dyn_fld_segment_length, field->fld_seg_length); } if (!(request->req_dbb->dbb_flags & DBB_v3)) if (field->fld_sub_type == BLOB_text) put_number (request, gds__dyn_fld_character_set, field->fld_character_set_id); - } +} else if (field->fld_dtype <= dtype_any_text) - { +{ if (field->fld_sub_type) put_number (request, gds__dyn_fld_sub_type, field->fld_sub_type); put_number (request, gds__dyn_fld_scale, 0); if (field->fld_dtype == dtype_varying) { - assert((field->fld_length - sizeof (USHORT)) <= MAX_SSHORT); - put_number (request, gds__dyn_fld_length, (SSHORT)(field->fld_length - sizeof (USHORT))); + /* CVC: Fix the assertion and the field length. It's no longer growth + by DDL_resolve_intl_type(), so nothing to decrement here. + Anyway, the assertion was flawed when run against the old code, too. + Here comes the compensation for DDL_resolve_intl_type(), since the field + length itself wasn't altered if it's varying. */ + assert((field->fld_length + sizeof (USHORT)) <= MAX_SSHORT); + put_number (request, gds__dyn_fld_length, (SSHORT)(field->fld_length /* - sizeof (USHORT)*/)); } else put_number (request, gds__dyn_fld_length, field->fld_length); if (!(request->req_dbb->dbb_flags & DBB_v3)) { - put_number (request, gds__dyn_fld_char_length, field->fld_character_length); - put_number (request, gds__dyn_fld_character_set, field->fld_character_set_id); - if (!udf_flag) - put_number (request, gds__dyn_fld_collation, field->fld_collation_id); + put_number (request, gds__dyn_fld_char_length, field->fld_character_length); + put_number (request, gds__dyn_fld_character_set, field->fld_character_set_id); + if (!udf_flag) + put_number (request, gds__dyn_fld_collation, field->fld_collation_id); } - } +} else - { +{ put_number (request, gds__dyn_fld_scale, field->fld_scale); put_number (request, gds__dyn_fld_length, field->fld_length); if (DTYPE_IS_EXACT(field->fld_dtype)) { - put_number (request, isc_dyn_fld_precision, field->fld_precision); - if (field->fld_sub_type) - put_number (request, isc_dyn_fld_sub_type, field->fld_sub_type); + put_number (request, isc_dyn_fld_precision, field->fld_precision); + if (field->fld_sub_type) + put_number (request, isc_dyn_fld_sub_type, field->fld_sub_type); } - } } - +} + static void put_local_variable ( REQ request, VAR variable) Index: dsql.c =================================================================== RCS file: /cvsroot/firebird/interbase/dsql/dsql.c,v retrieving revision 1.5 retrieving revision 1.6 diff -U3 -r1.5 -r1.6 --- dsql.c 2001/06/26 07:54:53 1.5 +++ dsql.c 2001/06/29 08:42:29 1.6 @@ -19,6 +19,9 @@ * * All Rights Reserved. * Contributor(s): ______________________________________. + * 2001.6.3 Claudio Valderrama: fixed a bad behaved loop in get_plan_info() + * and get_rsb_item() that caused a crash when plan info was requested. + * 2001.6.9 Claudio Valderrama: Added nod_del_view, nod_current_role and nod_breakleave. */ /* $Id$ @@ -2648,6 +2651,7 @@ if (get_rsb_item (&explain_length, &explain, &plan_length, &plan, &join_count, level_ptr)) return FAILURE; + /* CVC: Here's the additional stop condition. */ if (!*level_ptr) break; } Index: gen.c =================================================================== RCS file: /cvsroot/firebird/interbase/dsql/gen.c,v retrieving revision 1.6 retrieving revision 1.7 diff -U3 -r1.6 -r1.7 --- gen.c 2001/06/26 07:54:54 1.6 +++ gen.c 2001/06/29 08:42:29 1.7 @@ -2029,89 +2029,89 @@ list = rse->nod_arg [e_rse_items]; for (ptr = list->nod_arg, end = ptr + list->nod_count; ptr < end; ptr++) - { +{ item = *ptr; parameter = MAKE_parameter (request->req_receive, TRUE, TRUE); parameter->par_node = item; MAKE_desc (¶meter->par_desc, item); if (item->nod_type == nod_field) { - field = (FLD) item->nod_arg [e_fld_field]; - parameter->par_name = parameter->par_alias = field->fld_name; - context = (CTX) item->nod_arg [e_fld_context]; - if (context->ctx_relation) - { - parameter->par_rel_name = context->ctx_relation->rel_name; - parameter->par_owner_name = context->ctx_relation->rel_owner; - } - else if (context->ctx_procedure) - { - parameter->par_rel_name = context->ctx_procedure->prc_name; - parameter->par_owner_name = context->ctx_procedure->prc_owner; - } + field = (FLD) item->nod_arg [e_fld_field]; + parameter->par_name = parameter->par_alias = field->fld_name; + context = (CTX) item->nod_arg [e_fld_context]; + if (context->ctx_relation) + { + parameter->par_rel_name = context->ctx_relation->rel_name; + parameter->par_owner_name = context->ctx_relation->rel_owner; + } + else if (context->ctx_procedure) + { + parameter->par_rel_name = context->ctx_procedure->prc_name; + parameter->par_owner_name = context->ctx_procedure->prc_owner; + } } else if (item->nod_type == nod_dbkey) { - parameter->par_name = parameter->par_alias = db_key_name; - context = (CTX) item->nod_arg [0]->nod_arg [0]; - parameter->par_rel_name = context->ctx_relation->rel_name; - parameter->par_owner_name = context->ctx_relation->rel_owner; + parameter->par_name = parameter->par_alias = db_key_name; + context = (CTX) item->nod_arg [0]->nod_arg [0]; + parameter->par_rel_name = context->ctx_relation->rel_name; + parameter->par_owner_name = context->ctx_relation->rel_owner; } else if (item->nod_type == nod_alias) { - string = (STR) item->nod_arg [e_alias_alias]; - parameter->par_alias = (TEXT*) string->str_data; - alias = item->nod_arg [e_alias_value]; - if (alias->nod_type == nod_field) - { - field = (FLD) alias->nod_arg [e_fld_field]; - parameter->par_name = field->fld_name; - context = (CTX) alias->nod_arg [e_fld_context]; - if (context->ctx_relation) + string = (STR) item->nod_arg [e_alias_alias]; + parameter->par_alias = (TEXT*) string->str_data; + alias = item->nod_arg [e_alias_value]; + if (alias->nod_type == nod_field) { - parameter->par_rel_name = context->ctx_relation->rel_name; - parameter->par_owner_name = context->ctx_relation->rel_owner; + field = (FLD) alias->nod_arg [e_fld_field]; + parameter->par_name = field->fld_name; + context = (CTX) alias->nod_arg [e_fld_context]; + if (context->ctx_relation) + { + parameter->par_rel_name = context->ctx_relation->rel_name; + parameter->par_owner_name = context->ctx_relation->rel_owner; + } + else if (context->ctx_procedure) + { + parameter->par_rel_name = context->ctx_procedure->prc_name; + parameter->par_owner_name = context->ctx_procedure->prc_owner; + } } - else if (context->ctx_procedure) + else if (alias->nod_type == nod_dbkey) { - parameter->par_rel_name = context->ctx_procedure->prc_name; - parameter->par_owner_name = context->ctx_procedure->prc_owner; + parameter->par_name = db_key_name; + context = (CTX) alias->nod_arg [0]->nod_arg[0]; + parameter->par_rel_name = context->ctx_relation->rel_name; + parameter->par_owner_name = context->ctx_relation->rel_owner; } - } - else if (alias->nod_type == nod_dbkey) - { - parameter->par_name = db_key_name; - context = (CTX) alias->nod_arg [0]->nod_arg[0]; - parameter->par_rel_name = context->ctx_relation->rel_name; - parameter->par_owner_name = context->ctx_relation->rel_owner; - } } else if (item->nod_type == nod_map) { map = (MAP) item->nod_arg [e_map_map]; map_node = map->map_node; while (map_node->nod_type == nod_map) - { - /* skip all the nod_map nodes */ - map = (MAP) map_node->nod_arg [e_map_map]; - map_node = map->map_node; - } + { + /* skip all the nod_map nodes */ + map = (MAP) map_node->nod_arg [e_map_map]; + map_node = map->map_node; + } if (map_node->nod_type == nod_field) - { - field = (FLD) map_node->nod_arg [e_fld_field]; - parameter->par_name = parameter->par_alias = field->fld_name; - } + { + field = (FLD) map_node->nod_arg [e_fld_field]; + parameter->par_name = parameter->par_alias = field->fld_name; + } else if (map_node->nod_type == nod_alias) - { - string = (STR) map_node->nod_arg [e_alias_alias]; - parameter->par_alias = (TEXT*) string->str_data; - alias = map_node->nod_arg [e_alias_value]; - if (alias->nod_type == nod_field) + { + string = (STR) map_node->nod_arg [e_alias_alias]; + parameter->par_alias = (TEXT*) string->str_data; + alias = map_node->nod_arg [e_alias_value]; + if (alias->nod_type == nod_field) { - field = (FLD) alias->nod_arg [e_fld_field]; - parameter->par_name = field->fld_name; + field = (FLD) alias->nod_arg [e_fld_field]; + parameter->par_name = field->fld_name; } - } + } else if (map_node->nod_type == nod_agg_count) parameter->par_name = parameter->par_alias = "COUNT"; else if (map_node->nod_type == nod_agg_total) @@ -2129,25 +2129,28 @@ } else if (item->nod_type == nod_udf) { - udf = (UDF) item->nod_arg [0]; - parameter->par_name = parameter->par_alias = udf->udf_name; + udf = (UDF) item->nod_arg [0]; + parameter->par_name = parameter->par_alias = udf->udf_name; } else if (item->nod_type == nod_gen_id) - parameter->par_name = parameter->par_alias = "GEN_ID"; + parameter->par_name = parameter->par_alias = "GEN_ID"; else if (item->nod_type == nod_gen_id2) - parameter->par_name = parameter->par_alias = "GEN_ID"; + parameter->par_name = parameter->par_alias = "GEN_ID"; else if (item->nod_type == nod_user_name) - parameter->par_name = parameter->par_alias = "USER"; + parameter->par_name = parameter->par_alias = "USER"; else if (item->nod_type == nod_current_role) - parameter->par_name = parameter->par_alias = "ROLE"; + parameter->par_name = parameter->par_alias = "ROLE"; else if (item->nod_type == nod_substr) - { + { /* CVC: SQL starts at 1 but C starts at zero. */ NOD node = item->nod_arg [e_substr_start]; --(*(SLONG *) (node->nod_desc.dsc_address)); parameter->par_name = parameter->par_alias = "SUBSTRING"; - } - } /* for */ + } + else if (item->nod_type == nod_cast) + parameter->par_name = parameter->par_alias = "CAST"; +} /* for */ + /* Set up parameter to handle EOF */ Index: pass1.c =================================================================== RCS file: /cvsroot/firebird/interbase/dsql/pass1.c,v retrieving revision 1.5 retrieving revision 1.6 diff -U3 -r1.5 -r1.6 --- pass1.c 2001/06/26 07:54:54 1.5 +++ pass1.c 2001/06/29 08:42:29 1.6 @@ -26,6 +26,8 @@ * and index names in plans. * 2001.5.29: Claudio Valderrama: handle DROP VIEW case in pass1_statement(). * 2001.6.12: Claudio Valderrama: add basic BREAK capability to procedures. + * 2001.6.27: Claudio Valderrama: pass1_variable() now gives the name of the + * variable it can't find in the error message. */ #include "../jrd/ib_stdio.h" @@ -3793,7 +3795,7 @@ LLS_POP (&request->req_context); return node; } - + static NOD pass1_variable ( REQ request, NOD input) @@ -3809,7 +3811,7 @@ * **************************************/ NOD procedure_node, var_nodes, var_node, *ptr, *end; -STR var_name; +STR var_name = 0; VAR var; SSHORT position; @@ -3882,11 +3884,14 @@ /* field unresolved */ -field_error (NULL_PTR, NULL_PTR); +/* CVC: That's all [the fix], folks! */ +if (var_name) + field_error (NULL_PTR, (TEXT *) var_name->str_data); +else field_error (NULL_PTR, NULL_PTR); return NULL; } - + static NOD post_map ( NOD node, CTX context) |