2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD Access Method
|
|
|
|
* MODULE: ini.e
|
|
|
|
* DESCRIPTION: Metadata initialization / population
|
|
|
|
*
|
|
|
|
* 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): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
2001-07-29 19:42:23 +02:00
|
|
|
#include "firebird.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "../jrd/flags.h"
|
|
|
|
#include "../jrd/jrd.h"
|
|
|
|
#include "../jrd/val.h"
|
2003-11-08 17:40:17 +01:00
|
|
|
#include "../jrd/y_ref.h"
|
|
|
|
#include "../jrd/ibase.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/ods.h"
|
|
|
|
#include "../jrd/btr.h"
|
2001-07-29 19:42:23 +02:00
|
|
|
#include "gen/ids.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/tra.h"
|
|
|
|
#include "../jrd/trig.h"
|
|
|
|
#include "../jrd/intl.h"
|
|
|
|
#include "../jrd/dflt.h"
|
|
|
|
#include "../jrd/constants.h"
|
|
|
|
#include "../jrd/ini.h"
|
|
|
|
#include "../jrd/idx.h"
|
|
|
|
#include "../jrd/gdsassert.h"
|
|
|
|
#include "../jrd/all_proto.h"
|
|
|
|
#include "../jrd/blb_proto.h"
|
|
|
|
#include "../jrd/cch_proto.h"
|
|
|
|
#include "../jrd/cmp_proto.h"
|
|
|
|
#include "../jrd/dfw_proto.h"
|
|
|
|
#include "../jrd/dpm_proto.h"
|
|
|
|
#include "../jrd/err_proto.h"
|
|
|
|
#include "../jrd/exe_proto.h"
|
|
|
|
#include "../jrd/gds_proto.h"
|
|
|
|
#include "../jrd/idx_proto.h"
|
|
|
|
#include "../jrd/ini_proto.h"
|
|
|
|
#include "../jrd/jrd_proto.h"
|
|
|
|
#include "../jrd/met_proto.h"
|
|
|
|
#include "../jrd/thd_proto.h"
|
|
|
|
#include "../jrd/obj.h"
|
|
|
|
#include "../jrd/acl.h"
|
|
|
|
#include "../jrd/irq.h"
|
|
|
|
|
|
|
|
DATABASE DB = FILENAME "ODS.RDB";
|
|
|
|
|
2001-07-12 08:32:05 +02:00
|
|
|
#define PAD(string, field) jrd_vtof ((char*)(string), field, sizeof (field))
|
2001-05-23 15:26:42 +02:00
|
|
|
#define MAX_ACL_SIZE 4096
|
|
|
|
#define DEFAULT_CLASS "SQL$DEFAULT"
|
|
|
|
|
2003-03-03 10:22:32 +01:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2001-05-23 15:26:42 +02:00
|
|
|
static void add_generator(TEXT*, BLK*);
|
2003-03-03 10:22:32 +01:00
|
|
|
#endif
|
2001-05-23 15:26:42 +02:00
|
|
|
static void add_global_fields(USHORT);
|
|
|
|
static void add_index_set(DBB, USHORT, USHORT, USHORT);
|
|
|
|
static void add_new_triggers(USHORT, USHORT);
|
|
|
|
static void add_relation_fields(USHORT);
|
2003-10-29 11:53:47 +01:00
|
|
|
static void add_security_to_sys_rel(TDBB, const TEXT*, const TEXT*, const UCHAR*,
|
|
|
|
const SSHORT);
|
2003-03-03 10:22:32 +01:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2001-05-23 15:26:42 +02:00
|
|
|
static void add_trigger(TEXT*, BLK*, BLK*);
|
2003-03-03 10:22:32 +01:00
|
|
|
#endif
|
2003-03-01 20:11:57 +01:00
|
|
|
//static void add_user_priv(TDBB, TEXT*, TEXT*, TEXT*, TEXT);
|
2003-02-13 11:11:35 +01:00
|
|
|
static void modify_relation_field(TDBB, const UCHAR*, const UCHAR*, BLK*);
|
|
|
|
static void store_generator(TDBB, const GEN*, BLK*);
|
2001-05-23 15:26:42 +02:00
|
|
|
static void store_global_field(TDBB, GFLD*, BLK*);
|
|
|
|
static void store_intlnames(TDBB, DBB);
|
2003-02-13 11:11:35 +01:00
|
|
|
static void store_message(TDBB, const TRIGMSG*, BLK*);
|
|
|
|
static void store_relation_field(TDBB, const UCHAR*, const UCHAR*, int, BLK*, int);
|
|
|
|
static void store_trigger(TDBB, const JRD_TRG*, BLK*);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* This is the table used in defining triggers; note that
|
|
|
|
RDB$TRIGGER_0 was first changed to RDB$TRIGGER_7 to make it easier to
|
|
|
|
upgrade a database to support field-level grant. It has since been
|
|
|
|
changed to RDB$TRIGGER_9 to handle SQL security on relations whose
|
|
|
|
name is > 27 characters */
|
|
|
|
|
2003-02-28 13:57:13 +01:00
|
|
|
static const JRD_TRG triggers[] =
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_1", (UCHAR) nam_user_privileges,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger3), trigger3,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_8", (UCHAR) nam_user_privileges,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(trigger2), trigger2,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_9", (UCHAR) nam_user_privileges,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(trigger1), trigger1,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_2", (UCHAR) nam_trgs,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger4), trigger4,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_3", (UCHAR) nam_trgs,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(trigger4), trigger4,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_4", (UCHAR) nam_relations,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(trigger5), trigger5,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_5", (UCHAR) nam_relations,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger6), trigger6,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_6", (UCHAR) nam_gens,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(trigger7), trigger7,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_26", (UCHAR) nam_rel_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(trigger26), trigger26,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_25", (UCHAR) nam_rel_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger25),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger25, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_10", (UCHAR) nam_rel_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(trigger10), trigger10,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_11", (UCHAR) nam_rel_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(trigger11),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger11, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_12", (UCHAR) nam_ref_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(trigger12), trigger12,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_13", (UCHAR) nam_ref_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger13),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger13, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_14", (UCHAR) nam_chk_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger14),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger14, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_15", (UCHAR) nam_chk_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(trigger15), trigger15,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_16", (UCHAR) nam_chk_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(trigger16),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger16, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_17", (UCHAR) nam_i_segments,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(trigger17), trigger17,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_18", (UCHAR) nam_i_segments,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger18),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger18, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_19", (UCHAR) nam_indices,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(trigger19), trigger19,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_20", (UCHAR) nam_indices,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger20),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger20, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_21", (UCHAR) nam_trgs,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(trigger21), trigger21,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_22", (UCHAR) nam_trgs,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger22),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger22, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_23", (UCHAR) nam_r_fields,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(trigger23), trigger23,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_24", (UCHAR) nam_r_fields,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger24),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger24, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_27", (UCHAR) nam_r_fields,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(trigger27),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger27, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_28", (UCHAR) nam_procedures,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(trigger28), trigger28,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_29", (UCHAR) nam_procedures,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger29),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger29, 0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_30", (UCHAR) nam_exceptions,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(trigger30), trigger30,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_0 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_31", (UCHAR) nam_user_privileges,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_MODIFY, sizeof(trigger31),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger31, 0, ODS_8_1 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_32", (UCHAR) nam_user_privileges,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_ERASE, sizeof(trigger31), trigger31,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_1 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_33", (UCHAR) nam_user_privileges,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.PRE_STORE, sizeof(trigger31), trigger31,
|
2001-12-24 03:51:06 +01:00
|
|
|
0, ODS_8_1 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_34", (UCHAR) nam_rel_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(trigger34),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger34, TRG_ignore_perm, ODS_8_1 },
|
2003-08-04 01:26:51 +02:00
|
|
|
{ "RDB$TRIGGER_35", (UCHAR) nam_chk_constr,
|
2001-05-23 15:26:42 +02:00
|
|
|
RDB$TRIGGERS.RDB$TRIGGER_TYPE.POST_ERASE, sizeof(trigger35),
|
2001-12-24 03:51:06 +01:00
|
|
|
trigger35, TRG_ignore_perm, ODS_8_1 },
|
|
|
|
{ 0, 0, 0, 0, 0, 0 }
|
2001-05-23 15:26:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* this table is used in defining messages for system triggers */
|
|
|
|
|
2003-02-28 13:57:13 +01:00
|
|
|
static const TRIGMSG trigger_messages[] =
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2001-12-24 03:51:06 +01:00
|
|
|
{ "RDB$TRIGGER_9", 0, "grant_obj_notfound", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_9", 1, "grant_fld_notfound", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_9", 2, "grant_nopriv", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_9", 3, "nonsql_security_rel", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_9", 4, "nonsql_security_fld", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_9", 5, "grant_nopriv_on_base", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_1", 0, "existing_priv_mod", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_2", 0, "systrig_update", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_3", 0, "systrig_update", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_5", 0, "not_rel_owner", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_24", 1, "cnstrnt_fld_rename", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_23", 1, "cnstrnt_fld_del", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_22", 1, "check_trig_update", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_21", 1, "check_trig_del", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_20", 1, "integ_index_mod", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_20", 2, "integ_index_deactivate", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_20", 3, "integ_deactivate_primary", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_19", 1, "integ_index_del", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_18", 1, "integ_index_seg_mod", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_17", 1, "integ_index_seg_del", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_15", 1, "check_cnstrnt_del", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_14", 1, "check_cnstrnt_update", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_13", 1, "ref_cnstrnt_update", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_12", 1, "ref_cnstrnt_notfound", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_12", 2, "foreign_key_notfound", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_10", 1, "primary_key_ref", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_10", 2, "primary_key_notnull", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_25", 1, "rel_cnstrnt_update", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_26", 1, "constaint_on_view", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_26", 2, "invld_cnstrnt_type", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_26", 3, "primary_key_exists", ODS_8_0 },
|
|
|
|
{ "RDB$TRIGGER_31", 0, "no_write_user_priv", ODS_8_1 },
|
|
|
|
{ "RDB$TRIGGER_32", 0, "no_write_user_priv", ODS_8_1 },
|
|
|
|
{ "RDB$TRIGGER_33", 0, "no_write_user_priv", ODS_8_1 },
|
|
|
|
{ 0, 0, 0, 0 }
|
2001-05-23 15:26:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-01-23 04:33:53 +01:00
|
|
|
void INI_format(const TEXT* owner, TEXT* charset)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* I N I _ f o r m a t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Initialize system relations in the database.
|
|
|
|
* The full complement of metadata should be
|
|
|
|
* stored here.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
TDBB tdbb;
|
|
|
|
DBB dbb;
|
|
|
|
int n;
|
2003-02-13 11:11:35 +01:00
|
|
|
const RTYP* type;
|
|
|
|
const UCHAR* relfld;
|
|
|
|
const UCHAR* fld;
|
2001-05-23 15:26:42 +02:00
|
|
|
GFLD* gfield;
|
2003-02-13 11:11:35 +01:00
|
|
|
const JRD_TRG* trigger;
|
|
|
|
const TRIGMSG* message;
|
|
|
|
const GEN* generator;
|
2001-05-23 15:26:42 +02:00
|
|
|
TEXT string[32];
|
|
|
|
TEXT* p;
|
2003-01-23 04:33:53 +01:00
|
|
|
TEXT string2[32];
|
|
|
|
TEXT* p2;
|
2001-05-23 15:26:42 +02:00
|
|
|
BLK handle1;
|
|
|
|
BLK handle2;
|
|
|
|
|
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
/* Uppercase owner name */
|
|
|
|
|
|
|
|
*string = 0;
|
|
|
|
if (owner && *owner)
|
|
|
|
{
|
|
|
|
p = string;
|
2001-12-24 03:51:06 +01:00
|
|
|
while ( (*p++ = UPPER7(*owner)) )
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
++owner;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-01-23 04:33:53 +01:00
|
|
|
/* Uppercase owner name */
|
|
|
|
|
|
|
|
*string2 = 0;
|
|
|
|
if (charset && *charset)
|
|
|
|
{
|
|
|
|
p2 = string2;
|
|
|
|
while ( (*p++ = UPPER7(*charset)) )
|
|
|
|
{
|
|
|
|
++charset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
/* Make sure relations exist already */
|
|
|
|
|
|
|
|
for (n = 0; n < (int) rel_MAX; n++) {
|
|
|
|
DPM_create_relation(tdbb, MET_relation(tdbb, (USHORT)n));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Store RELATIONS and RELATION_FIELDS */
|
|
|
|
|
|
|
|
handle1 = handle2 = NULL;
|
|
|
|
for (relfld = relfields; relfld[RFLD_R_NAME]; relfld = fld + 1)
|
|
|
|
{
|
|
|
|
for (n = 0, fld = relfld + RFLD_RPT; fld[RFLD_F_NAME];
|
|
|
|
fld += RFLD_F_LENGTH)
|
|
|
|
{
|
|
|
|
if (!fld[RFLD_F_MINOR])
|
|
|
|
{
|
|
|
|
UCHAR* pFld = (UCHAR*) fld; /* const_cast */
|
|
|
|
UCHAR* pRelFld = (UCHAR*) relfld; /* const_cast */
|
|
|
|
store_relation_field(tdbb, pFld, pRelFld, n, &handle2, TRUE);
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE handle1) X IN RDB$RELATIONS
|
|
|
|
X.RDB$RELATION_ID = relfld[RFLD_R_ID];
|
|
|
|
PAD(names[relfld[RFLD_R_NAME]], X.RDB$RELATION_NAME);
|
|
|
|
X.RDB$FIELD_ID = n;
|
|
|
|
X.RDB$FORMAT = 0;
|
|
|
|
X.RDB$SYSTEM_FLAG = RDB_system;
|
|
|
|
X.RDB$DBKEY_LENGTH = 8;
|
|
|
|
X.RDB$OWNER_NAME.NULL = TRUE;
|
|
|
|
|
|
|
|
if (*string)
|
|
|
|
{
|
|
|
|
PAD(string, X.RDB$OWNER_NAME);
|
|
|
|
X.RDB$OWNER_NAME.NULL = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
END_STORE;
|
|
|
|
}
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
|
|
|
CMP_release(tdbb, (JRD_REQ)handle2);
|
2001-05-23 15:26:42 +02:00
|
|
|
handle1 = handle2 = NULL;
|
|
|
|
|
|
|
|
/* Store global FIELDS */
|
|
|
|
|
|
|
|
for (gfield = (GFLD*) gfields; gfield->gfld_name; gfield++)
|
|
|
|
{
|
|
|
|
store_global_field(tdbb, gfield, &handle1);
|
|
|
|
}
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
handle1 = NULL;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE handle1) X IN RDB$DATABASE
|
|
|
|
X.RDB$RELATION_ID = (int) USER_DEF_REL_INIT_ID;
|
2003-01-23 04:33:53 +01:00
|
|
|
X.RDB$CHARACTER_SET_NAME.NULL = TRUE;
|
|
|
|
if (*string2) {
|
|
|
|
PAD ( string2, X.RDB$CHARACTER_SET_NAME);
|
|
|
|
X.RDB$CHARACTER_SET_NAME.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
PAD (DEFAULT_DB_CHARACTER_SET_NAME, X.RDB$CHARACTER_SET_NAME);
|
|
|
|
X.RDB$CHARACTER_SET_NAME.NULL = FALSE;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
END_STORE
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
handle1 = NULL;
|
|
|
|
|
|
|
|
/* Create indices for system relations */
|
|
|
|
add_index_set(dbb, FALSE, 0, 0);
|
|
|
|
|
|
|
|
/* Create parameter types */
|
|
|
|
|
|
|
|
handle1 = NULL;
|
|
|
|
|
|
|
|
for (type = types; type->rtyp_name; ++type)
|
|
|
|
{
|
|
|
|
STORE(REQUEST_HANDLE handle1) X IN RDB$TYPES
|
|
|
|
PAD(names[type->rtyp_field], X.RDB$FIELD_NAME);
|
|
|
|
PAD(type->rtyp_name, X.RDB$TYPE_NAME);
|
|
|
|
X.RDB$TYPE = type->rtyp_value;
|
|
|
|
X.RDB$SYSTEM_FLAG = RDB_system;
|
|
|
|
END_STORE;
|
|
|
|
}
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Store symbols for international character sets & collations */
|
|
|
|
|
|
|
|
store_intlnames(tdbb, dbb);
|
|
|
|
|
|
|
|
/* Create generators to be used by system triggers */
|
|
|
|
|
|
|
|
handle1 = NULL;
|
|
|
|
for (generator = generators; generator->gen_name; generator++)
|
|
|
|
{
|
|
|
|
store_generator(tdbb, generator, &handle1);
|
|
|
|
}
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* store system-defined triggers */
|
|
|
|
|
|
|
|
handle1 = NULL;
|
|
|
|
for (trigger = triggers; trigger->trg_relation; ++trigger)
|
|
|
|
{
|
|
|
|
store_trigger(tdbb, trigger, &handle1);
|
|
|
|
}
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* store trigger messages to go with triggers */
|
|
|
|
|
|
|
|
handle1 = NULL;
|
|
|
|
for (message = trigger_messages; message->trigmsg_name; ++message)
|
|
|
|
{
|
|
|
|
store_message(tdbb, message, &handle1);
|
|
|
|
}
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
DFW_perform_system_work();
|
|
|
|
|
|
|
|
add_relation_fields(0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
====================================================================
|
|
|
|
==
|
|
|
|
== Add security on RDB$ROLES system table
|
|
|
|
==
|
|
|
|
======================================================================
|
|
|
|
*/
|
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
UCHAR buffer[MAX_ACL_SIZE];
|
|
|
|
UCHAR* acl = buffer;
|
2001-05-23 15:26:42 +02:00
|
|
|
*acl++ = ACL_version;
|
|
|
|
*acl++ = ACL_id_list;
|
|
|
|
*acl++ = id_person;
|
2003-10-29 11:53:47 +01:00
|
|
|
|
|
|
|
const TEXT* p_1 = string;
|
|
|
|
USHORT length = strlen(string);
|
2001-05-23 15:26:42 +02:00
|
|
|
*acl++ = (UCHAR)length;
|
|
|
|
if (length)
|
|
|
|
{
|
|
|
|
do {
|
|
|
|
*acl++ = *p_1++;
|
|
|
|
} while (--length);
|
|
|
|
}
|
|
|
|
*acl++ = ACL_end;
|
|
|
|
*acl++ = ACL_priv_list;
|
|
|
|
*acl++ = priv_protect;
|
|
|
|
*acl++ = priv_control;
|
|
|
|
*acl++ = priv_delete;
|
|
|
|
*acl++ = priv_write;
|
|
|
|
*acl++ = priv_read;
|
|
|
|
*acl++ = ACL_end;
|
|
|
|
*acl++ = ACL_id_list;
|
|
|
|
*acl++ = ACL_end;
|
|
|
|
*acl++ = ACL_priv_list;
|
|
|
|
*acl++ = priv_read;
|
|
|
|
*acl++ = ACL_end;
|
|
|
|
*acl++ = ACL_end;
|
|
|
|
length = acl - buffer;
|
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
add_security_to_sys_rel(tdbb, string, "RDB$ROLES", buffer, length);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
USHORT INI_get_trig_flags(TEXT* trig_name)
|
|
|
|
{
|
|
|
|
/*********************************************
|
|
|
|
*
|
|
|
|
* I N I _ g e t _ t r i g _ f l a g s
|
|
|
|
*
|
|
|
|
*********************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Return the trigger flags for a system trigger.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-02-13 11:11:35 +01:00
|
|
|
const JRD_TRG* trig;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
for (trig = triggers; trig->trg_length > 0; trig++)
|
|
|
|
{
|
|
|
|
if (!strcmp(trig->trg_name, trig_name))
|
|
|
|
{
|
|
|
|
return (trig->trg_flags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void INI_init(void)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* I N I _ i n i t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Initialize in memory meta data. Assume that all meta data
|
|
|
|
* fields exist in the database even if this is not the case.
|
|
|
|
* Do not fill in the format length or the address in each
|
|
|
|
* format descriptor.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
DBB dbb;
|
2002-11-17 01:13:59 +01:00
|
|
|
JRD_REL relation;
|
2001-05-23 15:26:42 +02:00
|
|
|
FMT format;
|
2002-11-30 18:45:02 +01:00
|
|
|
JRD_FLD field;
|
2001-05-23 15:26:42 +02:00
|
|
|
VEC formats;
|
|
|
|
VEC fields;
|
|
|
|
int n;
|
2003-02-13 11:11:35 +01:00
|
|
|
const UCHAR* relfld;
|
|
|
|
const UCHAR* fld_;
|
2001-12-24 03:51:06 +01:00
|
|
|
fmt::fmt_desc_iterator desc;
|
2003-02-13 11:11:35 +01:00
|
|
|
const GFLD* gfield;
|
|
|
|
const JRD_TRG* trigger;
|
2001-05-23 15:26:42 +02:00
|
|
|
TDBB tdbb;
|
2001-12-24 03:51:06 +01:00
|
|
|
vec::iterator itr;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
CHECK_DBB(dbb);
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
for (relfld = relfields; relfld[RFLD_R_NAME]; relfld = fld_ + 1)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
relation = MET_relation(tdbb, relfld[RFLD_R_ID]);
|
|
|
|
relation->rel_flags |= REL_system;
|
|
|
|
relation->rel_name = (/* const_cast */ TEXT*)names[relfld[RFLD_R_NAME]];
|
|
|
|
relation->rel_length = strlen(relation->rel_name);
|
|
|
|
n = 0;
|
2001-12-24 03:51:06 +01:00
|
|
|
for (fld_ = relfld + RFLD_RPT; fld_[RFLD_F_NAME]; fld_ += RFLD_F_LENGTH)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set a flag if their is a trigger on the relation. Later we may
|
|
|
|
need to compile it. */
|
|
|
|
|
|
|
|
for (trigger = triggers; trigger->trg_relation; trigger++)
|
|
|
|
{
|
|
|
|
if (relation->rel_name == names[trigger->trg_relation])
|
|
|
|
{
|
|
|
|
relation->rel_flags |= REL_sys_triggers;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
relation->rel_fields = fields = vec::newVector(*dbb->dbb_permanent, n);
|
2002-11-30 18:45:02 +01:00
|
|
|
//field = (JRD_FLD *) fields->vec_object;
|
2001-12-24 03:51:06 +01:00
|
|
|
itr = fields->begin();
|
|
|
|
relation->rel_current_format = format = fmt::newFmt(*dbb->dbb_permanent, n);
|
|
|
|
relation->rel_formats = formats = vec::newVector(*dbb->dbb_permanent, 1);
|
|
|
|
(*formats)[0] = format;
|
2001-05-23 15:26:42 +02:00
|
|
|
format->fmt_count = n;
|
2001-12-24 03:51:06 +01:00
|
|
|
desc = format->fmt_desc.begin();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
for (fld_ = relfld + RFLD_RPT; fld_[RFLD_F_NAME];
|
|
|
|
fld_ += RFLD_F_LENGTH, desc++, itr++)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2001-12-24 03:51:06 +01:00
|
|
|
gfield = &gfields[fld_[RFLD_F_ID]];
|
2001-05-23 15:26:42 +02:00
|
|
|
desc->dsc_length = gfield->gfld_length;
|
|
|
|
desc->dsc_dtype = gfield->gfld_dtype;
|
2002-11-30 18:45:02 +01:00
|
|
|
*itr = field = FB_NEW_RPT(*dbb->dbb_permanent,0) jrd_fld();
|
2001-12-24 03:51:06 +01:00
|
|
|
field->fld_name = names[fld_[RFLD_F_NAME]];
|
|
|
|
field->fld_length = strlen(field->fld_name);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void INI_init2(void)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* I N I _ i n i t 2
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Re-initialize in memory meta data. Fill in
|
|
|
|
* format 0 based on the minor ODS version of
|
|
|
|
* the database when it was created.
|
|
|
|
*
|
|
|
|
**************************************/
|
2002-11-17 01:13:59 +01:00
|
|
|
JRD_REL relation;
|
2001-05-23 15:26:42 +02:00
|
|
|
FMT format;
|
|
|
|
int n;
|
2003-02-13 11:11:35 +01:00
|
|
|
const UCHAR* relfld;
|
|
|
|
const UCHAR* fld;
|
2001-12-24 03:51:06 +01:00
|
|
|
fmt::fmt_desc_iterator desc;
|
2001-05-23 15:26:42 +02:00
|
|
|
TDBB tdbb;
|
|
|
|
USHORT major_version;
|
|
|
|
USHORT minor_original;
|
|
|
|
USHORT id;
|
2003-02-10 14:28:35 +01:00
|
|
|
VEC vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
DBB dbb;
|
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
major_version = (SSHORT) dbb->dbb_ods_version;
|
|
|
|
minor_original = (SSHORT) dbb->dbb_minor_original;
|
|
|
|
vector = dbb->dbb_relations;
|
|
|
|
|
|
|
|
for (relfld = relfields; relfld[RFLD_R_NAME]; relfld = fld + 1)
|
|
|
|
{
|
|
|
|
if (relfld[RFLD_R_MINOR] > ENCODE_ODS(major_version, minor_original))
|
|
|
|
{
|
|
|
|
/*****************************************************
|
|
|
|
**
|
|
|
|
** free the space allocated for RDB$ROLES
|
|
|
|
**
|
|
|
|
******************************************************/
|
|
|
|
id = relfld[RFLD_R_ID];
|
2002-11-17 01:13:59 +01:00
|
|
|
relation = (JRD_REL)(*vector)[id];
|
2001-12-24 03:51:06 +01:00
|
|
|
delete relation->rel_current_format;
|
|
|
|
delete relation->rel_formats;
|
|
|
|
delete relation->rel_fields;
|
|
|
|
(*vector)[id] = NULL;
|
2001-05-23 15:26:42 +02:00
|
|
|
fld = relfld + RFLD_RPT;
|
|
|
|
while (fld[RFLD_F_NAME])
|
|
|
|
{
|
|
|
|
fld += RFLD_F_LENGTH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
relation = MET_relation(tdbb, relfld[RFLD_R_ID]);
|
|
|
|
format = relation->rel_current_format;
|
|
|
|
|
|
|
|
for (n = 0, fld = relfld + RFLD_RPT; fld[RFLD_F_NAME];
|
|
|
|
fld += RFLD_F_LENGTH)
|
|
|
|
{
|
|
|
|
/* If the ODS is less than 10, then remove all fields named
|
|
|
|
* RDB$FIELD_PRECISION and field RDB$CHARACTER_LENGTH from
|
|
|
|
* relation RDB$FUNCTION_ARGUMENTS , as they were not present
|
|
|
|
* in < 10 ODS
|
|
|
|
*/
|
2003-08-04 01:26:51 +02:00
|
|
|
if (fld[RFLD_F_NAME] == nam_f_precision ||
|
|
|
|
(fld[RFLD_F_NAME] == nam_char_length &&
|
|
|
|
relfld[RFLD_R_NAME] == nam_args))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (major_version >= ODS_VERSION10)
|
|
|
|
{
|
|
|
|
if (!fld[RFLD_F_MINOR])
|
|
|
|
{
|
|
|
|
n++;
|
|
|
|
if (fld[RFLD_F_UPD_MINOR])
|
|
|
|
relation->rel_flags |= REL_force_scan;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
relation->rel_flags |= REL_force_scan;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-11-30 22:05:51 +01:00
|
|
|
else if (fld[RFLD_F_NAME] == nam_statistics &&
|
|
|
|
relfld[RFLD_R_NAME] == nam_i_segments)
|
|
|
|
{
|
|
|
|
if (major_version >= ODS_VERSION11)
|
|
|
|
{
|
|
|
|
if (!fld[RFLD_F_MINOR])
|
|
|
|
{
|
|
|
|
n++;
|
|
|
|
if (fld[RFLD_F_UPD_MINOR])
|
|
|
|
relation->rel_flags |= REL_force_scan;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
relation->rel_flags |= REL_force_scan;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!fld[RFLD_F_MINOR])
|
|
|
|
{
|
|
|
|
n++;
|
|
|
|
if (fld[RFLD_F_UPD_MINOR])
|
|
|
|
relation->rel_flags |= REL_force_scan;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
relation->rel_flags |= REL_force_scan;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
relation->rel_fields->resize(n);
|
2001-05-23 15:26:42 +02:00
|
|
|
format->fmt_count = n;
|
|
|
|
format->fmt_length = (USHORT)FLAG_BYTES(n);
|
2001-12-24 03:51:06 +01:00
|
|
|
desc = format->fmt_desc.begin();
|
2001-05-23 15:26:42 +02:00
|
|
|
for (fld = relfld + RFLD_RPT; fld[RFLD_F_NAME];
|
|
|
|
fld += RFLD_F_LENGTH, desc++)
|
|
|
|
{
|
|
|
|
if (n-- > 0)
|
|
|
|
{
|
2002-01-04 12:34:22 +01:00
|
|
|
format->fmt_length = (USHORT)MET_align(&*desc, format->fmt_length);
|
2001-05-23 15:26:42 +02:00
|
|
|
desc->dsc_address = (UCHAR*) (SLONG) format->fmt_length;
|
|
|
|
format->fmt_length += desc->dsc_length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
JRD_TRG* INI_lookup_sys_trigger(JRD_REL relation,
|
|
|
|
JRD_TRG* trigger,
|
2003-02-13 11:11:35 +01:00
|
|
|
const UCHAR** blr,
|
2001-05-23 15:26:42 +02:00
|
|
|
UCHAR* trigger_type,
|
2003-02-13 11:11:35 +01:00
|
|
|
const SCHAR** trigger_name,
|
2001-05-23 15:26:42 +02:00
|
|
|
USHORT* trig_flags)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* I N I _ l o o k u p _ s y s _ t r i g g e r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Lookup the next trigger for a system relation.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2001-07-29 19:42:23 +02:00
|
|
|
/* function should actually return (const TRIG*) */
|
2002-11-17 01:13:59 +01:00
|
|
|
const JRD_TRG* constTrigger = (trigger) ? trigger + 1 : triggers;
|
|
|
|
trigger = const_cast<JRD_TRG*>(constTrigger);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
for (; trigger->trg_relation; trigger++)
|
|
|
|
{
|
|
|
|
if (!strcmp(relation->rel_name, names[trigger->trg_relation]))
|
|
|
|
{
|
|
|
|
*blr = trigger->trg_blr;
|
|
|
|
*trigger_type = trigger->trg_type;
|
|
|
|
*trigger_name = trigger->trg_name;
|
|
|
|
*trig_flags = trigger->trg_flags;
|
|
|
|
return trigger;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void INI_update_database(void)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* I N I _ u p d a t e _ d a t a b a s e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2001-07-12 08:32:05 +02:00
|
|
|
* Perform changes to ODS that were required
|
2001-05-23 15:26:42 +02:00
|
|
|
* since ODS 8 and are dynamically updatable.
|
|
|
|
*
|
2001-07-12 08:32:05 +02:00
|
|
|
* %% Note %% Update the switch() statement to reflect new major ODS
|
2001-05-23 15:26:42 +02:00
|
|
|
* addition
|
|
|
|
**************************************/
|
|
|
|
DBB dbb;
|
|
|
|
HDR header;
|
|
|
|
WIN window;
|
|
|
|
USHORT major_version, minor_version;
|
|
|
|
TDBB tdbb;
|
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
CHECK_DBB(dbb);
|
|
|
|
|
|
|
|
/* If database is ReadOnly, return without upgrading ODS */
|
|
|
|
if (dbb->dbb_flags & DBB_read_only)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* check out the update version to see if we have work to do */
|
|
|
|
|
|
|
|
major_version = (SSHORT) dbb->dbb_ods_version;
|
|
|
|
minor_version = (SSHORT) dbb->dbb_minor_version;
|
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
** when old engine is attaching a newer ODS database, do nothing
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
/* if database ODS is less than the server's, then upgrade */
|
|
|
|
if (ENCODE_ODS(major_version, minor_version) >= ODS_CURRENT_VERSION)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************
|
2001-07-12 08:32:05 +02:00
|
|
|
** when new engine is attaching an older ODS database
|
2001-05-23 15:26:42 +02:00
|
|
|
** perform the necessary modifications
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
if (major_version == ODS_VERSION8)
|
|
|
|
{
|
|
|
|
/*** NOTE: The following two functions/structures need to understand
|
|
|
|
the difference between major ODS versions. The structure
|
|
|
|
which holds their information needs to have an additional field
|
|
|
|
to define which major ODS version they belong to.
|
|
|
|
PENDING WORK.
|
|
|
|
add_global_fields (major_version, minor_version);
|
|
|
|
add_relation_fields (major_version, minor_version);
|
|
|
|
Look at add_new_triggers() for reference.
|
|
|
|
***/
|
|
|
|
|
|
|
|
add_global_fields(minor_version);
|
|
|
|
add_relation_fields(minor_version);
|
|
|
|
}
|
|
|
|
|
|
|
|
add_index_set(dbb, TRUE, major_version, minor_version);
|
|
|
|
add_new_triggers(major_version, minor_version);
|
|
|
|
|
|
|
|
/* if the database was updated; mark it with the current ODS minor
|
|
|
|
version so other process will attempt to do so. We mark this after
|
|
|
|
doing the update so that no other process can see the new minor
|
|
|
|
version but not the update. */
|
|
|
|
|
|
|
|
window.win_page = HEADER_PAGE;
|
|
|
|
window.win_flags = 0;
|
|
|
|
header = (HDR) CCH_FETCH(tdbb, &window, LCK_write, pag_header);
|
|
|
|
CCH_MARK(tdbb, &window);
|
|
|
|
|
2001-07-12 08:32:05 +02:00
|
|
|
/* Only minor upgrades can occur within a major ODS, define which one
|
2001-05-23 15:26:42 +02:00
|
|
|
occured here. */
|
|
|
|
switch (major_version)
|
|
|
|
{
|
|
|
|
case ODS_VERSION8:
|
|
|
|
header->hdr_ods_minor = ODS_CURRENT8;
|
|
|
|
break;
|
|
|
|
case ODS_VERSION9:
|
|
|
|
header->hdr_ods_minor = ODS_CURRENT9;
|
|
|
|
break;
|
|
|
|
case ODS_VERSION10:
|
|
|
|
header->hdr_ods_minor = ODS_CURRENT10;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Make sure we add a new case per new major ODS. Look at code above */
|
2003-11-04 00:59:24 +01:00
|
|
|
fb_assert(FALSE);
|
2001-05-23 15:26:42 +02:00
|
|
|
header->hdr_ods_minor = minor_version;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
dbb->dbb_minor_version = header->hdr_ods_minor;
|
|
|
|
CCH_RELEASE(tdbb, &window);
|
2003-03-23 10:05:35 +01:00
|
|
|
|
|
|
|
DFW_perform_system_work();
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-03-03 10:22:32 +01:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2001-05-23 15:26:42 +02:00
|
|
|
static void add_generator(TEXT* generator_name, BLK* handle)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* a d d _ g e n e r a t o r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Store a generator of the given name.
|
|
|
|
* This routine is used to upgrade ODS versions.
|
|
|
|
* DO NOT DELETE, even though it is not used
|
|
|
|
* now, since it may be used when we go to 8.1.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
TDBB tdbb;
|
2003-02-13 11:11:35 +01:00
|
|
|
const GEN* generator = generators;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
|
|
|
|
/* find the new generator to be stored; assume it exists in the table */
|
|
|
|
/* TMN: If it doesn't exist in the table, we will CRASH here! */
|
|
|
|
|
|
|
|
while (strcmp(generator->gen_name, generator_name))
|
|
|
|
{
|
|
|
|
++generator;
|
|
|
|
}
|
|
|
|
|
|
|
|
store_generator(tdbb, generator, handle);
|
|
|
|
}
|
2003-03-03 10:22:32 +01:00
|
|
|
#endif
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
static void add_global_fields( USHORT minor_version)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* a d d _ g l o b a l _ f i e l d s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Add any global fields which have a non-zero
|
|
|
|
* update number in the fields table. That
|
|
|
|
* is, those that have been added since the last
|
|
|
|
* ODS change.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
TDBB tdbb;
|
|
|
|
BLK handle;
|
|
|
|
GFLD*gfield;
|
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
|
|
|
|
/* add desired global fields to system relations */
|
|
|
|
|
|
|
|
handle = NULL;
|
|
|
|
for (gfield = (GFLD*) gfields; gfield->gfld_name; gfield++)
|
|
|
|
{
|
|
|
|
if (minor_version < gfield->gfld_minor)
|
|
|
|
{
|
|
|
|
store_global_field(tdbb, gfield, &handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (handle) {
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DFW_perform_system_work();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void add_index_set(DBB dbb,
|
|
|
|
USHORT update_ods,
|
|
|
|
USHORT major_version,
|
|
|
|
USHORT minor_version)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* a d d _ i n d e x _ s e t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Add system indices. If update_ods is TRUE we are performing
|
|
|
|
* an ODS update, and only add the indices marked as newer than
|
|
|
|
* ODS (major_version,minor_version).
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
TDBB tdbb;
|
2002-11-17 01:13:59 +01:00
|
|
|
JRD_REL relation;
|
2001-05-23 15:26:42 +02:00
|
|
|
TEXT string[32];
|
2003-02-13 11:11:35 +01:00
|
|
|
const struct ini_idx_t* index;
|
|
|
|
const ini_idx_t::ini_idx_segment_t*segment;
|
2001-05-23 15:26:42 +02:00
|
|
|
IDX idx;
|
2001-07-12 08:32:05 +02:00
|
|
|
idx::idx_repeat* tail;
|
2001-05-23 15:26:42 +02:00
|
|
|
USHORT position;
|
2002-11-30 18:45:02 +01:00
|
|
|
JRD_FLD field;
|
2001-05-23 15:26:42 +02:00
|
|
|
BLK handle1;
|
|
|
|
BLK handle2;
|
|
|
|
USHORT n;
|
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
handle1 = handle2 = NULL;
|
|
|
|
|
|
|
|
for (n = 0; n < SYSTEM_INDEX_COUNT; n++)
|
|
|
|
{
|
|
|
|
index = &indices[n];
|
|
|
|
|
|
|
|
/* For minor ODS updates, only add indices newer than on-disk ODS */
|
|
|
|
if (update_ods &&
|
|
|
|
((index->ini_idx_version_flag <=
|
|
|
|
ENCODE_ODS(major_version, minor_version)) ||
|
|
|
|
(index->ini_idx_version_flag > ODS_CURRENT_VERSION) ||
|
|
|
|
(((USHORT) DECODE_ODS_MAJOR(index->ini_idx_version_flag)) !=
|
|
|
|
major_version)))
|
|
|
|
{
|
2001-07-12 08:32:05 +02:00
|
|
|
/* The DECODE_ODS_MAJOR() is used (in this case) to instruct the server
|
2001-05-23 15:26:42 +02:00
|
|
|
to perform updates for minor ODS versions only within a major ODS */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE handle1) X IN RDB$INDICES
|
|
|
|
relation = MET_relation(tdbb, index->ini_idx_relid);
|
|
|
|
PAD(relation->rel_name, X.RDB$RELATION_NAME);
|
|
|
|
sprintf(string, "RDB$INDEX_%d", index->ini_idx_index_id);
|
|
|
|
PAD(string, X.RDB$INDEX_NAME);
|
2003-08-06 18:30:49 +02:00
|
|
|
X.RDB$UNIQUE_FLAG = index->ini_idx_flags & idx_unique;
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$SEGMENT_COUNT = index->ini_idx_segment_count;
|
2003-08-06 18:30:49 +02:00
|
|
|
if (index->ini_idx_flags & idx_descending) {
|
|
|
|
X.RDB$INDEX_TYPE.NULL = FALSE;
|
|
|
|
X.RDB$INDEX_TYPE = 1;
|
|
|
|
} else
|
|
|
|
X.RDB$INDEX_TYPE.NULL = TRUE;
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$SYSTEM_FLAG = 1;
|
|
|
|
X.RDB$INDEX_INACTIVE = 0;
|
|
|
|
|
|
|
|
/* Store each segment for the index */
|
|
|
|
|
|
|
|
for (position = 0, tail = idx.idx_rpt;
|
|
|
|
position < index->ini_idx_segment_count; position++, tail++)
|
|
|
|
{
|
|
|
|
segment = &index->ini_idx_segment[position];
|
|
|
|
STORE(REQUEST_HANDLE handle2) Y IN RDB$INDEX_SEGMENTS
|
|
|
|
field =
|
2002-11-30 18:45:02 +01:00
|
|
|
(JRD_FLD) (*relation->rel_fields)[segment->ini_idx_rfld_id];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
Y.RDB$FIELD_POSITION = position;
|
|
|
|
PAD(X.RDB$INDEX_NAME, Y.RDB$INDEX_NAME);
|
|
|
|
PAD(field->fld_name, Y.RDB$FIELD_NAME);
|
|
|
|
tail->idx_field = segment->ini_idx_rfld_id;
|
|
|
|
tail->idx_itype = segment->ini_idx_type;
|
|
|
|
END_STORE;
|
|
|
|
}
|
|
|
|
idx.idx_count = index->ini_idx_segment_count;
|
2003-08-06 18:30:49 +02:00
|
|
|
idx.idx_flags = index->ini_idx_flags;
|
2003-11-30 22:05:51 +01:00
|
|
|
SelectivityList selectivity(tdbb->tdbb_default);
|
2003-08-28 15:16:03 +02:00
|
|
|
IDX_create_index(tdbb, relation, &idx, (UCHAR*)string, NULL, NULL,
|
2003-11-30 22:05:51 +01:00
|
|
|
selectivity);
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$INDEX_ID = idx.idx_id + 1;
|
|
|
|
END_STORE;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (handle1) {
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
if (handle2) {
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle2);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void add_new_triggers(USHORT major_version, USHORT minor_version)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* a d d _ n e w _ t r i g g e r s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2001-07-12 08:32:05 +02:00
|
|
|
* Store all new ODS 8.x (x > 0) triggers.
|
2001-05-23 15:26:42 +02:00
|
|
|
* The major and minor_version passed in are the ODS versions
|
2001-07-12 08:32:05 +02:00
|
|
|
* before the ODS is upgraded.
|
2001-05-23 15:26:42 +02:00
|
|
|
* This routine is used to upgrade ODS versions.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
TDBB tdbb;
|
2003-02-13 11:11:35 +01:00
|
|
|
const JRD_TRG* trig;
|
|
|
|
const TRIGMSG* message;
|
2001-05-23 15:26:42 +02:00
|
|
|
BLK handle1;
|
|
|
|
BLK handle2;
|
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
|
|
|
|
handle1 = handle2 = NULL;
|
|
|
|
|
|
|
|
/* add all new triggers, that were added since the database was created */
|
|
|
|
for (trig = triggers; trig->trg_length > 0; trig++)
|
|
|
|
{
|
|
|
|
if ((trig->trg_ods_version > ENCODE_ODS(major_version, minor_version))
|
|
|
|
&& (DECODE_ODS_MAJOR(trig->trg_ods_version) == major_version))
|
|
|
|
{
|
|
|
|
store_trigger(tdbb, trig, &handle1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (message = trigger_messages; message->trigmsg_name; message++)
|
|
|
|
{
|
|
|
|
if ((message->trg_ods_version >
|
|
|
|
ENCODE_ODS(major_version, minor_version)) &&
|
|
|
|
(DECODE_ODS_MAJOR(message->trg_ods_version) == major_version))
|
|
|
|
{
|
|
|
|
store_message(tdbb, message, &handle2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (handle1) {
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
if (handle2) {
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle2);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void add_relation_fields( USHORT minor_version)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* a d d _ r e l a t i o n _ f i e l d s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Add any local fields which have a non-zero
|
|
|
|
* update number in the relfields table. That
|
|
|
|
* is, those that have been added since the last
|
|
|
|
* ODS change.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
TDBB tdbb;
|
|
|
|
DBB dbb;
|
|
|
|
DSC desc;
|
|
|
|
BLK s_handle;
|
|
|
|
BLK m_handle;
|
2003-02-13 11:11:35 +01:00
|
|
|
const UCHAR* fld;
|
|
|
|
const UCHAR* relfld;
|
2001-05-23 15:26:42 +02:00
|
|
|
int n;
|
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
/* add desired fields to system relations, forcing a new format version */
|
|
|
|
|
|
|
|
s_handle = m_handle = NULL;
|
|
|
|
for (relfld = relfields; relfld[RFLD_R_NAME]; relfld = fld + 1)
|
|
|
|
{
|
|
|
|
for (n = 0, fld = relfld + RFLD_RPT; fld[RFLD_F_NAME];
|
|
|
|
n++, fld += RFLD_F_LENGTH)
|
|
|
|
{
|
|
|
|
if (minor_version < fld[RFLD_F_MINOR] ||
|
|
|
|
minor_version < fld[RFLD_F_UPD_MINOR])
|
|
|
|
{
|
|
|
|
if (minor_version < fld[RFLD_F_MINOR])
|
|
|
|
{
|
|
|
|
store_relation_field(tdbb, fld, relfld, n, &s_handle,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
modify_relation_field(tdbb, fld, relfld, &m_handle);
|
|
|
|
}
|
|
|
|
desc.dsc_dtype = dtype_text;
|
|
|
|
INTL_ASSIGN_DSC(&desc, CS_METADATA, COLLATE_NONE);
|
|
|
|
desc.dsc_address = (UCHAR*) names[relfld[RFLD_R_NAME]];
|
2001-07-12 08:32:05 +02:00
|
|
|
desc.dsc_length = strlen((char*)desc.dsc_address);
|
2001-05-23 15:26:42 +02:00
|
|
|
DFW_post_work(dbb->dbb_sys_trans, dfw_update_format, &desc, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s_handle) {
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)s_handle);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
if (m_handle) {
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)m_handle);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DFW_perform_system_work();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
// The caller used an UCHAR* to store the acl, it was converted to TEXT* to
|
|
|
|
// be passed to this function, only to be converted to UCHAR* to be passed
|
|
|
|
// to BLB_put_segment. Therefore, "acl" was changed to UCHAR* as param.
|
2001-05-23 15:26:42 +02:00
|
|
|
static void add_security_to_sys_rel(TDBB tdbb,
|
2003-10-29 11:53:47 +01:00
|
|
|
const TEXT* user_name,
|
|
|
|
const TEXT* rel_name,
|
|
|
|
const UCHAR* acl,
|
|
|
|
const SSHORT acl_length)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* a d d _ s e c u r i t y _ t o _ s y s _ r e l
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
*
|
2001-07-12 08:32:05 +02:00
|
|
|
* Add security to system relations. Only the owner of the
|
2001-05-23 15:26:42 +02:00
|
|
|
* database has SELECT/INSERT/UPDATE/DELETE privileges on
|
|
|
|
* any system relations. Any other users only has SELECT
|
|
|
|
* privilege.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
DBB dbb;
|
2003-11-11 13:19:20 +01:00
|
|
|
ISC_QUAD blob_id_1, blob_id_2;
|
2001-05-23 15:26:42 +02:00
|
|
|
BLB blob;
|
|
|
|
BLK handle1;
|
|
|
|
TEXT sec_class_name[100];
|
|
|
|
TEXT default_class[32];
|
|
|
|
SSHORT cnt;
|
|
|
|
|
|
|
|
SET_TDBB(tdbb);
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
strcpy(sec_class_name, "SQL$");
|
|
|
|
strcat(sec_class_name, rel_name);
|
|
|
|
|
|
|
|
blob = BLB_create(tdbb, dbb->dbb_sys_trans, (BID)&blob_id_1);
|
2003-10-29 11:53:47 +01:00
|
|
|
BLB_put_segment(tdbb, blob, acl, acl_length);
|
2001-05-23 15:26:42 +02:00
|
|
|
BLB_close(tdbb, blob);
|
|
|
|
|
|
|
|
blob = BLB_create(tdbb, dbb->dbb_sys_trans, (BID)&blob_id_2);
|
2003-10-29 11:53:47 +01:00
|
|
|
BLB_put_segment(tdbb, blob, acl, acl_length);
|
2001-05-23 15:26:42 +02:00
|
|
|
BLB_close(tdbb, blob);
|
|
|
|
|
2003-02-18 08:15:15 +01:00
|
|
|
sprintf(default_class, "%s%" QUADFORMAT "d", DEFAULT_CLASS,
|
2001-05-23 15:26:42 +02:00
|
|
|
DPM_gen_id(tdbb, MET_lookup_generator(tdbb, DEFAULT_CLASS),
|
|
|
|
0, (SINT64) 1));
|
|
|
|
|
|
|
|
for (cnt = 0; cnt < 6; cnt++)
|
|
|
|
{
|
|
|
|
handle1 = NULL;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE handle1) PRIV IN RDB$USER_PRIVILEGES
|
|
|
|
switch (cnt)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
strcpy(PRIV.RDB$USER, user_name);
|
|
|
|
PRIV.RDB$PRIVILEGE[0] = 'S';
|
|
|
|
PRIV.RDB$GRANT_OPTION = 1;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
strcpy(PRIV.RDB$USER, user_name);
|
|
|
|
PRIV.RDB$PRIVILEGE[0] = 'I';
|
|
|
|
PRIV.RDB$GRANT_OPTION = 1;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
strcpy(PRIV.RDB$USER, user_name);
|
|
|
|
PRIV.RDB$PRIVILEGE[0] = 'U';
|
|
|
|
PRIV.RDB$GRANT_OPTION = 1;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
strcpy(PRIV.RDB$USER, user_name);
|
|
|
|
PRIV.RDB$PRIVILEGE[0] = 'D';
|
|
|
|
PRIV.RDB$GRANT_OPTION = 1;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
strcpy(PRIV.RDB$USER, user_name);
|
|
|
|
PRIV.RDB$PRIVILEGE[0] = 'R';
|
|
|
|
PRIV.RDB$GRANT_OPTION = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
strcpy(PRIV.RDB$USER, "PUBLIC");
|
|
|
|
PRIV.RDB$PRIVILEGE[0] = 'S';
|
|
|
|
PRIV.RDB$GRANT_OPTION = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
strcpy(PRIV.RDB$GRANTOR, user_name);
|
|
|
|
PRIV.RDB$PRIVILEGE[1] = 0;
|
|
|
|
strcpy(PRIV.RDB$RELATION_NAME, rel_name);
|
|
|
|
PRIV.RDB$FIELD_NAME.NULL = TRUE;
|
|
|
|
PRIV.RDB$USER_TYPE = obj_user;
|
|
|
|
PRIV.RDB$OBJECT_TYPE = obj_relation;
|
|
|
|
END_STORE;
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
handle1 = NULL;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE handle1)
|
|
|
|
CLS IN RDB$SECURITY_CLASSES
|
2001-07-12 08:32:05 +02:00
|
|
|
jrd_vtof((char*)sec_class_name, CLS.RDB$SECURITY_CLASS,
|
2001-05-23 15:26:42 +02:00
|
|
|
sizeof(CLS.RDB$SECURITY_CLASS));
|
|
|
|
CLS.RDB$ACL = blob_id_1;
|
|
|
|
END_STORE;
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
handle1 = NULL;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE handle1)
|
|
|
|
CLS IN RDB$SECURITY_CLASSES
|
2001-07-12 08:32:05 +02:00
|
|
|
jrd_vtof((char*)default_class, CLS.RDB$SECURITY_CLASS,
|
2001-05-23 15:26:42 +02:00
|
|
|
sizeof(CLS.RDB$SECURITY_CLASS));
|
|
|
|
CLS.RDB$ACL = blob_id_2;
|
|
|
|
END_STORE;
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
handle1 = NULL;
|
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE handle1) REL IN RDB$RELATIONS
|
|
|
|
WITH REL.RDB$RELATION_NAME EQ rel_name
|
|
|
|
MODIFY REL USING
|
|
|
|
REL.RDB$DEFAULT_CLASS.NULL = FALSE;
|
2001-07-12 08:32:05 +02:00
|
|
|
jrd_vtof((char*)default_class, REL.RDB$DEFAULT_CLASS,
|
2001-05-23 15:26:42 +02:00
|
|
|
sizeof(REL.RDB$DEFAULT_CLASS));
|
|
|
|
END_MODIFY;
|
|
|
|
|
|
|
|
END_FOR;
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle1);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-03-03 10:22:32 +01:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2001-05-23 15:26:42 +02:00
|
|
|
static void add_trigger(TEXT* trigger_name, BLK* handle1, BLK* handle2)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* a d d _ t r i g g e r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Store a trigger of the given name.
|
|
|
|
* This routine is used to upgrade ODS versions.
|
|
|
|
* DO NOT DELETE, even though it is not used
|
|
|
|
* now, since it will be used when we go to 8.1.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
TDBB tdbb;
|
2003-02-13 11:11:35 +01:00
|
|
|
const JRD_TRG* trigger;
|
|
|
|
const TRIGMSG* message;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
tdbb = GET_THREAD_DATA;
|
|
|
|
|
|
|
|
/* Find the new trigger to be stored; assume it exists in the table */
|
|
|
|
|
|
|
|
trigger = triggers;
|
|
|
|
while (strcmp(trigger->trg_name, trigger_name))
|
|
|
|
{
|
|
|
|
++trigger;
|
|
|
|
}
|
|
|
|
|
|
|
|
store_trigger(tdbb, trigger, handle1);
|
|
|
|
|
|
|
|
/* Look for any related trigger messages */
|
|
|
|
|
|
|
|
for (message = trigger_messages; message->trigmsg_name; ++message)
|
|
|
|
{
|
|
|
|
if (!strcmp(message->trigmsg_name, trigger->trg_name))
|
|
|
|
{
|
|
|
|
store_message(tdbb, message, handle2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-03-03 10:22:32 +01:00
|
|
|
#endif
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
static void modify_relation_field(TDBB tdbb,
|
2003-02-13 11:11:35 +01:00
|
|
|
const UCHAR* fld,
|
|
|
|
const UCHAR* relfld,
|
2001-05-23 15:26:42 +02:00
|
|
|
BLK* handle)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* m o d i f y _ r e l a t i o n _ f i e l d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2001-07-12 08:32:05 +02:00
|
|
|
* Modify a local field according to the
|
2001-05-23 15:26:42 +02:00
|
|
|
* passed information. Note that the field id and
|
|
|
|
* field position do not change.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
DBB dbb;
|
2003-02-13 11:11:35 +01:00
|
|
|
const GFLD* gfield;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
SET_TDBB(tdbb);
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE * handle) X IN RDB$RELATION_FIELDS WITH
|
|
|
|
X.RDB$RELATION_NAME EQ names[relfld[RFLD_R_NAME]] AND
|
|
|
|
X.RDB$FIELD_NAME EQ names[fld[RFLD_F_NAME]]
|
|
|
|
MODIFY X USING
|
|
|
|
gfield = &gfields[fld[RFLD_F_UPD_ID]];
|
|
|
|
PAD(names[gfield->gfld_name], X.RDB$FIELD_SOURCE);
|
|
|
|
X.RDB$UPDATE_FLAG = fld[RFLD_F_UPDATE];
|
|
|
|
END_MODIFY;
|
|
|
|
END_FOR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-13 11:11:35 +01:00
|
|
|
static void store_generator(TDBB tdbb, const GEN* generator, BLK* handle)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s t o r e _ g e n e r a t o r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2001-07-12 08:32:05 +02:00
|
|
|
* Store the passed generator according to
|
2001-05-23 15:26:42 +02:00
|
|
|
* the information in the generator block.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
DBB dbb;
|
|
|
|
|
|
|
|
SET_TDBB(tdbb);
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE * handle) X IN RDB$GENERATORS
|
|
|
|
PAD(generator->gen_name, X.RDB$GENERATOR_NAME);
|
|
|
|
X.RDB$GENERATOR_ID = generator->gen_id;
|
|
|
|
X.RDB$SYSTEM_FLAG = RDB_system;
|
|
|
|
END_STORE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void store_global_field(TDBB tdbb, GFLD* gfield, BLK* handle)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s t o r e _ g l o b a l _ f i e l d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2001-07-12 08:32:05 +02:00
|
|
|
* Store a global field according to the
|
2001-05-23 15:26:42 +02:00
|
|
|
* passed information.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
DBB dbb;
|
2002-11-17 01:13:59 +01:00
|
|
|
JRD_TRA trans;
|
2001-05-23 15:26:42 +02:00
|
|
|
struct blb *blob;
|
|
|
|
|
|
|
|
SET_TDBB(tdbb);
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
trans = dbb->dbb_sys_trans;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE * handle) X IN RDB$FIELDS
|
|
|
|
PAD(names[gfield->gfld_name], X.RDB$FIELD_NAME);
|
|
|
|
X.RDB$FIELD_LENGTH = gfield->gfld_length;
|
|
|
|
X.RDB$FIELD_SCALE = 0;
|
|
|
|
X.RDB$SYSTEM_FLAG = RDB_system;
|
|
|
|
X.RDB$FIELD_SUB_TYPE.NULL = TRUE;
|
|
|
|
X.RDB$CHARACTER_SET_ID.NULL = TRUE;
|
|
|
|
X.RDB$COLLATION_ID.NULL = TRUE;
|
|
|
|
X.RDB$SEGMENT_LENGTH.NULL = TRUE;
|
|
|
|
if (gfield->gfld_dflt_blr)
|
|
|
|
{
|
|
|
|
blob = BLB_create(tdbb, trans, (BID)&X.RDB$DEFAULT_VALUE);
|
|
|
|
BLB_put_segment(tdbb,
|
|
|
|
blob,
|
|
|
|
(UCHAR*)gfield->gfld_dflt_blr,
|
|
|
|
gfield->gfld_dflt_len);
|
|
|
|
BLB_close(tdbb, blob);
|
|
|
|
X.RDB$DEFAULT_VALUE.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
X.RDB$DEFAULT_VALUE.NULL = TRUE;
|
|
|
|
}
|
|
|
|
switch (gfield->gfld_dtype)
|
|
|
|
{
|
|
|
|
case dtype_timestamp:
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_timestamp;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_sql_time:
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_sql_time;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_sql_date:
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_sql_date;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_short:
|
|
|
|
case dtype_long:
|
|
|
|
case dtype_int64:
|
|
|
|
if (gfield->gfld_dtype == dtype_short)
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_short;
|
|
|
|
else if (gfield->gfld_dtype == dtype_long)
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_long;
|
|
|
|
else
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_int64;
|
|
|
|
if ((gfield->gfld_sub_type == dsc_num_type_numeric) ||
|
|
|
|
(gfield->gfld_sub_type == dsc_num_type_decimal))
|
|
|
|
{
|
|
|
|
X.RDB$FIELD_SUB_TYPE.NULL = FALSE;
|
|
|
|
X.RDB$FIELD_SUB_TYPE = gfield->gfld_sub_type;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_double:
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_double;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_text:
|
|
|
|
case dtype_varying:
|
|
|
|
if (gfield->gfld_dtype == dtype_text)
|
|
|
|
{
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_text;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_varying;
|
|
|
|
X.RDB$FIELD_LENGTH -= sizeof(USHORT);
|
|
|
|
}
|
|
|
|
if (gfield->gfld_sub_type == dsc_text_type_metadata)
|
|
|
|
{
|
|
|
|
X.RDB$CHARACTER_SET_ID.NULL = FALSE;
|
|
|
|
X.RDB$CHARACTER_SET_ID = CS_METADATA;
|
|
|
|
X.RDB$COLLATION_ID.NULL = FALSE;
|
|
|
|
X.RDB$COLLATION_ID = COLLATE_NONE;
|
|
|
|
X.RDB$FIELD_SUB_TYPE.NULL = FALSE;
|
|
|
|
X.RDB$FIELD_SUB_TYPE = gfield->gfld_sub_type;
|
|
|
|
}
|
2003-09-19 15:56:48 +02:00
|
|
|
else if (gfield->gfld_sub_type == dsc_text_type_fixed)
|
|
|
|
{
|
|
|
|
X.RDB$CHARACTER_SET_ID.NULL = FALSE;
|
|
|
|
X.RDB$CHARACTER_SET_ID = CS_BINARY;
|
|
|
|
X.RDB$COLLATION_ID.NULL = FALSE;
|
|
|
|
X.RDB$COLLATION_ID = COLLATE_NONE;
|
|
|
|
X.RDB$FIELD_SUB_TYPE.NULL = FALSE;
|
|
|
|
X.RDB$FIELD_SUB_TYPE = gfield->gfld_sub_type;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
X.RDB$CHARACTER_SET_ID.NULL = FALSE;
|
|
|
|
X.RDB$CHARACTER_SET_ID = CS_NONE;
|
|
|
|
X.RDB$COLLATION_ID.NULL = FALSE;
|
|
|
|
X.RDB$COLLATION_ID = COLLATE_NONE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_blob:
|
|
|
|
X.RDB$FIELD_TYPE = (int) blr_blob;
|
|
|
|
X.RDB$FIELD_SUB_TYPE.NULL = FALSE;
|
|
|
|
X.RDB$SEGMENT_LENGTH.NULL = FALSE;
|
|
|
|
X.RDB$FIELD_SUB_TYPE = gfield->gfld_sub_type;
|
|
|
|
X.RDB$SEGMENT_LENGTH = 80;
|
|
|
|
if (gfield->gfld_sub_type == BLOB_text)
|
|
|
|
{
|
|
|
|
X.RDB$CHARACTER_SET_ID.NULL = FALSE;
|
|
|
|
X.RDB$CHARACTER_SET_ID = CS_METADATA;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-11-04 00:59:24 +01:00
|
|
|
fb_assert(FALSE);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
END_STORE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void store_intlnames(TDBB tdbb, DBB dbb)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
2001-07-12 08:32:05 +02:00
|
|
|
* s t o r e _ i n t l n a m e s
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Store symbolic names & information for international
|
|
|
|
* character sets & collations.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-02-13 11:11:35 +01:00
|
|
|
const CS_TYPE* csptr;
|
|
|
|
const COLL_TYPE* collptr;
|
2001-05-23 15:26:42 +02:00
|
|
|
BLK handle;
|
|
|
|
|
|
|
|
SET_TDBB(tdbb);
|
|
|
|
|
|
|
|
handle = NULL;
|
|
|
|
for (csptr = cs_types; csptr->init_charset_name; csptr++)
|
|
|
|
{
|
|
|
|
STORE(REQUEST_HANDLE handle) X IN RDB$CHARACTER_SETS USING
|
|
|
|
PAD(csptr->init_charset_name, X.RDB$CHARACTER_SET_NAME);
|
|
|
|
PAD(csptr->init_charset_name, X.RDB$DEFAULT_COLLATE_NAME);
|
|
|
|
X.RDB$CHARACTER_SET_ID = csptr->init_charset_id;
|
|
|
|
X.RDB$BYTES_PER_CHARACTER = csptr->init_charset_bytes_per_char;
|
|
|
|
X.RDB$SYSTEM_FLAG = RDB_system;
|
|
|
|
END_STORE;
|
|
|
|
}
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle);
|
2001-05-23 15:26:42 +02:00
|
|
|
handle = NULL;
|
|
|
|
|
|
|
|
for (collptr = coll_types; collptr->init_collation_name; collptr++)
|
|
|
|
{
|
|
|
|
STORE(REQUEST_HANDLE handle) X IN RDB$COLLATIONS USING
|
|
|
|
PAD(collptr->init_collation_name, X.RDB$COLLATION_NAME);
|
|
|
|
X.RDB$CHARACTER_SET_ID = collptr->init_collation_charset;
|
|
|
|
X.RDB$COLLATION_ID = collptr->init_collation_id;
|
|
|
|
X.RDB$SYSTEM_FLAG = RDB_system;
|
|
|
|
END_STORE;
|
|
|
|
}
|
|
|
|
|
2002-11-17 01:13:59 +01:00
|
|
|
CMP_release(tdbb, (JRD_REQ)handle);
|
2001-05-23 15:26:42 +02:00
|
|
|
handle = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-13 11:11:35 +01:00
|
|
|
static void store_message(TDBB tdbb, const TRIGMSG* message, BLK* handle)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s t o r e _ m e s s a g e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Store system trigger messages.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
DBB dbb;
|
|
|
|
|
|
|
|
SET_TDBB(tdbb);
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
/* store the trigger */
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE * handle) X IN RDB$TRIGGER_MESSAGES
|
|
|
|
PAD(message->trigmsg_name, X.RDB$TRIGGER_NAME);
|
|
|
|
X.RDB$MESSAGE_NUMBER = message->trigmsg_number;
|
|
|
|
PAD(message->trigmsg_text, X.RDB$MESSAGE);
|
|
|
|
END_STORE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void store_relation_field(TDBB tdbb,
|
2003-02-13 11:11:35 +01:00
|
|
|
const UCHAR* fld,
|
|
|
|
const UCHAR* relfld,
|
2001-05-23 15:26:42 +02:00
|
|
|
int field_id,
|
|
|
|
BLK* handle,
|
|
|
|
int fmt0_flag)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s t o r e _ r e l a t i o n _ f i e l d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2001-07-12 08:32:05 +02:00
|
|
|
* Store a local field according to the
|
2001-05-23 15:26:42 +02:00
|
|
|
* passed information.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
DBB dbb;
|
2003-02-13 11:11:35 +01:00
|
|
|
const GFLD* gfield;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
SET_TDBB(tdbb);
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE * handle) X IN RDB$RELATION_FIELDS
|
|
|
|
gfield = (fld[RFLD_F_UPD_MINOR] && !fmt0_flag) ?
|
|
|
|
&gfields[fld[RFLD_F_UPD_ID]] : &gfields[fld[RFLD_F_ID]];
|
|
|
|
PAD(names[relfld[RFLD_R_NAME]], X.RDB$RELATION_NAME);
|
|
|
|
PAD(names[fld[RFLD_F_NAME]], X.RDB$FIELD_NAME);
|
|
|
|
PAD(names[gfield->gfld_name], X.RDB$FIELD_SOURCE);
|
|
|
|
X.RDB$FIELD_POSITION = field_id;
|
|
|
|
X.RDB$FIELD_ID = field_id;
|
|
|
|
X.RDB$SYSTEM_FLAG = RDB_system;
|
|
|
|
X.RDB$UPDATE_FLAG = fld[RFLD_F_UPDATE];
|
|
|
|
END_STORE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-13 11:11:35 +01:00
|
|
|
static void store_trigger(TDBB tdbb, const JRD_TRG* trigger, BLK* handle)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s t o r e _ t r i g g e r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2001-07-12 08:32:05 +02:00
|
|
|
* Store the trigger according to the
|
2001-05-23 15:26:42 +02:00
|
|
|
* information in the trigger block.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
DBB dbb;
|
2002-11-17 01:13:59 +01:00
|
|
|
JRD_TRA trans;
|
2001-05-23 15:26:42 +02:00
|
|
|
DSC desc;
|
|
|
|
struct blb *blob;
|
|
|
|
|
|
|
|
SET_TDBB(tdbb);
|
|
|
|
dbb = tdbb->tdbb_database;
|
|
|
|
|
|
|
|
trans = dbb->dbb_sys_trans;
|
|
|
|
|
|
|
|
/* indicate that the relation format needs revising */
|
|
|
|
|
|
|
|
desc.dsc_dtype = dtype_text;
|
|
|
|
INTL_ASSIGN_DSC(&desc, CS_METADATA, COLLATE_NONE);
|
|
|
|
desc.dsc_address = (UCHAR*) names[trigger->trg_relation];
|
2001-07-12 08:32:05 +02:00
|
|
|
desc.dsc_length = strlen((char*)desc.dsc_address);
|
2001-05-23 15:26:42 +02:00
|
|
|
DFW_post_work(trans, dfw_update_format, &desc, 0);
|
|
|
|
|
|
|
|
/* store the trigger */
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE * handle) X IN RDB$TRIGGERS
|
|
|
|
PAD(trigger->trg_name, X.RDB$TRIGGER_NAME);
|
|
|
|
PAD(names[trigger->trg_relation], X.RDB$RELATION_NAME);
|
|
|
|
X.RDB$TRIGGER_SEQUENCE = 0;
|
|
|
|
X.RDB$SYSTEM_FLAG = RDB_system;
|
|
|
|
X.RDB$TRIGGER_TYPE = trigger->trg_type;
|
|
|
|
X.RDB$FLAGS = trigger->trg_flags;
|
|
|
|
blob = BLB_create(tdbb, trans, (BID)&X.RDB$TRIGGER_BLR);
|
|
|
|
BLB_put_segment(tdbb,
|
|
|
|
blob,
|
|
|
|
(UCHAR*)trigger->trg_blr,
|
|
|
|
trigger->trg_length);
|
|
|
|
BLB_close(tdbb, blob);
|
|
|
|
END_STORE;
|
2001-07-12 08:32:05 +02:00
|
|
|
}
|