summaryrefslogtreecommitdiffstats
path: root/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
blob: 8b8f081f27ce8bcc5deea59762caa46cc757ef80 (plain)
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
/* src/interfaces/ecpg/ecpglib/ecpglib_extern.h */

#ifndef _ECPG_ECPGLIB_EXTERN_H
#define _ECPG_ECPGLIB_EXTERN_H

#include "ecpg_config.h"
#include "ecpgtype.h"
#include "libpq-fe.h"
#include "sqlca.h"
#include "sqlda-compat.h"
#include "sqlda-native.h"

#ifndef CHAR_BIT
#include <limits.h>
#endif
#ifdef LOCALE_T_IN_XLOCALE
#include <xlocale.h>
#endif

enum COMPAT_MODE
{
	ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE, ECPG_COMPAT_ORACLE
};

extern bool ecpg_internal_regression_mode;

#define INFORMIX_MODE(X) ((X) == ECPG_COMPAT_INFORMIX || (X) == ECPG_COMPAT_INFORMIX_SE)
#define ORACLE_MODE(X) ((X) == ECPG_COMPAT_ORACLE)

enum ARRAY_TYPE
{
	ECPG_ARRAY_ERROR, ECPG_ARRAY_NOT_SET, ECPG_ARRAY_ARRAY, ECPG_ARRAY_VECTOR, ECPG_ARRAY_NONE
};

#define ECPG_IS_ARRAY(X) ((X) == ECPG_ARRAY_ARRAY || (X) == ECPG_ARRAY_VECTOR)

/* A generic varchar type. */
struct ECPGgeneric_varchar
{
	int			len;
	char		arr[FLEXIBLE_ARRAY_MEMBER];
};

/* A generic bytea type. */
struct ECPGgeneric_bytea
{
	int			len;
	char		arr[FLEXIBLE_ARRAY_MEMBER];
};

/*
 * type information cache
 */

struct ECPGtype_information_cache
{
	struct ECPGtype_information_cache *next;
	int			oid;
	enum ARRAY_TYPE isarray;
};

#ifdef HAVE_USELOCALE
extern locale_t ecpg_clocale;	/* LC_NUMERIC=C */
#endif

/* structure to store one statement */
struct statement
{
	int			lineno;
	char	   *command;
	char	   *name;
	struct connection *connection;
	enum COMPAT_MODE compat;
	bool		force_indicator;
	enum ECPG_statement_type statement_type;
	bool		questionmarks;
	struct variable *inlist;
	struct variable *outlist;
#ifdef HAVE_USELOCALE
	locale_t	oldlocale;
#else
	char	   *oldlocale;
#ifdef HAVE__CONFIGTHREADLOCALE
	int			oldthreadlocale;
#endif
#endif
	int			nparams;
	char	  **paramvalues;
	int		   *paramlengths;
	int		   *paramformats;
	PGresult   *results;
};

/* structure to store prepared statements for a connection */
struct prepared_statement
{
	char	   *name;
	bool		prepared;
	struct statement *stmt;
	struct prepared_statement *next;
};

/* structure to store connections */
struct connection
{
	char	   *name;
	PGconn	   *connection;
	bool		autocommit;
	struct ECPGtype_information_cache *cache_head;
	struct prepared_statement *prep_stmts;
	struct connection *next;
};

/* structure to store descriptors */
struct descriptor
{
	char	   *name;
	PGresult   *result;
	struct descriptor *next;
	int			count;
	struct descriptor_item *items;
};

struct descriptor_item
{
	int			num;
	char	   *data;
	int			indicator;
	int			length;
	int			precision;
	int			scale;
	int			type;
	bool		is_binary;
	int			data_len;
	struct descriptor_item *next;
};

struct variable
{
	enum ECPGttype type;
	void	   *value;
	void	   *pointer;
	long		varcharsize;
	long		arrsize;
	long		offset;
	enum ECPGttype ind_type;
	void	   *ind_value;
	void	   *ind_pointer;
	long		ind_varcharsize;
	long		ind_arrsize;
	long		ind_offset;
	struct variable *next;
};

struct var_list
{
	int			number;
	void	   *pointer;
	struct var_list *next;
};

extern struct var_list *ivlist;

/* Here are some methods used by the lib. */

bool		ecpg_add_mem(void *ptr, int lineno);

bool		ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type,
						  enum ECPGttype, char *, char *, long, long, long,
						  enum ARRAY_TYPE, enum COMPAT_MODE, bool);

#ifdef ENABLE_THREAD_SAFETY
void		ecpg_pthreads_init(void);
#endif
struct connection *ecpg_get_connection(const char *connection_name);
char	   *ecpg_alloc(long size, int lineno);
char	   *ecpg_auto_alloc(long size, int lineno);
char	   *ecpg_realloc(void *ptr, long size, int lineno);
void		ecpg_free(void *ptr);
bool		ecpg_init(const struct connection *con,
					  const char *connection_name,
					  const int lineno);
char	   *ecpg_strdup(const char *string, int lineno);
const char *ecpg_type_name(enum ECPGttype typ);
int			ecpg_dynamic_type(Oid type);
int			sqlda_dynamic_type(Oid type, enum COMPAT_MODE compat);
void		ecpg_clear_auto_mem(void);

struct descriptor *ecpg_find_desc(int line, const char *name);

struct prepared_statement *ecpg_find_prepared_statement(const char *name,
														struct connection *con,
														struct prepared_statement **prev_);

bool		ecpg_store_result(const PGresult *results, int act_field,
							  const struct statement *stmt, struct variable *var);
bool		ecpg_store_input(const int lineno, const bool force_indicator,
							 const struct variable *var,
							 char **tobeinserted_p, bool quote);
void		ecpg_free_params(struct statement *stmt, bool print);
bool		ecpg_do_prologue(int lineno, const int compat,
							 const int force_indicator, const char *connection_name,
							 const bool questionmarks, enum ECPG_statement_type statement_type,
							 const char *query, va_list args,
							 struct statement **stmt_out);
bool		ecpg_build_params(struct statement *stmt);
bool		ecpg_autostart_transaction(struct statement *stmt);
bool		ecpg_execute(struct statement *stmt);
bool		ecpg_process_output(struct statement *stmt, bool clear_result);
void		ecpg_do_epilogue(struct statement *stmt);
bool		ecpg_do(const int lineno, const int compat,
					const int force_indicator, const char *connection_name,
					const bool questionmarks, const int st, const char *query,
					va_list args);

bool		ecpg_check_PQresult(PGresult *results, int lineno,
								PGconn *connection, enum COMPAT_MODE compat);
void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
void		ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat);
char	   *ecpg_prepared(const char *name, struct connection *con);
bool		ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *con);
void		ecpg_log(const char *format,...) pg_attribute_printf(1, 2);
bool		ecpg_auto_prepare(int lineno, const char *connection_name,
							  const int compat, char **name, const char *query);
bool		ecpg_register_prepared_stmt(struct statement *stmt);
void		ecpg_init_sqlca(struct sqlca_t *sqlca);

struct sqlda_compat *ecpg_build_compat_sqlda(int line, PGresult *res, int row,
											 enum COMPAT_MODE compat);
void		ecpg_set_compat_sqlda(int lineno, struct sqlda_compat **_sqlda,
								  const PGresult *res, int row,
								  enum COMPAT_MODE compat);
struct sqlda_struct *ecpg_build_native_sqlda(int line, PGresult *res, int row,
											 enum COMPAT_MODE compat);
void		ecpg_set_native_sqlda(int lineno, struct sqlda_struct **_sqlda,
								  const PGresult *res, int row, enum COMPAT_MODE compat);
unsigned	ecpg_hex_dec_len(unsigned srclen);
unsigned	ecpg_hex_enc_len(unsigned srclen);
unsigned	ecpg_hex_encode(const char *src, unsigned len, char *dst);

#ifdef ENABLE_NLS
extern char *ecpg_gettext(const char *msgid) pg_attribute_format_arg(1);
#else
#define ecpg_gettext(x) (x)
#endif

/* SQLSTATE values generated or processed by ecpglib (intentionally
 * not exported -- users should refer to the codes directly) */

#define ECPG_SQLSTATE_NO_DATA				"02000"
#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS	"07001"
#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS		"07002"
#define ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION	"07006"
#define ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX		"07009"
#define ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION	"08001"
#define ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST		"08003"
#define ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN	"08007"
#define ECPG_SQLSTATE_CARDINALITY_VIOLATION "21000"
#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER "22002"
#define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION		"25001"
#define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION		"25P01"
#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME	"26000"
#define ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME	"33000"
#define ECPG_SQLSTATE_INVALID_CURSOR_NAME	"34000"
#define ECPG_SQLSTATE_SYNTAX_ERROR			"42601"
#define ECPG_SQLSTATE_DATATYPE_MISMATCH		"42804"
#define ECPG_SQLSTATE_DUPLICATE_CURSOR		"42P03"

/* implementation-defined internal errors of ecpg */
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR	"YE000"
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY	"YE001"

#endif							/* _ECPG_ECPGLIB_EXTERN_H */