Heikki Linnakangas <heikki.linnakangas@enterprisedb.com> writes:
> The problem is that mod_stmt is determined for the query that has
> canSetTag set, but in case of an INSTEAD OF rule that rewrites the
> statement into a different command, an INSERT into a DELETE in this
> case, canSetTag is not set. The return code of SPI_execute_plan still
> indicates SPI_OK_DELETE, so we have a mismatch in what that assertion is
> trying to check.
> mod_stmt is used to control whether to throw an error if the query
> returns more than one row and there's an INTO, and ISTM the logic is
> correct for that use. However, the logic for when to set FOUND is
> different, so I think the correct fix is to simply remove the assertion.
> At least for back-branches; you could argue for changing the behavior of
> FOUND, but that could break existing applications.
I think the real problem is this bit at the tail end of _SPI_execute_plan:
/* * If none of the queries had canSetTag, we return the last query's result * code, but not its auxiliary
results(for backwards compatibility). */ if (my_res == 0) my_res = res;
This always seemed a bit dubious to me, and in the light of this example
I wonder whether it was even really backwards-compatible. The problem
of course is what to return instead --- it almost seems like we'd have
to invent a new SPI return code "SPI_OK_REWRITTEN" or some such.
In any case, having an INSERT set FOUND on the basis of a rewritten
DELETE seems 100% wrong to me. It won't even be self-consistent because
the actual value of SPI_processed won't be coming from the DELETE.
And what if it's rewritten into a utility statement (eg NOTIFY)?
regards, tom lane