
Browsing through backend/commands/command.c I noticed the following code:

    if (indexStruct->indisunique)
    {
        List       *attrl;

        /* go through the fkconstraint->pk_attrs list */
        foreach(attrl, fkconstraint->pk_attrs)
        {
            Ident *attr=lfirst(attrl);
            found = false;
            for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0;
i++)
            {
                int pkattno = indexStruct->indkey[i];
                if (pkattno>0)
                {
                    char *name = NameStr(rel_attrs[pkattno-1]->attname);
                    if (strcmp(name, attr->name)==0)
                    {
                        found = true;
                        break;
                    }
                }
            }
            if (!found)
                break;
        }
    }

which is (I think) supposed to be checking for a unique index on the FK
fields in the referenced table.

Unfortunately, my reading of this code suggests it is doing the following:

    for each column in the FK

        see if we can find the column in the index
        if not, then die

    next FK column

The problem with this is that it needs to ensure a 1:1 match between
columns for the UNIQUE constraint requirement to be satisfied...I think.

To give an example,

    create table c2(f1 integer, f2 integer, unique(f1,f2));
    create table c1(f1 integer, f2 integer, foreign key(f1) references
c2(f1));

is allowed with current sources.

I'd guess that adding code to ensure the column lists are the same size
would fix the problem.


----------------------------------------------------------------
Philip Warner                    |     __---_____
Albatross Consulting Pty. Ltd.   |----/       -  \
(A.B.N. 75 008 659 498)          |          /(@)   ______---_
Tel: (+61) 0500 83 82 81         |                 _________  \
Fax: (+61) 0500 83 82 82         |                 ___________ |
Http://www.rhyme.com.au          |                /           \|
                                 |    --________--
PGP key available upon request,  |  /
and from pgp5.ai.mit.edu:11371   |/

Wed, 29 Nov 2000 02:49:11 +1100
Philip Warner <pjw@rhyme.com.au>
Problem in AlterTableAddConstraint?

Assuming the silence is agreement, does this look like the right solution
(I assume looping through the index is the only way to count the segments):

    if (indexStruct->indisunique)
    {
        List       *attrl;

        /* go through the fkconstraint->pk_attrs list */
        foreach(attrl, fkconstraint->pk_attrs)
        {
            Ident *attr=lfirst(attrl);
            found = false;
            for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0;
i++)
            {
                int pkattno = indexStruct->indkey[i];
                if (pkattno>0)
                {
                    char *name = NameStr(rel_attrs[pkattno-1]->attname);
                    if (strcmp(name, attr->name)==0)
                    {
                        found = true;
                        break;
                    }
                }
            }

            if (!found)
+           {
                break;
+           } else {
+
+               /* Require same number of segments */ 
+               if (i != length(fkconstraint->pk_attrs))
+               {
+                   found = false;
+                   break;
+               }
+           }
        }
    }


At 02:49 29/11/00 +1100, Philip Warner wrote:
>
>    create table c2(f1 integer, f2 integer, unique(f1,f2));
>    create table c1(f1 integer, f2 integer, 
>                    foreign key(f1) references c2(f1));
>
> is allowed with current sources.
>

----------------------------------------------------------------
Philip Warner                    |     __---_____
Albatross Consulting Pty. Ltd.   |----/       -  \
(A.B.N. 75 008 659 498)          |          /(@)   ______---_
Tel: (+61) 0500 83 82 81         |                 _________  \
Fax: (+61) 0500 83 82 82         |                 ___________ |
Http://www.rhyme.com.au          |                /           \|
                                 |    --________--
PGP key available upon request,  |  /
and from pgp5.ai.mit.edu:11371   |/

Wed, 29 Nov 2000 13:40:21 +1100
Philip Warner <pjw@rhyme.com.au>
Re: Problem in AlterTableAddConstraint?

Can anyone comment on this?

