Discussion:
[NOVICE] "where x between y and z" for timestamp data types
(too old to reply)
M Q
2012-08-12 18:52:22 UTC
Permalink
Hi,

I'm having trouble creating a function with a "where x between y and z" for
timestamp data types.

If I hardcode the values for y and z, my function works fine and returns
quickly (~80ms). If I parameterize y and z (i.e. use $1, $2), then the
function doesn't seem to return (killed query after waiting > 30 seconds)

Example:
I have two tables with timestamp data.

The hardcoded solution looks like this:

CREATE OR REPLACE FUNCTION time_test(IN timestamp without time zone, IN
timestamp without time zone)
RETURNS TABLE(v1 double precision, v2 double precision, ti1 timestamp
without time zone, ti2 timestamp without time zone) AS
$BODY$
BEGIN
RETURN QUERY
SELECT t1.value1, t2.value2, $1, $2
FROM
MyTable1 as t1 inner join MyTable2 as t2 on t1.date = t2.date
WHERE t1.date between '2010-06-01 15:10:20' and '2010-06-01 15:10:20' ;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;

select * from time_test('2010-06-01 15:10:20', '2010-06-01 15:10:20'); /*
arguments here aren't really used internally by where clause */


The paramterized solution looks like this (Same as above but just using $1
and $2 in where clause):

CREATE OR REPLACE FUNCTION time_test(IN timestamp without time zone, IN
timestamp without time zone)
RETURNS TABLE(v1 double precision, v2 double precision, ti1 timestamp
without time zone, ti2 timestamp without time zone) AS
$BODY$
BEGIN
RETURN QUERY
SELECT t1.value1, t2.value2, $1, $2
FROM
MyTable1 as t1 inner join MyTable2 as t2 on t1.date = t2.date
WHERE t1.date between $1 and $2;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;

select * from time_test('2010-06-01 15:10:20', '2010-06-01 15:10:20'); /*
arguments here should produce same result as hardcoded solution */


What am I not understanding?

Any help would be appreciated.

Thanks,
Kaib
Jeff Davis
2012-08-12 21:07:23 UTC
Permalink
Post by M Q
Hi,
I'm having trouble creating a function with a "where x between y and
z" for timestamp data types.
First, I'd like to suggest that you look at Range Types in the 9.2 beta,
which might be applicable to your problem:

http://www.postgresql.org/about/news/1405/
http://www.postgresql.org/docs/9.2/static/rangetypes.html
Post by M Q
If I hardcode the values for y and z, my function works fine and
returns quickly (~80ms). If I parameterize y and z (i.e. use $1, $2),
then the function doesn't seem to return (killed query after waiting >
30 seconds)
I have two tables with timestamp data.
I briefly tried your example and I didn't see a problem. Can you provide
some sample data that illustrates your problem? Also, is the "date"
field a date or a timestamp? And why are the upper and lower bounds of
the BETWEEN identical?

Regards,
Jeff Davis
--
Sent via pgsql-novice mailing list (pgsql-***@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-novice
Tom Lane
2012-08-12 21:28:24 UTC
Permalink
Post by Jeff Davis
I briefly tried your example and I didn't see a problem. Can you provide
some sample data that illustrates your problem? Also, is the "date"
field a date or a timestamp? And why are the upper and lower bounds of
the BETWEEN identical?
I'll bet a nickel the planner is choosing a different plan when it
doesn't know that the timestamp range condition is extremely selective.

regards, tom lane
--
Sent via pgsql-novice mailing list (pgsql-***@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-novice
M Q
2012-08-13 06:27:52 UTC
Permalink
The 'date' field is a timestamp without timezone. The upper and lower
bounds of the BETWEEN are identical just for testing purposes. Any range
would do.

I'm having trouble reproducing the problem on a similar data set. I
created a new db, same table schema, same row count with randomly generated
data for testing but the function works fine. So perhaps my problem is
related to the tables rather than the function. If I can successfully
reproduce the problem with another data set I'll send example code to
share. I'll also look into the links you gave me.

Thanks,
Kaib
Post by Tom Lane
Post by Jeff Davis
I briefly tried your example and I didn't see a problem. Can you provide
some sample data that illustrates your problem? Also, is the "date"
field a date or a timestamp? And why are the upper and lower bounds of
the BETWEEN identical?
I'll bet a nickel the planner is choosing a different plan when it
doesn't know that the timestamp range condition is extremely selective.
regards, tom lane
Loading...