mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Fast default trigger and expand_tuple fixes
Ensure that triggers get properly filled in tuples for the OLD value. Also fix the logic of detecting missing null values. The previous logic failed to detect a missing null column before the first missing column with a default. Fixing this has simplified the logic a bit. Regression tests are added to test changes. This should ensure better coverage of expand_tuple(). Original bug reports, and some code and test scripts from Tomas Vondra Backpatch to release 11.
This commit is contained in:
		@@ -823,44 +823,35 @@ expand_tuple(HeapTuple *targetHeapTuple,
 | 
			
		||||
		{
 | 
			
		||||
			if (attrmiss[firstmissingnum].am_present)
 | 
			
		||||
				break;
 | 
			
		||||
			else
 | 
			
		||||
				hasNulls = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * If there are no more missing values everything else must be NULL
 | 
			
		||||
		 * Now walk the missing attributes. If there is a missing value
 | 
			
		||||
		 * make space for it. Otherwise, it's going to be NULL.
 | 
			
		||||
		 */
 | 
			
		||||
		if (firstmissingnum >= natts)
 | 
			
		||||
		for (attnum = firstmissingnum;
 | 
			
		||||
			 attnum < natts;
 | 
			
		||||
			 attnum++)
 | 
			
		||||
		{
 | 
			
		||||
			hasNulls = true;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * Now walk the missing attributes. If there is a missing value
 | 
			
		||||
			 * make space for it. Otherwise, it's going to be NULL.
 | 
			
		||||
			 */
 | 
			
		||||
			for (attnum = firstmissingnum;
 | 
			
		||||
				 attnum < natts;
 | 
			
		||||
				 attnum++)
 | 
			
		||||
			if (attrmiss[attnum].am_present)
 | 
			
		||||
			{
 | 
			
		||||
				if (attrmiss[attnum].am_present)
 | 
			
		||||
				{
 | 
			
		||||
					Form_pg_attribute att = TupleDescAttr(tupleDesc, attnum);
 | 
			
		||||
				Form_pg_attribute att = TupleDescAttr(tupleDesc, attnum);
 | 
			
		||||
 | 
			
		||||
					targetDataLen = att_align_datum(targetDataLen,
 | 
			
		||||
													att->attalign,
 | 
			
		||||
													att->attlen,
 | 
			
		||||
													attrmiss[attnum].am_value);
 | 
			
		||||
				targetDataLen = att_align_datum(targetDataLen,
 | 
			
		||||
												att->attalign,
 | 
			
		||||
												att->attlen,
 | 
			
		||||
												attrmiss[attnum].am_value);
 | 
			
		||||
 | 
			
		||||
					targetDataLen = att_addlength_pointer(targetDataLen,
 | 
			
		||||
														  att->attlen,
 | 
			
		||||
														  attrmiss[attnum].am_value);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					/* no missing value, so it must be null */
 | 
			
		||||
					hasNulls = true;
 | 
			
		||||
				}
 | 
			
		||||
				targetDataLen = att_addlength_pointer(targetDataLen,
 | 
			
		||||
													  att->attlen,
 | 
			
		||||
													  attrmiss[attnum].am_value);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* no missing value, so it must be null */
 | 
			
		||||
				hasNulls = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}							/* end if have missing values */
 | 
			
		||||
 
 | 
			
		||||
@@ -3396,7 +3396,10 @@ ltrmark:;
 | 
			
		||||
		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result = heap_copytuple(&tuple);
 | 
			
		||||
	if (HeapTupleHeaderGetNatts(tuple.t_data) < relation->rd_att->natts)
 | 
			
		||||
		result = heap_expand_tuple(&tuple, relation->rd_att);
 | 
			
		||||
	else
 | 
			
		||||
		result = heap_copytuple(&tuple);
 | 
			
		||||
	ReleaseBuffer(buffer);
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user