Skip to content

Commit 2ece7c0

Browse files
committed
Add text-vs-name cross-type operators, and unify name_ops with text_ops.
Now that name comparison has effectively the same behavior as text comparison, we might as well merge the name_ops opfamily into text_ops, allowing cross-type comparisons to be processed without forcing a datatype coercion first. We need do little more than add cross-type operators to make the opfamily complete, and fix one or two places in the planner that assumed text_ops was a single-datatype opfamily. I chose to unify hash name_ops into hash text_ops as well, since the types have compatible hashing semantics. This allows marking the new cross-type equality operators as oprcanhash. (Note: this doesn't remove the name_ops opclasses, so there's no breakage of index definitions. Those opclasses are just reparented into the text_ops opfamily.) Discussion: https://postgr.es/m/15938.1544377821@sss.pgh.pa.us
1 parent 586b98f commit 2ece7c0

File tree

13 files changed

+385
-85
lines changed

13 files changed

+385
-85
lines changed

src/backend/optimizer/path/indxpath.c

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "catalog/pg_opfamily.h"
2626
#include "catalog/pg_type.h"
2727
#include "nodes/makefuncs.h"
28+
#include "nodes/nodeFuncs.h"
2829
#include "optimizer/clauses.h"
2930
#include "optimizer/cost.h"
3031
#include "optimizer/pathnode.h"
@@ -3518,6 +3519,10 @@ match_special_index_operator(Expr *clause, Oid opfamily, Oid idxcollation,
35183519
case OID_TEXT_ICLIKE_OP:
35193520
case OID_TEXT_REGEXEQ_OP:
35203521
case OID_TEXT_ICREGEXEQ_OP:
3522+
case OID_NAME_LIKE_OP:
3523+
case OID_NAME_ICLIKE_OP:
3524+
case OID_NAME_REGEXEQ_OP:
3525+
case OID_NAME_ICREGEXEQ_OP:
35213526
isIndexable =
35223527
(opfamily == TEXT_PATTERN_BTREE_FAM_OID) ||
35233528
(opfamily == TEXT_SPGIST_FAM_OID) ||
@@ -3537,14 +3542,6 @@ match_special_index_operator(Expr *clause, Oid opfamily, Oid idxcollation,
35373542
lc_collate_is_c(idxcollation)));
35383543
break;
35393544

3540-
case OID_NAME_LIKE_OP:
3541-
case OID_NAME_ICLIKE_OP:
3542-
case OID_NAME_REGEXEQ_OP:
3543-
case OID_NAME_ICREGEXEQ_OP:
3544-
/* name uses locale-insensitive sorting */
3545-
isIndexable = (opfamily == NAME_BTREE_FAM_OID);
3546-
break;
3547-
35483545
case OID_BYTEA_LIKE_OP:
35493546
isIndexable = (opfamily == BYTEA_BTREE_FAM_OID);
35503547
break;
@@ -4097,7 +4094,8 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
40974094
Const *prefix_const, Pattern_Prefix_Status pstatus)
40984095
{
40994096
List *result;
4100-
Oid datatype;
4097+
Oid ldatatype = exprType(leftop);
4098+
Oid rdatatype;
41014099
Oid oproid;
41024100
Expr *expr;
41034101
FmgrInfo ltproc;
@@ -4110,20 +4108,16 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
41104108
case TEXT_BTREE_FAM_OID:
41114109
case TEXT_PATTERN_BTREE_FAM_OID:
41124110
case TEXT_SPGIST_FAM_OID:
4113-
datatype = TEXTOID;
4111+
rdatatype = TEXTOID;
41144112
break;
41154113

41164114
case BPCHAR_BTREE_FAM_OID:
41174115
case BPCHAR_PATTERN_BTREE_FAM_OID:
4118-
datatype = BPCHAROID;
4119-
break;
4120-
4121-
case NAME_BTREE_FAM_OID:
4122-
datatype = NAMEOID;
4116+
rdatatype = BPCHAROID;
41234117
break;
41244118

41254119
case BYTEA_BTREE_FAM_OID:
4126-
datatype = BYTEAOID;
4120+
rdatatype = BYTEAOID;
41274121
break;
41284122

41294123
default:
@@ -4136,7 +4130,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
41364130
* If necessary, coerce the prefix constant to the right type. The given
41374131
* prefix constant is either text or bytea type.
41384132
*/
4139-
if (prefix_const->consttype != datatype)
4133+
if (prefix_const->consttype != rdatatype)
41404134
{
41414135
char *prefix;
41424136

@@ -4154,7 +4148,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
41544148
prefix_const->consttype);
41554149
return NIL;
41564150
}
4157-
prefix_const = string_to_const(prefix, datatype);
4151+
prefix_const = string_to_const(prefix, rdatatype);
41584152
pfree(prefix);
41594153
}
41604154

