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
156static char const rcsid[]= "$RCSfile: SQLBindParameter.c,v $ $Revision: 1.12 $";
157
158SQLRETURN 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