@@ -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
/*********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// 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
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
 *****************************************************************************
 *
 * File:         <file>
 * Description:  
 *               
 *               
 * Created:      7/10/95
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */

#include "Platform.h"

#include <ctype.h>
#include <string.h>

#include "ComCextdecs.h"

#include "NLSConversion.h"
#include "nawstring.h"
#include "exp_stdh.h"
#include "exp_clause_derived.h"
#include "exp_function.h"

#include "ExpLOB.h"
#include "ExpLOBinterface.h"
#include "ExpLOBexternal.h"
#include "ex_globals.h"
#include "ex_god.h"

ExLobGlobals *ExpLOBoper::initLOBglobal(NAHeap *parentHeap, ContextCli *currContext, NABoolean useLibHdfs, NABoolean isHiveRead)
{
  NAHeap *lobHeap = new (parentHeap) NAHeap("LOB Heap", parentHeap);
  ExLobGlobals *exLobGlobals = new (lobHeap) ExLobGlobals(lobHeap);
  exLobGlobals->setUseLibHdfs(useLibHdfs);
  exLobGlobals->initialize();
  // initialize lob interface
  ExpLOBoper::initLOBglobal(exLobGlobals, lobHeap, currContext, (char *)"default", (Int32)0, isHiveRead);
  return exLobGlobals; 
}


Lng32 ExpLOBoper::initLOBglobal(ExLobGlobals *& exLobGlobals, NAHeap *heap, ContextCli *currContext, char *hdfsServer ,Int32 port, NABoolean isHiveRead)
{
  // call ExeLOBinterface to initialize lob globals
  ExpLOBinterfaceInit(exLobGlobals, heap, currContext, isHiveRead, hdfsServer, port);
  return 0;
}

void ExpLOBoper::deleteLOBglobal(ExLobGlobals *exLobGlobals, NAHeap *heap)
{
  NAHeap *lobHeap = exLobGlobals->getHeap();
  NADELETE(exLobGlobals, ExLobGlobals, lobHeap);
  NADELETE(lobHeap, NAHeap, heap);
}

char * ExpLOBoper::ExpGetLOBname(Int64 uid, Lng32 num, char * outBuf, Lng32 outBufLen)
{
  if (outBufLen < 31)
    return NULL;

  str_sprintf(outBuf, "LOBP_%020ld_%04d",
	      uid, num);

  return outBuf;
}

char * ExpLOBoper::ExpGetLOBDescName(Lng32 schNameLen, char * schName,
				     Int64 uid, Lng32 num, 
				     char * outBuf, Lng32 outBufLen)
{
  if (outBufLen < 512)
    return NULL;

  str_sprintf(outBuf, "%s.\"LOBDsc_%020ld_%04d\"",
	      schName, uid, num);

  return outBuf;
}

char * ExpLOBoper::ExpGetLOBDescHandleObjNamePrefix(Int64 uid, 
					   char * outBuf, Lng32 outBufLen)
{
  if (outBufLen < 512)
    return NULL;
  
  str_sprintf(outBuf, "%s_%020ld", LOB_DESC_HANDLE_PREFIX,uid);
  
  return outBuf;
}

char * ExpLOBoper::ExpGetLOBDescHandleName(Lng32 schNameLen, char * schName,
					   Int64 uid, Lng32 num, 
					   char * outBuf, Lng32 outBufLen)
{
  if ((outBufLen < 512) ||
      (schName == NULL))
    return NULL;
  
  str_sprintf(outBuf, "%s.\"%s_%020ld_%04d\"",
	      schName, LOB_DESC_HANDLE_PREFIX,uid, num);
  
  return outBuf;
}

Lng32 ExpLOBoper::ExpGetLOBnumFromDescName(char * descName, Lng32 descNameLen)
{
  // Desc Name Format: LOBDescHandle_%020ld_%04d
  char * lobNumPtr = &descName[sizeof(LOB_DESC_HANDLE_PREFIX) + 20 + 1];
  Lng32 lobNum = str_atoi(lobNumPtr, 4);
  
  return lobNum;
}

char * ExpLOBoper::ExpGetLOBDescChunksName(Lng32 schNameLen, char * schName,
					   Int64 uid, Lng32 num, 
					   char * outBuf, Lng32 outBufLen)
{
  if ((outBufLen < 512) ||
      (schNameLen == 0) ||
      (schName == NULL))
    return NULL;
  
  str_sprintf(outBuf, "%s.\"%s_%020ld_%04d\"",
	      schName, LOB_DESC_CHUNK_PREFIX,uid, num);

  return outBuf;
}



char * ExpLOBoper::ExpGetLOBMDName(Lng32 schNameLen, char * schName,
				    Int64 uid,  
				    char * outBuf, Lng32 outBufLen)
{
  if (outBufLen < 512)
    return NULL;

  str_sprintf(outBuf, "%s.\"%s_%020ld\"",
	      schName, LOB_MD_PREFIX,uid);

  return outBuf;
}
Lng32 ExpLOBoper::createLOB(ExLobGlobals * exLobGlob, ContextCli *currContext, 
			    char * lobLoc,Int32 hdfsPort,char *hdfsServer,
			    Int64 uid, Lng32 num, Int64 lobMaxSize )
{
  char buf[LOB_NAME_LEN];
  
  char * lobName = ExpGetLOBname(uid, num, buf, LOB_NAME_LEN);
  if (lobName == NULL)
    return -1;

  Lng32 rc = 0;
  
  // Call ExeLOBinterface to create the LOB

  rc = ExpLOBinterfaceCreate(exLobGlob, lobName, lobLoc, Lob_HDFS_File,hdfsServer,lobMaxSize, hdfsPort);
  
  return rc;
}
void ExpLOBoper::calculateNewOffsets(ExLobInMemoryDescChunksEntry *dcArray, Lng32 numEntries)
{
  Int32 i = 0;
  //Check if there is a hole right up front for the first entry. If so start compacting with the first entry.
  if (dcArray[0].getCurrentOffset() != 0)
    {
      dcArray[0].setNewOffset(0);
      for (i = 1; i < numEntries; i++)
        {
          dcArray[i].setNewOffset(dcArray[i-1].getNewOffset() + dcArray[i-1].getChunkLen());
        }
    }
  else
    //Look for the first unused section and start compacting from there.
    {
      NABoolean done = FALSE;
      i = 0;
      Int32 j = 0;
      while (i < numEntries && !done )
        {
          if ((dcArray[i].getCurrentOffset()+dcArray[i].getChunkLen()) != 
              dcArray[i+1].getCurrentOffset())
            {
              j = i+1;
              while (j < numEntries)
                {
                   dcArray[j].setNewOffset(dcArray[j-1].getNewOffset()+dcArray[j-1].getChunkLen());
                   j++;
                }
              done = TRUE;
            }
          i++;
        }
    }
  return ;
}

