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: SQLProcedureColumnsW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $
31 *
32 * $Log: SQLProcedureColumnsW.c,v $
33 * Revision 1.9 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.8 2008/08/29 08:01:39 lurcher
37 * Alter the way W functions are passed to the driver
38 *
39 * Revision 1.7 2007/02/28 15:37:48 lurcher
40 * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg
41 *
42 * Revision 1.6 2004/01/12 09:54:39 lurcher
43 *
44 * Fix problem where STATE_S5 stops metadata calls
45 *
46 * Revision 1.5 2003/10/30 18:20:46 lurcher
47 *
48 * Fix broken thread protection
49 * Remove SQLNumResultCols after execute, lease S4/S% to driver
50 * Fix string overrun in SQLDriverConnect
51 * Add initial support for Interix
52 *
53 * Revision 1.4 2002/12/05 17:44:31 lurcher
54 *
55 * Display unknown return values in return logging
56 *
57 * Revision 1.3 2002/08/23 09:42:37 lurcher
58 *
59 * Fix some build warnings with casts, and a AIX linker mod, to include
60 * deplib's on the link line, but not the libtool generated ones
61 *
62 * Revision 1.2 2002/07/24 08:49:52 lurcher
63 *
64 * Alter UNICODE support to use iconv for UNICODE-ANSI conversion
65 *
66 * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher
67 *
68 * First upload to SourceForge
69 *
70 * Revision 1.3 2001/07/03 09:30:41 nick
71 *
72 * Add ability to alter size of displayed message in the log
73 *
74 * Revision 1.2 2001/04/12 17:43:36 nick
75 *
76 * Change logging and added autotest to odbctest
77 *
78 * Revision 1.1 2000/12/31 20:30:54 nick
79 *
80 * Add UNICODE support
81 *
82 *
83 **********************************************************************/
84
85#include <config.h>
86#include "drivermanager.h"
87
88static char const rcsid[]= "$RCSfile: SQLProcedureColumnsW.c,v $";
89
90SQLRETURN SQLProcedureColumnsW(
91 SQLHSTMT statement_handle,
92 SQLWCHAR *sz_catalog_name,
93 SQLSMALLINT cb_catalog_name,
94 SQLWCHAR *sz_schema_name,
95 SQLSMALLINT cb_schema_name,
96 SQLWCHAR *sz_proc_name,
97 SQLSMALLINT cb_proc_name,
98 SQLWCHAR *sz_column_name,
99 SQLSMALLINT cb_column_name )
100{
101 DMHSTMT statement = (DMHSTMT) statement_handle;
102 SQLRETURN ret;
103 SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ];
104
105 /*
106 * check statement
107 */
108
109 if ( !__validate_stmt( statement ))
110 {
111 dm_log_write( __FILE__,
112 __LINE__,
113 LOG_INFO,
114 LOG_INFO,
115 "Error: SQL_INVALID_HANDLE" );
116
117#ifdef WITH_HANDLE_REDIRECT
118 {
119 DMHSTMT parent_statement;
120
121 parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT );
122
123 if ( parent_statement ) {
124 dm_log_write( __FILE__,
125 __LINE__,
126 LOG_INFO,
127 LOG_INFO,
128 "Info: found parent handle" );
129
130 if ( CHECK_SQLPROCEDURECOLUMNSW( parent_statement -> connection ))
131 {
132 dm_log_write( __FILE__,
133 __LINE__,
134 LOG_INFO,
135 LOG_INFO,
136 "Info: calling redirected driver function" );
137
138 return SQLPROCEDURECOLUMNSW( parent_statement -> connection,
139 statement_handle,
140 sz_catalog_name,
141 cb_catalog_name,
142 sz_schema_name,
143 cb_schema_name,
144 sz_proc_name,
145 cb_proc_name,
146 sz_column_name,
147 cb_column_name );
148 }
149 }
150 }
151#endif
152 return SQL_INVALID_HANDLE;
153 }
154
155 function_entry( statement );
156
157 if ( log_info.log_flag )
158 {
159 sprintf( statement -> msg, "\n\t\tEntry:\
160\n\t\t\tStatement = %p\
161\n\t\t\tCatalog Name = %s\
162\n\t\t\tSchema Name = %s\
163\n\t\t\tProc Name = %s\
164\n\t\t\tColumn Type = %s",
165 statement,
166 __wstring_with_length( s1, sz_catalog_name, cb_catalog_name ),
167 __wstring_with_length( s2, sz_schema_name, cb_schema_name ),
168 __wstring_with_length( s3, sz_proc_name, cb_proc_name ),
169 __wstring_with_length( s4, sz_column_name, cb_column_name ));
170
171 dm_log_write( __FILE__,
172 __LINE__,
173 LOG_INFO,
174 LOG_INFO,
175 statement -> msg );
176 }
177
178 thread_protect( SQL_HANDLE_STMT, statement );
179
180 if (( sz_catalog_name && cb_catalog_name < 0 && cb_catalog_name != SQL_NTS ) ||
181 ( sz_schema_name && cb_schema_name < 0 && cb_schema_name != SQL_NTS ) ||
182 ( sz_proc_name && cb_proc_name < 0 && cb_proc_name != SQL_NTS ) ||
183 ( sz_column_name && cb_column_name < 0 && cb_column_name != SQL_NTS ))
184 {
185 dm_log_write( __FILE__,
186 __LINE__,
187 LOG_INFO,
188 LOG_INFO,
189 "Error: HY090" );
190
191 __post_internal_error( &statement -> error,
192 ERROR_HY090, NULL,
193 statement -> connection -> environment -> requested_version );
194
195 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
196 }
197
198 /*
199 * check states
200 */
201
202#ifdef NR_PROBE
203 if ( statement -> state == STATE_S5 ||
204 statement -> state == STATE_S6 ||
205 statement -> state == STATE_S7 )
206#else
207 if (( statement -> state == STATE_S6 && statement -> eod == 0 ) ||
208 statement -> state == STATE_S7 )
209#endif
210 {
211 dm_log_write( __FILE__,
212 __LINE__,
213 LOG_INFO,
214 LOG_INFO,
215 "Error: 24000" );
216
217 __post_internal_error( &statement -> error,
218 ERROR_24000, NULL,
219 statement -> connection -> environment -> requested_version );
220
221 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
222 }
223 else if ( statement -> state == STATE_S8 ||
224 statement -> state == STATE_S9 ||
225 statement -> state == STATE_S10 ||
226 statement -> state == STATE_S13 ||
227 statement -> state == STATE_S14 ||
228 statement -> state == STATE_S15 )
229 {
230 dm_log_write( __FILE__,
231 __LINE__,
232 LOG_INFO,
233 LOG_INFO,
234 "Error: HY010" );
235
236 __post_internal_error( &statement -> error,
237 ERROR_HY010, NULL,
238 statement -> connection -> environment -> requested_version );
239
240 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
241 }
242
243 if ( statement -> state == STATE_S11 ||
244 statement -> state == STATE_S12 )
245 {
246 if ( statement -> interupted_func != SQL_API_SQLPROCEDURECOLUMNS )
247 {
248 dm_log_write( __FILE__,
249 __LINE__,
250 LOG_INFO,
251 LOG_INFO,
252 "Error: HY010" );
253
254 __post_internal_error( &statement -> error,
255 ERROR_HY010, NULL,
256 statement -> connection -> environment -> requested_version );
257
258 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
259 }
260 }
261
262 /*
263 * TO_DO Check the SQL_ATTR_METADATA_ID settings
264 */
265
266 if ( statement -> connection -> unicode_driver ||
267 CHECK_SQLPROCEDURECOLUMNSW( statement -> connection ))
268 {
269 if ( !CHECK_SQLPROCEDURECOLUMNSW( statement -> connection ))
270 {
271 dm_log_write( __FILE__,
272 __LINE__,
273 LOG_INFO,
274 LOG_INFO,
275 "Error: IM001" );
276
277 __post_internal_error( &statement -> error,
278 ERROR_IM001, NULL,
279 statement -> connection -> environment -> requested_version );
280
281 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
282 }
283
284 ret = SQLPROCEDURECOLUMNSW( statement -> connection ,
285 statement -> driver_stmt,
286 sz_catalog_name,
287 cb_catalog_name,
288 sz_schema_name,
289 cb_schema_name,
290 sz_proc_name,
291 cb_proc_name,
292 sz_column_name,
293 cb_column_name );
294 }
295 else
296 {
297 SQLCHAR *as1, *as2, *as3, *as4;
298 int clen;
299
300 if ( !CHECK_SQLPROCEDURECOLUMNS( statement -> connection ))
301 {
302 dm_log_write( __FILE__,
303 __LINE__,
304 LOG_INFO,
305 LOG_INFO,
306 "Error: IM001" );
307
308 __post_internal_error( &statement -> error,
309 ERROR_IM001, NULL,
310 statement -> connection -> environment -> requested_version );
311
312 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
313 }
314
315 as1 = (SQLCHAR*) unicode_to_ansi_alloc( sz_catalog_name, cb_catalog_name, statement -> connection, &clen );
316 cb_catalog_name = clen;
317 as2 = (SQLCHAR*) unicode_to_ansi_alloc( sz_schema_name, cb_schema_name, statement -> connection, &clen );
318 cb_schema_name = clen;
319 as3 = (SQLCHAR*) unicode_to_ansi_alloc( sz_proc_name, cb_proc_name, statement -> connection, &clen );
320 cb_proc_name = clen;
321 as4 = (SQLCHAR*) unicode_to_ansi_alloc( sz_column_name, cb_column_name, statement -> connection, &clen );
322 cb_column_name = clen;
323
324 ret = SQLPROCEDURECOLUMNS( statement -> connection ,
325 statement -> driver_stmt,
326 as1,
327 cb_catalog_name,
328 as2,
329 cb_schema_name,
330 as3,
331 cb_proc_name,
332 as4,
333 cb_column_name );
334
335 if ( as1 ) free( as1 );
336 if ( as2 ) free( as2 );
337 if ( as3 ) free( as3 );
338 if ( as4 ) free( as4 );
339 }
340
341 if ( SQL_SUCCEEDED( ret ))
342 {
343 statement -> state = STATE_S5;
344 statement -> prepared = 0;
345 }
346 else if ( ret == SQL_STILL_EXECUTING )
347 {
348 statement -> interupted_func = SQL_API_SQLPROCEDURECOLUMNS;
349 if ( statement -> state != STATE_S11 &&
350 statement -> state != STATE_S12 )
351 statement -> state = STATE_S11;
352 }
353 else
354 {
355 statement -> state = STATE_S1;
356 }
357
358 if ( log_info.log_flag )
359 {
360 sprintf( statement -> msg,
361 "\n\t\tExit:[%s]",
362 __get_return_status( ret, s1 ));
363
364 dm_log_write( __FILE__,
365 __LINE__,
366 LOG_INFO,
367 LOG_INFO,
368 statement -> msg );
369 }
370
371 return function_return( SQL_HANDLE_STMT, statement, ret );
372}
373