Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
Database Servers
DB2InformixIngresMS SQLOraclePervasive.SQLPostgreSQLProgressSybase
Desktop Databases
FileMakerFoxProMS AccessParadox
General
General DB TopicsDatabase Theory
Related Topics
Java Development.NET DevelopmentVB DevelopmentMore Topics ...

Database Forum / Informix Topics / March 2008

Tip: Looking for answers? Try searching our database.

Problems storing in a INTERVAL DAY(9) TO DAY field

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Gerardo Santana - 25 Mar 2008 09:16 GMT
Try the following:

create table test(id serial, dd INTERVAL DAY(9) TO DAY);
insert into test values(0, INTERVAL(99) DAY TO DAY);
insert into test values(0, INTERVAL(100) DAY TO DAY); -- this one
gives a syntax error

why can't I store a 3-digit amount of days?, shouldn't I be able to
store a 9-digit amount of days at most?
Art S. Kagel (Oninit) - 25 Mar 2008 12:10 GMT
> Try the following:
>
[quoted text clipped - 6 lines]
> store a 9-digit amount of days at most?
>  

You can store 9 digit days, but your insert statement can only handle 2
digits.  Try:

insert into test values(0, INTERVAL(100) DAY(9) TO DAY);

Art S. Kagel
Oninit

> _______________________________________________
> Informix-list mailing list
> Informix-list@iiug.org
> http://www.iiug.org/mailman/listinfo/informix-list
Gerardo Santana - 25 Mar 2008 19:03 GMT
Art S. Kagel (Oninit) ha escrito:
> > Try the following:
> >
[quoted text clipped - 10 lines]
>
> insert into test values(0, INTERVAL(100) DAY(9) TO DAY);

Thank you Art.

I have another problem with INTERVALs.

I'm programming in ESQL/C and I really need to interpret the
underlying in_dec (dec_t) data that is part of the intrvl_t structure.

In fact, I already did it. I can succesfully interpret YEAR TO MONTH
and DAY TO SECOND values. But I found an edge case that doesn't follow
the manual, as I understood it.

The dec_t structure contains four fields: dec_exp, dec_pos, dec_ndgts
and dec_dgts. dec_pos gives me the sign, dec_exp gives me number of
digit pairs to count from the left to position the decimal point,
dec_ndgts is the number of significant digit pairs and dec_dgts are
the actual digits.

After retrieving a INTERVAL(3700) YEAR(9) TO YEAR value, I invextend()
it to YEAR TO MONTH (for my own purposes)

          invextend(data, &invl);

I do it like this:

           intrvl_t *data, invl;

           data = (intrvl_t *)var->sqldata;
           if (TU_START(data->in_qual) <= TU_MONTH)
               invl.in_qual = TU_IENCODE(9, TU_YEAR, TU_MONTH);
           else
               invl.in_qual = TU_IENCODE(9, TU_DAY, TU_F5);

           invextend(data, &invl);

When interpreting the resulting invl value, I find that exp is 7,
ndgts is 1 and dgts[0] is 37, but I expected ndgts to be 2.

My routine is interpreting then 3700 days incorrectly as 37 days,
because it only gets one pair of digits (ndgts == 1) from dgts.

What am I missing?

For now, I have worked around it memset()'ing invl to zero before
ivextend()'ing and, since I'm always extending to YEAR_TO_MONTH, I can
safely ignore dec_ndgts and interpret dec_dgts as if it always holds
months. In my example above, I would access dec_dgts[1] even though
dec_ndgts is 1, because I'm sure ivextend() worked and have preset
invl to zero.

Thanks in advance.
Jonathan Leffler - 26 Mar 2008 15:12 GMT
On Mar 25, 11:03 am, Gerardo Santana <gerardo.sant...@gmail.com>
wrote:
> Art S. Kagel (Oninit) ha escrito:
>
[quoted text clipped - 63 lines]
>
> Thanks in advance.