Lng32 ExpLOBoper::compactLobDataFile(ExLobGlobals *exLobGlob,ExLobInMemoryDescChunksEntry *dcArray,Int32 numEntries,char *tgtLobName,Int64 lobMaxChunkMemSize, NAHeap *lobHeap,  ContextCli *currContext,char *hdfsServer, Int32 hdfsPort, char *lobLoc)
{
  Int32 rc = 0;
  ExLobGlobals * exLobGlobL = NULL;
  // Call ExeLOBinterface to create the LOB
  if (exLobGlob == NULL)
    {
      rc = initLOBglobal(exLobGlobL, lobHeap,currContext,hdfsServer,hdfsPort);
      if (rc)
	return rc;
    }
  else
    exLobGlobL = exLobGlob;
 
   
  rc = ExpLOBinterfacePerformGC(exLobGlobL,tgtLobName, (void *)dcArray, numEntries,hdfsServer,hdfsPort,lobLoc,lobMaxChunkMemSize);
  
  if (exLobGlob == NULL)
     ExpLOBinterfaceCleanup(exLobGlobL);
  return rc;
}

Int32 ExpLOBoper::restoreLobDataFile(ExLobGlobals *exLobGlob, char *lobName, NAHeap *lobHeap, ContextCli *currContext,char *hdfsServer, Int32 hdfsPort, char *lobLoc)
{
  Int32 rc = 0;
  ExLobGlobals * exLobGlobL = NULL;
   if (exLobGlob == NULL)
    {
      rc = initLOBglobal(exLobGlobL, lobHeap,currContext, hdfsServer,hdfsPort);
      if (rc)
	return rc;
    }
  else
    exLobGlobL = exLobGlob;
  rc = ExpLOBinterfaceRestoreLobDataFile(exLobGlobL,hdfsServer,hdfsPort,lobLoc,lobName);
  if (exLobGlob == NULL)
     ExpLOBinterfaceCleanup(exLobGlobL);
  return rc;

}

Int32 ExpLOBoper::purgeBackupLobDataFile(ExLobGlobals *exLobGlob,char *lobName, NAHeap *lobHeap, ContextCli *currContext, char * hdfsServer, Int32 hdfsPort, char *lobLoc)
{
  Int32 rc = 0;
  ExLobGlobals * exLobGlobL = NULL;
  if (exLobGlob == NULL)
    {
      rc = initLOBglobal(exLobGlobL, lobHeap,currContext,hdfsServer,hdfsPort);
      if (rc)
	return rc;
    }
  else
    exLobGlobL = exLobGlob;
  rc = ExpLOBinterfacePurgeBackupLobDataFile(exLobGlobL,(char *)hdfsServer,hdfsPort,lobLoc,lobName);
  if (exLobGlob == NULL)
     ExpLOBinterfaceCleanup(exLobGlobL);
  return rc;
}


Lng32 ExpLOBoper::dropLOB(ExLobGlobals * exLobGlob, ContextCli *currContext,
			  char * lobLoc,Int32 hdfsPort, char *hdfsServer,
			  Int64 uid, Lng32 num)
{
  char buf[LOB_NAME_LEN];
  
  char * lobName = ExpGetLOBname(uid, num, buf, LOB_NAME_LEN);
  if (lobName == NULL)
    return -1;

  Lng32 rc = 0;
 
 
  // Call ExeLOBinterface to drop the LOB
  rc = ExpLOBinterfaceDrop(exLobGlob,hdfsServer, hdfsPort, lobName, lobLoc);
  
  return rc;
}

Lng32 ExpLOBoper::purgedataLOB(ExLobGlobals * exLobGlob, char * lobLoc, 
                               
			       Int64 uid, Lng32 num)
{
  char buf[LOB_NAME_LEN];
  
  char * lobName = ExpGetLOBname(uid, num, buf, LOB_NAME_LEN);
  if (lobName == NULL)
    return -1;

  // Call ExeLOBinterface to purgedata the LOB
  Lng32 rc = ExpLOBInterfacePurgedata(exLobGlob, lobName, lobLoc);
  if (rc < 0)
    return ex_expr::EXPR_ERROR;

  return ex_expr::EXPR_OK;
}

ExpLOBoper::ExpLOBoper(){};
ExpLOBoper::ExpLOBoper(OperatorTypeEnum oper_type,
		       short num_operands,
		       Attributes ** attr,
		       Space * space)
  : ex_clause(ex_clause::LOB_TYPE, oper_type, num_operands, attr, space),
    flags_(0),
    lobNum_(-1),
    lobHandleLenSaved_(0),
    lobStorageType_((short)Lob_Invalid_Storage),
    requestTag_(-1),
    descSchNameLen_(0)
{
  lobHandleSaved_[0] = 0;
  lobStorageLocation_[0] = 0;
  lobHdfsServer_[0] = 0;
  strcpy(lobHdfsServer_,"");
  lobHdfsPort_ = -1;
  descSchName_[0] = 0;
  lobSize_ = 0;
  lobMaxSize_ = 0;
  lobMaxChunkMemSize_ = 0;
  lobGCLimit_ = 0;
};


void ExpLOBoper::displayContents(Space * space, const char * displayStr, 
				 Int32 clauseNum, char * constsArea)
{
  ex_clause::displayContents(space, displayStr, clauseNum, constsArea);

  char buf[100];
  str_sprintf(buf, "    lobNum_ = %d, lobStorageType_ = %d",
	      lobNum_, lobStorageType_);
  space->allocateAndCopyToAlignedSpace(buf, str_len(buf), sizeof(short));

  Lng32 len = MINOF(strlen(lobStorageLocation_), 50);
  char loc[100];
  str_cpy_all(loc, lobStorageLocation_, len);
  loc[len] = 0;
  str_sprintf(buf, "    lobStorageLocation_ = %s\n",
	      loc);
  space->allocateAndCopyToAlignedSpace(buf, str_len(buf), sizeof(short));
}

Lng32 findNumDigits(Int64 val)
{
  Int64 v = val/10;
  Lng32 n = 1;
  while (v > 0)
    {
      n++;
      
      v = v / 10;


    }

  return n;
}

