Обсуждение: INTERVAL type: SQL92 implementation

Поиск
Список
Период
Сортировка

INTERVAL type: SQL92 implementation

От
"Oliver Elphick"
Дата:
If full SQL92 implementation of INTERVAL would be a welcome addition,
could it be added as a TODO item?  I would like to work on it, since I
want to use some features that are not currently supported.


SQL92 INTERVAL data type (also SQL99, I think):
 <interval type> ::= INTERVAL {{<start field> TO <end field>} |                              <single datetime field>}
 <start field> ::= <non-second datetime field>                        [(<interval leading field precision>)]
 <end field> ::= <non second datetime field> |                 SECOND [(<fractional seconds precision>)]
 <single datetime field> ::= <non-second datetime field>                                  [(<interval leading field
precision>)]|                             SECOND[(<interval leading field precision>
[,<fractionalseconds precision>])]
 
 <non-second datetime field> ::= YEAR | MONTH | DAY | HOUR | MINUTE
 0 < <interval leading field precision> < implementation defined maximum (default is 2)
 0 <= <fractional seconds precision> < 10 (default is 6)
 INTERVALs may be defined by a range within either YEAR TO MONTH or DAY TO SECOND.


INTERVAL literals are defined as:
 INTERVAL [+|-]'<value string>' <interval qualifier>
 <interval qualifier> ::= <start field> [TO <end field>]

Part of this syntax is supported by the parser, but not consistently.


Valid SQL92 syntax that is not currently supported:
 junk=# SELECT INTERVAL '1990' YEAR(4); ERROR:  parser: parse error at or near "(" junk=# select INTERVAL '1990' YEAR;
ERROR: Bad interval external representation '1990' junk=# SELECT INTERVAL -'1-1' YEAR TO MONTH; ERROR:  parser: parse
errorat or near "YEAR" junk=# SELECT INTERVAL +'100 0:0:0.1' DAY(3) TO SECOND; ERROR:  parser: parse error at or near
"DAY"junk=# SELECT INTERVAL +'100 0:0:0.1' DAY TO SECOND; ERROR:  parser: parse error at or near "DAY" junk=# --
actually,it doesn't like the + junk=# SELECT INTERVAL '0:0:0.0:' HOUR TO SECOND(9); ERROR:  parser: parse error at or
near"(" junk=# SELECT INTERVAL '100000.001' SECOND(6,3); ERROR:  parser: parse error at or near "(" junk=# SELECT
INTERVAL'100000.001' SECOND;           ?column?       -------------------  1 day 03:46:40.00 (1 row)
 
 junk=# -- should output '100000.001' junk=# SELECT INTERVAL -'10' MINUTE; ERROR:  parser: parse error at or near
"MINUTE"junk=# SELECT INTERVAL '1:1' HOUR(6) TO MINUTE; ERROR:  parser: parse error at or near "("
 


Valid interval value format not currently supported:
 year-month


Since there are aspects of SQL92 interval representation that clash
with the current implementation, I would suggest that current
practice be followed unless SQL92 syntax is used.  So a field that
is of type INTERVAL without qualification would continue to work
as it does now (except that I would like to implement range checking).

The main difference would be in the output format.  For a
SQL92-compliant interval column, the output would be the appropriate
parts of either
 year-month

or
 day hour:minute:second.fractional_second

according to the field definition, without any words (i.e.: "1 03:46:40.00"
instead of "1 day 03:46:40.00", and "3-5" instead of "3 years 5 mons").
All parts within the range will be shown, even if they are trailing zeros.

The other difference would be that input values would be range-checked
to see that they didn't exceed the possible range of the type; so
the range of INTERVAL HOUR(3) TO MINUTE would be 0 seconds to
+|-999:59:59.999999 and inserting a value outside the range would be
an error.  Intervals of the current type also need range-checking:

junk=# select interval '199999999 years';        ?column?         
---------------------------157913942 years -4 mons
(1 row)


What do you think?

-- 
Oliver Elphick                                Oliver.Elphick@lfix.co.uk
Isle of Wight                              http://www.lfix.co.uk/oliver
PGP: 1024R/32B8FAA1: 97 EA 1D 47 72 3F 28 47  6B 7E 39 CC 56 E4 C1 47
GPG: 1024D/3E1D0C1C: CA12 09E0 E8D5 8870 5839  932A 614D 4C34 3E1D 0C1C
========================================   "Use hospitality one to another without grudging."
           I Peter 4:9 
 