@@ -4163,7 +4157,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
41634157
*/
41644158
if (pstatus == Pattern_Prefix_Exact)
41654159
{
4166-
oproid = get_opfamily_member(opfamily, datatype, datatype,
4160+
oproid = get_opfamily_member(opfamily, ldatatype, rdatatype,
41674161
BTEqualStrategyNumber);
41684162
if (oproid == InvalidOid)
41694163
elog(ERROR, "no = operator for opfamily %u", opfamily);
@@ -4179,7 +4173,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
41794173
*
41804174
* We can always say "x >= prefix".
41814175
*/
4182-
oproid = get_opfamily_member(opfamily, datatype, datatype,
4176+
oproid = get_opfamily_member(opfamily, ldatatype, rdatatype,
41834177
BTGreaterEqualStrategyNumber);
41844178
if (oproid == InvalidOid)
41854179
elog(ERROR, "no >= operator for opfamily %u", opfamily);
@@ -4196,7 +4190,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
41964190
* using a C-locale index collation.
41974191
*-------
41984192
*/
4199-
oproid = get_opfamily_member(opfamily, datatype, datatype,
4193+
oproid = get_opfamily_member(opfamily, ldatatype, rdatatype,
42004194
BTLessStrategyNumber);
42014195
if (oproid == InvalidOid)
42024196
elog(ERROR, "no < operator for opfamily %u", opfamily);

src/backend/utils/adt/selfuncs.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,14 +1292,12 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
12921292
switch (vartype)
12931293
{
12941294
case TEXTOID:
1295+
case NAMEOID:
12951296
opfamily = TEXT_BTREE_FAM_OID;
12961297
break;
12971298
case BPCHAROID:
12981299
opfamily = BPCHAR_BTREE_FAM_OID;
12991300
break;
1300-
case NAMEOID:
1301-
opfamily = NAME_BTREE_FAM_OID;
1302-
break;
13031301
case BYTEAOID:
13041302
opfamily = BYTEA_BTREE_FAM_OID;
13051303
break;

src/backend/utils/adt/varlena.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2693,6 +2693,167 @@ text_smaller(PG_FUNCTION_ARGS)
26932693
}
26942694

26952695

2696+
/*
2697+
* Cross-type comparison functions for types text and name.
2698+
*/
2699+
2700+
Datum
2701+
nameeqtext(PG_FUNCTION_ARGS)
2702+
{
2703+
Name arg1 = PG_GETARG_NAME(0);
2704+
text *arg2 = PG_GETARG_TEXT_PP(1);
2705+
size_t len1 = strlen(NameStr(*arg1));
2706+
size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2707+
bool result;
2708+
2709+
result = (len1 == len2 &&
2710+
memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2711+
2712+
PG_FREE_IF_COPY(arg2, 1);
2713+
2714+
PG_RETURN_BOOL(result);
2715+
}
2716+
2717+
Datum
2718+
texteqname(PG_FUNCTION_ARGS)
2719+
{
2720+
text *arg1 = PG_GETARG_TEXT_PP(0);
2721+
Name arg2 = PG_GETARG_NAME(1);
2722+
size_t len1 = VARSIZE_ANY_EXHDR(arg1);
2723+
size_t len2 = strlen(NameStr(*arg2));
2724+
bool result;
2725+
2726+
result = (len1 == len2 &&
2727+
memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0);
2728+
2729+
PG_FREE_IF_COPY(arg1, 0);
2730+
2731+
PG_RETURN_BOOL(result);
2732+
}
2733+
2734+
Datum
2735+
namenetext(PG_FUNCTION_ARGS)
2736+
{
2737+
Name arg1 = PG_GETARG_NAME(0);
2738+
text *arg2 = PG_GETARG_TEXT_PP(1);
2739+
size_t len1 = strlen(NameStr(*arg1));
2740+
size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2741+
bool result;
2742+
2743+
result = !(len1 == len2 &&
2744+
memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2745+
2746+
PG_FREE_IF_COPY(arg2, 1);
2747+
2748+
PG_RETURN_BOOL(result);
2749+
}
2750+
2751+
Datum
2752+
textnename(PG_FUNCTION_ARGS)
2753+
{
2754+
text *arg1 = PG_GETARG_TEXT_PP(0);
2755+
Name arg2 = PG_GETARG_NAME(1);
2756+
size_t len1 = VARSIZE_ANY_EXHDR(arg1);
2757+
size_t len2 = strlen(NameStr(*arg2));
2758+
bool result;
2759+
2760+
result = !(len1 == len2 &&
2761+
memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0);
2762+
2763+
PG_FREE_IF_COPY(arg1, 0);
2764+
2765+
PG_RETURN_BOOL(result);
2766+
}
2767+
2768+
Datum
2769+
btnametextcmp(PG_FUNCTION_ARGS)
2770+
{
2771+
Name arg1 = PG_GETARG_NAME(0);
2772+
text *arg2 = PG_GETARG_TEXT_PP(1);
2773+
int32 result;
2774+
2775+
result = varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
2776+
VARDATA_ANY(arg2), VARSIZE_ANY_EXHDR(arg2),
2777+
PG_GET_COLLATION());
2778+
2779+
PG_FREE_IF_COPY(arg2, 1);
2780+
2781+
PG_RETURN_INT32(result);
2782+
}
2783+
2784+
Datum
2785+
bttextnamecmp(PG_FUNCTION_ARGS)
2786+
{
2787+
text *arg1 = PG_GETARG_TEXT_PP(0);
2788+
Name arg2 = PG_GETARG_NAME(1);
2789+
int32 result;
2790+
2791+
result = varstr_cmp(VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1),
2792+
NameStr(*arg2), strlen(NameStr(*arg2)),
2793+
PG_GET_COLLATION());
2794+
2795+
PG_FREE_IF_COPY(arg1, 0);
2796+
2797+
PG_RETURN_INT32(result);
2798+
}
2799+
2800+
#define CmpCall(cmpfunc) \
2801+
DatumGetInt32(DirectFunctionCall2Coll(cmpfunc, \
2802+
PG_GET_COLLATION(), \
2803+
PG_GETARG_DATUM(0), \
2804+
PG_GETARG_DATUM(1)))
2805+
2806+
Datum
2807+
namelttext(PG_FUNCTION_ARGS)
2808+
{
2809+
PG_RETURN_BOOL(CmpCall(btnametextcmp) < 0);
2810+
}
2811+
2812+
Datum
2813+
nameletext(PG_FUNCTION_ARGS)
2814+
{
2815+
PG_RETURN_BOOL(CmpCall(btnametextcmp) <= 0);
2816+
}
2817+
2818+
Datum
2819+
namegttext(PG_FUNCTION_ARGS)
2820+
{
2821+
PG_RETURN_BOOL(CmpCall(btnametextcmp) > 0);
2822+
}
2823+
2824+
Datum
2825+
namegetext(PG_FUNCTION_ARGS)
2826+
{
2827+
PG_RETURN_BOOL(CmpCall(btnametextcmp) >= 0);
2828+
}
2829+
2830+
Datum
2831+
textltname(PG_FUNCTION_ARGS)
2832+
{
2833+
PG_RETURN_BOOL(CmpCall(bttextnamecmp) < 0);
2834+
}
2835+
2836+
Datum
2837+
textlename(PG_FUNCTION_ARGS)
2838+
{
2839+
PG_RETURN_BOOL(CmpCall(bttextnamecmp) <= 0);
2840+
}
2841+
2842+
Datum
2843+
textgtname(PG_FUNCTION_ARGS)
2844+
{
2845+
PG_RETURN_BOOL(CmpCall(bttextnamecmp) > 0);
2846+
}
2847+
2848+
Datum
2849+
textgename(PG_FUNCTION_ARGS)
2850+
{
2851+
PG_RETURN_BOOL(CmpCall(bttextnamecmp) >= 0);
2852+
}
2853+
2854+
#undef CmpCall
2855+
2856+
26962857
/*
26972858
* The following operators support character-by-character comparison
26982859
* of text datums, to allow building indexes suitable for LIKE clauses.

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201812191
56+
#define CATALOG_VERSION_NO 201812192
5757

5858
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy