Thread: BUG #17774: Assert triggered on brin_minmax_multi.c

BUG #17774: Assert triggered on brin_minmax_multi.c

From
PG Bug reporting form
Date:
The following bug has been logged on the website:

Bug reference:      17774
Logged by:          Robins Tharakan
Email address:      tharakan@gmail.com
PostgreSQL version: 15.1
Operating system:   Ubuntu 20.04
Description:

This assert() is not easily reproducible, but thought the backtraces may be
interesting.

TRAP: FailedAssertion("(delta >= 0) && (delta <= 1)", File:
"brin_minmax_multi.c", Line: 2393, PID: 2922100)

Backtrace / SQL below.

Backtrace
=========
Core was generated by `postgres: d9f5345bf9@REL_15_STABLE@sqith: u81
postgres 127.0.0.1(59494) UPDATE'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007f3b8a8d0859 in __GI_abort () at abort.c:79
#2  0x000055e143f0ae8b in ExceptionalCondition (
    conditionName=0x55e143f92604 "(delta >= 0) && (delta <= 1)", 
    errorType=0x55e143f91ef4 "FailedAssertion", 
    fileName=0x55e143f91ee0 "brin_minmax_multi.c", lineNumber=2393)
    at assert.c:69
#3  0x000055e1437e8972 in brin_minmax_multi_distance_inet (
    fcinfo=0x7ffc448234f0) at brin_minmax_multi.c:2393
#4  0x000055e143f16bd6 in FunctionCall2Coll (flinfo=0x55e150aa1740, 
    collation=0, arg1=94426157654496, arg2=94426091683272) at fmgr.c:1146
#5  0x000055e1437e6792 in build_distances (distanceFn=0x55e150aa1740, 
    colloid=0, eranges=0x55e14ee95e10, neranges=8) at
brin_minmax_multi.c:1361
#6  0x000055e1437e7379 in compactify_ranges (bdesc=0x55e150aa1b58, 
    ranges=0x55e1473dbee0, max_values=32) at brin_minmax_multi.c:1831
#7  0x000055e1437e89d4 in brin_minmax_multi_serialize (bdesc=0x55e150aa1b58,

    src=94426051231456, dst=0x55e14d959fd0) at brin_minmax_multi.c:2411
#8  0x000055e1437eed6b in brin_form_tuple (brdesc=0x55e150aa1b58, blkno=0,

    tuple=0x55e14d959c40, size=0x7ffc448237a0) at brin_tuple.c:165
#9  0x000055e1437de6c1 in brininsert (idxRel=0x55e14ba5a4c0, 
    values=0x7ffc44823930, nulls=0x7ffc44823910, heaptid=0x55e14693e520, 
    heapRel=0x55e14a28ab88, checkUnique=UNIQUE_CHECK_NO, 
    indexUnchanged=false, indexInfo=0x55e14693ef70) at brin.c:281
#10 0x000055e14388517c in index_insert (indexRelation=0x55e14ba5a4c0, 
    values=0x7ffc44823930, isnull=0x7ffc44823910,
heap_t_ctid=0x55e14693e520, 
    heapRelation=0x55e14a28ab88, checkUnique=UNIQUE_CHECK_NO, 
    indexUnchanged=false, indexInfo=0x55e14693ef70) at indexam.c:193
#11 0x000055e143ad7a03 in ExecInsertIndexTuples (
    resultRelInfo=0x55e14b07ec80, slot=0x55e14693e4f0,
estate=0x55e1468ffc20, 
    update=true, noDupErr=false, specConflict=0x0, arbiterIndexes=0x0)
    at execIndexing.c:416
#12 0x000055e143b24a23 in ExecUpdateEpilogue (context=0x7ffc44823bf0, 
    updateCxt=0x7ffc44823b30, resultRelInfo=0x55e14b07ec80, 
    tupleid=0x7ffc44823b72, oldtuple=0x0, slot=0x55e14693e4f0, 
    recheckIndexes=0x0) at nodeModifyTable.c:2123
#13 0x000055e143b25379 in ExecUpdate (context=0x7ffc44823bf0, 
    resultRelInfo=0x55e14b07ec80, tupleid=0x7ffc44823b72, oldtuple=0x0, 
    slot=0x55e14693e4f0, canSetTag=true) at nodeModifyTable.c:2464
#14 0x000055e143b27a58 in ExecModifyTable (pstate=0x55e146901900)
    at nodeModifyTable.c:3857
#15 0x000055e143ae5eb2 in ExecProcNodeFirst (node=0x55e146901900)
    at execProcnode.c:464
#16 0x000055e143ad969f in ExecProcNode (node=0x55e146901900)
    at ../../../src/include/executor/executor.h:259
#17 0x000055e143adc3b1 in ExecutePlan (estate=0x55e1468ffc20, 
    planstate=0x55e146901900, use_parallel_mode=false, operation=CMD_UPDATE,

    sendTuples=true, numberTuples=0, direction=ForwardScanDirection, 
    dest=0x55e150a50bc8, execute_once=true) at execMain.c:1636
#18 0x000055e143ad9d79 in standard_ExecutorRun (queryDesc=0x55e150a50c60, 
    direction=ForwardScanDirection, count=0, execute_once=true)
    at execMain.c:363
#19 0x00007f3b878be203 in pgss_ExecutorRun (queryDesc=0x55e150a50c60, 
    direction=ForwardScanDirection, count=0, execute_once=true)
    at pg_stat_statements.c:1010
#20 0x000055e143ad9b6f in ExecutorRun (queryDesc=0x55e150a50c60, 
    direction=ForwardScanDirection, count=0, execute_once=true)
    at execMain.c:305
#21 0x000055e143d48e2b in ProcessQuery (plan=0x55e148d80ee8, 
    sourceText=0x55e146177d40 "update public.brintest_multi set \n  int8col
= pg_catalog.hashint4extended(\n    cast(public.brintest_multi.int4col as
int4),\n    cast(pg_catalog.pg_stat_get_bgwriter_requested_checkpoints() as
int8)), "..., params=0x0, queryEnv=0x0, dest=0x55e150a50bc8,
qc=0x7ffc44823f90)
    at pquery.c:160
#22 0x000055e143d4a989 in PortalRunMulti (portal=0x55e147d1ab20, 
    isTopLevel=true, setHoldSnapshot=true, dest=0x55e150a50bc8, 
    altdest=0x55e144252940 <donothingDR>, qc=0x7ffc44823f90) at
pquery.c:1277
#23 0x000055e143d4a4b3 in FillPortalStore (portal=0x55e147d1ab20, 
    isTopLevel=true) at pquery.c:1026
#24 0x000055e143d49dcc in PortalRun (portal=0x55e147d1ab20, 
    count=9223372036854775807, isTopLevel=true, run_once=true, 
    dest=0x55e148d81be8, altdest=0x55e148d81be8, qc=0x7ffc448241d0)
    at pquery.c:763
#25 0x000055e143d43067 in exec_simple_query (
    query_string=0x55e146177d40 "update public.brintest_multi set \n
int8col = pg_catalog.hashint4extended(\n
cast(public.brintest_multi.int4col as int4),\n
cast(pg_catalog.pg_stat_get_bgwriter_requested_checkpoints() as int8)),
"...) at postgres.c:1250
#26 0x000055e143d47c8c in PostgresMain (dbname=0x55e1461ce9c0 "postgres", 
    username=0x55e1461ce9a0 "u81") at postgres.c:4593
#27 0x000055e143c73785 in BackendRun (port=0x55e1461d31f0)
    at postmaster.c:4511
#28 0x000055e143c73056 in BackendStartup (port=0x55e1461d31f0)
    at postmaster.c:4239
#29 0x000055e143c6f142 in ServerLoop () at postmaster.c:1806
#30 0x000055e143c6e8db in PostmasterMain (argc=3, argv=0x55e1461703d0)
    at postmaster.c:1478
#31 0x000055e143b67f7e in main (argc=3, argv=0x55e1461703d0) at main.c:202


=== Backtrace FULL - PID 2922100 - d9f5345bf9@REL_15_STABLE ===
Core was generated by `postgres: d9f5345bf9@REL_15_STABLE@sqith: u81
postgres 127.0.0.1(59494) UPDATE'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
        set = {__val = {4194304, 0, 0, 0, 0, 94425988324624, 
            4611686018427387904, 0, 0, 139893715715306, 0, 94425988324670,

            128, 0, 140721457868752, 139893705594400}}
        pid = <optimized out>
        tid = <optimized out>
        ret = <optimized out>
