Foreword
In PostgreSQL, there isn’t a native foreach loop construct in C, because C itself doesn’t have a foreach loop as you might find in higher-level languages like Python or PHP. However, PostgreSQL often implements loop iterations over elements using Macros that simplify the handling of data structures, such as linked lists, which are commonly used within its codebase.
Common Loop Macros in PostgreSQL
lfirst(lc)
:- This macro retrieves the data stored in a
ListCell
. TheListCell
structure typically contains a union that can hold various types of pointers (likevoid*
,int
, etc.). Theptr_value
is a generic pointer that can point to any node or structure, andlfirst
simply casts it back from thevoid *
.
- This macro retrieves the data stored in a
lfirst_node(type, lc)
:- This macro is used when the list elements are known to be of a specific node type, which is common in the parser and planner where lists often contain specific types of nodes (e.g., expression or plan nodes).
lfirst_node
usescastNode
to cast the pointer retrieved bylfirst
to the specified type, ensuring type safety and readability in the code.
- This macro is used when the list elements are known to be of a specific node type, which is common in the parser and planner where lists often contain specific types of nodes (e.g., expression or plan nodes).
castNode(_type_, nodeptr)
:- A simple cast to the specified type
_type_
. It enhances readability and ensures that the casting is explicit in the code, which is crucial for understanding that a type conversion is taking place, particularly when navigating complex data structures common in PostgreSQL’s internals.
- A simple cast to the specified type
1 |
|
The ListCell
union consists of a single member, ptr_value
, which is a generic pointer (void *)
.
This pointer can hold a reference to any type of data, allowing for flexibility in what kind of data the list can contain.
This structure is useful for managing lists of generic data types.
The List structure represents a dynamic list in PostgreSQL.
It contains:
length
: An integer that specifies the current number of elements in the list.elements
: A pointer to an array ofListCell
elements, which holds the actual data in the list. This array can be re-allocated as the list grows or shrinks, allowing for dynamic resizing.- The comment suggests that sometimes
ListCell
elements may be allocated directly alongside the List structure itself. This can optimize memory usage and improve performance.
1 | typedef union ListCell |
The ForEachState structure is used to manage state while iterating over a list in PostgreSQL.
l
: A constant pointer to the list being iterated. The list is not meant to be modified during iteration.i
: An integer tracking the current index of the element in the list being processed. This helps keep track of the iteration progress.
These structures work together to handle lists of data in PostgreSQL, providing the flexibility to work with generic data types and iterate over lists efficiently and safely. The List structure allows for dynamic lists, while ForEachState
helps manage the state of iteration over the list.
1 | typedef struct ForEachState |
Here is the sample code, we can easy use foreach to iterator List*
objects.
1 | int main(void) { |
My smaple code link: foreach loop
此文作者:Daniel Shih(石頭)
此文地址: https://isdaniel.github.io/c_foreach/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!