1 | /********************************************************************* |
2 | * |
3 | * This is based on code created by Peter Harvey, |
4 | * (pharvey@codebydesign.com). |
5 | * |
6 | * Modified and extended by Nick Gorham |
7 | * (nick@lurcher.org). |
8 | * |
9 | * Any bugs or problems should be considered the fault of Nick and not |
10 | * Peter. |
11 | * |
12 | * copyright (c) 1999 Nick Gorham |
13 | * |
14 | * This library is free software; you can redistribute it and/or |
15 | * modify it under the terms of the GNU Lesser General Public |
16 | * License as published by the Free Software Foundation; either |
17 | * version 2 of the License, or (at your option) any later version. |
18 | * |
19 | * This library is distributed in the hope that it will be useful, |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
22 | * Lesser General Public License for more details. |
23 | * |
24 | * You should have received a copy of the GNU Lesser General Public |
25 | * License along with this library; if not, write to the Free Software |
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
27 | * |
28 | ********************************************************************** |
29 | * |
30 | * $Id: SQLBindParameter.c,v 1.12 2009/02/18 17:59:08 lurcher Exp $ |
31 | * |
32 | * $Log: SQLBindParameter.c,v $ |
33 | * Revision 1.12 2009/02/18 17:59:08 lurcher |
34 | * Shift to using config.h, the compile lines were making it hard to spot warnings |
35 | * |
36 | * Revision 1.11 2007/03/05 09:49:23 lurcher |
37 | * Get it to build on VMS again |
38 | * |
39 | * Revision 1.10 2006/04/18 10:24:47 lurcher |
40 | * Add a couple of changes from Mark Vanderwiel |
41 | * |
42 | * Revision 1.9 2006/04/11 10:22:56 lurcher |
43 | * Fix a data type check |
44 | * |
45 | * Revision 1.8 2006/03/08 11:22:13 lurcher |
46 | * Add check for valid C_TYPE |
47 | * |
48 | * Revision 1.7 2005/09/05 09:49:48 lurcher |
49 | * New QT detection macros added |
50 | * |
51 | * Revision 1.6 2005/04/26 08:40:35 lurcher |
52 | * |
53 | * Add data type mapping for SQLSetPos. |
54 | * Remove out of date macro in sqlext.h |
55 | * |
56 | * Revision 1.5 2003/10/30 18:20:45 lurcher |
57 | * |
58 | * Fix broken thread protection |
59 | * Remove SQLNumResultCols after execute, lease S4/S% to driver |
60 | * Fix string overrun in SQLDriverConnect |
61 | * Add initial support for Interix |
62 | * |
63 | * Revision 1.4 2002/12/05 17:44:30 lurcher |
64 | * |
65 | * Display unknown return values in return logging |
66 | * |
67 | * Revision 1.3 2002/08/19 09:11:49 lurcher |
68 | * |
69 | * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state |
70 | * |
71 | * Revision 1.2 2001/12/13 13:00:31 lurcher |
72 | * |
73 | * Remove most if not all warnings on 64 bit platforms |
74 | * Add support for new MS 3.52 64 bit changes |
75 | * Add override to disable the stopping of tracing |
76 | * Add MAX_ROWS support in postgres driver |
77 | * |
78 | * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher |
79 | * |
80 | * First upload to SourceForge |
81 | * |
82 | * Revision 1.2 2001/04/12 17:43:35 nick |
83 | * |
84 | * Change logging and added autotest to odbctest |
85 | * |
86 | * Revision 1.1.1.1 2000/09/04 16:42:52 nick |
87 | * Imported Sources |
88 | * |
89 | * Revision 1.9 1999/11/13 23:40:58 ngorham |
90 | * |
91 | * Alter the way DM logging works |
92 | * Upgrade the Postgres driver to 6.4.6 |
93 | * |
94 | * Revision 1.8 1999/10/24 23:54:17 ngorham |
95 | * |
96 | * First part of the changes to the error reporting |
97 | * |
98 | * Revision 1.7 1999/10/09 00:56:16 ngorham |
99 | * |
100 | * Added Manush's patch to map ODBC 3-2 datetime values |
101 | * |
102 | * Revision 1.6 1999/10/09 00:15:58 ngorham |
103 | * |
104 | * Add mapping from SQL_TYPE_X to SQL_X and SQL_C_TYPE_X to SQL_C_X |
105 | * when the driver is a ODBC 2 one |
106 | * |
107 | * Revision 1.5 1999/09/21 22:34:24 ngorham |
108 | * |
109 | * Improve performance by removing unneeded logging calls when logging is |
110 | * disabled |
111 | * |
112 | * Revision 1.4 1999/07/10 21:10:15 ngorham |
113 | * |
114 | * Adjust error sqlstate from driver manager, depending on requested |
115 | * version (ODBC2/3) |
116 | * |
117 | * Revision 1.3 1999/07/04 21:05:06 ngorham |
118 | * |
119 | * Add LGPL Headers to code |
120 | * |
121 | * Revision 1.2 1999/06/30 23:56:54 ngorham |
122 | * |
123 | * Add initial thread safety code |
124 | * |
125 | * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb |
126 | * first go at it |
127 | * |
128 | * Revision 1.3 1999/06/02 20:12:10 ngorham |
129 | * |
130 | * Fixed botched log entry, and removed the dos \r from the sql header files. |
131 | * |
132 | * Revision 1.2 1999/06/02 19:57:20 ngorham |
133 | * |
134 | * Added code to check if a attempt is being made to compile with a C++ |
135 | * Compiler, and issue a message. |
136 | * Start work on the ODBC2-3 conversions. |
137 | * |
138 | * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey |
139 | * Imported sources |
140 | * |
141 | * Revision 1.3 1999/05/03 19:50:43 nick |
142 | * Another check point |
143 | * |
144 | * Revision 1.2 1999/04/30 16:22:47 nick |
145 | * Another checkpoint |
146 | * |
147 | * Revision 1.1 1999/04/25 23:02:41 nick |
148 | * Initial revision |
149 | * |
150 | * |
151 | **********************************************************************/ |
152 | |
153 | #include <config.h> |
154 | #include "drivermanager.h" |
155 | |
156 | static char const rcsid[]= "$RCSfile: SQLBindParameter.c,v $ $Revision: 1.12 $" ; |
157 | |
158 | SQLRETURN SQLBindParameter( |
159 | SQLHSTMT statement_handle, |
160 | SQLUSMALLINT ipar, |
161 | SQLSMALLINT f_param_type, |
162 | SQLSMALLINT f_c_type, |
163 | SQLSMALLINT f_sql_type, |
164 | SQLULEN cb_col_def, |
165 | SQLSMALLINT ib_scale, |
166 | SQLPOINTER rgb_value, |
167 | SQLLEN cb_value_max, |
168 | SQLLEN *pcb_value ) |
169 | { |
170 | DMHSTMT statement = (DMHSTMT) statement_handle; |
171 | SQLRETURN ret; |
172 | |
173 | /* |
174 | * check statement |
175 | */ |
176 | |
177 | if ( !__validate_stmt( statement )) |
178 | { |
179 | dm_log_write( __FILE__, |
180 | __LINE__, |
181 | LOG_INFO, |
182 | LOG_INFO, |
183 | "Error: SQL_INVALID_HANDLE" ); |
184 | |
185 | return SQL_INVALID_HANDLE; |
186 | } |
187 | |
188 | function_entry( statement ); |
189 | |
190 | if ( log_info.log_flag ) |
191 | { |
192 | sprintf( statement -> msg, "\n\t\tEntry:\ |
193 | \n\t\t\tStatement = %p\ |
194 | \n\t\t\tParam Number = %d\ |
195 | \n\t\t\tParam Type = %d\ |
196 | \n\t\t\tC Type = %d %s\ |
197 | \n\t\t\tSQL Type = %d %s\ |
198 | \n\t\t\tCol Def = %d\ |
199 | \n\t\t\tScale = %d\ |
200 | \n\t\t\tRgb Value = %p\ |
201 | \n\t\t\tValue Max = %d\ |
202 | \n\t\t\tStrLen Or Ind = %p" , |
203 | statement, |
204 | ipar, |
205 | f_param_type, |
206 | f_c_type, |
207 | __c_as_text( f_c_type ), |
208 | f_sql_type, |
209 | __sql_as_text( f_sql_type ), |
210 | (int)cb_col_def, |
211 | (int)ib_scale, |
212 | (void*)rgb_value, |
213 | (int)cb_value_max, |
214 | (void*)pcb_value ); |
215 | |
216 | dm_log_write( __FILE__, |
217 | __LINE__, |
218 | LOG_INFO, |
219 | LOG_INFO, |
220 | statement -> msg ); |
221 | } |
222 | |
223 | thread_protect( SQL_HANDLE_STMT, statement ); |
224 | |
225 | if ( ipar < 1 ) |
226 | { |
227 | dm_log_write( __FILE__, |
228 | __LINE__, |
229 | LOG_INFO, |
230 | LOG_INFO, |
231 | "Error: 07009" ); |
232 | |
233 | __post_internal_error_api( &statement -> error, |
234 | ERROR_07009, NULL, |
235 | statement -> connection -> environment -> requested_version, |
236 | SQL_API_SQLBINDPARAMETER ); |
237 | |
238 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
239 | } |
240 | |
241 | if ( ((f_c_type == SQL_C_CHAR || f_c_type == SQL_C_BINARY || f_c_type == SQL_C_WCHAR) || |
242 | (f_c_type == SQL_C_DEFAULT && |
243 | (f_sql_type == SQL_DEFAULT || |
244 | f_sql_type == SQL_CHAR || |
245 | f_sql_type == SQL_BINARY || |
246 | f_sql_type == SQL_LONGVARCHAR || |
247 | f_sql_type == SQL_LONGVARBINARY || |
248 | f_sql_type == SQL_VARBINARY || |
249 | f_sql_type == SQL_VARCHAR || |
250 | f_sql_type == SQL_WCHAR || |
251 | f_sql_type == SQL_WLONGVARCHAR || |
252 | f_sql_type == SQL_WVARCHAR))) |
253 | && cb_value_max < 0 && cb_value_max != SQL_NTS ) |
254 | { |
255 | dm_log_write( __FILE__, |
256 | __LINE__, |
257 | LOG_INFO, |
258 | LOG_INFO, |
259 | "Error: HY090" ); |
260 | |
261 | __post_internal_error( &statement -> error, |
262 | ERROR_HY090, NULL, |
263 | statement -> connection -> environment -> requested_version ); |
264 | |
265 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
266 | } |
267 | |
268 | if ( rgb_value == NULL && |
269 | pcb_value == NULL && |
270 | f_param_type != SQL_PARAM_OUTPUT ) |
271 | { |
272 | dm_log_write( __FILE__, |
273 | __LINE__, |
274 | LOG_INFO, |
275 | LOG_INFO, |
276 | "Error: HY009" ); |
277 | |
278 | __post_internal_error( &statement -> error, |
279 | ERROR_HY009, NULL, |
280 | statement -> connection -> environment -> requested_version ); |
281 | |
282 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
283 | } |
284 | |
285 | if ( statement -> connection -> environment -> requested_version == SQL_OV_ODBC3_80 ) { |
286 | if ( f_param_type != SQL_PARAM_INPUT && |
287 | f_param_type != SQL_PARAM_INPUT_OUTPUT && |
288 | f_param_type != SQL_PARAM_OUTPUT && |
289 | f_param_type != SQL_PARAM_OUTPUT_STREAM && |
290 | f_param_type != SQL_PARAM_INPUT_OUTPUT_STREAM ) |
291 | { |
292 | dm_log_write( __FILE__, |
293 | __LINE__, |
294 | LOG_INFO, |
295 | LOG_INFO, |
296 | "Error: HY105" ); |
297 | |
298 | __post_internal_error( &statement -> error, |
299 | ERROR_HY105, NULL, |
300 | statement -> connection -> environment -> requested_version ); |
301 | |
302 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
303 | } |
304 | } |
305 | else { |
306 | if ( f_param_type != SQL_PARAM_INPUT && |
307 | f_param_type != SQL_PARAM_INPUT_OUTPUT && |
308 | f_param_type != SQL_PARAM_OUTPUT ) |
309 | { |
310 | dm_log_write( __FILE__, |
311 | __LINE__, |
312 | LOG_INFO, |
313 | LOG_INFO, |
314 | "Error: HY105" ); |
315 | |
316 | __post_internal_error( &statement -> error, |
317 | ERROR_HY105, NULL, |
318 | statement -> connection -> environment -> requested_version ); |
319 | |
320 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
321 | } |
322 | } |
323 | |
324 | /* |
325 | * Alter the types, this is a special to cope with a AllBase bug... |
326 | */ |
327 | if ( f_c_type == SQL_C_SLONG && 0 ) |
328 | { |
329 | dm_log_write( __FILE__, |
330 | __LINE__, |
331 | LOG_INFO, |
332 | LOG_INFO, |
333 | "Map from SQL_C_SLONG,SQL_C_CHAR to SQL_C_LONG,SQL_INTEGER" ); |
334 | |
335 | f_c_type = SQL_C_LONG; |
336 | f_sql_type = SQL_INTEGER; |
337 | } |
338 | |
339 | /* |
340 | * check states |
341 | */ |
342 | |
343 | if ( statement -> state == STATE_S8 || |
344 | statement -> state == STATE_S9 || |
345 | statement -> state == STATE_S10 || |
346 | statement -> state == STATE_S11 || |
347 | statement -> state == STATE_S12 || |
348 | statement -> state == STATE_S13 || |
349 | statement -> state == STATE_S14 || |
350 | statement -> state == STATE_S15 ) |
351 | { |
352 | dm_log_write( __FILE__, |
353 | __LINE__, |
354 | LOG_INFO, |
355 | LOG_INFO, |
356 | "Error: HY010" ); |
357 | |
358 | __post_internal_error( &statement -> error, |
359 | ERROR_HY010, NULL, |
360 | statement -> connection -> environment -> requested_version ); |
361 | |
362 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
363 | } |
364 | |
365 | /* |
366 | * check valid C_TYPE |
367 | */ |
368 | |
369 | if ( !check_target_type( f_c_type, statement -> connection -> environment -> requested_version )) |
370 | { |
371 | dm_log_write( __FILE__, |
372 | __LINE__, |
373 | LOG_INFO, |
374 | LOG_INFO, |
375 | "Error: HY003" ); |
376 | |
377 | __post_internal_error( &statement -> error, |
378 | ERROR_HY003, NULL, |
379 | statement -> connection -> environment -> requested_version ); |
380 | |
381 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
382 | } |
383 | |
384 | if ( CHECK_SQLBINDPARAMETER( statement -> connection )) |
385 | { |
386 | ret = SQLBINDPARAMETER( statement -> connection, |
387 | statement -> driver_stmt, |
388 | ipar, |
389 | f_param_type, |
390 | __map_type(MAP_C_DM2D,statement->connection,f_c_type), |
391 | __map_type(MAP_SQL_DM2D,statement->connection,f_sql_type), |
392 | cb_col_def, |
393 | ib_scale, |
394 | rgb_value, |
395 | cb_value_max, |
396 | pcb_value ); |
397 | } |
398 | else if ( CHECK_SQLBINDPARAM( statement -> connection )) |
399 | { |
400 | ret = SQLBINDPARAM( statement -> connection, |
401 | statement -> driver_stmt, |
402 | ipar, |
403 | __map_type(MAP_C_DM2D,statement->connection,f_c_type), |
404 | __map_type(MAP_SQL_DM2D,statement->connection,f_sql_type), |
405 | cb_col_def, |
406 | ib_scale, |
407 | rgb_value, |
408 | pcb_value ); |
409 | } |
410 | else |
411 | { |
412 | dm_log_write( __FILE__, |
413 | __LINE__, |
414 | LOG_INFO, |
415 | LOG_INFO, |
416 | "Error: IM001" ); |
417 | |
418 | __post_internal_error( &statement -> error, |
419 | ERROR_IM001, NULL, |
420 | statement -> connection -> environment -> requested_version ); |
421 | |
422 | return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); |
423 | } |
424 | |
425 | if ( log_info.log_flag ) |
426 | { |
427 | SQLCHAR buf[ 128 ]; |
428 | |
429 | sprintf( statement -> msg, |
430 | "\n\t\tExit:[%s]" , |
431 | __get_return_status( ret, buf )); |
432 | |
433 | dm_log_write( __FILE__, |
434 | __LINE__, |
435 | LOG_INFO, |
436 | LOG_INFO, |
437 | statement -> msg ); |
438 | } |
439 | |
440 | return function_return( SQL_HANDLE_STMT, statement, ret ); |
441 | } |
442 | |