#1  0x00007f3b8a8d0859 in __GI_abort () at abort.c:79
        save_stage = 1
        act = {__sigaction_handler = {sa_handler = 0x7f3b8aa63bf7, 
            sa_sigaction = 0x7f3b8aa63bf7}, sa_mask = {__val = {1, 
              139893705953310, 3, 140721457868932, 12, 139893705953314, 2,

              3559309584102229448, 7292282603983811380, 94425988324624, 
              7292003142558041952, 0, 14782313591304450816, 140721457869024,

              94425996395472, 140721457869904}}, sa_flags = 1132322064, 
          sa_restorer = 0x7ffc44824760}
        sigs = {__val = {32, 0 <repeats 15 times>}}
#2  0x000055e143f0ae8b in ExceptionalCondition (
    conditionName=0x55e143f92604 "(delta >= 0) && (delta <= 1)", 
    errorType=0x55e143f91ef4 "FailedAssertion", 
    fileName=0x55e143f91ee0 "brin_minmax_multi.c", lineNumber=2393)
    at assert.c:69
No locals.
#3  0x000055e1437e8972 in brin_minmax_multi_distance_inet (
    fcinfo=0x7ffc448234f0) at brin_minmax_multi.c:2393
        delta = -2.3283064365386963e-10
        i = -1
        len = 4
        addra = 0x55e14ee95fc0 ""
        addrb = 0x55e14ee95fe0 ""
        ipa = 0x55e14d95a1e0
        ipb = 0x55e149a6fdc8
        lena = 0
        lenb = 32
#4  0x000055e143f16bd6 in FunctionCall2Coll (flinfo=0x55e150aa1740, 
    collation=0, arg1=94426157654496, arg2=94426091683272) at fmgr.c:1146
        fcinfodata = {fcinfo = {flinfo = 0x55e150aa1740, context = 0x0, 
            resultinfo = 0x0, fncollation = 0, isnull = false, nargs = 2, 
            args = 0x7ffc44823510}, 
          fcinfo_data = "@\027\252P\341U", '\000' <repeats 23 times>,
"U\002\000ࡕM\341U\000\000\000\000\000\000\000\000\000\000\310\375\246I\341U\000\000\000\000\000\000\000\000\000"}
        fcinfo = 0x7ffc448234f0
        result = 94426179919656
        __func__ = "FunctionCall2Coll"
#5  0x000055e1437e6792 in build_distances (distanceFn=0x55e150aa1740, 
    colloid=0, eranges=0x55e14ee95e10, neranges=8) at
brin_minmax_multi.c:1361
        a1 = 94426157654496
        a2 = 94426091683272
        r = 94426209326968
        i = 0
        ndistances = 7
        distances = 0x55e14ee95f28
#6  0x000055e1437e7379 in compactify_ranges (bdesc=0x55e150aa1b58, 
    ranges=0x55e1473dbee0, max_values=32) at brin_minmax_multi.c:1831
        cmpFn = 0x55e150aa1778
        distanceFn = 0x55e150aa1740
        eranges = 0x55e14ee95e10
        neranges = 8
        distances = 0x55e14d95b520
        ctx = 0x55e14ee95cf0
        oldctx = 0x55e14d959b20
#7  0x000055e1437e89d4 in brin_minmax_multi_serialize (bdesc=0x55e150aa1b58,

    src=94426051231456, dst=0x55e14d959fd0) at brin_minmax_multi.c:2411
        ranges = 0x55e1473dbee0
        s = 0x55e14d95b520
