On 5 April 2017 at 08:23, Craig Ringer <cr...@2ndquadrant.com> wrote:
> On 5 April 2017 at 08:00, Craig Ringer <cr...@2ndquadrant.com> wrote:
>
>> Taking a look at this now.
>
> Rebased to current master with conflicts and whitespace errors fixed.
> Review pending.

This patch fails to update the documentation at all.

https://www.postgresql.org/docs/devel/static/spi.html



The patch crashes in initdb with --enable-cassert builds:

performing post-bootstrap initialization ... TRAP:
FailedAssertion("!(myState->pub.mydest == DestSQLFunction)", File:
"functions.c", Line: 800)
sh: line 1: 30777 Aborted                 (core dumped)
"/home/craig/projects/2Q/postgres/tmp_install/home/craig/pg/10/bin/postgres"
--single -F -O -j -c search_path=pg_catalog -c exit_on_error=true
template1 > /dev/null
child process exited with exit code 134

Backtrace attached.




Details on patch 1:

missing newline

+}
+int
+SPI_execute_callback(const char *src, bool read_only, long tcount,


+/* Execute a previously prepared plan with a callback Destination */


caps "Destination"



+                // XXX throw error if callback is set

^^



+static DestReceiver spi_callbackDR = {
+    donothingReceive, donothingStartup, donothingCleanup, donothingCleanup,
+    DestSPICallback
+};


Is the callback destreceiver supposed to be a blackhole? Why? Its
name, spi_callbackDR and DestSPICallback, doesn't seem to indicate
that it drops its input.

Presumably that's a default destination you're then supposed to modify
with your own callbacks? There aren't any comments to indicate what's
going on here.



Comments on patch 2:

If this is the "bare minimum" patch, what is pending? Does it impose
any downsides or limits?

+/* Get switch execution contexts */
+extern PLyExecutionContext
*PLy_switch_execution_context(PLyExecutionContext *new);

Comment makes no sense to me. This seems something like memory context
switch, where you supply the new and return the old. But the comment
doesn't explain it at all.

+void PLy_CSStartup(DestReceiver *self, int operation, TupleDesc typeinfo);
+void PLy_CSDestroy(DestReceiver *self);

These are declared in the plpy_spi.c. Why aren't these static?

+    volatile MemoryContext oldcontext;
+    volatile ResourceOwner oldowner;
     int         rv;
-    volatile MemoryContext oldcontext;
-    volatile ResourceOwner oldowner;

Unnecessary code movement.

In PLy_Callback_New, I think your use of a sub-context is sensible. Is
it necessary to palloc0 though?

+static CallbackState *
+PLy_Callback_Free(CallbackState *callback)

The code here looks like it could be part of spi.c's callback support,
rather than plpy_spi specific, since you provide a destroy callback in
the SPI callback struct.

+    /* We need to store this because the TupleDesc the receive
function gets has no names. */
+    myState->desc = typeinfo;

Is it safe to just store the pointer to the TupleDesc here? What's the lifetime?

+     * will clean it up when the time is right. XXX This might result in a leak
+     * if an error happens and the result doesn't get dereferenced.
+     */
+    MemoryContextSwitchTo(TopMemoryContext);
+    result->tupdesc = CreateTupleDescCopy(typeinfo);

especially given this XXX comment...


Patch needs bug fix, docs updates, fixes for issues marked in
comments. But overall approach looks sensible enough.

-- 
 Craig Ringer                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
#0  0x00007f9d5d64ea28 in raise () from /lib64/libc.so.6
No symbol table info available.
#1  0x00007f9d5d65062a in abort () from /lib64/libc.so.6
No symbol table info available.
#2  0x000000000083a521 in ExceptionalCondition 
(conditionName=conditionName@entry=0x9b68d0 "!(myState->pub.mydest == 
DestSQLFunction)", errorType=errorType@entry=0x882d29 "FailedAssertion", 
fileName=fileName@entry=0x9b6920 "functions.c", 
lineNumber=lineNumber@entry=800) at assert.c:54
No locals.
#3  0x00000000006166e8 in postquel_start (fcache=0x27772c0, es=0x284eb58) at 
functions.c:800
        myState = 0x284eeb8
        dest = 0x284eeb8
#4  fmgr_sql (fcinfo=0x27a7a28) at functions.c:1149
        fcache = 0x27772c0
        sqlerrcontext = {previous = 0x0, callback = 0x614910 
<sql_exec_error_callback>, arg = 0x27a79d0}
        randomAccess = 0 '\000'
        lazyEvalOK = <optimized out>
        is_first = <optimized out>
        pushed_snapshot = 0 '\000'
        es = 0x284eb58
        slot = <optimized out>
        result = <optimized out>
        eslist = <optimized out>
        eslc = 0x284eb90
        __func__ = "fmgr_sql"
#5  0x000000000060810b in ExecInterpExpr (state=0x27a7528, econtext=0x27a4ce0, 
isnull=<optimized out>) at execExprInterp.c:670
        fcinfo = 0x27a7a28
        argnull = 0x27a7d68 ""
        argno = <optimized out>
        op = 0x27a76f8
        resultslot = 0x27a7130
        innerslot = <optimized out>
        outerslot = 0x27a5930
        scanslot = 0x0
        dispatch_table = {0x608960 <ExecInterpExpr+3424>, 0x607e00 
<ExecInterpExpr+512>, 0x607e20 <ExecInterpExpr+544>, 0x607e38 
<ExecInterpExpr+568>, 0x607c90 <ExecInterpExpr+144>, 0x607cb0 
<ExecInterpExpr+176>, 0x607cf8 <ExecInterpExpr+248>, 0x607d14 
<ExecInterpExpr+276>, 0x607d58 <ExecInterpExpr+344>, 0x607d73 
<ExecInterpExpr+371>, 0x607e50 <ExecInterpExpr+592>, 0x607ea8 
<ExecInterpExpr+680>, 0x607ee0 <ExecInterpExpr+736>, 0x607f18 
<ExecInterpExpr+792>, 0x607f30 <ExecInterpExpr+816>, 0x607f80 
<ExecInterpExpr+896>, 0x607fb8 <ExecInterpExpr+952>, 0x607ff0 
<ExecInterpExpr+1008>, 0x608018 <ExecInterpExpr+1048>, 0x608050 
<ExecInterpExpr+1104>, 0x608070 <ExecInterpExpr+1136>, 0x6080b0 
<ExecInterpExpr+1200>, 0x608130 <ExecInterpExpr+1328>, 0x608238 
<ExecInterpExpr+1592>, 0x607db0 <ExecInterpExpr+432>, 0x607db7 
<ExecInterpExpr+439>, 0x6081f8 <ExecInterpExpr+1528>, 0x607c60 
<ExecInterpExpr+96>, 0x607c67 <ExecInterpExpr+103>, 0x608190 
<ExecInterpExpr+1424>, 0x6081b0 <ExecInterpExpr+1456>, 0x6081c8 
<ExecInterpExpr+1480>, 0x6082d0 <ExecInterpExpr+1744>, 0x6082d8 
<ExecInterpExpr+1752>, 0x6082f0 <ExecInterpExpr+1776>, 0x608308 
<ExecInterpExpr+1800>, 0x608330 <ExecInterpExpr+1840>, 0x608350 
<ExecInterpExpr+1872>, 0x608360 <ExecInterpExpr+1888>, 0x608380 
<ExecInterpExpr+1920>, 0x608388 <ExecInterpExpr+1928>, 0x6083b0 
<ExecInterpExpr+1968>, 0x6083d8 <ExecInterpExpr+2008>, 0x6083f8 
<ExecInterpExpr+2040>, 0x608410 <ExecInterpExpr+2064>, 0x608430 
<ExecInterpExpr+2096>, 0x608448 <ExecInterpExpr+2120>, 0x6084a0 
<ExecInterpExpr+2208>, 0x6084c0 <ExecInterpExpr+2240>, 0x608550 
<ExecInterpExpr+2384>, 0x6085a0 <ExecInterpExpr+2464>, 0x6085d8 
<ExecInterpExpr+2520>, 0x6085f0 <ExecInterpExpr+2544>, 0x608600 
<ExecInterpExpr+2560>, 0x608618 <ExecInterpExpr+2584>, 0x608630 
<ExecInterpExpr+2608>, 0x608648 <ExecInterpExpr+2632>, 0x6086c0 
<ExecInterpExpr+2752>, 0x608710 <ExecInterpExpr+2832>, 0x608728 
<ExecInterpExpr+2856>, 0x608740 <ExecInterpExpr+2880>, 0x608760 
<ExecInterpExpr+2912>, 0x608780 <ExecInterpExpr+2944>, 0x6087a8 
<ExecInterpExpr+2984>, 0x6087c0 <ExecInterpExpr+3008>, 0x6087d8 
<ExecInterpExpr+3032>, 0x608478 <ExecInterpExpr+2168>, 0x608828 
<ExecInterpExpr+3112>, 0x608840 <ExecInterpExpr+3136>, 0x6087f0 
<ExecInterpExpr+3056>, 0x608810 <ExecInterpExpr+3088>, 0x608868 
<ExecInterpExpr+3176>, 0x608880 <ExecInterpExpr+3200>, 0x6088c0 
<ExecInterpExpr+3264>, 0x6088d8 <ExecInterpExpr+3288>, 0x608908 
<ExecInterpExpr+3336>, 0x608920 <ExecInterpExpr+3360>, 0x608940 
<ExecInterpExpr+3392>}
#6  0x0000000000621952 in ExecEvalExprSwitchContext (isNull=0x7ffe9582565c "", 
econtext=0x27a4ce0, state=0x27a7528) at 
../../../src/include/executor/executor.h:289
        oldContext = 0x268ac20
