Re: [PATCHES] [HACKERS] bytea, index and like operator again and detailed report

2003-12-06 Thread Joe Conway
Alvar Freude wrote:
-- Joe Conway [EMAIL PROTECTED] wrote:
Please try the attached patch and let me know how it works for you. It is
against cvs HEAD, but should apply OK to 7.4.
so, I checked it with my database. 
It looks good, all checks I made are OK.
The attached fixes the bytea-like bug found by Alvar -- as well as some 
others I found while working on it. I would like to apply this evening 
so that it can be in the 7.4.1 release. Any objections?

Thanks,

Joe
Index: src/backend/utils/adt/selfuncs.c
===
RCS file: /opt/src/cvs/pgsql-server/src/backend/utils/adt/selfuncs.c,v
retrieving revision 1.149
diff -c -r1.149 selfuncs.c
*** src/backend/utils/adt/selfuncs.c29 Nov 2003 19:51:59 -  1.149
--- src/backend/utils/adt/selfuncs.c5 Dec 2003 19:42:39 -
***
*** 184,189 
--- 184,190 
  static Selectivity pattern_selectivity(Const *patt, Pattern_Type ptype);
  static Datum string_to_datum(const char *str, Oid datatype);
  static Const *string_to_const(const char *str, Oid datatype);
+ static Const *string_to_bytea_const(const char *str, size_t str_len);
  
  
  /*
***
*** 3135,3154 
}
else
{
!   patt = DatumGetCString(DirectFunctionCall1(byteaout, 
patt_const-constvalue));
!   pattlen = toast_raw_datum_size(patt_const-constvalue) - VARHDRSZ;
}
  
match = palloc(pattlen + 1);
match_pos = 0;
- 
for (pos = 0; pos  pattlen; pos++)
{
/* % and _ are wildcard characters in LIKE */
if (patt[pos] == '%' ||
patt[pos] == '_')
break;
!   /* Backslash quotes the next character */
if (patt[pos] == '\\')
{
pos++;
--- 3136,3166 
}
else
{
!   bytea   *bstr = DatumGetByteaP(patt_const-constvalue);
! 
!   pattlen = VARSIZE(bstr) - VARHDRSZ;
!   if (pattlen  0)
!   {
!   patt = (char *) palloc(pattlen);
!   memcpy(patt, VARDATA(bstr), pattlen);
!   }
!   else
!   patt = NULL;
! 
!   if ((Pointer) bstr != DatumGetPointer(patt_const-constvalue))
!   pfree(bstr);
}
  
match = palloc(pattlen + 1);
match_pos = 0;
for (pos = 0; pos  pattlen; pos++)
{
/* % and _ are wildcard characters in LIKE */
if (patt[pos] == '%' ||
patt[pos] == '_')
break;
! 
!   /* Backslash escapes the next character */
if (patt[pos] == '\\')
{
pos++;
***
*** 3174,3183 
match[match_pos] = '\0';
rest = patt[pos];
  
!   *prefix_const = string_to_const(match, typeid);
!   *rest_const = string_to_const(rest, typeid);
  
!   pfree(patt);
pfree(match);
  
/* in LIKE, an empty pattern is an exact match! */
--- 3186,3204 
match[match_pos] = '\0';
rest = patt[pos];
  
!   if (typeid != BYTEAOID)
!   {
!   *prefix_const = string_to_const(match, typeid);
!   *rest_const = string_to_const(rest, typeid);
!   }
!   else
!   {
!   *prefix_const = string_to_bytea_const(match, match_pos);
!   *rest_const = string_to_bytea_const(rest, pattlen - match_pos);
!   }
  
!   if (patt != NULL)
!   pfree(patt);
pfree(match);
  
/* in LIKE, an empty pattern is an exact match! */
***
*** 3500,3508 
}
else
{
!   patt = DatumGetCString(DirectFunctionCall1(byteaout, 
patt_const-constvalue));
!   pattlen = toast_raw_datum_size(patt_const-constvalue) - VARHDRSZ;
}
  
/* Skip any leading %; it's already factored into initial sel */
start = (*patt == '%') ? 1 : 0;
--- 3521,3542 
}
else
{
!   bytea   *bstr = DatumGetByteaP(patt_const-constvalue);
! 
!   pattlen = VARSIZE(bstr) - VARHDRSZ;
!   if (pattlen  0)
!   {
!   patt = (char *) palloc(pattlen);
!   memcpy(patt, VARDATA(bstr), pattlen);
!   }
!   else
!   patt = NULL;
! 
!   if ((Pointer) bstr != DatumGetPointer(patt_const-constvalue))
!   pfree(bstr);
}
+   /* patt should never be NULL in practice */
+   Assert(patt != NULL);
  
/* Skip any leading %; it's already factored into initial sel */
start = (*patt == '%') ? 1 : 0;
***
*** 3693,3700 
  
  /*
   * Try to generate a string greater than the given string or any

Re: [PATCHES] [HACKERS] bytea, index and like operator again and detailed report

2003-12-06 Thread Tom Lane
Joe Conway [EMAIL PROTECTED] writes:
 ! *prefix_const = string_to_bytea_const(match, match_pos);
 ! *rest_const = string_to_bytea_const(rest, pattlen - match_pos);

I think that should be pattlen - pos not pattlen - match_pos, no?

Otherwise it looks reasonable ...

regards, tom lane

---(end of broadcast)---
TIP 8: explain analyze is your friend