8
0
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:
asfernandes 2015-04-05 02:24:40 +00:00
parent b50abdb04c
commit 2828aee4ab
4 changed files with 72 additions and 13 deletions

View File

@ -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):

View File

@ -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

View File

@ -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);

View File

@ -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;