RE: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-10-06 Thread Clark, Chris M

> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> Sent: Thu 10/6/2005 10:14 AM
> Subject:  Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2
> <[EMAIL PROTECTED]> wrote:
> > Richard, I like to ask you, just to make sure; has the `order by` 
> > "bug"/issue, as result from automatic float->int conversion, been 
> > considered by you and if yes, do you plan any changes?
> > 
>
>
> You have a simple workaround:  Just add 0.0 to anything
> that you definitely want to be floating point.
>
> I will continue to trying to figure out a reasonable method
> of addressing your concerns.

In other databases the behavior in sqlite is the expected behavior. E.g. IBM 
db2udb, Ingres, Microsoft SQL Server. Oracle is different because of the wierd 
NUMBER datatype which is used to store both ints and decimal - I don't know 
about any others.

In most databases the datatypes of the operands dictate the result type; which  
is the sqlite behavior.

Chris




Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-10-06 Thread drh
=?ISO-8859-1?Q?Ren=E9_Tegel?= <[EMAIL PROTECTED]> wrote:
> Hi,
> 
> Richard, I like to ask you, just to make sure; has the `order by` 
> "bug"/issue, as result from automatic float->int conversion, been 
> considered by you and if yes, do you plan any changes?
> 

I have made note of the issues raised. I do not have a
solution to the problem at this point. (The various solutions
proposed on this mailing list are all unacceptable for
various reasons.)

You have a simple workaround:  Just add 0.0 to anything
that you definitely want to be floating point.

I will continue to trying to figure out a reasonable method
of addressing your concerns.

--
D. Richard Hipp <[EMAIL PROTECTED]>



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-10-06 Thread René Tegel

Hi,

Richard, I like to ask you, just to make sure; has the `order by` 
"bug"/issue, as result from automatic float->int conversion, been 
considered by you and if yes, do you plan any changes?


regards,

rene

Ralf Junker wrote:

Hello René Tegel,



May i add to that that 'order by' also seems involved, see below. This can lead to really 
unexpected errors... "order by 1.0 * b / c" as workaround solves it btw.



Thanks for pointing this out.

I am sure we will be able to come up with even more examples where the 
confusion of INTEGER / REAL numbers leads to unexpected errors.



Differating between floating point operator '/' and integer operator 'DIV' like 
some program languages do would lead to predictable output.



