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
1 change: 1 addition & 0 deletions IscDbc/Connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ class HeadSqlVar
virtual char * getSqlData() = 0;
virtual short * getSqlInd() = 0;
virtual void setSqlData( char *data ) = 0;
virtual void writeStringData( const char *src, int len ) = 0;
//virtual void setSqlInd( short *ind ) = 0;

virtual bool isReplaceForParamArray () = 0;
Expand Down
21 changes: 21 additions & 0 deletions IscDbc/IscHeadSqlVar.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,27 @@ class IscHeadSqlVar : public HeadSqlVar
inline char * getSqlData() { return sqlvar->sqldata; }
inline short * getSqlInd() { return sqlvar->sqlind; }

// Write `len` bytes from `src` into the sqlvar's pre-allocated buffer,
// honoring Firebird's in-buffer layout for the prepared type:
// SQL_VARYING : [uint16 len][data...] — leaves sqltype/sqllen untouched
// so checkAndRebuild() sees no override and Firebird reads
// the buffer using the original VARCHAR(N) metadata.
// SQL_TEXT : bare bytes; reports the effective length via sqllen.
inline void writeStringData(const char *src, int len)
{
char *buf = sqlvar->sqldata;
if (sqlvar->sqltype == SQL_VARYING)
{
*(unsigned short*)buf = (unsigned short)len;
memcpy(buf + sizeof(short), src, len);
}
else
{
memcpy(buf, src, len);
sqlvar->sqllen = (short)len;
}
}

// not used
//void setSqlInd( short *ind ) { sqlvar->sqlind = ind; }
//void setSqlType ( short type ) { sqlvar->sqltype = type; }
Expand Down
17 changes: 14 additions & 3 deletions IscDbc/Sqlda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,18 @@ const char* Sqlda::getColumnName(int index)

int Sqlda::getPrecision(int index)
{
CAttrSqlVar *var = Var(index);
CAttrSqlVar *curVar = Var(index);
// INPUT parameter precision is immutable from prepare time, even if the
// conversion layer later mutates sqllen on the CAttrSqlVar (e.g. the
// SQL_TEXT branch of writeStringData reports the effective length that
// way). Read from the orgSqlProperties snapshot so re-binding never
// sees a shrunken precision — this mirrors getColumnDisplaySize above.
// OUTPUT always uses the current sqlvar; SQL_ARRAY needs the mutable
// CAttrSqlVar for its `array` pointer.
const SqlProperties *var =
(SqldaDir == SQLDA_INPUT && curVar->sqltype != SQL_ARRAY)
? orgVarSqlProperties(index)
: curVar;

switch (var->sqltype)
{
Expand Down Expand Up @@ -798,8 +809,8 @@ int Sqlda::getPrecision(int index)
MAX_DECIMAL_LENGTH,
MAX_QUAD_LENGTH);

case SQL_ARRAY:
return var->array->arrOctetLength;
case SQL_ARRAY:
return curVar->array->arrOctetLength;
// return MAX_ARRAY_LENGTH;

case SQL_BLOB:
Expand Down
Loading