#8  0x000055e1437eed6b in brin_form_tuple (brdesc=0x55e150aa1b58, blkno=0,

    tuple=0x55e14d959c40, size=0x7ffc448237a0) at brin_tuple.c:165
        datumno = 1
        values = 0x55e14d95b240
        nulls = 0x55e14d95b358
        anynulls = true
        rettuple = 0xcd2553e428217300
        keyno = 9
        idxattno = 9
        phony_infomask = 0
        phony_nullbitmap = 0x55e14d95b390 "\177\177\177~\177\177\177\177"
        len = 94426157652768
        hoff = 0
        data_len = 140721457871152
        i = 1184099328
        untoasted_values = 0x55e14d95b3b0
        nuntoasted = 0
#9  0x000055e1437de6c1 in brininsert (idxRel=0x55e14ba5a4c0, 
    values=0x7ffc44823930, nulls=0x7ffc44823910, heaptid=0x55e14693e520, 
    heapRel=0x55e14a28ab88, checkUnique=UNIQUE_CHECK_NO, 
    indexUnchanged=false, indexInfo=0x55e14693ef70) at brin.c:281
        lp = 0x7f3b739fb198
        origsz = 2096
        newsz = 1800
        page = 0x7f3b739fb180 "\373\003"
        origtup = 0x55e14d95a228
        newtup = 0x7ffc44823820
        samepage = 11
        need_insert = true
        off = 1
        brtup = 0x7f3b739fc948
        dtup = 0x55e14d959c40
        pagesPerRange = 1
        origHeapBlk = 0
        heapBlk = 0
        bdesc = 0x55e150aa1b58
        revmap = 0x55e14b0800f8
        buf = 6896
        tupcxt = 0x55e14d959b20
        oldcxt = 0x55e1468ffb00
        autosummarize = false
        __func__ = "brininsert"
#10 0x000055e14388517c in index_insert (indexRelation=0x55e14ba5a4c0, 
    values=0x7ffc44823930, isnull=0x7ffc44823910,
heap_t_ctid=0x55e14693e520, 
    heapRelation=0x55e14a28ab88, checkUnique=UNIQUE_CHECK_NO, 
    indexUnchanged=false, indexInfo=0x55e14693ef70) at indexam.c:193
        __func__ = "index_insert"
#11 0x000055e143ad7a03 in ExecInsertIndexTuples (
    resultRelInfo=0x55e14b07ec80, slot=0x55e14693e4f0,
estate=0x55e1468ffc20, 
    update=true, noDupErr=false, specConflict=0x0, arbiterIndexes=0x0)
    at execIndexing.c:416
        applyNoDupErr = false
        checkUnique = UNIQUE_CHECK_NO
        indexRelation = 0x55e14ba5a4c0
        indexInfo = 0x55e14693ef70
        indexUnchanged = false
        satisfiesConstraint = false
        tupleid = 0x55e14693e520
        result = 0x0
        i = 1
        numIndices = 6
        relationDescs = 0x55e14693e498
        heapRelation = 0x55e14a28ab88
        indexInfoArray = 0x55e14693ece8
        econtext = 0x55e14693ec50
        values = {0, 0, 0, 0, 0, 2143289344, 0, 0, 0, 94426040101880, 0, 0,

          0, 0, 0, 0, 94426040101888, 0, 0, 0, 0, 94426032201696,
1149385217, 
          94426040100080, 140721457871730, 94426100181896, 140721457871520,

          94425991760257, 1, 140721457871904, 140721457871668, 
          140721457871665}
        isnull = {true, true, true, false, true, false, true, true, true, 
          false, true, true, true, true, true, true, false, true, true,
true, 
          252, 127, false, false, 52, 59, 130, 68, 252, 127, false, false}
#12 0x000055e143b24a23 in ExecUpdateEpilogue (context=0x7ffc44823bf0, 
    updateCxt=0x7ffc44823b30, resultRelInfo=0x55e14b07ec80, 
    tupleid=0x7ffc44823b72, oldtuple=0x0, slot=0x55e14693e4f0, 
    recheckIndexes=0x0) at nodeModifyTable.c:2123
        mtstate = 0x55e146901900
#13 0x000055e143b25379 in ExecUpdate (context=0x7ffc44823bf0, 
    resultRelInfo=0x55e14b07ec80, tupleid=0x7ffc44823b72, oldtuple=0x0, 
    slot=0x55e14693e4f0, canSetTag=true) at nodeModifyTable.c:2464
        estate = 0x55e1468ffc20
        resultRelationDesc = 0x55e14a28ab88
        updateCxt = {updated = true, updateIndexes = true, 
          crossPartUpdate = false, lockmode = LockTupleNoKeyExclusive}
        recheckIndexes = 0x0
        result = TM_Ok
        __func__ = "ExecUpdate"
#14 0x000055e143b27a58 in ExecModifyTable (pstate=0x55e146901900)
    at nodeModifyTable.c:3857
        node = 0x55e146901900
        context = {mtstate = 0x55e146901900, epqstate = 0x55e1469019e8, 
          estate = 0x55e1468ffc20, planSlot = 0x55e14b07ffe0, 
          GetUpdateNewTuple = 0x55e143b22924 <internalGetUpdateNewTuple>, 
          relaction = 0x0, tmfd = {ctid = {ip_blkid = {bi_hi = 0, 
                bi_lo = 19779}, ip_posid = 0}, xmax = 1258818464, 
            cmax = 21985, traversed = 161}, 
          cpUpdateRetrySlot = 0xcd2553e428217300, 
          cpUpdateReturningSlot = 0x7ffc44823c50}
        estate = 0x55e1468ffc20
        operation = CMD_UPDATE
        resultRelInfo = 0x55e14b07ec80
        subplanstate = 0x55e14b07ef78
        slot = 0x55e14693e4f0
        oldSlot = 0x55e14693e280
        tuple_ctid = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 3}
        oldtupdata = {t_len = 16, t_self = {ip_blkid = {bi_hi = 0, 
              bi_lo = 0}, ip_posid = 0}, t_tableOid = 0, t_data = 0x0}
        oldtuple = 0x0
        tupleid = 0x7ffc44823b72
        __func__ = "ExecModifyTable"