Surely one possible solutions, but it very likely does not conform to the SQL 
standard (but I haven't checked). On the other hand, the sqlite3 column 
affinity does not result in standard output either for the examples given in 
this thread.

Is there any chance that the problem will be addressed in the forseable future? 
Do we need to create a ticket to put it on the agenda?

Regards,

Ralf 





Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-10-04 Thread Ralf Junker
Hello René Tegel,

>May i add to that that 'order by' also seems involved, see below. This can 
>lead to really unexpected errors... "order by 1.0 * b / c" as workaround 
>solves it btw.

Thanks for pointing this out.

I am sure we will be able to come up with even more examples where the 
confusion of INTEGER / REAL numbers leads to unexpected errors.

>Differating between floating point operator '/' and integer operator 'DIV' 
>like some program languages do would lead to predictable output.

Surely one possible solutions, but it very likely does not conform to the SQL 
standard (but I haven't checked). On the other hand, the sqlite3 column 
affinity does not result in standard output either for the examples given in 
this thread.

Is there any chance that the problem will be addressed in the forseable future? 
Do we need to create a ticket to put it on the agenda?

Regards,

Ralf 



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-10-03 Thread René Tegel

Hi,

May i add to that that 'order by' also seems involved, see below. This 
can lead to really unexpected errors... "order by 1.0 * b / c" as 
workaround solves it btw.
Differating between floating point operator '/' and integer operator 
'DIV' like some program languages do would lead to predictable output.


regards,

rene

===
#select *, b/c, 1.0 * b/c from test2 order by b/c
a   b   c   b/c 1.0 * b/c
1   3   4   0   0.75
2   5   6   0   0.833
5   6   7   0   0.857142857142857
6   6   8   0   0.75
7   7   8   0   0.875
3   7   6   1   1.17
4   6   6   1   1.0
8   8   8   1   1.0
9   9   8   1   1.125
10  10  8   1   1.25
11  9   8   1   1.125
12  8   8   1   1.0
13  11  8   1   1.375
14  13  8   1   1.625
15  12  8   1   1.5

#select *, b/c, 1.0 * b/c from test2 order by 1.0*b/c
a   b   c   b/c 1.0 * b/c
1   3   4   0   0.75
6   6   8   0   0.75
2   5   6   0   0.833
5   6   7   0   0.857142857142857
7   7   8   0   0.875
4   6   6   1   1.0
8   8   8   1   1.0
12  8   8   1   1.0
9   9   8   1   1.125
11  9   8   1   1.125
3   7   6   1   1.17
10  10  8   1   1.25
13  11  8   1   1.375
15  12  8   1   1.5
14  13  8   1   1.625




Ralf Junker wrote:

Hello DRH,


3. If the division of INTEGERs can not be stored as an INTEGER 
(i.e. if a % b != 0), the result should be returned as a REAL.




create table t1( a integer, b integer);
insert into t1 values(5,2);
update t1 set a=a/b;

If your rule above was in force, this would leave
T1.A holding 2.5, which is incompatible with the 
way other database engines work.



Well, understandable. But suppose that's exactly what one wants to do? How to 
achieve this using the current implementation of sqlite3?

On the other hand, I think that the following, currently implemented behaviour 
of sqlite3 is also incompatible with the way other database engines work. Where 
they return 2.5 for real type columns, sqlite3 does not:

  create table t1 (a real, b real);
  insert into t1 values (5,2);
  select a / b from t1;
  2

So the final question biols down to: How can I reliably guarantee a real type 
result for divisions on real typed columns even if they happen to contain 
integers? I cant't believe I always have to use a workaround like this:

  select 1.0 * a / b from t1; 


I am sure there must be a better possibility without the extra multiplication! 
Or is there not?

Regards,

Ralf  





RE: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-10-03 Thread Jackson, Douglas H
Perhaps not a solution, but a workaround:
Try coercing the data entering the table into
a value recognizable as a real:

Create trigger t_t1i after insert on t1
Begin
  Update t1 set a = 1.0 * a, b = 1.0 * b
  Where rowid = new.rowid;
End;

Create trigger t_t1u after update on t1
Begin
   Update t1 set a = 1.0 * a, b = 1.0 * b
   Where rowid = new.rowid;
End;

The table will then hold reals in all cases.

Expressions then work without change:
  Select a/b from t1;
  Update a set a = a / b;

Doug

-Original Message-
From: Ralf Junker [mailto:[EMAIL PROTECTED] 
Sent: Monday, October 03, 2005 7:12 AM
To: sqlite-users@sqlite.org
Subject: Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

Hello DRH,

>> 3. If the division of INTEGERs can not be stored as an INTEGER 
>>(i.e. if a % b != 0), the result should be returned as a REAL.
>> 
>
>create table t1( a integer, b integer);
>insert into t1 values(5,2);
>update t1 set a=a/b;
>
>If your rule above was in force, this would leave
>T1.A holding 2.5, which is incompatible with the 
>way other database engines work.

Well, understandable. But suppose that's exactly what one wants to do?
How to achieve this using the current implementation of sqlite3?

On the other hand, I think that the following, currently implemented
behaviour of sqlite3 is also incompatible with the way other database
engines work. Where they return 2.5 for real type columns, sqlite3 does
not:

  create table t1 (a real, b real);
  insert into t1 values (5,2);
  select a / b from t1;
  2

So the final question biols down to: How can I reliably guarantee a real
type result for divisions on real typed columns even if they happen to
contain integers? I cant't believe I always have to use a workaround
like this:

  select 1.0 * a / b from t1; 

I am sure there must be a better possibility without the extra
multiplication! Or is there not?

Regards,

Ralf  



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-10-03 Thread Ralf Junker
Hello DRH,

>> 3. If the division of INTEGERs can not be stored as an INTEGER 
>>(i.e. if a % b != 0), the result should be returned as a REAL.
>> 
>
>create table t1( a integer, b integer);
>insert into t1 values(5,2);
>update t1 set a=a/b;
>
>If your rule above was in force, this would leave
>T1.A holding 2.5, which is incompatible with the 
>way other database engines work.

Well, understandable. But suppose that's exactly what one wants to do? How to 
achieve this using the current implementation of sqlite3?

On the other hand, I think that the following, currently implemented behaviour 
of sqlite3 is also incompatible with the way other database engines work. Where 
they return 2.5 for real type columns, sqlite3 does not:

  create table t1 (a real, b real);
  insert into t1 values (5,2);
  select a / b from t1;
  2

So the final question biols down to: How can I reliably guarantee a real type 
result for divisions on real typed columns even if they happen to contain 
integers? I cant't believe I always have to use a workaround like this:

  select 1.0 * a / b from t1; 

I am sure there must be a better possibility without the extra multiplication! 
Or is there not?

Regards,

Ralf  



RE: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-30 Thread Fred Williams
Anybody thought of:

t1.a = 5
t1.b = 2

select a / (b * 1.0);

I think that would return a real.

-Original Message-
From: Dennis Cote [mailto:[EMAIL PROTECTED]
Sent: Friday, September 30, 2005 11:10 AM
To: sqlite-users@sqlite.org
Subject: Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?


Ralf Junker wrote:

>>This can be fixed by checking the column affinity for a value when it
is stored. If an integer value is being stored in a column with numeric
affinity, then store the value as a REAL value

...




Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-30 Thread Dennis Cote

Ralf Junker wrote:


This can be fixed by checking the column affinity for a value when it is 
stored. If an integer value is being stored in a column with numeric affinity, 
then store the value as a REAL value rather than as an INTEGER value. This will 
perform the same conversion that the other engines do, and hence produce the 
same result when the division operation is performed later.
   



Unfortunately, this is not true for SQLite3. If you execute the following SQL 
commands

 CREATE TABLE t (a REAL, b REAL);
 INSERT INTO t VALUES (5, 2);

both values are stored as INTEGER and not as REAL as one would expect by the 
column affinity. In fact, this behaviour is intentional and is stated in the 
help as a feature to minimize storage space for INTEGER numbers.

 

I'm sorry I took so long to get back to, I started this reply last 
night, but had to leave it unfinished until now.


To clarify what I said above (since it obviously wasn't clear).

The first thing to note is that SQLite applies a data type to individual 
values, and data type affinities to table columns. These are different 
things.


I meant that your division problem can be fixed in SQLite if SQLite is 
modified so that it checks the affinity of the column before storing the 
integer value. In SQLite a column declared as REAL has an affinity of 
NUMERIC (see http://www.sqlite.org/datatype3.html section 2.1). The 
problem is that currently columns with NUMERIC affinity can store values 
of any type, in particular it can store both INTEGER and REAL (see 
section 1 of the data types documentation). The required change would be 
to modify SQLite so that it would convert INTEGER values to REAL values 
when they are stored in a column with NUMERIC affinity.


This would make your division work as expected. The integer value 
supplied to the insert statement would be converted to real and stored 
as real in the table. When the select statement later retrieves the 
values to do the division, it will have real values and do floating 
point path to produce a real result.


It has some side effects that others may not like however. Storing a 
value of 5 into the table would return a value of 5.0 when selected, 
since SQLite (at least the newest versions) formats REAL values with a 
decimal point on output. It would also make the database files larger if 
they were storing integer values in a typeless column or one with a type 
that produced NUMERIC affinity (again see the data types doc for the 
rules).


If a user really wants to force values to be stored and returned as 
integers they would simply need to explicitly declare the columns to 
have an INT type, so they would be assigned an INTEGER affinity. Then no 
conversion would be done when the values are stored. To me this seems 
like an optimization for both speed and space that the user can trigger 
by explicitly specifying the column's data type.



To force storing numbers as REALs SQLite3 requires to use data binding or to 
rewrite the 2nd command above like this:

 INSERT INTO t VALUES (5.0, 2.0);

In other words, SQLite3 requires REALs to be explicitly written as such. Many users are certainly not aware of this requirement. They expect REALs to be stored as REALs just like other DB-engines do if a column is defined as such. However, SQLite3 behaves differently and this can 


* result in wrong calculations / different than intended.
* lead to data errors when importing SQL scripts from other DBMS.

On the other INTEGER side, SQLite3 again behaves differently:

 CREATE TABLE i (a INTEGER, b INTEGER);
 INSERT INTO i VALUES (5, 2);
 INSERT INTO i VALUES (5.0, 2.0);

Both INSERTs above store the numbers as INTEGERs, even those explicitly marked 
as REALs by adding the '.0' decimal.

 

This behavior is also documented on the data type page. If the REAL 
value can be represented exactly as an INTEGER, an INTEGER is stored in 
columns declared to be of type INT. If not, the REAL value is stored. 
This seems reasonable to me. It is in some ways the complement to the 
change I proposed above.


If you do this in a standard SQL engine it will silently convert the 5.0 
value to an exact value with implementation defined precision. Usually 
not a problem for 5.0, but I suspect that 5.1 will probably come out of 
the INTEGER column with the same value as 5.0 does. In SQLite, it will 
store the 5.1 value as a REAL value even though it is in a column with 
INTEGER affinity.



Another problem shows when calculations are not performed on colums with type 
affinity but just on plain numbers like in

 SELECT 5 / 2;

What exactly is intended? From the findings above, both numbers might be seen 
as INTEGERs, but if '5.0' is interpreted as an INTEGER above, '5' might just as 
well be a REAL.

Arguing from "common sense" I would prefer 5 / 2 to return 2.5 rather than 2. 
If the result cannot be represented with exact numeric, I would rather want it to be 
aproximate only. I can not overcome the feeling 

Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-30 Thread Jay Sprenkle
On 9/30/05, Ralf Junker <[EMAIL PROTECTED]> wrote:
>
> Quite right, but even with explicit typing there are cases where SQLite3
> can not be instructed to store REAL numbers as REALs:
>
> C:\>sqlite3 num.db3
> SQLite version 3.2.1
> Enter ".help" for instructions
> sqlite> CREATE TABLE i (a INTEGER, b INTEGER);
> sqlite> INSERT INTO i VALUES (5, 2);
> sqlite> SELECT a / b FROM i;
> 2
> sqlite> INSERT INTO i VALUES (5.0, 2.0);
> sqlite> SELECT a / b FROM i;
> 2
> 2
>
> Even though the 2nd insert explicitly types 5.0 and 2.0 as REALs, they are
> stored as INTEGERs internally and resuls in incorrect calculations (the very
> last number should be 2.5 and not 2).


In that case it did what it was instructed to do. The type was integer
so it converted.



Summming up: Observations show that SQLite3 behaves inconsistent when
> storing and/or calculating numbers as INTEGERs or REALs. The point I am
> personally worried about is not so much the storage side of things but the
> calculation errors resulting from it.


Since it behaves in predictable ways I don't believe inconsistency is
a big problem. Inconsistency is the only constant I've found in life!
It's only inconsistent on one operation, storing integers in a real
type. If you code with a rule of thumb to always insert
with something like "insert into t values( round(x) );" then you
will have no problems.


I would like to propose the resolve this inconsistency as follows:
>
>
That would make sqlite math inconsistent with math as performed
by computer languages. I don't see that as an improvement.


---
The Castles of Dereth Calendar: a tour of the art and architecture of
Asheron's Call
http://www.lulu.com/content/77264


Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-30 Thread Gerry Snyder

Ralf Junker wrote:



Summming up: Observations show that SQLite3 behaves inconsistent when storing 
and/or calculating numbers as INTEGERs or REALs. The point I am personally 
worried about is not so much the storage side of things but the calculation 
errors resulting from it.

I would like to propose the resolve this inconsistency as follows:



3. If the division of INTEGERs can not be stored as an INTEGER (i.e. if a % b 
!= 0), the result should be returned as a REAL.



But this would break much, much code that expects integers to be treated 
as integers. This can't be right. Implementation would require, for 
every integer calculation, conversion to REAL, performing the 
calculation, and checking whether the result is an integer (within some 
tolerence). This suggestion won't float.


Gerry
--
--
Gerry Snyder
American Iris Society Director, Symposium Chair
in warm, winterless Los Angeles -- USDA zone 9b, Sunset 18-19



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-30 Thread drh
Ralf Junker <[EMAIL PROTECTED]> wrote:
> 
> 3. If the division of INTEGERs can not be stored as an INTEGER 
>(i.e. if a % b != 0), the result should be returned as a REAL.
> 

create table t1( a integer, b integer);
insert into t1 values(5,2);
update t1 set a=a/b;

If your rule above was in force, this would leave
T1.A holding 2.5, which is incompatible with the 
way other database engines work.
--
D. Richard Hipp <[EMAIL PROTECTED]>



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-30 Thread Ralf Junker
Hello Jay Sprenkle,

>I guess if you're going to use sqlite you're going to have to
>force typing explicitly if you're doing math with the sql engine. 

Quite right, but even with explicit typing there are cases where SQLite3 can 
not be instructed to store REAL numbers as REALs:

  C:\>sqlite3 num.db3
  SQLite version 3.2.1
  Enter ".help" for instructions
  sqlite> CREATE TABLE i (a INTEGER, b INTEGER);
  sqlite> INSERT INTO i VALUES (5, 2);
  sqlite> SELECT a / b FROM i;
  2
  sqlite> INSERT INTO i VALUES (5.0, 2.0);
  sqlite> SELECT a / b FROM i;
  2
  2

Even though the 2nd insert explicitly types 5.0 and 2.0 as REALs, they are 
stored as INTEGERs internally and resuls in incorrect calculations (the very 
last number should be 2.5 and not 2).

Summming up: Observations show that SQLite3 behaves inconsistent when storing 
and/or calculating numbers as INTEGERs or REALs. The point I am personally 
worried about is not so much the storage side of things but the calculation 
errors resulting from it.

I would like to propose the resolve this inconsistency as follows:

1. If two REALs are divided, the result should be a REAL. This is the current 
behaviour of SQLite3.

2. If two INTEGERs are divided, the result should be INTEGER only if it can be 
represented as an INTEGER (i.e. if a % b = 0).

3. If the division of INTEGERs can not be stored as an INTEGER (i.e. if a % b 
!= 0), the result should be returned as a REAL.

I do understand that 3. implies a change in numeric type, but in oder to 
perform calculations with SQL the type change seems unavoidable, at least as 
long as SQLite3 implements only 2 of the 3 numeric types suggested in this 
thread.

Regards,

Ralf 



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-30 Thread Ralf Junker
The following table sums up the division findings from other SQL engines:

   |SELECT 5 / 2 | SELECT 5.0 / 2 | SELECT 5 / 2.0 | SELECT 5.0 / 2.0
--
SQLite3| 2   | 2.5| 2.5| 2.5 
PostgreSQL | 2   | 2.5000 | 2.5000 |
SQL*Plus   | 2.5 |||
MySql  | 2.50|||

The implementation seems undecided, but I see that the "big players" Oracle 
SQL*Plus and MySql both do not strip off the decimal digits.

Thanks to all who run some tests and provided the results. Feel free to add 
other engines or fill in the gaps.

Regards,

Ralf 



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-29 Thread Clark Christensen
SQL*Plus: Release 8.1.7.0.0 - Production on Thu Sep 29 16:03:55 2005
 
 (c) Copyright 2000 Oracle Corporation.  All rights reserved.
 
 
 Connected to:
 Oracle8i Enterprise Edition Release 8.1.6.0.0 - Production
 With the Partitioning option
 JServer Release 8.1.6.0.0 - Production
 
 SQL> select 5/2 from dual;
 
5/2
 --
2.5
 
 SQL>

- Original Message 
From: Dennis Jenkins <[EMAIL PROTECTED]>
To: sqlite-users@sqlite.org
Sent: Thursday, September 29, 2005 13:14:48
Subject: Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?


>Just out of curiosity: Maybe someone can report the result of 'SELECT 5 / 2;' 
>on MySql, SQLServer, and others?
>
>  
>
devl=# SELECT 5 / 2;
 ?column?
--
2
(1 row)

devl=# select 5.0 / 2;
  ?column?

 2.5000
(1 row)

devl=# select 5 / 2.0;
  ?column?

 2.5000
(1 row)

devl=# select version();
version

 PostgreSQL 8.0.3 on i386-portbld-freebsd5.4, compiled by GCC cc (GCC) 
3.4.2 [FreeBSD] 20040728
(1 row)






Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-29 Thread Alexander J. Kozlovsky

> Unfortunately, this is not true for SQLite3. If you execute the following SQL 
> commands
> 
>   CREATE TABLE t (a REAL, b REAL);
>   INSERT INTO t VALUES (5, 2);
>
> both values are stored as INTEGER and not as REAL as one would expect
> by the column affinity. In fact, this behaviour is intentional and is
> stated in the help as a feature to minimize storage space for INTEGER
> numbers.

I think, it can be fixed by introducing special internal data type:
REAL_STORED_AS_INTEGER

If table column have REAL type, but inserted value is INTEGER, then
inserted type becomes REAL_STORED_AS_INTEGER and binary representation
keep small. When column value is extracted from SQLite or used in
SQL expression, then value dynamically converted to REAL.

That is, the user of database never see values of this type directly.
Such values stored as INTEGER, but can be seen only as REAL.


Best regards,
 Alexandermailto:[EMAIL PROTECTED]



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-29 Thread Jay Sprenkle
On 9/29/05, Ralf Junker <[EMAIL PROTECTED]> wrote:
>
> Unfortunately, this is not true for SQLite3. If you execute the following
> SQL commands
>
> CREATE TABLE t (a REAL, b REAL);
> INSERT INTO t VALUES (5, 2);
>
> both values are stored as INTEGER and not as REAL as one would expect by
> the column affinity. In fact, this behaviour is intentional and is stated in
> the help as a feature to minimize storage space for INTEGER numbers.
>

D:\temp\convention>sqlite3 num.db
SQLite version 3.0.8
Enter ".help" for instructions
sqlite> CREATE TABLE t (a REAL, b REAL);
sqlite> INSERT INTO t VALUES (5, 2);
sqlite> select a/b from t;
2
sqlite> insert into t values(5.0,2);
sqlite> select a/b from t;
2
2.5
sqlite>

I guess if you're going to use sqlite you're going to have to
force typing explicitly if you're doing math with the sql engine.


Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-29 Thread Jay Sprenkle
On 9/29/05, Ralf Junker <[EMAIL PROTECTED]> wrote:
>
> Another problem shows when calculations are not performed on colums with
> type affinity but just on plain numbers like in
>
> SELECT 5 / 2;
>
> What exactly is intended? From the findings above, both numbers might be
> seen as INTEGERs, but if '5.0' is interpreted as an INTEGER above, '5'
> might just as well be a REAL.
>

As per almost every interpreted language standard

5 is an integer.

5.0 is a float.

As you proved with your own example 5.0 is not interpreted as an integer.


Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-29 Thread Lawrence Chitty

Ralf Junker wrote:


In risk of asking the obvious, I wonder if the following division should be 
considered correct:

 | Query | Result Value | Result Type| OK?
---
1 | SELECT 5 / 2; | 2| SQLITE_INTEGER | No?
 

I am following the rest of this thread, but just wanted to add that the 
following may be useful as a workaround for your situation.


SELECT  ROUND(5) / 2
2.5

Regards

Lawrence


Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-29 Thread Dennis Jenkins



Just out of curiosity: Maybe someone can report the result of 'SELECT 5 / 2;' 
on MySql, SQLServer, and others?

 


devl=# SELECT 5 / 2;
?column?
--
   2
(1 row)

devl=# select 5.0 / 2;
 ?column?

2.5000
(1 row)

devl=# select 5 / 2.0;
 ?column?

2.5000
(1 row)

devl=# select version();
   version

PostgreSQL 8.0.3 on i386-portbld-freebsd5.4, compiled by GCC cc (GCC) 
3.4.2 [FreeBSD] 20040728

(1 row)



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-29 Thread Ralf Junker
Hello Dennis & Jay,

thanks for your detailed answers. I do understand your arguments and they make 
good sense for typed DB engines, but for the case of SQLite3 I dare to differ.

>This can be fixed by checking the column affinity for a value when it is 
>stored. If an integer value is being stored in a column with numeric affinity, 
>then store the value as a REAL value rather than as an INTEGER value. This 
>will perform the same conversion that the other engines do, and hence produce 
>the same result when the division operation is performed later.

Unfortunately, this is not true for SQLite3. If you execute the following SQL 
commands

  CREATE TABLE t (a REAL, b REAL);
  INSERT INTO t VALUES (5, 2);

both values are stored as INTEGER and not as REAL as one would expect by the 
column affinity. In fact, this behaviour is intentional and is stated in the 
help as a feature to minimize storage space for INTEGER numbers.

To force storing numbers as REALs SQLite3 requires to use data binding or to 
rewrite the 2nd command above like this:

  INSERT INTO t VALUES (5.0, 2.0);

In other words, SQLite3 requires REALs to be explicitly written as such. Many 
users are certainly not aware of this requirement. They expect REALs to be 
stored as REALs just like other DB-engines do if a column is defined as such. 
However, SQLite3 behaves differently and this can 

 * result in wrong calculations / different than intended.
 * lead to data errors when importing SQL scripts from other DBMS.

On the other INTEGER side, SQLite3 again behaves differently:

  CREATE TABLE i (a INTEGER, b INTEGER);
  INSERT INTO i VALUES (5, 2);
  INSERT INTO i VALUES (5.0, 2.0);

Both INSERTs above store the numbers as INTEGERs, even those explicitly marked 
as REALs by adding the '.0' decimal.

Another problem shows when calculations are not performed on colums with type 
affinity but just on plain numbers like in

  SELECT 5 / 2;

What exactly is intended? From the findings above, both numbers might be seen 
as INTEGERs, but if '5.0' is interpreted as an INTEGER above, '5' might just as 
well be a REAL.

Arguing from "common sense" I would prefer 5 / 2 to return 2.5 rather than 2. 
If the result cannot be represented with exact numeric, I would rather want it 
to be aproximate only. I can not overcome the feeling that exact numeric is 
sometimes simply wrong, especially with the whole family of financial 
calculations.

Just out of curiosity: Maybe someone can report the result of 'SELECT 5 / 2;' 
on MySql, SQLServer, and others?

Regards,

Ralf 



Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-29 Thread Dennis Cote

Ralf Junker wrote:


In risk of asking the obvious, I wonder if the following division should be 
considered correct:

 | Query | Result Value | Result Type| OK?
---
1 | SELECT 5 / 2; | 2| SQLITE_INTEGER | No?
2 | SELECT 5.0 / 2;   | 2.5  | SQLITE_FLOAT   | Yes
3 | SELECT 5 / 2.0;   | 2.5  | SQLITE_FLOAT   | Yes
4 | SELECT 5.0 / 2.0; | 2.5  | SQLITE_FLOAT   | Yes

The query in question is Query 1. Is the returned integer result correct or 
should it not better return the 2.5 float value instead?

I understand that this probably boils down to integer arithmetics, but the 
decimals dropping can cause severe rounding errors if SQLite stores an integer 
number without further warning like in:

 CREATE TABLE t (a REAL, b REAL);
 INSERT INTO t VALUES (5, 2);

Then the query

 SELECT a / b FROM t;

returns wrong results, even though both colums are declared as REAL.

In my opinion, any division which can not be represented as an integer should 
return a float value.

What do you think?

Regards,

Ralf


 


Ralf,

The following is from section 6.26  of the 
SQL:1999 standard.


1) If the declared type of both operands of a dyadic arithmetic operator 
is exact numeric, then the
declared type of the result is exact numeric, with precision and scale 
determined as follows:

a) Let S1 and S2 be the scale of the first and second operands respectively.
b) The precision of the result of addition and subtraction is 
implementation-defined, and the

scale is the maximum of S1 and S2.
c) The precision of the result of multiplication is 
implementation-defined, and the scale is S1+

S2.
d) The precision and scale of the result of division is 
implementation-defined.
2) If the declared type of either operand of a dyadic arithmetic 
operator is approximate numeric,
then the declared type of the result is approximate numeric. The 
precision of the result is

