Repository: trafodion Updated Branches: refs/heads/master 98b3ac3ab -> 1ee3de706
ClipVarchar Project: http://git-wip-us.apache.org/repos/asf/trafodion/repo Commit: http://git-wip-us.apache.org/repos/asf/trafodion/commit/4ffb07a8 Tree: http://git-wip-us.apache.org/repos/asf/trafodion/tree/4ffb07a8 Diff: http://git-wip-us.apache.org/repos/asf/trafodion/diff/4ffb07a8 Branch: refs/heads/master Commit: 4ffb07a845940e310fc41f75907e7e5393f0db52 Parents: ed0daf5 Author: Li Ze <[email protected]> Authored: Thu May 31 16:19:57 2018 +0800 Committer: Li Ze <[email protected]> Committed: Thu May 31 17:34:00 2018 +0800 ---------------------------------------------------------------------- .../jdbc/t4/CONNECTION_CONTEXT_def.java | 1 + .../jdbc/t4/InitializeDialogueMessage.java | 5 +- .../trafodion/jdbc/t4/InterfaceConnection.java | 4 + .../trafodion/jdbc/t4/InterfaceResultSet.java | 103 +++++++++++++--- .../org/trafodion/jdbc/t4/T4DSProperties.java | 3 + .../org/trafodion/jdbc/t4/T4Properties.java | 32 +++-- .../org/trafodion/jdbc/t4/TrafT4Statement.java | 4 +- core/conn/odbc/src/odbc/Common/Global.h | 2 + .../odbc/Krypton/generated_incs/odbcCommon.h | 1 + .../src/odbc/nsksrvr/Interface/odbcs_srvr.cpp | 3 + core/conn/odbc/src/odbc/nsksrvr/SrvrConnect.cpp | 1 + .../odbc/src/odbc/nsksrvrcore/srvrothers.cpp | 119 ++++++++++++++++++- 12 files changed, 247 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/CONNECTION_CONTEXT_def.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/CONNECTION_CONTEXT_def.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/CONNECTION_CONTEXT_def.java index d38b178..9f5c0ed 100644 --- a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/CONNECTION_CONTEXT_def.java +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/CONNECTION_CONTEXT_def.java @@ -35,6 +35,7 @@ class CONNECTION_CONTEXT_def { short autoCommit; short queryTimeoutSec; short idleTimeoutSec; + short clipVarchar; short loginTimeoutSec; short txnIsolationLevel; short rowSetSize; http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InitializeDialogueMessage.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InitializeDialogueMessage.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InitializeDialogueMessage.java index 39ba2b8..289f1d8 100644 --- a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InitializeDialogueMessage.java +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InitializeDialogueMessage.java @@ -40,14 +40,15 @@ class InitializeDialogueMessage { wlength += TRANSPORT.size_int; // dialogueId wlength += TRANSPORT.size_int; // optionFlags1 wlength += TRANSPORT.size_int; // optionFlags2 + wlength += TRANSPORT.size_int; // clipVarchar wlength += sessionBytes.length; wlength += clientUserBytes.length; buf = new LogicalByteArray(wlength, Header.sizeOf(), ic.getByteSwap()); + userDesc.insertIntoByteArray(buf); inContext.insertIntoByteArray(buf); - buf.insertInt(dialogueId); buf.insertInt(optionFlags1); buf.insertInt(optionFlags2); @@ -60,7 +61,7 @@ class InitializeDialogueMessage { { buf.insertString(clientUserBytes); } - + buf.insertInt(inContext.clipVarchar); return buf; } } http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceConnection.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceConnection.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceConnection.java index 46bed22..da3dcae 100644 --- a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceConnection.java +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceConnection.java @@ -228,6 +228,7 @@ class InterfaceConnection { inContext.queryTimeoutSec = t4props.getQueryTimeout(); inContext.idleTimeoutSec = (short) t4props.getConnectionTimeout(); + inContext.clipVarchar = (short) t4props.getClipVarchar(); inContext.loginTimeoutSec = (short) t4props.getLoginTimeout(); inContext.txnIsolationLevel = (short) SQL_TXN_READ_COMMITTED; inContext.rowSetSize = t4props.getFetchBufferSize(); @@ -388,6 +389,9 @@ class InterfaceConnection { int getConnectionTimeout() { return inContext.idleTimeoutSec; } + short getClipVarchar() { + return inContext.clipVarchar; + } String getCatalog() { if (outContext != null) { http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java index 7273338..fe911e5 100644 --- a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java @@ -712,7 +712,7 @@ class InterfaceResultSet { } // ---------------------------------------------------------------------------- - void setExecute2FetchOutputs(TrafT4ResultSet rs, int rowsAffected, boolean endOfData, byte[] values) + void setExecute2FetchOutputs(TrafT4ResultSet rs, int rowsAffected, boolean endOfData, byte[] values, boolean calledByFetch) throws SQLException { if (rs.useOldDateFormat()) { setFetchOutputs(rs, rowsAffected, endOfData, values); @@ -728,24 +728,50 @@ class InterfaceResultSet { int byteIndex = 0; int SQLDataInd = 0; int byteLen = 0; + int startOffset = 0; + int varOffset = 0; + int bufferLen =0; int maxRowLen = rs.connection_.ic_.getTransportBufferSize(); // maxRowLen columnArray = new Object[columnCount]; - int dataLength = 0; if (rs.outputDesc_ != null && rs.outputDesc_.length > 0) { dataLength = rs.outputDesc_[0].rowLength_; } - + long [] colBufLen = new long[columnCount]; + long remainLen = 0; + for (columnIndex = 0; columnIndex < columnCount; columnIndex++) { + if(columnIndex == columnCount - 1) + colBufLen[columnIndex] = dataLength - remainLen; + else { + if(rs.outputDesc_[columnIndex+1].nullValue_ != -1) { + colBufLen[columnIndex] = rs.outputDesc_[columnIndex+1].nullValue_ - startOffset; + startOffset = rs.outputDesc_[columnIndex+1].nullValue_; + } + else + { + colBufLen[columnIndex] = rs.outputDesc_[columnIndex+1].noNullValue_ - startOffset; + startOffset = rs.outputDesc_[columnIndex+1].noNullValue_; + } + remainLen += colBufLen[columnIndex]; + } + } + startOffset = 0; int rowOffset = 0; + int varcharCount = 0; + + for (columnIndex = 0; columnIndex < columnCount; columnIndex++) { + if(rs.outputDesc_[columnIndex].dataType_ == SQLTYPECODE_VARCHAR) + varcharCount ++; + } + for (rowIndex = 0; rowIndex < rowsAffected; rowIndex++) { rowOffset = rowIndex * dataLength; for (columnIndex = 0; columnIndex < columnCount; columnIndex++) { int noNullValueOffset = rs.outputDesc_[columnIndex].noNullValue_; int nullValueOffset = rs.outputDesc_[columnIndex].nullValue_; - if (nullValueOffset != -1) nullValueOffset += rowOffset; if (noNullValueOffset != -1) @@ -758,18 +784,63 @@ class InterfaceResultSet { rs.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "setExecute2FetchOutputs", temp, p); } - - if (nullValueOffset != -1 && Bytes.extractShort(values, nullValueOffset, this.ic_.getByteSwap()) == -1) { - columnValue = null; - } else { - columnValue = getExecute2FetchString(rs.connection_, rs.outputDesc_[columnIndex], values, - noNullValueOffset, rs.outputDesc_[columnIndex].dataType_, rs.useOldDateFormat(), this.ic_.getByteSwap()); - if (columnValue == null) { - throw TrafT4Messages - .createSQLException(rs.connection_.props_, ic_.getLocale(), "null_data", null); + if (rs.connection_.props_.getClipVarchar() != 0 && calledByFetch && varcharCount > 0) { // parse clipped buffer + if (nullValueOffset != -1 + && Bytes.extractShort(values, startOffset, this.ic_.getByteSwap()) == -1) { + varOffset = noNullValueOffset - nullValueOffset; + columnValue = null; + } else { + if(nullValueOffset == -1) + { + varOffset = 0; + columnValue = getExecute2FetchString(rs.connection_, rs.outputDesc_[columnIndex], values, + startOffset, rs.outputDesc_[columnIndex].dataType_, rs.useOldDateFormat(), + this.ic_.getByteSwap()); + if (columnValue == null) { + throw TrafT4Messages.createSQLException(rs.connection_.props_, ic_.getLocale(), "null_data", + null); + } + } + else { + varOffset = noNullValueOffset - nullValueOffset; + columnValue = getExecute2FetchString(rs.connection_, rs.outputDesc_[columnIndex], values, + startOffset + varOffset, rs.outputDesc_[columnIndex].dataType_, + rs.useOldDateFormat(), this.ic_.getByteSwap()); + if (columnValue == null) { + throw TrafT4Messages.createSQLException(rs.connection_.props_, ic_.getLocale(), + "null_data", null); + } + } + } // end if else + switch (rs.outputDesc_[columnIndex].dataType_) { + case SQLTYPECODE_VARCHAR: + boolean shortLength = rs.outputDesc_[columnIndex].precision_ < Math.pow(2, 15); + int dataOffset = ((shortLength) ? 2 : 4); + if(columnValue == null) + bufferLen = varOffset; + else + bufferLen = varOffset + dataOffset + ((byte[]) columnValue).length; + startOffset += bufferLen; + break; + default: + startOffset += colBufLen[columnIndex]; + break; } - } // end if else - + } + else{ + if (nullValueOffset != -1 + && Bytes.extractShort(values, nullValueOffset, this.ic_.getByteSwap()) == -1) { + columnValue = null; + } else { + columnValue = getExecute2FetchString(rs.connection_, rs.outputDesc_[columnIndex], values, + noNullValueOffset, rs.outputDesc_[columnIndex].dataType_, rs.useOldDateFormat(), + this.ic_.getByteSwap()); + if (columnValue == null) { + throw TrafT4Messages.createSQLException(rs.connection_.props_, ic_.getLocale(), "null_data", + null); + } + } // end if else + } columnArray[columnIndex] = columnValue; } // end for @@ -842,7 +913,7 @@ class InterfaceResultSet { rs.rawBuffer_ = fr.outValues; } - setExecute2FetchOutputs(rs, fr.rowsAffected, endOfData, fr.outValues); + setExecute2FetchOutputs(rs, fr.rowsAffected, endOfData, fr.outValues,true); dataFound = true; } http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4DSProperties.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4DSProperties.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4DSProperties.java index c16ab8e..700dfb1 100644 --- a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4DSProperties.java +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4DSProperties.java @@ -616,6 +616,9 @@ public class T4DSProperties extends T4Properties { public void setConnectionTimeout(int connectionTimeout) { super.setConnectionTimeout(connectionTimeout); } + public void setClipVarchar(short clipVarchar) { + super.setClipVarchar(clipVarchar); + } /** * Sets the max idle time value for the Type 4 connection. The default is http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Properties.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Properties.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Properties.java index 6c609d9..46abb29 100644 --- a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Properties.java +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/T4Properties.java @@ -126,7 +126,8 @@ public class T4Properties { private boolean useArrayBinding_; private boolean batchRecovery_; private final String propPrefix_ = "t4jdbc."; - + //clipVarchar flag + private short clipVarchar_ = 0; // Default catalog static final String DEFAULT_CATALOG = "TRAFODION"; @@ -166,7 +167,6 @@ public class T4Properties { private String _certificateFile; private boolean _keepAlive = false; private boolean _tokenAuth; - private static int DEFAULT_MAX_IDLE_TIMEOUT = 0; // Max idle timeout // default = infinite @@ -182,7 +182,6 @@ public class T4Properties { static String t4GlobalLogFile = null; static Logger t4GlobalLogger = null; static FileHandler t4GlobalLogFileHandler = null; - void initializeLogging() { if (t4GlobalLogger != null) { return; @@ -393,10 +392,10 @@ public class T4Properties { setBatchRecovery(getProperty("batchRecovery")); // setTransportBufferSize(getProperty("TransportBufferSize")); setLanguage(getProperty("language")); - setMaxIdleTime(getProperty("maxIdleTime")); setConnectionTimeout(getProperty("connectionTimeout")); - setFetchBufferSize(getProperty("fetchBufferSize")); + setClipVarchar(getProperty("clipVarchar")); + setFetchBufferSize(getProperty("fetchBufferSize")); // For LOB Support - SB 9/28/04 try { @@ -528,7 +527,8 @@ public class T4Properties { props.setProperty("keepAlive", String.valueOf(_keepAlive)); props.setProperty("tokenAuth", String.valueOf(_tokenAuth)); props.setProperty("tcpNoDelay", String.valueOf(_tcpNoDelay)); - + + props.setProperty("clipVarchar", String.valueOf(clipVarchar_)); props.setProperty("lobChunkSize", String.valueOf(lobChunkSize_)); props.setProperty("useLobHandle", String.valueOf(useLobHandle_)); @@ -1290,6 +1290,19 @@ public class T4Properties { setConnectionTimeout(tmpTimeout); } + void setClipVarchar(String clipVarchar) { + short tmp = 0; + if (clipVarchar != null) { + try { + tmp = Short.parseShort(clipVarchar); + } catch (NumberFormatException ex) { + sqlExceptionMessage_ = "Incorrect value for clipVarchar set: " + clipVarchar + ". " + + ex.getMessage(); + tmp = 0; + } + } + setClipVarchar(tmp); + } /* * Sets the connection timeout value for the Type 4 connection. Set this * value to 0 for infinite timeout. The default is set to -1. A negative @@ -1316,7 +1329,9 @@ public class T4Properties { connectionTimeout_ = connectionTimeout; } } - + void setClipVarchar(short clipVarchar) { + clipVarchar_=clipVarchar; + } /** * Sets the max idle time value for the Type 4 connection. The default is * set to 0 (no timeout). Negative values are treated as 0. @@ -1364,6 +1379,9 @@ public class T4Properties { int getConnectionTimeout() { return connectionTimeout_; } + short getClipVarchar() { + return clipVarchar_; + } /** * Returns the max idle time value associated with this Type 4 connection. http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Statement.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Statement.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Statement.java index cda76d6..3084648 100644 --- a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Statement.java +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Statement.java @@ -1276,9 +1276,9 @@ public class TrafT4Statement extends TrafT4Handle implements java.sql.Statement } else { if(resultSet_[result_set_offset].keepRawBuffer_ == true) resultSet_[result_set_offset].rawBuffer_ = values; - + //if setExecute2FetchOutputs is not called by fetch set flag to false , data has not been clipped resultSet_[result_set_offset].irs_.setExecute2FetchOutputs(resultSet_[result_set_offset], 1, true, - values); + values,false); } } else { resultSet_[result_set_offset] = null; http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/odbc/src/odbc/Common/Global.h ---------------------------------------------------------------------- diff --git a/core/conn/odbc/src/odbc/Common/Global.h b/core/conn/odbc/src/odbc/Common/Global.h index 0789b1c..fb29d50 100644 --- a/core/conn/odbc/src/odbc/Common/Global.h +++ b/core/conn/odbc/src/odbc/Common/Global.h @@ -898,6 +898,7 @@ typedef struct _SRVR_GLOBAL_Def bAutoCommitOn = FALSE; bAutoCommitSet = FALSE; javaConnIdleTimeout = JDBC_DATASOURCE_CONN_IDLE_TIMEOUT; + clipVarchar = 0; bSpjEnableProxy = FALSE; lastCQDAdaptiveSegment = -1; bWMS_AdaptiveSegment = false; @@ -982,6 +983,7 @@ typedef struct _SRVR_GLOBAL_Def long odbcConnIdleTimeout; //For ODBC Client timeout value + IDL_long clipVarchar ; // BOOL validTimerHandle; char ASProcessName[MAX_PROCESS_NAME_LEN]; PROCESS_ID_def nskASProcessInfo; http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/odbc/src/odbc/Krypton/generated_incs/odbcCommon.h ---------------------------------------------------------------------- diff --git a/core/conn/odbc/src/odbc/Krypton/generated_incs/odbcCommon.h b/core/conn/odbc/src/odbc/Krypton/generated_incs/odbcCommon.h index 50a9ebb..3fa7d35 100644 --- a/core/conn/odbc/src/odbc/Krypton/generated_incs/odbcCommon.h +++ b/core/conn/odbc/src/odbc/Krypton/generated_incs/odbcCommon.h @@ -273,6 +273,7 @@ struct CONNECTION_CONTEXT_t { char pad_to_offset_2572_[2]; IDL_unsigned_long queryTimeoutSec; IDL_unsigned_long idleTimeoutSec; + IDL_unsigned_long clipVarchar; IDL_unsigned_long loginTimeoutSec; IDL_short txnIsolationLevel; IDL_short rowSetSize; http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp ---------------------------------------------------------------------- diff --git a/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp b/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp index a6f6639..ff7e6d0 100644 --- a/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp +++ b/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp @@ -616,6 +616,9 @@ SQLCONNECT_IOMessage( else inContext.clientUserName = NULL; + inContext.clipVarchar = *(IDL_long *)(curptr+inputPosition); + inputPosition += sizeof(inContext.clipVarchar); + odbc_SQLSvc_InitializeDialogue_ame_( objtag_ , call_id_ http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/odbc/src/odbc/nsksrvr/SrvrConnect.cpp ---------------------------------------------------------------------- diff --git a/core/conn/odbc/src/odbc/nsksrvr/SrvrConnect.cpp b/core/conn/odbc/src/odbc/nsksrvr/SrvrConnect.cpp index c35659c..e37d8cc 100644 --- a/core/conn/odbc/src/odbc/nsksrvr/SrvrConnect.cpp +++ b/core/conn/odbc/src/odbc/nsksrvr/SrvrConnect.cpp @@ -3782,6 +3782,7 @@ odbc_SQLSvc_InitializeDialogue_ame_( if ((srvrGlobal->drvrVersion.componentId == JDBC_DRVR_COMPONENT) && ((long) (inContext->idleTimeoutSec) > JDBC_DATASOURCE_CONN_IDLE_TIMEOUT)) srvrGlobal->javaConnIdleTimeout = inContext->idleTimeoutSec; + srvrGlobal->clipVarchar = inContext->clipVarchar; // collect information for resource statistics char nodename[100]; short error; http://git-wip-us.apache.org/repos/asf/trafodion/blob/4ffb07a8/core/conn/odbc/src/odbc/nsksrvrcore/srvrothers.cpp ---------------------------------------------------------------------- diff --git a/core/conn/odbc/src/odbc/nsksrvrcore/srvrothers.cpp b/core/conn/odbc/src/odbc/nsksrvrcore/srvrothers.cpp index b4ca5c4..987edd4 100644 --- a/core/conn/odbc/src/odbc/nsksrvrcore/srvrothers.cpp +++ b/core/conn/odbc/src/odbc/nsksrvrcore/srvrothers.cpp @@ -3552,6 +3552,117 @@ odbc_SQLSvc_ExecDirect_sme_( } //LCOV_EXCL_STOP + +// Cut extra parts of varchar in outputDataValue to make data compaction +long long clipVarchar(SRVR_STMT_HDL *pSrvrStmt ) +{ + if(srvrGlobal->clipVarchar == 0) + { + return pSrvrStmt->outputDescVarBufferLen*pSrvrStmt->rowsAffected; + } + BYTE * desc = pSrvrStmt->outputDescBuffer; + BYTE *VarPtr = pSrvrStmt->outputDescVarBuffer; + long long remainLen = 0; + int numEntries = pSrvrStmt->columnCount; + int rowsAffected = pSrvrStmt->rowsAffected ; + int bufferRowLen = pSrvrStmt->outputDescVarBufferLen; + long long * colBuferLen = new long long [numEntries] ; + long startOffset = 0; + long varcharCount = 0; //counter of varchar column per row + BYTE * cpStart = VarPtr; + BYTE * cpEnd = cpStart; + BYTE * colEnd = cpStart; + BYTE * bufferOffset = cpStart; + int IndBuf,VarBuf; + int i = 0,j = 0; + for(j = 0 ; j < numEntries ; j++)//Calculate the data length of each column + { + if(pSrvrStmt->SqlDescInfo[j].DataType ==SQLTYPECODE_VARCHAR_WITH_LENGTH) + varcharCount ++; + if(j == numEntries -1 ){ + colBuferLen[j] = bufferRowLen - remainLen; + if(varcharCount == 0) + { + // if there is no varchar in the data do nothing and return + delete [] colBuferLen; + return pSrvrStmt->outputDescVarBufferLen*pSrvrStmt->rowsAffected; + } + } + else + { + IndBuf = *(int*)(desc+pSrvrStmt->SqlDescInfo[j+1].IndBuf) ; + VarBuf = *(int*)(desc+pSrvrStmt->SqlDescInfo[j+1].VarBuf); + if(IndBuf == -1) + { + colBuferLen[j] = VarBuf - startOffset; + startOffset = VarBuf; + } + else + { + colBuferLen[j] = IndBuf - startOffset; + startOffset = IndBuf; + } + remainLen += colBuferLen[j]; + } + } + for( i = 0; i < rowsAffected ; i++){//do clip + for (j = 0 ; j < numEntries ; j++) + { + switch (pSrvrStmt->SqlDescInfo[j].DataType) + { + case SQLTYPECODE_VARCHAR_WITH_LENGTH: + /* + |--------------column 1 ------|--------------column 2 ------| + column format nullable: |align_1|indPtr|align_2|varPtr|align_1|indPtr|align_2|varPtr| + + |--column 1--|--column 2--| + column format not null: |align|varPtr|align|varPtr| + indPtr is the pointer to store nullable info ,if column value is null indPtr = -1 + if varPtr is pointer to store column value + IndBuf is the offset of indPtr + VarBuf is the offset of varPtr + + */ + IndBuf = *(int*)(desc+pSrvrStmt->SqlDescInfo[j].IndBuf); + VarBuf = *(int*)(desc+pSrvrStmt->SqlDescInfo[j].VarBuf); + if(IndBuf != -1 && (*(short*)(VarPtr+IndBuf + i*bufferRowLen) == -1)) + { + cpEnd = cpStart+VarBuf-IndBuf; + colEnd = cpStart + colBuferLen[j]; + break; + } + if( pSrvrStmt->SqlDescInfo[j].Length > SHRT_MAX ) + { + cpEnd = VarPtr+VarBuf + i*bufferRowLen + 4 + *(int*)(VarPtr+VarBuf+i*bufferRowLen); + } + else + { + cpEnd = VarPtr+VarBuf + i*bufferRowLen + 2 + *(short*)(VarPtr+VarBuf+i*bufferRowLen); + + } + colEnd = cpStart + colBuferLen[j]; + break; + default: + cpEnd = cpStart + colBuferLen[j]; + colEnd = cpEnd; + break; + } + if(cpStart != bufferOffset) + { + memcpy(bufferOffset,cpStart,cpEnd-cpStart); + } + + bufferOffset += cpEnd-cpStart; + cpStart = colEnd; + } + } + + delete [] colBuferLen; + return bufferOffset-VarPtr; +} +//for setting in the indicator and Varpointers. + + //LCOV_EXCL_START /* * Synchronous method function for @@ -6117,7 +6228,7 @@ odbc_SQLSrvr_FetchPerf_sme_( int outputDataOffset = 0; *returnCode = SQL_SUCCESS; - + long long tmpLength; if (maxRowCnt < 0) { *returnCode = SQL_ERROR; @@ -6246,12 +6357,12 @@ odbc_SQLSrvr_FetchPerf_sme_( *outValuesFormat = ROWWISE_ROWSETS; rc = FETCH2bulk(pSrvrStmt); - if (pSrvrStmt->rowsAffected > 0) - { + tmpLength = clipVarchar(pSrvrStmt); + if (pSrvrStmt->rowsAffected > 0){ if(pSrvrStmt->outputDataValue._length == 0 && pSrvrStmt->outputDataValue._buffer == NULL) { outputDataValue->_buffer = pSrvrStmt->outputDescVarBuffer; - outputDataValue->_length = pSrvrStmt->outputDescVarBufferLen*pSrvrStmt->rowsAffected; + outputDataValue->_length = tmpLength; } else {