Re: INTERVAL type: SQL92 implementation

От
Thomas Lockhart
Дата:
> If full SQL92 implementation of INTERVAL would be a welcome addition,
> could it be added as a TODO item?  I would like to work on it, since I
> want to use some features that are not currently supported.
...
> Valid SQL92 syntax that is not currently supported:
...
>   junk=# SELECT INTERVAL '1990' YEAR(4);
...

So far, I've had shift/reduce troubles trying to have a trailing
qualifier field like this.

>   junk=# SELECT INTERVAL -'1-1' YEAR TO MONTH;
>   ERROR:  parser: parse error at or near "YEAR"

A leading sign in front of a string-like field? Yuck.

...
> Valid interval value format not currently supported:
>   year-month

I'll look at accepting this for the current INTERVAL type too.

> Since there are aspects of SQL92 interval representation that clash
> with the current implementation, I would suggest that current
> practice be followed unless SQL92 syntax is used.  So a field that
> is of type INTERVAL without qualification would continue to work
> as it does now (except that I would like to implement range checking).

I like this point. Really, SQL99 intervals are a bit unwieldy, though
they do have "extra features" which someone might find useful.

> The main difference would be in the output format...
> ... parts of either year-month or
> day hour:minute:second.fractional_second

We could probably support this format (now that you have described it to
us) at least for the "SQL" datestyle even for the existing INTERVAL
type.

> according to the field definition, without any words (i.e.: "1 03:46:40.00"
> instead of "1 day 03:46:40.00", and "3-5" instead of "3 years 5 mons").
> All parts within the range will be shown, even if they are trailing zeros.

This set of conventions might let the date/time parser do a complete
job. I put in the "days" text label to reduce the ambiguity of a single,
unlabeled integer.

> What do you think?

Have you gotten started yet? Finished yet?? ;)
                       - Thomas


Re: INTERVAL type: SQL92 implementation

От
Thomas Lockhart
Дата:
(back on list)

> As far as I can see, it is the same.  My examples come from Cannan and Otten
> on SQL92, but I read the spec for SQL99 and I can't see any obvious
> change, except that INTERVAL YEAR TO YEAR (and any other X TO X) is no
> longer allowed.   (I take it you have a copy of SQL99?)

We have a copy of an SQL99 draft which seems to be reasonably complete.
afaik we haven't come across an actual released version. Let me know if
you want me to forward it; perhaps it is on the ftp or web site?

>   >o We need to figure out how to parse it in gram.y. I looked at it a
>   >little bit (a couple of hours?) and it was not obvious how to get rid of
>   >shift/reduce problems.
> I don't have any deep knowledge of yacc/bison...yet.

Oh, you will... ;)

> I feel unhappy about multiplying interval types like that.  I would rather
> restrict it to interval (as now), intervalym (YEAR TO MONTH) and intervalds
> (DAY TO SECOND), with the parameters determining the interval range.

But that means (perhaps?) that you can't define a column INTERVAL DAY,
since internally everything would accept all values DAY TO SECOND. I
know you proposed setting an internal mask, but that would be per-value,
not per-column, so it doesn't help. The attribute system may not be much
help here either, unless we somehow generalize it (to allow types to
keep their own impure storage?).

> otherwise we would have 13 new types and would need to make conversion
> functions for all of them.  SQL99 says that YEAR TO MONTH and DAY TO SECOND
> are incompatible; the results of other combinations give the combined
> maximum range: DAY TO HOUR + HOUR TO SECOND = DAY TO SECOND, but I don't
> see this as being outside the capabilities of the 2 new types I propose.
> Is there some reason in the internals why it would be necessary to create all
> 13 new types?

3 for YEAR/MONTH, and 10 for DAY/HOUR/MIN/SEC to get all the
combinations. If you convert to a "super interval" for internal
operations, then you may only need the I/O and conversion functions,
which would be easy. 

My example still holds as a test case to evaluate an implementation
afaik:
 create table t (id interval day); insert into t(id) select interval '2' day + interval '05' minute;