implementation-defined.

As you can see, the result of exact (integer) division is also exact 
(integer) with implementation defined precision and scale.  The result 
of an expression containing approximate (floating point) values is 
approximate (floating point). So SQLite is conforming to the SQL standard.


The problem is that in SQLite, individual rows can store a column value 
using a data type that is different than the column was declared to 
hold. Expressions using these values will then be done using different 
math (i.e. integer vs float) for some rows.


This exposes a difference between SQLite and other database engines with 
strict data typing. I suspect that your example will behave differently 
on mySQL, Oracle, et. al. than it does on SQLite. With strict typing 
these engines will always store the values using the declared type and 
always use the type of math associated with the declared types. 
Effectively 5 and 2 are converted to 5.0 and 2.0 when they are stored 
into the row. So the same operation is performed for all rows. This 
isn't true for SQLite.


This can be fixed by checking the column affinity for a value when it is 
stored. If an integer value is being stored in a column with numeric 
affinity, then store the value as a REAL value rather than as an INTEGER 
value. This will perform the same conversion that the other engines do, 
and hence produce the same result when the division operation is 
performed later.


Note, this change will have the side effect of making database files 
slightly larger, and may slow down operations with untyped columns 
because they default to numeric affinity. All integer values stored in 
these columns will be converted to REAL values and all math will be done 
with floating point (which may require library calls for some embedded 
applications without an FPU). However all this can be avoided by simply 
declaring these column to be integer typed. This will set the affinity 
correctly, so no conversions are done. It probably makes sense to 
declare the type of columns explicitly for increased performance (much 
like the integer primary key declaration) as long as the untyped version 
still produces the correct results.


