Re: BUG #5448: psql \set does not terminate if variable is referenced recursively

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
Cc: "Francis" <fmarkham(at)gmail(dot)com>, pgsql-bugs(at)postgresql(dot)org, Peter Eisentraut <peter_e(at)gmx(dot)net>
Subject: Re: BUG #5448: psql \set does not terminate if variable is referenced recursively
Date: 2010-05-05 16:20:03
Message-ID: 3573.1273076403@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

"Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
> "Francis" <fmarkham(at)gmail(dot)com> wrote:
>> psql \set does not terminate if a variable is referenced
>> recursively. For example, the following will hang the psql client
>> in a nasty way:
>>
>> db=# \set n 1
>> db=# \set n (:n + 1)

> It seem to me that the above doesn't hang the psql client, but a
> subsequent reference to :n does.

As near as I can tell, it's actually trying to do a recursive expansion
of the variable, which of course doesn't terminate. On my machine it
fails after awhile with

out of dynamic memory in yy_scan_buffer()
xmalloc: out of virtual memory

but you could easily endure a lot of swapping before you get to that,
if your machine isn't carefully configured for amount of swap vs real
RAM vs max allowed process size.

I suppose the only fix is to keep track of which variables are being
actively expanded and refuse to attempt a recursive expansion.
However our options as to what to actually *do* when we detect recursion
are a bit limited. We could print a message and treat the inner
expansion as empty --- is that good enough?

regards, tom lane

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Kevin Grittner 2010-05-05 17:24:36 Re: BUG #5448: psql \set does not terminate if variable is referenced recursively
Previous Message Kevin Grittner 2010-05-05 15:54:25 Re: BUG #5448: psql \set does not terminate if variable is referenced recursively