You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafodion.apache.org by sa...@apache.org on 2017/09/04 06:58:37 UTC

[4/5] incubator-trafodion git commit: Main change:

Main change:

Added a method for JDBC driver to be able to close an open cursor abruptly by passing in a 0 length to the extract syntax. This will ensure internal opens are not left around if the application does not retrieve all the data with the stream API.
This abrupt close can be called when the result set is closed or the connection is closed by keeping track of all the open Blob objects. (in the driver)
Added a freeResources method and destructor to LobExtract and LobUpdate Tcbs.
Minor changes and fixes :
Refactored the ExLob::closeCursor
Removed the LOB_CLI_SELECT_CLOSE call from ::fetchCursor so it gets closed only when ExLob::closeCursor is called. Makes the code consistent and readable.
Took care of a few  memory allocations and deletions.
Refactored the LOB length calculation into on ecommon method  so it works correctly for both regular LOB dat aas well as external LOB files. Earlier the external lobs length was being returned incorrectly. Now it reports the length of the external HDFS file .
Fixed one place in generator where the CQD value was not being multiplied by the MB units correctly.


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/commit/f1864484
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/tree/f1864484
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/diff/f1864484

Branch: refs/heads/release2.2
Commit: f18644841f8d3c8aaa5c594c1018798d515821b0
Parents: 8a260f4
Author: Sandhya Sundaresan <sa...@apache.org>
Authored: Thu Aug 31 20:03:05 2017 +0000
Committer: Sandhya Sundaresan <sa...@apache.org>
Committed: Thu Aug 31 20:03:05 2017 +0000

----------------------------------------------------------------------
 core/sql/cli/Cli.cpp                  |   5 +-
 core/sql/clitest/blobtest.cpp         |  12 +-
 core/sql/executor/ExExeUtil.h         |   5 +-
 core/sql/executor/ExExeUtilLoad.cpp   | 229 +++++++++++++++++++----------
 core/sql/exp/ExpLOBaccess.cpp         | 146 +++++++++++++-----
 core/sql/exp/ExpLOBaccess.h           |   4 +-
 core/sql/exp/ExpLOBenums.h            |   4 +-
 core/sql/exp/ExpLOBinterface.cpp      |  57 ++++++-
 core/sql/exp/ExpLOBinterface.h        |  13 ++
 core/sql/generator/GenRelExeUtil.cpp  |   2 +-
 core/sql/regress/executor/EXPECTED130 |  78 +++++-----
 11 files changed, 394 insertions(+), 161 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/cli/Cli.cpp
----------------------------------------------------------------------
diff --git a/core/sql/cli/Cli.cpp b/core/sql/cli/Cli.cpp
index 1a6eaf5..a25a31b 100644
--- a/core/sql/cli/Cli.cpp
+++ b/core/sql/cli/Cli.cpp
@@ -10261,7 +10261,10 @@ Lng32 SQLCLI_LOBcliInterface
   NADELETEBASIC(query, currContext.exHeap());
 
   if (NOT (inCliInterface && (*inCliInterface)))