Dennis Cote


Re: [sqlite] Problem/Bug: "SELECT 5 / 2;" returns 2 ?

2005-09-29 Thread Jay Sprenkle
In the C language, which sqlite is written in, performs math this way:
If mixing types the operands are converted to the most precise type and the
operation
evaluated.

=> SELECT 5 / 2;
is: integer operation integer
the most precise type is integer, so it's strictly integer math.
evaluated as integer / integer = integer result

=> SELECT 5 / 2.0;
is: integer operation float
the most precise type is float
evaluated as float / float = float result

It's performing as I expected based on my knowledge of C.


On 9/29/05, Ralf Junker <[EMAIL PROTECTED]> wrote:
>
> In risk of asking the obvious, I wonder if the following division should
> be considered correct:
>
> | Query | Result Value | Result Type | OK?
> ---
> 1 | SELECT 5 / 2; | 2 | SQLITE_INTEGER | No?
> 2 | SELECT 5.0 / 2; | 2.5 | SQLITE_FLOAT | Yes
> 3 | SELECT 5 / 2.0; | 2.5 | SQLITE_FLOAT | Yes
> 4 | SELECT 5.0 / 2.0; | 2.5 | SQLITE_FLOAT | Yes
>
> The query in question is Query 1. Is the returned integer result correct
> or should it not better return the 2.5 float value instead?
>