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 MARIADB_STMT_BULK_UNIT_RESULTS_SUPPORTED(stmt)\
38 ((stmt)->mysql && \
39 (!((stmt)->mysql->server_capabilities & CLIENT_MYSQL) &&\
40 ((stmt)->mysql->extension->mariadb_client_flag & \
41 (MARIADB_CLIENT_BULK_UNIT_RESULTS >> 32))))
42
43#define CLEAR_CLIENT_STMT_ERROR(a) \
44do { \
45 (a)->last_errno= 0;\
46 strcpy((a)->sqlstate, "00000");\
47 (a)->last_error[0]= 0;\
48} while (0)
49
50#define MYSQL_PS_SKIP_RESULT_W_LEN -1
51#define MYSQL_PS_SKIP_RESULT_STR -2
52#define STMT_ID_LENGTH 4
53
54
55typedef struct st_mysql_stmt MYSQL_STMT;
56
57typedef MYSQL_RES* (*mysql_stmt_use_or_store_func)(MYSQL_STMT *);
58
59enum enum_stmt_attr_type
60{
61 STMT_ATTR_UPDATE_MAX_LENGTH,
62 STMT_ATTR_CURSOR_TYPE,
63 STMT_ATTR_PREFETCH_ROWS,
64
65 /* MariaDB only */
66 STMT_ATTR_PREBIND_PARAMS=200,
67 STMT_ATTR_ARRAY_SIZE,
68 STMT_ATTR_ROW_SIZE,
69 STMT_ATTR_STATE,
70 STMT_ATTR_CB_USER_DATA,
71 STMT_ATTR_CB_PARAM,
72 STMT_ATTR_CB_RESULT,
73 STMT_ATTR_SQL_STATEMENT
74};
75
76enum enum_cursor_type
77{
78 CURSOR_TYPE_NO_CURSOR= 0,
79 CURSOR_TYPE_READ_ONLY= 1,
80 CURSOR_TYPE_FOR_UPDATE= 2,
81 CURSOR_TYPE_SCROLLABLE= 4
82};
83
84enum enum_indicator_type
85{
86 STMT_INDICATOR_NTS=-1,
87 STMT_INDICATOR_NONE=0,
88 STMT_INDICATOR_NULL=1,
89 STMT_INDICATOR_DEFAULT=2,
90 STMT_INDICATOR_IGNORE=3,
91 STMT_INDICATOR_IGNORE_ROW=4
92};
93
94/*
95 bulk PS flags
96*/
97#define STMT_BULK_FLAG_CLIENT_SEND_TYPES 128
98#define STMT_BULK_FLAG_SEND_UNIT_RESULTS 64
99
100typedef enum mysql_stmt_state
101{
102 MYSQL_STMT_INITTED = 0,
103 MYSQL_STMT_PREPARED,
104 MYSQL_STMT_EXECUTED,
105 MYSQL_STMT_WAITING_USE_OR_STORE,
106 MYSQL_STMT_USE_OR_STORE_CALLED,
107 MYSQL_STMT_USER_FETCHING, /* fetch_row_buff or fetch_row_unbuf */
108 MYSQL_STMT_FETCH_DONE
109} enum_mysqlnd_stmt_state;
110
111typedef struct st_mysql_bind
112{
113 unsigned long *length; /* output length pointer */
114 my_bool *is_null; /* Pointer to null indicator */
115 void *buffer; /* buffer to get/put data */
116 /* set this if you want to track data truncations happened during fetch */
117 my_bool *error;
118 union {
119 unsigned char *row_ptr; /* for the current data position */
120 char *indicator; /* indicator variable */
121 } u;
122 void (*store_param_func)(NET *net, struct st_mysql_bind *param);
123 void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *,
124 unsigned char **row);
125 void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *,
126 unsigned char **row);
127 /* output buffer length, must be set when fetching str/binary */
128 unsigned long buffer_length;
129 unsigned long offset; /* offset position for char/binary fetch */
130 unsigned long length_value; /* Used if length is 0 */
131 unsigned int flags; /* special flags, e.g. for dummy bind */
132 unsigned int pack_length; /* Internal length for packed data */
133 enum enum_field_types buffer_type; /* buffer type */
134 my_bool error_value; /* used if error is 0 */
135 my_bool is_unsigned; /* set if integer type is unsigned */
136 my_bool long_data_used; /* If used with mysql_send_long_data */
137 my_bool is_null_value; /* Used if is_null is 0 */
138 void *extension;
139} MYSQL_BIND;
140
141typedef struct st_mysqlnd_upsert_result
142{
143 unsigned int warning_count;
144 unsigned int server_status;
145 unsigned long long affected_rows;
146 unsigned long long last_insert_id;
147} mysql_upsert_status;
148
149typedef struct st_mysql_cmd_buffer
150{
151 unsigned char *buffer;
152 size_t length;
153} MYSQL_CMD_BUFFER;
154
155typedef struct st_mysql_error_info
156{
157 unsigned int error_no;
158 char error[MYSQL_ERRMSG_SIZE+1];
159 char sqlstate[SQLSTATE_LENGTH + 1];
160} mysql_error_info;
161
162typedef int (*mysql_stmt_fetch_row_func)(MYSQL_STMT *stmt, unsigned char **row);
163typedef void (*ps_result_callback)(void *data, unsigned int column, unsigned char **row);
164typedef my_bool (*ps_param_callback)(void *data, MYSQL_BIND *bind, unsigned int row_nr);
165
166struct st_mysql_stmt
167{
168 MA_MEM_ROOT mem_root;
169 MYSQL *mysql;
170 unsigned long stmt_id;
171 unsigned long flags;/* cursor is set here */
172 enum_mysqlnd_stmt_state state;
173 MYSQL_FIELD *fields;
174 unsigned int field_count;
175 unsigned int param_count;
176 unsigned char send_types_to_server;
177 MYSQL_BIND *params;
178 MYSQL_BIND *bind;
179 MYSQL_DATA result; /* we don't use mysqlnd's result set logic */
180 MYSQL_ROWS *result_cursor;
181 my_bool bind_result_done;
182 my_bool bind_param_done;
183
184 mysql_upsert_status upsert_status;
185
186 unsigned int last_errno;
187 char last_error[MYSQL_ERRMSG_SIZE+1];
188 char sqlstate[SQLSTATE_LENGTH + 1];
189
190 my_bool update_max_length;
191 unsigned long prefetch_rows;
192 LIST list;
193
194 my_bool cursor_exists;
195
196 void *extension;
197 mysql_stmt_fetch_row_func fetch_row_func;
198 unsigned int execute_count;/* count how many times the stmt was executed */
199 mysql_stmt_use_or_store_func default_rset_handler;
200 unsigned char *request_buffer;
201 unsigned int array_size;
202 size_t row_size;
203 unsigned int prebind_params;
204 void *user_data;
205 ps_result_callback result_callback;
206 ps_param_callback param_callback;
207 size_t request_length;
208 MARIADB_CONST_STRING sql;
209};
210
211typedef void (*ps_field_fetch_func)(MYSQL_BIND *r_param, const MYSQL_FIELD * field, unsigned char **row);
212typedef struct st_mysql_perm_bind {
213 ps_field_fetch_func func;
214 /* should be signed int */
215 int pack_len;
216 unsigned long max_len;
217} MYSQL_PS_CONVERSION;
218
219extern MYSQL_PS_CONVERSION mysql_ps_fetch_functions[MYSQL_TYPE_GEOMETRY + 1];
220unsigned long ma_net_safe_read(MYSQL *mysql);
221void mysql_init_ps_subsystem(void);
222unsigned long net_field_length(unsigned char **packet);
223int ma_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
224 size_t length, my_bool skipp_check, void *opt_arg);
225void stmt_set_error(MYSQL_STMT *stmt,
226 unsigned int error_nr,
227 const char *sqlstate,
228 const char *format,
229 ...);
230/*
231 * function prototypes
232 */
233MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql);
234int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length);
235int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt);
236int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt);
237int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg, unsigned int column, unsigned long offset);
238int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt);
239unsigned long STDCALL mysql_stmt_param_count(MYSQL_STMT * stmt);
240my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt, enum enum_stmt_attr_type attr_type, const void *attr);
241my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt, enum enum_stmt_attr_type attr_type, void *attr);
242my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
243my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
244my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt);
245my_bool STDCALL mysql_stmt_reset(MYSQL_STMT * stmt);
246my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt);
247my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt, unsigned int param_number, const char *data, unsigned long length);
248MYSQL_RES *STDCALL mysql_stmt_result_metadata(MYSQL_STMT *stmt);
249MYSQL_RES *STDCALL mysql_stmt_param_metadata(MYSQL_STMT *stmt);
250unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt);
251const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt);
252const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt);
253MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET offset);
254MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_tell(MYSQL_STMT *stmt);
255void STDCALL mysql_stmt_data_seek(MYSQL_STMT *stmt, unsigned long long offset);
256unsigned long long STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt);
257unsigned long long STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt);
258unsigned long long STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt);
259unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt);
260int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt);
261my_bool STDCALL mysql_stmt_more_results(MYSQL_STMT *stmt);
262int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt, const char *stmt_str, size_t length);
263MYSQL_FIELD * STDCALL mariadb_stmt_fetch_fields(MYSQL_STMT *stmt);
264