All intervals - both in the YEAR-MONTH and the DAY-FRACTION classes
are stored as if there were seconds lurking around.  For example, an
INTERVAL YEAR(9) TO MONTH is stored as if the DECIMAL were:

YYYYYYYYY-MM-00 00:00:00.00000

INTERVAL MONTH(9) TO MONTH: MMMMMMMMM-00 00:00:00.00000
INTERVAL DAY(9) TO SECOND: DDDDDDDDD hh:mm:ss.00000
INTERVAL HOUR(9) TO SECOND: hhhhhhhhh:mm:ss.00000

...you can probably guess the story for minutes and se

And so on.  Of course, the fractional digits I cited are not really
stored, but the decimal point is placed appropriately.

Dig around the IIUG web site - there's code in SQLCMD and there should
be some separate ESQL/C code ivconv.ec to mess around with intervals.

Beware: INTERVAL SECOND(9) TO SECOND can only represent up to about 30
years worth of delta - to cover the entire time span from 0001-01-01
to 9999-12-31, it would need to be an INTERVAL SECOND(12) TO SECOND
(and to measure in minutes, we'd need INTERVAL MINUTE(10) TO SECOND).
Conversely, INTERVAL YEAR(9) TO YEAR can cover geological (but not
cosmological) time periods. The code in ivconv.ec takes this factor
into account.

They're fun - they're confusing - they're DATETIMEs and INTERVALs :-D

-=JL=-
Gerardo Santana - 26 Mar 2008 17:17 GMT
> On Mar 25, 11:03 am, Gerardo Santana <gerardo.sant...@gmail.com>
> wrote:
[quoted text clipped - 96 lines]
>
> -=JL=-

:-) Jonathan, thank you for taking the time to respond.

According to this
http://publib.boulder.ibm.com/infocenter/idshelp/v111/topic/com.ibm.esqlc.doc/es
qlc109.htm


dec_ndgts means the number of _significant_ pairs of digits. But...

an INTERVAL(37) YEAR TO YEAR is stored like this:
ndgts: 1
dgts: 37 26 76 96 00 00 00 06 00

an INTERVAL(3700) YEAR TO YEAR is stored like this:
ndgts: 1
dgts: 37 00 11 96 00 00 00 06

There's a difference is in the dec_exp part of course, that's what I'm
using to work around this problem by the way.

But my point is that I expected that the value of ndgts were 2 instead
of 1 in the case of INTERVAL(3700) YEAR TO YEAR. I understood that I
was supposed to extract ndgts entries from dgts.

Since ndgts is not 2, I get 37 years in both cases.

The workaround is ignoring ndgts and take as much digits as I need,
according to the class of the INTERVAL of course (I'm extending all
INTERVALs to either YEAR(9) TO MONTH or DAY(9) TO SECOND), with the
help of dec_exp.

Then the problem is that after extending the INTERVAL, as you can see
in the first dump, there's "garbage" in the rest of the digits. So I
have to memset first to get this:

ndgts: 1, dgts: 37 00 00 00 00 00 00 00

Then I can extract either 37 or 37 00, depending on dec_exp. No
problem any more.

But...

Shouldn't this be documented?, or, where am I wrong in my
suppositions?

I'm using the following documentation:

http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.sq
lr.doc/sqlrmst141.htm

http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.es
qlc.doc/esqlc123.htm

http://publib.boulder.ibm.com/infocenter/idshelp/v111/index.jsp?topic=/com.ibm.e
sqlc.doc/esqlc109.htm


By the way, I've reported a pair of errors in the documentation but
I'm not sure if it has reached someone because I haven't got any
answer.
Jonathan Leffler - 26 Mar 2008 19:00 GMT
> > On Mar 25, 11:03 am, Gerardo Santana <gerardo.sant...@gmail.com>
> > wrote:
[quoted text clipped - 106 lines]
> ndgts: 1
>  dgts: 37 26 76 96 00 00 00 06 00

