| src/backend/nodes/README |
| |
| Node Structures |
| =============== |
| |
| Introduction |
| ------------ |
| |
| Postgres uses "node" types to organize parse trees, plan trees, and |
| executor state trees. All objects that can appear in such trees must |
| be declared as node types. In addition, a few object types that aren't |
| part of parse/plan/execute node trees receive NodeTags anyway for |
| identification purposes, usually because they are involved in APIs |
| where we want to pass multiple object types through the same pointer. |
| |
| The node structures are plain old C structures with the first field |
| being of type NodeTag. "Inheritance" is achieved by convention: |
| the first field can alternatively be of another node type. |
| |
| Node types typically have support for being copied by copyObject(), |
| compared by equal(), serialized by outNode(), and deserialized by |
| nodeRead(). For some classes of Nodes, not all of these support |
| functions are required; for example, executor state nodes don't |
| presently need any of them. So far as the system is concerned, |
| output and read functions are only needed for node types that can |
| appear in parse trees stored in the catalogs, and for plan tree |
| nodes because those are serialized to be passed to parallel workers. |
| However, we provide output functions for some other node types as well, |
| because they are very handy for debugging. Currently, such coverage |
| exists for raw parsetrees and most planner data structures. However, |
| output coverage of raw parsetrees is incomplete: in particular, utility |
| statements are almost entirely unsupported. |
| |
| Relevant Files |
| -------------- |
| |
| Utility functions for manipulating node structures reside in this |
| directory. Some support functions are automatically generated by the |
| gen_node_support.pl script, other functions are maintained manually. |
| To control the automatic generation of support functions, node types |
| and node fields can be annotated with pg_node_attr() specifications; |
| see further documentation in src/include/nodes/nodes.h. |
| |
| |
| FILES IN THIS DIRECTORY (src/backend/nodes/) |
| |
| General-purpose node manipulation functions: |
| copyfuncs.c - copy a node tree (*) |
| equalfuncs.c - compare two node trees (*) |
| outfuncs.c - convert a node tree to text representation (*) |
| readfuncs.c - convert text representation back to a node tree (*) |
| makefuncs.c - creator functions for some common node types |
| nodeFuncs.c - some other general-purpose manipulation functions |
| queryjumblefuncs.c - compute a node tree for query jumbling (*) |
| |
| (*) - Most functions in these files are generated by |
| gen_node_support.pl and #include'd there. |
| |
| Specialized manipulation functions: |
| bitmapset.c - Bitmapset support |
| list.c - generic list support |
| multibitmapset.c - List-of-Bitmapset support |
| params.c - Param support |
| tidbitmap.c - TIDBitmap support |
| value.c - support for value nodes |
| |
| FILES IN src/include/nodes/ |
| |
| Node definitions primarily appear in: |
| nodes.h - define node tags (NodeTag) (*) |
| primnodes.h - primitive nodes |
| parsenodes.h - parse tree nodes |
| pathnodes.h - path tree nodes and planner internal structures |
| plannodes.h - plan tree nodes |
| execnodes.h - executor nodes |
| memnodes.h - memory nodes |
| pg_list.h - generic list |
| |
| (*) - Also #include's files generated by gen_node_support.pl. |
| |
| |
| Steps to Add a Node |
| ------------------- |
| |
| Suppose you want to define a node Foo: |
| |
| 1. Add the structure definition to the appropriate include/nodes/???.h file. |
| If you intend to inherit from, say a Plan node, put Plan as the first field |
| of your struct definition. (The T_Foo tag is created automatically.) |
| 2. Check that the generated support functions in copyfuncs.funcs.c, |
| equalfuncs.funcs.c, outfuncs.funcs.c, queryjumblefuncs.funcs.c and |
| readfuncs.funcs.c look correct. Add attributes as necessary to control the |
| outcome. (For some classes of node types, you don't need all the support |
| functions. Use node attributes similar to those of related node types.) |
| 3. Add cases to the functions in nodeFuncs.c as needed. There are many |
| other places you'll probably also need to teach about your new node |
| type. Best bet is to grep for references to one or two similar existing |
| node types to find all the places to touch. |
| (Except for frequently-created nodes, don't bother writing a creator |
| function in makefuncs.c.) |
| 4. Consider testing your new code with COPY_PARSE_PLAN_TREES, |
| WRITE_READ_PARSE_PLAN_TREES, and RAW_EXPRESSION_COVERAGE_TEST to ensure |
| support has been added everywhere that it's necessary; see |
| pg_config_manual.h about these. |
| |
| Adding a new node type moves the numbers associated with existing |
| tags, so you'll need to recompile the whole tree after doing this. |
| (--enable-depend usually helps.) It doesn't force initdb though, |
| because the numbers never go to disk. But altering or removing a node |
| type should usually be accompanied by an initdb-forcing catalog |
| version change, since the interpretation of serialized node trees |
| stored in system catalogs is affected by that. (If the node type |
| never appears in stored parse trees, as for example Plan nodes do not, |
| then a catversion change is not needed to change it.) |