8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-25 04:43:03 +01:00
firebird-mirror/src/jrd/dyn_util.epp

844 lines
22 KiB
Plaintext
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: JRD Data Definition Utility
* MODULE: dyn_util.epp
2001-05-23 15:26:42 +02:00
* DESCRIPTION: Dynamic data definition - utility functions
*
* 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): ______________________________________.
*
* 2002-02-24 Sean Leyne - Code Cleanup of old Win 3.1 port (WINDOWS_ONLY)
*
2001-05-23 15:26:42 +02:00
*/
#include "firebird.h"
2001-05-23 15:26:42 +02:00
#include <stdio.h>
#include <string.h>
#include "../jrd/common.h"
#include "../jrd/jrd.h"
#include "../jrd/tra.h"
#include "../jrd/scl.h"
#include "../jrd/drq.h"
#include "../jrd/flags.h"
2003-11-08 17:40:17 +01:00
#include "../jrd/ibase.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/lls.h"
#include "../jrd/met.h"
#include "../jrd/btr.h"
#include "../jrd/intl.h"
#include "../jrd/dyn.h"
2003-10-20 12:53:52 +02:00
#include "../jrd/ods.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/blb_proto.h"
#include "../jrd/cmp_proto.h"
#include "../jrd/dyn_proto.h"
#include "../jrd/dyn_md_proto.h"
#include "../jrd/dyn_ut_proto.h"
#include "../jrd/err_proto.h"
#include "../jrd/exe_proto.h"
#include "../jrd/gds_proto.h"
#include "../jrd/inf_proto.h"
#include "../jrd/intl_proto.h"
#include "../jrd/isc_f_proto.h"
#include "../jrd/vio_proto.h"
2008-01-16 09:46:02 +01:00
#include "../common/utils_proto.h"
2001-05-23 15:26:42 +02:00
using MsgFormat::SafeArg;
using namespace Jrd;
DATABASE DB = STATIC "ODS.RDB";
2001-05-23 15:26:42 +02:00
2008-12-18 11:57:12 +01:00
static const SCHAR gen_id_blr1[] =
{
2001-05-23 15:26:42 +02:00
blr_version5,
blr_begin,
blr_message, 0, 1, 0,
blr_int64, 0,
blr_begin,
blr_send, 0,
blr_begin,
blr_assignment,
blr_gen_id
};
2008-12-18 11:57:12 +01:00
static const SCHAR gen_id_blr2[] =
{
2001-05-23 15:26:42 +02:00
blr_literal, blr_long, 0, 1, 0, 0, 0,
blr_parameter, 0, 0, 0, blr_end, blr_end, blr_end, blr_eoc
};
2001-05-23 15:26:42 +02:00
2008-12-18 11:57:12 +01:00
static const UCHAR prot_blr[] =
{
2001-05-23 15:26:42 +02:00
blr_version5,
blr_begin,
blr_message, 1, 1, 0,
blr_short, 0,
blr_message, 0, 2, 0,
blr_cstring, 32, 0,
blr_cstring, 32, 0,
blr_receive, 0,
blr_begin,
blr_send, 1,
blr_begin,
blr_assignment,
blr_prot_mask,
blr_parameter, 0, 0, 0,
blr_parameter, 0, 1, 0,
blr_parameter, 1, 0, 0,
blr_end,
blr_end,
blr_end,
blr_eoc
};
SINT64 DYN_UTIL_gen_unique_id(thread_db* tdbb,
Global* gbl,
SSHORT id,
const char* generator_name)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ U T I L _ g e n _ u n i q u e _ i d
2001-05-23 15:26:42 +02:00
*
**************************************
*
* Functional description
* Generate a unique id using a generator.
*
**************************************/
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = CMP_find_request(tdbb, id, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
SINT64 value = 0;
try
2001-05-23 15:26:42 +02:00
{
if (!request)
{
const size_t name_length = strlen(generator_name);
2008-09-06 13:39:00 +02:00
fb_assert(name_length < MAX_SQL_IDENTIFIER_SIZE);
const size_t blr_size = sizeof(gen_id_blr1) + sizeof(gen_id_blr2) + 1 + name_length;
Firebird::UCharBuffer blr;
UCHAR* p = blr.getBuffer(blr_size);
memcpy(p, gen_id_blr1, sizeof(gen_id_blr1));
p += sizeof(gen_id_blr1);
*p++ = name_length;
memcpy(p, generator_name, name_length);
p += name_length;
memcpy(p, gen_id_blr2, sizeof(gen_id_blr2));
p += sizeof(gen_id_blr2);
request = CMP_compile2(tdbb, blr.begin(), TRUE);
}
EXE_start(tdbb, request, dbb->dbb_sys_trans);
EXE_receive(tdbb, request, 0, sizeof(value), (UCHAR*) &value);
EXE_unwind(tdbb, request);
}
catch (const Firebird::Exception&)
{
DYN_rundown_request(request, id);
throw;
2001-05-23 15:26:42 +02:00
}
if (!DYN_REQUEST(id)) {
DYN_REQUEST(id) = request;
2001-05-23 15:26:42 +02:00
}
return value;
}
void DYN_UTIL_generate_constraint_name( thread_db* tdbb, Global* gbl, Firebird::MetaName& buffer)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ U T I L _ g e n e r a t e _ c o n s t r a i n t _ n a m e
2001-05-23 15:26:42 +02:00
*
**************************************
*
* Functional description
* Generate a name unique to RDB$RELATION_CONSTRAINTS.
*
**************************************/
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = NULL;
2004-03-07 08:58:55 +01:00
SSHORT id = -1;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
2001-05-23 15:26:42 +02:00
bool found = false;
2008-12-18 11:57:12 +01:00
2001-05-23 15:26:42 +02:00
do {
2006-05-04 02:02:58 +02:00
buffer.printf("INTEG_%" SQUADFORMAT,
2008-12-18 11:57:12 +01:00
(SINT64) DYN_UTIL_gen_unique_id(tdbb, gbl, drq_g_nxt_con, "RDB$CONSTRAINT_NAME"));
2001-05-23 15:26:42 +02:00
request = CMP_find_request(tdbb, drq_f_nxt_con, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_f_nxt_con;
found = false;
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request)
FIRST 1 X IN RDB$RELATION_CONSTRAINTS
WITH X.RDB$CONSTRAINT_NAME EQ buffer.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_f_nxt_con))
DYN_REQUEST(drq_f_nxt_con) = request;
found = true;
2001-05-23 15:26:42 +02:00
END_FOR;
if (!DYN_REQUEST(drq_f_nxt_con))
DYN_REQUEST(drq_f_nxt_con) = request;
request = NULL;
} while (found);
2001-12-24 03:51:06 +01:00
} // try
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, id);
DYN_error_punt(true, 131);
2001-12-24 03:51:06 +01:00
/* msg 131: "Generation of constraint name failed" */
}
2001-05-23 15:26:42 +02:00
}
void DYN_UTIL_generate_field_name( thread_db* tdbb, Global* gbl, TEXT* buffer)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ U T I L _ g e n e r a t e _ f i e l d _ n a m e
*
**************************************
*
* Functional description
* Stub to make it work with char* too.
*
**************************************/
Firebird::MetaName temp;
DYN_UTIL_generate_field_name(tdbb, gbl, temp);
strcpy(buffer, temp.c_str());
}
void DYN_UTIL_generate_field_name( thread_db* tdbb, Global* gbl, Firebird::MetaName& buffer)
{
2001-05-23 15:26:42 +02:00
/**************************************
*
* D Y N _ U T I L _ g e n e r a t e _ f i e l d _ n a m e
2001-05-23 15:26:42 +02:00
*
**************************************
*
* Functional description
* Generate a name unique to RDB$FIELDS.
*
**************************************/
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = NULL;
2004-03-07 08:58:55 +01:00
SSHORT id = -1;
2008-12-18 11:57:12 +01:00
2001-12-24 03:51:06 +01:00
try {
2008-12-18 11:57:12 +01:00
bool found = false;
2001-12-24 03:51:06 +01:00
2001-05-23 15:26:42 +02:00
do {
2006-05-04 02:02:58 +02:00
buffer.printf("RDB$%" SQUADFORMAT,
2008-12-18 11:57:12 +01:00
(SINT64) DYN_UTIL_gen_unique_id(tdbb, gbl, drq_g_nxt_fld, "RDB$FIELD_NAME"));
2001-05-23 15:26:42 +02:00
request = CMP_find_request(tdbb, drq_f_nxt_fld, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_f_nxt_fld;
found = false;
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request)
FIRST 1 X IN RDB$FIELDS WITH X.RDB$FIELD_NAME EQ buffer.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_f_nxt_fld))
DYN_REQUEST(drq_f_nxt_fld) = request;
found = true;
2001-05-23 15:26:42 +02:00
END_FOR;
if (!DYN_REQUEST(drq_f_nxt_fld))
DYN_REQUEST(drq_f_nxt_fld) = request;
request = NULL;
} while (found);
2001-12-24 03:51:06 +01:00
} // try
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, id);
DYN_error_punt(true, 81);
2001-12-24 03:51:06 +01:00
/* msg 81: "Generation of field name failed" */
}
2001-05-23 15:26:42 +02:00
}
2008-12-18 11:57:12 +01:00
void DYN_UTIL_generate_field_position(thread_db* tdbb,
Global* gbl,
const Firebird::MetaName& relation_name,
SLONG* field_pos)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ U T I L _ g e n e r a t e _ f i e l d _ p o s i t i o n
2001-05-23 15:26:42 +02:00
*
**************************************
*
* Functional description
* Generate a field position if not specified
*
**************************************/
SLONG field_position = -1;
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = NULL;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
request = CMP_find_request(tdbb, drq_l_fld_pos, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request)
X IN RDB$RELATION_FIELDS
WITH X.RDB$RELATION_NAME EQ relation_name.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_l_fld_pos))
DYN_REQUEST(drq_l_fld_pos) = request;
if (X.RDB$FIELD_POSITION.NULL)
continue;
field_position = MAX(X.RDB$FIELD_POSITION, field_position);
END_FOR;
*field_pos = field_position;
2001-12-24 03:51:06 +01:00
} // try
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 162);
2001-12-24 03:51:06 +01:00
/* msg 162: "Looking up field position failed" */
}
2001-05-23 15:26:42 +02:00
}
2008-12-18 11:57:12 +01:00
void DYN_UTIL_generate_index_name(thread_db* tdbb, Global* gbl,
Firebird::MetaName& buffer, UCHAR verb)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ U T I L _ g e n e r a t e _ i n d e x _ n a m e
2001-05-23 15:26:42 +02:00
*
**************************************
*
* Functional description
* Generate a name unique to RDB$INDICES.
*
**************************************/
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = NULL;
2004-03-07 08:58:55 +01:00
SSHORT id = -1;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
bool found = false;
2001-05-23 15:26:42 +02:00
do {
const SCHAR* format;
2009-01-14 10:19:00 +01:00
switch (verb)
{
case isc_dyn_def_primary_key:
2006-05-04 02:02:58 +02:00
format = "RDB$PRIMARY%" SQUADFORMAT;
2009-01-14 10:19:00 +01:00
break;
case isc_dyn_def_foreign_key:
2006-05-04 02:02:58 +02:00
format = "RDB$FOREIGN%" SQUADFORMAT;
2009-01-14 10:19:00 +01:00
break;
default:
2006-05-04 02:02:58 +02:00
format = "RDB$%" SQUADFORMAT;
2009-01-14 10:19:00 +01:00
}
buffer.printf(format,
2008-12-20 20:57:43 +01:00
(SINT64) DYN_UTIL_gen_unique_id(tdbb, gbl, drq_g_nxt_idx, "RDB$INDEX_NAME"));
2001-05-23 15:26:42 +02:00
request = CMP_find_request(tdbb, drq_f_nxt_idx, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_f_nxt_idx;
found = false;
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request)
FIRST 1 X IN RDB$INDICES WITH X.RDB$INDEX_NAME EQ buffer.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_f_nxt_idx))
DYN_REQUEST(drq_f_nxt_idx) = request;
found = true;
2001-05-23 15:26:42 +02:00
END_FOR;
if (!DYN_REQUEST(drq_f_nxt_idx))
DYN_REQUEST(drq_f_nxt_idx) = request;
request = NULL;
} while (found);
2001-12-24 03:51:06 +01:00
} // try
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, id);
DYN_error_punt(true, 82);
2001-12-24 03:51:06 +01:00
/* msg 82: "Generation of index name failed" */
}
2001-05-23 15:26:42 +02:00
}
void DYN_UTIL_generate_trigger_name( thread_db* tdbb, Global* gbl, Firebird::MetaName& buffer)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ U T I L _ g e n e r a t e _ t r i g g e r _ n a m e
2001-05-23 15:26:42 +02:00
*
**************************************
*
* Functional description
* Generate a name unique to RDB$TRIGGERS.
*
**************************************/
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = NULL;
2004-03-07 08:58:55 +01:00
SSHORT id = -1;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
2008-12-18 11:57:12 +01:00
bool found = false;
2001-12-24 03:51:06 +01:00
2001-05-23 15:26:42 +02:00
do {
2006-05-04 02:02:58 +02:00
buffer.printf("CHECK_%" SQUADFORMAT,
2008-12-20 20:57:43 +01:00
(SINT64) DYN_UTIL_gen_unique_id(tdbb, gbl, drq_g_nxt_trg, "RDB$TRIGGER_NAME"));
2001-05-23 15:26:42 +02:00
request = CMP_find_request(tdbb, drq_f_nxt_trg, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_f_nxt_trg;
found = false;
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request)
FIRST 1 X IN RDB$TRIGGERS WITH X.RDB$TRIGGER_NAME EQ buffer.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_f_nxt_trg))
DYN_REQUEST(drq_f_nxt_trg) = request;
found = true;
2001-05-23 15:26:42 +02:00
END_FOR;
if (!DYN_REQUEST(drq_f_nxt_trg))
DYN_REQUEST(drq_f_nxt_trg) = request;
request = NULL;
} while (found);
2001-12-24 03:51:06 +01:00
} // try
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, id);
DYN_error_punt(true, 83);
2001-12-24 03:51:06 +01:00
/* msg 83: "Generation of trigger name failed" */
}
2001-05-23 15:26:42 +02:00
}
2008-01-16 09:46:02 +01:00
bool DYN_UTIL_find_field_source(thread_db* tdbb,
Global* gbl,
const Firebird::MetaName& view_name,
USHORT context,
const TEXT* local_name,
TEXT* output_field_name)
{
/**************************************
*
* D Y N _U T I L _ f i n d _ f i e l d _ s o u r c e
*
**************************************
*
* Functional description
* Find the original source for a view field.
*
**************************************/
SET_TDBB(tdbb);
2008-01-16 13:08:00 +01:00
Database* dbb = tdbb->getDatabase();
2008-01-16 09:46:02 +01:00
jrd_req* request = NULL;
/* CVC: It seems the logic of this function was changed over time. It's unlikely
it will cause a failure that leads to call DYN_error_punt(), unless the request finds
problems due to database corruption or unexpected ODS changes. Under normal
circumstances, it will return either true or false. When true, we found a field source
for the view's name/context/field and are loading this value in the last parameter,
that can be used against rdb$fields' rdb$field_name. */
bool found = false;
try {
request = CMP_find_request(tdbb, drq_l_fld_src2, DYN_REQUESTS);
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
VRL IN RDB$VIEW_RELATIONS CROSS
RFR IN RDB$RELATION_FIELDS OVER RDB$RELATION_NAME
WITH VRL.RDB$VIEW_NAME EQ view_name.c_str() AND
VRL.RDB$VIEW_CONTEXT EQ context AND
RFR.RDB$FIELD_NAME EQ local_name
if (!DYN_REQUEST(drq_l_fld_src2)) {
DYN_REQUEST(drq_l_fld_src2) = request;
}
found = true;
fb_utils::exact_name_limit(RFR.RDB$FIELD_SOURCE, sizeof(RFR.RDB$FIELD_SOURCE));
strcpy(output_field_name, RFR.RDB$FIELD_SOURCE);
END_FOR;
if (!DYN_REQUEST(drq_l_fld_src2)) {
DYN_REQUEST(drq_l_fld_src2) = request;
}
if (!found)
{
request = CMP_find_request(tdbb, drq_l_fld_src3, DYN_REQUESTS);
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
VRL IN RDB$VIEW_RELATIONS CROSS
PPR IN RDB$PROCEDURE_PARAMETERS
WITH VRL.RDB$RELATION_NAME EQ PPR.RDB$PROCEDURE_NAME AND
VRL.RDB$VIEW_NAME EQ view_name.c_str() AND
VRL.RDB$VIEW_CONTEXT EQ context AND
PPR.RDB$PARAMETER_NAME EQ local_name
if (!DYN_REQUEST(drq_l_fld_src3)) {
DYN_REQUEST(drq_l_fld_src3) = request;
}
found = true;
fb_utils::exact_name_limit(PPR.RDB$FIELD_SOURCE, sizeof(PPR.RDB$FIELD_SOURCE));
strcpy(output_field_name, PPR.RDB$FIELD_SOURCE);
END_FOR;
if (!DYN_REQUEST(drq_l_fld_src3)) {
DYN_REQUEST(drq_l_fld_src3) = request;
}
}
}
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 80);
/* msg 80: "Specified domain or source field does not exist" */
}
return found;
}
bool DYN_UTIL_get_prot(thread_db* tdbb,
Global* gbl,
const SCHAR* rname,
const SCHAR* fname,
SecurityClass::flags_t* prot_mask)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ U T I L _ g e t _ p r o t
2001-05-23 15:26:42 +02:00
*
**************************************
*
* Functional description
* Get protection mask for relation or relation_field
*
**************************************/
struct
{
SqlIdentifier relation_name;
SqlIdentifier field_name;
2001-05-23 15:26:42 +02:00
} in_msg;
SET_TDBB(tdbb);
jrd_req* request = CMP_find_request(tdbb, drq_l_prot_mask, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
2001-05-23 15:26:42 +02:00
if (!request)
{
request = CMP_compile2(tdbb, prot_blr, TRUE);
2001-05-23 15:26:42 +02:00
}
gds__vtov(rname, in_msg.relation_name, sizeof(in_msg.relation_name));
gds__vtov(fname, in_msg.field_name, sizeof(in_msg.field_name));
EXE_start(tdbb, request, gbl->gbl_transaction);
EXE_send(tdbb, request, 0, sizeof(in_msg), (UCHAR*)&in_msg);
EXE_receive(tdbb, request, 1, sizeof(SecurityClass::flags_t), (UCHAR*)prot_mask);
2001-05-23 15:26:42 +02:00
2004-03-07 08:58:55 +01:00
DYN_rundown_request(request, drq_l_prot_mask);
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
} // try
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
2004-03-11 06:47:35 +01:00
DYN_rundown_request(request, drq_l_prot_mask);
return false;
2001-12-24 03:51:06 +01:00
}
return true;
2001-05-23 15:26:42 +02:00
}
void DYN_UTIL_store_check_constraints(thread_db* tdbb,
Global* gbl,
const Firebird::MetaName& constraint_name,
const Firebird::MetaName& trigger_name)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ U T I L _s t o r e _ c h e c k _ c o n s t r a i n t s
*
**************************************
*
* Functional description
* Fill in rdb$check_constraints the association between a check name and the
* system defined trigger that implements that check.
2001-05-23 15:26:42 +02:00
*
**************************************/
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = CMP_find_request(tdbb, drq_s_chk_con, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
2001-05-23 15:26:42 +02:00
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
CHK IN RDB$CHECK_CONSTRAINTS
strcpy(CHK.RDB$CONSTRAINT_NAME, constraint_name.c_str());
strcpy(CHK.RDB$TRIGGER_NAME, trigger_name.c_str());
2001-05-23 15:26:42 +02:00
END_STORE;
2001-12-24 03:51:06 +01:00
if (!DYN_REQUEST(drq_s_chk_con)) {
2001-05-23 15:26:42 +02:00
DYN_REQUEST(drq_s_chk_con) = request;
2001-12-24 03:51:06 +01:00
}
} // try
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, drq_s_chk_con);
DYN_error_punt(true, 122);
2001-12-24 03:51:06 +01:00
/* msg 122: "STORE RDB$CHECK_CONSTRAINTS failed" */
}
2001-05-23 15:26:42 +02:00
}
//***************************************
//
// D Y N _ U T I L _ i s _ a r r a y
//
//**************************************
//
// Functional description
// Discover if a given domain (either automatic or explicit) has dimensions.
//
//***************************************
bool DYN_UTIL_is_array(thread_db* tdbb,
Global* gbl,
const Firebird::MetaName& domain_name)
{
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
2008-12-18 11:57:12 +01:00
jrd_req* request = CMP_find_request(tdbb, drq_dom_is_array, DYN_REQUESTS);
2008-12-18 11:57:12 +01:00
try
{
bool rc = false;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FIELDS WITH X.RDB$FIELD_NAME EQ domain_name.c_str()
2008-12-18 11:57:12 +01:00
if (!DYN_REQUEST(drq_dom_is_array))
DYN_REQUEST(drq_dom_is_array) = request;
2008-12-18 11:57:12 +01:00
rc = !X.RDB$DIMENSIONS.NULL && X.RDB$DIMENSIONS > 0;
END_FOR
2008-12-18 11:57:12 +01:00
if (!DYN_REQUEST(drq_dom_is_array))
DYN_REQUEST(drq_dom_is_array) = request;
2008-12-18 11:57:12 +01:00
return rc;
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, drq_dom_is_array);
DYN_error_punt(true, 227, domain_name.c_str());
// msg 227: "DYN_UTIL_is_array failed for domain %s"
return false; // Keep compiler happy.
}
}
//***************************************
//
// D Y N _ U T I L _ c o p y _ d o m a i n
//
//**************************************
//
// Functional description
// Copy a domain in another. More reliable than using dyn_fld as intermediate.
// The source cannot be an array domain.
// We don't copy the default, it may be useless work.
//
//***************************************
void DYN_UTIL_copy_domain(thread_db* tdbb,
2008-12-18 11:57:12 +01:00
Global* gbl,
const Firebird::MetaName& org_name,
const Firebird::MetaName& new_name)
{
SET_TDBB(tdbb);
//Database* dbb = tdbb->getDatabase();
jrd_req* request = NULL; //CMP_find_request(tdbb, drq_dom_copy, DYN_REQUESTS);
jrd_req* req2 = NULL;
try
{
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FIELDS WITH X.RDB$FIELD_NAME EQ org_name.c_str()
//if (!DYN_REQUEST(drq_dom_copy))
// DYN_REQUEST(drq_dom_copy) = request;
if (!X.RDB$DIMENSIONS.NULL && X.RDB$DIMENSIONS > 0)
ERR_punt();
2008-12-18 11:57:12 +01:00
STORE(REQUEST_HANDLE req2 TRANSACTION_HANDLE gbl->gbl_transaction)
X2 IN RDB$FIELDS
2008-12-18 11:57:12 +01:00
X2.RDB$FIELD_NAME.NULL = FALSE;
strcpy(X2.RDB$FIELD_NAME, new_name.c_str());
2008-12-18 11:57:12 +01:00
X2.RDB$QUERY_NAME.NULL = X.RDB$QUERY_NAME.NULL;
if (!X.RDB$QUERY_NAME.NULL)
strcpy(X2.RDB$QUERY_NAME, X.RDB$QUERY_NAME);
2008-12-18 11:57:12 +01:00
// The following fields may require blob copying:
// rdb$validation_blr, rdb$validation_source,
// rdb$computed_blr, rdb$computed_source,
// rdb$default_value, rdb$default_source,
// rdb$missing_value, rdb$missing_source,
// rdb$description and rdb$query_header.
2008-12-18 11:57:12 +01:00
X2.RDB$VALIDATION_BLR.NULL = X.RDB$VALIDATION_BLR.NULL;
X2.RDB$VALIDATION_BLR = X.RDB$VALIDATION_BLR;
2008-12-18 11:57:12 +01:00
X2.RDB$VALIDATION_SOURCE.NULL = X.RDB$VALIDATION_SOURCE.NULL;
X2.RDB$VALIDATION_SOURCE = X.RDB$VALIDATION_SOURCE;
2008-12-18 11:57:12 +01:00
X2.RDB$COMPUTED_BLR.NULL = X.RDB$COMPUTED_BLR.NULL;
X2.RDB$COMPUTED_BLR = X.RDB$COMPUTED_BLR;
2008-12-18 11:57:12 +01:00
X2.RDB$COMPUTED_SOURCE.NULL = X.RDB$COMPUTED_SOURCE.NULL;
X2.RDB$COMPUTED_SOURCE = X.RDB$COMPUTED_SOURCE;
2008-12-18 11:57:12 +01:00
//X2.RDB$DEFAULT_VALUE.NULL = X.RDB$DEFAULT_VALUE.NULL;
//X2.RDB$DEFAULT_VALUE = X.RDB$DEFAULT_VALUE;
2008-12-18 11:57:12 +01:00
//X2.RDB$DEFAULT_SOURCE.NULL = X.RDB$DEFAULT_SOURCE.NULL;
//X2.RDB$DEFAULT_SOURCE = X.RDB$DEFAULT_SOURCE;
2008-12-18 11:57:12 +01:00
X2.RDB$FIELD_LENGTH.NULL = X.RDB$FIELD_LENGTH.NULL;
X2.RDB$FIELD_LENGTH = X.RDB$FIELD_LENGTH;
2008-12-18 11:57:12 +01:00
X2.RDB$FIELD_SCALE.NULL = X.RDB$FIELD_SCALE.NULL;
X2.RDB$FIELD_SCALE = X.RDB$FIELD_SCALE;
2008-12-18 11:57:12 +01:00
X2.RDB$FIELD_TYPE.NULL = X.RDB$FIELD_TYPE.NULL;
X2.RDB$FIELD_TYPE = X.RDB$FIELD_TYPE;
2008-12-18 11:57:12 +01:00
X2.RDB$FIELD_SUB_TYPE.NULL = X.RDB$FIELD_SUB_TYPE.NULL;
X2.RDB$FIELD_SUB_TYPE = X.RDB$FIELD_SUB_TYPE;
2008-12-18 11:57:12 +01:00
X2.RDB$MISSING_VALUE.NULL = X.RDB$MISSING_VALUE.NULL;
X2.RDB$MISSING_VALUE = X.RDB$MISSING_VALUE;
2008-12-18 11:57:12 +01:00
X2.RDB$MISSING_SOURCE.NULL = X.RDB$MISSING_SOURCE.NULL;
X2.RDB$MISSING_SOURCE = X.RDB$MISSING_SOURCE;
2008-12-18 11:57:12 +01:00
X2.RDB$DESCRIPTION.NULL = X.RDB$DESCRIPTION.NULL;
X2.RDB$DESCRIPTION = X.RDB$DESCRIPTION;
2008-12-18 11:57:12 +01:00
X2.RDB$SYSTEM_FLAG.NULL = X.RDB$SYSTEM_FLAG.NULL;
X2.RDB$SYSTEM_FLAG = X.RDB$SYSTEM_FLAG;
2008-12-18 11:57:12 +01:00
X2.RDB$QUERY_HEADER.NULL = X.RDB$QUERY_HEADER.NULL;
X2.RDB$QUERY_HEADER = X.RDB$QUERY_HEADER;
2008-12-18 11:57:12 +01:00
X2.RDB$SEGMENT_LENGTH.NULL = X.RDB$SEGMENT_LENGTH.NULL;
X2.RDB$SEGMENT_LENGTH = X.RDB$SEGMENT_LENGTH;
2008-12-18 11:57:12 +01:00
X2.RDB$EDIT_STRING.NULL = X.RDB$EDIT_STRING.NULL;
if (!X.RDB$EDIT_STRING.NULL)
strcpy(X2.RDB$EDIT_STRING, X.RDB$EDIT_STRING);
2008-12-18 11:57:12 +01:00
X2.RDB$EXTERNAL_LENGTH.NULL = X.RDB$EXTERNAL_LENGTH.NULL;
X2.RDB$EXTERNAL_LENGTH = X.RDB$EXTERNAL_LENGTH;
2008-12-18 11:57:12 +01:00
X2.RDB$EXTERNAL_SCALE.NULL = X.RDB$EXTERNAL_SCALE.NULL;
X2.RDB$EXTERNAL_SCALE = X.RDB$EXTERNAL_SCALE;
2008-12-18 11:57:12 +01:00
X2.RDB$EXTERNAL_TYPE.NULL = X.RDB$EXTERNAL_TYPE.NULL;
X2.RDB$EXTERNAL_TYPE = X.RDB$EXTERNAL_TYPE;
2008-12-18 11:57:12 +01:00
X2.RDB$DIMENSIONS.NULL = X.RDB$DIMENSIONS.NULL;
X2.RDB$DIMENSIONS = X.RDB$DIMENSIONS;
2008-12-18 11:57:12 +01:00
X2.RDB$NULL_FLAG.NULL = X.RDB$NULL_FLAG.NULL;
X2.RDB$NULL_FLAG = X.RDB$NULL_FLAG;
2008-12-18 11:57:12 +01:00
X2.RDB$CHARACTER_LENGTH.NULL = X.RDB$CHARACTER_LENGTH.NULL;
X2.RDB$CHARACTER_LENGTH = X.RDB$CHARACTER_LENGTH;
2008-12-18 11:57:12 +01:00
X2.RDB$COLLATION_ID.NULL = X.RDB$COLLATION_ID.NULL;
X2.RDB$COLLATION_ID = X.RDB$COLLATION_ID;
2008-12-18 11:57:12 +01:00
X2.RDB$CHARACTER_SET_ID.NULL = X.RDB$CHARACTER_SET_ID.NULL;
X2.RDB$CHARACTER_SET_ID = X.RDB$CHARACTER_SET_ID;
2008-12-18 11:57:12 +01:00
X2.RDB$FIELD_PRECISION.NULL = X.RDB$FIELD_PRECISION.NULL;
X2.RDB$FIELD_PRECISION = X.RDB$FIELD_PRECISION;
END_STORE
CMP_release(tdbb, req2);
req2 = NULL;
END_FOR
2008-12-18 11:57:12 +01:00
CMP_release(tdbb, request);
request = NULL;
// For now, CMP_release used instead of this:
//if (!DYN_REQUEST(drq_dom_copy))
// DYN_REQUEST(drq_dom_copy) = request;
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1); //drq_dom_copy);
DYN_error_punt(true, 228, org_name.c_str());
// msg 228: "DYN_UTIL_copy_domain failed for domain %s"
}
}