8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-31 07:23:02 +01:00
firebird-mirror/src/jrd/dyn_del.epp

1766 lines
48 KiB
Plaintext
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: JRD Data Definition Utility
* MODULE: dyn_delete.epp
2001-05-23 15:26:42 +02:00
* DESCRIPTION: Dynamic data definition - DYN_delete_<x>
*
* 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-06-30 10:46:51 +02:00
*
* 24-May-2001 Claudio Valderrama - Forbid zero length identifiers,
* they are not ANSI SQL compliant.
* 23-May-2001 Claudio Valderrama - Move here DYN_delete_role.
* 20-Jun-2001 Claudio Valderrama - Make available DYN_delete_generator.
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 "../dsql/DdlNodes.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/jrd.h"
2002-06-30 10:46:51 +02:00
#include "../jrd/ods.h"
2001-05-23 15:26:42 +02:00
#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"
#include "../jrd/blb_proto.h"
#include "../jrd/cmp_proto.h"
#include "../jrd/dyn_proto.h"
#include "../jrd/dyn_proto.h"
#include "../jrd/dyn_dl_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/met_proto.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/vio_proto.h"
2003-12-31 06:36:12 +01:00
#include "../common/utils_proto.h"
2001-05-23 15:26:42 +02:00
using MsgFormat::SafeArg;
using namespace Jrd;
using namespace Firebird;
DATABASE DB = STATIC "ODS.RDB";
2001-05-23 15:26:42 +02:00
static bool delete_constraint_records(Global*, const Firebird::MetaName&, const Firebird::MetaName&);
static bool delete_dimension_records(Global*, const Firebird::MetaName&);
2008-12-18 11:57:12 +01:00
static void delete_f_key_constraint(thread_db*, Global*,
const Firebird::MetaName&, const Firebird::MetaName&,
const Firebird::MetaName&, const Firebird::MetaName&);
static void delete_gfield_for_lfield(Global*, const Firebird::MetaName&);
static bool delete_index_segment_records(Global*, const Firebird::MetaName&);
2001-05-23 15:26:42 +02:00
void DYN_delete_collation(Global* gbl, const UCHAR** ptr)
{
/**************************************
*
* D Y N _ d e l e t e _ c o l l a t i o n
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes a collation from rdb$collations.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
jrd_req* request = NULL;
2008-12-18 11:57:12 +01:00
bool found = false;
Firebird::MetaName collName;
2008-12-18 11:57:12 +01:00
try
{
GET_STRING(ptr, collName);
request = CMP_find_request(tdbb, drq_e_colls, DYN_REQUESTS);
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
COLL IN RDB$COLLATIONS
CROSS CS IN RDB$CHARACTER_SETS
WITH COLL.RDB$COLLATION_NAME EQ collName.c_str() AND
CS.RDB$CHARACTER_SET_ID EQ COLL.RDB$CHARACTER_SET_ID
if (!DYN_REQUEST(drq_e_colls))
DYN_REQUEST(drq_e_colls) = request;
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
DDL_TRIGGER_DROP_COLLATION, collName, gbl->sqlText);
if (!COLL.RDB$SYSTEM_FLAG.NULL && COLL.RDB$SYSTEM_FLAG == 1)
{
DYN_rundown_request(request, -1);
DYN_error_punt(false, 237);
// msg 237: "Cannot delete system collation"
}
if (COLL.RDB$COLLATION_ID == 0 ||
(!CS.RDB$DEFAULT_COLLATE_NAME.NULL &&
Firebird::MetaName(COLL.RDB$COLLATION_NAME) == Firebird::MetaName(CS.RDB$DEFAULT_COLLATE_NAME)))
{
fb_utils::exact_name_limit(CS.RDB$CHARACTER_SET_NAME,
sizeof(CS.RDB$CHARACTER_SET_NAME));
DYN_rundown_request(request, -1);
DYN_error_punt(false, 238, CS.RDB$CHARACTER_SET_NAME);
// msg 238: "Cannot delete default collation of CHARACTER SET %s"
}
found = true;
fb_utils::exact_name_limit(COLL.RDB$COLLATION_NAME,
sizeof(COLL.RDB$COLLATION_NAME));
jrd_req* request2 = CMP_find_request(tdbb, drq_l_rfld_coll, DYN_REQUESTS);
FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
RF IN RDB$RELATION_FIELDS CROSS F IN RDB$FIELDS
WITH RF.RDB$FIELD_SOURCE EQ F.RDB$FIELD_NAME AND
F.RDB$CHARACTER_SET_ID EQ COLL.RDB$CHARACTER_SET_ID AND
RF.RDB$COLLATION_ID EQ COLL.RDB$COLLATION_ID
if (!DYN_REQUEST(drq_l_rfld_coll))
DYN_REQUEST(drq_l_rfld_coll) = request2;
fb_utils::exact_name_limit(RF.RDB$RELATION_NAME, sizeof(RF.RDB$RELATION_NAME));
fb_utils::exact_name_limit(RF.RDB$FIELD_NAME, sizeof(RF.RDB$FIELD_NAME));
DYN_rundown_request(request2, -1);
DYN_error_punt(false, 235, SafeArg() << COLL.RDB$COLLATION_NAME <<
RF.RDB$RELATION_NAME << RF.RDB$FIELD_NAME);
// msg 235: "Collation %s is used in table %s (field name %s) and cannot be dropped"
END_FOR;
if (!DYN_REQUEST(drq_l_rfld_coll))
DYN_REQUEST(drq_l_rfld_coll) = request2;
request2 = CMP_find_request(tdbb, drq_l_prm_coll, DYN_REQUESTS);
FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
PRM IN RDB$PROCEDURE_PARAMETERS CROSS F IN RDB$FIELDS
WITH PRM.RDB$FIELD_SOURCE EQ F.RDB$FIELD_NAME AND
F.RDB$CHARACTER_SET_ID EQ COLL.RDB$CHARACTER_SET_ID AND
PRM.RDB$COLLATION_ID EQ COLL.RDB$COLLATION_ID
if (!DYN_REQUEST(drq_l_prm_coll))
DYN_REQUEST(drq_l_prm_coll) = request2;
fb_utils::exact_name_limit(PRM.RDB$PARAMETER_NAME, sizeof(PRM.RDB$PARAMETER_NAME));
DYN_rundown_request(request2, -1);
DYN_error_punt(false, 243, SafeArg() <<
COLL.RDB$COLLATION_NAME <<
QualifiedName(PRM.RDB$PROCEDURE_NAME,
(PRM.RDB$PACKAGE_NAME.NULL ? NULL : PRM.RDB$PACKAGE_NAME)).toString().c_str() <<
PRM.RDB$PARAMETER_NAME);
// msg 243: "Collation %s is used in procedure %s (parameter name %s) and cannot be dropped"
END_FOR;
if (!DYN_REQUEST(drq_l_prm_coll))
DYN_REQUEST(drq_l_prm_coll) = request2;
request2 = CMP_find_request(tdbb, drq_l_fld_coll, DYN_REQUESTS);
FOR (REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
F IN RDB$FIELDS
WITH F.RDB$CHARACTER_SET_ID EQ COLL.RDB$CHARACTER_SET_ID AND
F.RDB$COLLATION_ID EQ COLL.RDB$COLLATION_ID
if (!DYN_REQUEST(drq_l_fld_coll))
DYN_REQUEST(drq_l_fld_coll) = request2;
fb_utils::exact_name_limit(F.RDB$FIELD_NAME, sizeof(F.RDB$FIELD_NAME));
DYN_rundown_request(request2, -1);
DYN_error_punt(false, 236, SafeArg() << COLL.RDB$COLLATION_NAME << F.RDB$FIELD_NAME);
// msg 236: "Collation %s is used in domain %s and cannot be dropped"
END_FOR;
if (!DYN_REQUEST(drq_l_fld_coll))
DYN_REQUEST(drq_l_fld_coll) = request2;
ERASE COLL;
END_FOR;
if (!DYN_REQUEST(drq_e_colls))
DYN_REQUEST(drq_e_colls) = request;
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 233);
// msg 234: "ERASE RDB$COLLATIONS failed"
}
if (found)
{
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
DDL_TRIGGER_DROP_COLLATION, collName, gbl->sqlText);
}
else
{
DYN_error_punt(false, 152, collName.c_str());
// msg 152: "Collation %s not found"
}
}
void DYN_delete_constraint (Global* gbl, const UCHAR** ptr, const Firebird::MetaName* relation)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ c o n s t r a i n t
*
**************************************
*
* Functional description
* Execute ddl to DROP an Integrity Constraint
*
**************************************/
Firebird::MetaName rel_name, constraint;
2001-05-23 15:26:42 +02:00
2009-11-21 08:38:05 +01:00
// Get name of the constraint to be deleted
2001-05-23 15:26:42 +02:00
GET_STRING(ptr, constraint);
if (relation)
rel_name = *relation;
2003-11-08 17:40:17 +01:00
else if (*(*ptr)++ != isc_dyn_rel_name) {
2009-11-21 08:38:05 +01:00
DYN_error_punt(false, 128); // msg 128: "No relation specified in delete_constraint"
2001-05-23 15:26:42 +02:00
}
else
GET_STRING(ptr, rel_name);
if (!delete_constraint_records(gbl, constraint, rel_name))
2009-11-21 08:38:05 +01:00
DYN_error_punt(false, 130, constraint.c_str()); // msg 130: "CONSTRAINT %s does not exist."
2001-05-23 15:26:42 +02:00
}
2009-11-25 05:06:48 +01:00
void DYN_delete_dimensions(Global* gbl, const UCHAR** ptr)
2009-04-28 15:48:18 +02:00
//const Firebird::MetaName* relation_name,
//Firebird::MetaName* field_name) // Obtained from the stream
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ d i m e n s i o n s
*
**************************************
*
* Functional description
* Delete dimensions associated with
* a global field. Used when modifying
* the datatype and from places where a
* field is deleted directly in the system
* relations. The DYN version of delete
* global field deletes the dimensions for
* you.
*
**************************************/
Firebird::MetaName f;
2001-05-23 15:26:42 +02:00
GET_STRING(ptr, f);
delete_dimension_records(gbl, f);
2009-11-25 05:06:48 +01:00
while (*(*ptr)++ != isc_dyn_end)
{
2001-05-23 15:26:42 +02:00
--(*ptr);
DYN_execute(gbl, ptr, NULL, &f, NULL, NULL, NULL);
2001-05-23 15:26:42 +02:00
}
}
void DYN_delete_exception( Global* gbl, const UCHAR** ptr)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ e x c e p t i o n
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes an exception.
*
**************************************/
Firebird::MetaName t;
2001-05-23 15:26:42 +02:00
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
GET_STRING(ptr, t);
jrd_req* request = CMP_find_request(tdbb, drq_e_xcp, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
bool found = false;
2001-12-24 03:51:06 +01:00
try {
2009-11-25 05:06:48 +01:00
found = false;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$EXCEPTIONS
WITH X.RDB$EXCEPTION_NAME EQ t.c_str()
if (!DYN_REQUEST(drq_e_xcp))
DYN_REQUEST(drq_e_xcp) = request;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
found = true;
2009-11-25 05:06:48 +01:00
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
DDL_TRIGGER_DROP_EXCEPTION, t, gbl->sqlText);
2009-11-25 05:06:48 +01:00
ERASE X;
END_FOR;
if (!DYN_REQUEST(drq_e_xcp))
DYN_REQUEST(drq_e_xcp) = request;
2001-05-23 15:26:42 +02:00
} // try
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 143);
2009-11-21 08:38:05 +01:00
// msg 143: "ERASE EXCEPTION failed"
2001-12-24 03:51:06 +01:00
}
if (found)
{
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
DDL_TRIGGER_DROP_EXCEPTION, t, gbl->sqlText);
}
else
{
DYN_error_punt(false, 144);
2009-11-21 08:38:05 +01:00
// msg 144: "Exception not found"
2001-12-24 03:51:06 +01:00
}
if (*(*ptr)++ != isc_dyn_end) {
DYN_unsupported_verb();
}
2001-05-23 15:26:42 +02:00
}
void DYN_delete_filter( Global* gbl, const UCHAR** ptr)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ f i l t e r
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes a blob filter.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = CMP_find_request(tdbb, drq_e_filters, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
bool found = false;
Firebird::MetaName f;
2001-05-23 15:26:42 +02:00
GET_STRING(ptr, f);
2008-12-18 11:57:12 +01:00
try {
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
found = false;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FILTERS WITH X.RDB$FUNCTION_NAME = f.c_str()
if (!DYN_REQUEST(drq_e_filters))
DYN_REQUEST(drq_e_filters) = request;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
ERASE X;
found = true;
END_FOR;
if (!DYN_REQUEST(drq_e_filters))
DYN_REQUEST(drq_e_filters) = request;
2001-12-24 03:51:06 +01:00
}
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 36);
2009-11-21 08:38:05 +01:00
// msg 36: "ERASE BLOB FILTER failed"
2001-12-24 03:51:06 +01:00
}
2009-11-25 05:06:48 +01:00
if (!found)
{
DYN_error_punt(false, 37, f.c_str());
2009-11-21 08:38:05 +01:00
// msg 37: "Blob Filter %s not found"
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
2003-11-08 17:40:17 +01:00
if (*(*ptr)++ != isc_dyn_end) {
2001-05-23 15:26:42 +02:00
DYN_unsupported_verb();
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
}
void DYN_delete_generator(Global* gbl, const UCHAR**ptr)
2002-06-30 10:46:51 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ g e n e r a t o r
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes a generator from rdb$generator but the
* space allocated in the page won't be released.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2002-06-30 10:46:51 +02:00
jrd_req* request = NULL;
2008-12-18 11:57:12 +01:00
bool found = false;
Firebird::MetaName t;
GET_STRING(ptr, t);
2008-12-18 11:57:12 +01:00
2002-06-30 10:46:51 +02:00
try {
request = CMP_find_request(tdbb, drq_e_gens, DYN_REQUESTS);
found = false;
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$GENERATORS
WITH X.RDB$GENERATOR_NAME EQ t.c_str()
if (!DYN_REQUEST(drq_e_gens))
DYN_REQUEST(drq_e_gens) = request;
found = true;
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
DDL_TRIGGER_DROP_SEQUENCE, t, gbl->sqlText);
ERASE X;
END_FOR;
if (!DYN_REQUEST(drq_e_gens))
DYN_REQUEST(drq_e_gens) = request;
}
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
2002-06-30 10:46:51 +02:00
DYN_rundown_request(request, -1);
DYN_error_punt(true, 213);
2009-11-21 08:38:05 +01:00
// msg 213: "ERASE GENERATOR failed"
2002-06-30 10:46:51 +02:00
}
if (found)
{
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
DDL_TRIGGER_DROP_SEQUENCE, t, gbl->sqlText);
}
else
{
DYN_error_punt(false, 214, t.c_str());
2009-11-21 08:38:05 +01:00
// msg 214: "Generator %s not found"
2002-06-30 10:46:51 +02:00
}
}
void DYN_delete_global_field( Global* gbl, const UCHAR** ptr)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ g l o b a l _ f i e l d
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes a global field.
*
**************************************/
Firebird::MetaName f;
2001-05-23 15:26:42 +02:00
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = CMP_find_request(tdbb, drq_e_gfields, DYN_REQUESTS);
2008-12-18 11:57:12 +01:00
bool found = false;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
2009-11-25 05:06:48 +01:00
GET_STRING(ptr, f);
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FIELDS WITH X.RDB$FIELD_NAME EQ f.c_str()
if (!DYN_REQUEST(drq_e_gfields))
DYN_REQUEST(drq_e_gfields) = request;
2009-11-25 05:06:48 +01:00
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
DDL_TRIGGER_DROP_DOMAIN, f, gbl->sqlText);
2009-11-25 05:06:48 +01:00
delete_dimension_records(gbl, f);
ERASE X;
found = true;
END_FOR
if (!DYN_REQUEST(drq_e_gfields))
DYN_REQUEST(drq_e_gfields) = request;
2009-11-25 05:06:48 +01:00
request = CMP_find_request(tdbb, drq_l_fld_src, DYN_REQUESTS);
2009-11-25 05:06:48 +01:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
Y IN RDB$RELATION_FIELDS WITH Y.RDB$FIELD_SOURCE EQ f.c_str()
if (!DYN_REQUEST(drq_l_fld_src))
DYN_REQUEST(drq_l_fld_src) = request;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
fb_utils::exact_name_limit(Y.RDB$FIELD_SOURCE, sizeof(Y.RDB$FIELD_SOURCE));
fb_utils::exact_name_limit(Y.RDB$RELATION_NAME, sizeof(Y.RDB$RELATION_NAME));
fb_utils::exact_name_limit(Y.RDB$FIELD_NAME, sizeof(Y.RDB$FIELD_NAME));
DYN_rundown_request(request, -1);
DYN_error_punt(false, 43, SafeArg() << Y.RDB$FIELD_SOURCE << Y.RDB$RELATION_NAME <<
Y.RDB$FIELD_NAME);
// msg 43: "Domain %s is used in table %s (local name %s) and can not be dropped"
END_FOR;
if (!DYN_REQUEST(drq_l_fld_src))
DYN_REQUEST(drq_l_fld_src) = request;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
request = CMP_find_request(tdbb, drq_l_prp_src, DYN_REQUESTS);
2009-11-25 05:06:48 +01:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$PROCEDURE_PARAMETERS
WITH X.RDB$FIELD_SOURCE EQ f.c_str()
if (!DYN_REQUEST(drq_l_prp_src))
DYN_REQUEST(drq_l_prp_src) = request;
2009-11-25 05:06:48 +01:00
fb_utils::exact_name_limit(X.RDB$FIELD_SOURCE, sizeof(X.RDB$FIELD_SOURCE));
fb_utils::exact_name_limit(X.RDB$PROCEDURE_NAME, sizeof(X.RDB$PROCEDURE_NAME));
fb_utils::exact_name_limit(X.RDB$PARAMETER_NAME, sizeof(X.RDB$PARAMETER_NAME));
2009-11-25 05:06:48 +01:00
DYN_rundown_request(request, -1);
DYN_error_punt(false, 239, SafeArg() << X.RDB$FIELD_SOURCE <<
QualifiedName(X.RDB$PROCEDURE_NAME,
(X.RDB$PACKAGE_NAME.NULL ? NULL : X.RDB$PACKAGE_NAME)).toString().c_str() <<
X.RDB$PARAMETER_NAME);
// msg 239: "Domain %s is used in procedure %s (parameter name %s) and cannot be dropped"
2009-11-25 05:06:48 +01:00
END_FOR
if (!DYN_REQUEST(drq_l_prp_src))
DYN_REQUEST(drq_l_prp_src) = request;
} // try
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 44);
2009-11-21 08:38:05 +01:00
// msg 44: "ERASE RDB$FIELDS failed"
2001-12-24 03:51:06 +01:00
}
if (found)
{
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
DDL_TRIGGER_DROP_DOMAIN, f, gbl->sqlText);
}
else
{
DYN_error_punt(false, 89);
2006-09-01 03:27:55 +02:00
// msg 89: "Domain not found"
2001-05-23 15:26:42 +02:00
}
2009-11-25 05:06:48 +01:00
while (*(*ptr)++ != isc_dyn_end)
{
2001-05-23 15:26:42 +02:00
--(*ptr);
DYN_execute(gbl, ptr, NULL, &f, NULL, NULL, NULL);
2001-05-23 15:26:42 +02:00
}
}
void DYN_delete_index( Global* gbl, const UCHAR** ptr)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ i n d e x
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes an index.
*
**************************************/
Firebird::MetaName idx_name, rel_name;
2001-05-23 15:26:42 +02:00
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = CMP_find_request(tdbb, drq_e_indices, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
bool found = false;
bool is_expression = false;
2001-12-24 03:51:06 +01:00
try {
2009-11-25 05:06:48 +01:00
GET_STRING(ptr, idx_name);
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
found = false;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ idx_name.c_str()
if (!DYN_REQUEST(drq_e_indices))
DYN_REQUEST(drq_e_indices) = request;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
rel_name = IDX.RDB$RELATION_NAME;
found = true;
2009-11-25 05:06:48 +01:00
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
DDL_TRIGGER_DROP_INDEX, idx_name, gbl->sqlText);
2009-11-25 05:06:48 +01:00
is_expression = !IDX.RDB$EXPRESSION_BLR.NULL;
ERASE IDX;
END_FOR;
if (!DYN_REQUEST(drq_e_indices))
DYN_REQUEST(drq_e_indices) = request;
} //try
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 47);
2009-11-21 08:38:05 +01:00
// msg 47: "ERASE RDB$INDICES failed"
2001-12-24 03:51:06 +01:00
}
if (found)
{
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
DDL_TRIGGER_DROP_INDEX, idx_name, gbl->sqlText);
}
else
2001-12-24 03:51:06 +01:00
{
DYN_error_punt(false, 48);
2009-11-21 08:38:05 +01:00
// msg 48: "Index not found"
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
if (!is_expression)
if (!delete_index_segment_records(gbl, idx_name))
{
DYN_error_punt(false, 50);
2009-11-21 08:38:05 +01:00
// msg 50: "No segments found for index"
}
2009-11-25 05:06:48 +01:00
while (*(*ptr)++ != isc_dyn_end)
{
2001-05-23 15:26:42 +02:00
--(*ptr);
DYN_execute(gbl, ptr, &rel_name, NULL, NULL, NULL, NULL);
2001-05-23 15:26:42 +02:00
}
}
2009-11-25 05:06:48 +01:00
void DYN_delete_local_field(Global* gbl, const UCHAR** ptr, const Firebird::MetaName* relation_name)
2009-04-28 15:48:18 +02:00
//Firebird::MetaName* field_name) // Obtained from the stream
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ l o c a l _ f i e l d
*
**************************************
*
* Functional description
* Execute a dynamic ddl 'delete local field'
* statement.
*
* The rules for dropping a regular column:
2008-12-18 11:57:12 +01:00
*
2001-05-23 15:26:42 +02:00
* 1. the column is not referenced in any views.
* 2. the column is not part of any user defined indexes.
* 3. the column is not used in any SQL statements inside of store
* procedures or triggers
* 4. the column is not part of any check-constraints
2008-12-18 11:57:12 +01:00
*
2001-05-23 15:26:42 +02:00
* The rules for dropping a column that was created as primary key:
*
* 1. the column is not defined as any foreign keys
* 2. the column is not defined as part of compound primary keys
*
* The rules for dropping a column that was created as foreign key:
*
* 1. the column is not defined as a compound foreign key. A
* compound foreign key is a foreign key consisted of more
* than one columns.
*
* The RI enforcement for dropping primary key column is done by system
* triggers and the RI enforcement for dropping foreign key column is
* done by code and system triggers. See the functional description of
* delete_f_key_constraint function for detail.
*
**************************************/
Firebird::MetaName tbl_nm, col_nm, constraint, index_name;
2001-05-23 15:26:42 +02:00
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
GET_STRING(ptr, col_nm);
if (relation_name)
tbl_nm = *relation_name;
2009-11-25 05:06:48 +01:00
else if (*(*ptr)++ != isc_dyn_rel_name)
{
DYN_error_punt(false, 51);
2009-11-21 08:38:05 +01:00
// msg 51: "No relation specified in ERASE RFR"
2001-05-23 15:26:42 +02:00
}
else
GET_STRING(ptr, tbl_nm);
jrd_req* request = CMP_find_request(tdbb, drq_l_dep_flds, DYN_REQUESTS);
2004-03-07 08:58:55 +01:00
USHORT id = drq_l_dep_flds;
2008-12-18 11:57:12 +01:00
bool found;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
2009-11-21 08:38:05 +01:00
// make sure that column is not referenced in any views
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$RELATION_FIELDS CROSS Y IN RDB$RELATION_FIELDS CROSS
Z IN RDB$VIEW_RELATIONS WITH
X.RDB$RELATION_NAME EQ tbl_nm.c_str() AND
X.RDB$FIELD_NAME EQ col_nm.c_str() AND
2001-05-23 15:26:42 +02:00
X.RDB$FIELD_NAME EQ Y.RDB$BASE_FIELD AND
X.RDB$FIELD_SOURCE EQ Y.RDB$FIELD_SOURCE AND
Y.RDB$RELATION_NAME EQ Z.RDB$VIEW_NAME AND
X.RDB$RELATION_NAME EQ Z.RDB$RELATION_NAME AND
Y.RDB$VIEW_CONTEXT EQ Z.RDB$VIEW_CONTEXT
if (!DYN_REQUEST(drq_l_dep_flds))
DYN_REQUEST(drq_l_dep_flds) = request;
DYN_rundown_request(request, -1);
2008-12-18 11:57:12 +01:00
DYN_error_punt(false, 52, SafeArg() << col_nm.c_str() << tbl_nm.c_str() << Y.RDB$RELATION_NAME);
2009-11-21 08:38:05 +01:00
// msg 52: "field %s from relation %s is referenced in view %s"
2001-05-23 15:26:42 +02:00
END_FOR;
if (!DYN_REQUEST(drq_l_dep_flds))
DYN_REQUEST(drq_l_dep_flds) = request;
2009-11-21 08:38:05 +01:00
// If the column to be dropped is being used as a foreign key
// and the column was not part of any compound foreign key,
// then we can drop the column. But we have to drop the foreign key
// constraint first.
2001-05-23 15:26:42 +02:00
request = CMP_find_request(tdbb, drq_g_rel_constr_nm, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_g_rel_constr_nm;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
IDX IN RDB$INDICES CROSS
IDX_SEG IN RDB$INDEX_SEGMENTS CROSS
2001-05-23 15:26:42 +02:00
REL_CONST IN RDB$RELATION_CONSTRAINTS
WITH IDX.RDB$RELATION_NAME EQ tbl_nm.c_str()
AND REL_CONST.RDB$RELATION_NAME EQ tbl_nm.c_str()
AND IDX_SEG.RDB$FIELD_NAME EQ col_nm.c_str()
AND IDX.RDB$INDEX_NAME EQ IDX_SEG.RDB$INDEX_NAME
AND IDX.RDB$INDEX_NAME EQ REL_CONST.RDB$INDEX_NAME
2001-05-23 15:26:42 +02:00
AND REL_CONST.RDB$CONSTRAINT_TYPE EQ FOREIGN_KEY
if (!DYN_REQUEST(drq_g_rel_constr_nm))
DYN_REQUEST(drq_g_rel_constr_nm) = request;
2009-11-25 05:06:48 +01:00
if (IDX.RDB$SEGMENT_COUNT == 1)
{
constraint = REL_CONST.RDB$CONSTRAINT_NAME;
index_name = IDX.RDB$INDEX_NAME;
2001-05-23 15:26:42 +02:00
2008-12-18 11:57:12 +01:00
delete_f_key_constraint(tdbb, gbl, tbl_nm, col_nm, constraint, index_name);
2001-05-23 15:26:42 +02:00
}
2009-11-25 05:06:48 +01:00
else
{
DYN_rundown_request(request, -1);
DYN_error_punt(false, 187, SafeArg() << col_nm.c_str() << tbl_nm.c_str() <<
IDX.RDB$INDEX_NAME);
2009-11-21 08:38:05 +01:00
// msg 187: "field %s from relation %s is referenced in index %s"
2001-05-23 15:26:42 +02:00
}
END_FOR;
if (!DYN_REQUEST(drq_g_rel_constr_nm))
DYN_REQUEST(drq_g_rel_constr_nm) = request;
2009-11-21 08:38:05 +01:00
// make sure that column is not referenced in any user-defined indexes
// NOTE: You still could see the system generated indices even though
// they were already been deleted when dropping column that was
// used as foreign key before "commit".
2001-05-23 15:26:42 +02:00
request = CMP_find_request(tdbb, drq_e_l_idx, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_e_l_idx;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
2006-09-12 14:29:11 +02:00
IDX IN RDB$INDICES CROSS
IDX_SEG IN RDB$INDEX_SEGMENTS
WITH IDX.RDB$INDEX_NAME EQ IDX_SEG.RDB$INDEX_NAME
AND IDX.RDB$RELATION_NAME EQ tbl_nm.c_str()
AND IDX_SEG.RDB$FIELD_NAME EQ col_nm.c_str()
AND NOT ANY
REL_CONST IN RDB$RELATION_CONSTRAINTS
WITH REL_CONST.RDB$RELATION_NAME EQ IDX.RDB$RELATION_NAME
AND REL_CONST.RDB$INDEX_NAME EQ IDX.RDB$INDEX_NAME
2008-12-18 11:57:12 +01:00
if (!DYN_REQUEST(drq_e_l_idx))
2001-05-23 15:26:42 +02:00
DYN_REQUEST(drq_e_l_idx) = request;
2006-09-12 14:29:11 +02:00
DYN_rundown_request(request, -1);
DYN_error_punt(false, 187, SafeArg() << col_nm.c_str() << tbl_nm.c_str() <<
fb_utils::exact_name_limit(IDX.RDB$INDEX_NAME, sizeof(IDX.RDB$INDEX_NAME)));
2006-09-12 14:29:11 +02:00
// msg 187: "field %s from relation %s is referenced in index %s"
2001-05-23 15:26:42 +02:00
END_FOR;
if (!DYN_REQUEST(drq_e_l_idx))
DYN_REQUEST(drq_e_l_idx) = request;
request = CMP_find_request(tdbb, drq_e_lfield, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_e_lfield;
found = false;
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
RFR IN RDB$RELATION_FIELDS
WITH RFR.RDB$FIELD_NAME EQ col_nm.c_str()
AND RFR.RDB$RELATION_NAME EQ tbl_nm.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_e_lfield))
DYN_REQUEST(drq_e_lfield) = request;
ERASE RFR;
2008-12-18 11:57:12 +01:00
if (!RFR.RDB$SECURITY_CLASS.NULL &&
!strncmp(RFR.RDB$SECURITY_CLASS, SQL_SECCLASS_PREFIX, SQL_SECCLASS_PREFIX_LEN))
2004-12-16 04:03:13 +01:00
{
DYN_delete_security_class2(gbl->gbl_transaction, RFR.RDB$SECURITY_CLASS);
2004-12-16 04:03:13 +01:00
}
found = true;
2001-05-23 15:26:42 +02:00
delete_gfield_for_lfield(gbl, RFR.RDB$FIELD_SOURCE);
2009-11-25 05:06:48 +01:00
while (*(*ptr)++ != isc_dyn_end)
{
2001-05-23 15:26:42 +02:00
--(*ptr);
Firebird::MetaName rel_name(RFR.RDB$RELATION_NAME);
MetaTmp(RFR.RDB$FIELD_SOURCE)
DYN_execute(gbl, ptr, &rel_name, &tmp, NULL, NULL, NULL);
2001-05-23 15:26:42 +02:00
}
END_FOR;
2001-12-24 03:51:06 +01:00
if (!DYN_REQUEST(drq_e_lfield)) {
2001-05-23 15:26:42 +02:00
DYN_REQUEST(drq_e_lfield) = request;
2001-12-24 03:51:06 +01:00
}
2004-12-21 20:30:29 +01:00
request = CMP_find_request(tdbb, drq_e_fld_prvs, DYN_REQUESTS);
id = drq_e_fld_prvs;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
PRIV IN RDB$USER_PRIVILEGES WITH
PRIV.RDB$RELATION_NAME EQ tbl_nm.c_str() AND
PRIV.RDB$FIELD_NAME EQ col_nm.c_str() AND
2008-12-18 11:57:12 +01:00
PRIV.RDB$OBJECT_TYPE = obj_relation
2004-12-21 20:30:29 +01:00
if (!DYN_REQUEST(drq_e_fld_prvs))
DYN_REQUEST(drq_e_fld_prvs) = request;
ERASE PRIV;
END_FOR;
2004-12-21 20:30:29 +01:00
if (!DYN_REQUEST(drq_e_fld_prvs)) {
DYN_REQUEST(drq_e_fld_prvs) = request;
}
2001-12-24 03:51:06 +01:00
} // try
2009-01-20 09:33:59 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
2009-01-20 09:33:59 +01:00
switch (id)
{
case drq_l_dep_flds:
DYN_error_punt(true, 53);
// msg 53: "ERASE RDB$RELATION_FIELDS failed"
2004-12-21 20:30:29 +01:00
case drq_e_fld_prvs:
DYN_error_punt(true, 62);
// msg 62: "ERASE RDB$USER_PRIVILEGES failed"
default:
DYN_error_punt(true, 53);
// msg 53: "ERASE RDB$RELATION_FIELDS failed"
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
}
2009-11-25 05:06:48 +01:00
if (!found)
{
DYN_error_punt(false, 176, SafeArg() << col_nm.c_str() << tbl_nm.c_str());
// msg 176: "column %s does not exist in table/view %s"
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
}
void DYN_delete_relation( Global* gbl, const UCHAR** ptr, const Firebird::MetaName* relation)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ r e l a t i o n
2001-05-23 15:26:42 +02:00
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes a relation with all its indices, triggers
* and fields.
2001-05-23 15:26:42 +02:00
*
**************************************/
Firebird::MetaName relation_name;
2001-05-23 15:26:42 +02:00
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
if (relation)
relation_name = *relation;
else
GET_STRING(ptr, relation_name);
2001-05-23 15:26:42 +02:00
jrd_req* req2 = 0;
jrd_req* request = CMP_find_request(tdbb, drq_e_relation, DYN_REQUESTS);
USHORT id = drq_e_relation;
2001-05-23 15:26:42 +02:00
bool found = false;
bool view = false;
2001-05-23 15:26:42 +02:00
try {
2008-12-18 11:57:12 +01:00
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
R IN RDB$RELATIONS WITH R.RDB$RELATION_NAME EQ relation_name.c_str()
if (!DYN_REQUEST(drq_e_relation))
DYN_REQUEST(drq_e_relation) = request;
2001-05-23 15:26:42 +02:00
view = !R.RDB$VIEW_BLR.NULL;
2001-05-23 15:26:42 +02:00
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
(view ? DDL_TRIGGER_DROP_VIEW : DDL_TRIGGER_DROP_TABLE), relation_name, gbl->sqlText);
2001-05-23 15:26:42 +02:00
ERASE R;
2002-06-20 13:37:01 +02:00
if (!R.RDB$SECURITY_CLASS.NULL &&
!strncmp(R.RDB$SECURITY_CLASS, SQL_SECCLASS_PREFIX, SQL_SECCLASS_PREFIX_LEN))
{
DYN_delete_security_class2(gbl->gbl_transaction, R.RDB$SECURITY_CLASS);
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
found = true;
2001-05-23 15:26:42 +02:00
END_FOR;
if (!DYN_REQUEST(drq_e_relation))
DYN_REQUEST(drq_e_relation) = request;
2008-12-18 11:57:12 +01:00
request = CMP_find_request(tdbb, drq_e_rel_con2, DYN_REQUESTS);
id = drq_e_rel_con2;
2001-12-24 03:51:06 +01:00
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
CRT IN RDB$RELATION_CONSTRAINTS
WITH CRT.RDB$RELATION_NAME EQ relation_name.c_str() AND
2001-05-23 15:26:42 +02:00
(CRT.RDB$CONSTRAINT_TYPE EQ PRIMARY_KEY OR
CRT.RDB$CONSTRAINT_TYPE EQ UNIQUE_CNSTRT OR
CRT.RDB$CONSTRAINT_TYPE EQ FOREIGN_KEY)
SORTED BY ASCENDING CRT.RDB$CONSTRAINT_TYPE
if (!DYN_REQUEST(drq_e_rel_con2))
DYN_REQUEST(drq_e_rel_con2) = request;
ERASE CRT;
END_FOR;
if (!DYN_REQUEST(drq_e_rel_con2))
DYN_REQUEST(drq_e_rel_con2) = request;
request = CMP_find_request(tdbb, drq_e_rel_idxs, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_e_rel_idxs;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
IDX IN RDB$INDICES WITH IDX.RDB$RELATION_NAME EQ relation_name.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_e_rel_idxs))
DYN_REQUEST(drq_e_rel_idxs) = request;
delete_index_segment_records(gbl, IDX.RDB$INDEX_NAME);
ERASE IDX;
END_FOR;
if (!DYN_REQUEST(drq_e_rel_idxs))
DYN_REQUEST(drq_e_rel_idxs) = request;
request = CMP_find_request(tdbb, drq_e_trg_msgs2, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_e_trg_msgs2;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
TM IN RDB$TRIGGER_MESSAGES CROSS
T IN RDB$TRIGGERS WITH T.RDB$RELATION_NAME EQ relation_name.c_str() AND
2001-05-23 15:26:42 +02:00
TM.RDB$TRIGGER_NAME EQ T.RDB$TRIGGER_NAME
if (!DYN_REQUEST(drq_e_trg_msgs2))
DYN_REQUEST(drq_e_trg_msgs2) = request;
ERASE TM;
END_FOR;
if (!DYN_REQUEST(drq_e_trg_msgs2))
DYN_REQUEST(drq_e_trg_msgs2) = request;
// CVC: Moved this block here to avoid SF Bug #1111570.
request = CMP_find_request(tdbb, drq_e_rel_con3, DYN_REQUESTS);
id = drq_e_rel_con3;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
CRT IN RDB$RELATION_CONSTRAINTS WITH
CRT.RDB$RELATION_NAME EQ relation_name.c_str() AND
(CRT.RDB$CONSTRAINT_TYPE EQ CHECK_CNSTRT OR
CRT.RDB$CONSTRAINT_TYPE EQ NOT_NULL_CNSTRT)
if (!DYN_REQUEST(drq_e_rel_con3))
DYN_REQUEST(drq_e_rel_con3) = request;
ERASE CRT;
END_FOR;
if (!DYN_REQUEST(drq_e_rel_con3))
DYN_REQUEST(drq_e_rel_con3) = request;
request = CMP_find_request(tdbb, drq_e_rel_flds, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_e_rel_flds;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
RFR IN RDB$RELATION_FIELDS WITH RFR.RDB$RELATION_NAME EQ relation_name.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_e_rel_flds))
DYN_REQUEST(drq_e_rel_flds) = request;
2002-06-20 13:37:01 +02:00
ERASE RFR;
2008-12-18 11:57:12 +01:00
if (!RFR.RDB$SECURITY_CLASS.NULL &&
!strncmp(RFR.RDB$SECURITY_CLASS, SQL_SECCLASS_PREFIX, SQL_SECCLASS_PREFIX_LEN))
{
DYN_delete_security_class2(gbl->gbl_transaction, RFR.RDB$SECURITY_CLASS);
}
2001-05-23 15:26:42 +02:00
delete_gfield_for_lfield(gbl, RFR.RDB$FIELD_SOURCE);
END_FOR;
if (!DYN_REQUEST(drq_e_rel_flds))
DYN_REQUEST(drq_e_rel_flds) = request;
request = CMP_find_request(tdbb, drq_e_view_rels, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_e_view_rels;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
VR IN RDB$VIEW_RELATIONS WITH VR.RDB$VIEW_NAME EQ relation_name.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_e_view_rels))
DYN_REQUEST(drq_e_view_rels) = request;
ERASE VR;
END_FOR;
if (!DYN_REQUEST(drq_e_view_rels))
DYN_REQUEST(drq_e_view_rels) = request;
request = CMP_find_request(tdbb, drq_e_relation, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_e_relation;
if (!found) {
2001-12-24 03:51:06 +01:00
goto dyn_punt_61;
2001-05-23 15:26:42 +02:00
}
// Triggers must be deleted after check constraints
2001-05-23 15:26:42 +02:00
Firebird::MetaName trigger_name;
request = CMP_find_request(tdbb, drq_e_trigger2, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_e_trigger2;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$TRIGGERS WITH X.RDB$RELATION_NAME EQ relation_name.c_str()
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_e_trigger2))
DYN_REQUEST(drq_e_trigger2) = request;
trigger_name = X.RDB$TRIGGER_NAME;
ERASE X;
req2 = CMP_find_request(tdbb, drq_e_trg_prv, DYN_REQUESTS);
id = drq_e_trg_prv;
FOR(REQUEST_HANDLE req2 TRANSACTION_HANDLE gbl->gbl_transaction)
PRIV IN RDB$USER_PRIVILEGES WITH PRIV.RDB$USER EQ trigger_name.c_str()
AND PRIV.RDB$USER_TYPE = obj_trigger
if (!DYN_REQUEST(drq_e_trg_prv))
DYN_REQUEST(drq_e_trg_prv) = req2;
ERASE PRIV;
END_FOR;
if (!DYN_REQUEST(drq_e_trg_prv))
DYN_REQUEST(drq_e_trg_prv) = req2;
2008-12-18 11:57:12 +01:00
id = drq_e_trigger2;
2001-05-23 15:26:42 +02:00
END_FOR;
if (!DYN_REQUEST(drq_e_trigger2))
DYN_REQUEST(drq_e_trigger2) = request;
request = CMP_find_request(tdbb, drq_e_usr_prvs, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
id = drq_e_usr_prvs;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
PRIV IN RDB$USER_PRIVILEGES WITH
PRIV.RDB$RELATION_NAME EQ relation_name.c_str() AND
2008-12-18 11:57:12 +01:00
PRIV.RDB$OBJECT_TYPE = obj_relation
2001-05-23 15:26:42 +02:00
if (!DYN_REQUEST(drq_e_usr_prvs))
DYN_REQUEST(drq_e_usr_prvs) = request;
ERASE PRIV;
END_FOR;
if (!DYN_REQUEST(drq_e_usr_prvs)) {
DYN_REQUEST(drq_e_usr_prvs) = request;
}
request = CMP_find_request(tdbb, drq_e_view_prv, DYN_REQUESTS);
id = drq_e_view_prv;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
PRIV IN RDB$USER_PRIVILEGES WITH
PRIV.RDB$USER EQ relation_name.c_str() AND
PRIV.RDB$USER_TYPE = obj_view
if (!DYN_REQUEST(drq_e_view_prv))
DYN_REQUEST(drq_e_view_prv) = request;
ERASE PRIV;
END_FOR;
if (!DYN_REQUEST(drq_e_view_prv)) {
DYN_REQUEST(drq_e_view_prv) = request;
2001-12-24 03:51:06 +01:00
}
2001-12-24 03:51:06 +01:00
} // try
2009-01-20 09:33:59 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_rundown_request(req2, -1);
2001-12-24 03:51:06 +01:00
// lookup error # from id
// msg 57: "ERASE RDB$INDICES failed"
// msg 58: "ERASE RDB$RELATION_FIELDS failed"
// msg 59: "ERASE RDB$VIEW_RELATIONS failed"
// msg 60: "ERASE RDB$RELATIONS failed"
// msg 62: "ERASE RDB$USER_PRIVILEGES failed"
// msg 65: "ERASE RDB$TRIGGER_MESSAGES failed"
// msg 66: "ERASE RDB$TRIGGERS failed"
// msg 74: "ERASE RDB$SECURITY_CLASSES failed"
// msg 129: "ERASE RDB$RELATION_CONSTRAINTS failed"
USHORT number;
2009-01-20 09:33:59 +01:00
switch (id)
{
2008-01-16 09:46:02 +01:00
case drq_e_rel_con2:
number = 129;
break;
case drq_e_rel_idxs:
number = 57;
break;
case drq_e_trg_msgs2:
number = 65;
break;
case drq_e_trigger2:
number = 66;
break;
case drq_e_rel_flds:
number = 58;
break;
case drq_e_view_rels:
number = 59;
break;
case drq_e_relation:
number = 60;
break;
//case drq_e_sec_class:
// number = 74;
// break;
2008-01-16 09:46:02 +01:00
default:
number = 62;
break;
2001-12-24 03:51:06 +01:00
}
DYN_error_punt(true, number);
2001-12-24 03:51:06 +01:00
}
if (found)
{
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
(view ? DDL_TRIGGER_DROP_VIEW : DDL_TRIGGER_DROP_TABLE), relation_name, gbl->sqlText);
}
2003-11-08 17:40:17 +01:00
while (*(*ptr)++ != isc_dyn_end)
2001-12-24 03:51:06 +01:00
{
2001-05-23 15:26:42 +02:00
--(*ptr);
DYN_execute(gbl, ptr, &relation_name, NULL, NULL, NULL, NULL);
2001-05-23 15:26:42 +02:00
}
2001-12-24 03:51:06 +01:00
return;
dyn_punt_61:
DYN_error_punt(false, 61);
2009-11-21 08:38:05 +01:00
// msg 61: "Relation not found"
2001-05-23 15:26:42 +02:00
}
void DYN_delete_role( Global* gbl, const UCHAR** ptr)
2002-06-30 10:46:51 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ r o l e
*
**************************************
*
* Functional description
*
2008-12-18 11:57:12 +01:00
* Execute a dynamic ddl statement that deletes a role with all its
2002-06-30 10:46:51 +02:00
* members of the role.
*
**************************************/
2004-11-07 15:30:38 +01:00
int id = -1;
Firebird::MetaName role_name;
2002-06-30 10:46:51 +02:00
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2002-06-30 10:46:51 +02:00
jrd_req* request = NULL;
bool found = false;
2002-06-30 10:46:51 +02:00
try {
Firebird::MetaName user(tdbb->getAttachment()->att_user->usr_user_name);
user.upper7();
2002-06-30 10:46:51 +02:00
GET_STRING(ptr, role_name);
request = CMP_find_request(tdbb, drq_drop_role, DYN_REQUESTS);
2002-06-30 10:46:51 +02:00
id = drq_drop_role;
2008-12-18 11:57:12 +01:00
bool del_role_ok = true;
2002-06-30 10:46:51 +02:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
XX IN RDB$ROLES WITH
2008-12-18 11:57:12 +01:00
XX.RDB$ROLE_NAME EQ role_name.c_str()
if (!DYN_REQUEST(drq_drop_role))
DYN_REQUEST(drq_drop_role) = request;
2002-06-30 10:46:51 +02:00
found = true;
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
DDL_TRIGGER_DROP_ROLE, role_name, gbl->sqlText);
2007-08-26 11:05:29 +02:00
const Firebird::MetaName role_owner(XX.RDB$OWNER_NAME);
2002-06-30 10:46:51 +02:00
if (tdbb->getAttachment()->locksmith() || role_owner == user)
2002-06-30 10:46:51 +02:00
{
ERASE XX;
}
else
{
del_role_ok = false;
2002-06-30 10:46:51 +02:00
}
END_FOR;
if (!DYN_REQUEST(drq_drop_role)) {
DYN_REQUEST(drq_drop_role) = request;
}
if (del_role_ok)
{
request = CMP_find_request(tdbb, drq_del_role_1, DYN_REQUESTS);
2002-06-30 10:46:51 +02:00
id = drq_del_role_1;
2009-11-21 08:38:05 +01:00
// The first OR clause finds all members of the role.
// The 2nd OR clause finds all privileges granted to the role
2002-06-30 10:46:51 +02:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
PRIV IN RDB$USER_PRIVILEGES WITH
(PRIV.RDB$RELATION_NAME EQ role_name.c_str() AND
2002-06-30 10:46:51 +02:00
PRIV.RDB$OBJECT_TYPE = obj_sql_role)
OR (PRIV.RDB$USER EQ role_name.c_str() AND
2002-06-30 10:46:51 +02:00
PRIV.RDB$USER_TYPE = obj_sql_role)
if (!DYN_REQUEST(drq_del_role_1)) {
DYN_REQUEST(drq_del_role_1) = request;
}
2002-06-30 10:46:51 +02:00
ERASE PRIV;
END_FOR;
if (!DYN_REQUEST(drq_del_role_1)) {
DYN_REQUEST(drq_del_role_1) = request;
}
}
else
{
DYN_error(false, 191, SafeArg() << user.c_str() << role_name.c_str());
// only owner of SQL role or USR_locksmith could drop SQL role
2002-06-30 10:46:51 +02:00
goto do_punt;
}
} // try
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
2002-06-30 10:46:51 +02:00
DYN_rundown_request(request, -1);
const USHORT number = (id == drq_drop_role ? 191 : 62);
// msg 191: "ERASE RDB$ROLES failed"
// msg 62: "ERASE RDB$USER_PRIVILEGES failed"
DYN_error_punt(true, number);
2002-06-30 10:46:51 +02:00
}
if (found)
{
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
DDL_TRIGGER_DROP_ROLE, role_name, gbl->sqlText);
}
else
{
DYN_error_punt(false, 155, role_name.c_str());
// msg 155: "Role %s not found"
}
2002-06-30 10:46:51 +02:00
return;
do_punt: // ugly, rethink logic of this function
ERR_punt();
}
void DYN_delete_security_class( Global* gbl, const UCHAR** ptr)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ s e c u r i t y _ c l a s s
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes a security class.
*
**************************************/
Firebird::MetaName security_class;
2001-05-23 15:26:42 +02:00
GET_STRING(ptr, security_class);
if (!DYN_delete_security_class2(gbl->gbl_transaction, security_class))
2007-04-01 02:35:59 +02:00
{
DYN_error_punt(false, 75);
2009-11-21 08:38:05 +01:00
// msg 75: "Security class not found"
2007-04-01 02:35:59 +02:00
}
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
while (*(*ptr)++ != isc_dyn_end)
{
2001-05-23 15:26:42 +02:00
--(*ptr);
DYN_execute(gbl, ptr, NULL, NULL, NULL, NULL, NULL);
2001-05-23 15:26:42 +02:00
}
}
void DYN_delete_shadow( Global* gbl, const UCHAR** ptr)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ s h a d o w
*
**************************************
*
* Functional description
* Delete a shadow.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
if (!tdbb->getAttachment()->locksmith())
{
ERR_post(Arg::Gds(isc_adm_task_denied));
}
2001-05-23 15:26:42 +02:00
jrd_req* request = CMP_find_request(tdbb, drq_e_shadow, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
2009-11-25 05:06:48 +01:00
const int shadow_number = DYN_get_number(ptr);
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
FIL IN RDB$FILES WITH FIL.RDB$SHADOW_NUMBER EQ shadow_number
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
if (!DYN_REQUEST(drq_e_shadow))
DYN_REQUEST(drq_e_shadow) = request;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
ERASE FIL;
END_FOR;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
if (!DYN_REQUEST(drq_e_shadow))
DYN_REQUEST(drq_e_shadow) = request;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
}
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 63);
2009-11-21 08:38:05 +01:00
// msg 63: "ERASE RDB$FILES failed"
2001-12-24 03:51:06 +01:00
}
2003-11-08 17:40:17 +01:00
if (*(*ptr)++ != isc_dyn_end) {
2001-05-23 15:26:42 +02:00
DYN_unsupported_verb();
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
}
static bool delete_constraint_records(Global* gbl,
const Firebird::MetaName& constraint_name,
const Firebird::MetaName& relation_name)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* d e l e t e _ c o n s t r a i n t _ r e c o r d s
*
**************************************
*
* Functional description
* Delete a record from RDB$RELATION_CONSTRAINTS
* based on a constraint name.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = CMP_find_request(tdbb, drq_e_rel_con, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
bool found = false;
2001-12-24 03:51:06 +01:00
try {
2009-11-25 05:06:48 +01:00
found = false;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
RC IN RDB$RELATION_CONSTRAINTS
WITH RC.RDB$CONSTRAINT_NAME EQ constraint_name.c_str() AND
RC.RDB$RELATION_NAME EQ relation_name.c_str()
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
if (!DYN_REQUEST(drq_e_rel_con))
DYN_REQUEST(drq_e_rel_con) = request;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
found = true;
ERASE RC;
END_FOR;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
if (!DYN_REQUEST(drq_e_rel_con))
DYN_REQUEST(drq_e_rel_con) = request;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
}
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 129);
2009-11-21 08:38:05 +01:00
// msg 129: "ERASE RDB$RELATION_CONSTRAINTS failed"
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
return found;
}
2009-11-25 05:06:48 +01:00
static bool delete_dimension_records(Global* gbl, const Firebird::MetaName& field_name)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* d e l e t e _ d i m e n s i o n s _ r e c o r d s
*
**************************************
*
* Functional description
* Delete the records in RDB$FIELD_DIMENSIONS
* pertaining to a field.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = CMP_find_request(tdbb, drq_e_dims, DYN_REQUESTS);
2008-12-18 11:57:12 +01:00
bool found = false;
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
found = false;
2001-12-24 03:51:06 +01:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FIELD_DIMENSIONS WITH X.RDB$FIELD_NAME EQ field_name.c_str()
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
if (!DYN_REQUEST(drq_e_dims))
DYN_REQUEST(drq_e_dims) = request;
2001-05-23 15:26:42 +02:00
found = true;
2001-12-24 03:51:06 +01:00
ERASE X;
END_FOR;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
if (!DYN_REQUEST(drq_e_dims))
DYN_REQUEST(drq_e_dims) = request;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
}
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 35);
2009-11-21 08:38:05 +01:00
// msg 35: "ERASE RDB$FIELDS failed"
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
return found;
}
static void delete_f_key_constraint(thread_db* tdbb,
Global* gbl,
const Firebird::MetaName& tbl_nm,
const Firebird::MetaName& ,
const Firebird::MetaName& constraint_nm,
const Firebird::MetaName& index_name)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* d e l e t e _ f _ k e y _ c o n s t r a i n t
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes a record from RDB$RELATION_CONSTRAINTS based on a constraint_nm
2008-12-18 11:57:12 +01:00
*
2001-05-23 15:26:42 +02:00
* On deleting from RDB$RELATION_CONSTRAINTS, 2 system triggers fire:
2008-12-18 11:57:12 +01:00
*
2001-05-23 15:26:42 +02:00
* (A) pre delete trigger: pre_delete_constraint, will:
2008-12-18 11:57:12 +01:00
*
2001-05-23 15:26:42 +02:00
* 1. delete a record first from RDB$REF_CONSTRAINTS where
2008-12-18 11:57:12 +01:00
* RDB$REF_CONSTRAINTS.RDB$CONSTRAINT_NAME =
2001-05-23 15:26:42 +02:00
* RDB$RELATION_CONSTRAINTS.RDB$CONSTRAINT_NAME
2008-12-18 11:57:12 +01:00
*
2001-05-23 15:26:42 +02:00
* (B) post delete trigger: post_delete_constraint will:
2008-12-18 11:57:12 +01:00
*
2001-05-23 15:26:42 +02:00
* 1. also delete a record from RDB$INDICES where
* RDB$INDICES.RDB$INDEX_NAME =
* RDB$RELATION_CONSTRAINTS.RDB$INDEX_NAME
2008-12-18 11:57:12 +01:00
*
2001-05-23 15:26:42 +02:00
* 2. also delete a record from RDB$INDEX_SEGMENTS where
* RDB$INDEX_SEGMENTS.RDB$INDEX_NAME =
* RDB$RELATION_CONSTRAINTS.RDB$INDEX_NAME
2008-12-18 11:57:12 +01:00
*
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_e_rel_const, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
bool found = false;
2001-12-24 03:51:06 +01:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
RC IN RDB$RELATION_CONSTRAINTS
WITH RC.RDB$CONSTRAINT_NAME EQ constraint_nm.c_str()
2001-12-24 03:51:06 +01:00
AND RC.RDB$CONSTRAINT_TYPE EQ FOREIGN_KEY
AND RC.RDB$RELATION_NAME EQ tbl_nm.c_str()
AND RC.RDB$INDEX_NAME EQ index_name.c_str()
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
if (!DYN_REQUEST(drq_e_rel_const))
DYN_REQUEST(drq_e_rel_const) = request;
2001-05-23 15:26:42 +02:00
found = true;
2001-12-24 03:51:06 +01:00
ERASE RC;
END_FOR;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
if (!DYN_REQUEST(drq_e_rel_const))
DYN_REQUEST(drq_e_rel_const) = request;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
if (!found)
{
DYN_error_punt(false, 130, constraint_nm.c_str());
2009-11-21 08:38:05 +01:00
// msg 130: "CONSTRAINT %s does not exist."
2001-12-24 03:51:06 +01:00
}
}
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 129);
2009-11-21 08:38:05 +01:00
// msg 49: "ERASE RDB$RELATION_CONSTRAINTS failed"
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
}
static void delete_gfield_for_lfield( Global* gbl, const Firebird::MetaName& lfield_name)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* d e l e t e _ g f i e l d _ f o r _ l f i e l d
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that
* deletes a global field for a given local field.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
jrd_req* request = CMP_find_request(tdbb, drq_e_l_gfld, DYN_REQUESTS);
2001-05-23 15:26:42 +02:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
FLD IN RDB$FIELDS
WITH FLD.RDB$FIELD_NAME EQ lfield_name.c_str()
2001-05-23 15:26:42 +02:00
AND FLD.RDB$VALIDATION_SOURCE MISSING AND
FLD.RDB$NULL_FLAG MISSING AND
FLD.RDB$DEFAULT_SOURCE MISSING AND
FLD.RDB$FIELD_NAME STARTING WITH IMPLICIT_DOMAIN_PREFIX AND
2001-05-23 15:26:42 +02:00
NOT ANY RFR IN RDB$RELATION_FIELDS WITH
RFR.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME
if (!DYN_REQUEST(drq_e_l_gfld))
DYN_REQUEST(drq_e_l_gfld) = request;
delete_dimension_records(gbl, FLD.RDB$FIELD_NAME);
ERASE FLD;
END_FOR;
if (!DYN_REQUEST(drq_e_l_gfld))
DYN_REQUEST(drq_e_l_gfld) = request;
}
2009-11-25 05:06:48 +01:00
static bool delete_index_segment_records(Global* gbl, const Firebird::MetaName& index_name)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* d e l e t e _ i n d e x _ s e g m e n t _ r e c o r d s
*
**************************************
*
* Functional description
* Delete the records in RDB$INDEX_SEGMENTS
* pertaining to an index.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
jrd_req* request = CMP_find_request(tdbb, drq_e_idx_segs, DYN_REQUESTS);
2008-12-18 11:57:12 +01:00
bool found = false;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
try {
found = false;
2001-12-24 03:51:06 +01:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
I_S IN RDB$INDEX_SEGMENTS WITH I_S.RDB$INDEX_NAME EQ index_name.c_str()
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
if (!DYN_REQUEST(drq_e_idx_segs))
DYN_REQUEST(drq_e_idx_segs) = request;
2001-05-23 15:26:42 +02:00
found = true;
2001-12-24 03:51:06 +01:00
ERASE I_S;
END_FOR;
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
if (!DYN_REQUEST(drq_e_idx_segs))
DYN_REQUEST(drq_e_idx_segs) = request;
}
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 49);
2009-11-21 08:38:05 +01:00
// msg 49: "ERASE RDB$INDEX_SEGMENTS failed"
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
return found;
}
bool DYN_delete_security_class2(jrd_tra* transaction, const Firebird::MetaName& security_class)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* D Y N _ d e l e t e _ s e c u r i t y _ c l a s s 2
2001-05-23 15:26:42 +02:00
*
**************************************
*
* Functional description
* Utility routine for delete_security_class(),
* which takes a string as input.
*
**************************************/
2001-12-24 03:51:06 +01:00
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-12-24 03:51:06 +01:00
jrd_req* request = CMP_find_request(tdbb, drq_e_class, DYN_REQUESTS);
2001-12-24 03:51:06 +01:00
bool found = false;
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
2009-11-25 05:06:48 +01:00
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
SC IN RDB$SECURITY_CLASSES
WITH SC.RDB$SECURITY_CLASS EQ security_class.c_str()
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
if (!DYN_REQUEST(drq_e_class))
DYN_REQUEST(drq_e_class) = request;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
found = true;
ERASE SC;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
END_FOR;
2001-05-23 15:26:42 +02:00
2009-11-25 05:06:48 +01:00
if (!DYN_REQUEST(drq_e_class)) {
DYN_REQUEST(drq_e_class) = request;
}
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
}
2009-11-25 05:06:48 +01:00
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
DYN_error_punt(true, 74);
2009-11-21 08:38:05 +01:00
// msg 74: "ERASE RDB$SECURITY_CLASSES failed"
2001-12-24 03:51:06 +01:00
}
2001-05-23 15:26:42 +02:00
return found;
}