#7  ExecProject (projInfo=0x27a7520) at 
../../../src/include/executor/executor.h:323
        econtext = 0x27a4ce0
        state = 0x27a7528
        slot = 0x27a7130
        isnull = 0 '\000'
#8  ExecHashJoin (node=node@entry=0x27a4bc8) at nodeHashjoin.c:325
        outerNode = <optimized out>
        hashNode = <optimized out>
        otherqual = <optimized out>
        hashtable = 0x2773678
        hashvalue = 1944640558
        batchno = 0
        __func__ = "ExecHashJoin"
#9  0x000000000060ffd8 in ExecProcNode (node=0x27a4bc8) at execProcnode.c:520
        result = <optimized out>
        __func__ = "ExecProcNode"
#10 0x000000000062df64 in CteScanNext (node=node@entry=0x27a9908) at 
nodeCtescan.c:103
        cteslot = <optimized out>
        estate = <optimized out>
        dir = ForwardScanDirection
        forward = 1 '\001'
        tuplestorestate = 0x27a9a20
        eof_tuplestore = <optimized out>
        slot = 0x27aa750
#11 0x000000000061123a in ExecScanFetch (recheckMtd=0x62de60 <CteScanRecheck>, 
accessMtd=0x62de70 <CteScanNext>, node=0x27a9908) at execScan.c:95
        estate = <optimized out>
#12 ExecScan (node=node@entry=0x27a9908, accessMtd=accessMtd@entry=0x62de70 
<CteScanNext>, recheckMtd=recheckMtd@entry=0x62de60 <CteScanRecheck>) at 
execScan.c:162
        econtext = 0x27a9c50
        qual = 0x27a9d10
        projInfo = 0x0
#13 0x000000000062dfbf in ExecCteScan (node=node@entry=0x27a9908) at 
nodeCtescan.c:155
No locals.
#14 0x0000000000610048 in ExecProcNode (node=node@entry=0x27a9908) at 
execProcnode.c:489
        result = <optimized out>
        __func__ = "ExecProcNode"