will need to be stored with only the day field non-zero. Certainly that
column can not be allowed to end up holding quantities other than
integral days, right?

Also, the column defined above has no ability to enforce the "day only"
character of the column if we are using only a single type and without
help from the type or attribute system already in place.

> As I said above, I feel that this is to over-complicate things...

Hmm, but it may be a required minimum level of complication to meet the
spec. Given the arcane syntax and limited functionality (note the
gratuitous editorializing ;) it probably isn't worth doing unless it
gets us on an obvious path to SQL99-compliant functionality.

Also, it is one of the edge cases for SQL99, so even if it is a pain to
do we are only doing it once. They couldn't possibly come up with
anything uglier for SQL0x, could they? Please say no...

...
> the distinction between YEAR TO MONTH and DAY TO SECOND is one that is
> present in the existing interval type, so perhaps we could even get away with
> only one new type?

Not sure what you mean here. The existing type does keep years/months
stored separately from the days/hours/minutes/seconds (a total of two
internal fields) but SQL99 asks that these be kept completely away from
each other from what you've said. Does it define any arithmetic between
the two kinds of intervals?
                   - Thomas


Re: INTERVAL type: SQL92 implementation

От
"Ken Hirsch"
Дата:
Thomas Lockhart <lockhart@fourpalms.org> wrote:
> We have a copy of an SQL99 draft which seems to be reasonably complete.
> afaik we haven't come across an actual released version. Let me know if
> you want me to forward it; perhaps it is on the ftp or web site?

ftp://ftp.postgresql.org/pub/doc/sql/sql1998.tar.gz

Mostly the same files are at
http://gatekeeper.research.compaq.com/pub/standards/sql/
(or ftp).

I didn't know until recently that the ANSI standard was available in PDF
form for an almost reasonable price ($18/part) compared to the outrageous
ISO price ($98 to $275 per part).

See http://webstore.ansi.org/ansidocstore/find.asp?find_spec=sql

[...]
> Not sure what you mean here. The existing type does keep years/months
> stored separately from the days/hours/minutes/seconds (a total of two
> internal fields) but SQL99 asks that these be kept completely away from
> each other from what you've said. Does it define any arithmetic between
> the two kinds of intervals?

No.  Days/hours/minutes/seconds are exact quantities whereas years and
months are not, so they don't mix.






Re: INTERVAL type: SQL92 implementation

От
"Christopher Kings-Lynne"
Дата:
I seem to have the complete released (I think) SQL99 docs.  If anyone wants
them - just reply to me personally.  Should they be put on the postgres
site?  Is that legal?

Chris

> -----Original Message-----
> From: pgsql-hackers-owner@postgresql.org
> [mailto:pgsql-hackers-owner@postgresql.org]On Behalf Of Ken Hirsch
> Sent: Sunday, 2 September 2001 5:18 AM
> To: Hackers List
> Subject: Re: [HACKERS] INTERVAL type: SQL92 implementation
>
>
>
> Thomas Lockhart <lockhart@fourpalms.org> wrote:
> > We have a copy of an SQL99 draft which seems to be reasonably complete.
> > afaik we haven't come across an actual released version. Let me know if
> > you want me to forward it; perhaps it is on the ftp or web site?
>
> ftp://ftp.postgresql.org/pub/doc/sql/sql1998.tar.gz
>
> Mostly the same files are at
> http://gatekeeper.research.compaq.com/pub/standards/sql/
> (or ftp).
>
> I didn't know until recently that the ANSI standard was available in PDF
> form for an almost reasonable price ($18/part) compared to the outrageous
> ISO price ($98 to $275 per part).
>
> See http://webstore.ansi.org/ansidocstore/find.asp?find_spec=sql
>
> [...]
> > Not sure what you mean here. The existing type does keep years/months
> > stored separately from the days/hours/minutes/seconds (a total of two
> > internal fields) but SQL99 asks that these be kept completely away from
> > each other from what you've said. Does it define any arithmetic between
> > the two kinds of intervals?
>
> No.  Days/hours/minutes/seconds are exact quantities whereas years and
> months are not, so they don't mix.
>
>
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly
>



[PATCHES] to_char and Roman Numeral (RN) bug

От
"Command Prompt, Inc."
Дата:
Good day,

