Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit53e7c13

Browse files
committed
Repair indexed bytea like operations, and related selectivity
functionality. Per bug report by Alvar Freude:http://archives.postgresql.org/pgsql-bugs/2003-12/msg00022.php
1 parent7bb11a9 commit53e7c13

File tree

1 file changed

+87
-24
lines changed

1 file changed

+87
-24
lines changed

‎src/backend/utils/adt/selfuncs.c

Lines changed: 87 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.149 2003/11/29 19:51:59 pgsql Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.150 2003/12/07 04:14:10 joe Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -184,6 +184,7 @@ static Selectivity prefix_selectivity(Query *root, Var *var,
184184
staticSelectivitypattern_selectivity(Const*patt,Pattern_Typeptype);
185185
staticDatumstring_to_datum(constchar*str,Oiddatatype);
186186
staticConst*string_to_const(constchar*str,Oiddatatype);
187+
staticConst*string_to_bytea_const(constchar*str,size_tstr_len);
187188

188189

189190
/*
@@ -3135,20 +3136,31 @@ like_fixed_prefix(Const *patt_const, bool case_insensitive,
31353136
}
31363137
else
31373138
{
3138-
patt=DatumGetCString(DirectFunctionCall1(byteaout,patt_const->constvalue));
3139-
pattlen=toast_raw_datum_size(patt_const->constvalue)-VARHDRSZ;
3139+
bytea*bstr=DatumGetByteaP(patt_const->constvalue);
3140+
3141+
pattlen=VARSIZE(bstr)-VARHDRSZ;
3142+
if (pattlen>0)
3143+
{
3144+
patt= (char*)palloc(pattlen);
3145+
memcpy(patt,VARDATA(bstr),pattlen);
3146+
}
3147+
else
3148+
patt=NULL;
3149+
3150+
if ((Pointer)bstr!=DatumGetPointer(patt_const->constvalue))
3151+
pfree(bstr);
31403152
}
31413153

31423154
match=palloc(pattlen+1);
31433155
match_pos=0;
3144-
31453156
for (pos=0;pos<pattlen;pos++)
31463157
{
31473158
/* % and _ are wildcard characters in LIKE */
31483159
if (patt[pos]=='%'||
31493160
patt[pos]=='_')
31503161
break;
3151-
/* Backslash quotes the next character */
3162+
3163+
/* Backslash escapes the next character */
31523164
if (patt[pos]=='\\')
31533165
{
31543166
pos++;
@@ -3174,10 +3186,19 @@ like_fixed_prefix(Const *patt_const, bool case_insensitive,
31743186
match[match_pos]='\0';
31753187
rest=&patt[pos];
31763188

3177-
*prefix_const=string_to_const(match,typeid);
3178-
*rest_const=string_to_const(rest,typeid);
3189+
if (typeid!=BYTEAOID)
3190+
{
3191+
*prefix_const=string_to_const(match,typeid);
3192+
*rest_const=string_to_const(rest,typeid);
3193+
}
3194+
else
3195+
{
3196+
*prefix_const=string_to_bytea_const(match,match_pos);
3197+
*rest_const=string_to_bytea_const(rest,pattlen-pos);
3198+
}
31793199

3180-
pfree(patt);
3200+
if (patt!=NULL)
3201+
pfree(patt);
31813202
pfree(match);
31823203

31833204
/* in LIKE, an empty pattern is an exact match! */
@@ -3500,9 +3521,22 @@ like_selectivity(Const *patt_const, bool case_insensitive)
35003521
}
35013522
else
35023523
{
3503-
patt=DatumGetCString(DirectFunctionCall1(byteaout,patt_const->constvalue));
3504-
pattlen=toast_raw_datum_size(patt_const->constvalue)-VARHDRSZ;
3524+
bytea*bstr=DatumGetByteaP(patt_const->constvalue);
3525+
3526+
pattlen=VARSIZE(bstr)-VARHDRSZ;
3527+
if (pattlen>0)
3528+
{
3529+
patt= (char*)palloc(pattlen);
3530+
memcpy(patt,VARDATA(bstr),pattlen);
3531+
}
3532+
else
3533+
patt=NULL;
3534+
3535+
if ((Pointer)bstr!=DatumGetPointer(patt_const->constvalue))
3536+
pfree(bstr);
35053537
}
3538+
/* patt should never be NULL in practice */
3539+
Assert(patt!=NULL);
35063540

35073541
/* Skip any leading %; it's already factored into initial sel */
35083542
start= (*patt=='%') ?1 :0;
@@ -3693,8 +3727,8 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
36933727

36943728
/*
36953729
* Try to generate a string greater than the given string or any
3696-
* string it is a prefix of. If successful, return a palloc'd string;
3697-
* else return NULL.
3730+
* string it is a prefix of. If successful, return a palloc'd string
3731+
*in the form of a Const pointer;else return NULL.
36983732
*
36993733
* The key requirement here is that given a prefix string, say "foo",
37003734
* we must be able to generate another string "fop" that is greater
@@ -3712,27 +3746,38 @@ Const *
37123746
make_greater_string(constConst*str_const)
37133747
{
37143748
Oiddatatype=str_const->consttype;
3715-
char*str;
37163749
char*workstr;
37173750
intlen;
37183751

37193752
/* Get the string and a modifiable copy */
37203753
if (datatype==NAMEOID)
37213754
{
3722-
str=DatumGetCString(DirectFunctionCall1(nameout,str_const->constvalue));
3723-
len=strlen(str);
3755+
workstr=DatumGetCString(DirectFunctionCall1(nameout,
3756+
str_const->constvalue));
3757+
len=strlen(workstr);
37243758
}
37253759
elseif (datatype==BYTEAOID)
37263760
{
3727-
str=DatumGetCString(DirectFunctionCall1(byteaout,str_const->constvalue));
3728-
len=toast_raw_datum_size(str_const->constvalue)-VARHDRSZ;
3761+
bytea*bstr=DatumGetByteaP(str_const->constvalue);
3762+
3763+
len=VARSIZE(bstr)-VARHDRSZ;
3764+
if (len>0)
3765+
{
3766+
workstr= (char*)palloc(len);
3767+
memcpy(workstr,VARDATA(bstr),len);
3768+
}
3769+
else
3770+
workstr=NULL;
3771+
3772+
if ((Pointer)bstr!=DatumGetPointer(str_const->constvalue))
3773+
pfree(bstr);
37293774
}
37303775
else
37313776
{
3732-
str=DatumGetCString(DirectFunctionCall1(textout,str_const->constvalue));
3733-
len=strlen(str);
3777+
workstr=DatumGetCString(DirectFunctionCall1(textout,
3778+
str_const->constvalue));
3779+
len=strlen(workstr);
37343780
}
3735-
workstr=pstrdup(str);
37363781

37373782
while (len>0)
37383783
{
@@ -3747,9 +3792,11 @@ make_greater_string(const Const *str_const)
37473792
Const*workstr_const;
37483793

37493794
(*lastchar)++;
3750-
workstr_const=string_to_const(workstr,datatype);
3795+
if (datatype!=BYTEAOID)
3796+
workstr_const=string_to_const(workstr,datatype);
3797+
else
3798+
workstr_const=string_to_bytea_const(workstr,len);
37513799

3752-
pfree(str);
37533800
pfree(workstr);
37543801
returnworkstr_const;
37553802
}
@@ -3771,8 +3818,8 @@ make_greater_string(const Const *str_const)
37713818
}
37723819

37733820
/* Failed... */
3774-
pfree(str);
3775-
pfree(workstr);
3821+
if (workstr!=NULL)
3822+
pfree(workstr);
37763823

37773824
return (Const*)NULL;
37783825
}
@@ -3811,6 +3858,22 @@ string_to_const(const char *str, Oid datatype)
38113858
conval, false, false);
38123859
}
38133860

3861+
/*
3862+
* Generate a Const node of bytea type from a binary C string and a length.
3863+
*/
3864+
staticConst*
3865+
string_to_bytea_const(constchar*str,size_tstr_len)
3866+
{
3867+
bytea*bstr=palloc(VARHDRSZ+str_len);
3868+
Datumconval;
3869+
3870+
memcpy(VARDATA(bstr),str,str_len);
3871+
VARATT_SIZEP(bstr)=VARHDRSZ+str_len;
3872+
conval=PointerGetDatum(bstr);
3873+
3874+
returnmakeConst(BYTEAOID,-1,conval, false, false);
3875+
}
3876+
38143877
/*-------------------------------------------------------------------------
38153878
*
38163879
* Index cost estimation functions

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp