in driver/handles.c [1565:1829]
SQLRETURN EsSQLGetDescFieldW(
SQLHDESC DescriptorHandle,
SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier,
_Out_writes_opt_(_Inexpressible_(BufferLength))
SQLPOINTER ValuePtr,
SQLINTEGER BufferLength, /* byte count, also for wchar's */
SQLINTEGER *StringLengthPtr)
{
esodbc_desc_st *desc = DSCH(DescriptorHandle);
esodbc_state_et state;
wstr_st wstr;
SQLSMALLINT word;
SQLINTEGER intgr;
esodbc_rec_st *rec;
if (! check_access(desc, FieldIdentifier, O_RDONLY)) {
int llev;
#if 0
/*
* Actually, the spec ask to return success, but just set nothing: ???
* "When an application calls SQLGetDescField to retrieve the value of
* a field that is undefined for a particular descriptor type, the
* function returns SQL_SUCCESS but the value returned for the field
* is undefined."
*/
llev = LOG_LEVEL_ERR;
state = SQL_STATE_HY091;
#else /* 0 */
llev = LOG_LEVEL_WARN;
state = SQL_STATE_01000;
#endif /* 0 */
LOGH(desc, llev, 0, "field (%d) access check failed: not defined for "
"desciptor (type: %d).", FieldIdentifier, desc->type);
RET_HDIAG(desc, state,
"field type not defined for descriptor", 0);
}
state = check_buff(FieldIdentifier, ValuePtr, BufferLength, TRUE);
if (state != SQL_STATE_00000) {
ERRH(desc, "buffer/~ length check failed (%d).", state);
RET_HDIAGS(desc, state);
}
/* header fields */
switch (FieldIdentifier) {
case SQL_DESC_ALLOC_TYPE:
*(SQLSMALLINT *)ValuePtr = desc->alloc_type;
DBGH(desc, "returning: desc alloc type: %hu.",
*(SQLSMALLINT *)ValuePtr);
return SQL_SUCCESS;
case SQL_DESC_ARRAY_SIZE:
*(SQLULEN *)ValuePtr = desc->array_size;
DBGH(desc, "returning: desc array size: %llu.",
(uint64_t)*(SQLULEN *)ValuePtr);
return SQL_SUCCESS;
case SQL_DESC_ARRAY_STATUS_PTR:
*(SQLUSMALLINT **)ValuePtr =
desc->array_status_ptr;
DBGH(desc, "returning: status array ptr: 0x%p.",
(SQLUSMALLINT *)ValuePtr);
return SQL_SUCCESS;
case SQL_DESC_BIND_OFFSET_PTR:
*(SQLLEN **)ValuePtr = desc->bind_offset_ptr;
DBGH(desc, "returning binding offset ptr: 0x%p.",
(SQLLEN *)ValuePtr);
return SQL_SUCCESS;
case SQL_DESC_BIND_TYPE:
*(SQLUINTEGER *)ValuePtr = desc->bind_type;
DBGH(desc, "returning bind type: %lu.", *(SQLUINTEGER *)ValuePtr);
return SQL_SUCCESS;
case SQL_DESC_COUNT:
*(SQLSMALLINT *)ValuePtr = desc->count;
DBGH(desc, "returning count: %hd.", *(SQLSMALLINT *)ValuePtr);
return SQL_SUCCESS;
case SQL_DESC_ROWS_PROCESSED_PTR:
*(SQLULEN **)ValuePtr = desc->rows_processed_ptr;
DBGH(desc, "returning desc rows processed ptr: 0x%p.", ValuePtr);
return SQL_SUCCESS;
}
/*
* The field is a record field -> get the record to apply the field to.
*/
if (RecNumber < 0) { /* TODO: need to check also if AxD, as per spec?? */
ERRH(desc, "negative record number provided (%d) with record field "
"(%d).", RecNumber, FieldIdentifier);
RET_HDIAG(desc, SQL_STATE_07009,
"Negative record number provided with record field", 0);
} else if (RecNumber == 0) {
ERRH(desc, "unsupported record number 0."); /* TODO: bookmarks? */
RET_HDIAG(desc, SQL_STATE_07009,
"Unsupported record number 0", 0);
} else {
/*
* "When an application calls SQLGetDescField to retrieve the value of
* a field that is defined for a particular descriptor type but that
* has no default value and has not been set yet, the function returns
* SQL_SUCCESS but the value returned for the field is undefined."
*/
rec = get_record(desc, RecNumber, FALSE);
if (! rec) {
WARNH(desc, "record #%d not yet set; returning defaults.",
RecNumber);
get_rec_default(FieldIdentifier, BufferLength, ValuePtr);
return SQL_SUCCESS;
}
DBGH(desc, "getting field %d of record #%d @ 0x%p.", FieldIdentifier,
RecNumber, rec);
}
ASSERT_IXD_HAS_ES_TYPE(rec);
/*INDENT-OFF*/
/* record fields */
switch (FieldIdentifier) {
/* <SQLPOINTER> */
case SQL_DESC_DATA_PTR:
*(SQLPOINTER *)ValuePtr = rec->data_ptr;
DBGH(desc, "returning data pointer 0x%p.", rec->data_ptr);
break;
/* <SQLWCHAR *> */
do {
case SQL_DESC_BASE_COLUMN_NAME: wstr = rec->base_column_name; break;
case SQL_DESC_BASE_TABLE_NAME: wstr = rec->base_table_name; break;
case SQL_DESC_CATALOG_NAME: wstr = rec->catalog_name; break;
case SQL_DESC_LABEL: wstr = rec->label; break;
case SQL_DESC_NAME: wstr = rec->name; break;
case SQL_DESC_SCHEMA_NAME: wstr = rec->schema_name; break;
case SQL_DESC_TABLE_NAME: wstr = rec->table_name; break;
case SQL_DESC_LITERAL_PREFIX:
wstr = rec->es_type->literal_prefix;
break;
case SQL_DESC_LITERAL_SUFFIX:
wstr = rec->es_type->literal_suffix;
break;
case SQL_DESC_LOCAL_TYPE_NAME:
wstr = rec->es_type->local_type_name;
break;
case SQL_DESC_TYPE_NAME:
wstr = rec->es_type->type_name;
break;
} while (0);
if (! StringLengthPtr) {
RET_HDIAGS(desc, SQL_STATE_HY009);
} else {
*StringLengthPtr = (SQLINTEGER)wstr.cnt;
}
if (ValuePtr) {
memcpy(ValuePtr, wstr.str, *StringLengthPtr);
}
DBGH(desc, "returning SQLWCHAR record field %d: `" LWPDL "`.",
FieldIdentifier, LWSTR(&wstr));
break;
/* <SQLLEN *> */
case SQL_DESC_INDICATOR_PTR:
*(SQLLEN **)ValuePtr = rec->indicator_ptr;
DBGH(desc, "returning indicator pointer: 0x%p.",
rec->indicator_ptr);
break;
case SQL_DESC_OCTET_LENGTH_PTR:
*(SQLLEN **)ValuePtr = rec->octet_length_ptr;
DBGH(desc, "returning octet length pointer 0x%p.",
rec->octet_length_ptr);
break;
/* <SQLLEN> */
case SQL_DESC_DISPLAY_SIZE:
*(SQLLEN *)ValuePtr = rec->es_type->display_size;
DBGH(desc, "returning display size: %d.",
rec->es_type->display_size);
break;
case SQL_DESC_OCTET_LENGTH:
*(SQLLEN *)ValuePtr = rec->octet_length;
DBGH(desc, "returning octet length: %d.", rec->octet_length);
break;
/* <SQLULEN> */
case SQL_DESC_LENGTH:
*(SQLULEN *)ValuePtr = rec->length;
DBGH(desc, "returning length: %llu.", (uint64_t)rec->length);
break;
/* <SQLSMALLINT> */
do {
case SQL_DESC_CONCISE_TYPE: word = rec->concise_type; break;
case SQL_DESC_TYPE: word = rec->type; break;
case SQL_DESC_DATETIME_INTERVAL_CODE:
word = rec->datetime_interval_code; break;
case SQL_DESC_PARAMETER_TYPE: word = rec->parameter_type; break;
case SQL_DESC_ROWVER: word = rec->rowver; break;
case SQL_DESC_UNNAMED: word = rec->unnamed; break;
case SQL_DESC_PRECISION:
if (rec->desc->type == DESC_TYPE_IRD) {
word = (SQLSMALLINT)rec->es_type->column_size;
} else {
word = rec->precision;
}
break;
case SQL_DESC_SCALE:
if (rec->desc->type == DESC_TYPE_IRD) {
word = rec->es_type->maximum_scale;
} else {
word = rec->scale;
}
break;
case SQL_DESC_FIXED_PREC_SCALE:
word = rec->es_type->fixed_prec_scale;
break;
case SQL_DESC_NULLABLE: word = rec->es_type->nullable; break;
case SQL_DESC_SEARCHABLE: word = rec->es_type->searchable; break;
case SQL_DESC_UNSIGNED: word = rec->es_type->unsigned_attribute; break;
case SQL_DESC_UPDATABLE: word = rec->updatable; break;
} while (0);
*(SQLSMALLINT *)ValuePtr = word;
DBGH(desc, "returning record field %d as %d.", FieldIdentifier,
word);
break;
/* <SQLINTEGER> */
do {
case SQL_DESC_DATETIME_INTERVAL_PRECISION:
if (DESC_TYPE_IS_IMPLEMENTATION(rec->desc->type)) {
/* not used with ES (so far), as no interval types are sup. */
intgr = rec->es_type->interval_precision;
} else {
intgr = rec->datetime_interval_precision;
}
break;
case SQL_DESC_NUM_PREC_RADIX:
if DESC_TYPE_IS_IMPLEMENTATION(rec->desc->type) {
intgr = rec->es_type->num_prec_radix;
} else {
intgr = rec->num_prec_radix;
}
break;
case SQL_DESC_AUTO_UNIQUE_VALUE:
intgr = rec->es_type->auto_unique_value;
break;
case SQL_DESC_CASE_SENSITIVE:
intgr = rec->es_type->case_sensitive;
break;
} while (0);
*(SQLINTEGER *)ValuePtr = intgr;
DBGH(desc, "returning record field %d as %d.", FieldIdentifier,
intgr);
break;
default:
ERRH(desc, "unknown FieldIdentifier: %d.", FieldIdentifier);
RET_HDIAGS(desc, SQL_STATE_HY091);
}
/*INDENT-ON*/
return SQL_SUCCESS;
}