Re: SQL:2011 application time - Mailing list pgsql-hackers
From | Paul Jungwirth |
---|---|
Subject | Re: SQL:2011 application time |
Date | |
Msg-id | 30dc3561-d7ab-42be-a1c5-096643423590@illuminatedcomputing.com Whole thread Raw |
In response to | Re: SQL:2011 application time (Paul Jungwirth <pj@illuminatedcomputing.com>) |
Responses |
Re: SQL:2011 application time
|
List | pgsql-hackers |
On 7/17/24 20:34, Paul Jungwirth wrote: > I like this approach a lot, but I'd like to hear what some other people think? > > Jian he's &&& operator is similar to what I proposed upthread, but when either operand is an empty > value it simply raises an error. (It should be an ereport, not an elog, and I think > multirange_overlaps_multirange_internal is missing the empty check, but I can clean things up when I > integrate it into the patch series.) I thought of a possible problem: this operator works great if there are already rows in the table, but what if the *first row you insert* has an empty range? Then there is nothing to compare against, so the operator will never be used. Right? Except when I test it, it still works! After running `make installcheck`, I did this: regression=# truncate temporal_rng cascade; NOTICE: truncate cascades to table "temporal_fk_rng2rng" TRUNCATE TABLE regression=# insert into temporal_rng values ('[1,2)', 'empty'); ERROR: range cannot be empty My mental model must be wrong. Can anyone explain what is happening there? Is it something we can depend on? So I swapped in the &&& patch, cleaned it up, and added tests. But something is wrong. After I get one failure from an empty, I keep getting failures, even though the table is empty: regression=# truncate temporal_rng cascade; NOTICE: truncate cascades to table "temporal_fk_rng2rng" TRUNCATE TABLE regression=# insert into temporal_rng values ('[1,2)', '[2000-01-01,2010-01-01)'); -- ok so far INSERT 0 1 regression=# insert into temporal_rng values ('[1,2)', 'empty'); -- should fail and does ERROR: range cannot be empty regression=# insert into temporal_rng values ('[1,2)', '[2010-01-01,2020-01-01)'); -- uh oh ERROR: range cannot be empty regression=# truncate temporal_rng cascade; NOTICE: truncate cascades to table "temporal_fk_rng2rng" TRUNCATE TABLE regression=# insert into temporal_rng values ('[1,2)', '[2000-01-01,2010-01-01)'); -- ok so far INSERT 0 1 regression=# insert into temporal_rng values ('[1,2)', '[2010-01-01,2020-01-01)'); -- ok now INSERT 0 1 It looks like the index is getting corrupted. Continuing from the above: regression=# create extension pageinspect; CREATE EXTENSION regression=# select gist_page_items(get_raw_page('temporal_rng_pk', 0), 'temporal_rng_pk'); gist_page_items ---------------------------------------------------------------------------- (1,"(0,1)",40,f,"(id, valid_at)=(""[1,2)"", ""[2000-01-01,2010-01-01)"")") (2,"(0,2)",40,f,"(id, valid_at)=(""[1,2)"", ""[2010-01-01,2020-01-01)"")") (2 rows) regression=# insert into temporal_rng values ('[1,2)', 'empty'); ERROR: range cannot be empty regression=# select gist_page_items(get_raw_page('temporal_rng_pk', 0), 'temporal_rng_pk'); gist_page_items ---------------------------------------------------------------------------- (1,"(0,1)",40,f,"(id, valid_at)=(""[1,2)"", ""[2000-01-01,2010-01-01)"")") (2,"(0,2)",40,f,"(id, valid_at)=(""[1,2)"", ""[2010-01-01,2020-01-01)"")") (3,"(0,3)",32,f,"(id, valid_at)=(""[1,2)"", empty)") (3 rows) So maybe this is a bad place to ereport? Or is this a deeper bug with GiST? Here is where we're doing it: #0 range_nonempty_overlaps_internal (typcache=0x635a7fbf67f0, r1=0x635a7fc11f20, r2=0x635a7fc11f40) at rangetypes.c:876 #1 0x0000635a7f06175d in range_gist_consistent_leaf_range (typcache=0x635a7fbf67f0, strategy=31, key=0x635a7fc11f20, query=0x635a7fc11f40) at rangetypes_gist.c:1076 #2 0x0000635a7f05fc9a in range_gist_consistent (fcinfo=0x7ffcd20f9f60) at rangetypes_gist.c:216 #3 0x0000635a7f12d780 in FunctionCall5Coll (flinfo=0x635a7fb44eb8, collation=0, arg1=140723832725648, arg2=109240340727454, arg3=31, arg4=0, arg5=140723832725567) at fmgr.c:1242 #4 0x0000635a7e999af6 in gistindex_keytest (scan=0x635a7fb44d50, tuple=0x7d155c0a3fd0, page=0x7d155c0a2000 "", offset=1, recheck_p=0x7ffcd20fa129, recheck_distances_p=0x7ffcd20fa12a) at gistget.c:221 #5 0x0000635a7e99a109 in gistScanPage (scan=0x635a7fb44d50, pageItem=0x7ffcd20fa1e0, myDistances=0x0, tbm=0x0, ntids=0x0) at gistget.c:436 #6 0x0000635a7e99a797 in gistgettuple (scan=0x635a7fb44d50, dir=ForwardScanDirection) at gistget.c:637 #7 0x0000635a7e9e4d38 in index_getnext_tid (scan=0x635a7fb44d50, direction=ForwardScanDirection) at indexam.c:590 #8 0x0000635a7e9e4f7d in index_getnext_slot (scan=0x635a7fb44d50, direction=ForwardScanDirection, slot=0x635a7fb44950) at indexam.c:682 #9 0x0000635a7ec5690b in check_exclusion_or_unique_constraint (heap=0x7d1560cea348, index=0x7d1560cedd98, indexInfo=0x635a7fb44c40, tupleid=0x635a7fb44580, values=0x7ffcd20faf00, isnull=0x7ffcd20faee0, estate=0x635a7fb434a0, newIndex=false, waitMode=CEOUC_WAIT, violationOK=false, conflictTid=0x0) at execIndexing.c:780 #10 0x0000635a7ec55c58 in ExecInsertIndexTuples (resultRelInfo=0x635a7fb43930, slot=0x635a7fb44550, estate=0x635a7fb434a0, update=false, noDupErr=false, specConflict=0x0, arbiterIndexes=0x0, onlySummarizing=false) at execIndexing.c:483 #11 0x0000635a7eca38a2 in ExecInsert (context=0x7ffcd20fb1b0, resultRelInfo=0x635a7fb43930, slot=0x635a7fb44550, canSetTag=true, inserted_tuple=0x0, insert_destrel=0x0) at nodeModifyTable.c:1145 Is there anything I can do to save this &&& idea? I've attached the patches I'm working with, rebased to cd85ae1114. If ereport just won't work, then I might explore other definitions of a &&& operator. It was really nice to have such a clean solution. Yours, -- Paul ~{:-) pj@illuminatedcomputing.com
Attachment
pgsql-hackers by date: