8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 17:23:04 +01:00

The merge continued.

This commit is contained in:
dimitr 2008-01-16 08:46:02 +00:00
parent adfb76def6
commit 2c78462820
15 changed files with 942 additions and 400 deletions

View File

@ -766,18 +766,15 @@ static bool add_file(thread_db* tdbb, SSHORT phase, DeferredWork* work,
case 3:
if (CCH_exclusive(tdbb, LCK_EX, WAIT_PERIOD))
{
return true;
}
else
{
ERR_post(isc_no_meta_update,
isc_arg_gds, isc_lock_timeout,
isc_arg_gds, isc_obj_in_use,
isc_arg_string, ERR_cstring(dbb->dbb_filename.c_str()),
0);
return false;
}
ERR_post(isc_no_meta_update,
isc_arg_gds, isc_lock_timeout,
isc_arg_gds, isc_obj_in_use,
isc_arg_string, ERR_cstring(dbb->dbb_filename.c_str()),
0);
return false;
case 4:
CCH_flush(tdbb, FLUSH_FINI, 0L);
max = PageSpace::maxAlloc(dbb) + 1;
@ -1255,7 +1252,7 @@ static void check_dependencies(thread_db* tdbb,
AND DEP.RDB$DEPENDED_ON_TYPE = dpdo_type
AND DEP.RDB$FIELD_NAME EQ field_name
REDUCED TO DEP.RDB$DEPENDENT_NAME
if (!REQUEST(irq_ch_f_dpd))
if (!REQUEST(irq_ch_f_dpd))
REQUEST(irq_ch_f_dpd) = request;
/* If the found object is also being deleted, there's no dependency */
@ -1266,7 +1263,7 @@ static void check_dependencies(thread_db* tdbb,
0,
transaction))
{
dep_counts[DEP.RDB$DEPENDENT_TYPE]++;
++dep_counts[DEP.RDB$DEPENDENT_TYPE];
}
END_FOR;
@ -1283,7 +1280,7 @@ static void check_dependencies(thread_db* tdbb,
AND DEP.RDB$DEPENDED_ON_TYPE = dpdo_type
REDUCED TO DEP.RDB$DEPENDENT_NAME
if (!REQUEST(irq_ch_dpd))
if (!REQUEST(irq_ch_dpd))
REQUEST(irq_ch_dpd) = request;
/* If the found object is also being deleted, there's no dependency */
@ -1294,7 +1291,7 @@ static void check_dependencies(thread_db* tdbb,
0,
transaction))
{
dep_counts[DEP.RDB$DEPENDENT_TYPE]++;
++dep_counts[DEP.RDB$DEPENDENT_TYPE];
}
END_FOR;
@ -1302,59 +1299,69 @@ static void check_dependencies(thread_db* tdbb,
REQUEST(irq_ch_dpd) = request;
}
for (i = 0; i < obj_type_MAX; i++) {
if (dep_counts[i])
SLONG total = 0;
for (i = 0; i < obj_type_MAX; i++)
total += dep_counts[i];
if (!total)
return;
if (field_name)
{
ERR_post( isc_no_meta_update,
isc_arg_gds, isc_no_delete, /* Msg353: can not delete */
isc_arg_gds, isc_field_name,
isc_arg_string, ERR_cstring(field_name),
isc_arg_gds, isc_dependency,
isc_arg_number, total,
0); /* Msg310: there are %ld dependencies */
}
else
{
ISC_STATUS obj_type;
switch (dpdo_type)
{
ISC_STATUS obj_type;
switch (dpdo_type)
{
case obj_relation:
obj_type = isc_table_name;
break;
case obj_procedure:
obj_type = isc_proc_name;
break;
case obj_collation:
obj_type = isc_collation_name;
break;
case obj_exception:
obj_type = isc_exception_name;
break;
case obj_field:
obj_type = isc_domain_name;
break;
case obj_generator:
obj_type = isc_generator_name;
break;
case obj_udf:
obj_type = isc_udf_name;
break;
case obj_index:
obj_type = isc_index_name;
break;
default:
fb_assert(FALSE);
break;
}
if (field_name) {
ERR_post( isc_no_meta_update,
isc_arg_gds, isc_no_delete, /* Msg353: can not delete */
isc_arg_gds, isc_field_name,
isc_arg_string, ERR_cstring(field_name),
isc_arg_gds, isc_dependency,
isc_arg_number, dep_counts[i],
0); /* Msg310: there are %ld dependencies */
}
else {
ERR_post( isc_no_meta_update,
isc_arg_gds, isc_no_delete, /* can not delete */
isc_arg_gds, obj_type,
isc_arg_string, ERR_cstring(dpdo_name),
isc_arg_gds, isc_dependency,
isc_arg_number, dep_counts[i],
0); /* there are %ld dependencies */
}
case obj_relation:
obj_type = isc_table_name;
break;
/* Currently we don't get this type due to an internal bug.
case obj_view:
obj_type = isc_view_name;
break;
*/
case obj_procedure:
obj_type = isc_proc_name;
break;
case obj_collation:
obj_type = isc_collation_name;
break;
case obj_exception:
obj_type = isc_exception_name;
break;
case obj_field:
obj_type = isc_domain_name;
break;
case obj_generator:
obj_type = isc_generator_name;
break;
case obj_udf:
obj_type = isc_udf_name;
break;
case obj_index:
obj_type = isc_index_name;
break;
default:
fb_assert(FALSE);
break;
}
ERR_post( isc_no_meta_update,
isc_arg_gds, isc_no_delete, /* can not delete */
isc_arg_gds, obj_type,
isc_arg_string, ERR_cstring(dpdo_name),
isc_arg_gds, isc_dependency,
isc_arg_number, total,
0); /* there are %ld dependencies */
}
}
@ -2096,7 +2103,6 @@ static bool create_relation(thread_db* tdbb,
lock->lck_type = LCK_relation;
lock->lck_owner_handle = LCK_get_owner_handle(tdbb, lock->lck_type);
lock->lck_parent = dbb->dbb_lock;
lock->lck_owner = tdbb->getAttachment();
LCK_lock_non_blocking(tdbb, lock, LCK_EX, LCK_WAIT);
@ -4333,6 +4339,7 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work,
dbb->dbb_sys_trans,
&REL.RDB$RUNTIME);
jrd_req* request_fmtx = CMP_find_request(tdbb, irq_format2, IRQ_REQUESTS);
FOR(REQUEST_HANDLE request_fmtx)
RFR IN RDB$RELATION_FIELDS CROSS
FLD IN RDB$FIELDS WITH
@ -4511,7 +4518,7 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work,
if (!REQUEST(irq_format2))
REQUEST(irq_format2) = request_fmtx;
if (!physical_fields)
if (null_view && !physical_fields)
{
EXE_unwind(tdbb, request_fmt1);
ERR_post(isc_no_meta_update,
@ -4580,6 +4587,7 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work,
relation->rel_flags &= ~REL_scanned;
DFW_post_work(transaction, dfw_scan_relation, NULL, relation->rel_id);
break;
}
@ -4649,7 +4657,7 @@ static bool modify_procedure( thread_db* tdbb,
ERR_post(isc_no_meta_update,
isc_arg_gds, isc_obj_in_use,
isc_arg_string, ERR_cstring(work->dfw_name),
0);
0);
}
}
@ -4667,12 +4675,6 @@ static bool modify_procedure( thread_db* tdbb,
try {
#ifdef SUPERSERVER
if (!(tdbb->getDatabase()->dbb_flags & DBB_sp_rec_mutex_init))
{
THD_rec_mutex_init(&tdbb->getDatabase()->dbb_sp_rec_mutex);
tdbb->getDatabase()->dbb_flags |= DBB_sp_rec_mutex_init;
}
THREAD_EXIT();
if (THD_rec_mutex_lock(&tdbb->getDatabase()->dbb_sp_rec_mutex))
{
@ -4680,7 +4682,7 @@ static bool modify_procedure( thread_db* tdbb,
return false;
}
THREAD_ENTER();
#endif /* SUPERSERVER */
// Do not allow to modify procedure used by user requests
if (procedure->prc_use_count && MET_procedure_in_use(tdbb, procedure))
{
@ -4715,9 +4717,7 @@ static bool modify_procedure( thread_db* tdbb,
true,
PRC_being_altered)))
{
#ifdef SUPERSERVER
THD_rec_mutex_unlock(&tdbb->getDatabase()->dbb_sp_rec_mutex);
#endif
return false;
}
procedure->prc_alter_count = ++prc_alter_count;
@ -4771,16 +4771,11 @@ static bool modify_procedure( thread_db* tdbb,
catch (const Firebird::Exception& ex)
{
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
#ifdef SUPERSERVER
THD_rec_mutex_unlock(&tdbb->getDatabase()->dbb_sp_rec_mutex);
#endif
ERR_punt();
}
#ifdef SUPERSERVER
THD_rec_mutex_unlock(&tdbb->getDatabase()->dbb_sp_rec_mutex);
#endif
return true;
case 5:
@ -5132,7 +5127,7 @@ static Lock* protect_relation(thread_db* tdbb, jrd_tra* transaction, jrd_rel* re
* releaseLock set to true if there was no existing lock before
*
**************************************/
Lock* relLock = RLCK_transaction_relation_lock(transaction, relation);
Lock* relLock = RLCK_transaction_relation_lock(tdbb, transaction, relation);
releaseLock = (relLock->lck_logical == LCK_none);
@ -5489,9 +5484,7 @@ static bool validate_text_type(thread_db* tdbb,
{
return false;
}
else {
return true;
}
return true;
}

View File

@ -897,16 +897,18 @@ static void dmp_pip(const page_inv_page* page, ULONG sequence)
for (int n = 0; n < control->pgc_ppp;) {
while (n < control->pgc_ppp)
{
if (BIT(n))
break;
else
n++;
n++;
}
fprintf(dbg_file, "%d - ", n);
while (n < control->pgc_ppp)
{
if (!BIT(n))
break;
else
n++;
n++;
}
fprintf(dbg_file, "%d, ", n - 1);
}

View File

@ -493,8 +493,7 @@ int DPM_compress( thread_db* tdbb, data_page* page)
// This should also work just a little bit faster too.
const SSHORT l = ROUNDUP(index->dpg_length, ODS_ALIGNMENT);
space -= l;
MOVE_FAST((UCHAR *) page + index->dpg_offset, temp_page + space,
l);
MOVE_FAST((UCHAR *) page + index->dpg_offset, temp_page + space, l);
index->dpg_offset = space;
}
}
@ -927,8 +926,7 @@ void DPM_delete_relation_pages(Jrd::thread_db* tdbb, Jrd::jrd_rel* relation, Jrd
}
CCH_RELEASE_TAIL(tdbb, &data_window);
}
PAG_release_page(PageNumber(relPages->rel_pg_space_id, *page),
ZERO_PAGE_NUMBER);
PAG_release_page(PageNumber(relPages->rel_pg_space_id, *page), ZERO_PAGE_NUMBER);
}
const UCHAR pag_flags = ppage->ppg_header.pag_flags;
CCH_RELEASE_TAIL(tdbb, &window);
@ -946,8 +944,7 @@ void DPM_delete_relation_pages(Jrd::thread_db* tdbb, Jrd::jrd_rel* relation, Jrd
/* Now get rid of the index root page */
PAG_release_page(
PageNumber(relPages->rel_pg_space_id, relPages->rel_index_root),
ZERO_PAGE_NUMBER);
PageNumber(relPages->rel_pg_space_id, relPages->rel_index_root), ZERO_PAGE_NUMBER);
relPages->rel_index_root = 0;
}
@ -1381,8 +1378,7 @@ ULONG DPM_get_blob(thread_db* tdbb,
let somebody else complain. */
pointer_page* ppage = get_pointer_page(tdbb, blob->blb_relation,
blob->blb_relation->getPages(tdbb), &rpb.getWindow(tdbb), pp_sequence,
LCK_read);
blob->blb_relation->getPages(tdbb), &rpb.getWindow(tdbb), pp_sequence, LCK_read);
if (!ppage) {
blob->blb_flags |= BLB_damaged;
return 0UL;
@ -1464,10 +1460,8 @@ ULONG DPM_get_blob(thread_db* tdbb,
if (blob->blb_level == 0) {
blob->blb_space_remaining = length;
UCHAR* p = blob->blb_data;
if (length) {
MOVE_FASTER(q, p, length);
}
if (length)
memcpy(blob->getBuffer(), q, length);
}
else {
vcl* vector = blob->blb_pages;
@ -1476,7 +1470,7 @@ ULONG DPM_get_blob(thread_db* tdbb,
vcl::newVector(*blob->blb_transaction->tra_pool, 0);
}
vector->resize(length / sizeof(SLONG));
MOVE_FASTER(q, vector->memPtr(), length);
memcpy(vector->memPtr(), q, length);
}
if (!delete_flag) {
@ -1734,7 +1728,8 @@ void DPM_pages(
jrd_req* request = CMP_find_request(tdbb, irq_s_pages, IRQ_REQUESTS);
STORE(REQUEST_HANDLE request)
X IN RDB$PAGES X.RDB$RELATION_ID = rel_id;
X IN RDB$PAGES
X.RDB$RELATION_ID = rel_id;
X.RDB$PAGE_TYPE = type;
X.RDB$PAGE_SEQUENCE = sequence;
X.RDB$PAGE_NUMBER = page;
@ -2005,12 +2000,35 @@ RecordNumber DPM_store_blob(thread_db* tdbb, blb* blob, Record* record)
USHORT length;
const UCHAR* q;
PageStack stack;
Firebird::Array<UCHAR> buffer;
if (blob->blb_level == 0) {
if (blob->blb_level == 0)
{
length = blob->blb_clump_size - blob->blb_space_remaining;
q = (UCHAR *) ((blob_page*) blob->blb_data)->blp_page;
if (!blob->hasBuffer())
{
if (blob->blb_temp_size > 0)
{
blob->blb_transaction->getTempSpace()->read(
blob->blb_temp_offset, buffer.getBuffer(blob->blb_temp_size),
blob->blb_temp_size);
q = buffer.begin();
}
else
{
fb_assert(length == 0);
q = NULL;
}
}
else
q = blob->getBuffer();
if (q)
q = (UCHAR*) ((blob_page*) q)->blp_page;
}
else {
else
{
vector = blob->blb_pages;
length = vector->count() * sizeof(SLONG);
q = (UCHAR *) (vector->begin());
@ -2050,11 +2068,9 @@ RecordNumber DPM_store_blob(thread_db* tdbb, blb* blob, Record* record)
header->blh_sub_type = blob->blb_sub_type;
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_original) >= ODS_11_1)
header->blh_charset = blob->blb_charset;
UCHAR* p = (UCHAR *) header->blh_page;
if (length) {
MOVE_FASTER(q, p, length);
}
if (length)
memcpy(header->blh_page, q, length);
data_page* page = (data_page*) rpb.getWindow(tdbb).win_buffer;
if (blob->blb_level && !(page->dpg_header.pag_flags & dpg_large)) {
@ -2308,13 +2324,11 @@ static void delete_tail(thread_db* tdbb, rhdf* header, const USHORT page_space,
const SLONG* const end2 =
page2 + ((bpage->blp_length - BLP_SIZE) / sizeof(SLONG));
while (page2 < end2) {
PAG_release_page(PageNumber(page_space, *page2++),
ZERO_PAGE_NUMBER);
PAG_release_page(PageNumber(page_space, *page2++), ZERO_PAGE_NUMBER);
}
CCH_RELEASE_TAIL(tdbb, &window);
}
PAG_release_page(PageNumber(page_space, *page1),
ZERO_PAGE_NUMBER);
PAG_release_page(PageNumber(page_space, *page1), ZERO_PAGE_NUMBER);
}
}
@ -2991,8 +3005,8 @@ static rhd* locate_space(
locked, then give up on the assumption that things
are really screwed up. */
UCHAR* space = 0;
USHORT i;
for (i = 0; i < 20; i++) {
int i;
for (i = 0; i < 20; ++i) {
DPM_allocate(tdbb, window);
extend_relation(tdbb, relation, window);
space = find_space(tdbb, rpb, size, stack, record, type);
@ -3170,8 +3184,9 @@ static void store_big_record(thread_db* tdbb, record_param* rpb,
/* Start by finding the last data compression control block and set up
to start decompression from the end. */
DataComprControl* dcc;
for (dcc = head_dcc; dcc->dcc_next; dcc = dcc->dcc_next);
DataComprControl* dcc = head_dcc;
while (dcc->dcc_next)
dcc = dcc->dcc_next;
const SCHAR* control = dcc->dcc_end;
const SCHAR* in = (SCHAR *) rpb->rpb_address + rpb->rpb_length;

View File

@ -131,13 +131,13 @@ const int drq_e_prcs = 81; /* erase procedure */
const int drq_e_prms = 82; /* erase all of procedure's parameters */
const int drq_s_prm_src = 83; /* store parameter global field */
const int drq_s_intl_info = 84; /* store RDB$CHARACTER_FIELDS */
const int drq_m_prcs = 85; /* modify procedure */
const int drq_m_prcs = 85; /* modify procedure */
const int drq_s_log_files = 86; /* store log files */
const int drq_s_cache = 87; /* store cache */
const int drq_e_prm = 88; /* erase a procedure parameter */
const int drq_s_xcp = 89; /* store an exception */
const int drq_m_xcp = 90; /* modify an exception */
const int drq_e_prc_prvs = 91; /* erase user privileges on procedure */
const int drq_e_prc_prvs = 91; /* erase user privileges on procedure */
const int drq_e_prc_prv = 92; /* erase procedure's privileges */
const int drq_e_trg_prv = 93; /* erase trigger's privileges */
const int drq_d_log = 94; /* drop log */
@ -163,18 +163,18 @@ const int drq_gcg2 = 113; /* grantor_can_grant */
const int drq_gcg3 = 114; /* grantor_can_grant */
const int drq_gcg4 = 115; /* grantor_can_grant */
const int drq_gcg5 = 116; /* grantor_can_grant */
const int drq_l_view_idx = 117; /* table is view? */
const int drq_l_view_idx = 117; /* table is view? */
const int drq_role_gens = 118; /* store SQL role */
const int drq_get_role_nm = 119; /* get SQL role */
const int drq_get_role_au = 120; /* get SQL role auth */
const int drq_del_role_1 = 121; /* delete SQL role from rdb$user_privilege */
const int drq_del_role_1 = 121; /* delete SQL role from rdb$user_privilege */
const int drq_drop_role = 122; /* delete SQL role from rdb$roles */
const int drq_get_rel_owner = 123; /* get the owner of any relations */
const int drq_get_user_priv = 124; /* get the grantor of user privileges or
the user who was granted the privileges */
const int drq_g_rel_constr_nm= 125; /* get relation constraint name */
const int drq_e_rel_const = 126; /* erase relation constraints */
const int drq_e_gens = 127; /* erase generators */
const int drq_e_gens = 127; /* erase generators */
const int drq_s_f_class = 128; /* set the security class name for a field */
const int drq_s_u_class = 129; /* find a unique security class name for a field */
const int drq_l_difference = 130; /* Look up a backup difference file */
@ -203,6 +203,10 @@ const int drq_l_fld_coll = 152; // lookup field collation
const int drq_l_prp_src = 153; // lookup a procedure parameter source
const int drq_s_prms2 = 154; // store parameters (ODS 11.1)
const int drq_l_prm_coll = 155; // lookup procedure parameter collation
const int drq_MAX = 156;
const int drq_s_prms3 = 156; // store parameters (ODS 11.2)
const int drq_d_gfields2 = 157; // drop a global field for procedure param (ODS 11.2)
const int drq_m_map = 158; // modify os=>db names mapping
const int drq_MAX = 159;
#endif /* JRD_DRQ_H */

View File

@ -835,20 +835,11 @@ bool DSC_make_descriptor(DSC* desc,
break;
case blr_double:
#ifndef VMS
case blr_d_float:
#endif
desc->dsc_length = sizeof(double);
desc->dsc_dtype = dtype_double;
break;
#ifdef VMS
case blr_d_float:
desc->dsc_length = sizeof(double);
desc->dsc_dtype = dtype_d_float;
break;
#endif
case blr_timestamp:
desc->dsc_length = 2 * sizeof(SLONG);
desc->dsc_dtype = dtype_timestamp;

View File

@ -57,16 +57,9 @@ inline bool DTYPE_IS_EXACT(UCHAR d) {
return ((d == dtype_int64) || (d == dtype_long) || (d == dtype_short));
}
#ifdef VMS
inline bool DTYPE_IS_APPROX(UCHAR d) {
return ((d == dtype_double) || (d == dtype_real) || (d == dtype_d_float));
}
#else
inline bool DTYPE_IS_APPROX(UCHAR d) {
return ((d == dtype_double) || (d == dtype_real));
}
#endif
inline bool DTYPE_IS_NUMERIC(UCHAR d) {
return (((d >= dtype_byte) && (d <= dtype_d_float)) || (d == dtype_int64));

View File

@ -130,9 +130,6 @@ struct dsc
GDS_QUAD asQuad() const;
float asReal() const;
double asDouble() const;
#ifdef VMS
double asDFloat() const;
#endif
GDS_DATE asSqlDate() const;
GDS_TIME asSqlTime() const;
GDS_TIMESTAMP asSqlTimestamp() const;
@ -427,23 +424,14 @@ inline bool dsc::isSqlDecimal() const
// Floating point types?
#ifdef VMS
//#define DTYPE_IS_APPROX(d) (((d) == dtype_double) ||
// ((d) == dtype_real) ||
// ((d) == dtype_d_float))
#else
//#define DTYPE_IS_APPROX(d) (((d) == dtype_double) ||
// ((d) == dtype_real))
#endif
inline bool dsc::isApprox() const
{
switch (dsc_dtype) {
case dtype_real:
case dtype_double:
#ifdef VMS
case dtype_d_float:
#endif
return true;
default:
return false;
@ -462,11 +450,7 @@ inline bool dsc::isApprox() const
inline bool dsc::isANumber() const
{
return dsc_dtype >= dtype_byte
#ifdef VMS
&& dsc_dtype <= dtype_d_float
#else
&& dsc_dtype <= dtype_double
#endif
|| dsc_dtype == dtype_int64;
}
@ -648,15 +632,6 @@ inline double dsc::asDouble() const
return 0;
}
#ifdef VMS
inline double dsc::asDFloat() const
{
if (dsc_dtype == dtype_d_float)
return *reinterpret_cast<double*>(dsc_address);
return 0;
}
#endif
inline GDS_DATE dsc::asSqlDate() const
{
if (dsc_dtype == dtype_sql_date)

View File

@ -76,6 +76,10 @@
#include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../common/utils_proto.h"
#include "../jrd/jrd_pwd.h"
#include "../utilities/gsec/gsec.h"
#include "../utilities/gsec/secur_proto.h"
#include "../jrd/msg_encode.h"
using MsgFormat::SafeArg;
@ -94,6 +98,7 @@ static void revoke_permission(Global*, const UCHAR**);
static void store_privilege(Global*, const Firebird::MetaName&, const Firebird::MetaName&, const Firebird::MetaName&,
const TEXT*, SSHORT, SSHORT, int);
static void set_field_class_name(Global*, const Firebird::MetaName&, const Firebird::MetaName&);
static void dyn_user(Global*, const UCHAR**);
void DYN_ddl(Attachment* attachment, jrd_tra* transaction, USHORT length,
@ -633,6 +638,14 @@ void DYN_execute(Global* gbl,
DYN_modify_collation(gbl, ptr);
break;
case isc_dyn_mapping:
DYN_modify_mapping(gbl, ptr);
break;
case isc_dyn_user:
dyn_user(gbl, ptr);
break;
default:
DYN_unsupported_verb();
break;
@ -753,6 +766,47 @@ USHORT DYN_get_string(const TEXT** ptr, Firebird::MetaName& field, size_t, bool
}
USHORT DYN_get_string(const TEXT** ptr, Firebird::string& field, size_t, bool transliterate)
{
/**************************************
*
* D Y N _ g e t _ s t r i n g
*
**************************************
*
* Functional description
* Pick up an object name, move to a target. Return length of string.
* If destination field size is too small, punt.
*
**************************************/
const TEXT* p = *ptr;
USHORT length = (UCHAR) *p++;
length |= ((USHORT) ((UCHAR) (*p++))) << 8;
if (length > MAX_SQL_IDENTIFIER_LEN)
{
DYN_error_punt(false, 159);
// msg 159: Name longer than database field size
}
field.assign(p, length);
p += length;
*ptr = p;
if (transliterate)
{
TEXT temp[MAX_SQL_IDENTIFIER_LEN];
length = INTL_convert_bytes(JRD_get_thread_data(),
ttype_metadata, (BYTE*) temp, sizeof(temp),
ttype_dynamic, (const BYTE*) field.c_str(), field.length(), ERR_post);
field.assign(temp, length);
}
return length;
}
USHORT DYN_get_string(const TEXT** ptr, Firebird::PathName& field, size_t, bool transliterate)
{
/**************************************
@ -1513,7 +1567,8 @@ static bool grantor_can_grant(Global* gbl,
/* no grant option for privilege .. on column .. of [base] table/view .. */
return false;
}
else if (go_fld == -1)
if (go_fld == -1)
{
if (go_rel == 0)
{
@ -1525,7 +1580,8 @@ static bool grantor_can_grant(Global* gbl,
/* no grant option for privilege .. on [base] table/view .. (for column ..) */
return false;
}
else if (go_rel == -1)
if (go_rel == -1)
{
DYN_error(false,
(USHORT)(top_level ? 171 : 172),
@ -1545,7 +1601,8 @@ static bool grantor_can_grant(Global* gbl,
/* no grant option for privilege .. on table/view .. */
return false;
}
else if (go_rel == -1)
if (go_rel == -1)
{
DYN_error(false, 174, SafeArg() << privilege << relation_name.c_str());
/* no .. privilege with grant option on table/view .. */
@ -2129,3 +2186,162 @@ static void store_privilege(Global* gbl,
/* msg 79: "STORE RDB$USER_PRIVILEGES failed in grant" */
}
}
static void dyn_user(Global* gbl, const UCHAR** ptr)
{
/**************************************
*
* d y n _ u s e r
*
**************************************
*
* Functional description
* Implements CREATE/ALTER/DROP USER
*
**************************************/
#if (defined BOOT_BUILD || defined EMBEDDED)
Firebird::status_exception::raise(isc_wish_list, isc_arg_end);
#else
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->tdbb_database;
char securityDatabaseName[MAXPATHLEN];
SecurityDatabase::getPath(securityDatabaseName);
Firebird::ClumpletWriter dpb(Firebird::ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1);
dpb.insertByte(isc_dpb_gsec_attach, TRUE);
dpb.insertString(isc_dpb_trusted_auth, tdbb->tdbb_attachment->att_user->usr_user_name);
isc_db_handle securityDatabase = 0;
ISC_STATUS_ARRAY status;
try
{
THREAD_EXIT();
isc_attach_database(status, 0, securityDatabaseName, &securityDatabase,
dpb.getBufferLength(), reinterpret_cast<const char*>(dpb.getBuffer()));
THREAD_ENTER();
if (status[1])
{
Firebird::status_exception::raise(status);
}
internal_user_data userData;
UCHAR verb;
while ((verb = *(*ptr)++) != isc_user_end)
{
Firebird::string text;
GET_STRING(ptr, text);
switch(verb)
{
case isc_dyn_user_add:
userData.operation = ADD_OPER;
text.copyTo(userData.user_name, sizeof(userData.user_name));
userData.user_name_entered = true;
break;
case isc_dyn_user_mod:
userData.operation = MOD_OPER;
text.copyTo(userData.user_name, sizeof(userData.user_name));
userData.user_name_entered = true;
break;
case isc_dyn_user_del:
userData.operation = DEL_OPER;
text.copyTo(userData.user_name, sizeof(userData.user_name));
userData.user_name_entered = true;
break;
case isc_dyn_user_passwd:
if (text.isEmpty())
{
Firebird::status_exception::raise(ENCODE_ISC_MSG(249, DYN_MSG_FAC), isc_arg_end);
// 249: Password should not be empty string
}
text.copyTo(userData.password, sizeof(userData.password));
userData.password_entered = true;
break;
case isc_dyn_user_first:
if (text.hasData())
{
text.copyTo(userData.first_name, sizeof(userData.first_name));
userData.first_name_entered = true;
}
else
{
userData.first_name_entered = false;
userData.first_name_specified = true;
}
break;
case isc_dyn_user_middle:
if (text.hasData())
{
text.copyTo(userData.middle_name, sizeof(userData.middle_name));
userData.middle_name_entered = true;
}
else
{
userData.middle_name_entered = false;
userData.middle_name_specified = true;
}
break;
case isc_dyn_user_last:
if (text.hasData())
{
text.copyTo(userData.last_name, sizeof(userData.last_name));
userData.last_name_entered = true;
}
else
{
userData.last_name_entered = false;
userData.last_name_specified = true;
}
break;
}
}
THREAD_EXIT();
int errcode = (! userData.user_name_entered) ? GsecMsg18 :
SECURITY_exec_line(status, securityDatabase, &userData, NULL, NULL);
THREAD_ENTER();
switch (errcode)
{
case 0: // nothing
break;
case GsecMsg22:
Firebird::status_exception::raise(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC),
isc_arg_string, ERR_cstring(userData.user_name), isc_arg_end);
default:
Firebird::status_exception::raise(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC), isc_arg_end);
}
THREAD_EXIT();
isc_detach_database(status, &securityDatabase);
THREAD_ENTER();
if (status[1])
{
securityDatabase = 0;
Firebird::status_exception::raise(status);
}
}
catch(const Firebird::Exception& e)
{
if (securityDatabase)
{
THREAD_EXIT();
isc_detach_database(status, &securityDatabase);
THREAD_ENTER();
}
e.stuff_exception(status);
memmove(&status[2], &status[0], sizeof(status) - 2 * sizeof(status[0]));
status[0] = isc_arg_gds;
status[1] = isc_no_meta_update;
Firebird::status_exception::raise(status);
}
#endif
}

View File

@ -66,16 +66,21 @@ public:
const UCHAR* dyn_default_src;
const UCHAR* dyn_default_val;
bool dyn_drop_default;
const UCHAR* dyn_computed_src;
const UCHAR* dyn_computed_val;
bool dyn_drop_computed;
public:
explicit dyn_fld(MemoryPool& p)
: dyn_null_flag(false), dyn_dtype(0), dyn_precision(0), dyn_charlen(0),
dyn_collation(0), dyn_charset(0), dyn_fld_source(p), dyn_rel_name(p),
dyn_fld_name(p), dyn_charbytelen(0),
dyn_default_src(0), dyn_default_val(0), dyn_drop_default(false) { }
dyn_default_src(0), dyn_default_val(0), dyn_drop_default(false),
dyn_computed_src(0), dyn_computed_val(0), dyn_drop_computed(false) { }
dyn_fld()
: dyn_null_flag(false), dyn_dtype(0), dyn_precision(0), dyn_charlen(0),
dyn_collation(0), dyn_charset(0), dyn_charbytelen(0),
dyn_default_src(0), dyn_default_val(0), dyn_drop_default(false) { }
dyn_default_src(0), dyn_default_val(0), dyn_drop_default(false),
dyn_computed_src(0), dyn_computed_val(0), dyn_drop_computed(false) { }
};
} //namespace Jrd
@ -88,6 +93,7 @@ void DYN_execute(Jrd::Global*, const UCHAR**, const Firebird::MetaName*, Firebir
SLONG DYN_get_number(const UCHAR**);
USHORT DYN_get_string(const TEXT**, Firebird::MetaName&, size_t, bool);
USHORT DYN_get_string(const TEXT**, Firebird::PathName&, size_t, bool);
USHORT DYN_get_string(const TEXT**, Firebird::string&, size_t, bool);
USHORT DYN_get_string(const TEXT**, Firebird::UCharBuffer&, size_t, bool);
USHORT DYN_get_string(const TEXT**, TEXT*, size_t, bool);

View File

@ -121,7 +121,6 @@ static const UCHAR who_blr[] =
static void check_unique_name(thread_db*, Global*, const Firebird::MetaName&, bool);
static bool find_field_source(thread_db*, Global*, const Firebird::MetaName&, USHORT, const TEXT*, TEXT*);
static bool get_who(thread_db*, Global*, Firebird::MetaName&);
static bool is_it_user_name(Global*, const Firebird::MetaName&, thread_db*);
@ -514,13 +513,29 @@ void DYN_define_constraint(Global* gbl,
// msg 127: "STORE RDB$REF_CONSTRAINTS failed"
// msg 232: "%s cannot reference %s"
switch (id) {
case drq_s_rel_con: number = 121; local_id = id; break;
case drq_s_ref_con: number = 127; local_id = id; break;
case drq_c_unq_nam: number = 121; break;
case drq_n_idx_seg: number = 124; break;
case drq_c_dup_con: number = 125; break;
case drq_l_rel_info: number = 232; break;
default: number = 125; break;
case drq_s_rel_con:
number = 121;
local_id = id;
break;
case drq_s_ref_con:
number = 127;
local_id = id;
break;
case drq_c_unq_nam:
number = 121;
break;
case drq_n_idx_seg:
number = 124;
break;
case drq_c_dup_con:
number = 125;
break;
case drq_l_rel_info:
number = 232;
break;
default:
number = 125;
break;
}
DYN_rundown_request(request, local_id);
@ -757,12 +772,26 @@ void DYN_define_constraint(Global* gbl,
// msg 125: "Integrity constraint lookup failed"
// msg 127: "STORE RDB$REF_CONSTRAINTS failed"
switch (id) {
case drq_s_rel_con: number = 121; local_id = id; break;
case drq_s_ref_con: number = 127; local_id = id; break;
case drq_c_unq_nam: number = 121; break;
case drq_n_idx_seg: number = 124; break;
case drq_c_dup_con: number = 125; break;
default: number = 125; break;
case drq_s_rel_con:
number = 121;
local_id = id;
break;
case drq_s_ref_con:
number = 127;
local_id = id;
break;
case drq_c_unq_nam:
number = 121;
break;
case drq_n_idx_seg:
number = 124;
break;
case drq_c_dup_con:
number = 125;
break;
default:
number = 125;
break;
}
DYN_rundown_request(request, local_id);
@ -2567,7 +2596,6 @@ void DYN_define_local_field(Global* gbl,
DYN_put_blr_blob(gbl, ptr, &RFR.RDB$DEFAULT_VALUE);
break;
case isc_dyn_fld_default_source:
has_default = true;
RFR.RDB$DEFAULT_SOURCE.NULL = FALSE;
@ -2713,8 +2741,8 @@ void DYN_define_local_field(Global* gbl,
if (!RFR.RDB$VIEW_CONTEXT.NULL)
{
fb_assert(relation_name);
find_field_source(tdbb, gbl, *relation_name, RFR.RDB$VIEW_CONTEXT,
RFR.RDB$BASE_FIELD, RFR.RDB$FIELD_SOURCE);
DYN_UTIL_find_field_source(tdbb, gbl, *relation_name, RFR.RDB$VIEW_CONTEXT,
RFR.RDB$BASE_FIELD, RFR.RDB$FIELD_SOURCE);
}
END_STORE;
@ -2787,7 +2815,7 @@ void DYN_define_parameter( Global* gbl, const UCHAR** ptr, Firebird::MetaName* p
f_precision_null = f_charset_null = f_collation_null = f_notnull_null = TRUE;
id = drq_s_prms;
Firebird::MetaName prc_name;
Firebird::MetaName prc_name, rel_name, fld_name;
prm_mech_t mechanism = prm_mech_normal;
bool explicit_domain = false;
@ -2941,6 +2969,14 @@ void DYN_define_parameter( Global* gbl, const UCHAR** ptr, Firebird::MetaName* p
case isc_dyn_prm_mechanism:
mechanism = (prm_mech_t) DYN_get_number(ptr);
break;
case isc_dyn_rel_name:
GET_STRING(ptr, rel_name);
break;
case isc_dyn_fld_name:
GET_STRING(ptr, fld_name);
break;
default:
--(*ptr);
@ -2950,9 +2986,11 @@ void DYN_define_parameter( Global* gbl, const UCHAR** ptr, Firebird::MetaName* p
if (P.RDB$FIELD_SOURCE.NULL) {
/* Need to store dummy global field */
jrd_req* old_request = request;
id = drq_s_prm_src;
jrd_req* request2 = CMP_find_request(tdbb, drq_s_prm_src, DYN_REQUESTS);
STORE(REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
request = CMP_find_request(tdbb, drq_s_prm_src, DYN_REQUESTS);
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
PS IN RDB$FIELDS USING
DYN_UTIL_generate_field_name(tdbb, gbl, PS.RDB$FIELD_NAME);
strcpy(P.RDB$FIELD_SOURCE, PS.RDB$FIELD_NAME);
@ -2986,8 +3024,9 @@ void DYN_define_parameter( Global* gbl, const UCHAR** ptr, Firebird::MetaName* p
}
END_STORE;
if (!DYN_REQUEST(drq_s_prm_src))
DYN_REQUEST(drq_s_prm_src) = request2;
DYN_REQUEST(drq_s_prm_src) = request;
id = drq_s_prms;
request = old_request;
}
END_STORE;
@ -2995,19 +3034,23 @@ void DYN_define_parameter( Global* gbl, const UCHAR** ptr, Firebird::MetaName* p
DYN_REQUEST(drq_s_prms) = request;
}
request = NULL;
id = -1;
if (explicit_domain)
{
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_original) >= ODS_11_1)
{
jrd_req* request2 = CMP_find_request(tdbb, drq_s_prms2, DYN_REQUESTS);
request = CMP_find_request(tdbb, drq_s_prms2, DYN_REQUESTS);
id = drq_s_prms2;
FOR(REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
P IN RDB$PROCEDURE_PARAMETERS WITH
P.RDB$PROCEDURE_NAME EQ prc_name.c_str() AND
P.RDB$PARAMETER_NAME EQ parameter_name.c_str()
if (!DYN_REQUEST(drq_s_prms2))
DYN_REQUEST(drq_s_prms2) = request2;
DYN_REQUEST(drq_s_prms2) = request;
MODIFY P USING
P.RDB$COLLATION_ID.NULL = f_collation_null;
@ -3030,7 +3073,7 @@ void DYN_define_parameter( Global* gbl, const UCHAR** ptr, Firebird::MetaName* p
END_FOR
if (!DYN_REQUEST(drq_s_prms2))
DYN_REQUEST(drq_s_prms2) = request2;
DYN_REQUEST(drq_s_prms2) = request;
}
else
{
@ -3042,19 +3085,59 @@ void DYN_define_parameter( Global* gbl, const UCHAR** ptr, Firebird::MetaName* p
}
}
if (rel_name.hasData() && fld_name.hasData())
{
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_original) >= ODS_11_2)
{
request = CMP_find_request(tdbb, drq_s_prms3, DYN_REQUESTS);
id = drq_s_prms3;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
P IN RDB$PROCEDURE_PARAMETERS WITH
P.RDB$PROCEDURE_NAME EQ prc_name.c_str() AND
P.RDB$PARAMETER_NAME EQ parameter_name.c_str()
if (!DYN_REQUEST(drq_s_prms3))
DYN_REQUEST(drq_s_prms3) = request;
MODIFY P USING
P.RDB$RELATION_NAME.NULL = FALSE;
strcpy(P.RDB$RELATION_NAME, rel_name.c_str());
P.RDB$FIELD_NAME.NULL = FALSE;
strcpy(P.RDB$FIELD_NAME, fld_name.c_str());
END_MODIFY
END_FOR
if (!DYN_REQUEST(drq_s_prms3))
DYN_REQUEST(drq_s_prms3) = request;
}
else
{
request = NULL;
id = -1;
ERR_post(isc_dsql_feature_not_supported_ods,
isc_arg_number, 11,
isc_arg_number, 2,
0); // ODS_11_2
}
}
}
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
if (id == drq_s_prms) {
DYN_rundown_request(request, drq_s_prms);
if (id == -1 || id == drq_s_prms || id == drq_s_prm_src ||
id == drq_s_prms2 || id == drq_s_prms3)
{
if (id != -1)
DYN_rundown_request(request, id);
DYN_error_punt(true, 136);
/* msg 163: "STORE RDB$PROCEDURE_PARAMETERS failed" */
}
else if (id == drq_s_prm_src) {
DYN_rundown_request(request, drq_s_prm_src);
DYN_error_punt(true, 136);
/* msg 136: "STORE RDB$PROCEDURE_PARAMETERS failed" */
// msg 136: "STORE RDB$PROCEDURE_PARAMETERS failed"
}
DYN_rundown_request(request, -1);
/* Control should never reach this point,
@ -4570,96 +4653,6 @@ local_punt_false_132:
}
static bool find_field_source(thread_db* tdbb,
Global* gbl,
const Firebird::MetaName& view_name,
USHORT context,
const TEXT* local_name,
TEXT* output_field_name)
{
/**************************************
*
* 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);
Database* dbb = tdbb->getDatabase();
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;
}
static bool get_who( thread_db* tdbb, Global* gbl, Firebird::MetaName& output_name)
{
/**************************************

View File

@ -987,8 +987,8 @@ void DYN_delete_parameter(Global* gbl,
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
PP IN RDB$PROCEDURE_PARAMETERS WITH PP.RDB$PROCEDURE_NAME EQ proc_name->c_str()
AND PP.RDB$PARAMETER_NAME EQ name.c_str()
if (!DYN_REQUEST(drq_e_prm))
DYN_REQUEST(drq_e_prm) = request;
if (!DYN_REQUEST(drq_e_prm))
DYN_REQUEST(drq_e_prm) = request;
found = true;
/* get rid of parameters in rdb$fields */
@ -1003,10 +1003,33 @@ void DYN_delete_parameter(Global* gbl,
FLD IN RDB$FIELDS
WITH FLD.RDB$FIELD_NAME EQ PP.RDB$FIELD_SOURCE AND
FLD.RDB$FIELD_NAME STARTING WITH IMPLICIT_DOMAIN_PREFIX
if (!DYN_REQUEST(drq_d_gfields))
DYN_REQUEST(drq_d_gfields) = request;
if (!DYN_REQUEST(drq_d_gfields))
DYN_REQUEST(drq_d_gfields) = request;
ERASE FLD;
bool erase = true;
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_original) >= ODS_11_2)
{
jrd_req* request2 = CMP_find_request(tdbb, drq_d_gfields2, DYN_REQUESTS);
FOR(REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
PP2 IN RDB$PROCEDURE_PARAMETERS
WITH PP2.RDB$PROCEDURE_NAME = PP.RDB$PROCEDURE_NAME AND
PP2.RDB$PARAMETER_NAME = PP.RDB$PARAMETER_NAME
if (!DYN_REQUEST(drq_d_gfields2))
DYN_REQUEST(drq_d_gfields2) = request2;
if (!PP2.RDB$RELATION_NAME.NULL && !PP2.RDB$FIELD_NAME.NULL)
erase = false;
END_FOR;
if (!DYN_REQUEST(drq_d_gfields2))
DYN_REQUEST(drq_d_gfields2) = request2;
}
if (erase)
ERASE FLD;
END_FOR;
if (!DYN_REQUEST(drq_d_gfields))
@ -1104,7 +1127,26 @@ void DYN_delete_procedure( Global* gbl, const UCHAR** ptr)
if (!DYN_REQUEST(drq_d_gfields))
DYN_REQUEST(drq_d_gfields) = request;
ERASE FLD;
bool erase = true;
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_original) >= ODS_11_2)
{
jrd_req* request2 = NULL;
FOR(REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
PP2 IN RDB$PROCEDURE_PARAMETERS
WITH PP2.RDB$PROCEDURE_NAME = PP.RDB$PROCEDURE_NAME AND
PP2.RDB$PARAMETER_NAME = PP.RDB$PARAMETER_NAME
if (!PP2.RDB$RELATION_NAME.NULL && !PP2.RDB$FIELD_NAME.NULL)
erase = false;
END_FOR;
CMP_release(tdbb, request2);
}
if (erase)
ERASE FLD;
END_FOR;
if (!DYN_REQUEST(drq_d_gfields))
@ -1474,15 +1516,33 @@ void DYN_delete_relation( Global* gbl, const UCHAR** ptr, const Firebird::MetaNa
// msg 129: "ERASE RDB$RELATION_CONSTRAINTS failed"
USHORT number;
switch (id) {
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;
default: number = 62; break;
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;
default:
number = 62;
break;
}
DYN_error_punt(true, number);

View File

@ -42,6 +42,7 @@ void DYN_modify_trigger(Jrd::Global*, const UCHAR**);
void DYN_modify_trigger_msg(Jrd::Global*, const UCHAR**, Firebird::MetaName*);
void DYN_modify_sql_field(Jrd::Global*, const UCHAR**, const Firebird::MetaName*);
void DYN_modify_view(Jrd::Global*, const UCHAR**);
void DYN_modify_mapping(Jrd::Global*, const UCHAR**);
#endif // JRD_DYN_MD_PROTO_H

View File

@ -897,8 +897,8 @@ void DYN_modify_global_field(Global* gbl,
/* msg 160: "Only one constraint allowed for a domain" */
break;
}
else
single_validate = true;
single_validate = true;
break;
case isc_dyn_fld_validation_blr:
@ -908,9 +908,8 @@ void DYN_modify_global_field(Global* gbl,
/* msg 160: "Only one constraint allowed for a domain" */
break;
}
else
single_validate = true;
single_validate = true;
fldvald = *ptr;
bfldvald = true;
DYN_skip_attribute(ptr);
@ -1256,10 +1255,13 @@ void DYN_modify_local_field(
**************************************/
USHORT position;
Firebird::MetaName f, r;
TEXT *query_name, *edit_string,
*security_class, *new_name;
const UCHAR *query_header, *description;
const UCHAR* query_name;
const UCHAR* edit_string;
const UCHAR* security_class;
const UCHAR* new_name;
const UCHAR* query_header;
const UCHAR* description;
const UCHAR* new_source = NULL;
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
@ -1289,13 +1291,13 @@ void DYN_modify_local_field(
break;
case isc_dyn_new_fld_name:
new_name = (TEXT*) * ptr;
new_name = *ptr;
nnflag = true;
DYN_skip_attribute(ptr);
break;
case isc_dyn_fld_query_name:
query_name = (TEXT*) * ptr;
query_name = *ptr;
qnflag = true;
DYN_skip_attribute(ptr);
break;
@ -1307,17 +1309,22 @@ void DYN_modify_local_field(
break;
case isc_dyn_fld_edit_string:
edit_string = (TEXT*) * ptr;
edit_string = *ptr;
esflag = true;
DYN_skip_attribute(ptr);
break;
case isc_dyn_security_class:
security_class = (TEXT*) * ptr;
security_class = *ptr;
scflag = true;
DYN_skip_attribute(ptr);
break;
case isc_dyn_fld_source:
new_source = *ptr;
DYN_skip_attribute(ptr);
break;
case isc_dyn_description:
description = *ptr;
dflag = true;
@ -1365,8 +1372,10 @@ void DYN_modify_local_field(
Firebird::MetaName new_fld;
GET_STRING(&new_name, new_fld);
if (new_fld.length() == 0)
{
DYN_error_punt(false, 212);
/* msg 212: "Zero length identifiers not allowed" */
}
check_view_dependency(tdbb, dbb, gbl, r, f);
check_sptrig_dependency(tdbb, dbb, gbl, r, f);
@ -1400,6 +1409,10 @@ void DYN_modify_local_field(
else
FLD.RDB$SECURITY_CLASS.NULL = TRUE;
}
if (new_source)
GET_STRING(&new_source, FLD.RDB$FIELD_SOURCE);
if (dflag) {
if (DYN_put_text_blob(gbl, &description, &FLD.RDB$DESCRIPTION))
FLD.RDB$DESCRIPTION.NULL = FALSE;
@ -1413,11 +1426,8 @@ void DYN_modify_local_field(
DYN_REQUEST(drq_m_lfield) = request;
if (npflag && found && position != existing_position)
modify_lfield_position(tdbb, dbb, gbl, r, f, position,
existing_position);
}
modify_lfield_position(tdbb, dbb, gbl, r, f, position, existing_position);
} // try
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
DYN_rundown_request(request, -1);
@ -1529,8 +1539,6 @@ void DYN_modify_procedure( Global* gbl, const UCHAR** ptr)
jrd_req* request = NULL;
bool found = false;
bool only_description = false;
prc_t prc_type = prc_legacy;
const UCHAR* debug_info_ptr = NULL;
try {
@ -1570,6 +1578,15 @@ void DYN_modify_procedure( Global* gbl, const UCHAR** ptr)
P.RDB$PROCEDURE_SOURCE.NULL = TRUE;
P.RDB$PROCEDURE_INPUTS.NULL = TRUE;
P.RDB$PROCEDURE_OUTPUTS.NULL = TRUE;
// ODS_11_1 fields
P.RDB$DEBUG_INFO.NULL = TRUE;
P.RDB$PROCEDURE_TYPE = prc_legacy;
P.RDB$PROCEDURE_TYPE.NULL = FALSE;
P.RDB$VALID_BLR = TRUE;
P.RDB$VALID_BLR.NULL = FALSE;
}
UCHAR verb;
@ -1611,18 +1628,18 @@ void DYN_modify_procedure( Global* gbl, const UCHAR** ptr)
P.RDB$PROCEDURE_OUTPUTS.NULL = FALSE;
break;
case isc_dyn_prc_type:
prc_type = (prc_t) DYN_get_number(ptr);
break;
case isc_dyn_security_class:
GET_STRING(ptr, P.RDB$SECURITY_CLASS);
P.RDB$SECURITY_CLASS.NULL = FALSE;
break;
case isc_dyn_debug_info:
debug_info_ptr = *ptr;
DYN_skip_blr_blob(ptr);
DYN_put_blr_blob(gbl, ptr, &P.RDB$DEBUG_INFO); // ODS_11_1 field
P.RDB$DEBUG_INFO.NULL = FALSE;
break;
case isc_dyn_prc_type:
P.RDB$PROCEDURE_TYPE = DYN_get_number(ptr); // ODS_11_1 field
break;
default:
@ -1635,33 +1652,6 @@ void DYN_modify_procedure( Global* gbl, const UCHAR** ptr)
if (!DYN_REQUEST(drq_m_prcs))
DYN_REQUEST(drq_m_prcs) = request;
if (!only_description)
{
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_original) >= ODS_11_1)
{
jrd_req* sub_request = NULL;
FOR(REQUEST_HANDLE sub_request TRANSACTION_HANDLE gbl->gbl_transaction)
P IN RDB$PROCEDURES WITH P.RDB$PROCEDURE_NAME EQ procedure_name.c_str()
MODIFY P USING
P.RDB$PROCEDURE_TYPE = prc_type;
P.RDB$PROCEDURE_TYPE.NULL = FALSE;
P.RDB$VALID_BLR = TRUE;
P.RDB$VALID_BLR.NULL = FALSE;
P.RDB$DEBUG_INFO.NULL = (debug_info_ptr == NULL) ? TRUE : FALSE;
if (debug_info_ptr)
DYN_put_blr_blob(gbl, &debug_info_ptr, &P.RDB$DEBUG_INFO);
END_MODIFY;
END_FOR;
CMP_release(tdbb, sub_request);
}
}
}
catch (const Firebird::Exception& ex) {
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
@ -2695,8 +2685,11 @@ void DYN_modify_sql_field(Global* gbl,
// Check to see if the field being altered is involved in any type of dependency.
// If there is a dependency, call DYN_error_punt (inside the function).
fb_assert(relation_name);
check_sptrig_dependency(tdbb, dbb, gbl, *relation_name,
orig_fld.dyn_fld_name);
// ASF: check disabled to allow change of field type to be used
// with TYPE OF COLUMN table.column feature.
//check_sptrig_dependency(tdbb, dbb, gbl, *relation_name,
// orig_fld.dyn_fld_name);
jrd_req* request = NULL;
jrd_req* first_request = NULL;
@ -2705,20 +2698,31 @@ void DYN_modify_sql_field(Global* gbl,
charset;
dtype = scale = prec = subtype = charlen = collation = fldlen = nullflg =
charset = false;
int field_adjusted_count = 0;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
RFR IN RDB$RELATION_FIELDS WITH RFR.RDB$RELATION_NAME = relation_name->c_str()
AND RFR.RDB$FIELD_NAME = orig_fld.dyn_fld_name.c_str()
RFR IN RDB$RELATION_FIELDS CROSS
REL IN RDB$RELATIONS WITH
REL.RDB$RELATION_NAME = RFR.RDB$RELATION_NAME AND
RFR.RDB$RELATION_NAME = relation_name->c_str() AND
RFR.RDB$FIELD_NAME = orig_fld.dyn_fld_name.c_str()
first_request = request;
request = NULL;
found = true;
bool is_view = !REL.RDB$VIEW_BLR.NULL;
bool has_dimensions = false;
bool update_domain = false;
bool domain_has_default = false;
bool domain_is_computed = false;
SSHORT fld_position = 0;
bool fld_position_change = false;
SSHORT view_context = 0;
bool view_context_change = false;
Firebird::MetaName fld_base_field;
bool fld_base_field_change = false;
bool orig_computed = false;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
FLD IN RDB$FIELDS WITH FLD.RDB$FIELD_NAME = RFR.RDB$FIELD_SOURCE
@ -2739,6 +2743,7 @@ void DYN_modify_sql_field(Global* gbl,
orig_fld.dyn_collation = FLD.RDB$COLLATION_ID;
orig_fld.dyn_null_flag = FLD.RDB$NULL_FLAG != 0;
orig_fld.dyn_fld_source = RFR.RDB$FIELD_SOURCE;
orig_computed = !FLD.RDB$COMPUTED_BLR.NULL;
// If the original field type is an array, force its blr type to blr_blob
if (FLD.RDB$DIMENSIONS != 0)
@ -2877,6 +2882,37 @@ void DYN_modify_sql_field(Global* gbl,
new_fld.dyn_dtype = blr_blob;
break;
case isc_dyn_fld_position:
fld_position = DYN_get_number(ptr);
fld_position_change = true;
break;
case isc_dyn_fld_base_fld:
GET_STRING(ptr, fld_base_field);
fld_base_field_change = true;
break;
case isc_dyn_view_context:
view_context = DYN_get_number(ptr);
view_context_change = true;
break;
case isc_dyn_fld_computed_blr:
domain_is_computed = true;
new_fld.dyn_computed_val = *ptr;
DYN_skip_attribute(ptr);
break;
case isc_dyn_fld_computed_source:
new_fld.dyn_computed_src = *ptr;
DYN_skip_attribute(ptr);
break;
case isc_dyn_del_computed:
domain_is_computed = false;
new_fld.dyn_drop_computed = true;
break;
case isc_dyn_del_default:
new_fld.dyn_drop_default = true;
break;
@ -2901,9 +2937,8 @@ void DYN_modify_sql_field(Global* gbl,
DYN_skip_attribute(ptr);
break;
// These should only be defined for BLOB types and should not come through with
// any other types. BLOB types are detected above
// These should only be defined for BLOB types and should not come through with
// any other types. BLOB types are detected above
case isc_dyn_fld_segment_length:
DYN_get_number(ptr);
break;
@ -2914,17 +2949,44 @@ void DYN_modify_sql_field(Global* gbl,
DYN_execute(gbl, ptr, relation_name, &tmp, NULL, NULL, NULL);
}
}
if (fld_base_field_change && view_context_change)
{
fb_assert(is_view);
if (fld_base_field.hasData())
{
char field_name[MAX_SQL_IDENTIFIER_SIZE];
DYN_UTIL_find_field_source(tdbb, gbl, RFR.RDB$RELATION_NAME, view_context,
fld_base_field.c_str(), field_name);
dom_fld.dyn_fld_source = field_name;
update_domain = true;
}
else
DYN_UTIL_generate_field_name(tdbb, gbl, new_fld.dyn_fld_source);
}
END_FOR; // FLD in RDB$FIELDS
CMP_release(tdbb, request);
request = NULL;
const bool sourceIsInternalDomain =
fb_utils::implicit_domain(orig_fld.dyn_fld_source.c_str());
// Now that we have all of the information needed, let's check to see
// if the field type can be modifed
if (!is_view &&
((new_fld.dyn_computed_val && !orig_computed) ||
(!new_fld.dyn_computed_val && orig_computed)))
{
// Cannot add or remove COMPUTED from column @1
DYN_error_punt(false, 248,
SafeArg() << orig_fld.dyn_fld_name.c_str());
}
if (update_domain) {
const bool sourceIsInternalDomain =
fb_utils::implicit_domain(orig_fld.dyn_fld_source.c_str()) && RFR.RDB$BASE_FIELD.NULL;
const bool changeComputed = new_fld.dyn_computed_val || new_fld.dyn_drop_computed;
// Now that we have all of the information needed, let's check to see
// if the field type can be modified
if (update_domain)
{
// a1. Internal domain -> domain.
// a2. Domain -> domain.
@ -2939,9 +3001,12 @@ void DYN_modify_sql_field(Global* gbl,
dom_fld.dyn_charset, dom_fld.dyn_collation);
*/
const ULONG retval = check_update_fld_type(orig_fld, dom_fld);
if (retval != FB_SUCCESS)
modify_err_punt(tdbb, retval, orig_fld, dom_fld);
if (!domain_is_computed && !is_view)
{
const ULONG retval = check_update_fld_type(orig_fld, dom_fld);
if (retval != FB_SUCCESS)
modify_err_punt(tdbb, retval, orig_fld, dom_fld);
}
// If the original definition was a base field type, remove the entries from RDB$FIELDS
if (sourceIsInternalDomain)
@ -2968,8 +3033,25 @@ void DYN_modify_sql_field(Global* gbl,
END_MODIFY;
first_request = request;
request = NULL;
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_original) >= ODS_11_2)
{
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
PRM IN RDB$PROCEDURE_PARAMETERS
WITH PRM.RDB$RELATION_NAME = relation_name->c_str() AND
PRM.RDB$FIELD_NAME = orig_fld.dyn_fld_name.c_str()
MODIFY PRM USING
strcpy(PRM.RDB$FIELD_SOURCE, dom_fld.dyn_fld_source.c_str());
END_MODIFY;
END_FOR;
CMP_release(tdbb, request);
request = NULL;
}
}
else {
else
{
// b1. Domain -> internal domain.
// b2. Internal domain -> internal domain.
@ -2977,6 +3059,7 @@ void DYN_modify_sql_field(Global* gbl,
const UCHAR* defSrc = new_fld.dyn_default_src;
const bool dropDefault = new_fld.dyn_drop_default;
const bool changeDefault = defVal || defSrc || dropDefault;
// If we are altering only the default, we need the old field settings.
if (changeDefault && !new_fld.dyn_dsc.dsc_dtype)
{
@ -2998,9 +3081,13 @@ void DYN_modify_sql_field(Global* gbl,
new_fld.dyn_dsc.dsc_length,
new_fld.dyn_dsc.dsc_sub_type,
new_fld.dyn_charset, new_fld.dyn_collation);
const ULONG retval = check_update_fld_type(orig_fld, new_fld);
if (retval != FB_SUCCESS)
modify_err_punt(tdbb, retval, orig_fld, new_fld);
if (!changeComputed && !orig_computed && !is_view)
{
const ULONG retval = check_update_fld_type(orig_fld, new_fld);
if (retval != FB_SUCCESS)
modify_err_punt(tdbb, retval, orig_fld, new_fld);
}
// Check to see if the original data type for the field was based on a domain. If it
// was (and now it isn't), remove the domain information and replace it with a generated
@ -3009,11 +3096,10 @@ void DYN_modify_sql_field(Global* gbl,
if (!changeDefault && !sourceIsInternalDomain)
{
// b1. Domain -> internal domain. Not for changing DEFAULT value.
request = first_request;
MODIFY RFR USING
DYN_UTIL_generate_field_name(tdbb, gbl,
RFR.RDB$FIELD_SOURCE);
DYN_UTIL_generate_field_name(tdbb, gbl, RFR.RDB$FIELD_SOURCE);
new_fld.dyn_fld_source = RFR.RDB$FIELD_SOURCE;
END_MODIFY;
first_request = request;
@ -3084,13 +3170,41 @@ void DYN_modify_sql_field(Global* gbl,
FLD.RDB$FIELD_LENGTH = new_fld.dyn_dsc.dsc_length;
FLD.RDB$FIELD_LENGTH.NULL = FALSE;
}
if (new_fld.dyn_computed_val)
{
DYN_put_blr_blob(gbl, &new_fld.dyn_computed_val, &FLD.RDB$COMPUTED_BLR);
FLD.RDB$COMPUTED_BLR.NULL = FALSE;
}
if (new_fld.dyn_computed_src)
{
DYN_put_text_blob(gbl, &new_fld.dyn_computed_src, &FLD.RDB$COMPUTED_SOURCE);
FLD.RDB$COMPUTED_SOURCE.NULL = FALSE;
}
// Copy the field name into RDB$FIELDS
strcpy(FLD.RDB$FIELD_NAME, new_fld.dyn_fld_source.c_str());
END_STORE;
CMP_release(tdbb, request);
request = NULL;
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_original) >= ODS_11_2)
{
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
PRM IN RDB$PROCEDURE_PARAMETERS
WITH PRM.RDB$RELATION_NAME = relation_name->c_str() AND
PRM.RDB$FIELD_NAME = orig_fld.dyn_fld_name.c_str()
MODIFY PRM USING
strcpy(PRM.RDB$FIELD_SOURCE, new_fld.dyn_fld_source.c_str());
END_MODIFY;
END_FOR;
CMP_release(tdbb, request);
request = NULL;
}
}
else if (changeDefault)
{
@ -3199,17 +3313,23 @@ void DYN_modify_sql_field(Global* gbl,
FLD.RDB$FIELD_LENGTH = new_fld.dyn_dsc.dsc_length;
FLD.RDB$FIELD_LENGTH.NULL = FALSE;
}
// For now the test is redundant: we just can wipe out the
// computed part because we don't allow to change the
// computed expression or to turn a physical field into
// a computed one. Therefore, if we came here,
// it's to get rid of the computed part unconditionally.
if (domain_is_computed)
if (changeComputed)
{
FLD.RDB$COMPUTED_BLR.NULL = TRUE;
FLD.RDB$COMPUTED_SOURCE.NULL = TRUE;
FLD.RDB$DEFAULT_SOURCE.NULL = TRUE;
FLD.RDB$DEFAULT_VALUE.NULL = TRUE;
if (new_fld.dyn_computed_val)
{
DYN_put_blr_blob(gbl, &new_fld.dyn_computed_val, &FLD.RDB$COMPUTED_BLR);
FLD.RDB$COMPUTED_BLR.NULL = FALSE;
}
if (new_fld.dyn_computed_src)
{
DYN_put_text_blob(gbl, &new_fld.dyn_computed_src, &FLD.RDB$COMPUTED_SOURCE);
FLD.RDB$COMPUTED_SOURCE.NULL = FALSE;
}
}
END_MODIFY;
@ -3228,7 +3348,23 @@ void DYN_modify_sql_field(Global* gbl,
request = NULL;
}
} // else not a domain
request = first_request;
if (fld_position_change || view_context_change || fld_base_field_change)
{
MODIFY RFR USING
if (fld_position_change)
RFR.RDB$FIELD_POSITION = fld_position;
if (view_context_change)
RFR.RDB$VIEW_CONTEXT = view_context;
if (fld_base_field_change)
{
RFR.RDB$BASE_FIELD.NULL = fld_base_field.isEmpty();
strcpy(RFR.RDB$BASE_FIELD, fld_base_field.c_str());
}
END_MODIFY;
}
END_FOR; // RFR IN RDB$RELATION_FIELDS
CMP_release(tdbb, request);
request = NULL;
@ -3253,6 +3389,72 @@ void DYN_modify_sql_field(Global* gbl,
}
// *************************************
// D Y N _ m o d i f y _ m a p p i n g
// *************************************
// It's purpose is to add/drop mapping from OS security name
// to DB security object
void DYN_modify_mapping(Global* gbl, const UCHAR** ptr)
{
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->tdbb_database;
jrd_req* request = CMP_find_request(tdbb, drq_m_map, DYN_REQUESTS);
bool found = false;
Firebird::string osName, dbName;
GET_STRING(ptr, osName);
const UCHAR op = *(*ptr)++;
GET_STRING(ptr, dbName);
// This is FB 2.5 limited implementation!
// Later it should work with new system table, something like RDB$MAPPING.
if (osName != DOMAIN_ADMINS || dbName != ADMIN_ROLE)
{
Firebird::status_exception::raise(isc_no_meta_update, isc_arg_gds, isc_wish_list, isc_arg_end);
}
if (!(tdbb->tdbb_attachment && tdbb->tdbb_attachment->locksmith()))
ERR_post(isc_adm_task_denied, 0);
found = false;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$ROLES
WITH X.RDB$ROLE_NAME EQ dbName.c_str()
if (!DYN_REQUEST(drq_m_map))
DYN_REQUEST(drq_m_map) = request;
found = true;
MODIFY X
switch (op)
{
case isc_dyn_map_role:
X.RDB$SYSTEM_FLAG = ROLE_FLAG_DBO | ROLE_FLAG_MAY_TRUST;
break;
case isc_dyn_unmap_role:
X.RDB$SYSTEM_FLAG = ROLE_FLAG_DBO;
break;
default:
DYN_unsupported_verb();
}
END_MODIFY;
END_FOR;
if (!DYN_REQUEST(drq_m_map))
DYN_REQUEST(drq_m_map) = request;
if (!found)
{
Firebird::status_exception::raise(isc_no_meta_update, isc_arg_gds,
isc_random, isc_arg_string, "Missing RDB$ADMIN role in the database",
isc_arg_end);
}
}
void get_domain_type(thread_db* tdbb, Database* dbb, Global* gbl, dyn_fld& dom_fld)
{
/**************************************
@ -3384,7 +3586,6 @@ static ULONG check_update_fld_type(const dyn_fld& orig_fld,
return isc_dyn_dtype_invalid;
/* Cannot change datatype for column %s.
The operation cannot be performed on BLOB, or ARRAY columns. */
break;
/* DATE types */
case blr_sql_date:
@ -3448,7 +3649,6 @@ static ULONG check_update_fld_type(const dyn_fld& orig_fld,
return isc_dyn_dtype_invalid;
/* Cannot change datatype for column %s.
The operation cannot be performed on BLOB, or ARRAY columns. */
break;
case blr_sql_date:
case blr_sql_time:

View File

@ -27,6 +27,8 @@
void DYN_UTIL_store_check_constraints(Jrd::thread_db*, Jrd::Global*,
const Firebird::MetaName&, const Firebird::MetaName&);
bool DYN_UTIL_find_field_source(Jrd::thread_db* tdbb, Jrd::Global* gbl, const Firebird::MetaName& view_name,
USHORT context, const TEXT* local_name, TEXT* output_field_name);
bool DYN_UTIL_get_prot(Jrd::thread_db*, Jrd::Global*, const SCHAR*,
const SCHAR*, Jrd::SecurityClass::flags_t*);
void DYN_UTIL_generate_trigger_name(Jrd::thread_db*, Jrd::Global*, Firebird::MetaName&);

View File

@ -56,6 +56,7 @@
#include "../jrd/isc_f_proto.h"
#include "../jrd/thd.h"
#include "../jrd/vio_proto.h"
#include "../common/utils_proto.h"
using MsgFormat::SafeArg;
@ -468,6 +469,96 @@ void DYN_UTIL_generate_trigger_name( thread_db* tdbb, Global* gbl, Firebird::Met
}
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);
Database* dbb = tdbb->tdbb_database;
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,