| 
      
      
      From: <asf...@us...> - 2015-04-05 02:24:48
      
     | 
| Revision: 61241
          http://sourceforge.net/p/firebird/code/61241
Author:   asfernandes
Date:     2015-04-05 02:24:40 +0000 (Sun, 05 Apr 2015)
Log Message:
-----------
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.
Modified Paths:
--------------
    firebird/trunk/doc/WhatsNew
    firebird/trunk/src/dsql/DdlNodes.epp
    firebird/trunk/src/jrd/dfw.epp
    firebird/trunk/src/jrd/vio.cpp
Modified: firebird/trunk/doc/WhatsNew
===================================================================
--- firebird/trunk/doc/WhatsNew	2015-04-05 02:24:26 UTC (rev 61240)
+++ firebird/trunk/doc/WhatsNew	2015-04-05 02:24:40 UTC (rev 61241)
@@ -2,6 +2,11 @@
   * 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
         "BLOB not found" error at rollback after insert into table with expression index
       Contributor(s):
Modified: firebird/trunk/src/dsql/DdlNodes.epp
===================================================================
--- firebird/trunk/src/dsql/DdlNodes.epp	2015-04-05 02:24:26 UTC (rev 61240)
+++ firebird/trunk/src/dsql/DdlNodes.epp	2015-04-05 02:24:40 UTC (rev 61241)
@@ -4420,6 +4420,33 @@
 		}
 		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:
 		fb_assert(FALSE);
 		errorCode = ENCODE_ISC_MSG(87, DYN_MSG_FAC);				// MODIFY RDB$FIELDS FAILED
Modified: firebird/trunk/src/jrd/dfw.epp
===================================================================
--- firebird/trunk/src/jrd/dfw.epp	2015-04-05 02:24:26 UTC (rev 61240)
+++ firebird/trunk/src/jrd/dfw.epp	2015-04-05 02:24:40 UTC (rev 61241)
@@ -2148,6 +2148,7 @@
 
 	SET_TDBB(tdbb);
 
+	Jrd::Attachment* attachment = tdbb->getAttachment();
 	Lock* relationLock = NULL;
 	bool releaseRelationLock = false;
 
@@ -2160,15 +2161,33 @@
 	case 3:
 		try
 		{
-			SortedArray<int>& fields = work->dfw_ids;
-
 			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;
 
 			// Protect relation from modification
 			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;
 
 			blr.add(blr_version5);
Modified: firebird/trunk/src/jrd/vio.cpp
===================================================================
--- firebird/trunk/src/jrd/vio.cpp	2015-04-05 02:24:26 UTC (rev 61240)
+++ firebird/trunk/src/jrd/vio.cpp	2015-04-05 02:24:40 UTC (rev 61241)
@@ -2567,20 +2567,28 @@
 				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 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);
-					EVL_field(0, new_rpb->rpb_record, f_rfr_id, &desc2);
+					dsc desc3, desc4;
+					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);
-					SortedArray<int>& ids = DFW_get_ids(work);
+					if ((rc2 && MOV_get_long(&desc2, 0) != 0) ||
+						(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);
-					FB_SIZE_T pos;
-					if (!ids.find(id, pos))
-						ids.insert(pos, id);
+						DeferredWork* work = DFW_post_work(transaction, dfw_check_not_null, &desc1, 0);
+						SortedArray<int>& ids = DFW_get_ids(work);
+
+						int id = MOV_get_long(&desc2, 0);
+						FB_SIZE_T pos;
+						if (!ids.find(id, pos))
+							ids.insert(pos, id);
+					}
 				}
 			}
 			break;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
 |