Обсуждение: 8.1 Unique Index Issue/Bug???

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

8.1 Unique Index Issue/Bug???

От
"Chris Hoover"
Дата:
I am having what appears to be a bug with unique indexes on 8.1.3.

I have created a new table.

create table payer_835 (
    payer_id         int8 not null default nextval('payer_835_payer_id_seq'::regclass) primary key,
    payer_name        varchar(50) not null,
    payer_trn03        varchar(10) not null,
    payer_trn04        varchar(30),
    sku_id            int8 references skucode(sku_id) on delete cascade on update cascade,
    payer_billable        boolean not null default true,
    create_timestamp    timestamp not null default now(),
    last_mod_timestamp    timestamp,
    expire_timestamp    timestamp
);

On this table, I have created a unique index on payer_trn03, payer_trn04, and expire_timestamp.  However, since the expire_timestamp is normally null, the unique index does not appear to be working.  I have been able to enter two identical rows into this table.

Why is PostgreSQL not enforcing this index? This appears to be a pretty major a bug?  It would seem that you could have a unique index across columns that might have a null in them.

Here is the data from the table:

COPY payer_835 (payer_id, payer_name, payer_trn03, payer_trn04, sku_id, payer_billable, create_timestamp, last_mod_timestamp, expire_timestamp) FROM stdin;
1       CAHABA GBA-AL PART B    1630103830      \N      1       t       2006-07-13 09:57: 52.834631      \N      \N
2       FEP     123456789       00402   1       t       2006-07-10 10:56:23     \N      \N
3       NC Medicaid     123123123       \N      1       t       2006-07-10 10:56:41     \N      \N
4       CAHABA GBA-AL PART B    1630103830      \N      1       t       2006-07-11 16:13:43.808181      2006-07-12 10:09:46.066204      \N
\.


Notice records 1 and 4 have identical data (as far as my unique index is concerned), and the index it not complaining.

thanks,

Chris
RHAS 4.0
PG 8.1.3 (from rpms)

Re: 8.1 Unique Index Issue/Bug???

От
Scott Marlowe
Дата:
On Thu, 2006-07-13 at 09:40, Chris Hoover wrote:
> I am having what appears to be a bug with unique indexes on 8.1.3.
>
> I have created a new table.
>
> create table payer_835 (
>     payer_id         int8 not null default
> nextval('payer_835_payer_id_seq'::regclass) primary key,
>     payer_name        varchar(50) not null,
>     payer_trn03        varchar(10) not null,
>     payer_trn04        varchar(30),
>     sku_id            int8 references skucode(sku_id) on delete
> cascade on update cascade,
>     payer_billable        boolean not null default true,
>     create_timestamp    timestamp not null default now(),
>     last_mod_timestamp    timestamp,
>     expire_timestamp    timestamp
> );
>
> On this table, I have created a unique index on payer_trn03,
> payer_trn04, and expire_timestamp.  However, since the
> expire_timestamp is normally null, the unique index does not appear to
> be working.  I have been able to enter two identical rows into this
> table.
>
> Why is PostgreSQL not enforcing this index? This appears to be a
> pretty major a bug?  It would seem that you could have a unique index
> across columns that might have a null in them.
>
> Here is the data from the table:
>
> COPY payer_835 (payer_id, payer_name, payer_trn03, payer_trn04,
> sku_id, payer_billable, create_timestamp, last_mod_timestamp,
> expire_timestamp) FROM stdin;
> 1       CAHABA GBA-AL PART B    1630103830      \N      1
> t       2006-07-13 09:57: 52.834631      \N      \N
> 2       FEP     123456789       00402   1       t       2006-07-10
> 10:56:23     \N      \N
> 3       NC Medicaid     123123123       \N      1       t
> 2006-07-10 10:56:41     \N      \N
> 4       CAHABA GBA-AL PART B    1630103830      \N      1
> t       2006-07-11 16:13:43.808181      2006-07-12
> 10:09:46.066204      \N
> \.
>
>
> Notice records 1 and 4 have identical data (as far as my unique index
> is concerned), and the index it not complaining.

But you have NULL expire_timestamps, and NULL <> NULL

Re: 8.1 Unique Index Issue/Bug???

От
Michael Fuhr
Дата:
On Thu, Jul 13, 2006 at 10:40:43AM -0400, Chris Hoover wrote:
> Why is PostgreSQL not enforcing this index? This appears to be a pretty
> major a bug?  It would seem that you could have a unique index across
> columns that might have a null in them.

This comes up frequently due to a misunderstanding of how NULL
comparison works.

http://www.postgresql.org/docs/8.1/interactive/ddl-constraints.html#AEN2016

"In general, a unique constraint is violated when there are two or
more rows in the table where the values of all of the columns
included in the constraint are equal.  However, null values are not
considered equal in this comparison.  That means even in the presence
of a unique constraint it is possible to store duplicate rows that
contain a null value in at least one of the constrained columns.
This behavior conforms to the SQL standard, but we have heard that
other SQL databases may not follow this rule.  So be careful when
developing applications that are intended to be portable."

