in driver/info.c [861:1080]
SQLRETURN EsSQLGetDiagFieldW(
SQLSMALLINT HandleType,
SQLHANDLE Handle,
SQLSMALLINT RecNumber,
SQLSMALLINT DiagIdentifier,
_Out_writes_opt_(_Inexpressible_(BufferLength)) SQLPOINTER DiagInfoPtr,
SQLSMALLINT BufferLength,
_Out_opt_ SQLSMALLINT *StringLengthPtr)
{
esodbc_dbc_st *dbc;
esodbc_diag_st *diag, bak;
esodbc_env_st dummy;
SQLSMALLINT used;
size_t len;
void *srcptr;
wstr_st *wstrp, wstr;
SQLRETURN ret;
if (RecNumber <= 0) {
ERRH(Handle, "record number must be >=1; received: %d.", RecNumber);
return SQL_ERROR;
} else if (1 < RecNumber) {
return SQL_NO_DATA;
}
if (! Handle) {
ERR("null handle provided.");
return SQL_INVALID_HANDLE;
}
diag = &HDRH(Handle)->diag;
/* GetDiagField can't set diagnostics itself, so use a dummy */
*HDRH(&dummy) = *HDRH(Handle); /* need a valid hhdr struct */
/*INDENT-OFF*/
switch (DiagIdentifier) {
/* Header Fields */
case SQL_DIAG_NUMBER:
if (! DiagInfoPtr) {
ERRH(Handle, "NULL DiagInfo with SQL_DIAG_NUMBER");
return SQL_ERROR;
}
*(SQLINTEGER *)DiagInfoPtr =
(diag->state != SQL_STATE_00000) ? 1 : 0;
DBGH(Handle, "available diagnostics count: %ld.",
*(SQLINTEGER *)DiagInfoPtr);
return SQL_SUCCESS;
case SQL_DIAG_CURSOR_ROW_COUNT:
case SQL_DIAG_DYNAMIC_FUNCTION:
case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
case SQL_DIAG_ROW_COUNT:
/* should be handled by DM */
if (HandleType != SQL_HANDLE_STMT) {
ERRH(Handle, "DiagIdentifier %d called with non-statement "
"handle type %d.", DiagIdentifier, HandleType);
return SQL_ERROR;
}
ERRH(Handle, "DiagIdentifier %hd is not supported.");
return SQL_ERROR;
/* case SQL_DIAG_RETURNCODE: break; -- DM only */
/* Record Fields */
do {
case SQL_DIAG_CLASS_ORIGIN:
len = (sizeof(ORIG_DISCRIM) - 1) * sizeof (SQLWCHAR);
assert(len <= sizeof(esodbc_errors[diag->state].code));
if (memcmp(esodbc_errors[diag->state].code, MK_WPTR(ORIG_DISCRIM),
len) == 0) {
wstrp = &MK_WSTR(ORIG_CLASS_ODBC);
} else {
wstrp = &MK_WSTR(ORIG_CLASS_ISO);
}
break;
case SQL_DIAG_SUBCLASS_ORIGIN:
switch (diag->state) {
case SQL_STATE_01S00:
case SQL_STATE_01S01:
case SQL_STATE_01S02:
case SQL_STATE_01S06:
case SQL_STATE_01S07:
case SQL_STATE_07S01:
case SQL_STATE_08S01:
case SQL_STATE_21S01:
case SQL_STATE_21S02:
case SQL_STATE_25S01:
case SQL_STATE_25S02:
case SQL_STATE_25S03:
case SQL_STATE_42S01:
case SQL_STATE_42S02:
case SQL_STATE_42S11:
case SQL_STATE_42S12:
case SQL_STATE_42S21:
case SQL_STATE_42S22:
case SQL_STATE_HY095:
case SQL_STATE_HY097:
case SQL_STATE_HY098:
case SQL_STATE_HY099:
case SQL_STATE_HY100:
case SQL_STATE_HY101:
case SQL_STATE_HY105:
case SQL_STATE_HY107:
case SQL_STATE_HY109:
case SQL_STATE_HY110:
case SQL_STATE_HY111:
case SQL_STATE_HYT00:
case SQL_STATE_HYT01:
case SQL_STATE_IM001:
case SQL_STATE_IM002:
case SQL_STATE_IM003:
case SQL_STATE_IM004:
case SQL_STATE_IM005:
case SQL_STATE_IM006:
case SQL_STATE_IM007:
case SQL_STATE_IM008:
case SQL_STATE_IM010:
case SQL_STATE_IM011:
case SQL_STATE_IM012:
wstrp = &MK_WSTR(ORIG_CLASS_ODBC);
break;
default:
wstrp = &MK_WSTR(ORIG_CLASS_ISO);
}
break;
} while (0);
DBGH(Handle, "diagnostic code '"LWPD"' is of class '" LWPDL "'.",
esodbc_errors[diag->state].code, LWSTR(wstrp));
return write_wstr(&dummy, DiagInfoPtr, wstrp, BufferLength,
StringLengthPtr);
do {
case SQL_DIAG_CONNECTION_NAME:
case SQL_DIAG_SERVER_NAME:
switch (HandleType) {
case SQL_HANDLE_DBC:
dbc = DBCH(Handle);
break;
case SQL_HANDLE_STMT:
dbc = STMH(Handle)->hdr.dbc;
break;
case SQL_HANDLE_DESC:
dbc = DSCH(Handle)->hdr.stmt->hdr.dbc;
break;
default:
ERR("unknown handle type %hd, @0x%p.", HandleType, Handle);
return SQL_ERROR; // SQL_INVALID_HANDLE?
}
} while (0);
/* save (and then restore) the diag state, since this call mustn't
* change it */
bak = dbc->hdr.diag;
ret = EsSQLGetInfoW(dbc,
DiagIdentifier == SQL_DIAG_CONNECTION_NAME ?
SQL_DATA_SOURCE_NAME : SQL_SERVER_NAME,
DiagInfoPtr, BufferLength, StringLengthPtr);
dbc->hdr.diag = bak;
return ret;
case SQL_DIAG_MESSAGE_TEXT:
wstr.str = diag->text;
wstr.cnt = diag->text_len;
return write_wstr(Handle, DiagInfoPtr, &wstr,
BufferLength * sizeof(*diag->text), StringLengthPtr);
do {
case SQL_DIAG_NATIVE:
len = sizeof(diag->native_code);
srcptr = &diag->native_code;
break;
case SQL_DIAG_COLUMN_NUMBER:
len = sizeof(diag->column_number);
srcptr = &diag->column_number;
break;
case SQL_DIAG_ROW_NUMBER:
len = sizeof(diag->row_number);
srcptr = &diag->row_number;
break;
} while (0);
if (BufferLength != SQL_IS_POINTER) {
WARNH(Handle, "BufferLength param not indicating a ptr type.");
}
if (! DiagInfoPtr) {
ERRH(Handle, "integer diagnostic field %hd asked for, but "
"NULL destination provided.");
RET_HDIAGS(Handle, SQL_STATE_HY009);
} else {
memcpy(DiagInfoPtr, srcptr, len);
}
return SQL_SUCCESS;
case SQL_DIAG_SQLSTATE:
if (diag->state == SQL_STATE_00000) {
DBGH(Handle, "no diagnostic available for handle type %d.",
HandleType);
/* "The function also returns SQL_NO_DATA for any positive
* RecNumber if there are no diagnostic records for Handle" */
return SQL_NO_DATA;
}
wstr.str = esodbc_errors[diag->state].code;
wstr.cnt = wcslen(wstr.str);
ret = write_wstr(&dummy, DiagInfoPtr, &wstr, BufferLength, &used);
if (StringLengthPtr) {
*StringLengthPtr = used;
} else {
/* SQLSTATE is always on 5 chars, but this Identifier sticks
* out, by not being given a buffer to write this into */
WARNH(Handle, "SQLSTATE writen on %uB, but no output buffer "
"provided.", used);
}
return ret;
default:
ERRH(Handle, "unknown DiagIdentifier: %d.", DiagIdentifier);
return SQL_ERROR;
}
/*INDENT-ON*/
assert(0); // FIXME: shouldn't get here
return SQL_ERROR;
}