Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 595a5a7

Browse files
committed
> Okay. When you get back to the original issue, the gold is hidden in
> src/backend/optimizer/path/indxpath.c; see the "special indexable > operators" stuff near the bottom of that file. (It's a bit of a crock > that this code is hardwired there, and not somehow accessed through a > system catalog, but it's what we've got at the moment.) The attached patch re-enables a bytea right hand argument (as compared to a text right hand argument), and enables index usage, for bytea LIKE Joe Conway
1 parent 81efc82 commit 595a5a7

File tree

6 files changed

+256
-154
lines changed

6 files changed

+256
-154
lines changed

src/backend/optimizer/path/indxpath.c

Lines changed: 48 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.120 2002/07/13 19:20:34 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.121 2002/09/02 06:22:18 momjian Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -97,7 +97,7 @@ static bool function_index_operand(Expr *funcOpnd, RelOptInfo *rel,
9797
static bool match_special_index_operator(Expr *clause, Oid opclass,
9898
bool indexkey_on_left);
9999
static List *prefix_quals(Var *leftop, Oid expr_op,
100-
char *prefix, Pattern_Prefix_Status pstatus);
100+
Const *prefix, Pattern_Prefix_Status pstatus);
101101
static List *network_prefix_quals(Var *leftop, Oid expr_op, Datum rightop);
102102
static Oid find_operator(const char *opname, Oid datatype);
103103
static Datum string_to_datum(const char *str, Oid datatype);
@@ -1675,10 +1675,9 @@ match_special_index_operator(Expr *clause, Oid opclass,
16751675
Var *leftop,
16761676
*rightop;
16771677
Oid expr_op;
1678-
Datum constvalue;
1679-
char *patt;
1680-
char *prefix;
1681-
char *rest;
1678+
Const *patt = NULL;
1679+
Const *prefix = NULL;
1680+
Const *rest = NULL;
16821681

16831682
/*
16841683
* Currently, all known special operators require the indexkey on the
@@ -1697,76 +1696,53 @@ match_special_index_operator(Expr *clause, Oid opclass,
16971696
if (!IsA(rightop, Const) ||
16981697
((Const *) rightop)->constisnull)
16991698
return false;
1700-
constvalue = ((Const *) rightop)->constvalue;
1699+
patt = (Const *) rightop;
17011700

17021701
switch (expr_op)
17031702
{
17041703
case OID_TEXT_LIKE_OP:
17051704
case OID_BPCHAR_LIKE_OP:
17061705
case OID_VARCHAR_LIKE_OP:
17071706
case OID_NAME_LIKE_OP:
1707+
/* the right-hand const is type text for all of these */
17081708
if (locale_is_like_safe())
1709-
{
1710-
/* the right-hand const is type text for all of these */
1711-
patt = DatumGetCString(DirectFunctionCall1(textout,
1712-
constvalue));
17131709
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Like,
17141710
&prefix, &rest) != Pattern_Prefix_None;
1715-
if (prefix)
1716-
pfree(prefix);
1717-
pfree(patt);
1718-
}
1711+
break;
1712+
1713+
case OID_BYTEA_LIKE_OP:
1714+
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Like,
1715+
&prefix, &rest) != Pattern_Prefix_None;
17191716
break;
17201717

17211718
case OID_TEXT_ICLIKE_OP:
17221719
case OID_BPCHAR_ICLIKE_OP:
17231720
case OID_VARCHAR_ICLIKE_OP:
17241721
case OID_NAME_ICLIKE_OP:
1722+
/* the right-hand const is type text for all of these */
17251723
if (locale_is_like_safe())
1726-
{
1727-
/* the right-hand const is type text for all of these */
1728-
patt = DatumGetCString(DirectFunctionCall1(textout,
1729-
constvalue));
17301724
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Like_IC,
17311725
&prefix, &rest) != Pattern_Prefix_None;
1732-
if (prefix)
1733-
pfree(prefix);
1734-
pfree(patt);
1735-
}
17361726
break;
17371727

17381728
case OID_TEXT_REGEXEQ_OP:
17391729
case OID_BPCHAR_REGEXEQ_OP:
17401730
case OID_VARCHAR_REGEXEQ_OP:
17411731
case OID_NAME_REGEXEQ_OP:
1732+
/* the right-hand const is type text for all of these */
17421733
if (locale_is_like_safe())
1743-
{
1744-
/* the right-hand const is type text for all of these */
1745-
patt = DatumGetCString(DirectFunctionCall1(textout,
1746-
constvalue));
17471734
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Regex,
17481735
&prefix, &rest) != Pattern_Prefix_None;
1749-
if (prefix)
1750-
pfree(prefix);
1751-
pfree(patt);
1752-
}
17531736
break;
17541737