One base-100 digit is significant - the 37; the rest are ignored (I'd
prefer that they were zeroed, but that's life).

> an INTERVAL(3700) YEAR TO YEAR is stored like this:
> ndgts: 1
>  dgts: 37 00 11 96 00 00 00 06

Of course; there is one significant centisimal (base-100) digit, the
37.  The exponent is one large than for just 37 years.  If you had
experimented with 370 years, you'd find ndgits = 2, and the values
would be 03 and 70 and the exponent would be the same as for 3700
years.

I've discussed decimal representations before in this news group - and
there's also code in SQLCMD for dumping decimals and intervals
(dumpdec.ec, dumpintvl.ec) and then there's the ivconv.ec code I
mentioned too.

> There's a difference is in the dec_exp part of course, that's what I'm
> using to work around this problem by the way.
>
> But my point is that I expected that the value of ndgts were 2 instead
> of 1 in the case of INTERVAL(3700) YEAR TO YEAR. I understood that I
> was supposed to extract ndgts entries from dgts.

ndgts counts centesimal digits, not decimal digits.  The type is
arguably a misnomer (interestingly, that's the word of the day for one
of the online web sites that does that).  However, although you
specify numbers of decimal digits, the storage uses centesimal digits,
so there's a factor of two difference, give or take the odd one.

> Since ndgts is not 2, I get 37 years in both cases.
>
> The workaround is ignoring ndgts and take as much digits as I need,
> according to the class of the INTERVAL of course (I'm extending all
> INTERVALs to either YEAR(9) TO MONTH or DAY(9) TO SECOND), with the
> help of dec_exp.

That's bad; you'll get junk if you do that.  You have to treat the
value correctly.  For some work I've been doing, I concluded that I
needed to unpack the decimal part of an interval into a fixed format
structure (actually, an array of unsigned bytes) where there was
enough space for any interval (or datetime) value.  The implied
decimal point was in a fixed location.  The only tricky bit is that if
an interval is DAY TO SECOND, then certain bytes contain day values,
but if the interval is HOUR TO SECOND, then some of the 'day' storage
locations contain extra digits of the hour part (for HOUR(4) TO
SECOND, the most significant pair of decimal digits, or single most
significant base-100 digit, occupy the space that would be taken by
the least significant digits of an INTERVAL DAY TO SECOND).  But I
found that easier to manipulate than the floating decimal structure.

> Then the problem is that after extending the INTERVAL, as you can see
> in the first dump, there's "garbage" in the rest of the digits. So I
[quoted text clipped - 9 lines]
> Shouldn't this be documented?, or, where am I wrong in my
> suppositions?

Debatable whether it 'should' be documented.  Nominally, you use the
ESQL/C functions to handle the type.  However, they are not as
complete as you'd like, so you have to delve into the details like
this.

> I'm using the following documentation:

...dropped...

Version 10 - OK; the details haven't changed.

> By the way, I've reported a pair of errors in the documentation but
> I'm not sure if it has reached someone because I haven't got any
> answer.

The docinf@us.ibm.com mail alias has had problems recently -
apparently.
Send the messages to me, please, and I'll forward them to Tech Pubs.

HTH.

-=JL=-
Gerardo Santana - 26 Mar 2008 20:43 GMT
> > According to thishttp://publib.boulder.ibm.com/infocenter/idshelp/v111/topic/com.ibm.e...
>
[quoted text clipped - 6 lines]
> One base-100 digit is significant - the 37; the rest are ignored (I'd
> prefer that they were zeroed, but that's life).

Ouch. I see my mistake now. How embarrassing.

Thanks Jonathan.

> > By the way, I've reported a pair of errors in the documentation but
> > I'm not sure if it has reached someone because I haven't got any
[quoted text clipped - 3 lines]
> apparently.
> Send the messages to me, please, and I'll forward them to Tech Pubs.

Sure.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.