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

Commit1b393f4

Browse files
committed
Avoid detoast in texteq/textne/byteaeq/byteane for unequal-length strings.
We can get the length of a compressed or out-of-line datum without actuallydetoasting it. If the lengths of two strings are unequal, we can thenconclude they are unequal without detoasting. That saves considerable workin an admittedly less-common case, without costing anything much when theoptimization doesn't apply.Noah Misch
1 parent6e1726d commit1b393f4

File tree

1 file changed

+75
-41
lines changed

1 file changed

+75
-41
lines changed

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

Lines changed: 75 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,45 +1451,63 @@ text_cmp(text *arg1, text *arg2)
14511451
Datum
14521452
texteq(PG_FUNCTION_ARGS)
14531453
{
1454-
text*arg1=PG_GETARG_TEXT_PP(0);
1455-
text*arg2=PG_GETARG_TEXT_PP(1);
1454+
Datumarg1=PG_GETARG_DATUM(0);
1455+
Datumarg2=PG_GETARG_DATUM(1);
14561456
boolresult;
1457+
Sizelen1,
1458+
len2;
14571459

14581460
/*
14591461
* Since we only care about equality or not-equality, we can avoid all the
1460-
* expense of strcoll() here, and just do bitwise comparison.
1462+
* expense of strcoll() here, and just do bitwise comparison. In fact,
1463+
* we don't even have to do a bitwise comparison if we can show the
1464+
* lengths of the strings are unequal; which might save us from having
1465+
* to detoast one or both values.
14611466
*/
1462-
if (VARSIZE_ANY_EXHDR(arg1)!=VARSIZE_ANY_EXHDR(arg2))
1467+
len1=toast_raw_datum_size(arg1);
1468+
len2=toast_raw_datum_size(arg2);
1469+
if (len1!=len2)
14631470
result= false;
14641471
else
1465-
result= (memcmp(VARDATA_ANY(arg1),VARDATA_ANY(arg2),
1466-
VARSIZE_ANY_EXHDR(arg1))==0);
1472+
{
1473+
text*targ1=DatumGetTextPP(arg1);
1474+
text*targ2=DatumGetTextPP(arg2);
14671475

1468-
PG_FREE_IF_COPY(arg1,0);
1469-
PG_FREE_IF_COPY(arg2,1);
1476+
result= (memcmp(VARDATA_ANY(targ1),VARDATA_ANY(targ2),
1477+
len1-VARHDRSZ)==0);
1478+
1479+
PG_FREE_IF_COPY(targ1,0);
1480+
PG_FREE_IF_COPY(targ2,1);
1481+
}
14701482

14711483
PG_RETURN_BOOL(result);
14721484
}
14731485