Sorry to post to this list about a patch, but I seem to be having some
difficult getting on the pgsql-patches list; keep getting an "illegal
command" when I send it "subscribe", for some reason. At any rate:

In documenting the to_char() function for transformation of numbers to
text, I noticed that the "RN" template character sequence was displaying
some unusual behavior; specifically, unless in fill mode (with the "FM"
sequence), it would either return the result of the last query executed
derived from a to_char() result, or what appears to be a garbage pointer
if there was no such last query.

Example output from PostgreSQL 7.1.3:
-------------------------------------------------------
lx=# SELECT to_char(485, 'RN');    to_char
-----------------UERY :command 1
(1 row)

lx=# SELECT to_char(485, 'FMRN');to_char
---------CDLXXXV
(1 row)

lx=# SELECT to_char(485, 'RN');to_char
---------CDLXXXV
(1 row)

lx=# SELECT to_char(1000, 'RN');to_char
---------CDLXXXV
(1 row)

lx=# SELECT 1, 2, to_char(900, '999');?column? | ?column? | to_char
----------+----------+---------       1 |        2 |  900
(1 row)

lx=# SELECT to_char(485, 'RN');to_char
--------- 900
(1 row)
-------------------------------------------------------

Upon looking into src/backend/utils/adt/formatting.c, I noticed that for
RN transforms:
 strcpy(Np->inout_p, Np->number_p);

was only being called within the IS_FILLMODE if block. Moving it out, and
above that check seems to correct this behavior, and I've attached Patches
for both today's pgsql CVS snapshot and postgresql-7.1.3. Both compile,
but I've only tested the latter since my data path is not setup for
pre-7.2, and it seems like a fairly small change.

I consider myself a competent programmer, but never having hacked on
Postgres, I'm not 100% sure that this modification is totally correct
(e.g., if there are any strange side-effects from doing this?), since I'm
not even sure what the Np pointers are achieving in this instance. ;) I'm
guessing its copying the actual output result into the output value's
char* pointer, as that would explain the garbage pointer if it was never
copied.

Any explanation would be greatly appreciated, as I'd like to document this
apparent bug correctly.


Regards,
Jw.
-- 
jlx@commandprompt.com - John Worsley @ Command Prompt, Inc.
by way of pgsql-hackers@commandprompt.com

Re: [PATCHES] to_char and Roman Numeral (RN) bug

От
Karel Zak
Дата:
On Fri, Aug 31, 2001 at 07:28:50PM -0700, Command Prompt, Inc. wrote:

> In documenting the to_char() function for transformation of numbers to
> text, I noticed that the "RN" template character sequence was displaying
> some unusual behavior; specifically, unless in fill mode (with the "FM"
> sequence), it would either return the result of the last query executed
> derived from a to_char() result, or what appears to be a garbage pointer
> if there was no such last query.
You are right it's bug. For the 'RM' in non-fillmode is to_char() quiet.
I will fix it for 7.2.

> I consider myself a competent programmer, but never having hacked on
> Postgres, I'm not 100% sure that this modification is totally correct
I check it and if it's good solution we use it.
Thanks!
Karel

PS. Bruce, please, can you apply my previous (31 Aug) patch with to_char()   stuff? I want fix this bug in really
actualCVS code. Thanks.
 

-- Karel Zak  <zakkr@zf.jcu.cz>http://home.zf.jcu.cz/~zakkr/C, PostgreSQL, PHP, WWW, http://docs.linux.cz,
http://mape.jcu.cz


Re: [PATCHES] to_char and Roman Numeral (RN) bug

От
Karel Zak
Дата:
On Tue, Sep 04, 2001 at 11:37:48AM -0400, Bruce Momjian wrote:
> > On Fri, Aug 31, 2001 at 07:28:50PM -0700, Command Prompt, Inc. wrote:
> > 
> > > In documenting the to_char() function for transformation of numbers to
> > > text, I noticed that the "RN" template character sequence was displaying
> > > some unusual behavior; specifically, unless in fill mode (with the "FM"
> > > sequence), it would either return the result of the last query executed
> > > derived from a to_char() result, or what appears to be a garbage pointer
> > > if there was no such last query.
> > 
> >  You are right it's bug. For the 'RM' in non-fillmode is to_char() quiet.
> > I will fix it for 7.2.
> 
> Karel, I assume you will send in a patch yourself, right?
Right. It needs check.
Karel

