Fix for missing code in update LOB path causing core when updating a NULL value. Fix for SynthType.cpp where a change was lost in merge. Fix for HDFSWriteImmediate to handle close correctly and retry when the offset written to doesn't match initial calculation.
diff --git a/core/sql/exp/ExpLOB.cpp b/core/sql/exp/ExpLOB.cpp
index 84a8512..cd540fd 100644
--- a/core/sql/exp/ExpLOB.cpp
+++ b/core/sql/exp/ExpLOB.cpp
@@ -6,7 +6,9 @@
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
+// "License
+
+"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
@@ -1418,6 +1420,12 @@
char *inputAddr = NULL;
Int64 lobLen = 0;
char *lobData = NULL;
+ Int64 sourceFileSize = 0; // If the input is from a file get total file size
+ Int64 sourceFileReadOffset = 0;
+ Int64 chunkMemSize = 0;
+ char *retBuf = 0;
+ Int64 retReadLen = 0;
+ Int32 cliError = 0;
Lng32 sLobType;
Int64 sUid;
Lng32 sLobNum;
@@ -1426,7 +1434,31 @@
Int16 sFlags;
short sSchNameLen = 0;
char sSchName[500];
+ char tgtLobNameBuf[LOB_NAME_LEN];
+ char *tgtLobName = NULL;
lobLen = getOperand(1)->getLength();
+
+ char llid[LOB_LOCK_ID_SIZE];
+ if (lobLocking())
+ {
+ ExpLOBoper::genLobLockId(objectUID_,lobNum(),llid);;
+ NABoolean found = FALSE;
+ retcode = SQL_EXEC_CheckLobLock(llid, &found);
+ if (! retcode && !found)
+ {
+ retcode = SQL_EXEC_SetLobLock(llid);
+ }
+ else if (found)
+ {
+ Int32 lobError = LOB_DATA_FILE_LOCK_ERROR;
+ ExRaiseSqlError(h, diagsArea,
+ (ExeErrorCode)(8558), NULL,(Int32 *)&lobError,
+ NULL, NULL, (char*)"ExpLOBInterfaceInsert",
+ getLobErrStr(LOB_DATA_FILE_LOCK_ERROR),NULL);
+ return ex_expr::EXPR_ERROR;
+ }
+ }
+
if(fromString())
{
//If source is a varchar, find the actual length
@@ -1455,11 +1487,69 @@
if (getOperand(2)->getNullFlag() &&
nullValue_)
{
-
-
- char * handle = op_data[0];
+ if(fromFile())
+ {
+ lobData = new (h) char[lobLen];
+ str_cpy_and_null(lobData,op_data[1],lobLen,'\0',' ',TRUE);
+ retcode = ExpLOBInterfaceGetFileSize(getExeGlobals()->getExLobGlobal(),
+ lobData,//filename
+ getLobHdfsServer(),
+ getLobHdfsPort(),
+ sourceFileSize);
+ if (retcode < 0)
+ {
+ if (lobLocking())
+ retcode = SQL_EXEC_ReleaseLobLock(llid);
+ Lng32 intParam1 = -retcode;
+ ExRaiseSqlError(h, diagsArea,
+ (ExeErrorCode)(8442), NULL, &intParam1,
+ &cliError, NULL, (char*)"ExpLOBInterfaceGetFileSize",
+ getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
+ return ex_expr::EXPR_ERROR;
+ }
+ inputSize = sourceFileSize;
+ }
+ chunkMemSize = MINOF(getLobMaxChunkMemSize(), inputSize);
+ lobHandle = op_data[0];
handleLen = getOperand(0)->getLength();
- ex_expr::exp_return_type err = insertData(handleLen, handle, inputAddr, inputSize, lobHdfsOffset, h, diagsArea);;
+
+ if (handleLen == 0)
+ {
+ ExRaiseSqlError(h, diagsArea,
+ (ExeErrorCode)(8443), NULL, NULL);
+
+ return ex_expr::EXPR_ERROR;
+ }
+
+ if (fromFile())
+ {
+ //read a chunk of the file input data
+ retcode= ExpLOBInterfaceReadSourceFile(getExeGlobals()->getExLobGlobal(),
+ lobData,
+ getLobHdfsServer(),
+ getLobHdfsPort(),
+ sourceFileReadOffset,
+ chunkMemSize,
+ retBuf,
+ retReadLen);
+ if (retcode < 0)
+ {
+ if (lobLocking())
+ retcode = SQL_EXEC_ReleaseLobLock(llid);
+ Lng32 intParam1 = -retcode;
+ ExRaiseSqlError(h, diagsArea,
+ (ExeErrorCode)(8442), NULL, &intParam1,
+ &cliError, NULL, (char*)"ExpLOBInterfaceReadSourceFile",
+ getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
+ return ex_expr::EXPR_ERROR;
+ }
+
+
+ inputAddr = retBuf;
+
+ }
+ ex_expr::exp_return_type err = insertData(handleLen, lobHandle, inputAddr, inputSize, lobHdfsOffset, h, diagsArea);;
+
if (err == ex_expr::EXPR_ERROR)
return err;
err = insertDesc(op_data, inputAddr,inputSize, lobHdfsOffset, result,h, diagsArea);
@@ -1467,202 +1557,286 @@
return err;
return err;
+ inputSize -= chunkMemSize;
+ if (fromFile())
+ sourceFileReadOffset +=chunkMemSize;
+ inputAddr += chunkMemSize;
+
+ if(inputSize > 0)
+ {
+ char * lobHandle = op_data[0];
+ handleLen = getOperand(0)->getLength();
+ extractFromLOBhandle(&sFlags, &sLobType, &sLobNum, &sUid,
+ &sDescSyskey, &sDescTS,
+ &sSchNameLen, sSchName,
+ lobHandle);
+
+ tgtLobName = ExpGetLOBname(sUid, sLobNum, tgtLobNameBuf, LOB_NAME_LEN);
+ }
+ while(inputSize > 0) // chunk rest of the input into lobMaxChunkMemSize chunks and append.
+ {
+ chunkMemSize = MINOF(getLobMaxChunkMemSize(), inputSize);
+ if(!fromEmpty())
+ {
+
+ if (fromFile())
+ {
+ //read a chunk of the file input data
+ retcode= ExpLOBInterfaceReadSourceFile(getExeGlobals()->getExLobGlobal(),
+ lobData,
+ getLobHdfsServer(),
+ getLobHdfsPort(),
+ sourceFileReadOffset,
+ chunkMemSize,
+ retBuf,
+ retReadLen);
+ if (retcode < 0)
+ {
+ if (lobLocking())
+ retcode = SQL_EXEC_ReleaseLobLock(llid);
+ Lng32 intParam1 = -retcode;
+ ExRaiseSqlError(h, diagsArea,
+ (ExeErrorCode)(8442), NULL, &intParam1,
+ &cliError, NULL, (char*)"ExpLOBInterfaceReadSourceFile",
+ getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
+ return ex_expr::EXPR_ERROR;
+ }
+ inputAddr = retBuf;
+
+ }
+ char * handle = op_data[0];
+ handleLen = getOperand(0)->getLength();
+ LobsSubOper so = Lob_None;
+ if (fromFile())
+ so = Lob_File;
+ else if (fromString()) {
+ if (getOperand(1)->getVCIndicatorLength() > 0)
+ lobLen = getOperand(1)->getLength(op_data[1]-getOperand(1)->getVCIndicatorLength());
+ so = Lob_Memory;
+ }
+ else if (fromLob())
+ so = Lob_Lob;
+ else if (fromBuffer())
+ so= Lob_Buffer;
+ else if (fromExternal())
+ so = Lob_External_File;
+
+ retcode = ExpLOBInterfaceUpdateAppend
+ (getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
+ getLobHdfsServer(),
+ getLobHdfsPort(),
+ tgtLobName,
+ lobStorageLocation(),
+ handleLen, handle,
+ &outHandleLen_, outLobHandle_,
+ lobHdfsOffset,
+ -1,
+ 0,
+ 0,
+ so,
+ sDescSyskey,
+ chunkMemSize,
+ inputAddr,
+ NULL, 0, NULL,
+ -1, 0,
+ getLobMaxSize(), getLobMaxChunkMemSize(),getLobGCLimit());
+ if (retcode < 0)
+ {
+ if (lobLocking())
+ retcode = SQL_EXEC_ReleaseLobLock(llid);
+ Lng32 intParam1 = -retcode;
+ ExRaiseSqlError(h, diagsArea,
+ (ExeErrorCode)(8442), NULL, &intParam1,
+ &cliError, NULL, (char*)"ExpLOBInterfaceReadSourceFile",
+ getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
+ return ex_expr::EXPR_ERROR;
+ }
+ inputSize -= chunkMemSize;
+ if (fromFile())
+ sourceFileReadOffset +=chunkMemSize;
+ inputAddr += chunkMemSize;
+ }
+ }
+
+
}
else
{
lobHandle = op_data[2];
handleLen = getOperand(2)->getLength(op_data[-MAX_OPERANDS+2]);
- }
+
- extractFromLOBhandle(&sFlags, &sLobType, &sLobNum, &sUid,
- &sDescSyskey, &sDescTS,
- &sSchNameLen, sSchName,
- lobHandle); //op_data[2]);
- if (sDescSyskey == -1) //updating empty lob
- {
-
- char llid[LOB_LOCK_ID_SIZE];
- if (lobLocking())
+ extractFromLOBhandle(&sFlags, &sLobType, &sLobNum, &sUid,
+ &sDescSyskey, &sDescTS,
+ &sSchNameLen, sSchName,
+ lobHandle); //op_data[2]);
+ if (sDescSyskey == -1) //updating empty lob
{
- ExpLOBoper::genLobLockId(objectUID_,lobNum(),llid);;
- NABoolean found = FALSE;
- retcode = SQL_EXEC_CheckLobLock(llid, &found);
- if (! retcode && !found)
- {
- retcode = SQL_EXEC_SetLobLock(llid);
- }
- else if (found)
+
+ char llid[LOB_LOCK_ID_SIZE];
+ if (lobLocking())
{
- ExRaiseSqlError(h, diagsArea,
- (ExeErrorCode)(EXE_LOB_CONCURRENT_ACCESS_ERROR));
- return ex_expr::EXPR_ERROR;
+ ExpLOBoper::genLobLockId(objectUID_,lobNum(),llid);;
+ NABoolean found = FALSE;
+ retcode = SQL_EXEC_CheckLobLock(llid, &found);
+ if (! retcode && !found)
+ {
+ retcode = SQL_EXEC_SetLobLock(llid);
+ }
+ else if (found)
+ {
+ ExRaiseSqlError(h, diagsArea,
+ (ExeErrorCode)(EXE_LOB_CONCURRENT_ACCESS_ERROR));
+ return ex_expr::EXPR_ERROR;
+ }
}
- }
- char * handle = op_data[0];
- handleLen = getOperand(0)->getLength();
- ex_expr::exp_return_type err = insertData(handleLen, handle, inputAddr, inputSize, lobHdfsOffset, h, diagsArea);
- if (err == ex_expr::EXPR_ERROR)
- return err;
- err = insertDesc(op_data,inputAddr,inputSize, lobHdfsOffset, result, h, diagsArea);
- if (err == ex_expr::EXPR_ERROR)
- return err;
- if (lobLocking())
- retcode = SQL_EXEC_ReleaseLobLock(llid);
- return err;
- }
+ char * handle = op_data[0];
+ handleLen = getOperand(0)->getLength();
+ ex_expr::exp_return_type err = insertData(handleLen, handle, inputAddr, inputSize, lobHdfsOffset, h, diagsArea);
+ if (err == ex_expr::EXPR_ERROR)
+ return err;
+ err = insertDesc(op_data,inputAddr,inputSize, lobHdfsOffset, result, h, diagsArea);
+ if (err == ex_expr::EXPR_ERROR)
+ return err;
+ if (lobLocking())
+ retcode = SQL_EXEC_ReleaseLobLock(llid);
+ return err;
+ }
- // get the lob name where data need to be updated
- char tgtLobNameBuf[LOB_NAME_LEN];
- char * tgtLobName = ExpGetLOBname(sUid, sLobNum, tgtLobNameBuf, LOB_NAME_LEN);
+ // get the lob name where data need to be updated
+ char tgtLobNameBuf[LOB_NAME_LEN];
+ char * tgtLobName = ExpGetLOBname(sUid, sLobNum, tgtLobNameBuf, LOB_NAME_LEN);
- if (tgtLobName == NULL)
- return ex_expr::EXPR_ERROR;
+ if (tgtLobName == NULL)
+ return ex_expr::EXPR_ERROR;
- char fromLobNameBuf[LOB_NAME_LEN];
- char * fromLobName = NULL;
- Int64 fromDescKey = 0;
- Int64 fromDescTS = 0;
- short fromSchNameLen = 0;
- char fromSchName[ComAnsiNamePart::MAX_IDENTIFIER_EXT_LEN+1];
- // call function with the lobname and source value
- // to update it in the LOB.
- // Get back offset and len of the LOB.
- // Int64 offset = 0;
- lobLen = getOperand(1)->getLength();
+ char fromLobNameBuf[LOB_NAME_LEN];
+ char * fromLobName = NULL;
+ Int64 fromDescKey = 0;
+ Int64 fromDescTS = 0;
+ short fromSchNameLen = 0;
+ char fromSchName[ComAnsiNamePart::MAX_IDENTIFIER_EXT_LEN+1];
+ // call function with the lobname and source value
+ // to update it in the LOB.
+ // Get back offset and len of the LOB.
+ // Int64 offset = 0;
+ lobLen = getOperand(1)->getLength();
- LobsSubOper so = Lob_None;
- if (fromFile())
- so = Lob_File;
- else if (fromString()) {
- if (getOperand(1)->getVCIndicatorLength() > 0)
+ LobsSubOper so = Lob_None;
+ if (fromFile())
+ so = Lob_File;
+ else if (fromString()) {
+ if (getOperand(1)->getVCIndicatorLength() > 0)
lobLen = getOperand(1)->getLength(op_data[1]-getOperand(1)->getVCIndicatorLength());
- so = Lob_Memory;
- }
- else if (fromLob())
- so = Lob_Lob;
- else if (fromBuffer())
- so= Lob_Buffer;
- else if (fromExternal())
- so = Lob_External_File;
+ so = Lob_Memory;
+ }
+ else if (fromLob())
+ so = Lob_Lob;
+ else if (fromBuffer())
+ so= Lob_Buffer;
+ else if (fromExternal())
+ so = Lob_External_File;
- Int64 lobMaxSize = 0;
- if (getLobSize() > 0)
- {
- lobMaxSize = MINOF(getLobSize(), getLobMaxSize());
- }
- else
- lobMaxSize = getLobMaxSize();
- Lng32 waitedOp = 0;
- waitedOp = 1;
+ Int64 lobMaxSize = 0;
+ if (getLobSize() > 0)
+ {
+ lobMaxSize = MINOF(getLobSize(), getLobMaxSize());
+ }
+ else
+ lobMaxSize = getLobMaxSize();
+ Lng32 waitedOp = 0;
+ waitedOp = 1;
- Lng32 cliError = 0;
+ Lng32 cliError = 0;
- char * data = op_data[1];
- if (fromBuffer())
- {
- memcpy(&lobLen, op_data[3],sizeof(Int64)); // user specified buffer length
- Int64 userBufAddr = 0;
- memcpy(&userBufAddr,op_data[1],sizeof(Int64));
- data = (char *)userBufAddr;
- }
+ char * data = op_data[1];
+ if (fromBuffer())
+ {
+ memcpy(&lobLen, op_data[3],sizeof(Int64)); // user specified buffer length
+ Int64 userBufAddr = 0;
+ memcpy(&userBufAddr,op_data[1],sizeof(Int64));
+ data = (char *)userBufAddr;
+ }
- if(fromEmpty())
- {
- lobLen = 0;
- so = Lob_Memory;
- }
+ if(fromEmpty())
+ {
+ lobLen = 0;
+ so = Lob_Memory;
+ }
- char llid[LOB_LOCK_ID_SIZE];
- if (lobLocking())
- {
- ExpLOBoper::genLobLockId(objectUID_,lobNum(),llid);;
- NABoolean found = FALSE;
- retcode = SQL_EXEC_CheckLobLock(llid, &found);
- if (! retcode && !found)
- {
- retcode = SQL_EXEC_SetLobLock(llid);
- }
- else if (found)
- {
- Int32 lobError = LOB_DATA_FILE_LOCK_ERROR;
- ExRaiseSqlError(h, diagsArea,
- (ExeErrorCode)(8558), NULL,(Int32 *)&lobError,
- NULL, NULL, (char*)"ExpLOBInterfaceInsert",
- getLobErrStr(LOB_DATA_FILE_LOCK_ERROR),NULL);
- return ex_expr::EXPR_ERROR;
- }
- }
- if (isAppend() && !fromEmpty())
- {
- rc = ExpLOBInterfaceUpdateAppend
- (getExeGlobals()->getExLobGlobal(),
- (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
- getLobHdfsServer(),
- getLobHdfsPort(),
- tgtLobName,
- lobStorageLocation(),
- handleLen, lobHandle,
- &outHandleLen_, outLobHandle_,
- requestTag_,
- -1,
+
+ if (isAppend() && !fromEmpty())
+ {
+ rc = ExpLOBInterfaceUpdateAppend
+ (getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
+ getLobHdfsServer(),
+ getLobHdfsPort(),
+ tgtLobName,
+ lobStorageLocation(),
+ handleLen, lobHandle,
+ &outHandleLen_, outLobHandle_,
+ requestTag_,
+ -1,
- (lobOperStatus == CHECK_STATUS_ ? 1 : 0),
- waitedOp,
- so,
- sDescSyskey,
- lobLen,
- data,
- fromLobName, fromSchNameLen, fromSchName,
- fromDescKey, fromDescTS,
- lobMaxSize, getLobMaxChunkMemSize(),getLobGCLimit());
- }
- else
- {
- rc = ExpLOBInterfaceUpdate
- (getExeGlobals()->getExLobGlobal(),
- (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
- getLobHdfsServer(),
- getLobHdfsPort(),
- tgtLobName,
- lobStorageLocation(),
- handleLen, lobHandle,
- &outHandleLen_, outLobHandle_,
- requestTag_,
- -1,
+ (lobOperStatus == CHECK_STATUS_ ? 1 : 0),
+ waitedOp,
+ so,
+ sDescSyskey,
+ lobLen,
+ data,
+ fromLobName, fromSchNameLen, fromSchName,
+ fromDescKey, fromDescTS,
+ lobMaxSize, getLobMaxChunkMemSize(),getLobGCLimit());
+ }
+ else
+ {
+ rc = ExpLOBInterfaceUpdate
+ (getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
+ getLobHdfsServer(),
+ getLobHdfsPort(),
+ tgtLobName,
+ lobStorageLocation(),
+ handleLen, lobHandle,
+ &outHandleLen_, outLobHandle_,
+ requestTag_,
+ -1,
- (lobOperStatus == CHECK_STATUS_ ? 1 : 0),
- waitedOp,
- so,
- sDescSyskey,
- lobLen,
- data,
- fromLobName, fromSchNameLen, fromSchName,
- fromDescKey, fromDescTS,
- lobMaxSize, getLobMaxChunkMemSize(),getLobGCLimit());
+ (lobOperStatus == CHECK_STATUS_ ? 1 : 0),
+ waitedOp,
+ so,
+ sDescSyskey,
+ lobLen,
+ data,
+ fromLobName, fromSchNameLen, fromSchName,
+ fromDescKey, fromDescTS,
+ lobMaxSize, getLobMaxChunkMemSize(),getLobGCLimit());
+ }
+ if (lobLocking())
+ retcode = SQL_EXEC_ReleaseLobLock(llid);
+ if (rc < 0)
+ {
+ Lng32 intParam1 = -rc;
+ ExRaiseSqlError(h, diagsArea,
+ (ExeErrorCode)(8442), NULL, &intParam1,
+ &cliError, NULL, (char*)"ExpLOBInterfaceUpdate",
+ getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
+ return ex_expr::EXPR_ERROR;
+ }
}
- if (lobLocking())
- retcode = SQL_EXEC_ReleaseLobLock(llid);
- if (rc < 0)
- {
- Lng32 intParam1 = -rc;
- ExRaiseSqlError(h, diagsArea,
- (ExeErrorCode)(8442), NULL, &intParam1,
- &cliError, NULL, (char*)"ExpLOBInterfaceUpdate",
- getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
- return ex_expr::EXPR_ERROR;
- }
-
- // update lob handle with the returned values
- str_cpy_all(result, lobHandle, handleLen);
+ // update lob handle with the returned values
+ str_cpy_all(result, lobHandle, handleLen);
- getOperand(0)->setVarLength(handleLen, op_data[-MAX_OPERANDS]);
+ getOperand(0)->setVarLength(handleLen, op_data[-MAX_OPERANDS]);
- return ex_expr::EXPR_OK;
+ return ex_expr::EXPR_OK;
}
diff --git a/core/sql/optimizer/SynthType.cpp b/core/sql/optimizer/SynthType.cpp
index 64d59ab..bb31367 100644
--- a/core/sql/optimizer/SynthType.cpp
+++ b/core/sql/optimizer/SynthType.cpp
@@ -7129,6 +7129,7 @@
Lng32 tgtSize = MINOF((Lng32)op1.getLobLength(), tgtSize_);
+
NAType *result = new HEAP SQLVarChar(HEAP, tgtSize,
typ1.supportsSQLnull());
return result;
@@ -7160,6 +7161,7 @@
SQLlob& op1 = (SQLlob&)vid1.getType();
Lng32 tgtSize = MINOF((Lng32)op1.getLobLength(), tgtSize_);
+
NAType *result = new HEAP SQLVarChar(HEAP, tgtSize,
typ1.supportsSQLnull());
diff --git a/core/sql/regress/executor/EXPECTED130 b/core/sql/regress/executor/EXPECTED130
index a862063..2253928 100644
--- a/core/sql/regress/executor/EXPECTED130
+++ b/core/sql/regress/executor/EXPECTED130
@@ -63,10 +63,12 @@
C1 C2
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
1 LOBH0000000200010302322462619480041819302322462659477729318212415509160868978020"TRAFODION"."LOB130"
2 LOBH0000000200010302322462619480041819302322462659658191518212415509163952312020"TRAFODION"."LOB130"
3 LOBH0000000200010302322462619480041819302322462659685731618212415509164230282020"TRAFODION"."LOB130"
+
--- 3 row(s) selected.
>>
>>
@@ -205,6 +207,7 @@
>>----negative case
>>insert into t130var select c1,c2 from t130lob2;
+
*** ERROR[4035] Type LOB cannot be cast to type VARCHAR(100).
*** ERROR[8822] The statement was not prepared.
@@ -685,7 +688,9 @@
>>sh grep "^LOBH" TMP130 | sed "s/^/extract lobtofile(LOB '/g" | sed "s/$/' , 'tlob130_txt1.txt');/g" >> t130_extract_command;
>>
>>obey t130_extract_command;
+
>>extract lobtofile(LOB 'LOBH0000000200010302322462619485420419302322462711610371618212415509682402230020"TRAFODION"."LOB130" ' , 'tlob130_txt1.txt');
+
Success. Targetfile :tlob130_txt1.txt Length : 19
--- SQL operation complete.
@@ -701,7 +706,9 @@
>>sh rm t130_extract_command;
>>sh grep "^LOBH" TMP130 | sed "s/^/extract lobtofile(LOB '/g" | sed "s/$/' , 'tlob130_deep.jpg');/g" >> t130_extract_command;
>>obey t130_extract_command;
+
>>extract lobtofile(LOB 'LOBH0000000200010302322462619485651919302322462715900372918212415509725274892020"TRAFODION"."LOB130" ' , 'tlob130_deep.jpg');
+
Success. Targetfile :tlob130_deep.jpg Length : 159018
--- SQL operation complete.
@@ -718,6 +725,7 @@
>>
>>obey t130_extract_command;
>>extract lobtofile(LOB 'LOBH0000000200010302322462619485651919302322462715900372918212415509725274892020"TRAFODION"."LOB130" ' , 'tlob130_anoush.jpg');
+
Success. Targetfile :tlob130_anoush.jpg Length : 230150
--- SQL operation complete.
@@ -799,6 +807,38 @@
--- 3 row(s) selected.
+>>update tlob130txt2 set c2=NULL where c1=3;
+
+--- 1 row(s) updated.
+>>select * from tlob130txt2;
+
+C1 C2
+----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+ 1 LOBH0000000200010635645578190431822719635645578244780709118212419990806778795020"TRAFODION"."LOB130"
+ 2 LOBH0000000200010635645578190431822719635645578244930461118212419990809079499020"TRAFODION"."LOB130"
+ 3 ?
+
+--- 3 row(s) selected.
+>>update tlob130txt2 set c2=filetolob('hdfs:///user/trafodion/lobs/lob_input_d1.txt', append) where c1 = 3;
+
+--- 1 row(s) updated.
+>>select lobtostring(c2, 200 ) from tlob130txt2;
+
+(EXPR)
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Hey diddle diddle,
+
+The cat and the fiddle,
+
+The little dog laughed,
+To see such sport,
+
+And the dish ran away with the spoon.
+
+
+--- 3 row(s) selected.
>>
>>-- should see wrong text in the last few lines
>>update tlob130txt2 set c2=filetolob('hdfs:///user/trafodion/lobs/lob_input_e1.txt') where c1 =3 ;
@@ -838,7 +878,9 @@
>>
>>sh grep "^LOBH" TMP130 | sed "s/^/extract lobtofile(LOB '/g" | sed "s/$/' , 'hdfs:\/\/\/user\/trafodion\/lobs\/tlob130_txt2.txt');/g" >> t130_extract_command;
>>obey t130_extract_command;
+
>>extract lobtofile(LOB 'LOBH0000000200010302322462619486948319302322462724980286218212415509815960051020"TRAFODION"."LOB130" ' , 'hdfs:///user/trafodion/lobs/tlob130_txt2.txt');
+
Success. Targetfile :hdfs:///user/trafodion/lobs/tlob130_txt2.txt Length : 19
--- SQL operation complete.
@@ -854,6 +896,7 @@
>>sh rm t130_extract_command;
>>sh grep "^LOBH" TMP130 | sed "s/^/extract lobtofile(LOB '/g" | sed "s/$/' , 'hdfs:\/\/\/user\/trafodion\/lobs\/tlob130_deep.jpg');/g" >> t130_extract_command;
>>obey t130_extract_command;
+
>>extract lobtofile(LOB 'LOBH0000000200010302322462619487179919302322462728926701518212415509855552322020"TRAFODION"."LOB130" ' , 'hdfs:///user/trafodion/lobs/tlob130_deep.jpg');
Success. Targetfile :hdfs:///user/trafodion/lobs/tlob130_deep.jpg Length : 159018
@@ -1136,6 +1179,7 @@
TRAFODION LOB130 TLOB130GT2 C2 /user/trafodion/lobs LOBP_03023224626194919246_0001 0 0
TRAFODION LOB130 TLOB130GT2 C3 /user/trafodion/lobs LOBP_03023224626194919246_0002 0 0
+
TRAFODION LOB130 TLOB130GT2 C4 External HDFS Location External HDFS File 0 0
--- 3 row(s) selected.
@@ -1530,6 +1574,7 @@
Column Name : c2
Extracting lob handle for column c2...
LOB handle for c2: LOBH0000000200010302322462619496180919302322462812783026418212415510694095790020"TRAFODION"."LOB130"
+
>>select lobtostring(c2,40) from t130lob5;
(EXPR)
diff --git a/core/sql/regress/executor/TEST130 b/core/sql/regress/executor/TEST130
index 4e82e00..20782c3 100755
--- a/core/sql/regress/executor/TEST130
+++ b/core/sql/regress/executor/TEST130
@@ -379,6 +379,10 @@
--should update with full poem
update tlob130txt2 set c2=filetolob('hdfs:///user/trafodion/lobs/lob_input_d1.txt', append) where c1 = 3;
select lobtostring(c2, 200 ) from tlob130txt2;
+update tlob130txt2 set c2=NULL where c1=3;
+select * from tlob130txt2;
+update tlob130txt2 set c2=filetolob('hdfs:///user/trafodion/lobs/lob_input_d1.txt', append) where c1 = 3;
+select lobtostring(c2, 200 ) from tlob130txt2;
-- should see wrong text in the last few lines
update tlob130txt2 set c2=filetolob('hdfs:///user/trafodion/lobs/lob_input_e1.txt') where c1 =3 ;
diff --git a/core/sql/src/main/java/org/trafodion/sql/HDFSClient.java b/core/sql/src/main/java/org/trafodion/sql/HDFSClient.java
index 4f06e7b..b921488 100644
--- a/core/sql/src/main/java/org/trafodion/sql/HDFSClient.java
+++ b/core/sql/src/main/java/org/trafodion/sql/HDFSClient.java
@@ -495,23 +495,52 @@
long hdfsWriteImmediate(byte[] buff) throws IOException
{
+
if (logger_.isDebugEnabled())
- logger_.debug("HDFSClient.hdfsWriteClose() - started" );
- FSDataOutputStream fsOut;
- FileStatus filestatus;
- long writeOffset;
- if (fs_.exists(filepath_)) {
- filestatus = fs_.getFileStatus(filepath_);
- fsOut = fs_.append(filepath_);
- writeOffset = filestatus.getLen();
- }
- else {
- fsOut = fs_.create(filepath_);
- writeOffset = 0;
- }
- fsOut.write(buff);
- fsOut.close();
- return writeOffset;
+ logger_.debug("HDFSClient.hdfsWriteImmediate() - started" );
+
+ FSDataOutputStream fsOut=null;
+ FileStatus filestatus = null;
+ long writeOffset=0;
+ long writeEndOffset =0;
+ int trycount = 0;
+
+ while(trycount < 3)
+ {
+ try{
+ if (logger_.isDebugEnabled())
+ logger_.debug("HDFSClient.hdfsWriteImmediate() - started" );
+
+ if (fs_.exists(filepath_)) {
+ filestatus = fs_.getFileStatus(filepath_);
+ fsOut = fs_.append(filepath_);
+ writeOffset = filestatus.getLen();
+ }
+ else {
+ fsOut = fs_.create(filepath_);
+ writeOffset = 0;
+ }
+ fsOut.write(buff);
+ fsOut.hflush();
+ writeEndOffset = fsOut.getPos();
+ } finally {
+ if (fsOut != null )
+ fsOut.close();
+ }
+ // Do a checksum to ensure writeOffset is really the right value.
+ if (buff.length != writeEndOffset-writeOffset)
+ {
+ trycount++;
+ if (trycount == 3)
+
+ {
+ fsOut.close();
+ throw new IOException("HDFSwrite did not succeed due to multiple concurrent writes ");
+ }
+ }
+ else trycount = 100;
+ }
+ return writeOffset;
}
int hdfsWrite(byte[] buff) throws IOException