Re: [HACKERS] Bug in 6.4 release

From: Bruce Momjian <maillist(at)candle(dot)pha(dot)pa(dot)us>
To: vadim(at)krs(dot)ru (Vadim Mikheev)
Cc: hackers(at)postgreSQL(dot)org (PostgreSQL-development)
Subject: Re: [HACKERS] Bug in 6.4 release
Date: 1998-11-22 05:49:57
Message-ID: 199811220549.AAA04903@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

> Bruce Momjian wrote:
> >
> > >
> > > thplus=> select count(*) from envelope where state_id='H' or
> > > state_id='E';
> > > pqReadData() -- backend closed the channel unexpectedly.
> > > This probably means the backend terminated abnormally before or
> > > while processing the request.
> > > We have lost the connection to the backend, so further processing is
> > > impossible. Terminating.
> >
> > I need help with this one. Attached is a patch that also fails, but it
> > looks closer than the original code. The problem appears to be that I
> > can't get a slot that matches the items of the Var node I am trying to
> > evaluate. If I used one that matches the heap tuple, that fails,
> > because if the index is on the second column of the tuple, the attnum is
> > 1, while it is actually 2nd in the tuple slot.
> >
> > Does anyone know the executor well enough to find me that slot that
> > matches the Var node? I can't figure it out.
>
> Hi, Bruce!
>
> I'll take a look...
>
> Vadim
>

Thanks.

First, let me give you a reproducible example:

create table test (x int, y text);
insert into test values (1,'fred');
insert into test values (1,'barney');
insert into test select * from test;
..repeat the above several times
create index i_test on test(y);
vacuum;
select count(*) from test where y='fred' or y='barney';
..crash

This only crashes if the OR field is not the first field in the table.
The error appears to be that the indexqual has a varno of 1, while the
heap location of the column in the above example is obviously 2. My
guess is that the varno matches the index varno, and not the heap varno.

I not think previous patch is wrong. The original code is better. You
have to compare the qualification against the actual heap row, because
you could be using a different index on the second OR than the first:

This new patch uses scankeys instead of throwing the indexqual to the
executor. This is probably more efficient, but I am not sure about the
other ramifications. It still fails.

Obviously, the idea that I want to use indexqual to test a heap tuple
was never anticipated by the original coders. I wonder why more people
have not reported OR problems?

Good luck. I am kind of stumped on this.

---------------------------------------------------------------------------

Index: src/backend/executor/nodeIndexscan.c
===================================================================
RCS file: /usr/local/cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v
retrieving revision 1.27
diff -c -r1.27 nodeIndexscan.c
*** nodeIndexscan.c 1998/09/01 04:28:32 1.27
--- nodeIndexscan.c 1998/11/22 05:30:40
***************
*** 39,44 ****
--- 39,45 ----

#include "access/skey.h"
#include "access/heapam.h"
+ #include "access/valid.h"
#include "access/genam.h"
#include "utils/palloc.h"
#include "utils/mcxt.h"
***************
*** 95,101 ****
TupleTableSlot *slot;
Buffer buffer = InvalidBuffer;
int numIndices;
!
/* ----------------
* extract necessary information from index scan node
* ----------------
--- 96,104 ----
TupleTableSlot *slot;
Buffer buffer = InvalidBuffer;
int numIndices;
! int *numScanKeys;
! ScanKey *scanKeys;
!
/* ----------------
* extract necessary information from index scan node
* ----------------
***************
*** 109,114 ****
--- 112,119 ----
heapRelation = scanstate->css_currentRelation;
numIndices = indexstate->iss_NumIndices;
slot = scanstate->css_ScanTupleSlot;
+ numScanKeys = indexstate->iss_NumScanKeys;
+ scanKeys = indexstate->iss_ScanKeys;

/* ----------------
* ok, now that we have what we need, fetch an index tuple.
***************
*** 153,161 ****
for (prev_index = 0; prev_index < indexstate->iss_IndexPtr;
prev_index++)
{
! scanstate->cstate.cs_ExprContext->ecxt_scantuple = slot;
! if (ExecQual(nth(prev_index, node->indxqual),
! scanstate->cstate.cs_ExprContext))
{
prev_matches = true;
break;
--- 158,169 ----
for (prev_index = 0; prev_index < indexstate->iss_IndexPtr;
prev_index++)
{
! bool result;
!
! HeapKeyTest(tuple, RelationGetDescr(heapRelation),
! numScanKeys[prev_index],
! scanKeys[prev_index], result);
! if (result)
{
prev_matches = true;
break;

--
Bruce Momjian | http://www.op.net/~candle
maillist(at)candle(dot)pha(dot)pa(dot)us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Vadim Mikheev 1998-11-22 10:31:49 Re: [HACKERS] Bug in 6.4 release
Previous Message Bruce Momjian 1998-11-21 20:10:49 Re: [HACKERS] Allow ORDER BY a Function