-- Karel Zak  <zakkr@zf.jcu.cz>http://home.zf.jcu.cz/~zakkr/C, PostgreSQL, PHP, WWW, http://docs.linux.cz,
http://mape.jcu.cz


Re: [PATCHES] to_char and Roman Numeral (RN) bug

От
Bruce Momjian
Дата:
> On Fri, Aug 31, 2001 at 07:28:50PM -0700, Command Prompt, Inc. wrote:
> 
> > In documenting the to_char() function for transformation of numbers to
> > text, I noticed that the "RN" template character sequence was displaying
> > some unusual behavior; specifically, unless in fill mode (with the "FM"
> > sequence), it would either return the result of the last query executed
> > derived from a to_char() result, or what appears to be a garbage pointer
> > if there was no such last query.
> 
>  You are right it's bug. For the 'RM' in non-fillmode is to_char() quiet.
> I will fix it for 7.2.

Karel, I assume you will send in a patch yourself, right?

--  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,
Pennsylvania19026
 


Re: [PATCHES] to_char and Roman Numeral (RN) bug

От
Bruce Momjian
Дата:
I have checked this in CVS and it is working fine.  Karel, have you
fixed this?  I can't find a place where I have applied a fix for this.


> Good day,
> 
> Sorry to post to this list about a patch, but I seem to be having some
> difficult getting on the pgsql-patches list; keep getting an "illegal
> command" when I send it "subscribe", for some reason. At any rate:
> 
> In documenting the to_char() function for transformation of numbers to
> text, I noticed that the "RN" template character sequence was displaying
> some unusual behavior; specifically, unless in fill mode (with the "FM"
> sequence), it would either return the result of the last query executed
> derived from a to_char() result, or what appears to be a garbage pointer
> if there was no such last query.
> 
> Example output from PostgreSQL 7.1.3:
> -------------------------------------------------------
> lx=# SELECT to_char(485, 'RN');
>      to_char
> -----------------
>  UERY :command 1
> (1 row)
> 
> lx=# SELECT to_char(485, 'FMRN');
>  to_char
> ---------
>  CDLXXXV
> (1 row)
> 
> lx=# SELECT to_char(485, 'RN');
>  to_char
> ---------
>  CDLXXXV
> (1 row)
> 
> lx=# SELECT to_char(1000, 'RN');
>  to_char
> ---------
>  CDLXXXV
> (1 row)
> 
> lx=# SELECT 1, 2, to_char(900, '999');
>  ?column? | ?column? | to_char
> ----------+----------+---------
>         1 |        2 |  900
> (1 row)
> 
> lx=# SELECT to_char(485, 'RN');
>  to_char
> ---------
>   900
> (1 row)
> -------------------------------------------------------
> 
> Upon looking into src/backend/utils/adt/formatting.c, I noticed that for
> RN transforms:
> 
>   strcpy(Np->inout_p, Np->number_p);
> 
> was only being called within the IS_FILLMODE if block. Moving it out, and
> above that check seems to correct this behavior, and I've attached Patches
> for both today's pgsql CVS snapshot and postgresql-7.1.3. Both compile,
> but I've only tested the latter since my data path is not setup for
> pre-7.2, and it seems like a fairly small change.
> 
> I consider myself a competent programmer, but never having hacked on
> Postgres, I'm not 100% sure that this modification is totally correct
> (e.g., if there are any strange side-effects from doing this?), since I'm
> not even sure what the Np pointers are achieving in this instance. ;) I'm
> guessing its copying the actual output result into the output value's
> char* pointer, as that would explain the garbage pointer if it was never
> copied.
> 
> Any explanation would be greatly appreciated, as I'd like to document this
> apparent bug correctly.
> 
> 
> Regards,
> Jw.
> -- 
> jlx@commandprompt.com - John Worsley @ Command Prompt, Inc.
> by way of pgsql-hackers@commandprompt.com

Content-Description: 

[ Attachment, skipping... ]

Content-Description: 

[ Attachment, skipping... ]

> 
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
> 
> http://www.postgresql.org/users-lounge/docs/faq.html

--  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,
Pennsylvania19026