mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-11 19:20:40 +08:00
Fix core dump in QTNodeCompare when tsquery_cmp() is applied to two empty
tsqueries. CompareTSQ has to have a guard for the case rather than blindly applying QTNodeCompare to random data past the end of the datums. Also, change QTNodeCompare to be a little less trusting: use an actual test rather than just Assert'ing that the input is sane. Problem encountered while investigating another issue (I saw a core dump in autoanalyze on a table containing multiple empty tsquery values). Back-patch to all branches with tsquery support. In HEAD, also fix some bizarre (though not outright wrong) coding in tsq_mcontains().
This commit is contained in:
parent
57d9aefcaa
commit
57641a165f
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_op.c,v 1.8 2010/01/02 16:57:55 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_op.c,v 1.9 2010/08/03 00:10:39 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -149,7 +149,7 @@ CompareTSQ(TSQuery a, TSQuery b)
|
|||||||
{
|
{
|
||||||
return (VARSIZE(a) < VARSIZE(b)) ? -1 : 1;
|
return (VARSIZE(a) < VARSIZE(b)) ? -1 : 1;
|
||||||
}
|
}
|
||||||
else
|
else if (a->size != 0)
|
||||||
{
|
{
|
||||||
QTNode *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
|
QTNode *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
|
||||||
QTNode *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
|
QTNode *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
|
||||||
@ -247,20 +247,20 @@ tsq_mcontains(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(false);
|
PG_RETURN_BOOL(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iq = GETQUERY(query);
|
||||||
ie = GETQUERY(ex);
|
ie = GETQUERY(ex);
|
||||||
|
|
||||||
for (i = 0; i < ex->size; i++)
|
for (i = 0; i < ex->size; i++)
|
||||||
{
|
{
|
||||||
iq = GETQUERY(query);
|
|
||||||
if (ie[i].type != QI_VAL)
|
if (ie[i].type != QI_VAL)
|
||||||
continue;
|
continue;
|
||||||
for (j = 0; j < query->size; j++)
|
for (j = 0; j < query->size; j++)
|
||||||
if (iq[j].type == QI_VAL && ie[i].qoperand.valcrc == iq[j].qoperand.valcrc)
|
{
|
||||||
{
|
if (iq[j].type == QI_VAL &&
|
||||||
j = query->size + 1;
|
ie[i].qoperand.valcrc == iq[j].qoperand.valcrc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j == query->size)
|
if (j >= query->size)
|
||||||
{
|
{
|
||||||
PG_FREE_IF_COPY(query, 0);
|
PG_FREE_IF_COPY(query, 0);
|
||||||
PG_FREE_IF_COPY(ex, 1);
|
PG_FREE_IF_COPY(ex, 1);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_util.c,v 1.13 2010/01/02 16:57:55 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_util.c,v 1.14 2010/08/03 00:10:39 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -113,13 +113,11 @@ QTNodeCompare(QTNode *an, QTNode *bn)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else if (an->valnode->type == QI_VAL)
|
||||||
{
|
{
|
||||||
QueryOperand *ao = &an->valnode->qoperand;
|
QueryOperand *ao = &an->valnode->qoperand;
|
||||||
QueryOperand *bo = &bn->valnode->qoperand;
|
QueryOperand *bo = &bn->valnode->qoperand;
|
||||||
|
|
||||||
Assert(an->valnode->type == QI_VAL);
|
|
||||||
|
|
||||||
if (ao->valcrc != bo->valcrc)
|
if (ao->valcrc != bo->valcrc)
|
||||||
{
|
{
|
||||||
return (ao->valcrc > bo->valcrc) ? -1 : 1;
|
return (ao->valcrc > bo->valcrc) ? -1 : 1;
|
||||||
@ -127,6 +125,11 @@ QTNodeCompare(QTNode *an, QTNode *bn)
|
|||||||
|
|
||||||
return tsCompareString(an->word, ao->length, bn->word, bo->length, false);
|
return tsCompareString(an->word, ao->length, bn->word, bo->length, false);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elog(ERROR, "unrecognized QueryItem type: %d", an->valnode->type);
|
||||||
|
return 0; /* keep compiler quiet */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user