--
Michael Fuhr

Re: 8.1 Unique Index Issue/Bug???

От
"Aaron Bono"
Дата:
On 7/13/06, Chris Hoover <revoohc@gmail.com> wrote:
I am having what appears to be a bug with unique indexes on 8.1.3.

I have created a new table.

create table payer_835 (
    payer_id         int8 not null default nextval('payer_835_payer_id_seq'::regclass) primary key,
    payer_name        varchar(50) not null,
    payer_trn03        varchar(10) not null,
    payer_trn04        varchar(30),
    sku_id            int8 references skucode(sku_id) on delete cascade on update cascade,
    payer_billable        boolean not null default true,
    create_timestamp    timestamp not null default now(),
    last_mod_timestamp    timestamp,
    expire_timestamp    timestamp
);

On this table, I have created a unique index on payer_trn03, payer_trn04, and expire_timestamp.  However, since the expire_timestamp is normally null, the unique index does not appear to be working.  I have been able to enter two identical rows into this table.

Why is PostgreSQL not enforcing this index? This appears to be a pretty major a bug?  It would seem that you could have a unique index across columns that might have a null in them.

Here is the data from the table:

COPY payer_835 (payer_id, payer_name, payer_trn03, payer_trn04, sku_id, payer_billable, create_timestamp, last_mod_timestamp, expire_timestamp) FROM stdin;
1       CAHABA GBA-AL PART B    1630103830      \N      1       t       2006-07-13 09:57: 52.834631      \N      \N
2       FEP     123456789       00402   1       t       2006-07-10 10:56:23     \N      \N
3       NC Medicaid     123123123       \N      1       t       2006-07-10 10:56:41     \N      \N
4       CAHABA GBA-AL PART B    1630103830      \N      1       t       2006-07-11 16:13:43.808181      2006-07-12 10:09:46.066204      \N
\.


Notice records 1 and 4 have identical data (as far as my unique index is concerned), and the index it not complaining.

A null means no data so nulls are not considered on the unique constraints.  That is the way it is supposed to work.

There was discussion about this fact here:

http://www.thescripts.com/forum/thread400192.html
http://archives.postgresql.org/pgsql-bugs/2004-07/msg00099.php

You are probably going to need to write a trigger if you want to enforce that NULL is unique for that field.

==================================================================
   Aaron Bono
   Aranya Software Technologies, Inc.
   http://www.aranya.com
==================================================================

Re: 8.1 Unique Index Issue/Bug???

От
Stephan Szabo
Дата:
On Thu, 13 Jul 2006, Chris Hoover wrote:

> I am having what appears to be a bug with unique indexes on 8.1.3.
>
> I have created a new table.
>
> create table payer_835 (
>     payer_id         int8 not null default
> nextval('payer_835_payer_id_seq'::regclass) primary key,
>     payer_name        varchar(50) not null,
>     payer_trn03        varchar(10) not null,
>     payer_trn04        varchar(30),
>     sku_id            int8 references skucode(sku_id) on delete cascade on
> update cascade,
>     payer_billable        boolean not null default true,
>     create_timestamp    timestamp not null default now(),
>     last_mod_timestamp    timestamp,
>     expire_timestamp    timestamp
> );
>
> On this table, I have created a unique index on payer_trn03, payer_trn04,
> and expire_timestamp.  However, since the expire_timestamp is normally null,
> the unique index does not appear to be working.  I have been able to enter
> two identical rows into this table.

Two nulls are considered distinct for purposes of unique indexes and
constraints.

The unique constraint is defined effective as a search condition of
                 UNIQUE ( SELECT UCL FROM TN )
(with UCL being the column list in the constraint).

The definition from the UNIQUE predicate says (from sql92):
"If there are no two rows in T such that the value of each column in one
row is non-null as is equal to the value of the corresponding column in
the other row according to Subclause 8.2, "<comparison predicate>", then
the result of the <unique predicate> is true; otherwise, the result of the
<unique predicate> is false."

So, given something like
 1, 2, NULL
 1, 2, NULL
the unique predicate is true and the data is allowed by the constraint.

Re: 8.1 Unique Index Issue/Bug???

От
Peter Eisentraut
Дата:
Am Donnerstag, 13. Juli 2006 16:40 schrieb Chris Hoover:
> On this table, I have created a unique index on payer_trn03, payer_trn04,
> and expire_timestamp.  However, since the expire_timestamp is normally
> null, the unique index does not appear to be working.  I have been able to
> enter two identical rows into this table.

This behavior is correct according to the SQL standard, as two null values are
not considered equal.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: 8.1 Unique Index Issue/Bug???

От
Andy Shellam
Дата:
PostgreSQL does not consider a NULL value to be an equal value,
therefore it cannot be a duplicate.

If you must have a blank value in a column and need it to be unique,
you'd need to do something like an empty string, or a string/figure your
application will know is a null value that makes sense.

It's also the same on multi-column indexes - if one column is NULL-able,
the index won't be enforced against the null values.

 From http://www.postgresql.org/docs/8.1/static/indexes-unique.html:

