2017-01-03 15:40 GMT+01:00 Fabien COELHO <coe...@cri.ensmp.fr>: > > Hello again, > > *** PLEASE, could you remove the parts of emails you are not responding to > when replying in the thread? THANKS. *** > > [...] Did I understand? >>> >> > I guess that the answer is "no":-) > > When you are running under only one transaction, then you don't need to >> solve reset variables on rollback, because you cannot do anything when >> system fails. Only when you are handling a exception, then system continue, >> and you can or you cannot to set the variable. >> > > Sorry, I do not understand these sentences. > > The usual scenario of using secure content is not related to transactions >> - it is related to session. There are two kind of functions >> >> A. slow and expensive that creates secure content/context >> B. other that use secure content/context >> >> When you are running A, then some secure context is initialised or it is >> invalided. When A fails, then B doesn't work. >> > > Yes, I understand that it is the expected property: B must not work if A > has failed... I'm trying to understand what properties are required on the > session variables wrt to how A ran to achieve this. > > When A is successful, then context is valid to another call of A. Next >> call of A set context or invalidate context. The transactions play nothing >> in this game. >> > > Anything in PostgreSQL is always under a transaction... My concern is for > the following: > > -- in a session, there is a transaction > BEGIN; > SELECT A(...); > -- in A: > -- -> check this and that ... > -- -> insert in log ... > -- -> update something else ... > -- -> all seems fine... > -- SET SESSION VARIABLE status_ok = TRUE; > -- -> could do something else... > -- return from A > ROLLBACK; > -- the commit fails, because some differed trigger somewhere is > unhappy > -- or the user changed its mind... > > Now A has failed, but this could not be known from within the function, > and the status_ok is wrong. If the session proceeds with: > > SELECT B(); > > Then B believes that A succeeded, which is not the case.
No, just your design is unhappy SELECT A(..) SET SESSION VARIABLE status_ok = false; -- do all, if fails there, then follow line fails too, or never be executed SET SESSION VARIABLE status_ok = true; or SET SESSION VARIABLE status_ok = true TRY do something CATCH ROLLBACK SET SESSION VARIABLE status_ok = false Both I can do in current PL > > The key issue is that the final status (commit or rollback) of the > containing transaction cannot be known from within the function, so the > session variables cannot reflect this status. > > So somehow the status_ok variable must be (1) rolledback to previous value > or (2) removed (3) set to FALSE or (4) set to NULL. It cannot be TRUE if A > containing transactions has failed for the security as I understand it. > you don't need do rollback variable if you write well A > > Maybe it could work with subtransactions: A calls A', A' succeeds (return, > COMMIT is ok), *then* set user_status = ok. The session variables reflects > that A' succeeded, and if A fails later it is ok because the security is > based on the success of A', not the one of A. However, I'm not sure how > subtransactions can be stated simply and within a session in pg. > > The content of variable (used in PL) is defined by scope - not by >> successful or unsuccessful transactions. The security content will be >> valid >> although user have to do rollback. >> > > I do not understand how the "security context" can be valid of there has > been a rollback which has cancelled all operations: Some log may not have > been written for instance, which would be a key assumption for establishing > the validity of the security context. If you use patterns that I wrote - the security context will be valid always > > > -- > Fabien. >