On Wed, Nov 13, 2024 at 11:30 AM jian he <jian.universality@gmail.com> wrote:
>
> These 3 functions will call StoreRelNotNull to store the not-null constraint.
> StoreConstraints
> AddRelationNotNullConstraints
> AddRelationNewConstraints
>
> we can disallow not-null on virtual generated columns via these 3 functions.
> I guess we don't want to add more complexity to AddRelationNotNullConstraints.
> we can do it in StoreRelNotNull.
inspired by not-null and check check_modified_virtual_generated again.
in plpgsql_exec_trigger, we can:
/*
* In BEFORE trigger, stored generated columns are not computed yet,
* so make them null in the NEW row. (Only needed in UPDATE branch;
* in the INSERT case, they are already null, but in UPDATE, the field
* still contains the old value.) Alternatively, we could construct a
* whole new row structure without the generated columns, but this way
* seems more efficient and potentially less confusing.
*/
if (tupdesc->constr && tupdesc->constr->has_generated_stored &&
TRIGGER_FIRED_BEFORE(trigdata->tg_event))
{
for (int i = 0; i < tupdesc->natts; i++)
{
if (TupleDescAttr(tupdesc, i)->attgenerated ==
ATTRIBUTE_GENERATED_STORED ||
TupleDescAttr(tupdesc, i)->attgenerated ==
ATTRIBUTE_GENERATED_VIRTUAL)
expanded_record_set_field_internal(rec_new->erh,
i + 1,
(Datum) 0,
true, /* isnull */
false, false);
}
}
then we don't need check_modified_virtual_generated at all.
this will align with the stored generated column behave for
BEFORE UPDATE/INSERT FOR EACH ROW trigger. that is
you are free to assign the virtual generated column any value,
but at the plpgsql_exec_trigger, we will rewrite it to null.
also i understand correctly.
later if we want to implement virtual generated column with not-null then
check_modified_virtual_generated needs to be removed?