"When an index is declared unique, multiple table rows with equal
indexed values will not be allowed. Null values are not considered
equal. A multicolumn unique index will only reject cases where all of
the indexed columns are equal in two rows."

Andy.

Chris Hoover wrote:
> I am having what appears to be a bug with unique indexes on 8.1.3.
>
> I have created a new table.
>
> create table payer_835 (
>     payer_id         int8 not null default
> nextval('payer_835_payer_id_seq'::regclass) primary key,
>     payer_name        varchar(50) not null,
>     payer_trn03        varchar(10) not null,
>     payer_trn04        varchar(30),
>     sku_id            int8 references skucode(sku_id) on delete
> cascade on update cascade,
>     payer_billable        boolean not null default true,
>     create_timestamp    timestamp not null default now(),
>     last_mod_timestamp    timestamp,
>     expire_timestamp    timestamp
> );
>
> On this table, I have created a unique index on payer_trn03,
> payer_trn04, and expire_timestamp.  However, since the
> expire_timestamp is normally null, the unique index does not appear to
> be working.  I have been able to enter two identical rows into this
> table.
>
> Why is PostgreSQL not enforcing this index? This appears to be a
> pretty major a bug?  It would seem that you could have a unique index
> across columns that might have a null in them.
>
> Here is the data from the table:
>
> COPY payer_835 (payer_id, payer_name, payer_trn03, payer_trn04,
> sku_id, payer_billable, create_timestamp, last_mod_timestamp,
> expire_timestamp) FROM stdin;
> 1       CAHABA GBA-AL PART B    1630103830      \N      1
> t       2006-07-13 09:57: 52.834631      \N      \N
> 2       FEP     123456789       00402   1       t       2006-07-10
> 10:56:23     \N      \N
> 3       NC Medicaid     123123123       \N      1       t
> 2006-07-10 10:56:41     \N      \N
> 4       CAHABA GBA-AL PART B    1630103830      \N      1
> t       2006-07-11 16:13:43.808181      2006-07-12 10:09:46.066204      \N
> \.
>
>
> Notice records 1 and 4 have identical data (as far as my unique index
> is concerned), and the index it not complaining.
>
> thanks,
>
> Chris
> RHAS 4.0
> PG 8.1.3 (from rpms)
> !DSPAM:14,44b66a2a34531616211146!


Re: 8.1 Unique Index Issue/Bug???

От
"Rodrigo De Leon"
Дата:
On 7/13/06, Chris Hoover <revoohc@gmail.com> wrote:
> On this table, I have created a unique index on payer_trn03, payer_trn04,
> and expire_timestamp.  However, since the expire_timestamp is normally null,
> the unique index does not appear to be working.  I have been able to enter
> two identical rows into this table.
>
> Why is PostgreSQL not enforcing this index? This appears to be a pretty
> major a bug?  It would seem that you could have a unique index across
> columns that might have a null in them.

From:

http://www.postgresql.org/docs/8.1/interactive/indexes-unique.html

Quote:

"When an index is declared unique, multiple table rows with equal
indexed values will not be allowed. Null values are not considered
equal. A multicolumn unique index will only reject cases where all of
the indexed columns are equal in two rows."

Regards,

Rodrigo

Re: 8.1 Unique Index Issue/Bug???

От
"Joshua D. Drake"
Дата:
>> Why is PostgreSQL not enforcing this index? This appears to be a pretty
>> major a bug?  It would seem that you could have a unique index across
>> columns that might have a null in them.
>
> From:
>
> http://www.postgresql.org/docs/8.1/interactive/indexes-unique.html
>
> Quote:
>
> "When an index is declared unique, multiple table rows with equal
> indexed values will not be allowed. Null values are not considered
> equal. A multicolumn unique index will only reject cases where all of
> the indexed columns are equal in two rows."

To further this... in PostgreSQL:

IS NULL != ''

'' is a blank string and thus an actual value where IS NULL is nothing,
vapor, a blackhole.

That is why IS NULL can be placed in a unique index because it isn't
actually there (in the theorectical sense).

Sincerely,

Joshua D. Drake



>
> Regards,
>
> Rodrigo
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: explain analyze is your friend
>


--

    === The PostgreSQL Company: Command Prompt, Inc. ===
Sales/Support: +1.503.667.4564 || 24x7/Emergency: +1.800.492.2240
    Providing the most comprehensive  PostgreSQL solutions since 1997
              http://www.commandprompt.com/



Re: 8.1 Unique Index Issue/Bug???

От
Chris Browne
Дата:
jd@commandprompt.com ("Joshua D. Drake") writes:
> That is why IS NULL can be placed in a unique index because it isn't
> actually there (in the theorectical sense).

In effect, NULL is not actually a value.
--
(reverse (concatenate 'string "gro.mca" "@" "enworbbc"))
http://www.ntlug.org/~cbbrowne/sap.html
"Has anyone ever thought about the fact that in general, the only web
sites that are consistently making money are the ones dealing in
pornography?  This brings new meaning to the term, "obscene
profits". :)"  -- Paul Robinson <postmaster@paul.washington.dc.us>