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

894 lines
22 KiB
Plaintext

/*
* PROGRAM: JRD Data Definition Utility
* MODULE: dyn_define.epp
* DESCRIPTION: Dynamic data definition DYN_define_<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): ______________________________________.
*
* 23-May-2001 Claudio Valderrama - Forbid zero length identifiers,
* they are not ANSI SQL compliant.
* 2001.10.08 Claudio Valderrama: Add case isc_dyn_system_flag to
* DYN_define_trigger() in order to receive values for special triggers
* as defined in constants.h.
* 2001.10.08 Ann Harrison: Changed dyn_create_index so it doesn't consider
* simple unique indexes when finding a "referred index", but only
* indexes that support unique constraints or primary keys.
* 26-Sep-2001 Paul Beach - External File Directory Config. Parameter
* 2002-02-24 Sean Leyne - Code Cleanup of old Win 3.1 port (WINDOWS_ONLY)
* 2002.08.10 Dmitry Yemanov: ALTER VIEW
*
* 2002.10.29 Sean Leyne - Removed obsolete "Netware" port
*
* 2004.01.16 Vlad Horsun: added support for default parameters
*/
#include "firebird.h"
#include "dyn_consts.h"
#include "../common/classes/fb_string.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../common/common.h"
#include "../jrd/jrd.h"
#include "../jrd/ods.h"
#include "../jrd/tra.h"
#include "../jrd/scl.h"
#include "../jrd/drq.h"
#include "../jrd/req.h"
#include "../jrd/flags.h"
#include "../jrd/ibase.h"
#include "../jrd/lls.h"
#include "../jrd/met.h"
#include "../jrd/btr.h"
#include "../jrd/ini.h"
#include "../jrd/intl.h"
#include "../jrd/dyn.h"
#include "../common/gdsassert.h"
#include "../jrd/blb_proto.h"
#include "../jrd/cmp_proto.h"
#include "../jrd/dyn_proto.h"
#include "../jrd/dyn_df_proto.h"
#include "../jrd/dyn_ut_proto.h"
#include "../jrd/err_proto.h"
#include "../jrd/exe_proto.h"
#include "../yvalve/gds_proto.h"
#include "../jrd/inf_proto.h"
#include "../jrd/intl_proto.h"
#include "../common/isc_f_proto.h"
#include "../jrd/met_proto.h"
#include "../jrd/vio_proto.h"
#include "../jrd/scl_proto.h"
#include "../common/gdsassert.h"
#include "../common/os/path_utils.h"
#include "../common/utils_proto.h"
#include "../jrd/IntlManager.h"
#include "../common/IntlUtil.h"
#include "../dsql/DdlNodes.h"
using MsgFormat::SafeArg;
using namespace Jrd;
using namespace Firebird;
typedef Firebird::ObjectsArray<Firebird::MetaName> MetaNameArray;
const int FOR_KEY_UPD_CASCADE = 0x01;
const int FOR_KEY_UPD_NULL = 0x02;
const int FOR_KEY_UPD_DEFAULT = 0x04;
const int FOR_KEY_UPD_NONE = 0x08;
const int FOR_KEY_DEL_CASCADE = 0x10;
const int FOR_KEY_DEL_NULL = 0x20;
const int FOR_KEY_DEL_DEFAULT = 0x40;
const int FOR_KEY_DEL_NONE = 0x80;
DATABASE DB = STATIC "ODS.RDB";
static bool is_it_user_name(Global*, const Firebird::MetaName&, thread_db*);
void DYN_define_file(Global* gbl,
const UCHAR** ptr,
SLONG shadow_number,
SLONG* start,
USHORT msg)
{
/**************************************
*
* D Y N _ d e f i n e _ f i l e
*
**************************************
*
* Functional description
* Define a database or shadow file.
*
**************************************/
UCHAR verb;
SLONG temp;
USHORT man_auto;
SSHORT id;
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
if (!tdbb->getAttachment()->locksmith())
{
ERR_post(Arg::Gds(isc_adm_task_denied));
}
try {
id = -1;
Firebird::PathName temp_f;
GET_STRING(ptr, temp_f);
if (!ISC_expand_filename(temp_f, false))
DYN_error_punt(false, 231); // File name is invalid.
if (dbb->dbb_filename == temp_f)
DYN_error_punt(false, 166);
AutoCacheRequest request(tdbb, id = drq_l_files, DYN_REQUESTS);
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
FIRST 1 X IN RDB$FILES WITH X.RDB$FILE_NAME EQ temp_f.c_str()
{
DYN_error_punt(false, 166);
}
END_FOR
request.reset(tdbb, id = drq_s_files, DYN_REQUESTS);
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FILES
{
temp_f.copyTo(X.RDB$FILE_NAME, sizeof(X.RDB$FILE_NAME));
X.RDB$SHADOW_NUMBER = (SSHORT)shadow_number;
X.RDB$FILE_FLAGS = 0;
X.RDB$FILE_FLAGS.NULL = FALSE;
X.RDB$FILE_START.NULL = TRUE;
X.RDB$FILE_LENGTH.NULL = TRUE;
while ((verb = *(*ptr)++) != isc_dyn_end)
{
switch (verb)
{
case isc_dyn_file_start:
temp = DYN_get_number(ptr);
*start = MAX(*start, temp);
X.RDB$FILE_START = *start;
X.RDB$FILE_START.NULL = FALSE;
break;
case isc_dyn_file_length:
X.RDB$FILE_LENGTH = DYN_get_number(ptr);
X.RDB$FILE_LENGTH.NULL = FALSE;
break;
case isc_dyn_shadow_man_auto:
man_auto = (USHORT)DYN_get_number(ptr);
if (man_auto)
X.RDB$FILE_FLAGS |= FILE_manual;
break;
case isc_dyn_shadow_conditional:
if (DYN_get_number(ptr))
X.RDB$FILE_FLAGS |= FILE_conditional;
break;
default:
DYN_unsupported_verb();
}
}
*start += X.RDB$FILE_LENGTH;
}
END_STORE
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
if (id == drq_l_files)
DYN_error_punt(false, 166);
else
DYN_error_punt(true, msg);
}
}
void DYN_define_difference(Global* gbl, const UCHAR** ptr)
{
/**************************************
*
* D Y N _ d e f i n e _ d i f f e r e n c e
*
**************************************
*
* Functional description
* Define backup difference file.
*
**************************************/
SSHORT id = -1;
thread_db* tdbb = JRD_get_thread_data();
if (!tdbb->getAttachment()->locksmith())
{
ERR_post(Arg::Gds(isc_adm_task_denied));
}
try
{
bool found = false;
id = drq_l_difference;
AutoCacheRequest request(tdbb, drq_l_difference, DYN_REQUESTS);
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
FIL IN RDB$FILES
{
if (FIL.RDB$FILE_FLAGS & FILE_difference)
found = true;
}
END_FOR
if (found)
goto dyn_punt_216;
request.reset(tdbb, drq_s_difference, DYN_REQUESTS);
id = drq_s_difference;
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FILES
{
GET_STRING(ptr, X.RDB$FILE_NAME);
X.RDB$FILE_FLAGS = FILE_difference;
X.RDB$FILE_FLAGS.NULL = FALSE;
X.RDB$FILE_START = 0;
X.RDB$FILE_START.NULL = FALSE;
X.RDB$FILE_LENGTH.NULL = TRUE;
X.RDB$SHADOW_NUMBER.NULL = TRUE;
}
END_STORE
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
if (id == drq_s_difference)
{
DYN_error_punt(true, 150);
// msg 150: STORE RDB$FILES failed
}
else
{
DYN_error_punt(true, 156);
// msg 156: Difference file lookup failed
}
}
return;
dyn_punt_216:
DYN_error_punt(false, 216);
// msg 216: "Difference file is already defined"
}
void DYN_define_filter( Global* gbl, const UCHAR** ptr)
{
/**************************************
*
* D Y N _ d e f i n e _ f i l t e r
*
**************************************
*
* Functional description
* Define a blob filter.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Firebird::MetaName filter_name;
GET_STRING(ptr, filter_name);
AutoCacheRequest request(tdbb, drq_s_filters, DYN_REQUESTS);
bool b_ending_store = false;
try {
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FILTERS USING
strcpy(X.RDB$FUNCTION_NAME, filter_name.c_str());
X.RDB$OUTPUT_SUB_TYPE.NULL = TRUE;
X.RDB$INPUT_SUB_TYPE.NULL = TRUE;
X.RDB$MODULE_NAME.NULL = TRUE;
X.RDB$ENTRYPOINT.NULL = TRUE;
X.RDB$SYSTEM_FLAG = 0;
X.RDB$SYSTEM_FLAG.NULL = FALSE;
{
UCHAR verb;
while ((verb = *(*ptr)++) != isc_dyn_end)
{
switch (verb)
{
case isc_dyn_filter_in_subtype:
X.RDB$INPUT_SUB_TYPE = (SSHORT)DYN_get_number(ptr);
X.RDB$INPUT_SUB_TYPE.NULL = FALSE;
break;
case isc_dyn_filter_out_subtype:
X.RDB$OUTPUT_SUB_TYPE = (SSHORT)DYN_get_number(ptr);
X.RDB$OUTPUT_SUB_TYPE.NULL = FALSE;
break;
case isc_dyn_func_module_name:
GET_STRING(ptr, X.RDB$MODULE_NAME);
X.RDB$MODULE_NAME.NULL = FALSE;
break;
case isc_dyn_func_entry_point:
GET_STRING(ptr, X.RDB$ENTRYPOINT);
X.RDB$ENTRYPOINT.NULL = FALSE;
break;
default:
DYN_unsupported_verb();
}
}
}
END_STORE
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
if (b_ending_store)
{
DYN_error_punt(true, 7);
// msg 7: "DEFINE BLOB FILTER failed"
}
throw;
}
}
void DYN_define_function( Global* gbl, const UCHAR** ptr)
{
/**************************************
*
* D Y N _ d e f i n e _ f u n c t i o n
*
**************************************
*
* Functional description
* Define a user defined function.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Firebird::MetaName function_name;
GET_STRING(ptr, function_name);
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
DDL_TRIGGER_CREATE_FUNCTION, function_name, gbl->sqlText);
AutoCacheRequest request(tdbb, drq_s_funcs, DYN_REQUESTS);
bool b_ending_store = false;
try {
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FUNCTIONS USING
{
strcpy(X.RDB$FUNCTION_NAME, function_name.c_str());
X.RDB$RETURN_ARGUMENT.NULL = TRUE;
X.RDB$QUERY_NAME.NULL = TRUE;
X.RDB$MODULE_NAME.NULL = TRUE;
X.RDB$ENTRYPOINT.NULL = TRUE;
X.RDB$SYSTEM_FLAG = 0;
X.RDB$SYSTEM_FLAG.NULL = FALSE;
X.RDB$LEGACY_FLAG = 1;
X.RDB$LEGACY_FLAG.NULL = FALSE;
X.RDB$DETERMINISTIC_FLAG.NULL = TRUE;
X.RDB$ENGINE_NAME.NULL = TRUE;
UCHAR verb;
while ((verb = *(*ptr)++) != isc_dyn_end)
{
switch (verb)
{
case isc_dyn_func_return_argument:
X.RDB$RETURN_ARGUMENT = (SSHORT)DYN_get_number(ptr);
X.RDB$RETURN_ARGUMENT.NULL = FALSE;
if (X.RDB$RETURN_ARGUMENT > MAX_UDF_ARGUMENTS)
DYN_error_punt(true, 10);
// msg 10: "DEFINE FUNCTION failed"
break;
case isc_dyn_func_module_name:
GET_STRING(ptr, X.RDB$MODULE_NAME);
X.RDB$MODULE_NAME.NULL = FALSE;
break;
case isc_dyn_fld_query_name:
GET_STRING(ptr, X.RDB$QUERY_NAME);
X.RDB$QUERY_NAME.NULL = FALSE;
break;
case isc_dyn_func_entry_point:
GET_STRING(ptr, X.RDB$ENTRYPOINT);
X.RDB$ENTRYPOINT.NULL = FALSE;
break;
default:
--(*ptr);
{
MetaNameProxy tmp(X.RDB$FUNCTION_NAME);
DYN_execute(gbl, ptr, NULL, NULL, NULL, &tmp, NULL);
}
}
}
b_ending_store = true;
}
END_STORE
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
if (b_ending_store)
{
DYN_error_punt(true, 10);
// msg 10: "DEFINE FUNCTION failed"
}
throw;
}
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
DDL_TRIGGER_CREATE_FUNCTION, function_name, gbl->sqlText);
}
void DYN_define_function_arg(Global* gbl, const UCHAR** ptr, Firebird::MetaName* function_name)
{
/**************************************
*
* D Y N _ d e f i n e _ f u n c t i o n _ a r g
*
**************************************
*
* Functional description
* Define a user defined function argument.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
try
{
AutoCacheRequest request(tdbb, drq_s_func_args, DYN_REQUESTS);
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$FUNCTION_ARGUMENTS
{
X.RDB$ARGUMENT_POSITION = (SSHORT)DYN_get_number(ptr);
if (X.RDB$ARGUMENT_POSITION > MAX_UDF_ARGUMENTS)
DYN_error_punt(true, 12); // msg 12: "DEFINE FUNCTION ARGUMENT failed"
if (function_name)
{
strcpy(X.RDB$FUNCTION_NAME, function_name->c_str());
X.RDB$FUNCTION_NAME.NULL = FALSE;
}
else
X.RDB$FUNCTION_NAME.NULL = TRUE;
X.RDB$MECHANISM.NULL = TRUE;
X.RDB$FIELD_TYPE.NULL = TRUE;
X.RDB$FIELD_SCALE.NULL = TRUE;
X.RDB$FIELD_LENGTH.NULL = TRUE;
X.RDB$FIELD_SUB_TYPE.NULL = TRUE;
X.RDB$CHARACTER_SET_ID.NULL = TRUE;
X.RDB$FIELD_PRECISION.NULL = TRUE;
X.RDB$CHARACTER_LENGTH.NULL = TRUE;
UCHAR verb;
while ((verb = *(*ptr)++) != isc_dyn_end)
switch (verb)
{
case isc_dyn_function_name:
GET_STRING(ptr, X.RDB$FUNCTION_NAME);
X.RDB$FUNCTION_NAME.NULL = FALSE;
break;
case isc_dyn_func_mechanism:
X.RDB$MECHANISM = (SSHORT)DYN_get_number(ptr);
X.RDB$MECHANISM.NULL = FALSE;
break;
case isc_dyn_fld_type:
X.RDB$FIELD_TYPE = (SSHORT)DYN_get_number(ptr);
X.RDB$FIELD_TYPE.NULL = FALSE;
break;
case isc_dyn_fld_sub_type:
X.RDB$FIELD_SUB_TYPE = (SSHORT)DYN_get_number(ptr);
X.RDB$FIELD_SUB_TYPE.NULL = FALSE;
break;
case isc_dyn_fld_scale:
X.RDB$FIELD_SCALE = (SSHORT)DYN_get_number(ptr);
X.RDB$FIELD_SCALE.NULL = FALSE;
break;
case isc_dyn_fld_length:
X.RDB$FIELD_LENGTH = (SSHORT)DYN_get_number(ptr);
X.RDB$FIELD_LENGTH.NULL = FALSE;
break;
case isc_dyn_fld_character_set:
X.RDB$CHARACTER_SET_ID = (SSHORT)DYN_get_number(ptr);
X.RDB$CHARACTER_SET_ID.NULL = FALSE;
break;
case isc_dyn_fld_precision:
X.RDB$FIELD_PRECISION = (SSHORT)DYN_get_number(ptr);
X.RDB$FIELD_PRECISION.NULL = FALSE;
break;
// Ignore the field character length as the system UDF parameter
// table has no place to store the information
// But IB6/FB has the place for this information. CVC 2001.
case isc_dyn_fld_char_length:
X.RDB$CHARACTER_LENGTH = (SSHORT)DYN_get_number (ptr);
X.RDB$CHARACTER_LENGTH.NULL = FALSE;
break;
default:
DYN_unsupported_verb();
}
}
END_STORE
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_error_punt(true, 12);
// msg 12: "DEFINE FUNCTION ARGUMENT failed"
}
}
void DYN_define_index(Global* gbl, const UCHAR** ptr, const Firebird::MetaName* relation_name)
{
/**************************************
*
* D Y N _ d e f i n e _ i n d e x
*
**************************************
*
* Functional description
* Execute a dynamic ddl statement that creates an index.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
const UCHAR index_type = isc_dyn_def_idx;
Firebird::MetaName index_name;
UCHAR verb;
Firebird::MetaName trigger_name;
GET_STRING(ptr, index_name);
if (index_name.isEmpty())
DYN_UTIL_generate_index_name(tdbb, gbl->gbl_transaction, index_name, index_type);
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
DDL_TRIGGER_CREATE_INDEX, index_name, gbl->sqlText);
try
{
DYN_UTIL_check_unique_name(tdbb, gbl->gbl_transaction, index_name, obj_index);
}
catch (const Exception& ex)
{
stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_error_punt(true, 21); // msg 21: "STORE RDB$INDICES failed"
}
try
{
CreateIndexNode::Definition definition;
definition.type = index_type;
if (relation_name)
definition.relation = *relation_name;
else if (*(*ptr)++ == isc_dyn_rel_name)
GET_STRING(ptr, definition.relation);
else
DYN_error_punt(false, 14); // msg 14: "No relation specified for index"
while ((verb = *(*ptr)++) != isc_dyn_end)
{
switch (verb)
{
case isc_dyn_idx_unique:
definition.unique = bool(DYN_get_number(ptr));
break;
case isc_dyn_idx_inactive:
definition.inactive = bool(DYN_get_number(ptr));
break;
case isc_dyn_idx_type:
definition.descending = bool(DYN_get_number(ptr));
break;
case isc_dyn_fld_name:
{
MetaName& str = definition.columns.add();
GET_STRING(ptr, str);
break;
}
case isc_dyn_fld_computed_blr:
DYN_put_blr_blob(gbl, ptr, &definition.expressionBlr);
break;
case isc_dyn_fld_computed_source:
DYN_put_text_blob(gbl, ptr, &definition.expressionSource);
break;
default:
DYN_unsupported_verb();
}
}
CreateIndexNode::store(tdbb, gbl->gbl_transaction, index_name, definition);
}
catch (const Exception& ex)
{
stuff_exception(tdbb->tdbb_status_vector, ex);
throw;
}
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
DDL_TRIGGER_CREATE_INDEX, index_name, gbl->sqlText);
}
void DYN_define_role( Global* gbl, const UCHAR** ptr)
{
/**************************************
*
* D Y N _ d e f i n e _ r o l e
*
**************************************
*
* Functional description
*
* Define a SQL role.
* ROLES cannot be named the same as any existing user name
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Firebird::MetaName owner_name(tdbb->getAttachment()->att_user->usr_user_name);
owner_name.upper7();
Firebird::MetaName role_name;
GET_STRING(ptr, role_name);
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
DDL_TRIGGER_CREATE_ROLE, role_name, gbl->sqlText);
if (role_name == owner_name)
{
// user name could not be used for SQL role
DYN_error(false, 193, SafeArg() << owner_name.c_str());
ERR_punt();
}
if (role_name == NULL_ROLE)
{
// keyword NONE could not be used as SQL role name
DYN_error(false, 195, SafeArg() << role_name.c_str());
ERR_punt();
}
try {
if (is_it_user_name(gbl, role_name, tdbb))
{
// user name could not be used for SQL role
DYN_error(false, 193, SafeArg() << role_name.c_str());
goto do_err_punt;
}
Firebird::MetaName dummy_name;
if (DYN_is_it_sql_role(gbl, role_name, dummy_name, tdbb))
{
// SQL role @1 already exists
DYN_error(false, 194, SafeArg() << role_name.c_str());
goto do_err_punt;
}
AutoCacheRequest request(tdbb, drq_role_gens, DYN_REQUESTS);
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$ROLES
{
strcpy(X.RDB$ROLE_NAME, role_name.c_str());
strcpy(X.RDB$OWNER_NAME, owner_name.c_str());
X.RDB$SYSTEM_FLAG = 0;
X.RDB$SYSTEM_FLAG.NULL = FALSE;
}
END_STORE
if (*(*ptr)++ != isc_dyn_end)
goto do_error_punt_9;
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_error_punt(true, 8);
// msg 8: "DEFINE ROLE failed"
}
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
DDL_TRIGGER_CREATE_ROLE, role_name, gbl->sqlText);
return;
do_err_punt:
ERR_punt();
return;
do_error_punt_9:
DYN_error_punt(true, 9);
// msg 9: "DEFINE ROLE unexpected dyn verb"
}
void DYN_define_shadow( Global* gbl, const UCHAR** ptr)
{
/**************************************
*
* D Y N _ d e f i n e _ s h a d o w
*
**************************************
*
* Functional description
* Define a shadow.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
bool found = false;
const SLONG shadow_number = DYN_get_number(ptr);
// If a shadow set identified by the shadow number already exists return error.
AutoCacheRequest request(tdbb, drq_l_shadow, DYN_REQUESTS);
try
{
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
FIRST 1 X IN RDB$FILES WITH X.RDB$SHADOW_NUMBER EQ shadow_number
{
found = true;
}
END_FOR
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_error_punt(true, 164);
// msg 164: "Shadow lookup failed"
}
if (found)
{
DYN_error_punt(false, 165, SafeArg() << shadow_number);
// msg 165: "Shadow %ld already exists"
}
SLONG start = 0;
UCHAR verb;
while ((verb = *(*ptr)++) != isc_dyn_end)
{
switch (verb)
{
case isc_dyn_def_file:
DYN_define_file(gbl, ptr, shadow_number, &start, 157);
break;
default:
DYN_unsupported_verb();
}
}
}
bool is_it_user_name(Global* gbl, const Firebird::MetaName& role_name, thread_db* tdbb)
{
/**************************************
*
* i s _ i t _ u s e r _ n a m e
*
**************************************
*
* Functional description
*
* if role_name is user name returns true. Otherwise returns false.
*
**************************************/
USHORT request_id;
SET_TDBB(tdbb);
bool found = false;
try {
// If there is a user with privilege or a grantor on a relation we
// can infer there is a user with this name
request_id = drq_get_user_priv;
AutoCacheRequest request(tdbb, request_id, DYN_REQUESTS);
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
PRIV IN RDB$USER_PRIVILEGES WITH
(PRIV.RDB$USER EQ role_name.c_str() AND
PRIV.RDB$USER_TYPE = obj_user) OR
(PRIV.RDB$GRANTOR EQ role_name.c_str() AND
PRIV.RDB$OBJECT_TYPE = obj_relation)
{
found = true;
}
END_FOR
if (found)
return found;
// We can infer that 'role_name' is a user name if it owns any relations
// Note we can only get here if a user creates a table and revokes all
// his privileges on the table
request_id = drq_get_rel_owner;
request.reset(tdbb, request_id, DYN_REQUESTS);
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
REL IN RDB$RELATIONS WITH
REL.RDB$OWNER_NAME EQ role_name.c_str()
{
found = true;
}
END_FOR
}
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
ERR_punt();
}
return found;
}