@ -143,6 +143,14 @@ texticregexeq_support(PG_FUNCTION_ARGS)
PG_RETURN_POINTER ( like_regex_support ( rawreq , Pattern_Type_Regex_IC ) ) ;
}
Datum
text_starts_with_support ( PG_FUNCTION_ARGS )
{
Node * rawreq = ( Node * ) PG_GETARG_POINTER ( 0 ) ;
PG_RETURN_POINTER ( like_regex_support ( rawreq , Pattern_Type_Prefix ) ) ;
}
/* Common code for the above */
static Node *
like_regex_support ( Node * rawreq , Pattern_Type ptype )
@ -246,6 +254,7 @@ match_pattern_prefix(Node *leftop,
Oid eqopr ;
Oid ltopr ;
Oid geopr ;
Oid preopr = InvalidOid ;
bool collation_aware ;
Expr * expr ;
FmgrInfo ltproc ;
@ -302,12 +311,20 @@ match_pattern_prefix(Node *leftop,
switch ( ldatatype )
{
case TEXTOID :
if ( opfamily = = TEXT_PATTERN_BTREE_FAM_OID | |
opfamily = = TEXT_SPGIST_FAM_OID )
if ( opfamily = = TEXT_PATTERN_BTREE_FAM_OID )
{
eqopr = TextEqualOperator ;
ltopr = TextPatternLessOperator ;
geopr = TextPatternGreaterEqualOperator ;
collation_aware = false ;
}
else if ( opfamily = = TEXT_SPGIST_FAM_OID )
{
eqopr = TextEqualOperator ;
ltopr = TextPatternLessOperator ;
geopr = TextPatternGreaterEqualOperator ;
/* This opfamily has direct support for prefixing */
preopr = TextPrefixOperator ;
collation_aware = false ;
}
else
@ -360,20 +377,6 @@ match_pattern_prefix(Node *leftop,
return NIL ;
}
/*
* If necessary , verify that the index ' s collation behavior is compatible .
* For an exact - match case , we don ' t have to be picky . Otherwise , insist
* that the index collation be " C " . Note that here we are looking at the
* index ' s collation , not the expression ' s collation - - this test is * not *
* dependent on the LIKE / regex operator ' s collation .
*/
if ( collation_aware )
{
if ( ! ( pstatus = = Pattern_Prefix_Exact | |
lc_collate_is_c ( indexcollation ) ) )
return NIL ;
}
/*
* If necessary , coerce the prefix constant to the right type . The given
* prefix constant is either text or bytea type , therefore the only case
@ -409,8 +412,31 @@ match_pattern_prefix(Node *leftop,
}
/*
* Otherwise , we have a nonempty required prefix of the values .
*
* Otherwise , we have a nonempty required prefix of the values . Some
* opclasses support prefix checks directly , otherwise we ' ll try to
* generate a range constraint .
*/
if ( OidIsValid ( preopr ) & & op_in_opfamily ( preopr , opfamily ) )
{
expr = make_opclause ( preopr , BOOLOID , false ,
( Expr * ) leftop , ( Expr * ) prefix ,
InvalidOid , indexcollation ) ;
result = list_make1 ( expr ) ;
return result ;
}
/*
* Since we need a range constraint , it ' s only going to work reliably if
* the index is collation - insensitive or has " C " collation . Note that
* here we are looking at the index ' s collation , not the expression ' s
* collation - - this test is * not * dependent on the LIKE / regex operator ' s
* collation .
*/
if ( collation_aware & &
! lc_collate_is_c ( indexcollation ) )
return NIL ;
/*
* We can always say " x >= prefix " .
*/
if ( ! op_in_opfamily ( geopr , opfamily ) )
@ -1165,7 +1191,6 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype, Oid collation,
case Pattern_Type_Prefix :
/* Prefix type work is trivial. */
result = Pattern_Prefix_Partial ;
* rest_selec = 1.0 ; /* all */
* prefix = makeConst ( patt - > consttype ,
patt - > consttypmod ,
patt - > constcollid ,
@ -1175,6 +1200,8 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype, Oid collation,
patt - > constlen ) ,
patt - > constisnull ,
patt - > constbyval ) ;
if ( rest_selec ! = NULL )
* rest_selec = 1.0 ; /* all */
break ;
default :
elog ( ERROR , " unrecognized ptype: %d " , ( int ) ptype ) ;