#15 0x000055e143ae5eb2 in ExecProcNodeFirst (node=0x55e146901900)
    at execProcnode.c:464
No locals.
#16 0x000055e143ad969f in ExecProcNode (node=0x55e146901900)
    at ../../../src/include/executor/executor.h:259
No locals.
#17 0x000055e143adc3b1 in ExecutePlan (estate=0x55e1468ffc20, 
    planstate=0x55e146901900, use_parallel_mode=false, operation=CMD_UPDATE,

    sendTuples=true, numberTuples=0, direction=ForwardScanDirection, 
    dest=0x55e150a50bc8, execute_once=true) at execMain.c:1636
        slot = 0x2437ddd10
        current_tuple_count = 0
#18 0x000055e143ad9d79 in standard_ExecutorRun (queryDesc=0x55e150a50c60, 
    direction=ForwardScanDirection, count=0, execute_once=true)
    at execMain.c:363
        estate = 0x55e1468ffc20
        operation = CMD_UPDATE
        dest = 0x55e150a50bc8
        sendTuples = true
        oldcontext = 0x55e150a50970
        __func__ = "standard_ExecutorRun"
#19 0x00007f3b878be203 in pgss_ExecutorRun (queryDesc=0x55e150a50c60, 
    direction=ForwardScanDirection, count=0, execute_once=true)
    at pg_stat_statements.c:1010
        _save_exception_stack = 0x7ffc44824050
        _save_context_stack = 0x0
        _local_sigjmp_buf = {{__jmpbuf = {94425996395472, 
              -3663643427010865258, 94425988324624, 140721457874784, 0, 0,

              -3663643427042322538, -3699819632856623210}, 
            __mask_was_saved = 0, __saved_mask = {__val = {94426039843584,

                94426114820576, 448, 0, 0, 140721457872464, 
                14782313591304450816, 140721457872464, 94425991562550, 0, 
                94426208995696, 4311810336, 94426039843584, 140721457872512,

                139893653889288, 0}}}}
        _do_rethrow = false
#20 0x000055e143ad9b6f in ExecutorRun (queryDesc=0x55e150a50c60, 
    direction=ForwardScanDirection, count=0, execute_once=true)
    at execMain.c:305
No locals.
#21 0x000055e143d48e2b in ProcessQuery (plan=0x55e148d80ee8, 
    sourceText=0x55e146177d40 "update public.brintest_multi set \n  int8col
= pg_catalog.hashint4extended(\n    cast(public.brintest_multi.int4col as
int4),\n    cast(pg_catalog.pg_stat_get_bgwriter_requested_checkpoints() as
int8)), "..., params=0x0, queryEnv=0x0, dest=0x55e150a50bc8,
qc=0x7ffc44823f90)
    at pquery.c:160
        queryDesc = 0x55e150a50c60
#22 0x000055e143d4a989 in PortalRunMulti (portal=0x55e147d1ab20, 
    isTopLevel=true, setHoldSnapshot=true, dest=0x55e150a50bc8, 
    altdest=0x55e144252940 <donothingDR>, qc=0x7ffc44823f90) at
pquery.c:1277
        pstmt = 0x55e148d80ee8
        stmtlist_item__state = {l = 0x55e148d81bb0, i = 0}
        active_snapshot_set = true
        stmtlist_item = 0x55e148d81bc8
#23 0x000055e143d4a4b3 in FillPortalStore (portal=0x55e147d1ab20, 
    isTopLevel=true) at pquery.c:1026
        treceiver = 0x55e150a50bc8
        qc = {commandTag = CMDTAG_UNKNOWN, nprocessed = 0}
        __func__ = "FillPortalStore"
#24 0x000055e143d49dcc in PortalRun (portal=0x55e147d1ab20, 
    count=9223372036854775807, isTopLevel=true, run_once=true, 
    dest=0x55e148d81be8, altdest=0x55e148d81be8, qc=0x7ffc448241d0)
    at pquery.c:763
        _save_exception_stack = 0x7ffc448242e0
        _save_context_stack = 0x0
        _local_sigjmp_buf = {{__jmpbuf = {94425996395472, 
              -3663643429315635306, 94425988324624, 140721457874784, 0, 0,

              -3663643426998282346, -7416846826455394410}, 
            __mask_was_saved = 0, __saved_mask = {__val = {94426078125144,

                4869, 94426031944688, 94426078125032, 112, 0, 0, 0, 
                14782313591304450816, 140721457873168, 94425988439072, 
                140721457873200, 9727941148, 0, 94426078125032, 
                94426060925728}}}}
        _do_rethrow = false
        result = false
        nprocessed = 94425996138368
        saveTopTransactionResourceOwner = 0x55e1461cea80
        saveTopTransactionContext = 0x55e1461b5df0
        saveActivePortal = 0x0
        saveResourceOwner = 0x55e1461cea80
        savePortalContext = 0x0
        saveMemoryContext = 0x55e1461b5df0
        __func__ = "PortalRun"
#25 0x000055e143d43067 in exec_simple_query (
    query_string=0x55e146177d40 "update public.brintest_multi set \n
int8col = pg_catalog.hashint4extended(\n
cast(public.brintest_multi.int4col as int4),\n
cast(pg_catalog.pg_stat_get_bgwriter_requested_checkpoints() as int8)),
"...) at postgres.c:1250
        snapshot_set = true
        per_parsetree_context = 0x0
        plantree_list = 0x55e148d81bb0
        parsetree = 0x55e1492c3050
        commandTag = CMDTAG_UPDATE
        qc = {commandTag = CMDTAG_UNKNOWN, nprocessed = 0}
        querytree_list = 0x55e14fa8aad0
        portal = 0x55e147d1ab20
        receiver = 0x55e148d81be8
        format = 0
        parsetree_item__state = {l = 0x55e1492c3088, i = 0}
        dest = DestRemote
        oldcontext = 0x55e1461b5df0
        parsetree_list = 0x55e1492c3088
        parsetree_item = 0x55e1492c30a0
        save_log_statement_stats = false
        was_logged = false
        use_implicit_block = false
        msec_str =
