-
Notifications
You must be signed in to change notification settings - Fork 0
/
pg_variables.h
211 lines (182 loc) · 4.9 KB
/
pg_variables.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*-------------------------------------------------------------------------
*
* pg_variables.c
* exported definitions for pg_variables.c
*
* Copyright (c) 2015-2022, Postgres Professional
*
*-------------------------------------------------------------------------
*/
#ifndef __PG_VARIABLES_H__
#define __PG_VARIABLES_H__
#include "pg_config.h"
#include "access/htup.h"
#include "access/tupdesc.h"
#include "datatype/timestamp.h"
#include "utils/date.h"
#include "utils/guc.h"
#include "utils/hsearch.h"
#include "utils/numeric.h"
#include "utils/jsonb.h"
#include "lib/ilist.h"
/* Accessor for the i'th attribute of tupdesc. */
#if PG_VERSION_NUM > 100000
#define GetTupleDescAttr(tupdesc, i) (TupleDescAttr(tupdesc, i))
#else
#define GetTupleDescAttr(tupdesc, i) ((tupdesc)->attrs[(i)])
#endif
/* initial number of packages hashes */
#define NUMPACKAGES 8
#define NUMVARIABLES 16
typedef struct RecordVar
{
HTAB *rhash;
TupleDesc tupdesc;
/* Memory context for records hash table for easy memory release */
MemoryContext hctx;
/* Hash function info */
FmgrInfo hash_proc;
/* Match function info */
FmgrInfo cmp_proc;
} RecordVar;
typedef struct ScalarVar
{
Datum value;
bool is_null;
bool typbyval;
int16 typlen;
} ScalarVar;
/* Object levels (subxact + atx) */
typedef struct Levels
{
int level;
#ifdef PGPRO_EE
int atxlevel;
#endif
} Levels;
/* State of TransObject instance */
typedef struct TransState
{
dlist_node node;
bool is_valid;
Levels levels;
} TransState;
/* List node that stores one of the package's states */
typedef struct PackState
{
TransState state;
unsigned long trans_var_num; /* Number of valid transactional variables */
} PackState;
/* List node that stores one of the variable's states */
typedef struct VarState
{
TransState state;
union
{
ScalarVar scalar;
RecordVar record;
} value;
} VarState;
/* Transactional object */
typedef struct TransObject
{
char name[NAMEDATALEN];
dlist_head states;
} TransObject;
#ifdef PGPRO_EE
/* Package context for save transactional part of package */
typedef struct PackageContext
{
HTAB *varHashTransact;
MemoryContext hctxTransact;
TransState *state;
struct PackageContext *next;
} PackageContext;
#endif
/* Transactional package */
typedef struct Package
{
TransObject transObject;
HTAB *varHashRegular,
*varHashTransact;
/* Memory context for package variables for easy memory release */
MemoryContext hctxRegular,
hctxTransact;
#ifdef PGPRO_EE
PackageContext *context;
#endif
} Package;
/* Transactional variable */
typedef struct Variable
{
TransObject transObject;
Package *package;
Oid typid;
/*
* We need an additional flag to determine variable's type since we can
* store record type DATUM within scalar variable
*/
bool is_record;
/*
* The flag determines the further behavior of the variable. Can be
* specified only when creating a variable.
*/
bool is_transactional;
bool is_deleted;
} Variable;
typedef struct HashRecordKey
{
Datum value;
bool is_null;
/* Hash function info */
FmgrInfo *hash_proc;
/* Match function info */
FmgrInfo *cmp_proc;
} HashRecordKey;
typedef struct HashRecordEntry
{
HashRecordKey key;
Datum tuple;
} HashRecordEntry;
/* Element of list with objects created, changed or removed within transaction */
typedef struct ChangedObject
{
dlist_node node;
TransObject *object;
} ChangedObject;
/* Type of transactional object instance */
typedef enum TransObjectType
{
TRANS_PACKAGE,
TRANS_VARIABLE
} TransObjectType;
/* Element of stack with 'changedVars' and 'changedPacks' list heads*/
typedef struct ChangesStackNode
{
dlist_node node;
dlist_head *changedVarsList;
dlist_head *changedPacksList;
MemoryContext ctx;
} ChangesStackNode;
/* pg_variables.c */
extern bool convert_unknownoid;
extern void init_record(RecordVar *record, TupleDesc tupdesc, Variable *variable);
extern void check_attributes(Variable *variable, HeapTupleHeader *rec, TupleDesc tupdesc);
extern void coerce_unknown_first_record(TupleDesc *tupdesc, HeapTupleHeader * rec);
extern void check_record_key(Variable *variable, Oid typid);
extern void insert_record(Variable *variable, HeapTupleHeader tupleHeader);
extern bool update_record(Variable *variable, HeapTupleHeader tupleHeader);
extern bool delete_record(Variable *variable, Datum value, bool is_null);
extern void insert_record_copy(RecordVar *dest_record, Datum src_tuple,
Variable *variable);
extern bool removeObject(TransObject *object, TransObjectType type);
#define GetActualState(object) \
(dlist_head_element(TransState, node, &((TransObject *) object)->states))
#define GetActualValue(variable) \
(((VarState *) GetActualState(variable))->value)
#define GetPackState(package) \
(((PackState *) GetActualState(package)))
#define GetName(object) \
(AssertVariableIsOfTypeMacro(object->transObject, TransObject), \
object->transObject.name)
#endif /* __PG_VARIABLES_H__ */