> 
> Browsing through backend/commands/command.c I noticed the following code:
> 
>     if (indexStruct->indisunique)
>     {
>         List       *attrl;
> 
>         /* go through the fkconstraint->pk_attrs list */
>         foreach(attrl, fkconstraint->pk_attrs)
>         {
>             Ident *attr=lfirst(attrl);
>             found = false;
>             for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0;
> i++)
>             {
>                 int pkattno = indexStruct->indkey[i];
>                 if (pkattno>0)
>                 {
>                     char *name = NameStr(rel_attrs[pkattno-1]->attname);
>                     if (strcmp(name, attr->name)==0)
>                     {
>                         found = true;
>                         break;
>                     }
>                 }
>             }
>             if (!found)
>                 break;
>         }
>     }
> 
> which is (I think) supposed to be checking for a unique index on the FK
> fields in the referenced table.
> 
> Unfortunately, my reading of this code suggests it is doing the following:
> 
>     for each column in the FK
> 
>         see if we can find the column in the index
>         if not, then die
> 
>     next FK column
> 
> The problem with this is that it needs to ensure a 1:1 match between
> columns for the UNIQUE constraint requirement to be satisfied...I think.
> 
> To give an example,
> 
>     create table c2(f1 integer, f2 integer, unique(f1,f2));
>     create table c1(f1 integer, f2 integer, foreign key(f1) references
> c2(f1));
> 
> is allowed with current sources.
> 
> I'd guess that adding code to ensure the column lists are the same size
> would fix the problem.
> 
> 
> ----------------------------------------------------------------
> Philip Warner                    |     __---_____
> Albatross Consulting Pty. Ltd.   |----/       -  \
> (A.B.N. 75 008 659 498)          |          /(@)   ______---_
> Tel: (+61) 0500 83 82 81         |                 _________  \
> Fax: (+61) 0500 83 82 82         |                 ___________ |
> Http://www.rhyme.com.au          |                /           \|
>                                  |    --________--
> PGP key available upon request,  |  /
> and from pgp5.ai.mit.edu:11371   |/
> 


-- 
  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, Pennsylvania 19026

Mon, 22 Jan 2001 21:32:53 -0500 (EST)
Bruce Momjian <pgman@candle.pha.pa.us>
Re: Problem in AlterTableAddConstraint?
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> Can anyone comment on this?

The code seems to have been changed as per Philip's suggestion.

			regards, tom lane

Mon, 22 Jan 2001 21:56:59 -0500
Tom Lane <tgl@sss.pgh.pa.us>
Re: Problem in AlterTableAddConstraint? 

Should be fixed now.  I had sent a patch in a while ago about it
and the code does seem to do an extra step now which gets the length
of the index and compares it to the length of the attribute list.

On Mon, 22 Jan 2001, Bruce Momjian wrote:

> 
> Can anyone comment on this?
> 
> > 
> > Browsing through backend/commands/command.c I noticed the following code:
> > 
> >     if (indexStruct->indisunique)
> >     {
> >         List       *attrl;
> > 
> >         /* go through the fkconstraint->pk_attrs list */
> >         foreach(attrl, fkconstraint->pk_attrs)
> >         {
> >             Ident *attr=lfirst(attrl);
> >             found = false;
> >             for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0;
> > i++)
> >             {
> >                 int pkattno = indexStruct->indkey[i];
> >                 if (pkattno>0)
> >                 {
> >                     char *name = NameStr(rel_attrs[pkattno-1]->attname);
> >                     if (strcmp(name, attr->name)==0)
> >                     {
> >                         found = true;
> >                         break;
> >                     }
> >                 }
> >             }
> >             if (!found)
> >                 break;
> >         }
> >     }
> > 
> > which is (I think) supposed to be checking for a unique index on the FK
> > fields in the referenced table.
> > 
> > Unfortunately, my reading of this code suggests it is doing the following:
> > 
> >     for each column in the FK
> > 
> >         see if we can find the column in the index
> >         if not, then die
> > 
> >     next FK column
> > 
> > The problem with this is that it needs to ensure a 1:1 match between
> > columns for the UNIQUE constraint requirement to be satisfied...I think.
> > 
> > To give an example,
> > 
> >     create table c2(f1 integer, f2 integer, unique(f1,f2));
> >     create table c1(f1 integer, f2 integer, foreign key(f1) references
> > c2(f1));
> > 
> > is allowed with current sources.
> > 
> > I'd guess that adding code to ensure the column lists are the same size
> > would fix the problem.
> > 
> > 
> > ----------------------------------------------------------------
> > Philip Warner                    |     __---_____
> > Albatross Consulting Pty. Ltd.   |----/       -  \
> > (A.B.N. 75 008 659 498)          |          /(@)   ______---_
> > Tel: (+61) 0500 83 82 81         |                 _________  \
> > Fax: (+61) 0500 83 82 82         |                 ___________ |
> > Http://www.rhyme.com.au          |                /           \|
> >                                  |    --________--
> > PGP key available upon request,  |  /
> > and from pgp5.ai.mit.edu:11371   |/
> > 
> 
> 
> -- 
>   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, Pennsylvania 19026
> 


Mon, 22 Jan 2001 19:01:24 -0800 (PST)
Stephan Szabo <sszabo@megazone23.bigpanda.com>
Re: Problem in AlterTableAddConstraint?