unchanged.patch
text/x-patch
Filename: unchanged.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/adt/ri_triggers.c | 0 | 0 |
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
new file mode 100644
index 03a974a..107408f
*** a/src/backend/utils/adt/ri_triggers.c
--- b/src/backend/utils/adt/ri_triggers.c
*************** static void ri_BuildQueryKeyFull(RI_Quer
*** 205,215 ****
static void ri_BuildQueryKeyPkCheck(RI_QueryKey *key,
const RI_ConstraintInfo *riinfo,
int32 constr_queryno);
! static bool ri_KeysEqual(Relation rel, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk);
! static bool ri_AllKeysUnequal(Relation rel, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk);
! static bool ri_OneKeyEqual(Relation rel, int column,
HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk);
static bool ri_AttributesEqual(Oid eq_opr, Oid typeid,
--- 205,215 ----
static void ri_BuildQueryKeyPkCheck(RI_QueryKey *key,
const RI_ConstraintInfo *riinfo,
int32 constr_queryno);
! static bool ri_KeysUnchanged(Relation rel, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk);
! static bool ri_AllKeysChanged(Relation rel, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk);
! static bool ri_OneKeyUnchanged(Relation rel, int column,
HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk);
static bool ri_AttributesEqual(Oid eq_opr, Oid typeid,
*************** RI_FKey_noaction_upd(PG_FUNCTION_ARGS)
*** 932,940 ****
}
/*
! * No need to check anything if old and new keys are equal
*/
! if (ri_KeysEqual(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowShareLock);
return PointerGetDatum(NULL);
--- 932,940 ----
}
/*
! * No need to check anything if old and new keys are unchanged
*/
! if (ri_KeysUnchanged(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowShareLock);
return PointerGetDatum(NULL);
*************** RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
*** 1281,1289 ****
}
/*
! * No need to do anything if old and new keys are equal
*/
! if (ri_KeysEqual(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowExclusiveLock);
return PointerGetDatum(NULL);
--- 1281,1289 ----
}
/*
! * No need to do anything if old and new keys are unchanged
*/
! if (ri_KeysUnchanged(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowExclusiveLock);
return PointerGetDatum(NULL);
*************** RI_FKey_restrict_upd(PG_FUNCTION_ARGS)
*** 1646,1654 ****
}
/*
! * No need to check anything if old and new keys are equal
*/
! if (ri_KeysEqual(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowShareLock);
return PointerGetDatum(NULL);
--- 1646,1654 ----
}
/*
! * No need to check anything if old and new keys are unchanged
*/
! if (ri_KeysUnchanged(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowShareLock);
return PointerGetDatum(NULL);
*************** RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
*** 1993,2001 ****
}
/*
! * No need to do anything if old and new keys are equal
*/
! if (ri_KeysEqual(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowExclusiveLock);
return PointerGetDatum(NULL);
--- 1993,2001 ----
}
/*
! * No need to do anything if old and new keys are unchanged
*/
! if (ri_KeysUnchanged(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowExclusiveLock);
return PointerGetDatum(NULL);
*************** RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
*** 2012,2024 ****
* our cached plan, unless the update happens to change all
* columns in the key. Fortunately, for the most common case of a
* single-column foreign key, this will be true.
- *
- * In case you're wondering, the inequality check works because we
- * know that the old key value has no NULLs (see above).
*/
use_cached_query = (riinfo.confmatchtype == FKCONSTR_MATCH_FULL) ||
! ri_AllKeysUnequal(pk_rel, old_row, new_row,
&riinfo, true);
/*
--- 2012,2021 ----
* our cached plan, unless the update happens to change all
* columns in the key. Fortunately, for the most common case of a
* single-column foreign key, this will be true.
*/
use_cached_query = (riinfo.confmatchtype == FKCONSTR_MATCH_FULL) ||
! ri_AllKeysChanged(pk_rel, old_row, new_row,
&riinfo, true);
/*
*************** RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
*** 2064,2070 ****
* to changed columns in pk_rel's key
*/
if (riinfo.confmatchtype == FKCONSTR_MATCH_FULL ||
! !ri_OneKeyEqual(pk_rel, i, old_row, new_row,
&riinfo, true))
{
appendStringInfo(&querybuf,
--- 2061,2067 ----
* to changed columns in pk_rel's key
*/
if (riinfo.confmatchtype == FKCONSTR_MATCH_FULL ||
! !ri_OneKeyUnchanged(pk_rel, i, old_row, new_row,
&riinfo, true))
{
appendStringInfo(&querybuf,
*************** RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
*** 2389,2397 ****
}
/*
! * No need to do anything if old and new keys are equal
*/
! if (ri_KeysEqual(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowExclusiveLock);
return PointerGetDatum(NULL);
--- 2386,2394 ----
}
/*
! * No need to do anything if old and new keys are unchanged
*/
! if (ri_KeysUnchanged(pk_rel, old_row, new_row, &riinfo, true))
{
heap_close(fk_rel, RowExclusiveLock);
return PointerGetDatum(NULL);
*************** RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
*** 2443,2449 ****
* to changed columns in pk_rel's key
*/
if (riinfo.confmatchtype == FKCONSTR_MATCH_FULL ||
! !ri_OneKeyEqual(pk_rel, i, old_row, new_row,
&riinfo, true))
{
appendStringInfo(&querybuf,
--- 2440,2446 ----
* to changed columns in pk_rel's key
*/
if (riinfo.confmatchtype == FKCONSTR_MATCH_FULL ||
! !ri_OneKeyUnchanged(pk_rel, i, old_row, new_row,
&riinfo, true))
{
appendStringInfo(&querybuf,
*************** RI_FKey_keyequal_upd_pk(Trigger *trigger
*** 2540,2547 ****
{
case FKCONSTR_MATCH_UNSPECIFIED:
case FKCONSTR_MATCH_FULL:
! /* Return true if keys are equal */
! return ri_KeysEqual(pk_rel, old_row, new_row, &riinfo, true);
/* Handle MATCH PARTIAL set null delete. */
case FKCONSTR_MATCH_PARTIAL:
--- 2537,2544 ----
{
case FKCONSTR_MATCH_UNSPECIFIED:
case FKCONSTR_MATCH_FULL:
! /* Return true if keys are unchanged */
! return ri_KeysUnchanged(pk_rel, old_row, new_row, &riinfo, true);
/* Handle MATCH PARTIAL set null delete. */
case FKCONSTR_MATCH_PARTIAL:
*************** RI_FKey_keyequal_upd_fk(Trigger *trigger
*** 2585,2592 ****
{
case FKCONSTR_MATCH_UNSPECIFIED:
case FKCONSTR_MATCH_FULL:
! /* Return true if keys are equal */
! return ri_KeysEqual(fk_rel, old_row, new_row, &riinfo, false);
/* Handle MATCH PARTIAL set null delete. */
case FKCONSTR_MATCH_PARTIAL:
--- 2582,2589 ----
{
case FKCONSTR_MATCH_UNSPECIFIED:
case FKCONSTR_MATCH_FULL:
! /* Return true if keys are unchanged */
! return ri_KeysUnchanged(fk_rel, old_row, new_row, &riinfo, false);
/* Handle MATCH PARTIAL set null delete. */
case FKCONSTR_MATCH_PARTIAL:
*************** ri_HashPreparedPlan(RI_QueryKey *key, SP
*** 3763,3775 ****
/* ----------
! * ri_KeysEqual -
*
! * Check if all key values in OLD and NEW are equal.
* ----------
*/
static bool
! ri_KeysEqual(Relation rel, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk)
{
TupleDesc tupdesc = RelationGetDescr(rel);
--- 3760,3772 ----
/* ----------
! * ri_KeysUnchanged -
*
! * Check if all key values in OLD and NEW are unchanged.
* ----------
*/
static bool
! ri_KeysUnchanged(Relation rel, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk)
{
TupleDesc tupdesc = RelationGetDescr(rel);
*************** ri_KeysEqual(Relation rel, HeapTuple old
*** 3792,3812 ****
{
Datum oldvalue;
Datum newvalue;
! bool isnull;
!
! /*
! * Get one attribute's oldvalue. If it is NULL - they're not equal.
! */
! oldvalue = SPI_getbinval(oldtup, tupdesc, attnums[i], &isnull);
! if (isnull)
! return false;
/*
! * Get one attribute's newvalue. If it is NULL - they're not equal.
*/
! newvalue = SPI_getbinval(newtup, tupdesc, attnums[i], &isnull);
! if (isnull)
return false;
/*
* Compare them with the appropriate equality operator.
--- 3789,3809 ----
{
Datum oldvalue;
Datum newvalue;
! bool isoldnull;
! bool isnewnull;
/*
! * Get one attribute's oldvalue and newvalue. If they are both NULL,
! * the attribute is unchanged. If only one is NULL, it has changed.
*/
! oldvalue = SPI_getbinval(oldtup, tupdesc, attnums[i], &isoldnull);
! newvalue = SPI_getbinval(newtup, tupdesc, attnums[i], &isnewnull);
! if (isoldnull || isnewnull)
! {
! if (isoldnull && isnewnull)
! continue;
return false;
+ }
/*
* Compare them with the appropriate equality operator.
*************** ri_KeysEqual(Relation rel, HeapTuple old
*** 3821,3833 ****
/* ----------
! * ri_AllKeysUnequal -
*
! * Check if all key values in OLD and NEW are not equal.
* ----------
*/
static bool
! ri_AllKeysUnequal(Relation rel, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk)
{
TupleDesc tupdesc = RelationGetDescr(rel);
--- 3818,3830 ----
/* ----------
! * ri_AllKeysChanged -
*
! * Check if all key values in OLD and NEW are changed.
* ----------
*/
static bool
! ri_AllKeysChanged(Relation rel, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk)
{
TupleDesc tupdesc = RelationGetDescr(rel);
*************** ri_AllKeysUnequal(Relation rel, HeapTupl
*** 3850,3877 ****
{
Datum oldvalue;
Datum newvalue;
! bool isnull;
!
! /*
! * Get one attribute's oldvalue. If it is NULL - they're not equal.
! */
! oldvalue = SPI_getbinval(oldtup, tupdesc, attnums[i], &isnull);
! if (isnull)
! continue;
/*
! * Get one attribute's newvalue. If it is NULL - they're not equal.
*/
! newvalue = SPI_getbinval(newtup, tupdesc, attnums[i], &isnull);
! if (isnull)
continue;
/*
* Compare them with the appropriate equality operator.
*/
if (ri_AttributesEqual(eq_oprs[i], RIAttType(rel, attnums[i]),
oldvalue, newvalue))
! return false; /* found two equal items */
}
return true;
--- 3847,3874 ----
{
Datum oldvalue;
Datum newvalue;
! bool isoldnull;
! bool isnewnull;
/*
! * Get one attribute's oldvalue and newvalue. If they are both NULL,
! * the attribute is unchanged. If only one is NULL, it has changed.
*/
! oldvalue = SPI_getbinval(oldtup, tupdesc, attnums[i], &isoldnull);
! newvalue = SPI_getbinval(newtup, tupdesc, attnums[i], &isnewnull);
! if (isoldnull || isnewnull)
! {
! if (isoldnull && isnewnull)
! return false; /* found two unchanged items */
continue;
+ }
/*
* Compare them with the appropriate equality operator.
*/
if (ri_AttributesEqual(eq_oprs[i], RIAttType(rel, attnums[i]),
oldvalue, newvalue))
! return false; /* found two unchanged items */
}
return true;
*************** ri_AllKeysUnequal(Relation rel, HeapTupl
*** 3879,3895 ****
/* ----------
! * ri_OneKeyEqual -
*
! * Check if one key value in OLD and NEW is equal. Note column is indexed
* from zero.
*
! * ri_KeysEqual could call this but would run a bit slower. For
* now, let's duplicate the code.
* ----------
*/
static bool
! ri_OneKeyEqual(Relation rel, int column, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk)
{
TupleDesc tupdesc = RelationGetDescr(rel);
--- 3876,3892 ----
/* ----------
! * ri_OneKeyUnchanged -
*
! * Check if one key value in OLD and NEW is unchanged. Note column is indexed
* from zero.
*
! * ri_KeysUnchanged could call this but would run a bit slower. For
* now, let's duplicate the code.
* ----------
*/
static bool
! ri_OneKeyUnchanged(Relation rel, int column, HeapTuple oldtup, HeapTuple newtup,
const RI_ConstraintInfo *riinfo, bool rel_is_pk)
{
TupleDesc tupdesc = RelationGetDescr(rel);
*************** ri_OneKeyEqual(Relation rel, int column,
*** 3897,3903 ****
const Oid *eq_oprs;
Datum oldvalue;
Datum newvalue;
! bool isnull;
if (rel_is_pk)
{
--- 3894,3901 ----
const Oid *eq_oprs;
Datum oldvalue;
Datum newvalue;
! bool isoldnull;
! bool isnewnull;
if (rel_is_pk)
{
*************** ri_OneKeyEqual(Relation rel, int column,
*** 3911,3928 ****
}
/*
! * Get one attribute's oldvalue. If it is NULL - they're not equal.
! */
! oldvalue = SPI_getbinval(oldtup, tupdesc, attnums[column], &isnull);
! if (isnull)
! return false;
!
! /*
! * Get one attribute's newvalue. If it is NULL - they're not equal.
*/
! newvalue = SPI_getbinval(newtup, tupdesc, attnums[column], &isnull);
! if (isnull)
return false;
/*
* Compare them with the appropriate equality operator.
--- 3909,3925 ----
}
/*
! * Get one attribute's oldvalue and newvalue. If they are both NULL,
! * the attribute is unchanged. If only one is NULL, it has changed.
*/
! oldvalue = SPI_getbinval(oldtup, tupdesc, attnums[column], &isoldnull);
! newvalue = SPI_getbinval(newtup, tupdesc, attnums[column], &isnewnull);
! if (isoldnull || isnewnull)
! {
! if (isoldnull && isnewnull)
! return true;
return false;
+ }
/*
* Compare them with the appropriate equality operator.