#15 0x00000000006218a4 in ExecHashJoin (node=node@entry=0x27a8e10) at 
nodeHashjoin.c:136
        outerNode = <optimized out>
        hashNode = <optimized out>
        otherqual = <optimized out>
        hashtable = 0x0
        hashvalue = 0
        batchno = 41365104
        __func__ = "ExecHashJoin"
#16 0x000000000060ffd8 in ExecProcNode (node=node@entry=0x27a8e10) at 
execProcnode.c:520
        result = <optimized out>
        __func__ = "ExecProcNode"
#17 0x0000000000628b3e in ExecModifyTable (node=node@entry=0x27a8a00) at 
nodeModifyTable.c:1462
        estate = 0x27a4940
        operation = CMD_INSERT
        saved_resultRelInfo = 0x0
        resultRelInfo = 0x27a4ab0
        subplanstate = 0x27a8e10
        junkfilter = 0x0
        slot = <optimized out>
        planSlot = <optimized out>
        tupleid = 0x0
        tuple_ctid = {ip_blkid = {bi_hi = 35328, bi_lo = 634}, ip_posid = 0}
        oldtupdata = {t_len = 216, t_self = {ip_blkid = {bi_hi = 0, bi_lo = 0}, 
ip_posid = 61367}, t_tableOid = 0, t_data = 0x279fbe8}
        oldtuple = <optimized out>
        __func__ = "ExecModifyTable"
#18 0x0000000000610128 in ExecProcNode (node=node@entry=0x27a8a00) at 
execProcnode.c:424
        result = <optimized out>
        __func__ = "ExecProcNode"
#19 0x000000000060b75e in ExecutePlan (execute_once=<optimized out>, 
dest=0xd10be0 <debugtupDR>, direction=<optimized out>, numberTuples=0, 
sendTuples=<optimized out>, operation=CMD_INSERT, use_parallel_mode=<optimized 
out>, planstate=0x27a8a00, estate=0x27a4940) at execMain.c:1651
        slot = <optimized out>
        current_tuple_count = 0
#20 standard_ExecutorRun (queryDesc=0x2722300, direction=<optimized out>, 
count=0, execute_once=<optimized out>) at execMain.c:360
        estate = 0x27a4940
        operation = CMD_INSERT
        dest = 0xd10be0 <debugtupDR>
        sendTuples = <optimized out>
        __func__ = "standard_ExecutorRun"
#21 0x000000000073fb42 in ProcessQuery (plan=<optimized out>, 
sourceText=0x2673150 "WITH funcdescs AS ( SELECT p.oid as p_oid, oprname, 
coalesce(obj_description(o.oid, 'pg_operator'),'') as opdesc FROM pg_proc p 
JOIN pg_operator o ON oprcode = p.oid ) INSERT INTO pg_description   SEL"..., 
params=0x0, queryEnv=0x0, dest=0xd10be0 <debugtupDR>, 
completionTag=0x7ffe95825c30 "") at pquery.c:162
        queryDesc = 0x2722300
#22 0x000000000073fdb3 in PortalRunMulti (portal=portal@entry=0x26a9760, 
isTopLevel=isTopLevel@entry=1 '\001', setHoldSnapshot=setHoldSnapshot@entry=0 
'\000', dest=dest@entry=0xd10be0 <debugtupDR>, altdest=altdest@entry=0xd10be0 
<debugtupDR>, completionTag=completionTag@entry=0x7ffe95825c30 "") at 
pquery.c:1287
        active_snapshot_set = 1 '\001'
        stmtlist_item = 0x2754000
