Thread

Commits

  1. Support PlaceHolderVars in MERGE actions.

  1. Merge command is erroring with: PlaceHolderVar found where not expected

    Önder Kalacı <onderkalaci@gmail.com> — 2023-03-15T12:24:18Z

    Hi hackers,
    
    While playing with the Merge command, I get an unexpected error. I've
    searched the mailing list, but couldn't find any reference to this, so
    decided to send an e-mail.
    
    
    CREATE TABLE source (id integer, z int);
    CREATE TABLE target (id integer, z int);
    MERGE INTO public.target sda USING ((SELECT source.id, source.z, 12 AS rnd
    FROM public.source source) sdn FULL JOIN public.source sdn2 ON ((sdn.id
    OPERATOR(pg_catalog.=) sdn2.id))) ON (sda.id OPERATOR(pg_catalog.=) sdn.id)
    WHEN NOT MATCHED THEN INSERT (id, z) VALUES (sdn.id, sdn.rnd);
    
    *ERROR:  PlaceHolderVar found where not expected*
    
    
    Here is the backtrace:
    ```
    
    thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
    * frame #0: 0x000000010d60f0df postgres`errstart(elevel=21,
    domain=0x0000000000000000) at elog.c:453:6 [opt]
    frame #1: 0x000000010d6d7e7e postgres`pull_var_clause_walker.cold.7 at
    var.c:703:4 [opt]
    frame #2: 0x000000010d415dae
    postgres`pull_var_clause_walker(node=<unavailable>,
    context=0x00007ff7b2dcb7d0) at var.c:703:4 [opt]
    frame #3: 0x000000010d3782a5
    postgres`expression_tree_walker_impl(node=0x00007ff18503a7c0,
    walker=<unavailable>, context=<unavailable>) at nodeFuncs.c:2206:9 [opt]
    frame #4: 0x000000010d415dfe
    postgres`pull_var_clause_walker(node=<unavailable>, context=<unavailable>)
    at var.c:705:9 [opt] [artificial]
    frame #5: 0x000000010d415cfc postgres`pull_var_clause(node=<unavailable>,
    flags=0) at var.c:622:2 [opt]
    frame #6: 0x000000010d3fac81
    postgres`preprocess_targetlist(root=0x00007ff185037a28) at
    preptlist.c:165:11 [opt]
    frame #7: 0x000000010d3e6941 postgres`grouping_planner(root=<unavailable>,
    tuple_fraction=<unavailable>) at planner.c:1419:3 [opt]
    frame #8: 0x000000010d3e5678 postgres`subquery_planner(glob=<unavailable>,
    parse=<unavailable>, parent_root=<unavailable>, hasRecursion=<unavailable>,
    tuple_fraction=0) at planner.c:1065:2 [opt]
    frame #9: 0x000000010d3e4277
    postgres`standard_planner(parse=0x00007ff185011668,
    query_string=<unavailable>, cursorOptions=2048,
    boundParams=0x0000000000000000) at planner.c:411:9 [opt]
    ```
    
    
    Thanks,
    Onder KALACI
    
  2. Re: Merge command is erroring with: PlaceHolderVar found where not expected

    Tom Lane <tgl@sss.pgh.pa.us> — 2023-03-15T14:48:21Z

    =?UTF-8?B?w5ZuZGVyIEthbGFjxLE=?= <onderkalaci@gmail.com> writes:
    > CREATE TABLE source (id integer, z int);
    > CREATE TABLE target (id integer, z int);
    > MERGE INTO public.target sda USING ((SELECT source.id, source.z, 12 AS rnd
    > FROM public.source source) sdn FULL JOIN public.source sdn2 ON ((sdn.id
    > OPERATOR(pg_catalog.=) sdn2.id))) ON (sda.id OPERATOR(pg_catalog.=) sdn.id)
    > WHEN NOT MATCHED THEN INSERT (id, z) VALUES (sdn.id, sdn.rnd);
    
    > *ERROR:  PlaceHolderVar found where not expected*
    
    Thanks for the report!  Somebody was far too optimistic here:
    
                 * Add resjunk entries for any Vars used in each action's
                 * targetlist and WHEN condition that belong to relations other
                 * than target.  Note that aggregates, window functions and
                 * placeholder vars are not possible anywhere in MERGE's WHEN
                 * clauses.  (PHVs may be added later, but they don't concern us
                 * here.)
    
    I'm not sure offhand whether RECURSE or INCLUDE is the more appropriate
    action.
    
    			regards, tom lane