"\020B\202D\374\177\000\000e,\266C\341U\000\000\000\000\000\000\000\000\000\000\240B\202D\374\177\000"
        __func__ = "exec_simple_query"
#26 0x000055e143d47c8c in PostgresMain (dbname=0x55e1461ce9c0 "postgres", 
    username=0x55e1461ce9a0 "u81") at postgres.c:4593
        query_string = 0x55e146177d40 "update public.brintest_multi set \n
int8col = pg_catalog.hashint4extended(\n
cast(public.brintest_multi.int4col as int4),\n
cast(pg_catalog.pg_stat_get_bgwriter_requested_checkpoints() as int8)),
"...
        firstchar = 81
        input_message = {
          data = 0x55e146177d40 "update public.brintest_multi set \n
int8col = pg_catalog.hashint4extended(\n
cast(public.brintest_multi.int4col as int4),\n
cast(pg_catalog.pg_stat_get_bgwriter_requested_checkpoints() as int8)),
"..., len = 2008, maxlen = 2048, cursor = 2008}
        local_sigjmp_buf = {{__jmpbuf = {94425996395472, 
              -3663643429277886570, 94425988324624, 140721457874784, 0, 0,

              -3663643429282080874, -7416846831724882026}, 
            __mask_was_saved = 1, __saved_mask = {__val = {4194304, 
                139893708792864, 645248, 94426031943624, 0, 94426031916160,

                139893253697616, 4869, 94426031916160, 139893253697616, 
                645248, 0, 94426031944688, 4294967297, 94426031916160, 
                140721457873856}}}}
        send_ready_for_query = false
        idle_in_transaction_timeout_enabled = false
        idle_session_timeout_enabled = false
        __func__ = "PostgresMain"
#27 0x000055e143c73785 in BackendRun (port=0x55e1461d31f0)
    at postmaster.c:4511
No locals.
#28 0x000055e143c73056 in BackendStartup (port=0x55e1461d31f0)
    at postmaster.c:4239
        bn = 0x55e1461b2760
        pid = 0
        __func__ = "BackendStartup"
#29 0x000055e143c6f142 in ServerLoop () at postmaster.c:1806
        port = 0x55e1461d31f0
        i = 0
        rmask = {fds_bits = {32, 0 <repeats 15 times>}}
        selres = 1
        now = 1675609473
        readmask = {fds_bits = {96, 0 <repeats 15 times>}}
        nSockets = 7
        last_lockfile_recheck_time = 1675609457
        last_touch_time = 1675608541
        __func__ = "ServerLoop"



SQL - mostly irrelevant + didn't reduce since assert() is not reproducible
===
update public.brintest_multi set
                    
  int8col = pg_catalog.hashint4extended(
                    
    cast(public.brintest_multi.int4col as int4),
                    
    cast(pg_catalog.pg_stat_get_bgwriter_requested_checkpoints() as int8)),
                    
  int2col = public.brintest_multi.int2col,
                    
  int4col = public.brintest_multi.int4col,
                    
  oidcol = pg_catalog.pg_my_temp_schema(),
                    
  tidcol = pg_catalog.currtid2(
                    
    cast(pg_catalog.ts_headline(
                    
      cast(pg_catalog.get_current_ts_config() as regconfig),
                    
      cast(public.large_val() as text),
                    
      cast((select tsquery from public.tab_core_types limit 1 offset 34)
                    
         as tsquery)) as text),
                    
    cast(public.brintest_multi.tidcol as tid)),
                    
  float8col = public.brintest_multi.float8col,
                    
  macaddr8col = public.brintest_multi.macaddr8col,
                    
  inetcol = pg_catalog.set_masklen(
                    
    cast(pg_catalog.inet_server_addr() as inet),
                    
    cast(pg_catalog.pg_trigger_depth() as int4)),
                    
  cidrcol = pg_catalog.set_masklen(
                    
    cast(public.brintest_multi.cidrcol as cidr),
                    
    cast(pg_catalog.inet_client_port() as int4)),
                    
  datecol = pg_catalog.make_date(
                    
    cast(public.citext_pattern_cmp(
                    
      cast(public.citext(
                    
        cast(public.brintest_multi.inetcol as inet)) as public.citext),
                    
      cast(cast(null as public.citext) as public.citext)) as int4),
                    
    cast(pg_catalog.hashinet(
                    
      cast(pg_catalog.inet_server_addr() as inet)) as int4),
                    
    cast(public.func_with_bad_set() as int4)),
                    
  timecol = pg_catalog.time_in(
                    
    cast(cast(null as cstring) as cstring),
                    
    cast(public.brintest_multi.oidcol as oid),
                    
    cast(pg_catalog.hashint2(
                    
      cast(cast(coalesce(public.brintest_multi.int2col,
                    
        public.brintest_multi.int2col) as int2) as int2)) as int4)),
                    
  timestampcol = pg_catalog.timestamp(
                    
    cast(cast(null as "timestamp") as "timestamp"),
                    
    cast(public.brintest_multi.int4col as int4)),
                    
  timetzcol = pg_catalog.timetz(
                    
    cast(pg_catalog.transaction_timestamp() as timestamptz)),
                    
  lsncol = public.brintest_multi.lsncol
                    
returning
                    
  pg_catalog.jsonb_build_object() as c0;


Thanks to SQLSmith for the find.

-
Robins Tharakan
Amazon Web Services


Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
John Naylor
Date:
On Mon, Feb 6, 2023 at 3:06 PM PG Bug reporting form <noreply@postgresql.org> wrote:
> This assert() is not easily reproducible, but thought the backtraces may be
> interesting.
>
> TRAP: FailedAssertion("(delta >= 0) && (delta <= 1)", File:
> "brin_minmax_multi.c", Line: 2393, PID: 2922100)

> #2  0x000055e143f0ae8b in ExceptionalCondition (
>     conditionName=0x55e143f92604 "(delta >= 0) && (delta <= 1)",
>     errorType=0x55e143f91ef4 "FailedAssertion",
>     fileName=0x55e143f91ee0 "brin_minmax_multi.c", lineNumber=2393)
>     at assert.c:69
> No locals.
> #3  0x000055e1437e8972 in brin_minmax_multi_distance_inet (
>     fcinfo=0x7ffc448234f0) at brin_minmax_multi.c:2393
>         delta = -2.3283064365386963e-10
>         i = -1
>         len = 4
>         addra = 0x55e14ee95fc0 ""
>         addrb = 0x55e14ee95fe0 ""
>         ipa = 0x55e14d95a1e0
>         ipb = 0x55e149a6fdc8
>         lena = 0
>         lenb = 32