#23 0x00000000007409b3 in PortalRun (portal=portal@entry=0x26a9760, 
count=count@entry=9223372036854775807, isTopLevel=isTopLevel@entry=1 '\001', 
run_once=run_once@entry=1 '\001', dest=dest@entry=0xd10be0 <debugtupDR>, 
altdest=altdest@entry=0xd10be0 <debugtupDR>, completionTag=0x7ffe95825c30 "") 
at pquery.c:800
        save_exception_stack = 0x7ffe95825ea0
        save_context_stack = 0x0
        local_sigjmp_buf = {{__jmpbuf = {39972528, 3065876441714304163, 
40606192, 13700064, 40540000, 140731406769200, -3066668012307307357, 
3065872022924731555}, __mask_was_saved = 0, __saved_mask = {__val = {0, 0, 0, 
39972528, 8681844, 1, 40053440, 10715902, 40540000, 10715902, 1, 1, 1, 
140731406769200, 8801570, 41499144}}}}
        result = <optimized out>
        nprocessed = <optimized out>
        saveTopTransactionResourceOwner = 0x261eeb0
        saveTopTransactionContext = 0x26872a0
        saveActivePortal = 0x0
        saveResourceOwner = 0x261eeb0
        savePortalContext = 0x0
        saveMemoryContext = 0x26872a0
        __func__ = "PortalRun"
#24 0x000000000073c6b9 in exec_simple_query (query_string=0x2673150 "WITH 
funcdescs AS ( SELECT p.oid as p_oid, oprname, coalesce(obj_description(o.oid, 
'pg_operator'),'') as opdesc FROM pg_proc p JOIN pg_operator o ON oprcode = 
p.oid ) INSERT INTO pg_description   SEL"...) at postgres.c:1105
        portal = 0x26a9760
        snapshot_set = <optimized out>
        commandTag = <optimized out>
        completionTag = 
"\000\\\202\225\376\177\000\000\357݈\225\376\177\000\000\000\000\000\000\000\000\000\000\n\000\000\000\000\000\000\000P1g\002\000\000\000\000\300r_\002\000\000\000\000\351\003",
 '\000' <repeats 13 times>
        querytree_list = <optimized out>
        plantree_list = <optimized out>
        receiver = 0xd10be0 <debugtupDR>
        format = 0
        dest = DestDebug
        parsetree_list = 0x26b9a18
        parsetree_item = 0x26b99f0
        save_log_statement_stats = 0 '\000'
        was_logged = 0 '\000'
        isTopLevel = 1 '\001'
        msec_str = 
"\000\\\202\225\376\177\000\000\357݈\225\376\177\000\000\000\000\000\000\000\000\000\000\n\000\000\000\000\000\000"
        __func__ = "exec_simple_query"
#25 0x000000000073dacc in PostgresMain (argc=argc@entry=10, 
argv=argv@entry=0x25f18b0, dbname=0x26123c0 "template1", dbname@entry=0x0, 
username=<optimized out>) at postgres.c:4075
        query_string = 0x2673150 "WITH funcdescs AS ( SELECT p.oid as p_oid, 
oprname, coalesce(obj_description(o.oid, 'pg_operator'),'') as opdesc FROM 
pg_proc p JOIN pg_operator o ON oprcode = p.oid ) INSERT INTO pg_description   
SEL"...
        firstchar = 40317264
        input_message = {data = 0x2673150 "WITH funcdescs AS ( SELECT p.oid as 
p_oid, oprname, coalesce(obj_description(o.oid, 'pg_operator'),'') as opdesc 
FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid ) INSERT INTO 
pg_description   SEL"..., len = 451, maxlen = 1024, cursor = 451, long_ok = 0 
'\000'}
        local_sigjmp_buf = {{__jmpbuf = {39786672, 3065872400647890083, 
39809728, 1001, 0, 0, -3066668012108077917, 3065871986567586979}, 
__mask_was_saved = 1, __saved_mask = {__val = {0, 472446402651, 0, 0, 
532575944823, 1001, 0, 0, 140313854087694, 0, 140313857186624, 6, 39786672, 
1001, 0, 0}}}}
        send_ready_for_query = 0 '\000'
        disable_idle_in_transaction_timeout = <optimized out>
        __func__ = "PostgresMain"
#26 0x0000000000478a4c in main (argc=10, argv=0x25f18b0) at main.c:224
No locals.
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to