// Generates LOB handle that is stored in the SQL row.
// LOB handle len:  64 bytes
// <flags><LOBnum><objectUid><descKey><descTS><schNameLen><schName>
// <--4--><--4---><----8----><---8---><--8---><-----2----><--vc--->
void ExpLOBoper::genLOBhandle(Int64 uid, 
			      Lng32 lobNum,
			      Int32 lobType,
			      Int64 descKey, 
			      Int64 descTS,
			      Lng32 flags,
			      short schNameLen,
			      char  * schName,
			      Lng32 &handleLen,
			      char * ptr)
{
  LOBHandle * lobHandle = (LOBHandle*)ptr;
  lobHandle->flags_ = flags;
  lobHandle->lobType_ = lobType;
  lobHandle->lobNum_ = lobNum;
  lobHandle->objUID_ = uid;
  lobHandle->descSyskey_ = descKey;
  lobHandle->descPartnkey_ = descTS;
  lobHandle->schNameLen_ = schNameLen;
  handleLen = sizeof(LOBHandle);
  if (schNameLen > 0)
    {
      char * s = &lobHandle->schName_;
      str_cpy_all(s, schName, schNameLen);
      s[schNameLen] = 0;

      handleLen += schNameLen;
    }
  //  lobHandle->inlinedLOBlen_ = 0;
}

void ExpLOBoper::updLOBhandle(Int64 descSyskey, 
			      Lng32 flags,                            
			      char * ptr)
{
  LOBHandle * lobHandle = (LOBHandle*)ptr;
  lobHandle->flags_ = flags;  
  lobHandle->descSyskey_ = descSyskey;
}

// Extracts values from the LOB handle stored at ptr
Lng32 ExpLOBoper::extractFromLOBhandle(Int16 *flags,
				       Lng32 *lobType,
				       Lng32 *lobNum,
				       Int64 *uid, 
				       Int64 *descSyskey, 
				       Int64 *descPartnKey,
				       short *schNameLen,
				       char * schName,
				       char * ptrToLobHandle,
				       Lng32 handleLen)
{
  LOBHandle * lobHandle = (LOBHandle*)ptrToLobHandle;
  if (flags)
    *flags = lobHandle->flags_;
  if (lobType)
    *lobType = lobHandle->lobType_;
  if (lobNum)
    *lobNum = lobHandle->lobNum_;
  if (uid)
    *uid = lobHandle->objUID_;
  if (descSyskey)
    *descSyskey = lobHandle->descSyskey_;
  if (descPartnKey)
    *descPartnKey = lobHandle->descPartnkey_;
  if (schNameLen)
    *schNameLen = lobHandle->schNameLen_;
  if ((schNameLen) && (*schNameLen > 0) && (schName != NULL))
    {
      str_cpy_all(schName, &lobHandle->schName_, *schNameLen);
      schName[*schNameLen] = 0;
    }

  return 0;
}
// 12 byte lock identifier uniquely identifies the LOB file that is being 
// locked.
// <object UID + lob number > Each LOB column has a unique lob number and 
// each column has a unique data file.
void ExpLOBoper::genLobLockId(Int64 objid, Int32 lobNum, char *llid)
{
  memset(llid,'\0',LOB_LOCK_ID_SIZE);
  if (objid != -1 && lobNum != -1)
    {
      memcpy(llid,&objid,sizeof(Int64)) ;
      memcpy(&(llid[sizeof(Int64)]),&lobNum,sizeof(Int32));
    }    
}

// creates LOB handle in string format.
void ExpLOBoper::createLOBhandleString(Int16 flags,
				       Lng32 lobType,
				       Int64 uid, 
				       Lng32 lobNum,
				       Int64 descKey, 
				       Int64 descTS,
				       short schNameLen,
				       char * schName,
				       char * lobHandleBuf)
{
  str_sprintf(lobHandleBuf, "LOBH%04d%04d%04d%020ld%02d%ld%02d%ld%03d%s",
	      flags, lobType, lobNum, uid,
	      findNumDigits(descKey), descKey, 
	      findNumDigits(descTS), descTS,
	      schNameLen, schName);

 
}

// Extracts values from the string format of LOB handle 
Lng32 ExpLOBoper::extractFromLOBstring(Int64 &uid, 
				       Lng32 &lobNum,
				       Int64 &descPartnKey,
				       Int64 &descSyskey,
				       Int16 &flags,
				       Lng32 &lobType,
				       short &schNameLen,
				       char * schName,
				       char * handle,
				       Lng32 handleLen)
{
  // opp of:
  //  str_sprintf(lobHandleBuf, "LOBH%04d%04d%04d%020ld%02d%ld%02d%ld%03d%s",
  //	      flags, lobType, lobNum, uid,
  //	      findNumDigits(descKey), descKey, 
  //	      findNumDigits(descTS), descTS,
  //	      schNameLen, schName)


  if (handleLen < (4 + 4 + 4  + 20 + 2)) // Minimum sanity check.
    return -1;

  Lng32 curPos = 4;
  
  flags = (Lng32)str_atoi(&handle[curPos], 4);
  curPos += 4;

  lobType = (Lng32)str_atoi(&handle[curPos], 4);
  curPos += 4;

  lobNum = (Lng32)str_atoi(&handle[curPos], 4);
  curPos += 4;

  uid = str_atoi(&handle[curPos], 20);
  curPos += 20;

  short len1;
  len1 = (short)str_atoi(&handle[curPos], 2);
  curPos += 2;

  if (handleLen < (curPos + len1 + 2))
    return -1;

  descPartnKey = str_atoi(&handle[curPos], len1);
  curPos += len1;

  short len2;
  len2 = (short)str_atoi(&handle[curPos], 2);
  curPos += 2;

  if (handleLen < (curPos + len2 + 3))
    return -1;
  descSyskey = str_atoi(&handle[curPos], len2);
  curPos += len2;

  schNameLen = (short)str_atoi(&handle[curPos], 3);
  curPos += 3;
  if (handleLen < (curPos + schNameLen))
    return -1;
  
  str_cpy_and_null(schName, &handle[curPos], 
		   schNameLen, '\0', ' ', TRUE);

  //  flags = 0;

  return 0;
}

Lng32 ExpLOBoper::genLOBhandleFromHandleString(char * lobHandleString,
					       Lng32 lobHandleStringLen,
					       char * lobHandle,
					       Lng32 &lobHandleLen)
{
  
  Int64 uid;
  Lng32 lobNum;
  Int32 lobType;
  Int64 descPartnKey;
  Int64 descSyskey;
  Int16 flags;
  short schNameLen;
  char  schNameLenBuf[1024];
  Lng32 handleLen;

  if (extractFromLOBstring(uid, lobNum, descPartnKey, descSyskey, flags,
			   lobType,schNameLen, schNameLenBuf, 
			   lobHandleString, lobHandleStringLen))
    return -1;

  
  char lLobHandle[4096];
  genLOBhandle(uid, lobNum, lobType, descPartnKey, descSyskey, flags,
	       schNameLen, schNameLenBuf, handleLen, lLobHandle);

  if (handleLen > lobHandleLen)
    {
      return -1;
    }

  str_cpy_all(lobHandle, lLobHandle, handleLen);
  lobHandleLen = handleLen;

  return 0;
}

