Re: patch: function xmltable - Mailing list pgsql-hackers
From | Alvaro Herrera |
---|---|
Subject | Re: patch: function xmltable |
Date | |
Msg-id | 20161122204730.dgipy6gxi25j4e6a@alvherre.pgsql Whole thread Raw |
In response to | Re: patch: function xmltable (Pavel Stehule <pavel.stehule@gmail.com>) |
Responses |
Re: patch: function xmltable
Re: patch: function xmltable |
List | pgsql-hackers |
I found the whole TableExprGetTupleDesc() function a bit odd in nodeFuncs.c, so I renamed it to ExecTypeFromTableExpr() and moved it to execTuples.c -- but only because that's where ExecTypeFromTL and others already live. I would have liked to move it to tupdesc.c instead, but it requires knowledge of executor nodes, which is probably the reason that ExecTypeFromTL is in execTuples. I think we'd eat that bit of ugliness only because we're not the first. But anyway I quickly ran into another problem. I noticed that ExecTypeFromTableExpr is being called from the transform phase, which is much earlier than the executor. I noticed because of the warning that the above movement added to nodeFuncs.c, src/backend/nodes/nodeFuncs.c:509:5: warning: implicit declaration of function 'ExecTypeFromTableExpr' [-Wimplicit-function-declaration] so I thought, hm, is it okay to have parse analysis run an executor function? (I suppose this is the reason you put it in nodeFuncs in the first place). For fun, I tried this query under GDB, with a breakpoint on exprTypmod(): SELECT X.* FROM emp, XMLTABLE ('//depts/dept/employee' passing doc COLUMNS empID INTEGER PATH '@id', firstname int PATH 'name/first', lastname VARCHAR(25) PATH 'name/last') AS X; and sure enough, the type is resolved during parse analysis: Breakpoint 1, exprTypmod (expr=expr@entry=0x1d23ad8) at /pgsql/source/master/src/backend/nodes/nodeFuncs.c:283 283 if (!expr) (gdb) print *expr $2 = {type = T_TableExpr} (gdb) bt #0 exprTypmod (expr=expr@entry=0x1d23ad8) at /pgsql/source/master/src/backend/nodes/nodeFuncs.c:283 #1 0x000000000080c500 in get_expr_result_type (expr=0x1d23ad8, resultTypeId=0x7ffd482bfdb4, resultTupleDesc=0x7ffd482bfdb8) at /pgsql/source/master/src/backend/utils/fmgr/funcapi.c:247 #2 0x000000000056de1b in expandRTE (rte=rte@entry=0x1d6b800, rtindex=2, sublevels_up=0, location=location@entry=7, include_dropped=include_dropped@entry=0 '\000', colnames=colnames@entry=0x7ffd482bfe10, colvars=0x7ffd482bfe18) at/pgsql/source/master/src/backend/parser/parse_relation.c:2052 #3 0x000000000056e131 in expandRelAttrs (pstate=pstate@entry=0x1d238a8, rte=rte@entry=0x1d6b800, rtindex=<optimized out>, sublevels_up=<optimized out>, location=location@entry=7) at /pgsql/source/master/src/backend/parser/parse_relation.c:2435 #4 0x000000000056fa64 in ExpandSingleTable (pstate=pstate@entry=0x1d238a8, rte=rte@entry=0x1d6b800, location=7, make_target_entry=make_target_entry@entry=1'\001') at /pgsql/source/master/src/backend/parser/parse_target.c:1266 #5 0x000000000057135b in ExpandColumnRefStar (pstate=pstate@entry=0x1d238a8, cref=0x1d22720, make_target_entry=make_target_entry@entry=1'\001') at /pgsql/source/master/src/backend/parser/parse_target.c:1158 #6 0x00000000005716f9 in transformTargetList (pstate=0x1d238a8, targetlist=<optimized out>, exprKind=EXPR_KIND_SELECT_TARGET) This seems fine I guess, and it seems to say that we ought to move the code that generates the tupdesc to back parse analysis rather than executor. Okay, fine. But let's find a better place than nodeFuncs. But if I move the XMLTABLE() call to the target list instead, the type is resolved at planner time: SELECT XMLTABLE ('/dept/employee' passing $$<dept bldg="114"> <employee id="903"> <name> <first>Mary</first> <last>Jones</last> </name> <office>415</office> <phone>905-403-6112</phone> <phone>647-504-4546</phone> <salary currency="USD">64000</salary> </employee> </dept>$$ COLUMNS empID INTEGER PATH '@id', firstname varchar(4) PATH 'name/first', lastname VARCHAR(25) PATH 'name/last') AS X; Breakpoint 1, exprTypmod (expr=expr@entry=0x1d6bed8) at /pgsql/source/master/src/backend/nodes/nodeFuncs.c:283 283 if (!expr) (gdb) bt #0 exprTypmod (expr=expr@entry=0x1d6bed8) at /pgsql/source/master/src/backend/nodes/nodeFuncs.c:283 #1 0x0000000000654058 in set_pathtarget_cost_width (root=0x1d6bc68, target=0x1d6c728) at /pgsql/source/master/src/backend/optimizer/path/costsize.c:4729 #2 0x000000000066c197 in grouping_planner (root=0x1d6bc68, inheritance_update=40 '(', inheritance_update@entry=0 '\000', tuple_fraction=0.01, tuple_fraction@entry=0) at /pgsql/source/master/src/backend/optimizer/plan/planner.c:1745 #3 0x000000000066ef64 in subquery_planner (glob=glob@entry=0x1d6bbd0, parse=parse@entry=0x1d23818, parent_root=parent_root@entry=0x0, hasRecursion=hasRecursion@entry=0 '\000', tuple_fraction=tuple_fraction@entry=0) at /pgsql/source/master/src/backend/optimizer/plan/planner.c:795 #4 0x000000000066fe5e in standard_planner (parse=0x1d23818, cursorOptions=256, boundParams=<optimized out>) at /pgsql/source/master/src/backend/optimizer/plan/planner.c:307 This is surprising, but I'm not sure it's wrong. -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
pgsql-hackers by date: