/* * PROGRAM: JRD Data Definition Utility * MODULE: trn.c * DESCRIPTION: Translate meta-data change to dynamic meta data * * The contents of this file are subject to the Interbase Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy * of the License at http://www.Inprise.com/IPL.html * * Software distributed under the License is distributed on an * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express * or implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code was created by Inprise Corporation * and its predecessors. Portions created by Inprise Corporation are * Copyright (C) Inprise Corporation. * * All Rights Reserved. * Contributor(s): ______________________________________. */ #include "firebird.h" #include "../jrd/ib_stdio.h" #include #include "../jrd/gds.h" #include "../dudley/ddl.h" #include "../jrd/license.h" #include "../dudley/gener_proto.h" #include "../dudley/lex_proto.h" #include "../dudley/trn_proto.h" #include "../gpre/prett_proto.h" #include "../jrd/gds_proto.h" #include "../jrd/gdsassert.h" static void add_dimensions(STR, DUDLEY_FLD); static void add_field(STR, DUDLEY_FLD, DUDLEY_REL); static void add_files(STR, FIL, DBB); static void add_filter(STR, FILTER); static void add_function(STR, FUNC); static void add_function_arg(STR, FUNCARG); static void add_generator(STR, SYM); static void add_global_field(STR, DUDLEY_FLD); static void add_index(STR, DUDLEY_IDX); static void add_relation(STR, DUDLEY_REL); static void add_security_class(STR, SCL); static void add_trigger(STR, DUDLEY_TRG); static void add_trigger_msg(STR, TRGMSG); static void add_view(STR, DUDLEY_REL); static void drop_field(STR, DUDLEY_FLD); static void drop_filter(STR, FILTER); static void drop_function(STR, FUNC); static void drop_global_field(STR, DUDLEY_FLD); static void drop_index(STR, DUDLEY_IDX); static void drop_relation(STR, DUDLEY_REL); static void drop_security_class(STR, SCL); static void drop_shadow(STR, SLONG); static void drop_trigger(STR, DUDLEY_TRG); static void drop_trigger_msg(STR, TRGMSG); static int gen_dyn_c(int *, int, SCHAR *); static int gen_dyn_cxx(int *, int, SCHAR *); static int gen_dyn_pas(int *, int, SCHAR *); static void modify_database(STR, DBB); static void modify_field(STR, DUDLEY_FLD, DUDLEY_REL); static void modify_global_field(STR, DUDLEY_FLD); static void modify_index(STR, DUDLEY_IDX); static void modify_relation(STR, DUDLEY_REL); static void modify_trigger(STR, DUDLEY_TRG); static void modify_trigger_msg(STR, TRGMSG); static void put_acl(STR, UCHAR, SCL); static void put_blr(STR, UCHAR, DUDLEY_REL, DUDLEY_NOD); static void put_number(STR, TEXT, SSHORT); static void put_query_header(STR, TEXT, DUDLEY_NOD); static void put_symbol(STR, TEXT, SYM); static void put_text(STR, UCHAR, TXT); static void raw_ada(STR); static void raw_basic(STR); static void raw_cobol(STR); static void raw_ftn(STR); static void raw_pli(STR); static IB_FILE *output_file; #define STUFF(c) *dyn->str_current++ = c #define STUFF_WORD(c) {STUFF (c); STUFF (c >> 8);} #define CHECK_DYN(l) {if ( !(dyn->str_current - dyn->str_start + l <= \ dyn->str_length) && !TRN_get_buffer (dyn, l) ) \ DDL_error_abort ( NULL, 320, NULL, NULL, \ NULL, NULL, NULL );} #ifndef FOPEN_WRITE_TYPE #define FOPEN_WRITE_TYPE "w" #endif void TRN_translate(void) { /************************************** * * T R N _ t r a n s l a t e * ************************************** * * Functional description * Translate from internal data structures into dynamic DDL. * **************************************/ ACT action; USHORT length; struct str d, *dyn; /* Start by reversing the set of actions */ dyn = &d; dyn->str_current = dyn->str_start = (SCHAR *) gds__alloc((SLONG) 8192); dyn->str_length = 8192; #ifdef DEBUG_GDS_ALLOC /* For V4.0 we don't care about Gdef specific memory leaks */ gds_alloc_flag_unfreed(dyn->str_start); #endif if (!DYN_file_name[0]) output_file = ib_stdout; else if (!(output_file = ib_fopen(DYN_file_name, FOPEN_WRITE_TYPE))) { DDL_msg_put(281, DYN_file_name, NULL, NULL, NULL, NULL); /* msg 281: gdef: can't open DYN output file: %s */ DDL_exit(FINI_ERROR); } CHECK_DYN(2); STUFF(gds_dyn_version_1); STUFF(gds_dyn_begin); for (action = DDL_actions; action; action = action->act_next) if (!(action->act_flags & ACT_ignore)) switch (action->act_type) { case act_c_database: case act_m_database: modify_database(dyn, action->act_object); break; case act_a_relation: add_relation(dyn, (DUDLEY_REL) action->act_object); break; case act_m_relation: modify_relation(dyn, (DUDLEY_REL) action->act_object); break; case act_d_relation: drop_relation(dyn, (DUDLEY_REL) action->act_object); break; case act_a_field: add_field(dyn, (DUDLEY_FLD) action->act_object, NULL); break; case act_m_field: modify_field(dyn, (DUDLEY_FLD) action->act_object, NULL); break; case act_d_field: drop_field(dyn, (DUDLEY_FLD) action->act_object); break; case act_a_filter: add_filter(dyn, (FILTER) action->act_object); break; case act_d_filter: drop_filter(dyn, (FILTER) action->act_object); break; case act_a_function: add_function(dyn, (FUNC) action->act_object); break; case act_a_function_arg: add_function_arg(dyn, (FUNCARG) action->act_object); break; case act_d_function: drop_function(dyn, (FUNC) action->act_object); break; case act_a_generator: add_generator(dyn, (SYM) action->act_object); break; case act_a_gfield: add_global_field(dyn, (DUDLEY_FLD) action->act_object); break; case act_m_gfield: modify_global_field(dyn, (DUDLEY_FLD) action->act_object); break; case act_d_gfield: drop_global_field(dyn, (DUDLEY_FLD) action->act_object); break; case act_a_index: add_index(dyn, (DUDLEY_IDX)action->act_object); break; case act_m_index: modify_index(dyn, (DUDLEY_IDX)action->act_object); break; case act_d_index: drop_index(dyn, (DUDLEY_IDX)action->act_object); break; case act_a_security: add_security_class(dyn, (SCL) action->act_object); break; case act_d_security: drop_security_class(dyn, (SCL) action->act_object); break; case act_a_trigger: add_trigger(dyn, (DUDLEY_TRG) action->act_object); break; case act_d_trigger: drop_trigger(dyn, (DUDLEY_TRG) action->act_object); break; case act_m_trigger: modify_trigger(dyn, (DUDLEY_TRG) action->act_object); break; case act_a_trigger_msg: add_trigger_msg(dyn, (TRGMSG) action->act_object); break; case act_d_trigger_msg: drop_trigger_msg(dyn, (TRGMSG) action->act_object); break; case act_a_shadow: add_files(dyn, (FIL) action->act_object, NULL); break; case act_d_shadow: drop_shadow(dyn, (SLONG) (action->act_object)); break; case act_m_trigger_msg: modify_trigger_msg(dyn, (TRGMSG) action->act_object); break; default: DDL_err(282, NULL, NULL, NULL, NULL, NULL); /* msg 282: action not implemented yet */ } CHECK_DYN(2); STUFF(gds_dyn_end); STUFF(gds_dyn_eoc); switch (language) { case lan_undef: case lan_c: if (PRETTY_print_dyn(dyn->str_start, (int(*)()) gen_dyn_c, 0, 0)) DDL_err(283, NULL, NULL, NULL, NULL, NULL); /*msg 283: internal error during DYN pretty print */ break; case lan_cxx: if (PRETTY_print_dyn(dyn->str_start, (int(*)()) gen_dyn_cxx, 0, 0)) DDL_err(283, NULL, NULL, NULL, NULL, NULL); /*msg 283: internal error during DYN pretty print */ break; case lan_pascal: length = dyn->str_current - dyn->str_start; ib_fprintf(output_file, " gds_dyn_length : gds__short := %d;\n", length); ib_fprintf(output_file, " gds_dyn : packed array [1..%d] of char := (\n", length); if (PRETTY_print_dyn(dyn->str_start, (int(*)()) gen_dyn_pas, 0, 1)) DDL_err(285, NULL, NULL, NULL, NULL, NULL); /*msg 285: internal error during DYN pretty print */ ib_fprintf(output_file, " ); (* end of DYN string *)\n"); break; case lan_fortran: length = dyn->str_current - dyn->str_start; ib_fprintf(output_file, " INTEGER*2 GDS__DYN_LENGTH\n"); ib_fprintf(output_file, " INTEGER*4 GDS__DYN(%d)\n", (int) ((length + 3) / 4)); ib_fprintf(output_file, " DATA GDS__DYN_LENGTH /%d/\n", length); ib_fprintf(output_file, " DATA (GDS__DYN(I), I=1,%d) /\n", (int) ((length + 3) / 4)); raw_ftn(dyn); break; case lan_pli: length = dyn->str_current - dyn->str_start; ib_fprintf(output_file, "DECLARE gds_dyn_length FIXED BINARY (15) STATIC INITIAL (%d);\n", length); ib_fprintf(output_file, "DECLARE gds_dyn (%d) FIXED BINARY (7) STATIC INITIAL (\n", length); raw_pli(dyn); break; case lan_basic: length = dyn->str_current - dyn->str_start; ib_fprintf(output_file, " DECLARE WORD CONSTANT gds_dyn_length = %d\n", length); ib_fprintf(output_file, " DECLARE STRING CONSTANT gds_dyn =&\n", length); raw_basic(dyn); break; case lan_ada: length = dyn->str_current - dyn->str_start; ib_fprintf(output_file, "gds_dyn_length: short_integer := %d;\n", length); ib_fprintf(output_file, "gds_dyn : CONSTANT interbase.blr (1..%d) := (\n", length); raw_ada(dyn); break; case lan_ansi_cobol: length = dyn->str_current - dyn->str_start; ib_fprintf(output_file, " 01 GDS-DYN-LENGTH PIC S9(4) USAGE COMP VALUE IS %d.\n", length); ib_fprintf(output_file, " 01 GDS-DYN.\n"); raw_cobol(dyn); break; case lan_cobol: length = dyn->str_current - dyn->str_start; ib_fprintf(output_file, " 01 GDS__DYN_LENGTH PIC S9(4) USAGE COMP VALUE IS %d.\n", length); ib_fprintf(output_file, " 01 GDS__DYN.\n"); raw_cobol(dyn); break; } if (output_file != ib_stdout) ib_fclose(output_file); gds__free(dyn->str_start); } static void add_dimensions( STR dyn, DUDLEY_FLD field) { /************************************** * * a d d _ d i m e n s i o n s * ************************************** * * Functional description * Generate dynamic DDL to create dimensions. * First get rid of any old ones. * **************************************/ SLONG *range; USHORT n; put_symbol(dyn, gds_dyn_delete_dimensions, field->fld_name); CHECK_DYN(1); STUFF(gds_dyn_end); for (range = field->fld_ranges, n = 0; n < field->fld_dimension; range += 2, ++n) { put_number(dyn, gds_dyn_def_dimension, n); put_symbol(dyn, gds_dyn_fld_name, field->fld_name); put_number(dyn, gds_dyn_dim_lower, (SSHORT) range[0]); put_number(dyn, gds_dyn_dim_upper, (SSHORT) range[1]); CHECK_DYN(1); STUFF(gds_dyn_end); } } static void add_field( STR dyn, DUDLEY_FLD field, DUDLEY_REL view) { /************************************** * * a d d _ f i e l d * ************************************** * * Functional description * Generate dynamic DDL to create a * local field. * **************************************/ SYM name, symbol; DUDLEY_REL relation; DUDLEY_FLD source_field; int n; name = field->fld_name; if (view) relation = view; else relation = field->fld_relation; put_symbol(dyn, gds_dyn_def_local_fld, name); put_symbol(dyn, gds_dyn_rel_name, relation->rel_name); if ((symbol = field->fld_source) && strcmp(symbol->sym_string, name->sym_string) && !field->fld_computed) put_symbol(dyn, gds_dyn_fld_source, symbol); put_symbol(dyn, gds_dyn_security_class, field->fld_security_class); put_symbol(dyn, gds_dyn_fld_edit_string, field->fld_edit_string); put_symbol(dyn, gds_dyn_fld_query_name, field->fld_query_name); put_query_header(dyn, gds_dyn_fld_query_header, field->fld_query_header); if (field->fld_system) put_number(dyn, gds_dyn_system_flag, field->fld_system); put_symbol(dyn, gds_dyn_fld_base_fld, field->fld_base); if (field->fld_context) put_number(dyn, gds_dyn_view_context, field->fld_context->ctx_context_id); if (field->fld_computed) { if (!field->fld_context && view) put_number(dyn, gds_dyn_view_context, 0); put_blr(dyn, gds_dyn_fld_computed_blr, NULL, field->fld_computed); source_field = field->fld_source_field; put_number(dyn, gds_dyn_fld_type, source_field->fld_dtype); put_number(dyn, gds_dyn_fld_length, source_field->fld_length); put_number(dyn, gds_dyn_fld_scale, source_field->fld_scale); put_number(dyn, gds_dyn_fld_sub_type, source_field->fld_sub_type); if (n = source_field->fld_segment_length) put_number(dyn, gds_dyn_fld_segment_length, n); } put_text(dyn, gds_dyn_fld_computed_source, field->fld_compute_src); if (field->fld_flags & fld_explicit_position) put_number(dyn, gds_dyn_fld_position, field->fld_position); put_text(dyn, gds_dyn_description, field->fld_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_files( STR dyn, FIL files, DBB database) { /************************************** * * a d d _ f i l e s * ************************************** * * Functional description * Generate dynamic ddl to add database * or shadow files. * **************************************/ FIL file, next; /* Reverse the order of files (parser left them backwards) */ for (file = files, files = NULL; file; file = next) { next = file->fil_next; file->fil_next = files; files = file; } if (!database && files) put_number(dyn, gds_dyn_def_shadow, files->fil_shadow_number); for (file = files; file; file = file->fil_next) { put_symbol(dyn, gds_dyn_def_file, file->fil_name); put_number(dyn, gds_dyn_file_start, (SSHORT) (file->fil_start)); put_number(dyn, gds_dyn_file_length, (SSHORT) (file->fil_length)); put_number(dyn, gds_dyn_shadow_man_auto, file->fil_manual); put_number(dyn, gds_dyn_shadow_conditional, file->fil_conditional); CHECK_DYN(1); STUFF(gds_dyn_end); } if (!database && files) { CHECK_DYN(1); STUFF(gds_dyn_end); } } static void add_filter( STR dyn, FILTER filter) { /************************************** * * a d d _ f i l t e r * ************************************** * * Functional description * Generate dynamic DDL to create a * blob filter. * **************************************/ put_symbol(dyn, gds_dyn_def_filter, filter->filter_name); put_number(dyn, gds_dyn_filter_in_subtype, filter->filter_input_sub_type); put_number(dyn, gds_dyn_filter_out_subtype, filter->filter_output_sub_type); put_symbol(dyn, gds_dyn_func_entry_point, filter->filter_entry_point); put_symbol(dyn, gds_dyn_func_module_name, filter->filter_module_name); put_text(dyn, gds_dyn_description, filter->filter_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_function( STR dyn, FUNC function) { /************************************** * * a d d _ f u n c t i o n * ************************************** * * Functional description * Generate dynamic DDL to create a * user define function. * **************************************/ put_symbol(dyn, gds_dyn_def_function, function->func_name); put_symbol(dyn, gds_dyn_fld_query_name, function->func_query_name); put_symbol(dyn, gds_dyn_func_entry_point, function->func_entry_point); put_number(dyn, gds_dyn_func_return_argument, function->func_return_arg); put_symbol(dyn, gds_dyn_func_module_name, function->func_module_name); put_text(dyn, gds_dyn_description, function->func_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_function_arg( STR dyn, FUNCARG func_arg) { /************************************** * * a d d _ f u n c t i o n _ a r g * ************************************** * * Functional description * Generate dynamic DDL to create a * user defined function. * **************************************/ put_number(dyn, gds_dyn_def_function_arg, func_arg->funcarg_position); put_symbol(dyn, gds_dyn_function_name, func_arg->funcarg_funcname); put_number(dyn, gds_dyn_func_mechanism, func_arg->funcarg_mechanism); put_number(dyn, gds_dyn_fld_type, func_arg->funcarg_dtype); put_number(dyn, gds_dyn_fld_scale, func_arg->funcarg_scale); if (func_arg->funcarg_has_sub_type) put_number(dyn, gds_dyn_fld_sub_type, func_arg->funcarg_sub_type); put_number(dyn, gds_dyn_fld_length, func_arg->funcarg_length); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_generator( STR dyn, SYM symbol) { /************************************** * * a d d _ g e n e r a t o r * ************************************** * * Functional description * Generate dynamic DDL to create a * generator. * **************************************/ put_symbol(dyn, gds_dyn_def_generator, symbol); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_global_field( STR dyn, DUDLEY_FLD field) { /************************************** * * a d d _ g l o b a l _ f i e l d * ************************************** * * Functional description * Generate dynamic DDL to create a relation. * **************************************/ SYM name; int n; if (field->fld_computed) return; name = field->fld_name; put_symbol(dyn, gds_dyn_def_global_fld, name); put_symbol(dyn, gds_dyn_fld_edit_string, field->fld_edit_string); put_symbol(dyn, gds_dyn_fld_query_name, field->fld_query_name); put_query_header(dyn, gds_dyn_fld_query_header, field->fld_query_header); if (field->fld_system) put_number(dyn, gds_dyn_system_flag, field->fld_system); put_number(dyn, gds_dyn_fld_type, field->fld_dtype); put_number(dyn, gds_dyn_fld_length, field->fld_length); put_number(dyn, gds_dyn_fld_scale, field->fld_scale); put_number(dyn, gds_dyn_fld_sub_type, field->fld_sub_type); if (n = field->fld_segment_length) put_number(dyn, gds_dyn_fld_segment_length, n); put_blr(dyn, gds_dyn_fld_missing_value, NULL, field->fld_missing); put_blr(dyn, gds_dyn_fld_validation_blr, NULL, field->fld_validation); put_text(dyn, gds_dyn_fld_validation_source, field->fld_valid_src); put_text(dyn, gds_dyn_description, field->fld_description); if (field->fld_dimension) { put_number(dyn, gds_dyn_fld_dimensions, field->fld_dimension); add_dimensions(dyn, field); } CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_index( STR dyn, DUDLEY_IDX index) { /************************************** * * a d d _ i n d e x * ************************************** * * Functional description * Generate dynamic DDL to create an index. * **************************************/ TEXT i; put_symbol(dyn, gds_dyn_def_idx, index->idx_name); put_symbol(dyn, gds_dyn_rel_name, index->idx_relation); put_number(dyn, gds_dyn_idx_unique, index->idx_unique); if (index->idx_inactive) put_number(dyn, gds_dyn_idx_inactive, TRUE); else put_number(dyn, gds_dyn_idx_inactive, FALSE); if (index->idx_type) put_number(dyn, gds_dyn_idx_type, index->idx_type); put_text(dyn, gds_dyn_description, index->idx_description); for (i = 0; i < index->idx_count; i++) put_symbol(dyn, gds_dyn_fld_name, index->idx_field[i]); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_relation( STR dyn, DUDLEY_REL relation) { /************************************** * * a d d _ r e l a t i o n * ************************************** * * Functional description * Generate dynamic DDL to create a relation. * **************************************/ if (relation->rel_rse) { add_view(dyn, relation); return; } put_symbol(dyn, gds_dyn_def_rel, relation->rel_name); put_symbol(dyn, gds_dyn_security_class, relation->rel_security_class); put_symbol(dyn, gds_dyn_rel_ext_file, relation->rel_filename); if (relation->rel_system) put_number(dyn, gds_dyn_system_flag, relation->rel_system); put_text(dyn, gds_dyn_description, relation->rel_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_security_class( STR dyn, SCL class_) { /************************************** * * a d d _ s e c u r i t y _ c l a s s * ************************************** * * Functional description * Generate dynamic ddl to add a security class. * **************************************/ put_symbol(dyn, gds_dyn_def_security_class, class_->scl_name); put_acl(dyn, gds_dyn_scl_acl, class_); put_text(dyn, gds_dyn_description, class_->scl_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_trigger( STR dyn, DUDLEY_TRG trigger) { /************************************** * * a d d _ t r i g g e r * ************************************** * * Functional description * Generate dynamic ddl to add a trigger for a relation. * **************************************/ SYM name; DUDLEY_REL relation; relation = trigger->trg_relation; name = trigger->trg_name; put_symbol(dyn, gds_dyn_def_trigger, name); put_symbol(dyn, gds_dyn_rel_name, relation->rel_name); put_number(dyn, gds_dyn_trg_type, trigger->trg_type); put_number(dyn, gds_dyn_trg_sequence, trigger->trg_sequence); put_number(dyn, gds_dyn_trg_inactive, trigger->trg_inactive); put_blr(dyn, gds_dyn_trg_blr, relation, trigger->trg_statement); put_text(dyn, gds_dyn_trg_source, trigger->trg_source); put_text(dyn, gds_dyn_description, trigger->trg_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_trigger_msg( STR dyn, TRGMSG trigmsg) { /************************************** * * a d d _ t r i g g e r _ m s g * ************************************** * * Functional description * Generate dynamic ddl to add a trigger message. * **************************************/ put_number(dyn, gds_dyn_def_trigger_msg, trigmsg->trgmsg_number); put_symbol(dyn, gds_dyn_trg_name, trigmsg->trgmsg_trg_name); put_symbol(dyn, gds_dyn_trg_msg, trigmsg->trgmsg_text); CHECK_DYN(1); STUFF(gds_dyn_end); } static void add_view( STR dyn, DUDLEY_REL relation) { /************************************** * * a d d _ v i e w * ************************************** * * Functional description * Generate dynamic DDL to create a view. * **************************************/ DUDLEY_FLD field; DUDLEY_CTX context; DUDLEY_NOD *arg, contexts; SSHORT i; put_symbol(dyn, gds_dyn_def_view, relation->rel_name); put_symbol(dyn, gds_dyn_security_class, relation->rel_security_class); if (relation->rel_system) put_number(dyn, gds_dyn_system_flag, relation->rel_system); put_text(dyn, gds_dyn_description, relation->rel_description); put_blr(dyn, gds_dyn_view_blr, relation, relation->rel_rse); put_text(dyn, gds_dyn_view_source, relation->rel_view_source); contexts = relation->rel_rse->nod_arg[s_rse_contexts]; for (i = 0, arg = contexts->nod_arg; i < contexts->nod_count; i++, arg++) { context = (DUDLEY_CTX) (*arg)->nod_arg[0]; put_symbol(dyn, gds_dyn_view_relation, context->ctx_relation->rel_name); put_number(dyn, gds_dyn_view_context, context->ctx_context_id); put_symbol(dyn, gds_dyn_view_context_name, context->ctx_name); CHECK_DYN(1); STUFF(gds_dyn_end); } for (field = relation->rel_fields; field; field = field->fld_next) add_field(dyn, field, relation); CHECK_DYN(1); STUFF(gds_dyn_end); } BOOLEAN TRN_get_buffer(STR dyn, USHORT length) { /************************************** * * g e t _ b u f f e r * ************************************** * * Functional description * Generated DYN string is about to over the memory allocated for it. * So, allocate an extra memory. * **************************************/ SCHAR *p, *q, *old; USHORT len, n; len = dyn->str_current - dyn->str_start; /* Compute the next incremental string len */ n = MIN(dyn->str_length * 2, 65536 - 4); /* If we're in danger of blowing the limit, stop right here */ if (n < len + length) return FALSE; q = old = dyn->str_start; dyn->str_start = p = (SCHAR *) gds__alloc((SLONG) n); if (!p) return FALSE; dyn->str_length = n; dyn->str_current = dyn->str_start + len; #ifdef DEBUG_GDS_ALLOC /* For V4.0 we don't care about Gdef specific memory leaks */ gds_alloc_flag_unfreed(dyn->str_start); #endif memmove(p, q, len); gds__free(old); return TRUE; } static void drop_field( STR dyn, DUDLEY_FLD field) { /************************************** * * d r o p _ f i e l d * ************************************** * * Functional description * Generate dynamic DDL to eliminate * a local field. * **************************************/ SYM name; DUDLEY_REL relation; name = field->fld_name; relation = field->fld_relation; put_symbol(dyn, gds_dyn_delete_local_fld, name); put_symbol(dyn, gds_dyn_rel_name, relation->rel_name); CHECK_DYN(1); STUFF(gds_dyn_end); } static void drop_filter( STR dyn, FILTER filter) { /************************************** * * d r o p _ f i l t e r * ************************************** * * Functional description * Generate dynamic DDL to delete a * blob filter. * **************************************/ put_symbol(dyn, gds_dyn_delete_filter, filter->filter_name); CHECK_DYN(1); STUFF(gds_dyn_end); } static void drop_function( STR dyn, FUNC function) { /************************************** * * d r o p _ f u n c t i o n * ************************************** * * Functional description * Generate dynamic DDL to delete a * user defined function. * **************************************/ put_symbol(dyn, gds_dyn_delete_function, function->func_name); CHECK_DYN(1); STUFF(gds_dyn_end); } static void drop_global_field( STR dyn, DUDLEY_FLD field) { /************************************** * * d r o p _ g l o b a l _ f i e l d * ************************************** * * Functional description * Generate dynamic DDL to eliminate * a global field. * **************************************/ SYM name; name = field->fld_name; put_symbol(dyn, gds_dyn_delete_global_fld, name); CHECK_DYN(1); STUFF(gds_dyn_end); } static void drop_index( STR dyn, DUDLEY_IDX index) { /************************************** * * d r o p _ i n d e x * ************************************** * * Functional description * Generate dynamic DDL to delete an index. * **************************************/ put_symbol(dyn, gds_dyn_delete_idx, index->idx_name); CHECK_DYN(1); STUFF(gds_dyn_end); } static void drop_relation( STR dyn, DUDLEY_REL relation) { /************************************** * * d r o p _ r e l a t i o n * ************************************** * * Functional description * Generate dynamic DDL to delete an relation. * **************************************/ put_symbol(dyn, gds_dyn_delete_rel, relation->rel_name); CHECK_DYN(1); STUFF(gds_dyn_end); } static void drop_security_class( STR dyn, SCL class_) { /************************************** * * d r o p _ s e c u r i t y _ c l a s s * ************************************** * * Functional description * Generate dynamic DDL to delete an securtiy_class. * **************************************/ put_symbol(dyn, gds_dyn_delete_security_class, class_->scl_name); CHECK_DYN(1); STUFF(gds_dyn_end); } static void drop_shadow( STR dyn, SLONG shadow_number) { /************************************** * * d r o p _ s h a d o w * ************************************** * * Functional description * Generate dynamic ddl to drop a shadow. * **************************************/ put_number(dyn, gds_dyn_delete_shadow, (SSHORT) shadow_number); CHECK_DYN(1); STUFF(gds_dyn_end); } static void drop_trigger( STR dyn, DUDLEY_TRG trigger) { /************************************** * * d r o p _ t r i g g e r * ************************************** * * Functional description * Generate dynamic ddl to delete a trigger. * **************************************/ SYM name; name = trigger->trg_name; put_symbol(dyn, gds_dyn_delete_trigger, name); CHECK_DYN(1); STUFF(gds_dyn_end); } static void drop_trigger_msg( STR dyn, TRGMSG trigmsg) { /************************************** * * d r o p _ t r i g g e r _ m s g * ************************************** * * Functional description * Generate dynamic ddl to delete a trigger message. * **************************************/ put_number(dyn, gds_dyn_delete_trigger_msg, trigmsg->trgmsg_number); put_symbol(dyn, gds_dyn_trg_name, trigmsg->trgmsg_trg_name); CHECK_DYN(1); STUFF(gds_dyn_end); } static int gen_dyn_c( int *user_arg, int offset, SCHAR * string) { /************************************** * * g e n _ d y n _ c * ************************************** * * Functional description * Callback routine for BLR pretty printer. * **************************************/ ib_fprintf(output_file, " %s\n", string); return TRUE; } static int gen_dyn_cxx( int *user_arg, int offset, SCHAR * string) { /************************************** * * g e n _ d y n _ c x x * ************************************** * * Functional description * Callback routine for BLR pretty printer. * **************************************/ SCHAR *p, *q, *r; q = p = string; ib_fprintf(output_file, " "); for (; *q; *q++) { if ((*q == '$') || (*q == '_')) { r = q; if ((*--r == '_') && (*--r == 's') && (*--r == 'd') && (*--r == 'g')) { *q = 0; ib_fprintf(output_file, "%s", p); p = ++q; } } } ib_fprintf(output_file, "%s\n", p); return TRUE; } static int gen_dyn_pas( int *user_arg, int offset, SCHAR * string) { /************************************** * * g e n _ d y n _ p a s * ************************************** * * Functional description * Callback routine for BLR pretty printer. * **************************************/ ib_fprintf(output_file, " %s\n", string); return TRUE; } static void modify_database( STR dyn, DBB database) { /************************************** * * m o d i f y _ d a t a b a s e * ************************************** * * Functional description * Generate dynamic DDL to modify a database. * **************************************/ if (!(database->dbb_files || database->dbb_security_class || database->dbb_description || (database-> dbb_flags & (DBB_null_security_class | DBB_null_description)))) return; CHECK_DYN(1); STUFF(gds_dyn_mod_database); add_files(dyn, database->dbb_files, database); if (database->dbb_flags & DBB_null_security_class) { CHECK_DYN(3); STUFF(gds_dyn_security_class); STUFF_WORD(0); } else put_symbol(dyn, gds_dyn_security_class, database->dbb_security_class); if (database->dbb_flags & DBB_null_description) { CHECK_DYN(3); STUFF(gds_dyn_description); STUFF_WORD(0); } else if (database->dbb_description) put_text(dyn, gds_dyn_description, database->dbb_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void modify_field( STR dyn, DUDLEY_FLD field, DUDLEY_REL view) { /************************************** * * m o d i f y _ f i e l d * ************************************** * * Functional description * Generate dynamic DDL to modify a * local field. * **************************************/ SYM name, symbol; DUDLEY_REL relation; name = field->fld_name; if (view) relation = view; else relation = field->fld_relation; put_symbol(dyn, gds_dyn_mod_local_fld, name); put_symbol(dyn, gds_dyn_rel_name, relation->rel_name); if ((symbol = field->fld_source) && strcmp(symbol->sym_string, name->sym_string) && !field->fld_computed) put_symbol(dyn, gds_dyn_fld_source, symbol); if (field->fld_flags & fld_null_security_class) { CHECK_DYN(3); STUFF(gds_dyn_security_class); STUFF_WORD(0); } else put_symbol(dyn, gds_dyn_security_class, field->fld_security_class); if (field->fld_flags & fld_null_edit_string) { CHECK_DYN(3); STUFF(gds_dyn_fld_edit_string); STUFF_WORD(0); } else put_symbol(dyn, gds_dyn_fld_edit_string, field->fld_edit_string); if (field->fld_flags & fld_null_query_name) { CHECK_DYN(3); STUFF(gds_dyn_fld_query_name); STUFF_WORD(0); } else put_symbol(dyn, gds_dyn_fld_query_name, field->fld_query_name); if (field->fld_flags & fld_null_query_header) { CHECK_DYN(3); STUFF(gds_dyn_fld_query_header); STUFF_WORD(0); } else put_query_header(dyn, gds_dyn_fld_query_header, field->fld_query_header); if (field->fld_system) put_number(dyn, gds_dyn_system_flag, field->fld_system); if (field->fld_flags & fld_explicit_position) put_number(dyn, gds_dyn_fld_position, field->fld_position); if (field->fld_flags & fld_null_description) { CHECK_DYN(3); STUFF(gds_dyn_description); STUFF_WORD(0); } else if (field->fld_description) put_text(dyn, gds_dyn_description, field->fld_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void modify_global_field( STR dyn, DUDLEY_FLD field) { /************************************** * * m o d i f y _ g l o b a l _ f i e l d * ************************************** * * Functional description * Generate dynamic DDL to * modify a global field. This gets * more and more tiresome. * **************************************/ SYM name; int n; if (field->fld_computed) return; name = field->fld_name; put_symbol(dyn, gds_dyn_mod_global_fld, name); if (field->fld_flags & fld_null_edit_string) { CHECK_DYN(3); STUFF(gds_dyn_fld_edit_string); STUFF_WORD(0); } else put_symbol(dyn, gds_dyn_fld_edit_string, field->fld_edit_string); if (field->fld_flags & fld_null_query_name) { CHECK_DYN(3); STUFF(gds_dyn_fld_query_name); STUFF_WORD(0); } else put_symbol(dyn, gds_dyn_fld_query_name, field->fld_query_name); if (field->fld_flags & fld_null_query_header) { CHECK_DYN(3); STUFF(gds_dyn_fld_query_header); STUFF_WORD(0); } else put_query_header(dyn, gds_dyn_fld_query_header, field->fld_query_header); if (field->fld_system & fld_explicit_system) put_number(dyn, gds_dyn_system_flag, field->fld_system); if (field->fld_dtype) { put_number(dyn, gds_dyn_fld_type, field->fld_dtype); put_number(dyn, gds_dyn_fld_length, field->fld_length); put_number(dyn, gds_dyn_fld_scale, field->fld_scale); } if (field->fld_has_sub_type) put_number(dyn, gds_dyn_fld_sub_type, field->fld_sub_type); if (n = field->fld_segment_length) put_number(dyn, gds_dyn_fld_segment_length, n); if (field->fld_flags & fld_null_missing_value) { CHECK_DYN(3); STUFF(gds_dyn_fld_missing_value); STUFF_WORD(0); } else if (field->fld_missing) put_blr(dyn, gds_dyn_fld_missing_value, NULL, field->fld_missing); if (field->fld_flags & fld_null_validation) { CHECK_DYN(6); STUFF(gds_dyn_fld_validation_blr); STUFF_WORD(0); STUFF(gds_dyn_fld_validation_source); STUFF_WORD(0) } else if (field->fld_validation) { put_blr(dyn, gds_dyn_fld_validation_blr, NULL, field->fld_validation); put_text(dyn, gds_dyn_fld_validation_source, field->fld_valid_src); } if (field->fld_flags & fld_null_description) { CHECK_DYN(3); STUFF(gds_dyn_description); STUFF_WORD(0); } else if (field->fld_description) put_text(dyn, gds_dyn_description, field->fld_description); if (field->fld_dimension) { put_number(dyn, gds_dyn_fld_dimensions, field->fld_dimension); add_dimensions(dyn, field); } CHECK_DYN(1); STUFF(gds_dyn_end); } static void modify_index( STR dyn, DUDLEY_IDX index) { /************************************** * * m o d i f y _ i n d e x * ************************************** * * Functional description * Generate dynamic DDL to modify an index. * **************************************/ put_symbol(dyn, gds_dyn_mod_idx, index->idx_name); if (index->idx_flags & IDX_unique_flag) put_number(dyn, gds_dyn_idx_unique, index->idx_unique); if (index->idx_flags & IDX_active_flag) put_number(dyn, gds_dyn_idx_inactive, (index->idx_inactive) ? TRUE : FALSE); if (index->idx_flags & IDX_type_flag) put_number(dyn, gds_dyn_idx_type, index->idx_type); if (index->idx_flags & IDX_null_description) { CHECK_DYN(3); STUFF(gds_dyn_description); STUFF_WORD(0); } else if (index->idx_description) put_text(dyn, gds_dyn_description, index->idx_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void modify_relation( STR dyn, DUDLEY_REL relation) { /************************************** * * m o d i f y _ r e l a t i o n * ************************************** * * Functional description * Generate dynamic DDL to modify a relation. * **************************************/ put_symbol(dyn, gds_dyn_mod_rel, relation->rel_name); if (relation->rel_flags & rel_null_security_class) { CHECK_DYN(3); STUFF(gds_dyn_security_class); STUFF_WORD(0); } else put_symbol(dyn, gds_dyn_security_class, relation->rel_security_class); if (relation->rel_system) put_number(dyn, gds_dyn_system_flag, relation->rel_system); if (relation->rel_flags & rel_null_description) { CHECK_DYN(3); STUFF(gds_dyn_description); STUFF_WORD(0); } else if (relation->rel_description) put_text(dyn, gds_dyn_description, relation->rel_description); if (relation->rel_flags & rel_null_ext_file) { CHECK_DYN(3); STUFF(gds_dyn_rel_ext_file); STUFF_WORD(0); } else put_symbol(dyn, gds_dyn_rel_ext_file, relation->rel_filename); CHECK_DYN(1); STUFF(gds_dyn_end); } static void modify_trigger( STR dyn, DUDLEY_TRG trigger) { /************************************** * * m o d i f y _ t r i g g e r * ************************************** * * Functional description * Generate dynamic ddl to modify a trigger for a relation. * **************************************/ SYM name; DUDLEY_REL relation; relation = trigger->trg_relation; name = trigger->trg_name; put_symbol(dyn, gds_dyn_mod_trigger, name); put_symbol(dyn, gds_dyn_rel_name, relation->rel_name); if (trigger->trg_mflag & trg_mflag_onoff) put_number(dyn, gds_dyn_trg_inactive, trigger->trg_inactive); if (trigger->trg_mflag & trg_mflag_type) put_number(dyn, gds_dyn_trg_type, trigger->trg_type); if (trigger->trg_mflag & trg_mflag_seqnum) put_number(dyn, gds_dyn_trg_sequence, trigger->trg_sequence); if (trigger->trg_statement) put_blr(dyn, gds_dyn_trg_blr, relation, trigger->trg_statement); if (trigger->trg_source) put_text(dyn, gds_dyn_trg_source, trigger->trg_source); if (trigger->trg_description) put_text(dyn, gds_dyn_description, trigger->trg_description); CHECK_DYN(1); STUFF(gds_dyn_end); } static void modify_trigger_msg( STR dyn, TRGMSG trigmsg) { /************************************** * * m o d i f y _ t r i g g e r _ m s g * ************************************** * * Functional description * Generate dynamic ddl to modify a trigger message. * **************************************/ put_number(dyn, gds_dyn_mod_trigger_msg, trigmsg->trgmsg_number); put_symbol(dyn, gds_dyn_trg_name, trigmsg->trgmsg_trg_name); put_symbol(dyn, gds_dyn_trg_msg, trigmsg->trgmsg_text); CHECK_DYN(1); STUFF(gds_dyn_end); } static void put_acl( STR dyn, UCHAR attribute, SCL class_) { /************************************** * * p u t _ a c l * ************************************** * * Functional description * **************************************/ USHORT length; TEXT buffer[4096], *p; if (!class_) return; length = GENERATE_acl(class_, (UCHAR*) buffer); assert(length <= 4096); /* to make sure buffer is big enough */ CHECK_DYN(3 + length); STUFF(attribute); STUFF_WORD(length); p = buffer; while (length--) STUFF(*p++); } static void put_blr( STR dyn, UCHAR attribute, DUDLEY_REL relation, DUDLEY_NOD node) { /************************************** * * p u t _ b l r * ************************************** * * Functional description * **************************************/ SCHAR *p; USHORT length, offset; if (!node) return; CHECK_DYN(3); STUFF(attribute); /* Skip over space to put count later, generate blr, then go bad and fix up length */ offset = dyn->str_current - dyn->str_start; dyn->str_current = dyn->str_current + 2; GENERATE_blr(dyn, node); p = dyn->str_start + offset; length = (dyn->str_current - p) - 2; *p++ = length; *p = (length >> 8); } static void put_number( STR dyn, TEXT attribute, SSHORT number) { /************************************** * * p u t _ n u m b e r * ************************************** * * Functional description * **************************************/ CHECK_DYN(5); STUFF(attribute); /* Assume number can be expressed in two bytes */ STUFF_WORD(2); STUFF_WORD(number); } static void put_query_header( STR dyn, TEXT attribute, DUDLEY_NOD node) { /************************************** * * p u t _ q u e r y _ h e a d e r * ************************************** * * Functional description * **************************************/ DUDLEY_NOD *ptr, *end; SYM symbol; SCHAR *s; USHORT length, offset; if (!node) return; CHECK_DYN(3); STUFF(attribute); offset = dyn->str_current - dyn->str_start; dyn->str_current = dyn->str_current + 2; for (ptr = node->nod_arg, end = ptr + node->nod_count; ptr < end; ptr++) { symbol = (SYM) * ptr; s = (SCHAR *) symbol->sym_string; CHECK_DYN(symbol->sym_length); while (*s) STUFF(*s++); } s = dyn->str_start + offset; length = (dyn->str_current - s) - 2; *s++ = length; *s = (length >> 8); } static void put_symbol( STR dyn, TEXT attribute, SYM symbol) { /************************************** * * p u t _ s y m b o l * ************************************** * * Functional description * **************************************/ TEXT *string; USHORT l; if (!symbol) return; l = symbol->sym_length; CHECK_DYN(l + 5); STUFF(attribute); STUFF_WORD(l); for (string = symbol->sym_string; *string;) STUFF(*string++); } static void put_text( STR dyn, UCHAR attribute, TXT text) { /************************************** * * p u t _ t e x t * ************************************** * * Functional description * **************************************/ USHORT length; if (!text) return; length = text->txt_length; if (!length) return; CHECK_DYN(length + 5); STUFF(attribute); STUFF_WORD(length); LEX_get_text(dyn->str_current, text); dyn->str_current += length; } static void raw_ada( STR dyn) { /************************************** * * r a w _ a d a * ************************************** * * Functional description * **************************************/ SCHAR *p; USHORT n; n = 0; for (p = dyn->str_start; p < dyn->str_current; p++) { if (p < (dyn->str_current - 1)) { ib_fprintf(output_file, "%d,", *p); n += 4; } else { ib_fprintf(output_file, "%d", *p); n += 3; } if (n > 60) { ib_fprintf(output_file, "\n"); n = 0; } } ib_fprintf(output_file, ");\n"); } static void raw_basic( STR dyn) { /************************************** * * r a w _ b a s i c * ************************************** * * Functional description * **************************************/ SCHAR *blr; TEXT buffer[80], *p; UCHAR c; int blr_length; blr = dyn->str_start; blr_length = dyn->str_current - dyn->str_start; p = buffer; while (--blr_length) { c = *blr++; if (c >= ' ' && c <= 'z') sprintf(p, "'%c' + ", c); else sprintf(p, "'%d'C + ", c); while (*p) p++; if (p - buffer > 60) { ib_fprintf(output_file, " %s &\n", buffer); p = buffer; *p = 0; } } c = *blr++; if (c >= ' ' && c <= 'z') sprintf(p, "'%c'", c); else sprintf(p, "'%d'C", c); ib_fprintf(output_file, " %s\n", buffer); } static void raw_cobol( STR dyn) { /************************************** * * r a w _ c o b o l * ************************************** * * Functional description * **************************************/ SCHAR *blr, *c; int blr_length, length; union { SCHAR bytewise_blr[4]; SLONG longword_blr; } blr_hunk; length = 1; blr = dyn->str_start; blr_length = dyn->str_current - dyn->str_start; while (blr_length) { for (c = blr_hunk.bytewise_blr; c < blr_hunk.bytewise_blr + sizeof(SLONG); c++) { *c = *blr++; if (!(--blr_length)) break; } if (language == lan_ansi_cobol) ib_fprintf(output_file, " 03 GDS-DYN-%d PIC S9(10) USAGE COMP VALUE IS %" SLONGFORMAT".\n", length++, blr_hunk.longword_blr); else ib_fprintf(output_file, " 03 GDS__DYN_%d PIC S9(10) USAGE COMP VALUE IS %" SLONGFORMAT".\n", length++, blr_hunk.longword_blr); } } static void raw_ftn( STR dyn) { /************************************** * * r a w _ f t n * ************************************** * * Functional description * **************************************/ UCHAR *blr, *c; TEXT buffer[80], *p; int blr_length; union { UCHAR bytewise_blr[4]; SLONG longword_blr; } blr_hunk; blr = (UCHAR *) dyn->str_start; blr_length = dyn->str_current - dyn->str_start; p = buffer; while (blr_length) { for (c = blr_hunk.bytewise_blr, blr_hunk.longword_blr = 0; c < blr_hunk.bytewise_blr + sizeof(SLONG); c++) { *c = *blr++; if (!(--blr_length)) break; } if (blr_length) sprintf(p, "%"SLONGFORMAT",", blr_hunk.longword_blr); else sprintf(p, "%"SLONGFORMAT"/", blr_hunk.longword_blr); while (*p) p++; if (p - buffer > 50) { ib_fprintf(output_file, "%s%s\n", " + ", buffer); p = buffer; *p = 0; } } if (p != buffer) ib_fprintf(output_file, "%s%s\n", " + ", buffer); } static void raw_pli( STR dyn) { /************************************** * * r a w _ p l i * ************************************** * * Functional description * **************************************/ SCHAR *blr, c; TEXT buffer[80], *p; int blr_length; blr = dyn->str_start; blr_length = dyn->str_current - dyn->str_start; p = buffer; while (--blr_length) { c = *blr++; sprintf(p, "%d,", c); while (*p) p++; if (p - buffer > 60) { ib_fprintf(output_file, " %s\n", buffer); p = buffer; *p = 0; } } c = *blr++; sprintf(p, "%d);", c); ib_fprintf(output_file, " %s", buffer); }