-    delete cliInterface;
+    {
+      delete cliInterface;
+      cliInterface = NULL;
+    }
 
   if (cliRC < 0)
     {

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/clitest/blobtest.cpp
----------------------------------------------------------------------
diff --git a/core/sql/clitest/blobtest.cpp b/core/sql/clitest/blobtest.cpp
index a9a457a..492bbd6 100644
--- a/core/sql/clitest/blobtest.cpp
+++ b/core/sql/clitest/blobtest.cpp
@@ -92,7 +92,7 @@ Int32 extractLobToBuffer(CliGlobals *cliglob, char * lobHandle, Int64 &lengthOfL
   while ((retcode != 100) && !(retcode<0))
     {    
       retcode = cliInterface.clearExecFetchClose(NULL,NULL,statusBuf, &statusBufLen);
-      if (!retcode)
+      if (retcode>= 0)
 	{
 	memcpy((char*)&(lobFinalBuf[i]),(char *)lobDataBuf,lobExtractLen);
 	i += lobExtractLen;
@@ -107,6 +107,9 @@ Int32 extractLobToBuffer(CliGlobals *cliglob, char * lobHandle, Int64 &lengthOfL
 
       fclose(lobFileId);
     }
+  str_sprintf(query,"extract lobtobuffer(lob '%s', LOCATION %Ld, SIZE 0) ", lobHandle, (Int64)lobDataBuf);
+ 
+  cliInterface.clearExecFetchClose(NULL,NULL,statusBuf, &statusBufLen);
   delete  lobFinalBuf;
   delete query;
   delete lobDataBuf;
@@ -142,13 +145,16 @@ Int32 extractLobToFileInChunks(CliGlobals *cliglob,  char * lobHandle, char *fil
   while ((retcode != 100) && !(retcode<0))
     {    
       retcode = cliInterface.clearExecFetchClose(NULL,NULL,statusBuf, &statusBufLen);
-      if (!retcode)
+      if (retcode>= 0)
 	{
 	  byteCount=fwrite(lobDataBuf,sizeof(char),*inputOutputAddr, lobFileId);
 	 cout << "Wrote " << byteCount << " bytes to file : " << filename << endl;
 	}
     }
-  
+  lobExtractLen = 0;
+  str_sprintf(query,"extract lobtobuffer(lob '%s', LOCATION %Ld, SIZE %Ld) ", lobHandle, (Int64)lobDataBuf, inputOutputAddr);
+  retcode = cliInterface.executeImmediatePrepare(query);
+  cliInterface.clearExecFetchClose(NULL,NULL,statusBuf, &statusBufLen);
 
   fclose(lobFileId);
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/executor/ExExeUtil.h
----------------------------------------------------------------------
diff --git a/core/sql/executor/ExExeUtil.h b/core/sql/executor/ExExeUtil.h
index 1ca9c97..07d3b22 100644
--- a/core/sql/executor/ExExeUtil.h
+++ b/core/sql/executor/ExExeUtil.h
@@ -2931,6 +2931,8 @@ public:
 			 ex_globals * glob = 0);
   
   virtual short work();
+  virtual ~ExExeUtilLobExtractTcb();
+  virtual void freeResources();
   
   ExExeUtilLobExtractTdb & lobTdb() const
   {
@@ -3036,7 +3038,8 @@ public:
 			 ex_globals * glob = 0);
   
   virtual short work();
-  
+  virtual ~ExExeUtilLobUpdateTcb();
+  virtual void freeResources();
   ExExeUtilLobUpdateTdb & lobTdb() const
   {
     return (ExExeUtilLobUpdateTdb &) tdb;

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/executor/ExExeUtilLoad.cpp
----------------------------------------------------------------------
diff --git a/core/sql/executor/ExExeUtilLoad.cpp b/core/sql/executor/ExExeUtilLoad.cpp
index 45a15e5..614adde 100644
--- a/core/sql/executor/ExExeUtilLoad.cpp
+++ b/core/sql/executor/ExExeUtilLoad.cpp
@@ -2749,6 +2749,45 @@ ExExeUtilLobExtractTcb::ExExeUtilLobExtractTcb
 
 }
 
+void ExExeUtilLobExtractTcb::freeResources()
+{
+  Lng32 cliRC = 0;
+  Lng32 retcode = 0;
+  void * lobGlobs = getLobGlobals()->lobAccessGlobals();
+  ContextCli *currContext =
+    getGlobals()->castToExExeStmtGlobals()->castToExMasterStmtGlobals()->
+    getStatement()->getContext();
+  //close any open cursors.
+   retcode = ExpLOBInterfaceSelectCursor
+	      (lobGlobs,
+	       lobName_, 
+	       lobLoc_,
+	       lobType_,
+	       lobTdb().getLobHdfsServer(),
+	       lobTdb().getLobHdfsPort(),
+
+	       lobHandleLen_, lobHandle_,
+               0, //cursor bytes
+               NULL, //cursor id
+	       requestTag_, 
+	       Lob_Buffer,
+	       0, // not check status
+	       1, // waited op
+
+	       0, lobDataSpecifiedExtractLen_, 
+	       lobDataLen_, lobData_, 
+	       3, // close
+               0); // open type not applicable
+
+   NADELETE(lobGlobals_,LOBglobals,currContext->exHeap());
+  lobGlobals_ = NULL;
+}
+
+ExExeUtilLobExtractTcb::~ExExeUtilLobExtractTcb()
+{
+  freeResources();
+}
+
 short ExExeUtilLobExtractTcb::work()
 {
   Lng32 cliRC = 0;
@@ -2996,7 +3035,49 @@ short ExExeUtilLobExtractTcb::work()
 		  }
 
 	      }
-	    
+            Int16 flags;
+	    Lng32  lobNum;
+	    Int64 uid, inDescSyskey, descPartnKey;
+	    short schNameLen;
+	    char schName[1024];
+	    ExpLOBoper::extractFromLOBhandle(&flags, &lobType_, &lobNum, &uid,  
+					     &inDescSyskey, &descPartnKey, 
+					     &schNameLen, (char *)schName,
+					     (char *)lobHandle_, (Lng32)lobHandleLen_);
+
+            //Retrieve the lobLocation for this lobNum which will be used 
+            //in the other steps_ which open and read lob data file.
+            short *lobNumList = new (getHeap()) short[1];
+	    short *lobTypList = new (getHeap()) short[1];
+	    char  **lobLocList = new (getHeap()) char*[1];
+             char  **lobColNameList = new (getHeap()) char*[1];
+	    lobLocList[0] = new (getHeap()) char[1024];
+	    lobColNameList[0] = new (getHeap()) char[256];
+
+	    Lng32 numLobs = lobNum;
+	    Lng32 cliRC = SQL_EXEC_LOBddlInterface
+	      (
+	       schName,
+	       schNameLen,
+	       uid,
+	       numLobs,
+	       LOB_CLI_SELECT_UNIQUE,
+	       lobNumList,
+	       lobTypList,
+	       lobLocList,lobColNameList,lobTdb().getLobHdfsServer(),
+               lobTdb().getLobHdfsPort(),0,FALSE);
+	    if (cliRC < 0)
+	      {
+		getDiagsArea()->mergeAfter(diags);
+
+		step_ = HANDLE_ERROR_;
+		break;
+	      }
+
+	    strcpy(lobLoc_, lobLocList[0]);
+            NADELETEBASIC(lobColNameList[0],getHeap());
+            NADELETEBASIC(lobNumList,getHeap());
+            NADELETEBASIC(lobTypList,getHeap());
 	    if (lobTdb().getToType() == ComTdbExeUtilLobExtract::TO_BUFFER_)
 	      step_ = EXTRACT_LOB_DATA_;
 	    else
@@ -3029,28 +3110,31 @@ short ExExeUtilLobExtractTcb::work()
 					     &schNameLen, (char *)schName,
 					     (char *)lobHandle_, (Lng32)lobHandleLen_);
 
-	   
-		//Retrieve the total length of this lob using the handle info and return to the caller
-		Int64 dummy = 0;
-		cliRC = SQL_EXEC_LOBcliInterface(lobHandle_, lobHandleLen_,NULL,NULL,NULL,NULL,LOB_CLI_SELECT_LOBLENGTH,LOB_CLI_ExecImmed, 0,&lobDataLen_, &dummy, &dummy,0,0,FALSE);
-		if (cliRC < 0)
-		   {
-		     getDiagsArea()->mergeAfter(diags);
-		     
-		     step_ = HANDLE_ERROR_;
-		     break;
-		   }
-		if  (lobTdb().retrieveLength())
-		  {
-		    if ((lobTdb().getBufAddr() != -1) && (lobTdb().getBufAddr() != 0))
-		      str_cpy_all((char *)lobTdb().getBufAddr(), (char *)&lobDataLen_,sizeof(Int64));
-		    str_sprintf(statusString_," LOB Length : %d", lobDataLen_);
-		    step_ = RETURN_STATUS_;
-		    break;	
-		  }
-		else
-		  step_ = EXTRACT_LOB_DATA_;
-		break;
+
+	    lobName_ = ExpLOBoper::ExpGetLOBname(uid, lobNum, lobNameBuf_, 1000);	   
+       
+            //Retrieve the total length of this lob using the handle info and return to the caller
+
+            retcode = ExpLOBInterfaceGetLobLength( lobGlobs,
+                                                   lobName_, 
+                                                   lobLoc_,
+                                                   lobType_,
+                                                   lobTdb().getLobHdfsServer(),
+                                                   lobTdb().getLobHdfsPort(),
+                                                   lobHandleLen_, lobHandle_, 
+                                                   lobDataLen_);
+                                                  
+            if  (lobTdb().retrieveLength())
+              {
+                if ((lobTdb().getBufAddr() != -1) && (lobTdb().getBufAddr() != 0))
+                  str_cpy_all((char *)lobTdb().getBufAddr(), (char *)&lobDataLen_,sizeof(Int64));
+                str_sprintf(statusString_," LOB Length : %d", lobDataLen_);
+                step_ = RETURN_STATUS_;
+                break;	
+              }
+            else
+              step_ = EXTRACT_LOB_DATA_;
+            break;
 	      
 	  }
 	case EXTRACT_LOB_DATA_ :
@@ -3069,38 +3153,16 @@ short ExExeUtilLobExtractTcb::work()
 
 	    lobDataSpecifiedExtractLen_ = lobTdb().totalBufSize_; 
 	    
-	    
+            if (lobDataSpecifiedExtractLen_ == 0)
+              {
+                // Passed in length is 0 indicates the caller is done with 
+                // this lobhandle and wants to close this cursor
+                step_ = CLOSE_CURSOR_;
+                break;
+              }
 	   
 	     
-	    short *lobNumList = new (getHeap()) short[1];
-	    short *lobTypList = new (getHeap()) short[1];
-	    char  **lobLocList = new (getHeap()) char*[1];
-             char  **lobColNameList = new (getHeap()) char*[1];
-	    lobLocList[0] = new (getHeap()) char[1024];
-	    lobColNameList[0] = new (getHeap()) char[256];
-
-	    Lng32 numLobs = lobNum;
-	    Lng32 cliRC = SQL_EXEC_LOBddlInterface
-	      (
-	       schName,
-	       schNameLen,
-	       uid,
-	       numLobs,
-	       LOB_CLI_SELECT_UNIQUE,
-	       lobNumList,
-	       lobTypList,
-	       lobLocList,lobColNameList,lobTdb().getLobHdfsServer(),
-               lobTdb().getLobHdfsPort(),0,FALSE);
-	    if (cliRC < 0)
-	      {
-		getDiagsArea()->mergeAfter(diags);
-
-		step_ = HANDLE_ERROR_;
-		break;
-	      }
-
-	    strcpy(lobLoc_, lobLocList[0]);
-
+	   
 	    // Read the lob contents  into target file
 	    
 
@@ -3204,6 +3266,15 @@ short ExExeUtilLobExtractTcb::work()
 	    if (lobTdb().getToType() == ComTdbExeUtilLobExtract::TO_BUFFER_)
 	      so = Lob_Buffer;
 	    lobDataSpecifiedExtractLen_ = *((Int64 *)(lobTdb().dataExtractSizeIOAddr()));
+
+            if (lobDataSpecifiedExtractLen_ == 0)
+              {
+                // Passed in length is 0 indicates the caller is done with 
+                // this lobhandle and wants to close this cursor
+                step_ = CLOSE_CURSOR_;
+                break;
+              }
+                
 	    retcode = ExpLOBInterfaceSelectCursor
 	      (lobGlobs,
 	       lobName_, 
@@ -3420,6 +3491,18 @@ ExExeUtilLobUpdateTcb::ExExeUtilLobUpdateTcb
      currContext->exHeap(),currContext,lobTdb().getLobHdfsServer(),
                lobTdb().getLobHdfsPort());
 }
