Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ SQLRETURN SQL_API SQLCloseCursor (SQLHSTMT arg0)
SQLRETURN SQL_API SQLColAttribute( SQLHSTMT hStmt, SQLUSMALLINT columnNumber,
SQLUSMALLINT fieldIdentifier, SQLPOINTER characterAttribute,
SQLSMALLINT bufferLength, SQLSMALLINT *stringLength,
#ifdef _WIN64
#if defined(_WIN64) || !defined(_WIN32)
SQLLEN *numericAttribute )
#else
SQLPOINTER numericAttribute )
Expand Down
2 changes: 1 addition & 1 deletion MainUnicode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ SQLRETURN SQL_API SQLDriversW( SQLHENV hEnv, SQLUSMALLINT fDirection,
SQLRETURN SQL_API SQLColAttributeW( SQLHSTMT hStmt, SQLUSMALLINT columnNumber,
SQLUSMALLINT fieldIdentifier, SQLPOINTER characterAttribute,
SQLSMALLINT bufferLength, SQLSMALLINT *stringLength,
#ifdef _WIN64
#if defined(_WIN64) || !defined(_WIN32)
SQLLEN *numericAttribute )
#else
SQLPOINTER numericAttribute )
Expand Down
125 changes: 113 additions & 12 deletions OdbcDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ SQLRETURN OdbcDesc::operator =(OdbcDesc &sour)

if ( srcrec )
{
sour.defineImplRecord( n, srcrec );

rec = srcrec;
rec.sizeColumnExtendedFetch = srcrec->sizeColumnExtendedFetch;
}
Expand Down Expand Up @@ -328,15 +330,107 @@ OdbcObjectType OdbcDesc::getType()
return odbcTypeDescriptor;
}

// An implementation record keeps the concise SQL type in `type` and the
// converter's C type in `conciseType`. The descriptor API reports ODBC's
// verbose type, concise type and datetime interval code, all derived from
// the SQL type; an application may also have stored the verbose form with
// its interval code in an IPD record.
SQLSMALLINT OdbcDesc::conciseSqlType( int type, int datetimeIntervalCode )
{
if ( type == SQL_DATETIME )
{
switch ( datetimeIntervalCode )
{
case SQL_CODE_DATE:
return SQL_TYPE_DATE;
case SQL_CODE_TIME:
return SQL_TYPE_TIME;
case SQL_CODE_TIMESTAMP:
return SQL_TYPE_TIMESTAMP;
}
}
return (SQLSMALLINT)type;
}

SQLSMALLINT OdbcDesc::verboseSqlType( int conciseSqlType )
{
switch ( conciseSqlType )
{
case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
case SQL_TYPE_TIMESTAMP:
case SQL_TIME:
case SQL_TIMESTAMP:
return SQL_DATETIME;
}
return (SQLSMALLINT)conciseSqlType;
}

SQLSMALLINT OdbcDesc::datetimeIntervalCodeOf( int conciseSqlType )
{
switch ( conciseSqlType )
{
case SQL_TYPE_DATE:
return SQL_CODE_DATE;
case SQL_TYPE_TIME:
case SQL_TIME:
return SQL_CODE_TIME;
case SQL_TYPE_TIMESTAMP:
case SQL_TIMESTAMP:
return SQL_CODE_TIMESTAMP;
}
return 0;
}

// SQLPrepare sizes the implementation descriptors but fills a record only
// when its column or parameter is bound or the statement executes. The
// descriptor API fills it the same way before reading or copying it.
void OdbcDesc::defineImplRecord( int recNumber, DescRecord * record )
{
if ( !recNumber || record->isDefined )
return;

if ( headType == odtImplementationRow )
{
if ( metaDataOut )
defFromMetaDataOut( recNumber, record );
}
else if ( headType == odtImplementationParameter )
{
int countIn = metaDataIn ? metaDataIn->getColumnCount() : 0;

if ( recNumber <= countIn )
defFromMetaDataIn( recNumber, record );
else if ( metaDataOut && recNumber - countIn <= metaDataOut->getColumnCount() )
defFromMetaDataOut( recNumber - countIn, record );
}
}