14741486
Datum
14751487
textne(PG_FUNCTION_ARGS)
14761488
{
1477-
text*arg1=PG_GETARG_TEXT_PP(0);
1478-
text*arg2=PG_GETARG_TEXT_PP(1);
1489+
Datumarg1=PG_GETARG_DATUM(0);
1490+
Datumarg2=PG_GETARG_DATUM(1);
14791491
boolresult;
1492+
Sizelen1,
1493+
len2;
14801494

1481-
/*
1482-
* Since we only care about equality or not-equality, we can avoid all the
1483-
* expense of strcoll() here, and just do bitwise comparison.
1484-
*/
1485-
if (VARSIZE_ANY_EXHDR(arg1)!=VARSIZE_ANY_EXHDR(arg2))
1495+
/* See comment in texteq() */
1496+
len1=toast_raw_datum_size(arg1);
1497+
len2=toast_raw_datum_size(arg2);
1498+
if (len1!=len2)
14861499
result= true;
14871500
else
1488-
result= (memcmp(VARDATA_ANY(arg1),VARDATA_ANY(arg2),
1489-
VARSIZE_ANY_EXHDR(arg1))!=0);
1501+
{
1502+
text*targ1=DatumGetTextPP(arg1);
1503+
text*targ2=DatumGetTextPP(arg2);
14901504

1491-
PG_FREE_IF_COPY(arg1,0);
1492-
PG_FREE_IF_COPY(arg2,1);
1505+
result= (memcmp(VARDATA_ANY(targ1),VARDATA_ANY(targ2),
1506+
len1-VARHDRSZ)!=0);
1507+
1508+
PG_FREE_IF_COPY(targ1,0);
1509+
PG_FREE_IF_COPY(targ2,1);
1510+
}
14931511

14941512
PG_RETURN_BOOL(result);
14951513
}
@@ -2358,47 +2376,63 @@ SplitIdentifierString(char *rawstring, char separator,
23582376
Datum
23592377
byteaeq(PG_FUNCTION_ARGS)
23602378
{
2361-
bytea*arg1=PG_GETARG_BYTEA_PP(0);
2362-
bytea*arg2=PG_GETARG_BYTEA_PP(1);
2363-
intlen1,
2364-
len2;
2379+
Datumarg1=PG_GETARG_DATUM(0);
2380+
Datumarg2=PG_GETARG_DATUM(1);
23652381
boolresult;
2382+
Sizelen1,
2383+
len2;
23662384

2367-
len1=VARSIZE_ANY_EXHDR(arg1);
2368-
len2=VARSIZE_ANY_EXHDR(arg2);
2369-
2370-
/* fast path for different-length inputs */
2385+
/*
2386+
* We can use a fast path for unequal lengths, which might save us from
2387+
* having to detoast one or both values.
2388+
*/
2389+
len1=toast_raw_datum_size(arg1);
2390+
len2=toast_raw_datum_size(arg2);
23712391
if (len1!=len2)
23722392
result= false;
23732393
else
2374-
result= (memcmp(VARDATA_ANY(arg1),VARDATA_ANY(arg2),len1)==0);
2394+
{
2395+
bytea*barg1=DatumGetByteaPP(arg1);
2396+
bytea*barg2=DatumGetByteaPP(arg2);
23752397

2376-
PG_FREE_IF_COPY(arg1,0);
2377-
PG_FREE_IF_COPY(arg2,1);
2398+
result= (memcmp(VARDATA_ANY(barg1),VARDATA_ANY(barg2),
2399+
len1-VARHDRSZ)==0);
2400+
2401+
PG_FREE_IF_COPY(barg1,0);
2402+
PG_FREE_IF_COPY(barg2,1);
2403+
}
23782404

23792405
PG_RETURN_BOOL(result);
23802406
}
23812407

23822408
Datum
23832409
byteane(PG_FUNCTION_ARGS)
23842410
{
2385-
bytea*arg1=PG_GETARG_BYTEA_PP(0);
2386-
bytea*arg2=PG_GETARG_BYTEA_PP(1);
2387-
intlen1,
2388-
len2;
2411+
Datumarg1=PG_GETARG_DATUM(0);
2412+
Datumarg2=PG_GETARG_DATUM(1);
23892413
boolresult;
2414+
Sizelen1,
2415+
len2;
23902416

2391-
len1=VARSIZE_ANY_EXHDR(arg1);
2392-
len2=VARSIZE_ANY_EXHDR(arg2);
2393-
2394-
/* fast path for different-length inputs */
2417+
/*
2418+
* We can use a fast path for unequal lengths, which might save us from
2419+
* having to detoast one or both values.
2420+
*/
2421+
len1=toast_raw_datum_size(arg1);
2422+
len2=toast_raw_datum_size(arg2);
23952423
if (len1!=len2)
23962424
result= true;
23972425
else
2398-
result= (memcmp(VARDATA_ANY(arg1),VARDATA_ANY(arg2),len1)!=0);
2426+
{
2427+
bytea*barg1=DatumGetByteaPP(arg1);
2428+
bytea*barg2=DatumGetByteaPP(arg2);
23992429

2400-
PG_FREE_IF_COPY(arg1,0);
2401-
PG_FREE_IF_COPY(arg2,1);
2430+
result= (memcmp(VARDATA_ANY(barg1),VARDATA_ANY(barg2),
2431+
len1-VARHDRSZ)!=0);
2432+
2433+
PG_FREE_IF_COPY(barg1,0);
2434+
PG_FREE_IF_COPY(barg2,1);
2435+
}
24022436

24032437
PG_RETURN_BOOL(result);
24042438
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp