1/************************************************************************
2
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Library General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public
14 License along with this library; if not, write to the Free
15 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 MA 02111-1301, USA
17
18 Part of this code includes code from PHP's mysqlnd extension
19 (written by Andrey Hristov, Georg Richter and Ulf Wendel), freely
20 available from http://www.php.net/software
21
22*************************************************************************/
23
24#define MYSQL_NO_DATA 100
25#define MYSQL_DATA_TRUNCATED 101
26#define MYSQL_DEFAULT_PREFETCH_ROWS (unsigned long) 1
27
28/* Bind flags */
29#define MADB_BIND_DUMMY 1
30
31#define MARIADB_STMT_BULK_SUPPORTED(stmt)\
32 ((stmt)->mysql && \
33 (!((stmt)->mysql->server_capabilities & CLIENT_MYSQL) &&\
34 ((stmt)->mysql->extension->mariadb_server_capabilities & \
35 (MARIADB_CLIENT_STMT_BULK_OPERATIONS >> 32))))
36
37#define SET_CLIENT_STMT_ERROR(a, b, c, d) \
38{ \
39 (a)->last_errno= (b);\
40 strncpy((a)->sqlstate, (c), SQLSTATE_LENGTH);\
41 strncpy((a)->last_error, (d) ? (d) : ER((b)), MYSQL_ERRMSG_SIZE - 1);\
42}
43
44#define CLEAR_CLIENT_STMT_ERROR(a) \
45{ \
46 (a)->last_errno= 0;\
47 strcpy((a)->sqlstate, "00000");\
48 (a)->last_error[0]= 0;\
49}
50
51#define MYSQL_PS_SKIP_RESULT_W_LEN -1
52#define MYSQL_PS_SKIP_RESULT_STR -2
53#define STMT_ID_LENGTH 4
54
55
56typedef struct st_mysql_stmt MYSQL_STMT;
57
58typedef MYSQL_RES* (*mysql_stmt_use_or_store_func)(MYSQL_STMT *);
59
60enum enum_stmt_attr_type
61{
62 STMT_ATTR_UPDATE_MAX_LENGTH,
63 STMT_ATTR_CURSOR_TYPE,
64 STMT_ATTR_PREFETCH_ROWS,
65 STMT_ATTR_PREBIND_PARAMS=200,
66 STMT_ATTR_ARRAY_SIZE,
67 STMT_ATTR_ROW_SIZE,
68 STMT_ATTR_STATE
69};
70
71enum enum_cursor_type
72{
73 CURSOR_TYPE_NO_CURSOR= 0,
74 CURSOR_TYPE_READ_ONLY= 1,
75 CURSOR_TYPE_FOR_UPDATE= 2,
76 CURSOR_TYPE_SCROLLABLE= 4
77};
78
79enum enum_indicator_type
80{
81 STMT_INDICATOR_NTS=-1,
82 STMT_INDICATOR_NONE=0,
83 STMT_INDICATOR_NULL=1,
84 STMT_INDICATOR_DEFAULT=2,
85 STMT_INDICATOR_IGNORE=3,
86 STMT_INDICATOR_IGNORE_ROW=4
87};
88
89/*
90 bulk PS flags
91*/
92#define STMT_BULK_FLAG_CLIENT_SEND_TYPES 128
93#define STMT_BULK_FLAG_INSERT_ID_REQUEST 64
94
95typedef enum mysql_stmt_state
96{
97 MYSQL_STMT_INITTED = 0,
98 MYSQL_STMT_PREPARED,
99 MYSQL_STMT_EXECUTED,
100 MYSQL_STMT_WAITING_USE_OR_STORE,
101 MYSQL_STMT_USE_OR_STORE_CALLED,
102 MYSQL_STMT_USER_FETCHING, /* fetch_row_buff or fetch_row_unbuf */
103 MYSQL_STMT_FETCH_DONE
104} enum_mysqlnd_stmt_state;
105
106typedef struct st_mysql_bind
107{
108 unsigned long *length; /* output length pointer */
109 my_bool *is_null; /* Pointer to null indicator */
110 void *buffer; /* buffer to get/put data */
111 /* set this if you want to track data truncations happened during fetch */
112 my_bool *error;
113 union {
114 unsigned char *row_ptr; /* for the current data position */
115 char *indicator; /* indicator variable */
116 } u;
117 void (*store_param_func)(NET *net, struct st_mysql_bind *param);
118 void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *,
119 unsigned char **row);
120 void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *,
121 unsigned char **row);
122 /* output buffer length, must be set when fetching str/binary */
123 unsigned long buffer_length;
124 unsigned long offset; /* offset position for char/binary fetch */
125 unsigned long length_value; /* Used if length is 0 */
126 unsigned int flags; /* special flags, e.g. for dummy bind */
127 unsigned int pack_length; /* Internal length for packed data */
128 enum enum_field_types buffer_type; /* buffer type */
129 my_bool error_value; /* used if error is 0 */
130 my_bool is_unsigned; /* set if integer type is unsigned */
131 my_bool long_data_used; /* If used with mysql_send_long_data */
132 my_bool is_null_value; /* Used if is_null is 0 */
133 void *extension;
134} MYSQL_BIND;
135
136typedef struct st_mysqlnd_upsert_result
137{
138 unsigned int warning_count;
139 unsigned int server_status;
140 unsigned long long affected_rows;
141 unsigned long long last_insert_id;
142} mysql_upsert_status;
143
144typedef struct st_mysql_cmd_buffer
145{
146 unsigned char *buffer;
147 size_t length;
148} MYSQL_CMD_BUFFER;
149
150typedef struct st_mysql_error_info
151{
152 unsigned int error_no;
153 char error[MYSQL_ERRMSG_SIZE+1];
154 char sqlstate[SQLSTATE_LENGTH + 1];
155} mysql_error_info;
156
157
158struct st_mysqlnd_stmt_methods
159{
160 my_bool (*prepare)(const MYSQL_STMT * stmt, const char * const query, size_t query_len);
161 my_bool (*execute)(const MYSQL_STMT * stmt);
162 MYSQL_RES * (*use_result)(const MYSQL_STMT * stmt);
163 MYSQL_RES * (*store_result)(const MYSQL_STMT * stmt);
164 MYSQL_RES * (*get_result)(const MYSQL_STMT * stmt);
165 my_bool (*free_result)(const MYSQL_STMT * stmt);
166 my_bool (*seek_data)(const MYSQL_STMT * stmt, unsigned long long row);
167 my_bool (*reset)(const MYSQL_STMT * stmt);
168 my_bool (*close)(const MYSQL_STMT * stmt); /* private */
169 my_bool (*dtor)(const MYSQL_STMT * stmt); /* use this for mysqlnd_stmt_close */
170
171 my_bool (*fetch)(const MYSQL_STMT * stmt, my_bool * const fetched_anything);
172
173 my_bool (*bind_param)(const MYSQL_STMT * stmt, const MYSQL_BIND bind);
174 my_bool (*refresh_bind_param)(const MYSQL_STMT * stmt);
175 my_bool (*bind_result)(const MYSQL_STMT * stmt, const MYSQL_BIND *bind);
176 my_bool (*send_long_data)(const MYSQL_STMT * stmt, unsigned int param_num,
177 const char * const data, size_t length);
178 MYSQL_RES *(*get_parameter_metadata)(const MYSQL_STMT * stmt);
179 MYSQL_RES *(*get_result_metadata)(const MYSQL_STMT * stmt);
180 unsigned long long (*get_last_insert_id)(const MYSQL_STMT * stmt);
181 unsigned long long (*get_affected_rows)(const MYSQL_STMT * stmt);
182 unsigned long long (*get_num_rows)(const MYSQL_STMT * stmt);
183
184 unsigned int (*get_param_count)(const MYSQL_STMT * stmt);
185 unsigned int (*get_field_count)(const MYSQL_STMT * stmt);
186 unsigned int (*get_warning_count)(const MYSQL_STMT * stmt);
187
188 unsigned int (*get_error_no)(const MYSQL_STMT * stmt);
189 const char * (*get_error_str)(const MYSQL_STMT * stmt);
190 const char * (*get_sqlstate)(const MYSQL_STMT * stmt);
191
192 my_bool (*get_attribute)(const MYSQL_STMT * stmt, enum enum_stmt_attr_type attr_type, const void * value);
193 my_bool (*set_attribute)(const MYSQL_STMT * stmt, enum enum_stmt_attr_type attr_type, const void * value);
194 void (*set_error)(MYSQL_STMT *stmt, unsigned int error_nr, const char *sqlstate, const char *format, ...);
195};
196
197typedef int (*mysql_stmt_fetch_row_func)(MYSQL_STMT *stmt, unsigned char **row);
198
199struct st_mysql_stmt
200{
201 MA_MEM_ROOT mem_root;
202 MYSQL *mysql;
203 unsigned long stmt_id;
204 unsigned long flags;/* cursor is set here */
205 enum_mysqlnd_stmt_state state;
206 MYSQL_FIELD *fields;
207 unsigned int field_count;
208 unsigned int param_count;
209 unsigned char send_types_to_server;
210 MYSQL_BIND *params;
211 MYSQL_BIND *bind;
212 MYSQL_DATA result; /* we don't use mysqlnd's result set logic */
213 MYSQL_ROWS *result_cursor;
214 my_bool bind_result_done;
215 my_bool bind_param_done;
216
217 mysql_upsert_status upsert_status;
218
219 unsigned int last_errno;
220 char last_error[MYSQL_ERRMSG_SIZE+1];
221 char sqlstate[SQLSTATE_LENGTH + 1];
222
223 my_bool update_max_length;
224 unsigned long prefetch_rows;
225 LIST list;
226
227 my_bool cursor_exists;
228
229 void *extension;
230 mysql_stmt_fetch_row_func fetch_row_func;
231 unsigned int execute_count;/* count how many times the stmt was executed */
232 mysql_stmt_use_or_store_func default_rset_handler;
233 struct st_mysqlnd_stmt_methods *m;
234 unsigned int array_size;
235 size_t row_size;
236 unsigned int prebind_params;
237};
238
239typedef void (*ps_field_fetch_func)(MYSQL_BIND *r_param, const MYSQL_FIELD * field, unsigned char **row);
240typedef struct st_mysql_perm_bind {
241 ps_field_fetch_func func;
242 /* should be signed int */
243 int pack_len;
244 unsigned long max_len;
245} MYSQL_PS_CONVERSION;
246
247extern MYSQL_PS_CONVERSION mysql_ps_fetch_functions[MYSQL_TYPE_GEOMETRY + 1];
248unsigned long ma_net_safe_read(MYSQL *mysql);
249void mysql_init_ps_subsystem(void);
250unsigned long net_field_length(unsigned char **packet);
251int ma_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
252 size_t length, my_bool skipp_check, void *opt_arg);
253/*
254 * function prototypes
255 */
256MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql);
257int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length);
258int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt);
259int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt);
260int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg, unsigned int column, unsigned long offset);
261int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt);
262unsigned long STDCALL mysql_stmt_param_count(MYSQL_STMT * stmt);
263my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt, enum enum_stmt_attr_type attr_type, const void *attr);
264my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt, enum enum_stmt_attr_type attr_type, void *attr);
265my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
266my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
267my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt);
268my_bool STDCALL mysql_stmt_reset(MYSQL_STMT * stmt);
269my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt);
270my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt, unsigned int param_number, const char *data, unsigned long length);
271MYSQL_RES *STDCALL mysql_stmt_result_metadata(MYSQL_STMT *stmt);
272MYSQL_RES *STDCALL mysql_stmt_param_metadata(MYSQL_STMT *stmt);
273unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt);
274const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt);
275const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt);
276MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET offset);
277MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_tell(MYSQL_STMT *stmt);
278void STDCALL mysql_stmt_data_seek(MYSQL_STMT *stmt, unsigned long long offset);
279unsigned long long STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt);
280unsigned long long STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt);
281unsigned long long STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt);
282unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt);
283int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt);
284my_bool STDCALL mysql_stmt_more_results(MYSQL_STMT *stmt);
285int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt, const char *stmt_str, size_t length);
286