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