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:
parent
adfb76def6
commit
2c78462820
169
src/jrd/dfw.epp
169
src/jrd/dfw.epp
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
222
src/jrd/dyn.epp
222
src/jrd/dyn.epp
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
/**************************************
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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&);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user