17551738
case OID_TEXT_ICREGEXEQ_OP:
17561739
case OID_BPCHAR_ICREGEXEQ_OP:
17571740
case OID_VARCHAR_ICREGEXEQ_OP:
17581741
case OID_NAME_ICREGEXEQ_OP:
1742+
/* the right-hand const is type text for all of these */
17591743
if (locale_is_like_safe())
1760-
{
1761-
/* the right-hand const is type text for all of these */
1762-
patt = DatumGetCString(DirectFunctionCall1(textout,
1763-
constvalue));
17641744
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC,
17651745
&prefix, &rest) != Pattern_Prefix_None;
1766-
if (prefix)
1767-
pfree(prefix);
1768-
pfree(patt);
1769-
}
17701746
break;
17711747

17721748
case OID_INET_SUB_OP:
@@ -1777,6 +1753,12 @@ match_special_index_operator(Expr *clause, Oid opclass,
17771753
break;
17781754
}
17791755

1756+
if (prefix)
1757+
{
1758+
pfree(DatumGetPointer(prefix->constvalue));
1759+
pfree(prefix);
1760+
}
1761+
17801762
/* done if the expression doesn't look indexable */
17811763
if (!isIndexable)
17821764
return false;
@@ -1798,6 +1780,12 @@ match_special_index_operator(Expr *clause, Oid opclass,
17981780
isIndexable = false;
17991781
break;
18001782

1783+
case OID_BYTEA_LIKE_OP:
1784+
if (!op_in_opclass(find_operator(">=", BYTEAOID), opclass) ||
1785+
!op_in_opclass(find_operator("<", BYTEAOID), opclass))
1786+
isIndexable = false;
1787+
break;
1788+
18011789
case OID_BPCHAR_LIKE_OP:
18021790
case OID_BPCHAR_ICLIKE_OP:
18031791
case OID_BPCHAR_REGEXEQ_OP:
@@ -1867,10 +1855,9 @@ expand_indexqual_conditions(List *indexquals)
18671855
Var *leftop = get_leftop(clause);
18681856
Var *rightop = get_rightop(clause);
18691857
Oid expr_op = ((Oper *) clause->oper)->opno;
1870-
Datum constvalue;
1871-
char *patt;
1872-
char *prefix;
1873-
char *rest;
1858+
Const *patt = (Const *) rightop;
1859+
Const *prefix = NULL;
1860+
Const *rest = NULL;
18741861
Pattern_Prefix_Status pstatus;
18751862

18761863
switch (expr_op)
@@ -1885,82 +1872,57 @@ expand_indexqual_conditions(List *indexquals)
18851872
case OID_BPCHAR_LIKE_OP:
18861873
case OID_VARCHAR_LIKE_OP:
18871874
case OID_NAME_LIKE_OP:
1888-
/* the right-hand const is type text for all of these */
1889-
constvalue = ((Const *) rightop)->constvalue;
1890-
patt = DatumGetCString(DirectFunctionCall1(textout,
1891-
constvalue));
1875+
case OID_BYTEA_LIKE_OP:
18921876
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like,
18931877
&prefix, &rest);
18941878
resultquals = nconc(resultquals,
18951879
prefix_quals(leftop, expr_op,
18961880
prefix, pstatus));
1897-
if (prefix)
1898-
pfree(prefix);
1899-
pfree(patt);
19001881
break;
19011882

19021883
case OID_TEXT_ICLIKE_OP:
19031884
case OID_BPCHAR_ICLIKE_OP:
19041885
case OID_VARCHAR_ICLIKE_OP:
19051886
case OID_NAME_ICLIKE_OP:
19061887
/* the right-hand const is type text for all of these */
1907-
constvalue = ((Const *) rightop)->constvalue;
1908-
patt = DatumGetCString(DirectFunctionCall1(textout,
1909-
constvalue));
19101888
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like_IC,
19111889
&prefix, &rest);
19121890
resultquals = nconc(resultquals,
19131891
prefix_quals(leftop, expr_op,
19141892
prefix, pstatus));
1915-
if (prefix)
1916-
pfree(prefix);
1917-
pfree(patt);
19181893
break;
19191894

19201895
case OID_TEXT_REGEXEQ_OP:
19211896
case OID_BPCHAR_REGEXEQ_OP:
19221897
case OID_VARCHAR_REGEXEQ_OP:
19231898
case OID_NAME_REGEXEQ_OP:
19241899
/* the right-hand const is type text for all of these */
1925-
constvalue = ((Const *) rightop)->constvalue;
1926-
patt = DatumGetCString(DirectFunctionCall1(textout,
1927-
constvalue));
19281900
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex,
19291901
&prefix, &rest);
19301902
resultquals = nconc(resultquals,
19311903
prefix_quals(leftop, expr_op,
19321904
prefix, pstatus));
1933-
if (prefix)
1934-
pfree(prefix);
1935-
pfree(patt);
19361905
break;
19371906

19381907
case OID_TEXT_ICREGEXEQ_OP:
19391908
case OID_BPCHAR_ICREGEXEQ_OP:
19401909
case OID_VARCHAR_ICREGEXEQ_OP:
19411910
case OID_NAME_ICREGEXEQ_OP:
19421911
/* the right-hand const is type text for all of these */
1943-
constvalue = ((Const *) rightop)->constvalue;
1944-
patt = DatumGetCString(DirectFunctionCall1(textout,
1945-
constvalue));
19461912
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC,
19471913
&prefix, &rest);
19481914
resultquals = nconc(resultquals,
19491915
prefix_quals(leftop, expr_op,
19501916
prefix, pstatus));
1951-
if (prefix)
1952-
pfree(prefix);
1953-
pfree(patt);
19541917
break;
19551918