Long ExpLOBoper::pack(void * space)
{
  //  if (lobStorageLocation_)
  //    lobStorageLocation_.pack(space);

  return packClause(space, sizeof(ExpLOBoper));
}

Lng32 ExpLOBoper::unpack (void * base, void * reallocator)
{
  //  if (lobStorageLocation_.unpack(base))
  //    return -1;

  return unpackClause(base, reallocator);
}

Lng32 ExpLOBoper::initClause()
{
  requestTag_ = -1;

  return 0;
}

///////////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////////

Lng32 ExpLOBoper::checkLobOperStatus()
{
  Lng32 lobOperStatus = 0;

  if (requestTag_ == -1) // this clause has not been evaluated yet
    lobOperStatus = START_LOB_OPER_;   // start lob process
  else if (requestTag_ == -2) // this request has completed
    lobOperStatus = DO_NOTHING_; // do nothing
  else // a valid request tag
    lobOperStatus = CHECK_STATUS_; // check status for this clause
  
  return lobOperStatus;
}

////////////////////////////////////////////////////////
// ExpLOBiud
////////////////////////////////////////////////////////
ExpLOBiud::ExpLOBiud(){};
ExpLOBiud::ExpLOBiud(OperatorTypeEnum oper_type,
		     Lng32 numAttrs,
		     Attributes ** attr, 
		     Int64 objectUID,
		     short descSchNameLen,
		     char * descSchName,
		     Space * space)
  : ExpLOBoper(oper_type, numAttrs, attr, space),
    objectUID_(objectUID),
    liudFlags_(0)
   
    //    descSchNameLen_(descSchNameLen),
    //    liFlags_(0)
{
  str_cpy_and_null(descSchName_, descSchName, descSchNameLen, 
		   '\0', ' ', TRUE);

  setDescSchNameLen(descSchNameLen);
};

////////////////////////////////////////////////////////
// ExpLOBinsert
////////////////////////////////////////////////////////
ExpLOBinsert::ExpLOBinsert(){};
ExpLOBinsert::ExpLOBinsert(OperatorTypeEnum oper_type,
			   Lng32 numAttrs,
			   Attributes ** attr,			   
			   Int64 objectUID,
			   short descSchNameLen,
			   char * descSchName,
			   Space * space)
  : ExpLOBiud(oper_type, numAttrs, attr, objectUID, descSchNameLen, descSchName, space),
    //    objectUID_(objectUID),
    //    descSchNameLen_(descSchNameLen),
    liFlags_(0)
{
};

void ExpLOBinsert::displayContents(Space * space, const char * displayStr, 
				   Int32 clauseNum, char * constsArea)

{
  ex_clause::displayContents(space, "ExpLOBinsert", clauseNum, constsArea);

  char buf[100];

  str_sprintf(buf, "    liFlags_ = %d", liFlags_);
  space->allocateAndCopyToAlignedSpace(buf, str_len(buf), sizeof(short));
}




