Обсуждение: Behavior of nextval() and currval()
The following works in 7.1. Is this behavior guaranteed or is it the
subject of possible change in the future? Or am I just "getting
lucky" that nextval() is evaluated before currval():
CREATE SEQUENCE s;
CREATE TABLE test (
key1 int4,
key2 int4
);
INSERT INTO test
SELECT nextval('s'), currval('s');
SELECT * FROM test;
key1 | key2
------+------
1 | 1
Thanks for any information,
Mike Mascari
mascarm@mascari.com
> The following works in 7.1. Is this behavior guaranteed or is it the
> subject of possible change in the future? Or am I just "getting
> lucky" that nextval() is evaluated before currval():
>
> CREATE SEQUENCE s;
>
> CREATE TABLE test (
> key1 int4,
> key2 int4
> );
>
> INSERT INTO test
> SELECT nextval('s'), currval('s');
>
> SELECT * FROM test;
>
> key1 | key2
> ------+------
> 1 | 1
>
> Thanks for any information,
So you are asking if the order of column function evaluations is
reliable. I tend to think so. I think the only thing that could
reorder it is rules.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Mike Mascari <mascarm@mascari.com> writes:
> The following works in 7.1. Is this behavior guaranteed or is it the
> subject of possible change in the future? Or am I just "getting
> lucky" that nextval() is evaluated before currval():
> SELECT nextval('s'), currval('s');
Hmm. SELECT target expressions are indeed evaluated left to right at
present, and I don't see any reason to change that --- but it's not
guaranteed by the spec AFAIK. I think you're right to be wary of
depending on it. Why would you need to do this anyway?
regards, tom lane
Bruce Momjian wrote:
>
> So you are asking if the order of column function evaluations is
> reliable. I tend to think so. I think the only thing that could
> reorder it is rules.
and
Tom Lane wrote:
>
> Mike Mascari <mascarm@mascari.com> writes:
> > The following works in 7.1. Is this behavior guaranteed or is it the
> > subject of possible change in the future? Or am I just "getting
> > lucky" that nextval() is evaluated before currval():
>
> > SELECT nextval('s'), currval('s');
>
> Hmm. SELECT target expressions are indeed evaluated left to right at
> present, and I don't see any reason to change that --- but it's not
> guaranteed by the spec AFAIK. I think you're right to be wary of
> depending on it. Why would you need to do this anyway?
It's an odd scenario, where I need to generate primary keys from an
INSERT..SELECT and the secondary field should match the primary key
in this instance. The secondary field represents a "parent" which
refers to itself if the record is not a child (as opposed to say,
0). I've switched to using a CREATE TEMPORARY TABLE AS SELECT..,
INSERT..SELECT to avoid the scenario.
Thanks,
Mike Mascari
mascarm@mascari.com
>
> regards, tom lane
Mike Mascari <mascarm@mascari.com> writes:
> I've switched to using a CREATE TEMPORARY TABLE AS SELECT..,
> INSERT..SELECT to avoid the scenario.
Uh, you mean something like
select a, a from (select nextval('foo') as a) as b;
That might surprise you even more :-(
Perhaps the planner shouldn't pull up subqueries whose targetlists
include any noncachable functions. This needs more thought.
regards, tom lane
Tom Lane wrote:
>
> Mike Mascari <mascarm@mascari.com> writes:
> > I've switched to using a CREATE TEMPORARY TABLE AS SELECT..,
> > INSERT..SELECT to avoid the scenario.
>
> Uh, you mean something like
>
> select a, a from (select nextval('foo') as a) as b;
I'm not that clever. I just did:
CREATE TEMPORARY TABLE foo AS
SELECT nextval('foo') as a, 0 as b, ...
FROM source;
INSERT INTO bar
SELECT a, a
FROM foo;
instead of:
INSERT INTO bar
SELECT nextval('foo'), currval('foo'), ...
FROM source;
>
> That might surprise you even more :-(
>
You mean:
test=# create table test (key int4 not null);
CREATE
test=# insert into test values (1);
INSERT 803954 1
test=# insert into test values (2);
INSERT 803955 1
test=# select a, a from (select nextval('foo') as a) as b, test;
a | a
---+---
4 | 4
4 | 4 <--- That should be 5?
>
> Perhaps the planner shouldn't pull up subqueries whose targetlists
> include any noncachable functions. This needs more thought.
>
> regards, tom lane
Mike Mascari
mascarm@mascari.com
Hey guys, Hot on the heals of our book (Practical PostgreSQL) being sent to final edit, we have released version 0.8 of our PostgreSQL application server. It is available in the book (on the CD) as well as online at: http://www.commandprompt.com/products_lxp.lxp You can read the documentation here: http://www.postgresql.info/c19970.htm Sincerely, Joshua Drake -- by way of pgsql-general@commandprompt.com http://www.postgresql.info/ http://www.commandprompt.com/
Mike Mascari <mascarm@mascari.com> writes:
> Tom Lane wrote:
>> That might surprise you even more :-(
> You mean:
> test=# create table test (key int4 not null);
> CREATE
> test=# insert into test values (1);
> INSERT 803954 1
> test=# insert into test values (2);
> INSERT 803955 1
> test=# select a, a from (select nextval('foo') as a) as b, test;
> a | a
> ---+---
> 4 | 4
> 4 | 4 <--- That should be 5?
That works okay, but there are variant cases where the planner
will collapse the inner and outer selects, replacing each reference
in the outer select with a copy of the expression from the inner
select. For example,
regression=# select key, a, a from (select key, nextval('foo') as a from test) ss;
key | a | a
-----+---+---
1 | 2 | 3
2 | 4 | 5
(2 rows)
regression=#
This is probably not good when the inner expression contains noncachable
functions ... but I'm hesitant to disable the potential optimization
from collapsing the selects in "harmless" cases such as use of
timestamp-dependent functions. We really need a finer-grain notion
of function cachability...
regards, tom lane