Skip to content

Commit d2f7d1f

Browse files
committed
Mark bpchareq not hashjoinable, since it strips trailing blanks
before comparison; if fields being joined are different widths then hashing will yield wrong answer. Also, remove hashjoinable mark from all uses of array_eq, because array structures may have padding bytes between elements and the pad bytes are of uncertain content. This could be revisited if array code is cleaned up. Modify opr_sanity regress test to complain if array_eq operator is marked hashjoinable.
1 parent 22fe3d4 commit d2f7d1f

File tree

3 files changed

+49
-39
lines changed

3 files changed

+49
-39
lines changed

src/include/catalog/pg_operator.h

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: pg_operator.h,v 1.58 1999/07/27 03:51:11 tgl Exp $
10+
* $Id: pg_operator.h,v 1.59 1999/09/06 21:16:18 tgl Exp $
1111
*
1212
* NOTES
1313
* the genbki.sh script reads this file and generates .bki
@@ -109,32 +109,32 @@ DATA(insert OID = 96 ( "=" PGUID 0 b t t 23 23 16 96 518 97 97 int4eq
109109
DATA(insert OID = 97 ( "<" PGUID 0 b t f 23 23 16 521 525 0 0 int4lt intltsel intltjoinsel ));
110110
DATA(insert OID = 98 ( "=" PGUID 0 b t t 25 25 16 98 531 664 664 texteq eqsel eqjoinsel ));
111111

112-
DATA(insert OID = 329 ( "=" PGUID 0 b t t 1000 1000 16 329 0 0 0 array_eq eqsel eqjoinsel ));
113-
DATA(insert OID = 349 ( "=" PGUID 0 b t t 1001 1001 16 349 0 0 0 array_eq eqsel eqjoinsel ));
114-
DATA(insert OID = 374 ( "=" PGUID 0 b t t 1002 1002 16 374 0 0 0 array_eq eqsel eqjoinsel ));
115-
DATA(insert OID = 375 ( "=" PGUID 0 b t t 1003 1003 16 375 0 0 0 array_eq eqsel eqjoinsel ));
116-
DATA(insert OID = 377 ( "=" PGUID 0 b t t 1005 1005 16 377 0 0 0 array_eq eqsel eqjoinsel ));
117-
DATA(insert OID = 378 ( "=" PGUID 0 b t t 1006 1006 16 378 0 0 0 array_eq eqsel eqjoinsel ));
118-
DATA(insert OID = 379 ( "=" PGUID 0 b t t 1007 1007 16 379 0 0 0 array_eq eqsel eqjoinsel ));
119-
DATA(insert OID = 380 ( "=" PGUID 0 b t t 1008 1008 16 380 0 0 0 array_eq eqsel eqjoinsel ));
120-
DATA(insert OID = 381 ( "=" PGUID 0 b t t 1009 1009 16 381 0 0 0 array_eq eqsel eqjoinsel ));
121-
DATA(insert OID = 382 ( "=" PGUID 0 b t t 1028 1028 16 382 0 0 0 array_eq eqsel eqjoinsel ));
122-
DATA(insert OID = 383 ( "=" PGUID 0 b t t 1010 1010 16 383 0 0 0 array_eq eqsel eqjoinsel ));
123-
DATA(insert OID = 384 ( "=" PGUID 0 b t t 1011 1011 16 384 0 0 0 array_eq eqsel eqjoinsel ));
124-
DATA(insert OID = 385 ( "=" PGUID 0 b t t 1012 1012 16 385 0 0 0 array_eq eqsel eqjoinsel ));
125-
DATA(insert OID = 386 ( "=" PGUID 0 b t t 1013 1013 16 386 0 0 0 array_eq eqsel eqjoinsel ));
126-
DATA(insert OID = 390 ( "=" PGUID 0 b t t 1017 1017 16 390 0 0 0 array_eq eqsel eqjoinsel ));
112+
DATA(insert OID = 329 ( "=" PGUID 0 b t f 1000 1000 16 329 0 0 0 array_eq eqsel eqjoinsel ));
113+
DATA(insert OID = 349 ( "=" PGUID 0 b t f 1001 1001 16 349 0 0 0 array_eq eqsel eqjoinsel ));
114+
DATA(insert OID = 374 ( "=" PGUID 0 b t f 1002 1002 16 374 0 0 0 array_eq eqsel eqjoinsel ));
115+
DATA(insert OID = 375 ( "=" PGUID 0 b t f 1003 1003 16 375 0 0 0 array_eq eqsel eqjoinsel ));
116+
DATA(insert OID = 377 ( "=" PGUID 0 b t f 1005 1005 16 377 0 0 0 array_eq eqsel eqjoinsel ));
117+
DATA(insert OID = 378 ( "=" PGUID 0 b t f 1006 1006 16 378 0 0 0 array_eq eqsel eqjoinsel ));
118+
DATA(insert OID = 379 ( "=" PGUID 0 b t f 1007 1007 16 379 0 0 0 array_eq eqsel eqjoinsel ));
119+
DATA(insert OID = 380 ( "=" PGUID 0 b t f 1008 1008 16 380 0 0 0 array_eq eqsel eqjoinsel ));
120+
DATA(insert OID = 381 ( "=" PGUID 0 b t f 1009 1009 16 381 0 0 0 array_eq eqsel eqjoinsel ));
121+
DATA(insert OID = 382 ( "=" PGUID 0 b t f 1028 1028 16 382 0 0 0 array_eq eqsel eqjoinsel ));
122+
DATA(insert OID = 383 ( "=" PGUID 0 b t f 1010 1010 16 383 0 0 0 array_eq eqsel eqjoinsel ));
123+
DATA(insert OID = 384 ( "=" PGUID 0 b t f 1011 1011 16 384 0 0 0 array_eq eqsel eqjoinsel ));
124+
DATA(insert OID = 385 ( "=" PGUID 0 b t f 1012 1012 16 385 0 0 0 array_eq eqsel eqjoinsel ));
125+
DATA(insert OID = 386 ( "=" PGUID 0 b t f 1013 1013 16 386 0 0 0 array_eq eqsel eqjoinsel ));
126+
DATA(insert OID = 390 ( "=" PGUID 0 b t f 1017 1017 16 390 0 0 0 array_eq eqsel eqjoinsel ));
127127
DATA(insert OID = 391 ( "=" PGUID 0 b t f 1018 1018 16 391 0 0 0 array_eq eqsel eqjoinsel ));
128128
DATA(insert OID = 392 ( "=" PGUID 0 b t f 1019 1019 16 392 0 0 0 array_eq eqsel eqjoinsel ));
129129
DATA(insert OID = 393 ( "=" PGUID 0 b t f 1020 1020 16 393 0 0 0 array_eq eqsel eqjoinsel ));
130130
DATA(insert OID = 394 ( "=" PGUID 0 b t f 1021 1021 16 394 0 0 0 array_eq eqsel eqjoinsel ));
131131
DATA(insert OID = 395 ( "=" PGUID 0 b t f 1022 1022 16 395 0 0 0 array_eq eqsel eqjoinsel ));
132-
DATA(insert OID = 396 ( "=" PGUID 0 b t t 1023 1023 16 396 0 0 0 array_eq eqsel eqjoinsel ));
133-
DATA(insert OID = 397 ( "=" PGUID 0 b t t 1024 1024 16 397 0 0 0 array_eq eqsel eqjoinsel ));
132+
DATA(insert OID = 396 ( "=" PGUID 0 b t f 1023 1023 16 396 0 0 0 array_eq eqsel eqjoinsel ));
133+
DATA(insert OID = 397 ( "=" PGUID 0 b t f 1024 1024 16 397 0 0 0 array_eq eqsel eqjoinsel ));
134134
DATA(insert OID = 398 ( "=" PGUID 0 b t f 1025 1025 16 398 0 0 0 array_eq eqsel eqjoinsel ));
135-
DATA(insert OID = 399 ( "=" PGUID 0 b t t 1026 1026 16 399 0 0 0 array_eq eqsel eqjoinsel ));
136-
DATA(insert OID = 400 ( "=" PGUID 0 b t t 1027 1027 16 400 0 0 0 array_eq eqsel eqjoinsel ));
137-
DATA(insert OID = 401 ( "=" PGUID 0 b t t 1034 1034 16 401 0 0 0 array_eq eqsel eqjoinsel ));
135+
DATA(insert OID = 399 ( "=" PGUID 0 b t f 1026 1026 16 399 0 0 0 array_eq eqsel eqjoinsel ));
136+
DATA(insert OID = 400 ( "=" PGUID 0 b t f 1027 1027 16 400 0 0 0 array_eq eqsel eqjoinsel ));
137+
DATA(insert OID = 401 ( "=" PGUID 0 b t f 1034 1034 16 401 0 0 0 array_eq eqsel eqjoinsel ));
138138

139139
DATA(insert OID = 410 ( "=" PGUID 0 b t t 20 20 16 410 411 412 412 int8eq eqsel eqjoinsel ));
140140
DATA(insert OID = 411 ( "<>" PGUID 0 b t f 20 20 16 411 410 0 0 int8ne neqsel neqjoinsel ));
@@ -434,7 +434,7 @@ DATA(insert OID = 971 ( "@@" PGUID 0 l t f 0 604 600 0 0 0 0 poly_cent
434434
DATA(insert OID = 974 ( "||" PGUID 0 b t f 1042 1042 1042 0 0 0 0 textcat - - ));
435435
DATA(insert OID = 979 ( "||" PGUID 0 b t f 1043 1043 1043 0 0 0 0 textcat - - ));
436436

437-
DATA(insert OID = 1054 ( "=" PGUID 0 b t t 1042 1042 16 1054 1057 1058 1058 bpchareq eqsel eqjoinsel ));
437+
DATA(insert OID = 1054 ( "=" PGUID 0 b t f 1042 1042 16 1054 1057 1058 1058 bpchareq eqsel eqjoinsel ));
438438
DATA(insert OID = 1055 ( "~" PGUID 0 b t f 1042 25 16 0 1056 0 0 textregexeq eqsel eqjoinsel ));
439439
#define OID_BPCHAR_REGEXEQ_OP 1055
440440
DATA(insert OID = 1056 ( "!~" PGUID 0 b t f 1042 25 16 0 1055 0 0 textregexne neqsel neqjoinsel ));

src/test/regress/expected/opr_sanity.out

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -237,14 +237,11 @@ WHERE p1.oprcanhash AND NOT
237237
1137|=
238238
(2 rows)
239239

240-
QUERY: SELECT p1.oid, p1.oprcanhash, p2.oid, p2.oprcanhash, t1.typname, t2.typname
241-
FROM pg_operator AS p1, pg_operator AS p2, pg_type AS t1, pg_type AS t2
242-
WHERE p1.oprname = '=' AND p1.oprleft = p1.oprright AND
243-
p2.oprname = '=' AND p2.oprleft = p2.oprright AND
244-
p1.oprleft = t1.oid AND p2.oprleft = t2.oid AND t1.typelem = t2.oid AND
245-
p1.oprcanhash != p2.oprcanhash;
246-
oid|oprcanhash|oid|oprcanhash|typname|typname
247-
---+----------+---+----------+-------+-------
240+
QUERY: SELECT p1.oid, p1.oprname
241+
FROM pg_operator AS p1, pg_proc AS p2
242+
WHERE p1.oprcanhash AND p1.oprcode = p2.oid AND p2.proname = 'array_eq';
243+
oid|oprname
244+
---+-------
248245
(0 rows)
249246

250247
QUERY: SELECT p1.oid, p1.oprname, p2.oid, p2.proname

src/test/regress/sql/opr_sanity.sql

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,15 +240,28 @@ WHERE p1.oprcanhash AND NOT
240240
(p1.oprkind = 'b' AND p1.oprresult = 16 AND p1.oprleft = p1.oprright AND
241241
p1.oprname = '=' AND p1.oprcom = p1.oid);
242242

243-
-- Look for array equality operators that are hashable when the underlying
244-
-- type is not, or vice versa. This is presumably bogus.
245-
246-
SELECT p1.oid, p1.oprcanhash, p2.oid, p2.oprcanhash, t1.typname, t2.typname
247-
FROM pg_operator AS p1, pg_operator AS p2, pg_type AS t1, pg_type AS t2
248-
WHERE p1.oprname = '=' AND p1.oprleft = p1.oprright AND
249-
p2.oprname = '=' AND p2.oprleft = p2.oprright AND
250-
p1.oprleft = t1.oid AND p2.oprleft = t2.oid AND t1.typelem = t2.oid AND
251-
p1.oprcanhash != p2.oprcanhash;
243+
-- In 6.5 we accepted hashable array equality operators when the array element
244+
-- type is hashable. However, what we actually need to make hashjoin work on
245+
-- an array is a hashable element type *and* no padding between elements in
246+
-- the array storage (or, perhaps, guaranteed-zero padding). Currently,
247+
-- since the padding code in arrayfuncs.c is pretty bogus, it seems safest
248+
-- to just forbid hashjoin on array equality ops.
249+
-- This should be reconsidered someday.
250+
251+
-- -- Look for array equality operators that are hashable when the underlying
252+
-- -- type is not, or vice versa. This is presumably bogus.
253+
--
254+
-- SELECT p1.oid, p1.oprcanhash, p2.oid, p2.oprcanhash, t1.typname, t2.typname
255+
-- FROM pg_operator AS p1, pg_operator AS p2, pg_type AS t1, pg_type AS t2
256+
-- WHERE p1.oprname = '=' AND p1.oprleft = p1.oprright AND
257+
-- p2.oprname = '=' AND p2.oprleft = p2.oprright AND
258+
-- p1.oprleft = t1.oid AND p2.oprleft = t2.oid AND t1.typelem = t2.oid AND
259+
-- p1.oprcanhash != p2.oprcanhash;
260+
261+
-- Substitute check: forbid hashable array ops, period.
262+
SELECT p1.oid, p1.oprname
263+
FROM pg_operator AS p1, pg_proc AS p2
264+
WHERE p1.oprcanhash AND p1.oprcode = p2.oid AND p2.proname = 'array_eq';
252265

253266
-- Check that each operator defined in pg_operator matches its oprcode entry
254267
-- in pg_proc. Easiest to do this separately for each oprkind.

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