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,
9797static bool match_special_index_operator (Expr * clause ,Oid opclass ,
9898bool indexkey_on_left );
9999static List * prefix_quals (Var * leftop ,Oid expr_op ,
100- char * prefix ,Pattern_Prefix_Status pstatus );
100+ Const * prefix ,Pattern_Prefix_Status pstatus );
101101static List * network_prefix_quals (Var * leftop ,Oid expr_op ,Datum rightop );
102102static Oid find_operator (const char * opname ,Oid datatype );
103103static Datum string_to_datum (const char * str ,Oid datatype );
@@ -1675,10 +1675,9 @@ match_special_index_operator(Expr *clause, Oid opclass,
16751675Var * leftop ,
16761676* rightop ;
16771677Oid 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,
16971696if (!IsA (rightop ,Const )||
16981697((Const * )rightop )-> constisnull )
16991698return false;
1700- constvalue = (( Const * )rightop ) -> constvalue ;
1699+ patt = (Const * )rightop ;
17011700
17021701switch (expr_op )
17031702{
17041703case OID_TEXT_LIKE_OP :
17051704case OID_BPCHAR_LIKE_OP :
17061705case OID_VARCHAR_LIKE_OP :
17071706case OID_NAME_LIKE_OP :
1707+ /* the right-hand const is type text for all of these */
17081708if (locale_is_like_safe ())
1709- {
1710- /* the right-hand const is type text for all of these */
1711- patt = DatumGetCString (DirectFunctionCall1 (textout ,
1712- constvalue ));
17131709isIndexable = 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 ;
17191716break ;
17201717
17211718case OID_TEXT_ICLIKE_OP :
17221719case OID_BPCHAR_ICLIKE_OP :
17231720case OID_VARCHAR_ICLIKE_OP :
17241721case OID_NAME_ICLIKE_OP :
1722+ /* the right-hand const is type text for all of these */
17251723if (locale_is_like_safe ())
1726- {
1727- /* the right-hand const is type text for all of these */
1728- patt = DatumGetCString (DirectFunctionCall1 (textout ,
1729- constvalue ));
17301724isIndexable = pattern_fixed_prefix (patt ,Pattern_Type_Like_IC ,
17311725& prefix ,& rest )!= Pattern_Prefix_None ;
1732- if (prefix )
1733- pfree (prefix );
1734- pfree (patt );
1735- }
17361726break ;
17371727
17381728case OID_TEXT_REGEXEQ_OP :
17391729case OID_BPCHAR_REGEXEQ_OP :
17401730case OID_VARCHAR_REGEXEQ_OP :
17411731case OID_NAME_REGEXEQ_OP :
1732+ /* the right-hand const is type text for all of these */
17421733if (locale_is_like_safe ())
1743- {
1744- /* the right-hand const is type text for all of these */
1745- patt = DatumGetCString (DirectFunctionCall1 (textout ,
1746- constvalue ));
17471734isIndexable = pattern_fixed_prefix (patt ,Pattern_Type_Regex ,
17481735& prefix ,& rest )!= Pattern_Prefix_None ;
1749- if (prefix )
1750- pfree (prefix );
1751- pfree (patt );
1752- }
17531736break ;
17541737
17551738case OID_TEXT_ICREGEXEQ_OP :
17561739case OID_BPCHAR_ICREGEXEQ_OP :
17571740case OID_VARCHAR_ICREGEXEQ_OP :
17581741case OID_NAME_ICREGEXEQ_OP :
1742+ /* the right-hand const is type text for all of these */
17591743if (locale_is_like_safe ())
1760- {
1761- /* the right-hand const is type text for all of these */
1762- patt = DatumGetCString (DirectFunctionCall1 (textout ,
1763- constvalue ));
17641744isIndexable = pattern_fixed_prefix (patt ,Pattern_Type_Regex_IC ,
17651745& prefix ,& rest )!= Pattern_Prefix_None ;
1766- if (prefix )
1767- pfree (prefix );
1768- pfree (patt );
1769- }
17701746break ;
17711747
17721748case OID_INET_SUB_OP :
@@ -1777,6 +1753,12 @@ match_special_index_operator(Expr *clause, Oid opclass,
17771753break ;
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 */
17811763if (!isIndexable )
17821764return false;
@@ -1798,6 +1780,12 @@ match_special_index_operator(Expr *clause, Oid opclass,
17981780isIndexable = false;
17991781break ;
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+
18011789case OID_BPCHAR_LIKE_OP :
18021790case OID_BPCHAR_ICLIKE_OP :
18031791case OID_BPCHAR_REGEXEQ_OP :
@@ -1867,10 +1855,9 @@ expand_indexqual_conditions(List *indexquals)
18671855Var * leftop = get_leftop (clause );
18681856Var * rightop = get_rightop (clause );
18691857Oid 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 ;
18741861Pattern_Prefix_Status pstatus ;
18751862
18761863switch (expr_op )
@@ -1885,82 +1872,57 @@ expand_indexqual_conditions(List *indexquals)
18851872case OID_BPCHAR_LIKE_OP :
18861873case OID_VARCHAR_LIKE_OP :
18871874case 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 :
18921876pstatus = pattern_fixed_prefix (patt ,Pattern_Type_Like ,
18931877& prefix ,& rest );
18941878resultquals = nconc (resultquals ,
18951879prefix_quals (leftop ,expr_op ,
18961880prefix ,pstatus ));
1897- if (prefix )
1898- pfree (prefix );
1899- pfree (patt );
19001881break ;
19011882
19021883case OID_TEXT_ICLIKE_OP :
19031884case OID_BPCHAR_ICLIKE_OP :
19041885case OID_VARCHAR_ICLIKE_OP :
19051886case 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 ));
19101888pstatus = pattern_fixed_prefix (patt ,Pattern_Type_Like_IC ,
19111889& prefix ,& rest );
19121890resultquals = nconc (resultquals ,
19131891prefix_quals (leftop ,expr_op ,
19141892prefix ,pstatus ));
1915- if (prefix )
1916- pfree (prefix );
1917- pfree (patt );
19181893break ;
19191894
19201895case OID_TEXT_REGEXEQ_OP :
19211896case OID_BPCHAR_REGEXEQ_OP :
19221897case OID_VARCHAR_REGEXEQ_OP :
19231898case 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 ));
19281900pstatus = pattern_fixed_prefix (patt ,Pattern_Type_Regex ,
19291901& prefix ,& rest );
19301902resultquals = nconc (resultquals ,
19311903prefix_quals (leftop ,expr_op ,
19321904prefix ,pstatus ));
1933- if (prefix )
1934- pfree (prefix );
1935- pfree (patt );
19361905break ;
19371906
19381907case OID_TEXT_ICREGEXEQ_OP :
19391908case OID_BPCHAR_ICREGEXEQ_OP :
19401909case OID_VARCHAR_ICREGEXEQ_OP :
19411910case 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 ));
19461912pstatus = pattern_fixed_prefix (patt ,Pattern_Type_Regex_IC ,
19471913& prefix ,& rest );
19481914resultquals = nconc (resultquals ,
19491915prefix_quals (leftop ,expr_op ,
19501916prefix ,pstatus ));
1951- if (prefix )
1952- pfree (prefix );
1953- pfree (patt );
19541917break ;
19551918
19561919case OID_INET_SUB_OP :
19571920case OID_INET_SUBEQ_OP :
19581921case OID_CIDR_SUB_OP :
19591922case OID_CIDR_SUBEQ_OP :
1960- constvalue = ((Const * )rightop )-> constvalue ;
19611923resultquals = nconc (resultquals ,
19621924network_prefix_quals (leftop ,expr_op ,
1963- constvalue ));
1925+ patt -> constvalue ));
19641926break ;
19651927
19661928default :
@@ -1980,15 +1942,16 @@ expand_indexqual_conditions(List *indexquals)
19801942 */
19811943static List *
19821944prefix_quals (Var * leftop ,Oid expr_op ,
1983- char * prefix ,Pattern_Prefix_Status pstatus )
1945+ Const * prefix_const ,Pattern_Prefix_Status pstatus )
19841946{
19851947List * result ;
19861948Oid datatype ;
19871949Oid oproid ;
1950+ char * prefix ;
19881951Const * con ;
19891952Oper * op ;
19901953Expr * expr ;
1991- char * greaterstr ;
1954+ Const * greaterstr = NULL ;
19921955
19931956Assert (pstatus != Pattern_Prefix_None );
19941957
@@ -2001,6 +1964,10 @@ prefix_quals(Var *leftop, Oid expr_op,
20011964datatype = TEXTOID ;
20021965break ;
20031966
1967+ case OID_BYTEA_LIKE_OP :
1968+ datatype = BYTEAOID ;
1969+ break ;
1970+
20041971case OID_BPCHAR_LIKE_OP :
20051972case OID_BPCHAR_ICLIKE_OP :
20061973case OID_BPCHAR_REGEXEQ_OP :
@@ -2027,6 +1994,11 @@ prefix_quals(Var *leftop, Oid expr_op,
20271994return 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 );
20642036if (greaterstr )
20652037{
20662038oproid = find_operator ("<" ,datatype );
20672039if (oproid == InvalidOid )
20682040elog (ERROR ,"prefix_quals: no < operator for type %u" ,datatype );
2069- con = string_to_const (greaterstr ,datatype );
20702041op = makeOper (oproid ,InvalidOid ,BOOLOID , false);
2071- expr = make_opclause (op ,leftop , (Var * )con );
2042+ expr = make_opclause (op ,leftop , (Var * )greaterstr );
20722043result = lappend (result ,expr );
2073- pfree (greaterstr );
20742044}
20752045
20762046return result ;
@@ -2186,6 +2156,8 @@ string_to_datum(const char *str, Oid datatype)
21862156 */
21872157if (datatype == NAMEOID )
21882158return DirectFunctionCall1 (namein ,CStringGetDatum (str ));
2159+ else if (datatype == BYTEAOID )
2160+ return DirectFunctionCall1 (byteain ,CStringGetDatum (str ));
21892161else
21902162return DirectFunctionCall1 (textin ,CStringGetDatum (str ));
21912163}