Thanks for the report! From the stack trace we can see that it computed a negative delta, coming from:

/* Calculate the difference between the addresses. */
delta = 0;
for (i = len - 1; i >= 0; i--)
{
  unsigned char a = addra[i];
  unsigned char b = addrb[i];

  delta += (float8) b - (float8) a;
  delta /= 256;
}
Assert((delta >= 0) && (delta <= 1));

I wonder if it needs to be something like "delta += Abs((float8) b - (float8) a);". 

--
John Naylor
EDB: http://www.enterprisedb.com

Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Dmitry Dolgov
Date:
> On Wed, Feb 08, 2023 at 04:26:49PM +0700, John Naylor wrote:
> On Mon, Feb 6, 2023 at 3:06 PM PG Bug reporting form <noreply@postgresql.org>
> wrote:
> > This assert() is not easily reproducible, but thought the backtraces may
> be
> > interesting.
> >
> > TRAP: FailedAssertion("(delta >= 0) && (delta <= 1)", File:
> > "brin_minmax_multi.c", Line: 2393, PID: 2922100)
>
> > #2  0x000055e143f0ae8b in ExceptionalCondition (
> >     conditionName=0x55e143f92604 "(delta >= 0) && (delta <= 1)",
> >     errorType=0x55e143f91ef4 "FailedAssertion",
> >     fileName=0x55e143f91ee0 "brin_minmax_multi.c", lineNumber=2393)
> >     at assert.c:69
> > No locals.
> > #3  0x000055e1437e8972 in brin_minmax_multi_distance_inet (
> >     fcinfo=0x7ffc448234f0) at brin_minmax_multi.c:2393
> >         delta = -2.3283064365386963e-10
> >         i = -1
> >         len = 4
> >         addra = 0x55e14ee95fc0 ""
> >         addrb = 0x55e14ee95fe0 ""
> >         ipa = 0x55e14d95a1e0
> >         ipb = 0x55e149a6fdc8
> >         lena = 0
> >         lenb = 32
>
> Thanks for the report! From the stack trace we can see that it computed a
> negative delta, coming from:
>
> /* Calculate the difference between the addresses. */
> delta = 0;
> for (i = len - 1; i >= 0; i--)
> {
>   unsigned char a = addra[i];
>   unsigned char b = addrb[i];
>
>   delta += (float8) b - (float8) a;
>   delta /= 256;
> }
> Assert((delta >= 0) && (delta <= 1));
>
> I wonder if it needs to be something like "delta += Abs((float8) b -
> (float8) a);".

The negative delta might be only a consequence. From what I see it's
called from build_distances, and the idea is to find the gaps between
the max value of the current interval and the min value of the next one,
so they should be ordered and delta should be always positive.

In fact, I've just reproduced it by randomly inserting some inets into
the test table, let me see if I can get a stable reproducer.



Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Dmitry Dolgov
Date:
> On Wed, Feb 08, 2023 at 11:06:58AM +0100, Dmitry Dolgov wrote:
> > On Wed, Feb 08, 2023 at 04:26:49PM +0700, John Naylor wrote:
> > On Mon, Feb 6, 2023 at 3:06 PM PG Bug reporting form <noreply@postgresql.org>
> > wrote:
> > > This assert() is not easily reproducible, but thought the backtraces may
> > be
> > > interesting.
> > >
> > > TRAP: FailedAssertion("(delta >= 0) && (delta <= 1)", File:
> > > "brin_minmax_multi.c", Line: 2393, PID: 2922100)
> >
> > > #2  0x000055e143f0ae8b in ExceptionalCondition (
> > >     conditionName=0x55e143f92604 "(delta >= 0) && (delta <= 1)",
> > >     errorType=0x55e143f91ef4 "FailedAssertion",
> > >     fileName=0x55e143f91ee0 "brin_minmax_multi.c", lineNumber=2393)
> > >     at assert.c:69
> > > No locals.
> > > #3  0x000055e1437e8972 in brin_minmax_multi_distance_inet (
> > >     fcinfo=0x7ffc448234f0) at brin_minmax_multi.c:2393
> > >         delta = -2.3283064365386963e-10
> > >         i = -1
> > >         len = 4
> > >         addra = 0x55e14ee95fc0 ""
> > >         addrb = 0x55e14ee95fe0 ""
> > >         ipa = 0x55e14d95a1e0
> > >         ipb = 0x55e149a6fdc8
> > >         lena = 0
> > >         lenb = 32
> >
> > Thanks for the report! From the stack trace we can see that it computed a
> > negative delta, coming from:
> >
> > /* Calculate the difference between the addresses. */
> > delta = 0;
> > for (i = len - 1; i >= 0; i--)
> > {
> >   unsigned char a = addra[i];
> >   unsigned char b = addrb[i];
> >
> >   delta += (float8) b - (float8) a;
> >   delta /= 256;
> > }
> > Assert((delta >= 0) && (delta <= 1));
> >
> > I wonder if it needs to be something like "delta += Abs((float8) b -
> > (float8) a);".
>
> The negative delta might be only a consequence. From what I see it's
> called from build_distances, and the idea is to find the gaps between
> the max value of the current interval and the min value of the next one,
> so they should be ordered and delta should be always positive.
>
> In fact, I've just reproduced it by randomly inserting some inets into
> the test table, let me see if I can get a stable reproducer.

