Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : /*
14 : * This code was created by Peter Harvey (mostly during Christmas 98/99).
15 : * This code is LGPL. Please ensure that this message remains in future
16 : * distributions and uses of this code (thats about all I get out of it).
17 : * - Peter Harvey pharvey@codebydesign.com
18 : *
19 : * This file has been modified for the MonetDB project. See the file
20 : * Copyright in this directory for more information.
21 : */
22 :
23 : /**********************************************************************
24 : * SQLColAttribute()
25 : * CLI Compliance: ISO 92
26 : *
27 : * Author: Martin van Dinther, Sjoerd Mullender
28 : * Date : 30 aug 2002
29 : *
30 : **********************************************************************/
31 :
32 : #include "ODBCGlobal.h"
33 : #include "ODBCStmt.h"
34 : #include "ODBCUtil.h"
35 :
36 :
37 : SQLRETURN
38 18 : MNDBColAttribute(ODBCStmt *stmt,
39 : SQLUSMALLINT ColumnNumber,
40 : SQLUSMALLINT FieldIdentifier,
41 : SQLPOINTER CharacterAttributePtr,
42 : SQLSMALLINT BufferLength,
43 : SQLSMALLINT *StringLengthPtr,
44 : LENP_OR_POINTER_T NumericAttributePtr)
45 : {
46 18 : ODBCDescRec *rec;
47 :
48 : /* check statement cursor state, query should be prepared or executed */
49 18 : if (stmt->State == INITED) {
50 : /* Function sequence error */
51 0 : addStmtError(stmt, "HY010", NULL, 0);
52 0 : return SQL_ERROR;
53 : }
54 18 : if (stmt->State == EXECUTED0) {
55 : /* Invalid cursor state */
56 0 : addStmtError(stmt, "24000", NULL, 0);
57 0 : return SQL_ERROR;
58 : }
59 18 : if (stmt->State == PREPARED0 && FieldIdentifier != SQL_DESC_COUNT) {
60 : /* Prepared statement not a cursor-specification */
61 0 : addStmtError(stmt, "07005", NULL, 0);
62 0 : return SQL_ERROR;
63 : }
64 :
65 18 : if (stmt->ImplRowDescr->descRec == NULL) {
66 : /* General error */
67 0 : addStmtError(stmt, "HY000", "Cannot return the column info. No result set is available", 0);
68 0 : return SQL_ERROR;
69 : }
70 :
71 : /* check input parameter */
72 18 : if (ColumnNumber < 1 || ColumnNumber > stmt->ImplRowDescr->sql_desc_count) {
73 : /* Invalid descriptor index */
74 0 : addStmtError(stmt, "07009", NULL, 0);
75 0 : return SQL_ERROR;
76 : }
77 :
78 : /* TODO: finish implementation */
79 18 : rec = stmt->ImplRowDescr->descRec + ColumnNumber;
80 :
81 18 : switch (FieldIdentifier) {
82 0 : case SQL_DESC_AUTO_UNIQUE_VALUE:/* SQL_COLUMN_AUTO_INCREMENT */
83 0 : if (NumericAttributePtr)
84 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_auto_unique_value;
85 : break;
86 0 : case SQL_DESC_BASE_COLUMN_NAME:
87 0 : copyString(rec->sql_desc_base_column_name,
88 : strlen((char *) rec->sql_desc_base_column_name),
89 : CharacterAttributePtr, BufferLength,
90 : StringLengthPtr, SQLSMALLINT, addStmtError,
91 : stmt, return SQL_ERROR);
92 : break;
93 0 : case SQL_DESC_BASE_TABLE_NAME:
94 0 : copyString(rec->sql_desc_base_table_name,
95 : strlen((char *) rec->sql_desc_base_table_name),
96 : CharacterAttributePtr, BufferLength,
97 : StringLengthPtr, SQLSMALLINT, addStmtError,
98 : stmt, return SQL_ERROR);
99 : break;
100 0 : case SQL_DESC_CASE_SENSITIVE: /* SQL_COLUMN_CASE_SENSITIVE */
101 0 : if (NumericAttributePtr)
102 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_case_sensitive;
103 : break;
104 0 : case SQL_DESC_CATALOG_NAME: /* SQL_COLUMN_QUALIFIER_NAME */
105 0 : copyString(rec->sql_desc_catalog_name,
106 : strlen((char *) rec->sql_desc_catalog_name),
107 : CharacterAttributePtr, BufferLength,
108 : StringLengthPtr, SQLSMALLINT, addStmtError,
109 : stmt, return SQL_ERROR);
110 : break;
111 2 : case SQL_DESC_CONCISE_TYPE: /* SQL_COLUMN_TYPE */
112 2 : if (NumericAttributePtr)
113 2 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_concise_type;
114 : break;
115 0 : case SQL_COLUMN_COUNT:
116 : case SQL_DESC_COUNT:
117 0 : if (NumericAttributePtr)
118 0 : *(SQLLEN *) NumericAttributePtr = stmt->ImplRowDescr->sql_desc_count;
119 : break;
120 2 : case SQL_DESC_DISPLAY_SIZE: /* SQL_COLUMN_DISPLAY_SIZE */
121 2 : if (NumericAttributePtr)
122 2 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_display_size;
123 : break;
124 0 : case SQL_DESC_FIXED_PREC_SCALE: /* SQL_COLUMN_MONEY */
125 0 : if (NumericAttributePtr)
126 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_fixed_prec_scale;
127 : break;
128 0 : case SQL_DESC_LABEL: /* SQL_COLUMN_LABEL */
129 0 : copyString(rec->sql_desc_label,
130 : strlen((char *) rec->sql_desc_label),
131 : CharacterAttributePtr, BufferLength,
132 : StringLengthPtr, SQLSMALLINT, addStmtError,
133 : stmt, return SQL_ERROR);
134 : break;
135 2 : case SQL_COLUMN_LENGTH:
136 : case SQL_DESC_LENGTH:
137 2 : if (NumericAttributePtr)
138 2 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_length;
139 : break;
140 0 : case SQL_DESC_LITERAL_PREFIX:
141 0 : copyString(rec->sql_desc_literal_prefix,
142 : strlen((char *) rec->sql_desc_literal_prefix),
143 : CharacterAttributePtr, BufferLength,
144 : StringLengthPtr, SQLSMALLINT, addStmtError,
145 : stmt, return SQL_ERROR);
146 : break;
147 0 : case SQL_DESC_LITERAL_SUFFIX:
148 0 : copyString(rec->sql_desc_literal_suffix, strlen((char *) rec->sql_desc_literal_suffix), CharacterAttributePtr, BufferLength, StringLengthPtr, SQLSMALLINT, addStmtError, stmt, return SQL_ERROR);
149 : break;
150 0 : case SQL_DESC_LOCAL_TYPE_NAME:
151 0 : copyString(rec->sql_desc_local_type_name,
152 : strlen((char *) rec->sql_desc_local_type_name),
153 : CharacterAttributePtr, BufferLength,
154 : StringLengthPtr, SQLSMALLINT, addStmtError,
155 : stmt, return SQL_ERROR);
156 : break;
157 0 : case SQL_COLUMN_NAME:
158 : case SQL_DESC_NAME:
159 0 : copyString(rec->sql_desc_name,
160 : strlen((char *) rec->sql_desc_name),
161 : CharacterAttributePtr, BufferLength,
162 : StringLengthPtr, SQLSMALLINT, addStmtError,
163 : stmt, return SQL_ERROR);
164 : break;
165 0 : case SQL_COLUMN_NULLABLE:
166 0 : if (NumericAttributePtr)
167 0 : *(SQLINTEGER *) NumericAttributePtr = rec->sql_desc_nullable;
168 : break;
169 0 : case SQL_DESC_NULLABLE:
170 0 : if (NumericAttributePtr)
171 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_nullable;
172 : break;
173 0 : case SQL_DESC_NUM_PREC_RADIX:
174 0 : if (NumericAttributePtr)
175 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_num_prec_radix;
176 : break;
177 0 : case SQL_DESC_OCTET_LENGTH:
178 0 : if (NumericAttributePtr)
179 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_octet_length;
180 : break;
181 0 : case SQL_COLUMN_PRECISION:
182 0 : if (NumericAttributePtr)
183 0 : *(SQLINTEGER *) NumericAttributePtr = rec->sql_desc_precision;
184 : break;
185 0 : case SQL_DESC_PRECISION:
186 0 : if (NumericAttributePtr)
187 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_precision;
188 : break;
189 0 : case SQL_COLUMN_SCALE:
190 0 : if (NumericAttributePtr)
191 0 : *(SQLINTEGER *) NumericAttributePtr = rec->sql_desc_scale;
192 : break;
193 0 : case SQL_DESC_SCALE:
194 0 : if (NumericAttributePtr)
195 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_scale;
196 : break;
197 0 : case SQL_DESC_SCHEMA_NAME: /* SQL_COLUMN_OWNER_NAME */
198 0 : copyString(rec->sql_desc_schema_name,
199 : strlen((char *) rec->sql_desc_schema_name),
200 : CharacterAttributePtr, BufferLength,
201 : StringLengthPtr, SQLSMALLINT, addStmtError,
202 : stmt, return SQL_ERROR);
203 : break;
204 0 : case SQL_DESC_SEARCHABLE: /* SQL_COLUMN_SEARCHABLE */
205 0 : if (NumericAttributePtr)
206 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_searchable;
207 : break;
208 0 : case SQL_DESC_TABLE_NAME: /* SQL_COLUMN_TABLE_NAME */
209 0 : copyString(rec->sql_desc_table_name,
210 : strlen((char *) rec->sql_desc_table_name),
211 : CharacterAttributePtr, BufferLength,
212 : StringLengthPtr, SQLSMALLINT, addStmtError,
213 : stmt, return SQL_ERROR);
214 : break;
215 0 : case SQL_DESC_TYPE:
216 0 : if (NumericAttributePtr)
217 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_type;
218 : break;
219 0 : case SQL_DESC_TYPE_NAME: /* SQL_COLUMN_TYPE_NAME */
220 0 : copyString(rec->sql_desc_type_name,
221 : strlen((char *) rec->sql_desc_type_name),
222 : CharacterAttributePtr, BufferLength,
223 : StringLengthPtr, SQLSMALLINT, addStmtError,
224 : stmt, return SQL_ERROR);
225 : break;
226 0 : case SQL_DESC_UNNAMED:
227 0 : if (NumericAttributePtr)
228 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_unnamed;
229 : break;
230 12 : case SQL_DESC_UNSIGNED: /* SQL_COLUMN_UNSIGNED */
231 12 : if (NumericAttributePtr)
232 12 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_unsigned;
233 : break;
234 0 : case SQL_DESC_UPDATABLE: /* SQL_COLUMN_UPDATABLE */
235 0 : if (NumericAttributePtr)
236 0 : *(SQLLEN *) NumericAttributePtr = rec->sql_desc_updatable;
237 : break;
238 0 : default:
239 : /* Invalid descriptor field identifier */
240 0 : addStmtError(stmt, "HY091", NULL, 0);
241 0 : return SQL_ERROR;
242 : }
243 :
244 18 : return stmt->Error ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
245 : }
246 :
247 : SQLRETURN SQL_API
248 : SQLColAttribute(SQLHSTMT StatementHandle,
249 : SQLUSMALLINT ColumnNumber,
250 : SQLUSMALLINT FieldIdentifier,
251 : SQLPOINTER CharacterAttributePtr,
252 : SQLSMALLINT BufferLength,
253 : SQLSMALLINT *StringLengthPtr,
254 : LENP_OR_POINTER_T NumericAttributePtr)
255 : {
256 : #ifdef ODBCDEBUG
257 6 : ODBCLOG("SQLColAttribute %p %d %s %p %d %p %p\n",
258 : StatementHandle, (int) ColumnNumber,
259 : translateFieldIdentifier(FieldIdentifier),
260 : CharacterAttributePtr, (int) BufferLength,
261 : StringLengthPtr,
262 : (void *) NumericAttributePtr);
263 : #endif
264 :
265 6 : if (!isValidStmt((ODBCStmt *) StatementHandle))
266 : return SQL_INVALID_HANDLE;
267 :
268 6 : clearStmtErrors((ODBCStmt *) StatementHandle);
269 :
270 6 : switch (FieldIdentifier) {
271 : case SQL_DESC_AUTO_UNIQUE_VALUE:
272 : case SQL_DESC_BASE_COLUMN_NAME:
273 : case SQL_DESC_BASE_TABLE_NAME:
274 : case SQL_DESC_CASE_SENSITIVE:
275 : case SQL_DESC_CATALOG_NAME:
276 : case SQL_DESC_CONCISE_TYPE:
277 : case SQL_DESC_COUNT:
278 : case SQL_DESC_DISPLAY_SIZE:
279 : case SQL_DESC_FIXED_PREC_SCALE:
280 : case SQL_DESC_LABEL:
281 : case SQL_DESC_LENGTH:
282 : case SQL_DESC_LITERAL_PREFIX:
283 : case SQL_DESC_LITERAL_SUFFIX:
284 : case SQL_DESC_LOCAL_TYPE_NAME:
285 : case SQL_DESC_NAME:
286 : case SQL_DESC_NULLABLE:
287 : case SQL_DESC_NUM_PREC_RADIX:
288 : case SQL_DESC_OCTET_LENGTH:
289 : case SQL_DESC_PRECISION:
290 : case SQL_DESC_SCALE:
291 : case SQL_DESC_SCHEMA_NAME:
292 : case SQL_DESC_SEARCHABLE:
293 : case SQL_DESC_TABLE_NAME:
294 : case SQL_DESC_TYPE:
295 : case SQL_DESC_TYPE_NAME:
296 : case SQL_DESC_UNNAMED:
297 : case SQL_DESC_UNSIGNED:
298 : case SQL_DESC_UPDATABLE:
299 6 : break;
300 0 : default:
301 : /* Invalid descriptor field identifier */
302 0 : addStmtError((ODBCStmt *) StatementHandle, "HY091", NULL, 0);
303 0 : return SQL_ERROR;
304 : }
305 6 : return MNDBColAttribute((ODBCStmt *) StatementHandle,
306 : ColumnNumber,
307 : FieldIdentifier,
308 : CharacterAttributePtr,
309 : BufferLength,
310 : StringLengthPtr,
311 : NumericAttributePtr);
312 : }
313 :
314 : SQLRETURN SQL_API
315 : SQLColAttributeA(SQLHSTMT StatementHandle,
316 : SQLSMALLINT ColumnNumber,
317 : SQLSMALLINT FieldIdentifier,
318 : SQLPOINTER CharacterAttributePtr,
319 : SQLSMALLINT BufferLength,
320 : SQLSMALLINT *StringLengthPtr,
321 : LENP_OR_POINTER_T NumericAttributePtr)
322 : {
323 0 : return SQLColAttribute(StatementHandle,
324 0 : (SQLUSMALLINT) ColumnNumber,
325 0 : (SQLUSMALLINT) FieldIdentifier,
326 : CharacterAttributePtr,
327 : BufferLength,
328 : StringLengthPtr,
329 : NumericAttributePtr);
330 : }
331 :
332 : SQLRETURN SQL_API
333 : SQLColAttributeW(SQLHSTMT StatementHandle,
334 : SQLUSMALLINT ColumnNumber,
335 : SQLUSMALLINT FieldIdentifier,
336 : SQLPOINTER CharacterAttributePtr,
337 : SQLSMALLINT BufferLength,
338 : SQLSMALLINT *StringLengthPtr,
339 : LENP_OR_POINTER_T NumericAttributePtr)
340 : {
341 12 : ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
342 12 : SQLPOINTER ptr;
343 12 : SQLRETURN rc;
344 12 : SQLSMALLINT n;
345 :
346 : #ifdef ODBCDEBUG
347 12 : ODBCLOG("SQLColAttributeW %p %d %s %p %d %p %p\n",
348 : StatementHandle, (int) ColumnNumber,
349 : translateFieldIdentifier(FieldIdentifier),
350 : CharacterAttributePtr, (int) BufferLength,
351 : StringLengthPtr,
352 : (void *) NumericAttributePtr);
353 : #endif
354 :
355 12 : if (!isValidStmt(stmt))
356 : return SQL_INVALID_HANDLE;
357 :
358 12 : clearStmtErrors(stmt);
359 :
360 12 : switch (FieldIdentifier) {
361 : /* all string atributes */
362 0 : case SQL_DESC_BASE_COLUMN_NAME:
363 : case SQL_DESC_BASE_TABLE_NAME:
364 : case SQL_DESC_CATALOG_NAME: /* SQL_COLUMN_QUALIFIER_NAME */
365 : case SQL_DESC_LABEL: /* SQL_COLUMN_LABEL */
366 : case SQL_DESC_LITERAL_PREFIX:
367 : case SQL_DESC_LITERAL_SUFFIX:
368 : case SQL_DESC_LOCAL_TYPE_NAME:
369 : case SQL_DESC_NAME:
370 : case SQL_DESC_SCHEMA_NAME: /* SQL_COLUMN_OWNER_NAME */
371 : case SQL_DESC_TABLE_NAME: /* SQL_COLUMN_TABLE_NAME */
372 : case SQL_DESC_TYPE_NAME: /* SQL_COLUMN_TYPE_NAME */
373 0 : ptr = malloc(BufferLength);
374 0 : if (ptr == NULL) {
375 : /* Memory allocation error */
376 0 : addStmtError(stmt, "HY001", NULL, 0);
377 0 : return SQL_ERROR;
378 : }
379 : break;
380 : /* all other attributes */
381 : case SQL_DESC_AUTO_UNIQUE_VALUE:
382 : case SQL_DESC_CASE_SENSITIVE:
383 : case SQL_DESC_CONCISE_TYPE:
384 : case SQL_DESC_COUNT:
385 : case SQL_DESC_DISPLAY_SIZE:
386 : case SQL_DESC_FIXED_PREC_SCALE:
387 : case SQL_DESC_LENGTH:
388 : case SQL_DESC_NULLABLE:
389 : case SQL_DESC_NUM_PREC_RADIX:
390 : case SQL_DESC_OCTET_LENGTH:
391 : case SQL_DESC_PRECISION:
392 : case SQL_DESC_SCALE:
393 : case SQL_DESC_SEARCHABLE:
394 : case SQL_DESC_TYPE:
395 : case SQL_DESC_UNNAMED:
396 : case SQL_DESC_UNSIGNED:
397 : case SQL_DESC_UPDATABLE:
398 : ptr = CharacterAttributePtr;
399 : break;
400 0 : default:
401 : /* Invalid descriptor field identifier */
402 0 : addStmtError(stmt, "HY091", NULL, 0);
403 0 : return SQL_ERROR;
404 : }
405 :
406 12 : rc = MNDBColAttribute(stmt, ColumnNumber, FieldIdentifier, ptr,
407 : BufferLength, &n, NumericAttributePtr);
408 :
409 12 : if (ptr != CharacterAttributePtr) {
410 0 : if (rc == SQL_SUCCESS_WITH_INFO) {
411 0 : clearStmtErrors(stmt);
412 0 : free(ptr);
413 0 : ptr = malloc(++n); /* add one for NULL byte */
414 0 : if (ptr == NULL) {
415 : /* Memory allocation error */
416 0 : addStmtError(stmt, "HY001", NULL, 0);
417 0 : return SQL_ERROR;
418 : }
419 0 : rc = MNDBColAttribute(stmt, ColumnNumber,
420 : FieldIdentifier, ptr, n, &n,
421 : NumericAttributePtr);
422 : }
423 0 : if (SQL_SUCCEEDED(rc)) {
424 0 : fixWcharOut(rc, ptr, n, CharacterAttributePtr,
425 : BufferLength, StringLengthPtr, 2,
426 : addStmtError, stmt);
427 : }
428 0 : free(ptr);
429 12 : } else if (StringLengthPtr)
430 0 : *StringLengthPtr = n;
431 :
432 : return rc;
433 : }
|