1# TimescaleDB code style guide
2
3Source code should follow the
4[PostgreSQL coding conventions](https://www.postgresql.org/docs/current/static/source.html). This
5includes
6[source formatting](https://www.postgresql.org/docs/current/static/source-format.html)
7with 4 column tab spacing and layout rules according to the BSD style.
8
9## SQL and PL/pgSQL style
10
11There is no official SQL or PL/pgSQL style guide for PostgreSQL that
12we are aware of, apart from the general spacing and layout rules
13above. For now, try to follow the style of the surrounding code when
14making modifications. We might develop more stringent guidelines in
15the future.
16
17## Error messages
18
19Error messages in TimescaleDB should obey the PostgreSQL
20[error message style guide](https://www.postgresql.org/docs/current/static/error-style-guide.html).
21
22## C style
23
24While the PostgreSQL project mandates that
25[C code adheres to the C89 standard](https://www.postgresql.org/docs/current/static/source-conventions.html)
26with some exceptions, we've chosen to allow many C99 features for the
27clarity and convenience they provide. PostgreSQL sticks with C89
28mostly for compatibility with many older compilers and platforms, such
29as Visual Studio on Windows. Visual Studio should support most of C99
30nowadays, however. We might revisit this decision in the future if it
31turns out to be a problem for important platforms.
32
33Unfortunately, PostgreSQL does not have a consistent style for naming
34of functions, variables and types. This
35[mailing-list thread](https://www.postgresql.org/message-id/1221125165.5637.12.camel%40abbas-laptop)
36elaborates on the situation. Instead, we've tried our best to develop
37a consistent style that roughly follows the style of the PostgreSQL
38source code.
39
40### Declarations before code
41
42C99 supports having code before a declaration, similar to C++, and we
43also support this in the code. For instance, the following code
44follows the guidelines:
45
46```C
47void some_function()
48{
49    prepare();
50	int result = fetch();
51	...
52}
53```
54
55### Function and variable names
56
57For clarity and consistency, we've chosen to go with lowercase
58under-score separated names for functions and variables. For instance,
59this piece of code is correct:
60
61```C
62static void
63my_function_name(int my_parameter)
64{
65    int my_variable;
66    ...
67}
68```
69
70while this one is wrong:
71
72```C
73static void
74MyFunctionName(int myParameter)
75{
76    int myVariable;
77    ...
78}
79```
80
81### Type declarations
82
83New composite/aggregate types should be typedef'd and use
84UpperCamelCase naming. For instance, the following is correct:
85
86```C
87typedef struct MyType
88{
89    ...
90} MyType;
91```
92
93while the following is wrong:
94
95```C
96typedef struct my_type
97{
98    ...
99} my_type;
100```
101
102### Modular code and namespacing
103
104When possible, code should be grouped into logical modules. Such modules
105typically resemble classes in object-oriented programming (OOP)
106languages and should use namespaced function and variable names that
107have the module name as prefix. TimescaleDB's [Cache](../src/cache.c)
108implementation is a good example of such a module where one would use
109
110```C
111void
112cache_initialize(Cache *c)
113{
114    ...
115}
116```
117
118rather than
119
120```C
121void
122initialize_cache(Cache *c)
123{
124
125}
126```
127
128### Object-orientated programming style
129
130Even though C is not an object-oriented programming language, it is
131fairly straight-forward to write C code with an OOP flavor. While we
132do not mandate that C code has an OOP flavor, we recommend it when it
133makes sense (e.g., to achieve modularity and code reuse).
134
135For example, TimescaleDB's [cache.c](../src/cache.c) module can be
136seen as a _base class_ with multiple derived _subclasses_, such as
137[hypertable_cache.c](../src/hypertable_cache.c) and
138[chunk_cache.c](../src/chunk_cache.c). Here's another example of
139subclassing using shapes:
140
141```C
142typedef struct Shape
143{
144    int color;
145    void (*draw)(Shape *, Canvas *);
146} Shape;
147
148void
149shape_draw(Shape *shape)
150{
151    /* open canvas for drawing */
152    Canvas *c = canvas_open();
153
154    /* other common shape code */
155    ...
156
157    shape->draw(shape, c);
158
159    canvas_close(c);
160}
161
162typedef struct Circle
163{
164    Shape shape;
165    float diameter;
166} Circle;
167
168Circle blue_circle = {
169    .shape = {
170        .color = BLUE,
171        .draw = circle_draw,
172    },
173    .diameter = 10.1,
174};
175
176void
177circle_draw(Shape *shape, Canvas *canvas)
178{
179    Circle *circle = (Circle *) shape;
180
181    /* draw circle */
182    ...
183}
184
185```
186
187There are a couple of noteworthy take-aways from this
188example.
189
190* Non-static "member" methods should take a pointer to the
191object as first argument and be namespaced as described above.
192* Derived modules can expand the original type using struct embedding,
193in which case the "superclass" should be the first member of the
194"subclass", so that one can easily upcast a `Circle` to a `Shape` or,
195vice-versa, downcast as in `circle_draw()` above.
196* C++-style virtual functions can be implemented with functions
197pointers. Good use cases for such functions are module-specific
198initialization and cleanup, or function overriding in a subclass.
199
200### Other noteworthy recommendations
201
202* Prefer static allocation and/or stack-allocated variables over
203  heap/dynamic allocation when possible. Fortunately, PostgreSQL has a
204  nice `MemoryContext` implementation that helps with heap allocation
205  when needed.
206* Try to minimize the number of included headers in source files,
207  especially when header files include other headers. Avoid circular
208  header dependencies by predeclaring types (or use struct pointers).
209
210
211For a general guide to writing C functions in PostgreSQL, you can
212review the section on
213[C-language functions](https://www.postgresql.org/docs/current/static/xfunc-c.html)
214in the PostgreSQL documentation.
215
216## Tools and editors
217
218We require running C code through clang-format before submitting a PR.
219This will ensure your code is properly formatted according to our style
220(which is similar to the PostgreSQL style but implement in clang-format).
221You can run clang-format on all of the TimescaleDB code using `make format`
222if you have clang-format (version >= 7) or docker installed.
223
224
225The following
226[Wiki post](https://wiki.postgresql.org/wiki/Developer_FAQ#What.27s_the_formatting_style_used_in_PostgreSQL_source_code.3F)
227contains links to style configuration files for various editors.
228