Yep, this sequence reproduces the issue reliably for me:

    create table brin_test (data inet);
    create index brin_multi on brin_test using brin (data inet_minmax_multi_ops);

    insert into brin_test values('127.0.0.1/0');
    insert into brin_test values('2001:db8:3333:4444:5555:6666:7777:8888');
    insert into brin_test values('0.0.0.0/12');

    TRAP: failed Assert("(delta >= 0) && (delta <= 1)"), File: "brin_minmax_multi.c", Line: 2389, PID: 76147
    [local] INSERT(ExceptionalCondition+0x9e)[0xb432a7]
    [local] INSERT(brin_minmax_multi_distance_inet+0x409)[0x494345]
    [local] INSERT(FunctionCall2Coll+0x99)[0xb4e027]
    [local] INSERT[0x4922c8]
    [local] INSERT[0x492deb]
    [local] INSERT[0x4943a7]
    [local] INSERT(brin_form_tuple+0x231)[0x498dd4]
    [local] INSERT(brininsert+0x406)[0x48a35f]
    [...]



Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Tom Lane
Date:
Dmitry Dolgov <9erthalion6@gmail.com> writes:
> The negative delta might be only a consequence. From what I see it's
> called from build_distances, and the idea is to find the gaps between
> the max value of the current interval and the min value of the next one,
> so they should be ordered and delta should be always positive.

I'd believe this argument more readily if the calculation weren't being
done in float arithmetic.  Since it is, you're at the mercy of roundoff
error ... and that small negative delta could certainly pass for
roundoff error.

Clamping the result to [0,1] would be a brighter plan than just asserting
that it's in-range.

            regards, tom lane



Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Dmitry Dolgov
Date:
> On Wed, Feb 08, 2023 at 10:03:01AM -0500, Tom Lane wrote:
> Dmitry Dolgov <9erthalion6@gmail.com> writes:
> > The negative delta might be only a consequence. From what I see it's
> > called from build_distances, and the idea is to find the gaps between
> > the max value of the current interval and the min value of the next one,
> > so they should be ordered and delta should be always positive.
>
> I'd believe this argument more readily if the calculation weren't being
> done in float arithmetic.  Since it is, you're at the mercy of roundoff
> error ... and that small negative delta could certainly pass for
> roundoff error.
>
> Clamping the result to [0,1] would be a brighter plan than just asserting
> that it's in-range.

Hmm...yeah, good point. In both the reproducer I've posted and the
backtrace from the thread the delta is indeed rather small.



Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Tom Lane
Date:
Dmitry Dolgov <9erthalion6@gmail.com> writes:
>> On Wed, Feb 08, 2023 at 10:03:01AM -0500, Tom Lane wrote:
>> I'd believe this argument more readily if the calculation weren't being
>> done in float arithmetic.  Since it is, you're at the mercy of roundoff
>> error ... and that small negative delta could certainly pass for
>> roundoff error.

> Hmm...yeah, good point. In both the reproducer I've posted and the
> backtrace from the thread the delta is indeed rather small.

I bet also it only fails when dealing with IPv6 addresses.
With 32-bit IPv4 addresses, a float8 would have enough mantissa
bits that the calculation wouldn't become imprecise.

            regards, tom lane



Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
John Naylor
Date:

On Wed, Feb 8, 2023 at 11:05 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> Dmitry Dolgov <9erthalion6@gmail.com> writes:
> >> On Wed, Feb 08, 2023 at 10:03:01AM -0500, Tom Lane wrote:
> >> I'd believe this argument more readily if the calculation weren't being
> >> done in float arithmetic.  Since it is, you're at the mercy of roundoff
> >> error ... and that small negative delta could certainly pass for
> >> roundoff error.
>
> > Hmm...yeah, good point. In both the reproducer I've posted and the
> > backtrace from the thread the delta is indeed rather small.
>
> I bet also it only fails when dealing with IPv6 addresses.
> With 32-bit IPv4 addresses, a float8 would have enough mantissa
> bits that the calculation wouldn't become imprecise.

Addresses from different families are treated as a distance of one, so I don't think inserting a single IPv6 address would get this far, and in fact I still get a crash in an empty table by taking out the IPv6 address from Dmitry's example:

insert into brin_test values('127.0.0.1/0');
insert into brin_test values('0.0.0.0/12');

Adding some debug calls shows it starts off negative from the start:

=# insert into brin_test values('127.0.0.1/0');
INSERT 0 1
=#  insert into brin_test values('0.0.0.0/12');
NOTICE:  idx: 3 before div: -1.000000
NOTICE:  idx: 3 after div: -0.003906
NOTICE:  idx: 2 before div: -0.003906
NOTICE:  idx: 2 after div: -0.000015
NOTICE:  idx: 1 before div: -0.000015
NOTICE:  idx: 1 after div: -0.000000
NOTICE:  idx: 0 before div: -0.000000
NOTICE:  idx: 0 after div: -0.000000

...so something else is wrong here but I haven't dug deeper yet.

--
John Naylor
EDB: http://www.enterprisedb.com

Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Tomas Vondra
Date:

