mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:43:02 +01:00
Fixed CORE-4733 - Command "Alter table <T> alter TYPE <C> <DOMAIN_WITH_NOT_NULL" does not verifies data in column <C> and makes incorrect assignments in <C> to ZERO / JULIAN_DATE / ASCII(0) for types INT, TIMESTAMP and VARCHAR.
This commit is contained in:
parent
b50abdb04c
commit
2828aee4ab
@ -2,6 +2,11 @@
|
|||||||
* v3.0 Beta 2
|
* v3.0 Beta 2
|
||||||
*************
|
*************
|
||||||
|
|
||||||
|
* Bugfix CORE-4733
|
||||||
|
Command "Alter table <T> alter TYPE <C> <DOMAIN_WITH_NOT_NULL" does not verifies data in column <C> and makes incorrect assignments in <C> to ZERO / JULIAN_DATE / ASCII(0) for types INT, TIMESTAMP and VARCHAR
|
||||||
|
Contributor(s):
|
||||||
|
Adriano dos Santos Fernandes <adrianosf at gmail.com>
|
||||||
|
|
||||||
* Bugfix CORE-4713
|
* Bugfix CORE-4713
|
||||||
"BLOB not found" error at rollback after insert into table with expression index
|
"BLOB not found" error at rollback after insert into table with expression index
|
||||||
Contributor(s):
|
Contributor(s):
|
||||||
|
@ -4420,6 +4420,33 @@ void AlterDomainNode::checkUpdate(const dyn_fld& origFld, const dyn_fld& newFld)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case blr_bool:
|
||||||
|
switch (newFld.dyn_dtype)
|
||||||
|
{
|
||||||
|
case blr_bool:
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*** ASF: I'm not yet sure about this, and it is not working internally.
|
||||||
|
// If the original field is a boolean field and the new field is a character field,
|
||||||
|
// is there enough space in the new field?
|
||||||
|
case blr_text:
|
||||||
|
case blr_varying:
|
||||||
|
case blr_cstring:
|
||||||
|
if (newFld.dyn_charlen < origLen)
|
||||||
|
{
|
||||||
|
// msg 208: New size specified for column %s must be at least %d characters.
|
||||||
|
errorCode = isc_dyn_char_fld_too_small;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
***/
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Cannot change datatype for column %s. Conversion from base type %s to base type %s is not supported.
|
||||||
|
errorCode = isc_dyn_invalid_dtype_conversion;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fb_assert(FALSE);
|
fb_assert(FALSE);
|
||||||
errorCode = ENCODE_ISC_MSG(87, DYN_MSG_FAC); // MODIFY RDB$FIELDS FAILED
|
errorCode = ENCODE_ISC_MSG(87, DYN_MSG_FAC); // MODIFY RDB$FIELDS FAILED
|
||||||
|
@ -2148,6 +2148,7 @@ static bool check_not_null(thread_db* tdbb, SSHORT phase, DeferredWork* work, jr
|
|||||||
|
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
|
|
||||||
|
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||||
Lock* relationLock = NULL;
|
Lock* relationLock = NULL;
|
||||||
bool releaseRelationLock = false;
|
bool releaseRelationLock = false;
|
||||||
|
|
||||||
@ -2160,15 +2161,33 @@ static bool check_not_null(thread_db* tdbb, SSHORT phase, DeferredWork* work, jr
|
|||||||
case 3:
|
case 3:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SortedArray<int>& fields = work->dfw_ids;
|
|
||||||
|
|
||||||
jrd_rel* relation = MET_lookup_relation(tdbb, work->dfw_name);
|
jrd_rel* relation = MET_lookup_relation(tdbb, work->dfw_name);
|
||||||
if (relation->rel_view_rse || fields.isEmpty())
|
if (relation->rel_view_rse || work->dfw_ids.isEmpty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Protect relation from modification
|
// Protect relation from modification
|
||||||
relationLock = protect_relation(tdbb, transaction, relation, releaseRelationLock);
|
relationLock = protect_relation(tdbb, transaction, relation, releaseRelationLock);
|
||||||
|
|
||||||
|
SortedArray<int> fields;
|
||||||
|
AutoRequest handle;
|
||||||
|
|
||||||
|
for (SortedArray<int>::iterator itr(work->dfw_ids.begin());
|
||||||
|
itr != work->dfw_ids.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
FOR(REQUEST_HANDLE handle)
|
||||||
|
RFL IN RDB$RELATION_FIELDS CROSS
|
||||||
|
FLD IN RDB$FIELDS
|
||||||
|
WITH RFL.RDB$RELATION_NAME EQ work->dfw_name.c_str() AND
|
||||||
|
FLD.RDB$FIELD_NAME EQ RFL.RDB$FIELD_SOURCE AND
|
||||||
|
RFL.RDB$FIELD_ID EQ *itr AND
|
||||||
|
(RFL.RDB$NULL_FLAG = TRUE OR FLD.RDB$NULL_FLAG = TRUE)
|
||||||
|
{
|
||||||
|
fields.add(RFL.RDB$FIELD_ID);
|
||||||
|
}
|
||||||
|
END_FOR
|
||||||
|
}
|
||||||
|
|
||||||
UCharBuffer blr;
|
UCharBuffer blr;
|
||||||
|
|
||||||
blr.add(blr_version5);
|
blr.add(blr_version5);
|
||||||
|
@ -2567,20 +2567,28 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
|
|||||||
check_class(tdbb, transaction, org_rpb, new_rpb, f_rfr_class);
|
check_class(tdbb, transaction, org_rpb, new_rpb, f_rfr_class);
|
||||||
|
|
||||||
bool rc1 = EVL_field(NULL, org_rpb->rpb_record, f_rfr_null_flag, &desc1);
|
bool rc1 = EVL_field(NULL, org_rpb->rpb_record, f_rfr_null_flag, &desc1);
|
||||||
bool rc2 = EVL_field(NULL, new_rpb->rpb_record, f_rfr_null_flag, &desc2);
|
|
||||||
|
|
||||||
if ((!rc1 || MOV_get_long(&desc1, 0) == 0) && rc2 && MOV_get_long(&desc2, 0) != 0)
|
if ((!rc1 || MOV_get_long(&desc1, 0) == 0))
|
||||||
{
|
{
|
||||||
EVL_field(0, new_rpb->rpb_record, f_rfr_rname, &desc1);
|
dsc desc3, desc4;
|
||||||
EVL_field(0, new_rpb->rpb_record, f_rfr_id, &desc2);
|
bool rc2 = EVL_field(NULL, new_rpb->rpb_record, f_rfr_null_flag, &desc2);
|
||||||
|
bool rc3 = EVL_field(NULL, org_rpb->rpb_record, f_rfr_sname, &desc3);
|
||||||
|
bool rc4 = EVL_field(NULL, new_rpb->rpb_record, f_rfr_sname, &desc4);
|
||||||
|
|
||||||
DeferredWork* work = DFW_post_work(transaction, dfw_check_not_null, &desc1, 0);
|
if ((rc2 && MOV_get_long(&desc2, 0) != 0) ||
|
||||||
SortedArray<int>& ids = DFW_get_ids(work);
|
(rc3 && rc4 && MOV_compare(&desc3, &desc4) != 0))
|
||||||
|
{
|
||||||
|
EVL_field(0, new_rpb->rpb_record, f_rfr_rname, &desc1);
|
||||||
|
EVL_field(0, new_rpb->rpb_record, f_rfr_id, &desc2);
|
||||||
|
|
||||||
int id = MOV_get_long(&desc2, 0);
|
DeferredWork* work = DFW_post_work(transaction, dfw_check_not_null, &desc1, 0);
|
||||||
FB_SIZE_T pos;
|
SortedArray<int>& ids = DFW_get_ids(work);
|
||||||
if (!ids.find(id, pos))
|
|
||||||
ids.insert(pos, id);
|
int id = MOV_get_long(&desc2, 0);
|
||||||
|
FB_SIZE_T pos;
|
||||||
|
if (!ids.find(id, pos))
|
||||||
|
ids.insert(pos, id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user