On Wed, Jul 10, 2019 at 11:33 AM Fabien COELHO <coe...@cri.ensmp.fr> wrote:
> > Hello Ibrar, > > >> SELECT 1 AS one \; > >> SELECT 2 AS two UNION SELECT 2 \; > >> SELECT 3 AS three \aset > >> > >> will set both "one" and "three", while "two" is not set because there > were > >> two rows. It is a kind of more permissive \gset. > > > > Are you sure two is not set :)? > > > > SELECT 2 AS two UNION SELECT 2; -- only returns one row. > > but > > SELECT 2 AS two UNION SELECT 10; -- returns the two rows. > > Indeed, my intension was to show an example like the second. > > > Is this the expected behavior with \aset? > > > In my opinion throwing a valid error like "client 0 script 0 command 0 > > query 0: expected one row, got 2" make more sense. > > Hmmm. My intention with \aset is really NOT to throw an error. With > pgbench, the existence of the variable can be tested later to know whether > it was assigned or not, eg: > > SELECT 1 AS x \; > -- 2 rows, no assignment > SELECT 'calvin' AS firstname UNION SELECT 'hobbes' \; > SELECT 2 AS z \aset > -- next test is false > \if :{?firstname} > ... > \endif > > The rational is that one may want to benefit from combined queries (\;) > which result in less communication thus has lower latency, but still be > interested in extracting some results. > > The question is what to do if the query returns 0 or >1 rows. If an error > is raised, the construct cannot be used for testing whether there is one > result or not, eg for a query returning 0 or 1 row, you could not write: > > \set id random(1, :number_of_users) > SELECT firtname AS fn FROM user WHERE id = :id \aset > \if :{?fn} > -- the user exists, proceed with further queries > \else > -- no user, maybe it was removed, it is not an error > \endif > > Another option would to just assign the value so that > - on 0 row no assignment is made, and it can be tested afterwards. > - on >1 rows the last (first?) value is kept. I took last so to > ensure that all results are received. > > I think that having some permissive behavior allows to write some more > interesting test scripts that use combined queries and extract values. > > What do you think? > > Yes, I think that make more sense. > > - With \gset > > > > SELECT 2 AS two UNION SELECT 10 \gset > > INSERT INTO test VALUES(:two,0,0); > > > > client 0 script 0 command 0 query 0: expected one row, got 2 > > Run was aborted; the above results are incomplete. > > Yes, that is the intented behavior. > > > - With \aset > > > > SELECT 2 AS two UNION SELECT 10 \aset > > INSERT INTO test VALUES(:two,0,0); > > [...] > > client 0 script 0 aborted in command 1 query 0: ERROR: syntax error at > or near ":" > > Indeed, the user should test whether the variable was assigned before > using it if the result is not warranted to return one row. > > > The new status of this patch is: Waiting on Author > > The attached patch implements the altered behavior described above. > > -- > Fabien. -- Ibrar Ahmed