On 2/9/23 04:53, John Naylor wrote:
> 
> On Wed, Feb 8, 2023 at 11:05 PM Tom Lane <tgl@sss.pgh.pa.us
> <mailto:tgl@sss.pgh.pa.us>> wrote:
>>
>> Dmitry Dolgov <9erthalion6@gmail.com <mailto:9erthalion6@gmail.com>>
> writes:
>> >> On Wed, Feb 08, 2023 at 10:03:01AM -0500, Tom Lane wrote:
>> >> I'd believe this argument more readily if the calculation weren't being
>> >> done in float arithmetic.  Since it is, you're at the mercy of roundoff
>> >> error ... and that small negative delta could certainly pass for
>> >> roundoff error.
>>
>> > Hmm...yeah, good point. In both the reproducer I've posted and the
>> > backtrace from the thread the delta is indeed rather small.
>>
>> I bet also it only fails when dealing with IPv6 addresses.
>> With 32-bit IPv4 addresses, a float8 would have enough mantissa
>> bits that the calculation wouldn't become imprecise.
> 
> Addresses from different families are treated as a distance of one, so I
> don't think inserting a single IPv6 address would get this far, and in
> fact I still get a crash in an empty table by taking out the IPv6
> address from Dmitry's example:
> 
> insert into brin_test values('127.0.0.1/0' <http://127.0.0.1/0'>);
> insert into brin_test values('0.0.0.0/12' <http://0.0.0.0/12'>);
> 
> Adding some debug calls shows it starts off negative from the start:
> 
> =# insert into brin_test values('127.0.0.1/0' <http://127.0.0.1/0'>);
> INSERT 0 1
> =#  insert into brin_test values('0.0.0.0/12' <http://0.0.0.0/12'>);
> NOTICE:  idx: 3 before div: -1.000000
> NOTICE:  idx: 3 after div: -0.003906
> NOTICE:  idx: 2 before div: -0.003906
> NOTICE:  idx: 2 after div: -0.000015
> NOTICE:  idx: 1 before div: -0.000015
> NOTICE:  idx: 1 after div: -0.000000
> NOTICE:  idx: 0 before div: -0.000000
> NOTICE:  idx: 0 after div: -0.000000
> 
> ...so something else is wrong here but I haven't dug deeper yet.
> 

I believe the bug is pretty trivial - the code applies the netmask
incorrectly, so that with 127.0.0.1/0 it ends with 0.0.0.1, and because
it assumes 0.0.0.1 < 0.0.0.0 it ends with negative delta.

In particular, the issue is that the code does this:

    lena = ip_bits(ipa);     -- 0
    len = ip_addrsize(ipa);  -- 4

    for (for (i = 0; i < len; i++)
    {
      nbits = lena - (i * 8);
      ...
      mask = (0xFF << (8 - nbits));
      ...
    }

But for 127.0.0.1/0 we get lena=0, so for i>0 nbits gets negative, and
the shift is probably going to do something silly (not sure what
exactly, but AFAICS it's undefined behavior).

Attached is a fixup that resolves this failure for me. I need to look a
bit closer if there are some other issues (e.g. with the float rounding
errors, etc.).

Good thing is this is this won't break anything without the assert - we
may pick incorrect ranges to merge, so the index is a bit less
efficient, but still valid/correct.


-- 
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Attachment

Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Dmitry Dolgov
Date:
> On Thu, Feb 09, 2023 at 05:18:47PM +0100, Tomas Vondra wrote:
>
> I believe the bug is pretty trivial - the code applies the netmask
> incorrectly, so that with 127.0.0.1/0 it ends with 0.0.0.1, and because
> it assumes 0.0.0.1 < 0.0.0.0 it ends with negative delta.
>
> In particular, the issue is that the code does this:
>
>     lena = ip_bits(ipa);     -- 0
>     len = ip_addrsize(ipa);  -- 4
>
>     for (for (i = 0; i < len; i++)
>     {
>       nbits = lena - (i * 8);
>       ...
>       mask = (0xFF << (8 - nbits));
>       ...
>     }
>
> But for 127.0.0.1/0 we get lena=0, so for i>0 nbits gets negative, and
> the shift is probably going to do something silly (not sure what
> exactly, but AFAICS it's undefined behavior).
>
> Attached is a fixup that resolves this failure for me. I need to look a
> bit closer if there are some other issues (e.g. with the float rounding
> errors, etc.).

Thanks, the fix looks good and solves the issue. With the patch applied
after a quick round of testing I haven't found any failures so far,
whether due to float arithmetic or something else.



Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Dmitry Dolgov
Date:
> On Sat, Feb 11, 2023 at 08:00:37PM +0100, Dmitry Dolgov wrote:
> > On Thu, Feb 09, 2023 at 05:18:47PM +0100, Tomas Vondra wrote:
> >
> > I believe the bug is pretty trivial - the code applies the netmask
> > incorrectly, so that with 127.0.0.1/0 it ends with 0.0.0.1, and because
> > it assumes 0.0.0.1 < 0.0.0.0 it ends with negative delta.
> >
> > In particular, the issue is that the code does this:
> >
> >     lena = ip_bits(ipa);     -- 0
> >     len = ip_addrsize(ipa);  -- 4
> >
> >     for (for (i = 0; i < len; i++)
> >     {
> >       nbits = lena - (i * 8);
> >       ...
> >       mask = (0xFF << (8 - nbits));
> >       ...
> >     }
> >
> > But for 127.0.0.1/0 we get lena=0, so for i>0 nbits gets negative, and
> > the shift is probably going to do something silly (not sure what
> > exactly, but AFAICS it's undefined behavior).
> >
> > Attached is a fixup that resolves this failure for me. I need to look a
> > bit closer if there are some other issues (e.g. with the float rounding
> > errors, etc.).
>
> Thanks, the fix looks good and solves the issue. With the patch applied
> after a quick round of testing I haven't found any failures so far,
> whether due to float arithmetic or something else.

It occurred to me this fix wasn't applied yet, right? Are there any
concerns about it?



Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Tomas Vondra
Date:
On 3/17/23 21:20, Dmitry Dolgov wrote:
>> ...
> 
> It occurred to me this fix wasn't applied yet, right? Are there any
> concerns about it?

Thanks for reminding me, I had it on the back burner. I added a trivial
regression test, polished the commit message a bit and pushed it
(including backpatching).

regards

-- 
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: BUG #17774: Assert triggered on brin_minmax_multi.c

From
Dmitry Dolgov
Date:
> On Mon, Mar 20, 2023 at 10:31:14AM +0100, Tomas Vondra wrote:
>
> On 3/17/23 21:20, Dmitry Dolgov wrote:
> >> ...
> >
> > It occurred to me this fix wasn't applied yet, right? Are there any
> > concerns about it?
>
> Thanks for reminding me, I had it on the back burner. I added a trivial
> regression test, polished the commit message a bit and pushed it
> (including backpatching).

Great, thank you.