ex_expr::exp_return_type ExpLOBiud::insertDesc(char *op_data[],
                                                char *lobData,
                                                Int64 lobLen,
                                                Int64 lobHdfsDataOffset,
                                                char *&result,
                                                CollHeap*h,
                                                ComDiagsArea** diagsArea)
{
  Lng32 rc;

 
  Lng32 handleLen = 0;
  char lobHandleBuf[LOB_HANDLE_LEN];
  Int64 descTS = NA_JulianTimestamp();
  char * lobHandle = NULL; 
  lobHandle = lobHandleBuf;
  ExpLOBoper::genLOBhandle(objectUID_, lobNum(), (short)lobStorageType(),
                           -1, descTS, -1,
                           descSchNameLen_, descSchName(),
                           handleLen, lobHandle);
 

  // get the lob name where data need to be inserted
  if (lobNum() == -1)
    {
      Int32 intparam = LOB_PTR_ERROR;
      Int32 detailError = 0;
     
      ExRaiseSqlError(h, diagsArea, 
		      (ExeErrorCode)(8434));
      return ex_expr::EXPR_ERROR;
    }
  char tgtLobNameBuf[LOB_NAME_LEN];
  char * tgtLobName = ExpGetLOBname(objectUID_, lobNum(), tgtLobNameBuf, LOB_NAME_LEN);

  if (tgtLobName == NULL)
    return ex_expr::EXPR_ERROR;

  // call function with the lobname and source value
  // to insert it in the LOB.
  // Get back offset and len of the LOB.
  Int64 descSyskey = 0;

  
  LobsSubOper so = Lob_None;
  if (fromFile())
    so = Lob_File;
  else if (fromString() || fromLoad())
    so = Lob_Memory;
  else if (fromLob())
    so = Lob_Lob;
  else if (fromLobExternal())
    so = Lob_External_Lob;
  else if (fromBuffer())
    so = Lob_Buffer;
  else if (fromExternal())
    so = Lob_External_File;
  else if (fromEmpty())
    {
      so = Lob_Memory;
    }

  

  Lng32 waitedOp = 0;
  waitedOp = 1;

  
  // until SQL_EXEC_LOBcliInterface is changed to allow for unlimited
  // black box sizes, we have to prevent over-sized file names from
  // being stored
  if ((so == Lob_External_File) && (lobLen > MAX_LOB_FILE_NAME_LEN))
    {
      ExRaiseSqlError(h, diagsArea, 
		      (ExeErrorCode)(8557));
      return ex_expr::EXPR_ERROR;
    }
  
  blackBoxLen_ = 0;
  if (fromExternal())
    {
      blackBoxLen_ = lobLen;
      str_cpy_and_null(blackBox_, lobData, (Lng32)blackBoxLen_,
		       '\0', ' ', TRUE);
    }

  Lng32 cliError = 0;

  
 
  LobsOper lo ;
 
 if (lobHandle == NULL)       
    lo = Lob_InsertDataSimple;
  else
    lo = Lob_InsertDesc;
  Int64 lobMaxSize = 0;
  if (getLobSize() > 0)
    {
      lobMaxSize = MINOF(getLobSize(), getLobMaxSize());
    }
  else
    lobMaxSize = getLobMaxSize();
    
  if ((so == Lob_Lob) || (so == Lob_External_Lob))
    {
      
      rc = ExpLOBInterfaceInsertSelect
        (getExeGlobals()->getExLobGlobal(), 
         (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
         getLobHdfsServer(), getLobHdfsPort(),
         tgtLobName, 
         so,
         lobStorageLocation(),lobStorageType(),
         -1,
         handleLen, lobHandle,  &outHandleLen_, outLobHandle_,            
         lobData, lobLen, blackBox_, blackBoxLen_,lobMaxSize, getLobMaxChunkMemSize(),getLobGCLimit()); 
        
    }
else
  rc = ExpLOBInterfaceInsert
    (getExeGlobals()->getExLobGlobal(), 
     (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
     tgtLobName, 
     lobStorageLocation(),
     lobStorageType(),
     getLobHdfsServer(), getLobHdfsPort(),

     handleLen, lobHandle,
     &outHandleLen_, outLobHandle_,
     blackBoxLen_, blackBox_,
     lobHdfsDataOffset,
     -1,
     descSyskey,
     lo,
     &cliError,
     so,
     waitedOp,
     lobData, lobLen, lobMaxSize, getLobMaxChunkMemSize(),getLobGCLimit());
  
  if (rc == LOB_ACCESS_PREEMPT)
    {
      // save the handle so it could be used after return from preempt
      lobHandleLenSaved_ = handleLen;
      str_cpy_all(lobHandleSaved_, lobHandle, handleLen);
      
      return ex_expr::EXPR_PREEMPT;
    }

  if (rc < 0)
    {
      Lng32 intParam1 = -rc;
      ExRaiseSqlError(h, diagsArea, 
		      (ExeErrorCode)(8442), NULL, &intParam1, 
		      &cliError, NULL, (char*)"ExpLOBInterfaceInsert",
		      getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
      return ex_expr::EXPR_ERROR;
    }

  // extract and update lob handle with the returned values
  if (outHandleLen_ > 0)
    {
      Int32 lobType = 0;
      ExpLOBoper::extractFromLOBhandle(NULL, &lobType, NULL, NULL, &descSyskey,
				       NULL, NULL, NULL, outLobHandle_);
      
      ExpLOBoper::updLOBhandle(descSyskey, 0, lobHandle); 
    }

  str_cpy_all(result, lobHandle, handleLen);
  getOperand(0)->setVarLength(handleLen, op_data[-MAX_OPERANDS]);
 

  return ex_expr::EXPR_OK;
}



ex_expr::exp_return_type ExpLOBiud::insertData(Lng32 handleLen,
                                                char *&handle,
                                                char *lobData,
                                                Int64 lobLen,
                                                Int64 &hdfsDataOffset,
                                                CollHeap*h,
                                                ComDiagsArea** diagsArea)
{
  Lng32 rc = 0;

  Lng32 lobType;
  Int64 uid;
  Lng32 lobColNum;
  
 
  Int64 descSyskey = -1;
 
  short numChunks = 0;
 
  
   // get the lob name where data need to be inserted
  char tgtLobNameBuf[LOB_NAME_LEN];
  char * tgtLobName = ExpGetLOBname(objectUID_, lobNum(), tgtLobNameBuf, LOB_NAME_LEN);

  if (tgtLobName == NULL)
    return ex_expr::EXPR_ERROR;

  
  if (fromExternal() || fromLob() || fromLobExternal())
    {
      //no need to insert any data. All data resides in the external file
      // for external LOB and it has already been read/inserted during 
      // ::insertDesc for insert from another  LOB
      return ex_expr::EXPR_OK;
    }
 
  LobsOper lo ;
 
  if (handle == NULL)       
    lo = Lob_InsertDataSimple;
  else
    lo = Lob_InsertData;

  LobsSubOper so = Lob_None;
  if (fromFile())    
    so = Lob_File;       
  else if (fromString() || fromLoad())
    so = Lob_Memory;
  else if (fromLob())
    so = Lob_Lob;
  else if(fromBuffer())
    so = Lob_Buffer;
  else if (fromExternal())
    so = Lob_External_File;

 
  Lng32 waitedOp = 0;
  waitedOp = 1;

  Lng32 cliError = 0;

  blackBoxLen_ = 0;

  
      rc = ExpLOBInterfaceInsert(getExeGlobals()->getExLobGlobal(),
                                 (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
				 tgtLobName, 
				 lobStorageLocation(),
				 lobType,
				 getLobHdfsServer(), getLobHdfsPort(),

				 handleLen, handle,
				 &outHandleLen_, outLobHandle_,

				 blackBoxLen_, blackBox_,

				 hdfsDataOffset,
				 -1,
				 
				 descSyskey, 
				 lo,
				 &cliError,
				 so,
				 waitedOp,				 
				 lobData,
				 lobLen,getLobMaxSize(),
                                 getLobMaxChunkMemSize(),
                                 getLobGCLimit());
    

  if (rc == LOB_ACCESS_PREEMPT)
    {
      return ex_expr::EXPR_PREEMPT;
    }

  if (rc < 0)
    {
      Lng32 intParam1 = -rc;
      ExRaiseSqlError(h, diagsArea, 
		      (ExeErrorCode)(8442), NULL, &intParam1, 
		      &cliError, NULL, (char*)"ExpLOBInterfaceInsert",
		      getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
      return ex_expr::EXPR_ERROR;
    }

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExpLOBinsert::eval(char *op_data[],
					    CollHeap*h,
					    ComDiagsArea** diagsArea)
{

  ex_expr::exp_return_type err;
  Int32 retcode = 0;
  Int32 cliError = 0;
  Int64 lobHdfsOffset = 0;  
  char * result = op_data[0];
  Int64 lobLen = 0; 
  char *lobData = NULL;
  Int64 chunkMemSize = 0;
  char *inputAddr = NULL;
  Int64 sourceFileSize = 0; // If the input is from a file get total file size
  Int64 sourceFileReadOffset = 0; 
  char *retBuf = 0;
  Int64 retReadLen = 0;
  Lng32 sLobType;
  Int64 sUid;
  Lng32 sLobNum;
  Int64 sDescSyskey = -1;
  Int64 sDescTS = -1;
  Int16 sFlags;
  short sSchNameLen = 0;
  char sSchName[500];
  char tgtLobNameBuf[LOB_NAME_LEN];
  char *tgtLobName = NULL;
  Int32 handleLen = 0;

  if (lobNum() == -1)
    {
      Int32 intparam = LOB_PTR_ERROR;
      Int32 detailError = 0;
     
      ExRaiseSqlError(h, diagsArea, 
		      (ExeErrorCode)(8434));
      return ex_expr::EXPR_ERROR;
    }
     
  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 (!fromEmpty())
    lobLen = getOperand(1)->getLength();
                 
  if(fromString())
    {
      //If source is a varchar, find the actual length
      if (getOperand(1)->getVCIndicatorLength() >0)   
        lobLen = getOperand(1)->getLength(op_data[1]- getOperand(1)->getVCIndicatorLength());  
    } 
 
  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;
        }
      lobLen = sourceFileSize;
    }
    else
      lobData = op_data[1];
  long inputSize = lobLen;
  if (fromBuffer())
    {
      memcpy(&lobLen, op_data[2],sizeof(Int64)); // user specified buffer length
      Int64 userBufAddr = 0;
      memcpy(&userBufAddr,op_data[1],sizeof(Int64));
      lobData = (char *)userBufAddr;
    }
 
  inputAddr = lobData ;
 
  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();
      err = insertData(handleLen, handle,inputAddr, chunkMemSize,lobHdfsOffset,h, diagsArea);
      if (err == ex_expr::EXPR_ERROR)  
        {
          if (lobLocking())
            retcode = SQL_EXEC_ReleaseLobLock(llid);
          return err;      
        }
    }
  err = insertDesc(op_data,inputAddr, chunkMemSize,lobHdfsOffset, result,h, diagsArea);
  if (err == ex_expr::EXPR_ERROR)  
    {
      if (lobLocking())
        retcode = SQL_EXEC_ReleaseLobLock(llid);
          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;
        }
    }

  if (lobLocking())
    retcode = SQL_EXEC_ReleaseLobLock(llid);
  return err;
}
////////////////////////////////////////////////////////
// ExpLOBdelete
////////////////////////////////////////////////////////
ExpLOBdelete::ExpLOBdelete(){};
ExpLOBdelete::ExpLOBdelete(OperatorTypeEnum oper_type,
			   Attributes ** attr, 
			   Space * space)
  : ExpLOBiud(oper_type, 2, attr, -1, 0, NULL, space),
    ldFlags_(0)
{
};

void ExpLOBdelete::displayContents(Space * space, const char * displayStr, 
				   Int32 clauseNum, char * constsArea)

{
  ExpLOBoper::displayContents(space, "ExpLOBdelete", clauseNum, constsArea);

}


ex_expr::exp_return_type ExpLOBdelete::eval(char *op_data[],
					    CollHeap*h,
					    ComDiagsArea** diagsArea)
{
  Lng32 rc = 0;

  Lng32 lobOperStatus = checkLobOperStatus();
  if (lobOperStatus == DO_NOTHING_)
    return ex_expr::EXPR_OK;

  char * result = op_data[0];

  Lng32 lobType;
  Int64 uid;
  Lng32 lobNum;
  Int64 descSyskey;
  Int64 descTS = -1;
  extractFromLOBhandle(NULL, &lobType, &lobNum, &uid,
		       &descSyskey, NULL, //descTS, 
		       NULL, NULL,
		       op_data[1]);
  
  Lng32 handleLen = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

  // get the lob name where data need to be deleted
  char lobNameBuf[LOB_NAME_LEN];
  char * lobName = ExpGetLOBname(uid, lobNum, lobNameBuf, LOB_NAME_LEN);
  if (lobName == NULL)
    return ex_expr::EXPR_ERROR;

  Lng32 waitedOp = 0;
  waitedOp = 1;

  Lng32 cliError = 0;

  // call function with the lobname and offset to delete it.
  rc = ExpLOBInterfaceDelete
    (
     getExeGlobals()->getExLobGlobal(),
     (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
     getLobHdfsServer(),
     getLobHdfsPort(),
     lobName, 
     lobStorageLocation(),
     handleLen, op_data[1],
     requestTag_,
     -1,
     descSyskey,
     //     (getExeGlobals()->lobGlobals()->getCurrLobOperInProgress() ? 1 : 0),
     (lobOperStatus == CHECK_STATUS_ ? 1 : 0),
     waitedOp);
  
  if (rc == LOB_ACCESS_PREEMPT)
    {
      return ex_expr::EXPR_PREEMPT;
    }

  if (rc < 0)
    {
      Lng32 intParam1 = -rc;
      ExRaiseSqlError(h, diagsArea, 
		      (ExeErrorCode)(8442), NULL, &intParam1, 
		      &cliError, NULL, (char*)"ExpLOBInterfaceDelete",
		      getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
      return ex_expr::EXPR_ERROR;
    }

  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////
// ExpLOBupdate
////////////////////////////////////////////////////////
ExpLOBupdate::ExpLOBupdate(){};
ExpLOBupdate::ExpLOBupdate(OperatorTypeEnum oper_type,
			   Lng32 numAttrs,
			   Attributes ** attr, 
			   Int64 objectUID,
			   short descSchNameLen,
			   char * descSchName,
			   Space * space)
  : ExpLOBiud(oper_type, numAttrs, attr, objectUID, 
	      descSchNameLen, descSchName, space),
    luFlags_(0),
    nullValue_(0)
{
};

void ExpLOBupdate::displayContents(Space * space, const char * displayStr, 
				   Int32 clauseNum, char * constsArea)

{
  ExpLOBoper::displayContents(space, "ExpLOBupdate", clauseNum, constsArea);

  char buf[100];

  str_sprintf(buf, "    luFlags_ = %d", luFlags_);
  space->allocateAndCopyToAlignedSpace(buf, str_len(buf), sizeof(short));
}

ex_expr::exp_return_type 
ExpLOBupdate::processNulls(char *null_data[], CollHeap *heap,
			   ComDiagsArea **diagsArea
			   )
{
  nullValue_ = 0;

  if ((getOperand(1)->getNullFlag()) &&    // nullable
      (! null_data[1]))                    // missing value 
    {
      ExpTupleDesc::setNullValue( null_data[0],
				  getOperand(0)->getNullBitIndex(),
				  getOperand(0)->getTupleFormat() );

      return ex_expr::EXPR_NULL;
    }
  
  if ((getOperand(2)->getNullFlag()) &&    // nullable
      (! null_data[2]))                    // missing value 
    {
      nullValue_ = 1;
    }

  // move 0 to the null bytes of result
  if (getOperand(0)->getNullFlag())
    {
      ExpTupleDesc::clearNullValue( null_data[0],
                                    getOperand(0)->getNullBitIndex(),
                                    getOperand(0)->getTupleFormat() );
    }

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type ExpLOBupdate::eval(char *op_data[],
					    CollHeap*h,
					    ComDiagsArea** diagsArea)
{
  Lng32 rc, retcode = 0;

  Lng32 lobOperStatus = checkLobOperStatus();
  if (lobOperStatus == DO_NOTHING_)
    return ex_expr::EXPR_OK;

  char * result = op_data[0];
  Int64 lobHdfsOffset = 0;  
  char * lobHandle = NULL;
  Lng32 handleLen = 0;
  char *inputAddr = NULL;
  Int64 lobLen = 0;
  char *lobData = NULL;
  Lng32 sLobType;
  Int64 sUid;
  Lng32 sLobNum;
  Int64 sDescSyskey = -1;
  Int64 sDescTS = -1;
  Int16 sFlags;
  short sSchNameLen = 0;
  char sSchName[500];
  lobLen = getOperand(1)->getLength();
  if(fromString())
    {
      //If source is a varchar, find the actual length
      if (getOperand(1)->getVCIndicatorLength() >0)   
        lobLen = getOperand(1)->getLength(op_data[1]- getOperand(1)->getVCIndicatorLength());  
     
    } 
  if(fromFile())
    {
      
      lobData = new (h) char[lobLen];  
      str_cpy_and_null(lobData,op_data[1],lobLen,'\0',' ',TRUE);
    }
    else
      lobData = op_data[1];
  if (fromBuffer())
    {
      memcpy(&lobLen, op_data[2],sizeof(Int64)); // user specified buffer length
      Int64 userBufAddr = 0;
      memcpy(&userBufAddr,op_data[1],sizeof(Int64));
      lobData = (char *)userBufAddr;
    }
 
  long inputSize = lobLen;
  inputAddr = lobData ;
  if (getOperand(2)->getNullFlag() &&
      nullValue_)
    {
     
     
      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;
      return err;

    }
  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())
        {
          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;
    }
    
  
  // 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;

  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)
          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;
 
   
 
  Int64 lobMaxSize = 0;
  if (getLobSize() > 0)
    {
      lobMaxSize = MINOF(getLobSize(), getLobMaxSize());
    }
  else
    lobMaxSize = getLobMaxSize();
  Lng32 waitedOp = 0;
  waitedOp = 1;

  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;
    }

  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,
	 
	 (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());
    }
   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);
 
   getOperand(0)->setVarLength(handleLen, op_data[-MAX_OPERANDS]);

   return ex_expr::EXPR_OK;
}


////////////////////////////////////////////////////////
// ExpLOBselect
////////////////////////////////////////////////////////
ExpLOBselect::ExpLOBselect(){};
ExpLOBselect::ExpLOBselect(OperatorTypeEnum oper_type,
			   Attributes ** attr, 
			   Space * space)
  : ExpLOBoper(oper_type, 2, attr, space),
    lsFlags_(0)
   
{
  tgtLocation_[0] = 0;
  tgtFile_[0] = 0;
};

void ExpLOBselect::displayContents(Space * space, const char * displayStr, 
				   Int32 clauseNum, char * constsArea)

{
  ExpLOBoper::displayContents(space, "ExpLOBselect", clauseNum, constsArea); 
}


ex_expr::exp_return_type ExpLOBselect::eval(char *op_data[],
					    CollHeap*h,
					    ComDiagsArea** diagsArea)
{
  char * result = op_data[0];
  Lng32 rc = 0;
  Int64 uid;
  Lng32 lobType;
  Lng32 lobNum;
  Int64 descKey;
  Int16 flags;
  Int64 descTS = -1;
  short schNameLen = 0;
  char  schName[500];
  LobsSubOper so;
  Lng32 waitedOp = 0;
  Int64 lobLen = 0; 
  char *lobData = NULL;
  Lng32 cliError = 0;
  Lng32 lobOperStatus = checkLobOperStatus();
  if (lobOperStatus == DO_NOTHING_)
    return ex_expr::EXPR_OK;
  Int32 handleLen = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  char * lobHandle = op_data[1];
  extractFromLOBhandle(&flags, &lobType, &lobNum, &uid,
		       &descKey, &descTS, 
		       &schNameLen, schName,
		       lobHandle);
  // select returns lobhandle only
  str_pad(result, getOperand(0)->getLength());
  str_cpy_all(result, lobHandle, strlen(lobHandle));
  
  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////
// ExpLOBconvert
////////////////////////////////////////////////////////
ExpLOBconvert::ExpLOBconvert(){};
ExpLOBconvert::ExpLOBconvert(OperatorTypeEnum oper_type,
					 Attributes ** attr, 
					 Space * space)
  : ExpLOBoper(oper_type, 2, attr, space),
    lcFlags_(0),
    convertSize_(0)
{
};

void ExpLOBconvert::displayContents(Space * space, const char * displayStr, 
				   Int32 clauseNum, char * constsArea)

{
  ExpLOBoper::displayContents(space, "ExpLOBconvert", clauseNum, constsArea);

}

ex_expr::exp_return_type ExpLOBconvert::eval(char *op_data[],
					     CollHeap*h,
					     ComDiagsArea** diagsArea)
{
  Lng32 rc = 0;

  Lng32 lobOperStatus = checkLobOperStatus();
  if (lobOperStatus == DO_NOTHING_)
    return ex_expr::EXPR_OK;

  char * result = op_data[0];
  char * lobHandle = op_data[1];
  char *tgtFileName = NULL;
  Int32 handleLen = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);

  Int64 uid;
  Lng32 lobType;
  Lng32 lobNum;
  Int64 descKey;
  Int64 descTS;
  Int16 flags;
  short schNameLen = 0;
  char schName[500];
  LobsSubOper so;
  Lng32 cliError = 0;

  Lng32 waitedOp = 0;
  Int64 lobLen = 0; 
  char *lobData = NULL;
  waitedOp = 1;

  extractFromLOBhandle(&flags, &lobType, &lobNum, &uid,
			   &descKey, &descTS, 
			   &schNameLen, schName,
			   lobHandle);
  // get the lob name where data need to be inserted
  char lobNameBuf[LOB_NAME_LEN];
  char * lobName = ExpGetLOBname(uid, lobNum, lobNameBuf, LOB_NAME_LEN);
      
  if (descKey == -1) //This is an empty_blob/clob
    {
      Int32 intParam1 = LOB_DATA_EMPTY_ERROR;
      Int32 cliError = 0;
       ExRaiseSqlError(h, diagsArea, 
			  (ExeErrorCode)(8442), NULL, &intParam1, 
			  &cliError, NULL, (char*)"ExpLOBInterfaceSelect",
		          getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
	  return ex_expr::EXPR_ERROR;
    }
  if(toFile())
    {
      so = Lob_File;
      tgtFileName = tgtFileName_;
      rc = ExpLOBInterfaceSelect(getExeGlobals()->getExLobGlobal(), 
                                 (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
				 lobName, 
				 lobStorageLocation(),
				 lobType,
				 getLobHdfsServer(), getLobHdfsPort(),

				 handleLen, lobHandle,
				 requestTag_,
                                 so,
				 -1,
				 (lobOperStatus == CHECK_STATUS_ ? 1 : 0),
 				 waitedOp,

				 0, lobLen, lobLen, tgtFileName,getLobMaxChunkMemSize());
    }
  else if (toString())
    {
      so = Lob_Memory;
      
      if (lobName == NULL)
	return ex_expr::EXPR_ERROR;
      
      
      lobLen = getConvertSize(); 
      lobData = new(h) char[(Lng32)lobLen];
      rc = ExpLOBInterfaceSelect(getExeGlobals()->getExLobGlobal(), 
                                 (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
				 lobName, 
				 lobStorageLocation(),
				 lobType,
				 getLobHdfsServer(), getLobHdfsPort(),

				 handleLen, lobHandle,
				 requestTag_,
                                 so,
				 -1,
				 (lobOperStatus == CHECK_STATUS_ ? 1 : 0),
 				 waitedOp,

				 0, lobLen, lobLen, lobData,getLobMaxChunkMemSize());

      if (rc == LOB_ACCESS_PREEMPT)
	{
	  return ex_expr::EXPR_PREEMPT;
	}
      
      if (rc < 0)
	{
	  Lng32 intParam1 = -rc;
	  ExRaiseSqlError(h, diagsArea, 
			  (ExeErrorCode)(8442), NULL, &intParam1, 
			  &cliError, NULL, (char*)"ExpLOBInterfaceSelect",
		          getLobErrStr(intParam1), (char*)getSqlJniErrorStr());
	  return ex_expr::EXPR_ERROR;
	}

      // store the length of substring in the varlen indicator.
      if (getOperand(0)->getVCIndicatorLength() > 0)
	{
	  getOperand(0)->setVarLength((UInt32)lobLen, op_data[-MAX_OPERANDS] );
	  if (lobLen > 0) 
	    str_cpy_all(op_data[0], lobData, (Lng32)lobLen);
	}
      else
	{
	  str_pad(result, getOperand(0)->getLength());
	  str_cpy_all(result, lobData, strlen(lobData));
	}
      NADELETEBASIC(lobData, h);
    }
  else
    return ex_expr::EXPR_ERROR;

  return ex_expr::EXPR_OK;
}

////////////////////////////////////////////////////////
// ExpLOBconvertHandle
////////////////////////////////////////////////////////
ExpLOBconvertHandle::ExpLOBconvertHandle(){};
ExpLOBconvertHandle::ExpLOBconvertHandle(OperatorTypeEnum oper_type,
					 Attributes ** attr, 
					 Space * space)
  : ExpLOBoper(oper_type, 2, attr, space),
    lchFlags_(0)
{
};

void ExpLOBconvertHandle::displayContents(Space * space, const char * displayStr, 
				   Int32 clauseNum, char * constsArea)

{
  ExpLOBoper::displayContents(space, "ExpLOBconvertHandle", clauseNum, constsArea);

}


ex_expr::exp_return_type ExpLOBconvertHandle::eval(char *op_data[],
						   CollHeap*,
						   ComDiagsArea** diagsArea)
{
  char * result = op_data[0];
  char * source = op_data[1];

  Lng32 lobType;
  Int64 uid = 0;
  Lng32 lobNum = 0;
  Int64 descPartnKey = 0;
  Int64 descSysKey = 0;
  Int64 descTS = 0;
  Int16 flags = 0;
  Int16 schNameLen = 0;
  char schName[1024];
  long handleLen = 0;
  if (toString())
    {
      extractFromLOBhandle(&flags, &lobType, &lobNum, &uid,
			   &descSysKey, &descTS, 
			   &schNameLen, schName,
			   source);
      
      char lobHandleBuf[LOB_HANDLE_LEN];
      createLOBhandleString(flags, lobType, uid, lobNum, 
			    descSysKey, descTS, 
			    schNameLen, schName,
			    lobHandleBuf);
      
      str_cpy_all(result, lobHandleBuf, strlen(lobHandleBuf));

      getOperand(0)->setVarLength(strlen(lobHandleBuf), op_data[-MAX_OPERANDS]);
    }
  else if (toLob())
    {
       Int64 addrOfLobHandleLen = (Int64)source-sizeof(short) ;  
       Int32 lobHandleLen = *(short *)addrOfLobHandleLen;
      if (strncmp(source,"LOBH",4)== 0)
	{
	  // This is the external string format of the handle

	  extractFromLOBstring(uid, 
			       lobNum, 
			       descPartnKey,
			       descSysKey, 
			       flags,
			       lobType,
			       schNameLen,
			       schName,
			       source, 
			       lobHandleLen);
      
	  Lng32 handleLen = 0;
	  short lobType = 1;
	  genLOBhandle(uid, lobNum, lobType, descPartnKey, descSysKey, flags,
		   schNameLen, schName,
		   handleLen,
		   result);

	  getOperand(0)->setVarLength(handleLen, op_data[-MAX_OPERANDS]);
	}
      else 
	{
	  // Source is pointing to the internal packed format as stored on disk.
	  // Simply cast result to source so it can be interpreted/cast 
	  // as LOBhandle.
	  str_cpy_all(result, source, sizeof(Int64));
	  getOperand(0)->setVarLength(lobHandleLen, op_data[-MAX_OPERANDS]);
	}
    }

  return ex_expr::EXPR_OK;
}


//////////////////////////////////////////////////
// ExpLOBfunction
//////////////////////////////////////////////////
ExpLOBfunction::ExpLOBfunction(){};
ExpLOBfunction::ExpLOBfunction(OperatorTypeEnum oper_type,
			       short num_operands,
			       Attributes ** attr,
			       Space * space)
  : ExpLOBoper(oper_type, num_operands, attr, space),
    funcFlags_(0)
{};


//////////////////////////////////////////////////
// ExpLOBfuncSubstring
//////////////////////////////////////////////////
ExpLOBfuncSubstring::ExpLOBfuncSubstring(){};
ExpLOBfuncSubstring::ExpLOBfuncSubstring(OperatorTypeEnum oper_type,
					 short num_operands,
					 Attributes ** attr,
					 Space * space)
  : ExpLOBfunction(oper_type, num_operands, attr, space)
{};

void ExpLOBfuncSubstring::displayContents(Space * space, const char * displayStr, 
					  Int32 clauseNum, char * constsArea)
  
{
  ex_clause::displayContents(space, "ExpLOBfuncSubstring", clauseNum, constsArea);

}

ex_expr::exp_return_type ExpLOBfuncSubstring::eval(char *op_data[],
						   CollHeap *heap,
						   ComDiagsArea** diagsArea)
{

  Int32 len1_bytes = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]);
  Int32 startPos = *(Lng32 *)op_data[2];
  
  Int32 specifiedLen = len1_bytes;
  if (getNumOperands() == 4)
    specifiedLen = *(Lng32 *)op_data[3]; 

  return ex_expr::EXPR_OK;
}
  
Lng32 LOBsql2loaderInterface
(
 /*IN*/     char * fileName,
 /*IN*/     Lng32  fileNameLen,
 /*IN*/     char * loaderInfo,
 /*IN*/     Lng32  loaderInfoLen,
 /*IN*/     char * handle,
 /*IN*/     Lng32  handleLen,
 /*IN*/     char * lobInfo,
 /*IN*/     Lng32  lobInfoLen
 )
{
  return 0;
}

Will this compile? Looks like a stray line feed got added to the code.