+ExExeUtilLobUpdateTcb::~ExExeUtilLobUpdateTcb()
+{
+  freeResources();
+}
+
+void ExExeUtilLobUpdateTcb::freeResources()
+{
+ ContextCli *currContext =
+    getGlobals()->castToExExeStmtGlobals()->castToExMasterStmtGlobals()->
+    getStatement()->getContext();
+   NADELETE(lobGlobals_,LOBglobals,currContext->exHeap());
+}
 
 short ExExeUtilLobUpdateTcb::work()
 {
@@ -3538,7 +3621,7 @@ short ExExeUtilLobUpdateTcb::work()
             char  **lobColNameList = new (getHeap()) char*[1];
 	    lobLocList[0] = new (getHeap()) char[1024];
 	    lobColNameList[0] = new (getHeap()) char[256];
-
+          
 	    Lng32 numLobs = lobNum;
 	    Lng32 cliRC = SQL_EXEC_LOBddlInterface
 	      (
@@ -3560,6 +3643,10 @@ short ExExeUtilLobUpdateTcb::work()
 	      }
 
 	    strcpy(lobLoc_, lobLocList[0]);
+            NADELETEBASIC(lobLocList[0],getHeap());
+            NADELETEBASIC(lobColNameList[0],getHeap());
+            NADELETEBASIC(lobNumList,getHeap());
+            NADELETEBASIC(lobTypList,getHeap());
             char outLobHandle[LOB_HANDLE_LEN];
             Int32 outHandleLen;
             Int64 requestTag = 0;
@@ -3652,6 +3739,10 @@ short ExExeUtilLobUpdateTcb::work()
 	      }
 
 	    strcpy(lobLoc_, lobLocList[0]);