SQLRETURN OdbcDesc::sqlGetDescField(int recNumber, int fieldId, SQLPOINTER ptr, int bufferLength, SQLINTEGER *lengthPtr)
{
clearErrors();
SQLINTEGER size = 0;
SQLCHAR *string = NULL;
DescRecord *record = NULL;
const bool implRecord = headType == odtImplementationRow || headType == odtImplementationParameter;

if ( bDefined == false )
return sqlReturn (SQL_ERROR, "HY091", "Invalid descriptor field identifier");
{
switch (fieldId)
{
case SQL_DESC_ALLOC_TYPE:
case SQL_DESC_ARRAY_SIZE:
case SQL_DESC_ARRAY_STATUS_PTR:
case SQL_DESC_BIND_OFFSET_PTR:
case SQL_DESC_BIND_TYPE:
case SQL_DESC_ROWS_PROCESSED_PTR:
break; // header fields do not depend on the result set
default:
if ( headType == odtImplementationRow )
return sqlReturn (SQL_ERROR, "HY007", "Associated statement is not prepared");
return sqlReturn (SQL_ERROR, "HY091", "Invalid descriptor field identifier");
}
}

if ( recNumber > headCount )
return sqlReturn (SQL_NO_DATA_FOUND, "HY021", "Inconsistent descriptor information");
Expand All @@ -356,6 +450,7 @@ SQLRETURN OdbcDesc::sqlGetDescField(int recNumber, int fieldId, SQLPOINTER ptr,
if ( !recNumber && headType == odtImplementationParameter )
return sqlReturn (SQL_ERROR, "HY091", "Invalid descriptor field identifier");
record = getDescRecord (recNumber);
defineImplRecord( recNumber, record );
}

try
Expand Down Expand Up @@ -455,19 +550,19 @@ SQLRETURN OdbcDesc::sqlGetDescField(int recNumber, int fieldId, SQLPOINTER ptr,
// Record
case SQL_DESC_TYPE:
if (record && ptr)
*(SQLSMALLINT*) ptr = record->type,
*(SQLSMALLINT*) ptr = implRecord ? verboseSqlType( conciseSqlType( record->type, record->datetimeIntervalCode ) ) : record->type,
size = sizeof (SQLSMALLINT);
break;

case SQL_DESC_DATETIME_INTERVAL_CODE:
if (record && ptr)
*(SQLSMALLINT*) ptr = record->datetimeIntervalCode,
*(SQLSMALLINT*) ptr = implRecord ? datetimeIntervalCodeOf( conciseSqlType( record->type, record->datetimeIntervalCode ) ) : record->datetimeIntervalCode,
size = sizeof (SQLSMALLINT);
break;

case SQL_DESC_CONCISE_TYPE:
if (record && ptr)
*(SQLSMALLINT*) ptr = record->conciseType,
*(SQLSMALLINT*) ptr = implRecord ? conciseSqlType( record->type, record->datetimeIntervalCode ) : record->conciseType,
size = sizeof (SQLSMALLINT);
break;

Expand Down Expand Up @@ -536,8 +631,8 @@ SQLRETURN OdbcDesc::sqlGetDescField(int recNumber, int fieldId, SQLPOINTER ptr,
if(headType == odtImplementationRow)
{
if (record && ptr)
*(SQLINTEGER*) ptr = record->displaySize,
size = sizeof (SQLINTEGER);
*(SQLLEN*) ptr = record->displaySize,
size = sizeof (SQLLEN);
}
else
return sqlReturn (SQL_ERROR, "HY091", "Invalid descriptor field identifier");
Expand Down Expand Up @@ -599,8 +694,8 @@ SQLRETURN OdbcDesc::sqlGetDescField(int recNumber, int fieldId, SQLPOINTER ptr,

case SQL_DESC_LENGTH:
if (record && ptr)
*(SQLUINTEGER*) ptr = record->length,
size = sizeof (SQLUINTEGER);
*(SQLULEN*) ptr = record->length,
size = sizeof (SQLULEN);
break;

case SQL_DESC_NAME:
Expand Down Expand Up @@ -638,8 +733,8 @@ SQLRETURN OdbcDesc::sqlGetDescField(int recNumber, int fieldId, SQLPOINTER ptr,

case SQL_DESC_OCTET_LENGTH:
if (record && ptr)
*(SQLINTEGER*) ptr = record->octetLength,
size = sizeof (SQLINTEGER);
*(SQLLEN*) ptr = record->octetLength,
size = sizeof (SQLLEN);
break;

case SQL_DESC_OCTET_LENGTH_PTR:
Expand Down Expand Up @@ -1198,7 +1293,11 @@ SQLRETURN OdbcDesc::sqlGetDescRec( SQLSMALLINT recNumber,
DescRecord *record = NULL;

if ( bDefined == false )
{
if ( headType == odtImplementationRow )
return sqlReturn (SQL_ERROR, "HY007", "Associated statement is not prepared");
return sqlReturn (SQL_ERROR, "HY091", "Invalid descriptor field identifier");
}

if ( recNumber > headCount )
return sqlReturn (SQL_NO_DATA_FOUND, "HY021", "Inconsistent descriptor information");
Expand All @@ -1207,15 +1306,17 @@ SQLRETURN OdbcDesc::sqlGetDescRec( SQLSMALLINT recNumber,
return sqlReturn (SQL_ERROR, "HY091", "Invalid descriptor field identifier");

record = getDescRecord (recNumber);
defineImplRecord( recNumber, record );
const bool implRecord = headType == odtImplementationRow || headType == odtImplementationParameter;

try
{
rc = returnStringInfo (name, bufferLength,stringLengthPtr,record->name.getString());
if( rc )
return rc;

*typePtr = record->type;
*subTypePtr = record->datetimeIntervalCode;
*typePtr = implRecord ? verboseSqlType( conciseSqlType( record->type, record->datetimeIntervalCode ) ) : record->type;
*subTypePtr = implRecord ? datetimeIntervalCodeOf( conciseSqlType( record->type, record->datetimeIntervalCode ) ) : record->datetimeIntervalCode;
*lengthPtr = record->octetLength;
*precisionPtr = record->precision;
*scalePtr = record->scale;
Expand Down
4 changes: 4 additions & 0 deletions OdbcDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ class OdbcDesc : public OdbcObject
void defFromMetaDataOut(int recNumber, DescRecord * record);
int getConciseType(int type);
int getConciseSize(int type, int length);
void defineImplRecord(int recNumber, DescRecord * record);
static SQLSMALLINT conciseSqlType(int type, int datetimeIntervalCode);
static SQLSMALLINT verboseSqlType(int conciseSqlType);
static SQLSMALLINT datetimeIntervalCodeOf(int conciseSqlType);
int getDefaultFromSQLToConciseType(int sqlType, int bufferLength = 0);

//Head
Expand Down
26 changes: 19 additions & 7 deletions OdbcStatement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ OdbcStatement::OdbcStatement(OdbcConnection *connect, int statementNumber)
statement = connection->connection->createInternalStatement();
bulkInsert = NULL;
execute = &OdbcStatement::executeStatement;
keysetSize = 0;
fetchNext = &ResultSet::nextFetch;
schemaFetchData = true;
metaData = NULL;
Expand Down Expand Up @@ -2577,6 +2578,11 @@ SQLRETURN OdbcStatement::sqlGetStmtAttr(int attribute, SQLPOINTER ptr, int buffe
TRACE02(SQL_ROWSET_SIZE,value);
break;

case SQL_ATTR_KEYSET_SIZE:
value = keysetSize;
TRACE02(SQL_ATTR_KEYSET_SIZE,value);
break;

case SQL_ATTR_MAX_ROWS: // SQL_MAX_ROWS 1
value = maxRows;
TRACE02(SQL_ATTR_MAX_ROWS,value);
Expand Down Expand Up @@ -3434,6 +3440,10 @@ SQLRETURN OdbcStatement::sqlSetStmtAttr(int attribute, SQLPOINTER ptr, int lengt
break;

case SQL_ATTR_KEYSET_SIZE: // 8
keysetSize = (uintptr_t) ptr;
TRACE02(SQL_ATTR_KEYSET_SIZE,(intptr_t) ptr);
break;

case SQL_ROWSET_SIZE: // 9
applicationRowDescriptor->headArraySize = (intptr_t) ptr;
TRACE02(SQL_ROWSET_SIZE,(intptr_t) ptr);
Expand Down Expand Up @@ -3658,7 +3668,7 @@ SQLRETURN OdbcStatement::sqlRowCount(SQLLEN *rowCount)
return sqlSuccess();
}

#ifdef _WIN64
#if defined(_WIN64) || !defined(_WIN32)
SQLRETURN OdbcStatement::sqlColAttribute( int column, int fieldId, SQLPOINTER attributePtr, int bufferLength, SQLSMALLINT *strLengthPtr, SQLLEN *numericAttributePtr )
#else
SQLRETURN OdbcStatement::sqlColAttribute( int column, int fieldId, SQLPOINTER attributePtr, int bufferLength, SQLSMALLINT *strLengthPtr, SQLPOINTER numericAttributePtr )
Expand Down Expand Up @@ -3704,11 +3714,18 @@ SQLRETURN OdbcStatement::sqlColAttribute( int column, int fieldId, SQLPOINTER at
value = metaData->getColumnCount();
break;

case SQL_DESC_TYPE:
case SQL_DESC_CONCISE_TYPE:
value = metaData->getColumnType (column, realSqlType);
break;

case SQL_DESC_TYPE:
value = OdbcDesc::verboseSqlType( metaData->getColumnType (column, realSqlType) );
break;

case SQL_DESC_DATETIME_INTERVAL_CODE:
value = OdbcDesc::datetimeIntervalCodeOf( metaData->getColumnType (column, realSqlType) );
break;

case SQL_COLUMN_LENGTH:
case SQL_DESC_LENGTH:
value = metaData->getColumnDisplaySize (column);
Expand Down Expand Up @@ -3803,13 +3820,8 @@ SQLRETURN OdbcStatement::sqlColAttribute( int column, int fieldId, SQLPOINTER at
setString (string, (SQLCHAR*) attributePtr, bufferLength, strLengthPtr);
else if (numericAttributePtr)
{
#ifdef _WIN64
*(SQLLEN*) numericAttributePtr = value;
if ( strLengthPtr ) *strLengthPtr = sizeof ( SQLLEN );
#else
*(SQLINTEGER*) numericAttributePtr = value;
if ( strLengthPtr ) *strLengthPtr = sizeof ( SQLINTEGER );
#endif
}

return sqlSuccess();
Expand Down
3 changes: 2 additions & 1 deletion OdbcStatement.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class OdbcStatement : public OdbcObject
inline SQLRETURN fetchData();
inline SQLRETURN returnData();
inline SQLRETURN returnDataFromExtendedFetch();
#ifdef _WIN64
#if defined(_WIN64) || !defined(_WIN32)
SQLRETURN sqlColAttribute( int column, int fieldId, SQLPOINTER attributePtr, int bufferLength, SQLSMALLINT *strLengthPtr, SQLLEN *numericAttributePtr );
#else
SQLRETURN sqlColAttribute( int column, int fieldId, SQLPOINTER attributePtr, int bufferLength, SQLSMALLINT *strLengthPtr, SQLPOINTER numericAttributePtr );
Expand Down Expand Up @@ -192,6 +192,7 @@ class OdbcStatement : public OdbcObject
bool asyncEnable;
int rowNumber;
int rowNumberParamArray;
SQLULEN keysetSize;
int lastRowsetSize;
SQLLEN indicatorRowNumber;
int maxRows;
Expand Down
Loading
Loading