19561919
case OID_INET_SUB_OP:
19571920
case OID_INET_SUBEQ_OP:
19581921
case OID_CIDR_SUB_OP:
19591922
case OID_CIDR_SUBEQ_OP:
1960-
constvalue = ((Const *) rightop)->constvalue;
19611923
resultquals = nconc(resultquals,
19621924
network_prefix_quals(leftop, expr_op,
1963-
constvalue));
1925+
patt->constvalue));
19641926
break;
19651927

19661928
default:
@@ -1980,15 +1942,16 @@ expand_indexqual_conditions(List *indexquals)
19801942
*/
19811943
static List *
19821944
prefix_quals(Var *leftop, Oid expr_op,
1983-
char *prefix, Pattern_Prefix_Status pstatus)
1945+
Const *prefix_const, Pattern_Prefix_Status pstatus)
19841946
{
19851947
List *result;
19861948
Oid datatype;
19871949
Oid oproid;
1950+
char *prefix;
19881951
Const *con;
19891952
Oper *op;
19901953
Expr *expr;
1991-
char *greaterstr;
1954+
Const *greaterstr = NULL;
19921955

19931956
Assert(pstatus != Pattern_Prefix_None);
19941957

@@ -2001,6 +1964,10 @@ prefix_quals(Var *leftop, Oid expr_op,
20011964
datatype = TEXTOID;
20021965
break;
20031966

1967+
case OID_BYTEA_LIKE_OP:
1968+
datatype = BYTEAOID;
1969+
break;
1970+
20041971
case OID_BPCHAR_LIKE_OP:
20051972
case OID_BPCHAR_ICLIKE_OP:
20061973
case OID_BPCHAR_REGEXEQ_OP:
@@ -2027,6 +1994,11 @@ prefix_quals(Var *leftop, Oid expr_op,
20271994
return NIL;
20281995
}
20291996

1997+
if (prefix_const->consttype != BYTEAOID)
1998+
prefix = DatumGetCString(DirectFunctionCall1(textout, prefix_const->constvalue));
1999+
else
2000+
prefix = DatumGetCString(DirectFunctionCall1(byteaout, prefix_const->constvalue));
2001+
20302002
/*
20312003
* If we found an exact-match pattern, generate an "=" indexqual.
20322004
*/
@@ -2060,17 +2032,15 @@ prefix_quals(Var *leftop, Oid expr_op,
20602032
* "x < greaterstr".
20612033
*-------
20622034
*/
2063-
greaterstr = make_greater_string(prefix, datatype);
2035+
greaterstr = make_greater_string(con);
20642036
if (greaterstr)
20652037
{
20662038
oproid = find_operator("<", datatype);
20672039
if (oproid == InvalidOid)
20682040
elog(ERROR, "prefix_quals: no < operator for type %u", datatype);
2069-
con = string_to_const(greaterstr, datatype);
20702041
op = makeOper(oproid, InvalidOid, BOOLOID, false);
2071-
expr = make_opclause(op, leftop, (Var *) con);
2042+
expr = make_opclause(op, leftop, (Var *) greaterstr);
20722043
result = lappend(result, expr);
2073-
pfree(greaterstr);
20742044
}
20752045

20762046
return result;
@@ -2186,6 +2156,8 @@ string_to_datum(const char *str, Oid datatype)
21862156
*/
21872157
if (datatype == NAMEOID)
21882158
return DirectFunctionCall1(namein, CStringGetDatum(str));
2159+
else if (datatype == BYTEAOID)
2160+
return DirectFunctionCall1(byteain, CStringGetDatum(str));
21892161
else
21902162
return DirectFunctionCall1(textin, CStringGetDatum(str));
21912163
}

src/backend/utils/adt/like.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/like.c,v 1.51 2002/08/29 07:22:26 ishii Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/like.c,v 1.52 2002/09/02 06:22:19 momjian Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -242,7 +242,7 @@ Datum
242242
bytealike(PG_FUNCTION_ARGS)
243243
{
244244
bytea *str = PG_GETARG_BYTEA_P(0);
245-
text *pat = PG_GETARG_TEXT_P(1);
245+
bytea *pat = PG_GETARG_BYTEA_P(1);
246246
bool result;
247247
unsigned char *s,
248248
*p;
@@ -263,7 +263,7 @@ Datum
263263
byteanlike(PG_FUNCTION_ARGS)
264264
{
265265
bytea *str = PG_GETARG_BYTEA_P(0);
266-
text *pat = PG_GETARG_TEXT_P(1);
266+
bytea *pat = PG_GETARG_BYTEA_P(1);
267267
bool result;
268268
unsigned char *s,
269269
*p;

0 commit comments

Comments
 (0)