+            NADELETEBASIC(lobLocList[0],getHeap());
+            NADELETEBASIC(lobColNameList[0],getHeap());
+            NADELETEBASIC(lobNumList,getHeap());
+            NADELETEBASIC(lobTypList,getHeap());
             char outLobHandle[LOB_HANDLE_LEN];
             Int32 outHandleLen;
             Int64 requestTag = 0;
@@ -3744,33 +3835,15 @@ short ExExeUtilLobUpdateTcb::work()
 	      }
 
 	    strcpy(lobLoc_, lobLocList[0]);
+            NADELETEBASIC(lobLocList[0],getHeap());
+            NADELETEBASIC(lobColNameList[0],getHeap());
+            NADELETEBASIC(lobNumList,getHeap());
+            NADELETEBASIC(lobTypList,getHeap());
+           
             char outLobHandle[LOB_HANDLE_LEN];
             Int32 outHandleLen;
             Int64 requestTag = 0;
-            /*    retcode = ExpLOBInterfaceDelete(lobGlobs,
-                                             lobTdb().getLobHdfsServer(),
-                                            lobTdb().getLobHdfsPort(),
-                                            lobName_,
-                                            lobLoc_,
-                                            lobHandleLen_,
-                                            lobHandle_,
-                                            requestTag_,
-                                            getLobGlobals()->xnId(),
-                                            inDescSyskey,
-                                            0,1);
-            if (retcode < 0)
-	      {
-		Lng32 cliError = 0;
-                
-		Lng32 intParam1 = -retcode;
-		ComDiagsArea * diagsArea = getDiagsArea();
-		ExRaiseSqlError(getHeap(), &diagsArea, 
-				(ExeErrorCode)(8442), NULL, &intParam1, 
-				&cliError, NULL, (char*)"ExpLOBInterfaceUpdate",
-				getLobErrStr(intParam1));
-		step_ = HANDLE_ERROR_;
-		break;
-                }  */
+          
             retcode = ExpLOBInterfaceUpdate(lobGlobs,
                                             lobTdb().getLobHdfsServer(),
                                             lobTdb().getLobHdfsPort(),

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/exp/ExpLOBaccess.cpp
----------------------------------------------------------------------
diff --git a/core/sql/exp/ExpLOBaccess.cpp b/core/sql/exp/ExpLOBaccess.cpp
index 9478c64..af2846c 100644
--- a/core/sql/exp/ExpLOBaccess.cpp
+++ b/core/sql/exp/ExpLOBaccess.cpp
@@ -230,21 +230,6 @@ Ex_Lob_Error ExLob::fetchCursor(char *handleIn, Int32 handleLenIn, Int64 &outOff
     if (cliErr == 100 )
       {
         isEOD= TRUE;
-        cliErr = SQL_EXEC_LOBcliInterface(handleIn, handleLenIn, 
-				     NULL, NULL,
-                                     (char *)&dummyParam, (Lng32 *)&dummyParam,
-                                     LOB_CLI_SELECT_CLOSE, LOB_CLI_ExecImmed,
-                                     &dummyParam, &dummyParam,
-                                     &dummyParam, &dummyParam, 
-				     &cliInterface,
-                                          transId,lobTrace_);
-        if (cliErr <0 ) 
-          {
-            str_sprintf(logBuf, "LOB_CLI_SELECT_CLOSE Returned cli error  %d",cliErr);
-            lobDebugInfo(logBuf,0,__LINE__,lobTrace_);
-            err = LOB_DESC_READ_ERROR;
-            return err;
-          }
         
       }
     else
@@ -256,9 +241,17 @@ Ex_Lob_Error ExLob::fetchCursor(char *handleIn, Int32 handleLenIn, Int64 &outOff
             char temp[blackBoxLen+1];
             str_cpy_and_null(temp, blackBox, blackBoxLen, '\0', '0', TRUE);
             lobDataFile_ = temp;
+            outOffset = offset;
+            err=statSourceFile(temp,outSize);
+            if (err != LOB_OPER_OK)
+              return err;
           }
-        outOffset = offset;
-        outSize = size;
+        else
+          {
+            outOffset = offset;
+            outSize = size;
+          }
+        
       }
 
     str_sprintf(logBuf, " Returned after ::fetchCursor %Ld,%Ld",outOffset,outSize);
@@ -804,6 +797,62 @@ Ex_Lob_Error ExLob::readExternalSourceFile(char *srcfile, char *&fileData, Int32
   return LOB_OPER_OK;
 }
 
+Ex_Lob_Error ExLob::getLength(char *handleIn, Int32 handleInLen,Int64 &outLobLen,LobsSubOper so, Int64 transId)
+{
+  char logBuf[4096];
+  Int32 cliErr = 0;
+  Ex_Lob_Error err=LOB_OPER_OK; 
+  char *blackBox = new(getLobGlobalHeap()) char[MAX_LOB_FILE_NAME_LEN+6];
+  Int32 blackBoxLen = 0;
+  Int64 dummy = 0;
+  Int32 dummy2 = 0;
+  if (so != Lob_External_File)
+    {
+      
+      cliErr = SQL_EXEC_LOBcliInterface(handleIn, handleInLen,NULL,NULL,NULL,NULL,LOB_CLI_SELECT_LOBLENGTH,LOB_CLI_ExecImmed, 0,&outLobLen, 0, 0,0,transId,lobTrace_);
+    
+      if (cliErr < 0 ) {
+        str_sprintf(logBuf,"CLI SELECT_LOBLENGTH returned error %d",cliErr);
+        lobDebugInfo(logBuf, 0,__LINE__,lobTrace_);
+  
+        return LOB_DESC_READ_ERROR;
+      }
+    }
+    else
+      {
+        //Get the lob external filename from the descriptor file and get the length of the file
+        cliErr = SQL_EXEC_LOBcliInterface(handleIn, 
+                                          handleInLen, 
+                                          blackBox, &blackBoxLen,
+                                          NULL, 0,
+                                          LOB_CLI_SELECT_UNIQUE, LOB_CLI_ExecImmed,
+                                          &dummy, &dummy,
+                                          &dummy, &dummy, 
+                                          0,
+                                          transId,lobTrace_);
+        if (cliErr < 0 ) {
+          str_sprintf(logBuf,"CLI SELECT_LOBLENGTH returned error %d",cliErr);
+          lobDebugInfo(logBuf, 0,__LINE__,lobTrace_);
+  
+          return LOB_DESC_READ_ERROR;
+        }
+        if (blackBox && blackBoxLen >0 )
+          {
+            // we have received the external data file name from the 
+            // descriptor table
+            
+            char temp[blackBoxLen+1];
+            str_cpy_and_null(temp, blackBox, blackBoxLen, '\0', '0', TRUE);
+            
+            
+            err=statSourceFile(temp,outLobLen);
+            if (err != LOB_OPER_OK)
+              return err;
+          }
+       
+      }
+  return err;
+}
 Ex_Lob_Error ExLob::writeDesc(Int64 &sourceLen, char *source, LobsSubOper subOper, Int64 &descNumOut, Int64 &operLen, Int64 lobMaxSize,Int64 lobMaxChunkMemSize,Int64 lobGCLimit, char * handleIn, Int32 handleInLen, char *blackBox, Int32 *blackBoxLen, char *handleOut, Int32 &handleOutLen, Int64 xnId, void *lobGlobals)
 {
   Ex_Lob_Error err=LOB_OPER_OK; 
@@ -1566,7 +1615,7 @@ Ex_Lob_Error ExLob::readCursor(char *tgt, Int64 tgtSize, char *handleIn, Int32 h
     if (cursor.eod_) {
        // remove cursor from the map.
        // server has already closed the cursor. 
-       closeCursor(handleIn, handleInLen); 
+      closeCursor(handleIn, handleInLen,transId); 
        // indicate EOD to SQL
        operLen = 0; 
        return LOB_OPER_OK;
@@ -1585,17 +1634,48 @@ Ex_Lob_Error ExLob::readCursor(char *tgt, Int64 tgtSize, char *handleIn, Int32 h
 
 
 
-Ex_Lob_Error ExLob::closeCursor(char *handleIn, Int32 handleInLen)
+Ex_Lob_Error ExLob::closeCursor(char *handleIn, Int32 handleInLen, Int64 transId)
 {
   char logBuf[4096];
+  Int64 dummyParam = 0;
+  Int32 cliErr = 0;
+  Ex_Lob_Error err = LOB_OPER_OK;
   lobCursors_it it = lobCursors_.find(string(handleIn, handleInLen));
+  if (it == lobCursors_.end())
+    {
+      // cursor already closed
+      return LOB_OPER_OK;                         
+    }
+
+  void *cliInterface = it->second.cliInterface_;
+  if (cliInterface)
+    {
+      cliErr = SQL_EXEC_LOBcliInterface(handleIn, handleInLen, 
+                                        NULL, NULL,
+                                        (char *)&dummyParam, (Lng32 *)&dummyParam,
+                                        LOB_CLI_SELECT_CLOSE, LOB_CLI_ExecImmed,
+                                        &dummyParam, &dummyParam,
+                                        &dummyParam, &dummyParam, 
+                                        &cliInterface,
+                                        transId,lobTrace_);
+      if (cliErr <0 ) 
+        {
+          str_sprintf(logBuf, "LOB_CLI_SELECT_CLOSE Returned cli error  %d",cliErr);
+          lobDebugInfo(logBuf,0,__LINE__,lobTrace_);
+          err = LOB_DESC_READ_ERROR;
+          return err;
+        }
+    }
   if (it != lobCursors_.end())
     {
       str_sprintf(logBuf,"closing cursor for handle");
       lobDebugInfo(logBuf,0,__LINE__,lobTrace_);    
       lobCursors_.erase(it);
     }
-    return LOB_OPER_OK;
+  
+ 
+      
+  return LOB_OPER_OK;
 }
 
 Ex_Lob_Error ExLob::allocateDesc(ULng32 size, Int64 &descNum, Int64 &dataOffset, Int64 lobMaxSize, Int64 lobMaxChunkMemLen, char *handleIn, Int32 handleInLen, Int64 lobGCLimit, void *lobGlobals)
@@ -1949,7 +2029,7 @@ Ex_Lob_Error ExLob::readCursorData(char *tgt, Int64 tgtSize, cursor_t &cursor, I
    char logBuf[4096];
    lobDebugInfo("In ExLob::readCursorData",0,__LINE__,lobTrace_);
 
-   while ( (operLen <= tgtSize) && !cursor.eod_ )
+   while ( (operLen < tgtSize) && !cursor.eod_ )
    {
     
       if (cursor.bytesRead_ == cursor.descSize_) // time to read next chunck
@@ -1970,14 +2050,7 @@ Ex_Lob_Error ExLob::readCursorData(char *tgt, Int64 tgtSize, cursor_t &cursor, I
               continue;
          }
       }
-      if (operLen == tgtSize)
-        {
-          //The cursor still has data available but wait until redrive since
-          //we have fetched all the data for this extract operation
-          hdfsCloseFile(fs_, fdData_);
-          fdData_ = NULL;
-          return LOB_OPER_OK;
-        }
+      
       bytesAvailable = cursor.descSize_ - cursor.bytesRead_;
       bytesToCopy = min(bytesAvailable, tgtSize - operLen);
       offset = cursor.descOffset_ + cursor.bytesRead_;
@@ -2028,6 +2101,7 @@ Ex_Lob_Error ExLob::readCursorData(char *tgt, Int64 tgtSize, cursor_t &cursor, I
       operLen += bytesRead;
       tgt += bytesRead;
    }
+  
    hdfsCloseFile(fs_, fdData_);
    fdData_ = NULL;
    return LOB_OPER_OK;
@@ -2117,7 +2191,7 @@ Ex_Lob_Error ExLob::readDataToMem(char *memAddr,
 	 	 
       if (err==LOB_OPER_OK)
 	closeCursor(handleIn, 
-		    handleLenIn);
+		    handleLenIn,transId);
       else
 	return err;
     }
@@ -2232,7 +2306,7 @@ Ex_Lob_Error ExLob::readDataToLocalFile(char *fileName,  Int64 offset, Int64 siz
 	    tgtOffset += chunkSize;     
 	  }
 	closeCursor(handleIn, 
-		    handleInLen);
+		    handleInLen,transId);
       }
     close(fdDestFile);
     return LOB_OPER_OK;
@@ -2359,7 +2433,7 @@ Ex_Lob_Error ExLob::readDataToHdfsFile(char *tgtFileName,  Int64 offset, Int64 s
 
 	}
       closeCursor(handleIn, 
-		  handleInLen);	    
+		  handleInLen,transId);	    
     }
   hdfsCloseFile(fs_, fdTgtFile);
   fdTgtFile=NULL;
@@ -2644,7 +2718,11 @@ Ex_Lob_Error ExLobsOper (
       if (blackBox)
         (lobGlobals->getHeap())->deallocateMemory((char*) blackBox);
       break;
-
+    case Lob_GetLength:
+      {
+        err = lobPtr->getLength(handleIn, handleInLen,retOperLen,subOperation,transId);  
+      }
+      break;
     case Lob_ReadDesc: // read desc only. Needed for pass thru.
       err = lobPtr->getDesc(desc,handleIn,handleInLen,(char *)blackBox, &blackBoxLen,handleOut,handleOutLen,transId); 
       retOperLen = 0;
@@ -2711,7 +2789,7 @@ Ex_Lob_Error ExLobsOper (
       break;
 
     case Lob_CloseCursor:
-      err = lobPtr->closeCursor(handleIn, handleInLen);
+      err = lobPtr->closeCursor(handleIn, handleInLen,transId);
       break;
 
     case Lob_CloseDataCursorSimple:

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/exp/ExpLOBaccess.h
----------------------------------------------------------------------
diff --git a/core/sql/exp/ExpLOBaccess.h b/core/sql/exp/ExpLOBaccess.h
index acb63fc..3a5a8ca 100644
--- a/core/sql/exp/ExpLOBaccess.h
+++ b/core/sql/exp/ExpLOBaccess.h
@@ -436,7 +436,7 @@ class ExLob : public NABasicObject
   Ex_Lob_Error purgeLob();
   Ex_Lob_Error closeFile();
   LobInputOutputFileType fileType(char *ioFileName);
-  Ex_Lob_Error closeCursor(char *handleIn, Int32 handleInLen);
+  Ex_Lob_Error closeCursor(char *handleIn, Int32 handleInLen,Int64 transId);
   Ex_Lob_Error closeDataCursorSimple(const char *fileName, ExLobGlobals *lobGlobals);
   
   Ex_Lob_Error doSanityChecks(char *dir, LobsStorage storage,
@@ -496,7 +496,7 @@ class ExLob : public NABasicObject
 
   ExLobStats *getStats() { return &stats_; }
   NAHeap *getLobGlobalHeap() { return lobGlobalHeap_;}
-
+  Ex_Lob_Error getLength(char *handleIn, Int32 handleInLen,Int64 &outLobLen,LobsSubOper so, Int64 transId);
   //    ExLobRequest *getRequest() { return &request_; }
   
   //The next 2 functions are not active at this point. They serve as an example

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/exp/ExpLOBenums.h
----------------------------------------------------------------------
diff --git a/core/sql/exp/ExpLOBenums.h b/core/sql/exp/ExpLOBenums.h
index 37af1d0..d04b080 100644
--- a/core/sql/exp/ExpLOBenums.h
+++ b/core/sql/exp/ExpLOBenums.h
@@ -259,7 +259,9 @@ typedef enum {
    Lob_Cleanup, // destroy everything under globals
    Lob_PerformGC,
    Lob_RestoreLobDataFile,
-   Lob_PurgeBackupLobDataFile
+   Lob_PurgeBackupLobDataFile,
+   Lob_GetLength
+   
 } LobsOper;
 
 typedef enum {

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/exp/ExpLOBinterface.cpp
----------------------------------------------------------------------
diff --git a/core/sql/exp/ExpLOBinterface.cpp b/core/sql/exp/ExpLOBinterface.cpp
index 5016a01..9b58344 100644
--- a/core/sql/exp/ExpLOBinterface.cpp
+++ b/core/sql/exp/ExpLOBinterface.cpp
@@ -982,8 +982,9 @@ Lng32 ExpLOBInterfaceSelectCursor(void * exLobGlob,
                    waitedOp,
 		   exLobGlob,
 		   0,
-		   hdfsDetailError, 0,0,0,0,0,0,0,
+		   hdfsDetailError,0,0,0,0,0,0,0,
                    openType
+                   
 		   );
 
   if (err != LOB_OPER_OK)
@@ -994,6 +995,60 @@ Lng32 ExpLOBInterfaceSelectCursor(void * exLobGlob,
   return LOB_ACCESS_SUCCESS;
 }
 
+
+Lng32 ExpLOBInterfaceGetLobLength(void * exLobGlob, 
+				  char * lobName, 
+				  char * lobLoc,
+				  Lng32 lobType,
+				  char * lobHdfsServer,
+				  Lng32 lobHdfsPort,
+				  Int32 handleLen, 
+				  char * lobHandle,
+			          Int64 &outLobLen
+                                 
+				  )
+{
+  Ex_Lob_Error err;
+  
+  Int64 dummyParam = 0;
+  Int32 dummyParam2 = 0;
+  Ex_Lob_Error status;
+  Int64 cliError=0;
+  
+  LobsOper lo;
+  LobsSubOper so;
+  LobsStorage ls = (LobsStorage)lobType;
+  if (ls == Lob_External_HDFS_File)
+    so = Lob_External_File;
+  else 
+    so = Lob_Buffer;
+  err = ExLobsOper(lobName, 
+		   lobHandle, handleLen, 
+		   lobHdfsServer, lobHdfsPort,
+                   NULL, dummyParam2, 
+		   dummyParam, dummyParam, 
+		   outLobLen,
+                   dummyParam, dummyParam,
+		   status, cliError, 
+		   lobLoc, ls, //Lob_HDFS_File,
+		   NULL, 0, 
+		   dummyParam,NULL,
+		   Lob_GetLength,
+		   so,
+                   TRUE,
+		   exLobGlob,
+		   0,
+		   0, 0,0,0,0,0,0,0,
+                   0
+		   );
+
+  if (err != LOB_OPER_OK)
+    {
+      return -err;
+    }
+  
+  return LOB_ACCESS_SUCCESS;
+}
 Lng32 ExpLOBinterfaceStats(
 			    void * exLobGlob, 
 			    ExLobStats * lobStats,

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/exp/ExpLOBinterface.h
----------------------------------------------------------------------
diff --git a/core/sql/exp/ExpLOBinterface.h b/core/sql/exp/ExpLOBinterface.h
index a8245c8..88b6fe9 100644
--- a/core/sql/exp/ExpLOBinterface.h
+++ b/core/sql/exp/ExpLOBinterface.h
@@ -331,6 +331,19 @@ Lng32 ExpLOBinterfaceEmptyDirectory(void * lobGlob,
                             short  replication =0,
                             int    blocksize=0);
 
+Lng32 ExpLOBInterfaceGetLobLength(void * exLobGlob, 
+				  char * lobName, 
+				  char * lobLoc,
+				  Lng32 lobType,
+				  char * lobHdfsServer,
+				  Lng32 lobHdfsPort,
+				  Int32 handleLen, 
+				  char * lobHandle,
+			          Int64 &outLobLen 
+                                  
+				  );
+
+
 /*
 class HdfsFileInfo
 {

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/f1864484/core/sql/generator/GenRelExeUtil.cpp
----------------------------------------------------------------------
diff --git a/core/sql/generator/GenRelExeUtil.cpp b/core/sql/generator/GenRelExeUtil.cpp
index d514cb5..df627cb 100644
--- a/core/sql/generator/GenRelExeUtil.cpp
+++ b/core/sql/generator/GenRelExeUtil.cpp
@@ -4298,7 +4298,7 @@ if (handleInStringFormat_)
     {
       exe_util_tdb->setRetrieveLength(TRUE);
     }
-  exe_util_tdb->setTotalBufSize(CmpCommon::getDefaultNumeric(LOB_MAX_CHUNK_MEM_SIZE));
+  exe_util_tdb->setTotalBufSize(CmpCommon::getDefaultNumeric(LOB_MAX_CHUNK_MEM_SIZE)*1024*1024);
 
   generator->setCriDesc(givenDesc, Generator::DOWN);
   generator->setCriDesc(returnedDesc, Generator::UP);