// LCOV_EXCL_START ex_expr::exp_return_type ex_aggregate_clause::eval(char * /*op_data*/[], CollHeap *heap, ComDiagsArea** diagsArea) { ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); return ex_expr::EXPR_ERROR; }
ex_expr::exp_return_type ex_function_substring_doublebyte::eval(char *op_data[], CollHeap* heap, ComDiagsArea** diagsArea) { #pragma nowarn(1506) // warning elimination Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]); #pragma warn(1506) // warning elimination len1 /= sizeof(NAWchar); // len1 now counts in terms of number of NCHARs. // Get the starting position from operand 2. Int64 start = *(Lng32 *)op_data[2]; // If operand 3 exists, get the length of substring from operand 3. // Otherwise, length of the substring is (len1 - start + 1). Int64 len = 0; Int64 temp = 0; if (getNumOperands() == 4) { len = *(Lng32 *)op_data[3]; temp = start + len; } else { if (start > (len1 + 1)) temp = start; else temp = len1 + 1; } // Check for error conditions. if (temp < start) { ExRaiseSqlError(heap, diagsArea, EXE_SUBSTRING_ERROR); return ex_expr::EXPR_ERROR; } Lng32 len0 = 0; if ((start <= len1) && (temp > 0)) { if (start < 1) start = 1; if (temp > (len1 + 1)) temp = len1 + 1; len0 = int64ToInt32(temp - start); } len0 *= sizeof(NAWchar); // convert the length back into the number of octets. // Result is always a varchar, so store the length of substring // in the varlen indicator. getOperand(0)->setVarLength(len0, op_data[-MAX_OPERANDS]); // Now, copy the substring of operand 1 from the starting position into // operand 0, if len0 is greater than 0. if (len0 > 0) str_cpy_all(op_data[0], &op_data[1][sizeof(NAWchar)*(int64ToInt32(start) - 1)], len0); return ex_expr::EXPR_OK; }
// LCOV_EXCL_START ex_expr::exp_return_type ExFunctionMath::evalUnsupportedOperations( char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); return ex_expr::EXPR_ERROR; }
ex_expr::exp_return_type ex_aggr_any_true_max_clause::eval(char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { ex_expr::exp_return_type retcode = ex_expr::EXPR_OK; switch (*(Lng32 *)op_data[1]) { case 1: // operand is TRUE { // return TRUE as result *(Lng32 *)op_data[0] = 1; retcode = ex_expr::EXPR_TRUE; } break; case -1: // operand is NULL { // remember that a null was seen. // LCOV_EXCL_START nullSeen_ = 1; // Genesis 10-040203-2921 // Fix for nested query returning different number of rows with ESP CQD. // The case where all operands are NULL wasnt being handled. When all // the operands are NULL, the result too is NULL. *(Lng32 *) op_data[0] = -1; } break; case 0: // operand is FALSE { if (nullSeen_) *(Lng32 *)op_data[0] = -1; else *(Lng32 *)op_data[0] = 0; retcode = ex_expr::EXPR_TRUE; } break; default: { ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); retcode = ex_expr::EXPR_ERROR; // LCOV_EXCL_STOP } break; } // return code of EXPR_TRUE tells the caller to short circuit // and not process any more rows. return retcode; }
ComDiagsArea *ExRaiseSqlWarning(CollHeap* heap, ex_queue_entry* req, ExeErrorCode code, Lng32 * intParam1, char * stringParam1, ComCondition** cond) { return ExRaiseSqlError(heap, req, (ExeErrorCode)(-code), intParam1, stringParam1, cond); }
ComDiagsArea *ExRaiseSqlError(CollHeap* heap, ex_queue_entry* req, ExeErrorCode err, Lng32 * intParam1, char * stringParam1, ComCondition** newCond) { ComDiagsArea* da = req->getDiagsArea(); if (da == NULL) da = ComDiagsArea::allocate(heap); else da = da->copy(); return ExRaiseSqlError(heap, &da, (ExeErrorCode)(-err), newCond, intParam1, NULL, NULL, stringParam1); }
short ExExeUtilHiveQueryTcb::work() { short rc = 0; Lng32 cliRC = 0; if (qparent_.down->isEmpty()) return WORK_OK; if (qparent_.up->isFull()) return WORK_OK; ex_queue_entry * pentry_down = qparent_.down->getHeadEntry(); ExExeUtilPrivateState & pstate = *((ExExeUtilPrivateState*) pentry_down->pstate); while (1) { switch (step_) { case INITIAL_: { step_ = PROCESS_QUERY_; } break; case PROCESS_QUERY_: { if (HiveClient_JNI::executeHiveSQL(htTdb().getHiveQuery()) != HVC_OK) { ExRaiseSqlError(getHeap(), &diagsArea_, -1214, NULL, NULL, NULL, getSqlJniErrorStr(), htTdb().getHiveQuery()); step_ = ERROR_; break; } step_ = DONE_; } break; case ERROR_: { if (handleError()) return WORK_OK; step_ = DONE_; } break; case DONE_: { if (handleDone()) return WORK_OK; step_ = INITIAL_; return WORK_OK; } break; } // switch } // while }
void ExHdfsFastExtractTcb::createSequenceFileError(Int32 sfwRetCode) { ContextCli *currContext = GetCliGlobals()->currContext(); ComDiagsArea * diagsArea = NULL; char* errorMsg = sequenceFileWriter_->getErrorText((SFW_RetCode)sfwRetCode); ExRaiseSqlError(getHeap(), &diagsArea, (ExeErrorCode)(8447), NULL, NULL, NULL, NULL, errorMsg, (char *)currContext->getJniErrorStr().data()); //ex_queue_entry *pentry_down = qParent_.down->getHeadEntry(); //pentry_down->setDiagsArea(diagsArea); updateWorkATPDiagsArea(diagsArea); }
ComDiagsArea *ExRaiseFunctionSqlError(CollHeap* heap, ComDiagsArea** diagsArea, ExeErrorCode err, NABoolean derivedFunction, OperatorTypeEnum origOperType, ComCondition** cond) { ExRaiseSqlError(heap, diagsArea, err); if (derivedFunction) { **diagsArea << DgSqlCode(-EXE_MAPPED_FUNCTION_ERROR); **diagsArea << DgString0(exClauseGetText(origOperType)); } return *diagsArea; }
ex_expr::exp_return_type ex_aggr_one_row_clause::eval(char * /*op_data*/ [], CollHeap *heap, ComDiagsArea** diagsArea) { ex_expr::exp_return_type retcode = ex_expr::EXPR_OK; // if oneRowProcessed_ is > 0, return error. if (oneRowProcessed_) { ExRaiseSqlError(heap, diagsArea, EXE_CARDINALITY_VIOLATION); retcode = ex_expr::EXPR_ERROR; } else { oneRowProcessed_ = 1; } return retcode; }
ex_expr::exp_return_type ex_function_abs::eval(char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { ex_expr::exp_return_type retcode = ex_expr::EXPR_OK; switch (getOperand(1)->getDatatype()) { case REC_BIN8_SIGNED: *(Int8 *)op_data[0] = (*(Int8 *)op_data[1] < 0 ? -*(Int8 *)op_data[1] : *(Int8 *)op_data[1]); break; case REC_BIN16_SIGNED: #pragma nowarn(1506) // warning elimination *(short *)op_data[0] = (*(short *)op_data[1] < 0 ? -*(short *)op_data[1] : *(short *)op_data[1]); #pragma warn(1506) // warning elimination break; case REC_BIN32_SIGNED: *(Lng32 *)op_data[0] = labs(*(Lng32 *)op_data[1]); break; case REC_BIN64_SIGNED: *(Int64 *)op_data[0] = (*(Int64 *)op_data[1] < 0 ? -*(Int64 *)op_data[1] : *(Int64 *)op_data[1]); break; case REC_FLOAT64: *(double *)op_data[0] = fabs(*(double *)op_data[1]); break; default: ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); retcode = ex_expr::EXPR_ERROR; break; // LCOV_EXCL_STOP } return retcode; }
//Detailed error support for conversions, especially for use in convdoit. ComDiagsArea *ExRaiseDetailSqlError(CollHeap* heap, ComDiagsArea** diagsArea, ExeErrorCode err, char *src, Int32 srcLength, Int16 srcType, Int32 srcScale, Int16 tgtType, UInt32 flags, Int32 tgtLength, Int32 tgtScale, Int32 tgtPrecision, Int32 srcPrecision) { //if looping situation, no need to proceed further, return back. if(flags & CONV_CONTROL_LOOPING) return NULL; NABoolean intermediate; if( flags & CONV_INTERMEDIATE_CONVERSION ) intermediate = TRUE; else intermediate = FALSE; if (diagsArea == NULL) return NULL; if (*diagsArea == NULL){ if (heap == NULL) return NULL; *diagsArea = ComDiagsArea::allocate(heap); } //Allocate buf once, for formatting and opstring[1]. // |--------formatting--------|--opstring[1]------| char *buf = new (heap) char[FORMATTING+ OPVALUE_LEN] ; if( !buf ){ ExRaiseSqlError(heap, diagsArea, err); return *diagsArea; } char *opString = &buf[FORMATTING]; ExConvertErrorToString(heap, diagsArea, src, srcLength, srcType, srcScale, opString, OPVALUE_LEN); char srcDatatypeDetail[200]; char tgtDatatypeDetail[200]; char srcTypeAsText[1000]; char tgtTypeAsText[100]; srcTypeAsText[0] = 0; tgtTypeAsText[0] = 0; if (srcPrecision != -1) { rec_datetime_field startField; rec_datetime_field endField; ExpDatetime::getDatetimeFields(srcPrecision, startField, endField); convertTypeToText_basic(srcTypeAsText, srcType, srcLength, srcPrecision, srcScale, startField, endField, 0, 0, 0, 0, (CharInfo::CharSet)srcScale, NULL, NULL, 0); strcpy(srcDatatypeDetail, getDatatypeAsString(srcType, false)); } else if ((DFS2REC::isCharacterString(srcType)) && (srcLength >= 0) && (srcScale > 0) && (srcPrecision == -1)) str_sprintf(srcDatatypeDetail, "%s,%d BYTES,%s", getDatatypeAsString(srcType, false), srcLength, (srcScale == CharInfo::ISO88591 ? "ISO88591" : "UTF8")); else strcpy(srcDatatypeDetail, getDatatypeAsString(srcType, false)); if (tgtLength != -1) { rec_datetime_field startField; rec_datetime_field endField; ExpDatetime::getDatetimeFields(tgtPrecision, startField, endField); convertTypeToText_basic(tgtTypeAsText, tgtType, tgtLength, tgtPrecision, tgtScale, startField, endField, 0, 0, 0, 0, (CharInfo::CharSet)tgtScale, NULL, NULL, 0); strcpy(tgtDatatypeDetail, getDatatypeAsString(tgtType, false)); } else if ((DFS2REC::isCharacterString(tgtType)) && (tgtLength >= 0) && (tgtScale > 0)) str_sprintf(tgtDatatypeDetail, "%s,%d %s,%s", getDatatypeAsString(tgtType, false), tgtPrecision ? tgtPrecision : tgtLength, tgtPrecision ? "CHARS" : "BYTES", (tgtScale == CharInfo::ISO88591 ? "ISO88591" : "UTF8")); else strcpy(tgtDatatypeDetail, getDatatypeAsString(tgtType, false)); str_sprintf(buf, " %s of Source Type:%s(%s) Source Value:%s to Target Type:%s(%s).", intermediate? "Intermediate conversion" : "Conversion", (strlen(srcTypeAsText) == 0 ? getDatatypeAsString(srcType,true) : srcTypeAsText), srcDatatypeDetail, opString, (strlen(tgtTypeAsText) == 0 ? getDatatypeAsString(tgtType,true) : tgtTypeAsText), tgtDatatypeDetail); **diagsArea << DgSqlCode(-err); **diagsArea<<DgString0(buf); NADELETEBASICARRAY(buf, (heap)); return *diagsArea; }
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[100]; char * lobName = ExpGetLOBname(uid, lobNum, lobNameBuf, 100); if (lobName == NULL) return ex_expr::EXPR_ERROR; Lng32 waitedOp = 0; #ifdef __EID waitedOp = 0; // nowaited op from EID/TSE process #else waitedOp = 1; #endif //temptemp. Remove after ExLobsOper adds nowaited support. waitedOp = 1; Lng32 cliError = 0; // call function with the lobname and offset to delete it. rc = ExpLOBInterfaceDelete (getExeGlobals()->lobGlobal(), getLobHdfsServer(), getLobHdfsPort(), lobName, lobStorageLocation(), handleLen, op_data[1], requestTag_, getExeGlobals()->lobGlobals()->xnId(), 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)); return ex_expr::EXPR_ERROR; } return ex_expr::EXPR_OK; }
//Detailed error support for pcode expression evaluation. ComDiagsArea *ExRaiseDetailSqlError(CollHeap* heap, ComDiagsArea** diagsArea, ExeErrorCode err, Int32 pciInst, char *op1, char *op2, char *op3) { if (diagsArea == NULL) return NULL; if (*diagsArea == NULL){ if (heap == NULL) return NULL; *diagsArea = ComDiagsArea::allocate(heap); } PCIT::Operation operation; PCIT::AddressingMode am[6]; Int32 numAModes; Int32 rangeInst = PCode::isInstructionRangeType((PCIT::Instruction)pciInst)? 1: 0; if(PCode::getOpCodeMapElements( pciInst, operation, am, numAModes ) ){ ExRaiseSqlError(heap, diagsArea, err); return *diagsArea; } // Single allocation of buf is split up to be used for opstrings, // formatting. See defines at beginning of this header file // for details. char *buf = new (heap) char[(numAModes * (VALUE_TYPE_LEN + OPVALUE_LEN)) + INSTR_LEN + FORMATTING]; if( !buf ){ ExRaiseSqlError(heap, diagsArea, err); return *diagsArea; } char *opStrings = &buf[(numAModes * VALUE_TYPE_LEN) + INSTR_LEN ]; char *buf1 = // assign FORMATTING part of address. &buf[(numAModes * (VALUE_TYPE_LEN + OPVALUE_LEN)) + INSTR_LEN]; switch( numAModes ){ case 1: ExConvertErrorToString(heap, diagsArea, op1, PCIT::getOperandLengthForAddressingMode(am[0]), PCIT::getDataTypeForMemoryAddressingMode(am[0]), 0, (char*)&opStrings[0], OPVALUE_LEN); //construct a formated string and assign to diags area **diagsArea << DgSqlCode(-err); if(rangeInst){ str_sprintf( buf, " Source Value:%s not within limits of Target Type:%s(%s).", &opStrings[0], getDatatypeAsString(PCIT::getDataTypeForMemoryAddressingMode(am[0]),true), PCIT::addressingModeString(am[0])); } else{ str_sprintf( buf, " Operand Type:%s(%s) Operand Value:%s.", getDatatypeAsString(PCIT::getDataTypeForMemoryAddressingMode(am[0]),true), PCIT::addressingModeString(am[0]), &opStrings[0]); } str_sprintf( buf1, " Instruction:%s Operation:%s.", PCIT::instructionString((PCIT::Instruction)pciInst), PCIT::operationString(operation)); str_cat(buf, buf1, buf); **diagsArea<<DgString0(buf); break; case 3: case 4: //since we are only interested in left and right operands, just overright //am modes to be processed by case 2 below. am[0] = am[1]; am[1] = am[2]; //do not break here. Flow down to case 2. case 2: ExConvertErrorToString(heap, diagsArea, op1, PCIT::getOperandLengthForAddressingMode(am[0]), PCIT::getDataTypeForMemoryAddressingMode(am[0]), 0, (char*)&opStrings[0], OPVALUE_LEN); ExConvertErrorToString(heap, diagsArea, op2, PCIT::getOperandLengthForAddressingMode(am[1]), PCIT::getDataTypeForMemoryAddressingMode(am[1]), 0, (char*)&opStrings[OPVALUE_LEN], OPVALUE_LEN); //construct a formated string and assign to diags area **diagsArea << DgSqlCode(-err); str_sprintf( buf, " %s Type:%s(%s) %s Value:%s", rangeInst? "Source":"Operand1", getDatatypeAsString(PCIT::getDataTypeForMemoryAddressingMode(am[0]),true), PCIT::addressingModeString(am[0]), rangeInst? "Source":"Operand1", &opStrings[0]); str_sprintf( buf1, " %s Type:%s(%s)%s%s Value:%s.", rangeInst? "Target":"Operand2", getDatatypeAsString(PCIT::getDataTypeForMemoryAddressingMode(am[1]),true), PCIT::addressingModeString(am[1]), rangeInst? (opStrings[OPVALUE_LEN] == '-' ? " Min ": " Max "):" ", rangeInst? "Target":"Operand2", &opStrings[OPVALUE_LEN]); str_cat(buf, buf1, buf); str_sprintf( buf1, " Instruction:%s Operation:%s.", PCIT::instructionString((PCIT::Instruction)pciInst), PCIT::operationString(operation)); str_cat(buf, buf1, buf); **diagsArea<<DgString0(buf); break; //Needs to be enhanced for other types. Just dump what ever we have. default: ExRaiseSqlError(heap, diagsArea, err); }; NADELETEBASICARRAY(buf, (heap)); return *diagsArea; }
//Detailed error support for clause expression evaluation. ComDiagsArea *ExRaiseDetailSqlError(CollHeap* heap, ComDiagsArea** diagsArea, ExeErrorCode err, ex_clause *clause, char *op_data[]) { if (diagsArea == NULL) return NULL; if (*diagsArea == NULL){ if (heap == NULL) return NULL; *diagsArea = ComDiagsArea::allocate(heap); } Int16 numOperands = clause->getNumOperands(); Attributes *op; Int16 i; // Single allocation of buf is split up to be used for opstrings, // formatting. See defines at beginning of this header file // for details. char *buf = new (heap) char[(numOperands * (VALUE_TYPE_LEN + OPVALUE_LEN)) + INSTR_LEN + FORMATTING]; if( !buf ){ ExRaiseSqlError(heap, diagsArea, err); return *diagsArea; } char *opStrings = &buf[(numOperands * VALUE_TYPE_LEN) + INSTR_LEN ]; // assign FORMATTING part of address. char *buf1 = &buf[(numOperands * (VALUE_TYPE_LEN + OPVALUE_LEN)) + INSTR_LEN]; for (i = 1; i < numOperands; i++){ op = clause->getOperand(i); ExConvertErrorToString(heap, diagsArea, (char*)op_data[i], op->getLength(), op->getDatatype(), op->getScale(), (char*)&opStrings[(i-1)*OPVALUE_LEN], OPVALUE_LEN); } //initialize buf before entering the loop. buf[0] = '\0'; for(i = 1; i< numOperands; i++){ op = clause->getOperand(i); str_sprintf(buf1, " Operand%d Type:%s(%s) Operand%d Value:%s",i, getDatatypeAsString(op->getDatatype(), true), getDatatypeAsString(op->getDatatype(), false), i, &opStrings[(i-1)*OPVALUE_LEN]); str_cat(buf, buf1, buf); } if(numOperands) { str_sprintf(buf1,"."); str_cat(buf, buf1, buf); } str_sprintf(buf1, " Clause Type:%d Clause number:%d Operation:%s.", clause->getType(), clause->clauseNum(), exClauseGetText(clause->getOperType())); str_cat(buf, buf1, buf); **diagsArea << DgSqlCode(-err); **diagsArea<<DgString0(buf); NADELETEBASICARRAY(buf, (heap)); return *diagsArea; }
ExWorkProcRetcode ExHdfsFastExtractTcb::work() { #ifdef __EID // This class should not be instantiated in EID. return WORK_BAD_ERROR; #else Lng32 retcode = 0; SFW_RetCode sfwRetCode = SFW_OK; ULng32 recSepLen = strlen(myTdb().getRecordSeparator()); ULng32 delimLen = strlen(myTdb().getDelimiter()); ULng32 nullLen = (myTdb().getNullString() ? strlen(myTdb().getNullString()) : 0); if (myTdb().getIsHiveInsert()) { recSepLen = 1; delimLen = 1; } if (getEmptyNullString()) //covers hive null case also nullLen = 0; ExOperStats *stats = NULL; ExFastExtractStats *feStats = getFastExtractStats(); while (TRUE) { // if no parent request, return if (qParent_.down->isEmpty()) return WORK_OK; ex_queue_entry *pentry_down = qParent_.down->getHeadEntry(); const ex_queue::down_request request = pentry_down->downState.request; const Lng32 value = pentry_down->downState.requestValue; ExFastExtractPrivateState &pstate = *((ExFastExtractPrivateState *) pentry_down->pstate); switch (pstate.step_) { case EXTRACT_NOT_STARTED: { pstate.step_= EXTRACT_CHECK_MOD_TS; } break; case EXTRACT_CHECK_MOD_TS: { if ((! myTdb().getTargetFile()) || (myTdb().getModTSforDir() == -1)) { pstate.step_ = EXTRACT_INITIALIZE; break; } numBuffers_ = 0; memset (hdfsHost_, '\0', sizeof(hdfsHost_)); strncpy(hdfsHost_, myTdb().getHdfsHostName(), sizeof(hdfsHost_)); hdfsPort_ = myTdb().getHdfsPortNum(); memset (fileName_, '\0', sizeof(fileName_)); memset (targetLocation_, '\0', sizeof(targetLocation_)); snprintf(targetLocation_,999, "%s", myTdb().getTargetName()); retcode = lobInterfaceDataModCheck(); if (retcode < 0) { Lng32 cliError = 0; Lng32 intParam1 = -retcode; ComDiagsArea * diagsArea = NULL; ExRaiseSqlError(getHeap(), &diagsArea, (ExeErrorCode)(EXE_ERROR_FROM_LOB_INTERFACE), NULL, &intParam1, &cliError, NULL, "HDFS", (char*)"ExpLOBInterfaceDataModCheck", getLobErrStr(intParam1)); pentry_down->setDiagsArea(diagsArea); pstate.step_ = EXTRACT_ERROR; break; } if (retcode == 1) // check failed { ComDiagsArea * diagsArea = NULL; ExRaiseSqlError(getHeap(), &diagsArea, (ExeErrorCode)(EXE_HIVE_DATA_MOD_CHECK_ERROR)); pentry_down->setDiagsArea(diagsArea); pstate.step_ = EXTRACT_ERROR; break; } pstate.step_= EXTRACT_INITIALIZE; } break; case EXTRACT_INITIALIZE: { pstate.processingStarted_ = FALSE; errorOccurred_ = FALSE; //Allocate writeBuffers. numBuffers_ = 1; for (Int16 i = 0; i < numBuffers_; i++) { bool done = false; Int64 input_datalen = myTdb().getHdfsIoBufferSize(); char * buf_addr = 0; while ((!done) && input_datalen >= 32 * 1024) { buf_addr = 0; buf_addr = (char *)((NAHeap *)heap_)->allocateAlignedHeapMemory((UInt32)input_datalen, 512, FALSE); if (buf_addr) { done = true; bufferPool_[i] = new (heap_) IOBuffer((char*) buf_addr, (Int32)input_datalen); } else { bufferAllocFailuresCount_++; input_datalen = input_datalen / 2; } } if (!done) { numBuffers_ = i; break ; // if too few buffers have been allocated we will raise } // an error later } if (feStats) { feStats->setBufferAllocFailuresCount(bufferAllocFailuresCount_); feStats->setBuffersCount(numBuffers_); } ComDiagsArea *da = NULL; if (!myTdb().getSkipWritingToFiles()) if (myTdb().getTargetFile() ) { Lng32 fileNum = getGlobals()->castToExExeStmtGlobals()->getMyInstanceNumber(); memset (hdfsHost_, '\0', sizeof(hdfsHost_)); strncpy(hdfsHost_, myTdb().getHdfsHostName(), sizeof(hdfsHost_)); hdfsPort_ = myTdb().getHdfsPortNum(); memset (fileName_, '\0', sizeof(fileName_)); memset (targetLocation_, '\0', sizeof(targetLocation_)); time_t t; time(&t); char pt[30]; struct tm * curgmtime = gmtime(&t); strftime(pt, 30, "%Y%m%d%H%M%S", curgmtime); srand(getpid()); snprintf(targetLocation_,999, "%s", myTdb().getTargetName()); if (myTdb().getIsHiveInsert()) snprintf(fileName_,999, "%s%d-%s-%d", myTdb().getHiveTableName(), fileNum, pt,rand() % 1000); else snprintf(fileName_,999, "%s%d-%s-%d", "file", fileNum, pt,rand() % 1000); if ((isSequenceFile() || myTdb().getBypassLibhdfs()) && !sequenceFileWriter_) { sequenceFileWriter_ = new(getHeap()) SequenceFileWriter((NAHeap *)getHeap()); sfwRetCode = sequenceFileWriter_->init(); if (sfwRetCode != SFW_OK) { createSequenceFileError(sfwRetCode); pstate.step_ = EXTRACT_ERROR; break; } } if (isSequenceFile() || myTdb().getBypassLibhdfs()) { strcat(targetLocation_, "//"); strcat(targetLocation_, fileName_); if (isSequenceFile()) sfwRetCode = sequenceFileWriter_->open(targetLocation_, SFW_COMP_NONE); else sfwRetCode = sequenceFileWriter_->hdfsCreate(targetLocation_, isHdfsCompressed()); if (sfwRetCode != SFW_OK) { createSequenceFileError(sfwRetCode); pstate.step_ = EXTRACT_ERROR; break; } } else { retcode = 0; retcode = lobInterfaceCreate(); if (retcode < 0) { Lng32 cliError = 0; Lng32 intParam1 = -retcode; ComDiagsArea * diagsArea = NULL; ExRaiseSqlError(getHeap(), &diagsArea, (ExeErrorCode)(8442), NULL, &intParam1, &cliError, NULL, (char*)"ExpLOBinterfaceCreate", getLobErrStr(intParam1)); pentry_down->setDiagsArea(diagsArea); pstate.step_ = EXTRACT_ERROR; break; } } if (feStats) { feStats->setPartitionNumber(fileNum); } } else { updateWorkATPDiagsArea(__FILE__,__LINE__,"sockets are not supported"); pstate.step_ = EXTRACT_ERROR; break; } for (UInt32 i = 0; i < myTdb().getChildTuple()->numAttrs(); i++) { Attributes * attr = myTdb().getChildTableAttr(i); Attributes * attr2 = myTdb().getChildTableAttr2(i); ex_conv_clause tempClause; int convIndex = 0; sourceFieldsConvIndex_[i] = tempClause.find_case_index( attr->getDatatype(), 0, attr2->getDatatype(), 0, 0); } pstate.step_= EXTRACT_PASS_REQUEST_TO_CHILD; } break; case EXTRACT_PASS_REQUEST_TO_CHILD: { // pass the parent request to the child downqueue if (!qChild_.down->isFull()) { ex_queue_entry * centry = qChild_.down->getTailEntry(); if (request == ex_queue::GET_N) centry->downState.request = ex_queue::GET_ALL; else centry->downState.request = request; centry->downState.requestValue = pentry_down->downState.requestValue; centry->downState.parentIndex = qParent_.down->getHeadIndex(); // set the child's input atp centry->passAtp(pentry_down->getAtp()); qChild_.down->insert(); pstate.processingStarted_ = TRUE; } else // couldn't pass request to child, return return WORK_OK; pstate.step_ = EXTRACT_RETURN_ROWS_FROM_CHILD; } break; case EXTRACT_RETURN_ROWS_FROM_CHILD: { if ((qChild_.up->isEmpty())) { return WORK_OK; } if (currBuffer_ == NULL) { currBuffer_ = bufferPool_[0]; memset(currBuffer_->data_, '\0',currBuffer_->bufSize_); currBuffer_->bytesLeft_ = currBuffer_->bufSize_; } ex_queue_entry * centry = qChild_.up->getHeadEntry(); ComDiagsArea *cda = NULL; ex_queue::up_status child_status = centry->upState.status; switch (child_status) { case ex_queue::Q_OK_MMORE: { // for the very first row retruned from child // include the header row if necessary if ((pstate.matchCount_ == 0) && myTdb().getIncludeHeader()) { if (!myTdb().getIsAppend()) { Int32 headerLength = strlen(myTdb().getHeader()); char * target = currBuffer_->data_; if (headerLength + 1 < currBuffer_->bufSize_) { strncpy(target, myTdb().getHeader(),headerLength); target[headerLength] = '\n' ; currBuffer_->bytesLeft_ -= headerLength+1 ; } else { updateWorkATPDiagsArea(__FILE__,__LINE__,"header does not fit in buffer"); pstate.step_ = EXTRACT_ERROR; break; } } } tupp_descriptor *dataDesc = childOutputTD_; ex_expr::exp_return_type expStatus = ex_expr::EXPR_OK; if (myTdb().getChildDataExpr()) { UInt32 childTuppIndex = myTdb().childDataTuppIndex_; workAtp_->getTupp(childTuppIndex) = dataDesc; // Evaluate the child data expression. If diags are generated they // will be left in the down entry ATP. expStatus = myTdb().getChildDataExpr()->eval(centry->getAtp(), workAtp_); workAtp_->getTupp(childTuppIndex).release(); if (expStatus == ex_expr::EXPR_ERROR) { updateWorkATPDiagsArea(centry); pstate.step_ = EXTRACT_ERROR; break; } } // if (myTdb().getChildDataExpr()) /////////////////////// char * targetData = currBuffer_->data_ + currBuffer_->bufSize_ - currBuffer_->bytesLeft_; if (targetData == NULL) { updateWorkATPDiagsArea(__FILE__,__LINE__,"targetData is NULL"); pstate.step_ = EXTRACT_ERROR; break; } NABoolean convError = FALSE; convertSQRowToString(nullLen, recSepLen, delimLen, dataDesc, targetData, convError); /////////////////////////////// pstate.matchCount_++; if (!convError) { if (feStats) { feStats->incProcessedRowsCount(); } pstate.successRowCount_ ++; } else { if (feStats) { feStats->incErrorRowsCount(); } pstate.errorRowCount_ ++; } if (currBuffer_->bytesLeft_ < (Int32) maxExtractRowLength_) { pstate.step_ = EXTRACT_DATA_READY_TO_SEND; } } break; case ex_queue::Q_NO_DATA: { pstate.step_ = EXTRACT_DATA_READY_TO_SEND; endOfData_ = TRUE; pstate.processingStarted_ = FALSE ; // so that cancel does not //wait for this Q_NO_DATA } break; case ex_queue::Q_SQLERROR: { pstate.step_ = EXTRACT_ERROR; } break; case ex_queue::Q_INVALID: { updateWorkATPDiagsArea(__FILE__,__LINE__, "ExFastExtractTcb::work() Invalid state returned by child"); pstate.step_ = EXTRACT_ERROR; } break; } // switch qChild_.up->removeHead(); } break; case EXTRACT_DATA_READY_TO_SEND: { ssize_t bytesToWrite = currBuffer_->bufSize_ - currBuffer_->bytesLeft_; if (!myTdb().getSkipWritingToFiles()) if (isSequenceFile()) { sfwRetCode = sequenceFileWriter_->writeBuffer(currBuffer_->data_, bytesToWrite, myTdb().getRecordSeparator()); if (sfwRetCode != SFW_OK) { createSequenceFileError(sfwRetCode); pstate.step_ = EXTRACT_ERROR; break; } } else if (myTdb().getBypassLibhdfs()) { sfwRetCode = sequenceFileWriter_->hdfsWrite(currBuffer_->data_, bytesToWrite); if (sfwRetCode != SFW_OK) { createSequenceFileError(sfwRetCode); pstate.step_ = EXTRACT_ERROR; break; } } else { retcode = 0; retcode = lobInterfaceInsert(bytesToWrite); if (retcode < 0) { Lng32 cliError = 0; Lng32 intParam1 = -retcode; ComDiagsArea * diagsArea = NULL; ExRaiseSqlError(getHeap(), &diagsArea, (ExeErrorCode)(8442), NULL, &intParam1, &cliError, NULL, (char*)"ExpLOBInterfaceInsert", getLobErrStr(intParam1)); pentry_down->setDiagsArea(diagsArea); pstate.step_ = EXTRACT_ERROR; break; } } if (feStats) { feStats->incReadyToSendBuffersCount(); feStats->incReadyToSendBytes(currBuffer_->bufSize_ - currBuffer_->bytesLeft_); } currBuffer_ = NULL; if (endOfData_) { pstate.step_ = EXTRACT_DONE; } else { pstate.step_ = EXTRACT_RETURN_ROWS_FROM_CHILD; } } break; case EXTRACT_ERROR: { // If there is no room in the parent queue for the reply, // try again later. //Later we may split this state into 2 one for cancel and one for query if (qParent_.up->isFull()) return WORK_OK; // Cancel the child request - there must be a child request in // progress to get to the ERROR state. if (pstate.processingStarted_) { qChild_.down->cancelRequestWithParentIndex(qParent_.down->getHeadIndex()); //pstate.processingStarted_ = FALSE; } while (pstate.processingStarted_ && pstate.step_ == EXTRACT_ERROR) { if (qChild_.up->isEmpty()) return WORK_OK; ex_queue_entry * childEntry = qChild_.up->getHeadEntry(); ex_queue::up_status childStatus = childEntry->upState.status; if (childStatus == ex_queue::Q_NO_DATA) { pstate.step_ = EXTRACT_DONE; pstate.processingStarted_ = FALSE; } qChild_.up->removeHead(); } ex_queue_entry *pentry_up = qParent_.up->getTailEntry(); pentry_up->copyAtp(pentry_down); // Construct and return the error row. // if (workAtp_->getDiagsArea()) { ComDiagsArea *diagsArea = pentry_up->getDiagsArea(); if (diagsArea == NULL) { diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); pentry_up->setDiagsArea(diagsArea); } pentry_up->getDiagsArea()->mergeAfter(*workAtp_->getDiagsArea()); workAtp_->setDiagsArea(NULL); } pentry_up->upState.status = ex_queue::Q_SQLERROR; pentry_up->upState.parentIndex = pentry_down->downState.parentIndex; pentry_up->upState.downIndex = qParent_.down->getHeadIndex(); pentry_up->upState.setMatchNo(pstate.matchCount_); qParent_.up->insert(); // errorOccurred_ = TRUE; pstate.step_ = EXTRACT_DONE; } break; case EXTRACT_DONE: { // If there is no room in the parent queue for the reply, // try again later. // if (qParent_.up->isFull()) return WORK_OK; if (!myTdb().getSkipWritingToFiles()) if (isSequenceFile()) { sfwRetCode = sequenceFileWriter_->close(); if (!errorOccurred_ && sfwRetCode != SFW_OK ) { createSequenceFileError(sfwRetCode); pstate.step_ = EXTRACT_ERROR; break; } } else if (myTdb().getBypassLibhdfs()) { if (sequenceFileWriter_) { sfwRetCode = sequenceFileWriter_->hdfsClose(); if (!errorOccurred_ && sfwRetCode != SFW_OK ) { createSequenceFileError(sfwRetCode); pstate.step_ = EXTRACT_ERROR; break; } } } else { retcode = lobInterfaceClose(); if (! errorOccurred_ && retcode < 0) { Lng32 cliError = 0; Lng32 intParam1 = -retcode; ComDiagsArea * diagsArea = NULL; ExRaiseSqlError(getHeap(), &diagsArea, (ExeErrorCode)(8442), NULL, &intParam1, &cliError, NULL, (char*)"ExpLOBinterfaceCloseFile", getLobErrStr(intParam1)); pentry_down->setDiagsArea(diagsArea); pstate.step_ = EXTRACT_ERROR; break; } } //insertUpQueueEntry will insert Q_NO_DATA into the up queue and //remove the head of the down queue insertUpQueueEntry(ex_queue::Q_NO_DATA, NULL, TRUE); errorOccurred_ = FALSE; endOfData_ = FALSE; //we need to set the next state so that the query can get re-executed //and we start from the beginning again. Not sure if pstate will be //valid anymore because insertUpQueueEntry() might have cleared it //already. pstate.step_ = EXTRACT_NOT_STARTED; //exit out now and not break. return WORK_OK; } break; default: { ex_assert(FALSE, "Invalid state in ExHdfsFastExtractTcb "); } break; } // switch(pstate.step_) } // while return WORK_OK; #endif }//ExHdfsFastExtractTcb::work()
ex_expr::exp_return_type ex_function_abs::eval(char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { ex_expr::exp_return_type retcode = ex_expr::EXPR_OK; switch (getOperand(1)->getDatatype()) { case REC_BIN16_SIGNED: #pragma nowarn(1506) // warning elimination *(short *)op_data[0] = (*(short *)op_data[1] < 0 ? -*(short *)op_data[1] : *(short *)op_data[1]); #pragma warn(1506) // warning elimination break; case REC_BIN32_SIGNED: *(Lng32 *)op_data[0] = labs(*(Lng32 *)op_data[1]); break; case REC_BIN64_SIGNED: *(Int64 *)op_data[0] = (*(Int64 *)op_data[1] < 0 ? -*(Int64 *)op_data[1] : *(Int64 *)op_data[1]); break; case REC_FLOAT64: *(double *)op_data[0] = fabs(*(double *)op_data[1]); break; case REC_TDM_FLOAT64: { // convert tdm float to ieee float, do the abs and // convert result back from ieee to tdm float. double op1Double; // LCOV_EXCL_START if (convDoIt(op_data[1], getOperand(1)->getLength(), getOperand(1)->getDatatype(), getOperand(1)->getPrecision(), getOperand(1)->getScale(), (char*)&op1Double, (Lng32)sizeof(double), REC_FLOAT64, 0, 0, NULL, 0, heap, diagsArea, CONV_UNKNOWN) != ex_expr::EXPR_OK) return ex_expr::EXPR_ERROR; if (op1Double < 0) op1Double = -op1Double; // convert to result type. if (convDoIt((char*)&op1Double, (Lng32)sizeof(double), REC_FLOAT64, 0, 0, op_data[0], getOperand(0)->getLength(), getOperand(0)->getDatatype(), getOperand(0)->getPrecision(), getOperand(0)->getScale(), NULL, 0, heap, diagsArea, CONV_UNKNOWN) != ex_expr::EXPR_OK) return ex_expr::EXPR_ERROR; } break; default: ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); retcode = ex_expr::EXPR_ERROR; break; // LCOV_EXCL_STOP } return retcode; }
ex_expr::exp_return_type ExFunctionBitOper::eval(char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { ex_expr::exp_return_type retcode = ex_expr::EXPR_OK; switch (getOperType()) { case ITM_BITAND: { // LCOV_EXCL_START if (getOperand(0)->getDatatype() == REC_BIN32_UNSIGNED) *(UInt32 *)op_data[0] = *(UInt32 *)op_data[1] & *(UInt32 *)op_data[2]; else if (getOperand(0)->getDatatype() == REC_BIN32_SIGNED) *(Int32 *)op_data[0] = *(Int32 *)op_data[1] & *(Int32 *)op_data[2]; else *(Int64 *)op_data[0] = *(Int64 *)op_data[1] & *(Int64 *)op_data[2]; } break; case ITM_BITOR: { if (getOperand(0)->getDatatype() == REC_BIN32_UNSIGNED) *(UInt32 *)op_data[0] = *(UInt32 *)op_data[1] | *(UInt32 *)op_data[2]; else if (getOperand(0)->getDatatype() == REC_BIN32_SIGNED) *(Int32 *)op_data[0] = *(Int32 *)op_data[1] | *(Int32 *)op_data[2]; else *(Int64 *)op_data[0] = *(Int64 *)op_data[1] | *(Int64 *)op_data[2]; } break; case ITM_BITXOR: { if (getOperand(0)->getDatatype() == REC_BIN32_UNSIGNED) *(UInt32 *)op_data[0] = *(UInt32 *)op_data[1] ^ *(UInt32 *)op_data[2]; else if (getOperand(0)->getDatatype() == REC_BIN32_SIGNED) *(Int32 *)op_data[0] = *(Int32 *)op_data[1] ^ *(Int32 *)op_data[2]; else *(Int64 *)op_data[0] = *(Int64 *)op_data[1] ^ *(Int64 *)op_data[2]; } break; case ITM_BITNOT: { if (getOperand(0)->getDatatype() == REC_BIN32_UNSIGNED) *(UInt32 *)op_data[0] = ~*(UInt32 *)op_data[1]; else if (getOperand(0)->getDatatype() == REC_BIN32_SIGNED) *(Int32 *)op_data[0] = ~*(Int32 *)op_data[1]; else if (getOperand(0)->getDatatype() == REC_BIN64_SIGNED) *(Int64 *)op_data[0] = ~*(Int64 *)op_data[1]; else { for (Int32 i = 0; i < getOperand(0)->getLength(); i++) { ((char*)(op_data[0]))[i] = ~((char*)(op_data[1]))[i]; } } } break; // LCOV_EXCL_STOP case ITM_BITEXTRACT: { UInt32 startBit = *(UInt32 *)op_data[2]; UInt32 numBits = *(UInt32 *)op_data[3]; UInt32 opLen = getOperand(1)->getLength(); UInt32 startByte = startBit / 8; UInt32 endByte = (startBit + numBits - 1) / 8 ; if ((numBits == 0) || (endByte >= opLen)) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("BITEXTRACT"); return ex_expr::EXPR_ERROR; } UInt64 result = 0; //Int64 temp = 0; switch (getOperand(1)->getDatatype()) { case REC_BIN16_SIGNED: case REC_BIN16_UNSIGNED: { UInt16 temp; temp = *(UInt16*)op_data[1] << startBit; temp = temp >> (16 - numBits); result = temp; } break; case REC_BIN32_SIGNED: case REC_BIN32_UNSIGNED: case REC_IEEE_FLOAT32: { UInt32 temp; // LCOV_EXCL_START temp = *(UInt32*)op_data[1] << startBit; temp = temp >> (32 - numBits); result = temp; } break; case REC_BIN64_SIGNED: case REC_IEEE_FLOAT64: { result = *(Int64*)op_data[1] << startBit; result = result >> (64 - numBits); } break; default: { // not yet supported // UInt32 middleBytes = //((endByte - startByte) > 1 ? (endByte - startByte) : 0); ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("BITEXTRACT"); return ex_expr::EXPR_ERROR; } // LCOV_EXCL_STOP break; } // switch if (getOperand(0)->getDatatype() == REC_BIN32_SIGNED) *(Int32*)op_data[0] = (Int32)result; else *(Int64*)op_data[0] = result; } break; case ITM_CONVERTTOBITS: { #pragma nowarn(1506) // warning elimination Lng32 len1 = getOperand(1)->getLength(op_data[-MAX_OPERANDS+1]); #pragma warn(1506) // warning elimination Int32 i; if ( DFS2REC::isDoubleCharacter(getOperand(1)->getDatatype()) ) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("CONVERTTOBITS"); return ex_expr::EXPR_ERROR; } else { for (i = 0; i < len1; i++) { op_data[0][8*i+0] = (0x80 & op_data[1][i] ? '1' : '0'); op_data[0][8*i+1] = (0x40 & op_data[1][i] ? '1' : '0'); op_data[0][8*i+2] = (0x20 & op_data[1][i] ? '1' : '0'); op_data[0][8*i+3] = (0x10 & op_data[1][i] ? '1' : '0'); op_data[0][8*i+4] = (0x08 & op_data[1][i] ? '1' : '0'); op_data[0][8*i+5] = (0x04 & op_data[1][i] ? '1' : '0'); op_data[0][8*i+6] = (0x02 & op_data[1][i] ? '1' : '0'); op_data[0][8*i+7] = (0x01 & op_data[1][i] ? '1' : '0'); } } getOperand(0)->setVarLength(2 * len1, op_data[-MAX_OPERANDS]); } break; } return retcode; }
////////////////////////////////////////////////////// // work() for ExExeUtilHiveTruncateTcb ////////////////////////////////////////////////////// short ExExeUtilHiveTruncateTcb::work() { short rc = 0; Lng32 cliRC = 0; // if no parent request, return if (qparent_.down->isEmpty()) return WORK_OK; // if no room in up queue, won't be able to return data/status. // Come back later. if (qparent_.up->isFull()) return WORK_OK; ex_queue_entry * pentry_down = qparent_.down->getHeadEntry(); ExExeUtilPrivateState & pstate = *((ExExeUtilPrivateState*) pentry_down->pstate); while (1) { switch (step_) { case INITIAL_: { // if 'if exists' clause was specified and table does not exist // during compile phase, return. // If table was missing during compile and was created before // execute, then QI/AQR/Timestamp check will recompile. if (htTdb().getIfExists() && htTdb().getTableNotExists()) { step_ = DONE_; break; } if (htTdb().getIsExternal()) step_ = ALTER_TO_MANAGED_; else step_ = TRUNCATE_TABLE_; } break; case ALTER_TO_MANAGED_: { // A Hive table can be an External or Managed table. // Currently, an External Hive table cannot be truncated. // Maybe some future Hive version will allow that. // Temporarily change the table attribute to be Managed, // truncate the table and then change it back to be External. NAString alterStmt("alter table "); alterStmt += htTdb().getHiveTableName(); alterStmt += " set tblproperties ('EXTERNAL'='False')"; if (HiveClient_JNI::executeHiveSQL(alterStmt.data()) != HVC_OK) { // alter failed ExRaiseSqlError(getHeap(), &diagsArea_, -1214, NULL, NULL, NULL, getSqlJniErrorStr(), htTdb().getHiveTruncQuery()); step_ = ERROR_; break; } step_ = TRUNCATE_TABLE_; } break; case TRUNCATE_TABLE_: { if (HiveClient_JNI::executeHiveSQL(htTdb().getHiveTruncQuery()) != HVC_OK) { ExRaiseSqlError(getHeap(), &diagsArea_, -1214, NULL, NULL, NULL, getSqlJniErrorStr(), htTdb().getHiveTruncQuery()); if (htTdb().getIsExternal()) { step_ = ALTER_TO_EXTERNAL_AND_ERROR_; break; } step_ = ERROR_; break; } if (htTdb().getIsExternal()) step_ = ALTER_TO_EXTERNAL_; else step_= DONE_; } break; case ALTER_TO_EXTERNAL_: case ALTER_TO_EXTERNAL_AND_ERROR_: { // table was altered to Managed. Alter it back to External. NAString alterStmt("alter table "); alterStmt += htTdb().getHiveTableName(); alterStmt += " set tblproperties ('EXTERNAL'='TRUE')"; if (HiveClient_JNI::executeHiveSQL(alterStmt.data()) != HVC_OK) { // alter failed ExRaiseSqlError(getHeap(), &diagsArea_, -1214, NULL, NULL, NULL, getSqlJniErrorStr(), alterStmt.data()); step_ = ERROR_; break; } if (step_ == ALTER_TO_EXTERNAL_AND_ERROR_) step_ = ERROR_; else step_ = DONE_; } break; case ERROR_: { if (handleError()) return WORK_OK; step_ = DONE_; } break; case DONE_: { if (handleDone()) return WORK_OK; step_ = INITIAL_; return WORK_OK; } break; } // switch } // while }
ex_expr::exp_return_type ex_arith_clause::evalUnsupportedOperations( char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { // if this operation could be done by converting to an // intermediate datatype, do it. short op1Type = getOperand(1)->getDatatype(); short op2Type = getOperand(2)->getDatatype(); // if either of the two operands is a Tandem float, convert // them to IEEE float and then do the arith operation. This case // will be reached for pre-R2 programs where only tandem floats // were supported. We support this so as to not require applications // to recompile. This case is also needed for versioning support // in mixed node environments. if ((op1Type == REC_TDM_FLOAT32) || (op1Type == REC_TDM_FLOAT64) || (op2Type == REC_TDM_FLOAT32) || (op2Type == REC_TDM_FLOAT64)) { // convert both operands to double. // Do the arith operation and convert result back to the // type of result operand. double op1Double; double op2Double; double op0Double; // result char * opDoubleData[3]; opDoubleData[0] = (char *)&op0Double; opDoubleData[1] = (char *)&op1Double; opDoubleData[2] = (char *)&op2Double; if (convDoIt(op_data[1], getOperand(1)->getLength(), op1Type, getOperand(1)->getPrecision(), getOperand(1)->getScale(), (char*)&op1Double, (Lng32)sizeof(double), REC_FLOAT64, 0, 0, NULL, 0, heap, diagsArea, CONV_UNKNOWN) != ex_expr::EXPR_OK) return ex_expr::EXPR_ERROR; if (convDoIt(op_data[2], getOperand(2)->getLength(), op2Type, getOperand(2)->getPrecision(), getOperand(2)->getScale(), (char*)&op2Double, (Lng32)sizeof(double), REC_FLOAT64, 0, 0, NULL, 0, heap, diagsArea, CONV_UNKNOWN) != ex_expr::EXPR_OK) return ex_expr::EXPR_ERROR; // do the arith operation. ex_arith_clause tempArith; SimpleType op1DoubleAttr(REC_FLOAT64, sizeof(double), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); SimpleType op2DoubleAttr(REC_FLOAT64, sizeof(double), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); SimpleType op0DoubleAttr(REC_FLOAT64, sizeof(double), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); tempArith.set_case_index(getOperType(), &op1DoubleAttr, &op2DoubleAttr, &op0DoubleAttr); if (tempArith.get_case_index() == ARITH_NOT_SUPPORTED) { ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); return ex_expr::EXPR_ERROR; } if (tempArith.eval(opDoubleData, heap, diagsArea) != ex_expr::EXPR_OK) return ex_expr::EXPR_ERROR; // convert double result to the actual result type. if (convDoIt(opDoubleData[0], (Lng32)sizeof(double), REC_FLOAT64, 0, 0, op_data[0], getOperand(0)->getLength(), getOperand(0)->getDatatype(), getOperand(0)->getPrecision(), getOperand(0)->getScale(), NULL, 0, heap, diagsArea, CONV_UNKNOWN) != ex_expr::EXPR_OK) return ex_expr::EXPR_ERROR; } else { ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); return ex_expr::EXPR_ERROR; } return ex_expr::EXPR_OK; }
ex_expr::exp_return_type ExpLOBiud::insertDesc(char *op_data[], CollHeap*h, ComDiagsArea** diagsArea) { Lng32 rc; Lng32 lobOperStatus = checkLobOperStatus(); if (lobOperStatus == DO_NOTHING_) return ex_expr::EXPR_OK; char * result = op_data[0]; // get the lob name where data need to be inserted char tgtLobNameBuf[100]; char * tgtLobName = ExpGetLOBname(objectUID_, lobNum(), tgtLobNameBuf, 100); 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; char * lobHandle = NULL; Lng32 handleLen = 0; char lobHandleBuf[LOB_HANDLE_LEN]; // if (getExeGlobals()->lobGlobals()->getCurrLobOperInProgress()) if (lobOperStatus == CHECK_STATUS_) { lobHandle = lobHandleSaved_; handleLen = lobHandleLenSaved_; } else { Int64 descTS = NA_JulianTimestamp(); lobHandle = lobHandleBuf; ExpLOBoper::genLOBhandle(objectUID_, lobNum(), (short)lobStorageType(), -1, descTS, -1, descSchNameLen_, descSchName(), handleLen, lobHandle); } LobsSubOper so = Lob_None; if (fromFile()) so = Lob_File; else if (fromString() || fromLoad()) so = Lob_Memory; else if (fromLob()) so = Lob_Foreign_Lob; else if (fromBuffer()) so = Lob_Buffer; Lng32 waitedOp = 0; #ifdef __EID waitedOp = 0; // nowaited op from EID/TSE process #else waitedOp = 1; #endif //temptemp. Remove after ExLobsOper adds nowaited support. waitedOp = 1; // temp. Pass lobLen. When ExLobsOper fixes it so len is not needed during // lob desc update, then remove this. Int64 lobLen = getOperand(1)->getLength(); blackBoxLen_ = 0; if (fromExternal()) { blackBoxLen_ = getOperand(1)->getLength(); str_cpy_and_null(blackBox_, op_data[1], (Lng32)blackBoxLen_, '\0', ' ', TRUE); } Lng32 cliError = 0; char * lobData = NULL; lobData= new(h) char[lobLen]; //send lobData only if it's a lob_file operation if (so == Lob_File) { str_cpy_and_null(lobData,op_data[1],lobLen,'\0',' ',TRUE); } if (so == Lob_Buffer) { memcpy(&lobLen, op_data[2],sizeof(Int64)); } LobsOper lo ; if (lobOperStatus == CHECK_STATUS_) lo = Lob_Check_Status; else if (lobHandle == NULL) lo = Lob_InsertDataSimple; else lo = Lob_InsertDesc; rc = ExpLOBInterfaceInsert (getExeGlobals()->lobGlobal(), tgtLobName, lobStorageLocation(), lobStorageType(), getLobHdfsServer(), getLobHdfsPort(), handleLen, lobHandle, &outHandleLen_, outLobHandle_, blackBoxLen_, blackBox_, requestTag_, getExeGlobals()->lobGlobals()->xnId(), descSyskey, lo, &cliError, so, waitedOp, lobData, lobLen, getLobMaxSize(), 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)); return ex_expr::EXPR_ERROR; } // extract and update lob handle with the returned values if (outHandleLen_ > 0) { ExpLOBoper::extractFromLOBhandle(NULL, NULL, 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]); if (NOT fromExternal()) { getExeGlobals()->lobGlobals()->lobLoadInfo()-> setLobHandle(lobNum(), handleLen, lobHandle); } return ex_expr::EXPR_OK; }
ex_expr::exp_return_type ExpLOBupdate::eval(char *op_data[], CollHeap*h, ComDiagsArea** diagsArea) { Lng32 rc; Lng32 lobOperStatus = checkLobOperStatus(); if (lobOperStatus == DO_NOTHING_) return ex_expr::EXPR_OK; char * result = op_data[0]; char * lobHandle = NULL; Lng32 handleLen = 0; Lng32 sLobType; Int64 sUid; Lng32 sLobNum; Int64 sDescSyskey = -1; Int64 sDescTS = -1; Int16 sFlags; short sSchNameLen = 0; char sSchName[500]; if (getOperand(2)->getNullFlag() && nullValue_) { ex_expr::exp_return_type err = insertDesc(op_data, h, diagsArea); if (err == ex_expr::EXPR_ERROR) return err; char * handle = op_data[0]; handleLen = getOperand(0)->getLength(); err = insertData(handleLen, handle, op_data, h, diagsArea); 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]); // get the lob name where data need to be updated char tgtLobNameBuf[100]; char * tgtLobName = ExpGetLOBname(sUid, sLobNum, tgtLobNameBuf, 100); if (tgtLobName == NULL) return ex_expr::EXPR_ERROR; char fromLobNameBuf[100]; char * fromLobName = NULL; Int64 fromDescKey = 0; Int64 fromDescTS = 0; short fromSchNameLen = 0; char fromSchName[500]; if (0) // TBD. fromLob()) { Lng32 fromLobType; Int64 fromLobUid; Lng32 fromLobNum; Int16 fromFlags; extractFromLOBhandle(&fromFlags, &fromLobType, &fromLobNum, &fromLobUid, &fromDescKey, &fromDescTS, &fromSchNameLen, fromSchName, op_data[1]); // get the lob name where data will be read from fromLobName = ExpGetLOBname(fromLobUid, fromLobNum, fromLobNameBuf, 100); if (fromLobName == NULL) return ex_expr::EXPR_ERROR; } LobsSubOper so = Lob_None; if (fromFile()) so = Lob_File; else if (fromString()) so = Lob_Memory; else if (fromLob()) so = Lob_Foreign_Lob; else if (fromBuffer()) so= Lob_Buffer; Lng32 waitedOp = 0; #ifdef __EID waitedOp = 0; // nowaited op from EID/TSE process #else waitedOp = 1; #endif //temptemp. Remove after ExLobsOper adds nowaited support. waitedOp = 1; Lng32 cliError = 0; // 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; Int64 lobLen = getOperand(1)->getLength(); char * data = op_data[1]; if (fromBuffer()) { memcpy(&lobLen, op_data[3],sizeof(Int64)); // user specified buffer length memcpy(data,op_data[1],sizeof(Int64)); // user buffer address } if (isAppend()) { rc = ExpLOBInterfaceUpdateAppend (getExeGlobals()->lobGlobal(), getLobHdfsServer(), getLobHdfsPort(), tgtLobName, lobStorageLocation(), handleLen, lobHandle, &outHandleLen_, outLobHandle_, requestTag_, getExeGlobals()->lobGlobals()->xnId(), (lobOperStatus == CHECK_STATUS_ ? 1 : 0), waitedOp, so, sDescSyskey, lobLen, data, fromLobName, fromSchNameLen, fromSchName, fromDescKey, fromDescTS, getLobMaxSize(), getLobMaxChunkMemSize(),getLobGCLimit()); } else { rc = ExpLOBInterfaceUpdate (getExeGlobals()->lobGlobal(), getLobHdfsServer(), getLobHdfsPort(), tgtLobName, lobStorageLocation(), handleLen, lobHandle, &outHandleLen_, outLobHandle_, requestTag_, getExeGlobals()->lobGlobals()->xnId(), (lobOperStatus == CHECK_STATUS_ ? 1 : 0), waitedOp, so, sDescSyskey, lobLen, data, fromLobName, fromSchNameLen, fromSchName, fromDescKey, fromDescTS, getLobMaxSize(), getLobMaxChunkMemSize(),getLobGCLimit()); } if (rc < 0) { Lng32 intParam1 = -rc; ExRaiseSqlError(h, diagsArea, (ExeErrorCode)(8442), NULL, &intParam1, &cliError, NULL, (char*)"ExpLOBInterfaceUpdate", getLobErrStr(intParam1)); return ex_expr::EXPR_ERROR; } // update lob handle with the returned values str_cpy_all(result, lobHandle, handleLen); // str_cpy_all(result, op_data[2], handleLen); // ExpLOBoper::updLOBhandle(sDescSyskey, 0, result); getOperand(0)->setVarLength(handleLen, op_data[-MAX_OPERANDS]); return ex_expr::EXPR_OK; }
short BigNum::div(Attributes * left, Attributes * right, char * op_data[], NAMemory *heap, ComDiagsArea** diagsArea) { // Extract signs. // Extract signs. char leftSign = BIGN_GET_SIGN(op_data[1], ((BigNum*) left)->getLength()); char rightSign = BIGN_GET_SIGN(op_data[2], ((BigNum*) right)->getLength()); // Clear sign bits BIGN_CLR_SIGN(op_data[1], ((BigNum*) left)->getLength()); BIGN_CLR_SIGN(op_data[2], ((BigNum*) right)->getLength()); // Ignore trailing zeros in right. unsigned short * rightDataInShorts = (unsigned short *) op_data[2]; Lng32 rightLengthInShorts = (((BigNum *) right)->getLength())/2; while ((rightDataInShorts[rightLengthInShorts - 1] == 0) && (rightLengthInShorts > 0)) rightLengthInShorts--; if (rightLengthInShorts == 0) { if (heap) ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); // Reset sign bits if (leftSign) BIGN_SET_SIGN(op_data[1], ((BigNum*) left)->getLength()); if (rightSign) BIGN_SET_SIGN(op_data[2], ((BigNum*) right)->getLength()); return -1; } if (rightLengthInShorts == 1) { BigNumHelper::SimpleDivHelper(((BigNum *) left)->getLength(), 2, op_data[1], op_data[2], op_data[0]); } else { BigNumHelper::DivHelper(((BigNum *) left)->getLength(), 2*rightLengthInShorts, op_data[1], op_data[2], op_data[0], (char *) tempSpacePtr_); } if (leftSign) BIGN_SET_SIGN(op_data[1], ((BigNum*) left)->getLength()); if (rightSign) BIGN_SET_SIGN(op_data[2], ((BigNum*) right)->getLength()); if (leftSign == rightSign) { BIGN_CLR_SIGN(op_data[0], getLength()); } else { BIGN_SET_SIGN(op_data[0], getLength()); } return 0; }
// this method implements the ROUND function on big nums short BigNum::round (Attributes * left, Attributes * right, char * op_data[], NAMemory *heap, ComDiagsArea** diagsArea) { // obtain the rounding value Int64 roundingValue = left->getScale(); if (right) { Int64 rightOperandValue = 0; switch (right->getDatatype()) { case REC_BIN8_SIGNED: rightOperandValue = *((char *)op_data[2]); break; case REC_BIN8_UNSIGNED: rightOperandValue = *((unsigned char *)op_data[2]); break; case REC_BIN16_SIGNED: rightOperandValue = *((Int16 *)op_data[2]); break; case REC_BPINT_UNSIGNED: case REC_BIN16_UNSIGNED: rightOperandValue = *((UInt16 *)op_data[2]); break; case REC_BIN32_SIGNED: rightOperandValue = *((Int32 *)op_data[2]); break; case REC_BIN32_UNSIGNED: rightOperandValue = *((UInt32 *)op_data[2]); break; case REC_BIN64_SIGNED: rightOperandValue = *((Int64 *)op_data[2]); break; case REC_BIN64_UNSIGNED: rightOperandValue = *((UInt64 *)op_data[2]); break; default: { // MathFunc::preCodeGen (generator/GenPreCode.cpp) should // have guaranteed that we have an integer type here if (heap) ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); return -1; } break; } roundingValue -= rightOperandValue; } // Extract sign char leftSign = BIGN_GET_SIGN(op_data[1], left->getLength()); // Clear sign bits BIGN_CLR_SIGN(op_data[1], getLength()); short result = BigNumHelper::RoundHelper(left->getLength(), getLength(), op_data[1], roundingValue, op_data[0]); if (result < 0) { if (heap) ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW, NULL, NULL, NULL, NULL, " The error occurred when rounding up a value."); return -1; } // Reset sign bits if (leftSign) BIGN_SET_SIGN(op_data[1], left->getLength()); if (leftSign && (result == 0)) { BIGN_SET_SIGN(op_data[0], getLength()); } else { BIGN_CLR_SIGN(op_data[0], getLength()); } return 0; }
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; #ifdef __EID waitedOp = 0; // nowaited op from EID/TSE process #else waitedOp = 1; #endif //temptemp. Remove after ExLobsOper adds nowaited support. waitedOp = 1; extractFromLOBhandle(&flags, &lobType, &lobNum, &uid, &descKey, &descTS, &schNameLen, schName, lobHandle); // get the lob name where data need to be inserted char lobNameBuf[100]; char * lobName = ExpGetLOBname(uid, lobNum, lobNameBuf, 100); if(toFile()) { so = Lob_File; tgtFileName = tgtFileName_; rc = ExpLOBInterfaceSelect(getExeGlobals()->lobGlobal(), lobName, lobStorageLocation(), lobType, getLobHdfsServer(), getLobHdfsPort(), handleLen, lobHandle, requestTag_, so, getExeGlobals()->lobGlobals()->xnId(), (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()->lobGlobal(), lobName, lobStorageLocation(), lobType, getLobHdfsServer(), getLobHdfsPort(), handleLen, lobHandle, requestTag_, so, getExeGlobals()->lobGlobals()->xnId(), (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)); 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; }
ex_expr::exp_return_type ex_function_trim_doublebyte::eval(char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { // find out the length of trim character. #pragma nowarn(1506) // warning elimination Lng32 len1 = (getOperand(1)->getLength(op_data[-MAX_OPERANDS+1])) / sizeof(NAWchar); #pragma warn(1506) // warning elimination // len1 (length of trim character) must be 1. Raise an exception if greater // than 1. if (len1 != 1) { ExRaiseSqlError(heap, diagsArea, EXE_TRIM_ERROR); return ex_expr::EXPR_ERROR; } #pragma nowarn(1506) // warning elimination Lng32 len2 = (getOperand(2)->getLength(op_data[-MAX_OPERANDS+2])) / sizeof(NAWchar); #pragma warn(1506) // warning elimination // Find how many leading characters in operand 2 correspond to the trim // character. Lng32 len0 = len2; Lng32 start = 0; NAWchar trimNChar = *((NAWchar*)op_data[1]); NAWchar* trimSource = (NAWchar*)op_data[2]; if ((getTrimMode() == 1) || (getTrimMode() == 2)) while ((start < len2) && //(op_data[1][0] == op_data[2][start]) (trimNChar == trimSource[start]) ){ start++; len0--; } // Find how many trailing characters in operand 2 correspond to the trim // character. Lng32 end = len2; if ((getTrimMode() == 0) || (getTrimMode() == 2)) while ((end > (start)) && //(op_data[1][0] == op_data[2][end-1]) ( trimNChar == trimSource[end-1]) ){ end--; len0--; } len0 *= sizeof(NAWchar); // convert to the length in terms of number of bytes. start *= sizeof(NAWchar); // convert to the start index in terms of number of bytes. // Result is always a varchar. // store the length of trimmed string in the varlen indicator. getOperand(0)->setVarLength(len0, op_data[-MAX_OPERANDS]); // Now, copy operand 2 skipping the trim characters into // operand 0. if (len0 > 0) str_cpy_all(op_data[0], &op_data[2][start], len0); return ex_expr::EXPR_OK; };
ex_expr::exp_return_type ExpLOBiud::insertData(Lng32 handleLen, char * handle, char *op_data[], CollHeap*h, ComDiagsArea** diagsArea) { Lng32 rc = 0; Lng32 lobOperStatus = checkLobOperStatus(); if (lobOperStatus == DO_NOTHING_) return ex_expr::EXPR_OK; Lng32 lobType; Int64 uid; Lng32 lobNum; Int64 lobLen; // Lng32 flags; Int64 descSyskey = -1; // Int64 descTS = -1; short numChunks = 0; // short schNameLen = 0; // char schName[500]; extractFromLOBhandle(NULL, &lobType, &lobNum, &uid, &descSyskey, NULL, //&descTS, NULL, NULL, //&schNameLen, schName, handle); // get the lob name where data need to be inserted char tgtLobNameBuf[100]; char * tgtLobName = ExpGetLOBname(uid, lobNum, tgtLobNameBuf, 100); if (tgtLobName == NULL) return ex_expr::EXPR_ERROR; lobLen = getOperand(1)->getLength(); char * lobData = NULL; 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 memcpy(lobData,op_data[1],sizeof(Int64)); // user buffer address } LobsOper lo ; if (lobOperStatus == CHECK_STATUS_) lo = Lob_Check_Status; else 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_Foreign_Lob; else if(fromBuffer()) so = Lob_Buffer; Lng32 waitedOp = 0; #ifdef __EID waitedOp = 0; // nowaited op from EID/TSE process #else waitedOp = 1; #endif //temptemp. Remove after ExLobsOper adds nowaited support. waitedOp = 1; Lng32 cliError = 0; blackBoxLen_ = 0; if (fromLob()) { Int64 srcDescKey = -1; Int64 srcDescTS = -1; char srcLobNameBuf[100]; char * srcLobName = NULL; short srcSchNameLen = 0; char srcSchName[500]; extractFromLOBhandle(NULL, &lobType, &lobNum, &uid, &srcDescKey, &srcDescTS, &srcSchNameLen, srcSchName, op_data[1]); // get the lob name where data will be read from srcLobName = ExpGetLOBname(uid, lobNum, srcLobNameBuf, 100); if (srcLobName == NULL) return ex_expr::EXPR_ERROR; } else { rc = ExpLOBInterfaceInsert(getExeGlobals()->lobGlobal(), tgtLobName, lobStorageLocation(), lobType, getLobHdfsServer(), getLobHdfsPort(), handleLen, handle, &outHandleLen_, outLobHandle_, blackBoxLen_, blackBox_, requestTag_, getExeGlobals()->lobGlobals()->xnId(), 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)); return ex_expr::EXPR_ERROR; } return ex_expr::EXPR_OK; }
////////////////////////////////////////////////////// // work() for ExExeUtilHiveTruncateLegacyTcb ////////////////////////////////////////////////////// short ExExeUtilHiveTruncateLegacyTcb::work() { short rc = 0; Lng32 cliRC = 0; // if no parent request, return if (qparent_.down->isEmpty()) return WORK_OK; // if no room in up queue, won't be able to return data/status. // Come back later. if (qparent_.up->isFull()) return WORK_OK; ex_queue_entry * pentry_down = qparent_.down->getHeadEntry(); ExExeUtilPrivateState & pstate = *((ExExeUtilPrivateState*) pentry_down->pstate); while (1) { switch (step_) { case INITIAL_: { step_ = EMPTY_DIRECTORY_; } break; case EMPTY_DIRECTORY_: { cliRC = ExpLOBinterfaceEmptyDirectory( lobGlob_, (char*)"", //name is empty (htTdb().getPartnLocation() ? htTdb().getPartnLocation() : htTdb().getTableLocation()), Lob_HDFS_File, htTdb().getHdfsHost(), htTdb().getHdfsPort(), 0 , 1 , 0); if (cliRC != 0) { Lng32 cliError = 0; Lng32 intParam1 = -cliRC; ExRaiseSqlError(getHeap(), &diagsArea_, (ExeErrorCode)(EXE_ERROR_FROM_LOB_INTERFACE), NULL, &intParam1, &cliError, NULL, "HDFS", (char*)"ExpLOBInterfaceEmptyDirectory", getLobErrStr(intParam1)); char reason[200]; strcpy(reason, " "); if (intParam1 == LOB_DIR_NAME_ERROR) { if (htTdb().getPartnLocation()) strcpy(reason, "Reason: specified partition does not exist"); else strcpy(reason, "Reason: specified table location does not exist"); } else if (intParam1 == LOB_DATA_FILE_DELETE_ERROR) { strcpy(reason, "Reason: error occurred during deletion of one or more files at the specified location"); } ExRaiseSqlError(getHeap(), &diagsArea_, (ExeErrorCode)(EXE_HIVE_TRUNCATE_ERROR), NULL, NULL, NULL, NULL, reason, NULL, NULL); step_ = ERROR_; } else { step_= DONE_; } } break; case ERROR_: { if (handleError()) return WORK_OK; step_ = DONE_; } break; case DONE_: { if (handleDone()) return WORK_OK; step_ = INITIAL_; return WORK_OK; } break; } // switch } // while }
// LCOV_EXCL_STOP ex_expr::exp_return_type ex_arith_clause::eval(char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { switch (get_case_index()) { /* ADD operation */ case ADD_BIN16S_BIN16S_BIN16S: #pragma nowarn(1506) // warning elimination *(short *)op_data[0] = *(short *)op_data[1] + *(short *)op_data[2]; #pragma warn(1506) // warning elimination break; // LCOV_EXCL_START case ADD_BIN16S_BIN16S_BIN32S: *(Lng32 *)op_data[0] = *(short *)op_data[1] + *(short *)op_data[2]; break; case ADD_BIN16S_BIN32S_BIN32S: *(Lng32 *)op_data[0] = *(short *)op_data[1] + *(Lng32 *)op_data[2]; break; // LCOV_EXCL_STOP case ADD_BIN32S_BIN16S_BIN32S: *(Lng32 *)op_data[0] = *(Lng32 *)op_data[1] + *(short *)op_data[2]; break; case ADD_BIN32S_BIN32S_BIN32S: *(Lng32 *)op_data[0] = *(Lng32 *)op_data[1] + *(Lng32 *)op_data[2]; break; case ADD_BIN32S_BIN64S_BIN64S: // LCOV_EXCL_START *(Int64 *)op_data[0] = *(Int64 *)op_data[2] + *(Lng32 *)op_data[1]; break; // LCOV_EXCL_STOP case ADD_BIN64S_BIN32S_BIN64S: *(Int64 *)op_data[0] = *(Int64 *)op_data[1] + *(Lng32 *)op_data[2]; break; case ADD_BIN64S_BIN64S_BIN64S: { short ov; *(Int64 *)op_data[0] = EXP_FIXED_OV_ADD(*(Int64 *)op_data[1], *(Int64 *)op_data[2], &ov); if (ov) { // LCOV_EXCL_START ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; // LCOV_EXCL_STOP } } break; case ADD_BIN16U_BIN16U_BIN16U: #pragma nowarn(1506) // warning elimination *(unsigned short *)op_data[0] = *(unsigned short *)op_data[1] + *(unsigned short *)op_data[2]; #pragma warn(1506) // warning elimination break; case ADD_BIN16U_BIN16U_BIN32U: *(ULng32 *)op_data[0] = *(unsigned short *)op_data[1] + *(unsigned short *)op_data[2]; break; case ADD_BIN16U_BIN32U_BIN32U: // LCOV_EXCL_START *(ULng32 *)op_data[0] = *(unsigned short *)op_data[1] + *(ULng32 *)op_data[2]; break; // LCOV_EXCL_STOP case ADD_BIN32U_BIN16U_BIN32U: *(ULng32 *)op_data[0] = *(ULng32 *)op_data[1] + *(unsigned short *)op_data[2]; break; case ADD_BIN32U_BIN32U_BIN32U: *(ULng32 *)op_data[0] = *(ULng32 *)op_data[1] + *(ULng32 *)op_data[2]; break; case ADD_BPINTU_BIN64S_BIN64S: *(Int64 *)op_data[0] = *(Int64 *)op_data[2] + *(unsigned short *)op_data[1]; break; case ADD_BIN64S_BPINTU_BIN64S: // LCOV_EXCL_START *(Int64 *)op_data[0] = *(Int64 *)op_data[1] + *(unsigned short *)op_data[2]; break; case ADD_BIN32U_BIN64S_BIN64S: *(Int64 *)op_data[0] = *(Int64 *)op_data[2] + *(ULng32 *)op_data[1]; break; // LCOV_EXCL_STOP case ADD_BIN64S_BIN32U_BIN64S: *(Int64 *)op_data[0] = *(Int64 *)op_data[1] + *(ULng32 *)op_data[2]; break; case ADD_FLOAT32_FLOAT32_FLOAT32: *(float *)op_data[0] = *(float *)op_data[1] + *(float *)op_data[2]; break; case ADD_FLOAT64_FLOAT64_FLOAT64: { short ov; *(double *)op_data[0] = MathReal64Add(*(double *)op_data[1], *(double *)op_data[2], &ov); if (ov) { ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; } } break; case ADD_DATETIME_INTERVAL_DATETIME: if (((ExpDatetime *) getOperand(0))-> arithDatetimeInterval(ExpDatetime::DATETIME_ADD, (ExpDatetime *)getOperand(1), getOperand(2), op_data[1], op_data[2], op_data[0], heap, diagsArea) != 0) return ex_expr::EXPR_ERROR; break; case ADD_INTERVAL_DATETIME_DATETIME: if (((ExpDatetime *) getOperand(0))-> arithDatetimeInterval(ExpDatetime::DATETIME_ADD, (ExpDatetime *)getOperand(2), getOperand(1), op_data[2], op_data[1], op_data[0], heap, diagsArea) != 0) return ex_expr::EXPR_ERROR; break; /* SUB operation */ case SUB_BIN16S_BIN16S_BIN16S: #pragma nowarn(1506) // warning elimination // LCOV_EXCL_START *(short *)op_data[0] = *(short *)op_data[1] - *(short *)op_data[2]; #pragma warn(1506) // warning elimination break; case SUB_BIN16S_BIN16S_BIN32S: *(Lng32 *)op_data[0] = *(short *)op_data[1] - *(short *)op_data[2]; break; case SUB_BIN16S_BIN32S_BIN32S: *(Lng32 *)op_data[0] = *(short *)op_data[1] - *(Lng32 *)op_data[2]; break; case SUB_BIN32S_BIN16S_BIN32S: *(Lng32 *)op_data[0] = *(Lng32 *)op_data[1] - *(short *)op_data[2]; break; case SUB_BIN32S_BIN32S_BIN32S: *(Lng32 *)op_data[0] = *(Lng32 *)op_data[1] - *(Lng32 *)op_data[2]; break; // LCOV_EXCL_STOP case SUB_BIN64S_BIN64S_BIN64S: { short ov; *(Int64 *)op_data[0] = EXP_FIXED_OV_SUB(*(Int64 *)op_data[1], *(Int64 *)op_data[2], &ov); if (ov) { // LCOV_EXCL_START ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; // LCOV_EXCL_STOP } //*(Int64 *)op_data[0] = *(Int64 *)op_data[1] - *(Int64 *)op_data[2]; } break; case SUB_BIN16U_BIN16U_BIN16U: #pragma nowarn(1506) // warning elimination *(unsigned short *)op_data[0] = *(unsigned short *)op_data[1] - *(unsigned short *)op_data[2]; #pragma warn(1506) // warning elimination break; case SUB_BIN16U_BIN16U_BIN32U: *(ULng32 *)op_data[0] = *(unsigned short *)op_data[1] - *(unsigned short *)op_data[2]; break; case SUB_BIN16U_BIN32U_BIN32U: *(ULng32 *)op_data[0] = *(unsigned short *)op_data[1] - *(ULng32 *)op_data[2]; break; case SUB_BIN32U_BIN16U_BIN32U: *(ULng32 *)op_data[0] = *(ULng32 *)op_data[1] - *(unsigned short *)op_data[2]; break; case SUB_BIN32U_BIN32U_BIN32U: *(ULng32 *)op_data[0] = *(ULng32 *)op_data[1] - *(ULng32 *)op_data[2]; break; case SUB_FLOAT32_FLOAT32_FLOAT32: *(float *)op_data[0] = *(float *)op_data[1] - *(float *)op_data[2]; break; case SUB_FLOAT64_FLOAT64_FLOAT64: { short ov; *(double *)op_data[0] = MathReal64Sub(*(double *)op_data[1], *(double *)op_data[2], &ov); if (ov) { ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; } } break; case SUB_DATETIME_INTERVAL_DATETIME: if (((ExpDatetime *) getOperand(0))-> arithDatetimeInterval(ExpDatetime::DATETIME_SUB, (ExpDatetime *)getOperand(1), getOperand(2), op_data[1], op_data[2], op_data[0], heap, diagsArea) != 0) return ex_expr::EXPR_ERROR; break; case SUB_DATETIME_DATETIME_INTERVAL: if (((ExpDatetime *) getOperand(1))->subDatetimeDatetime(getOperand(1), getOperand(0), op_data[1], op_data[2], op_data[0], heap, diagsArea) != 0) return ex_expr::EXPR_ERROR; break; /* MUL operation */ case MUL_BIN16S_BIN16S_BIN16S: #pragma nowarn(1506) // warning elimination *(short *)op_data[0] = *(short *)op_data[1] * *(short *)op_data[2]; #pragma warn(1506) // warning elimination break; case MUL_BIN16S_BIN16S_BIN32S: *(Lng32 *)op_data[0] = *(short *)op_data[1] * *(short *)op_data[2]; break; case MUL_BIN16S_BIN32S_BIN32S: *(Lng32 *)op_data[0] = *(short *)op_data[1] * *(Lng32 *)op_data[2]; break; case MUL_BIN32S_BIN16S_BIN32S: *(Lng32 *)op_data[0] = *(Lng32 *)op_data[1] * *(short *)op_data[2]; break; case MUL_BIN32S_BIN32S_BIN32S: *(Lng32 *)op_data[0] = *(Lng32 *)op_data[1] * *(Lng32 *)op_data[2]; break; case MUL_BIN16S_BIN32S_BIN64S: *(Int64 *)op_data[0] = (Int64)*(short *)op_data[1] * (Int64)*(Lng32 *)op_data[2]; break; case MUL_BIN32S_BIN16S_BIN64S: *(Int64 *)op_data[0] = (Int64)*(Lng32 *)op_data[1] * (Int64)*(short *)op_data[2]; break; case MUL_BIN32S_BIN32S_BIN64S: *(Int64 *)op_data[0] = (Int64)*(Lng32 *)op_data[1] * (Int64)*(Lng32 *)op_data[2]; break; case MUL_BIN64S_BIN64S_BIN64S: { short ov; *(Int64 *)op_data[0] = EXP_FIXED_OV_MUL(*(Int64 *)op_data[1], *(Int64 *)op_data[2], &ov); if (ov) { ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; } //*(Int64 *)op_data[0] = *(Int64 *)op_data[1] * *(Int64 *)op_data[2]; } break; case MUL_BIN16U_BIN16U_BIN16U: #pragma nowarn(1506) // warning elimination *(unsigned short *)op_data[0] = *(unsigned short *)op_data[1] * *(unsigned short *)op_data[2]; #pragma warn(1506) // warning elimination break; case MUL_BIN16U_BIN16U_BIN32U: *(ULng32 *)op_data[0] = *(unsigned short *)op_data[1] * *(unsigned short *)op_data[2]; break; case MUL_BIN16U_BIN32U_BIN32U: *(ULng32 *)op_data[0] = *(unsigned short *)op_data[1] * *(ULng32 *)op_data[2]; break; case MUL_BIN32U_BIN16U_BIN32U: *(ULng32 *)op_data[0] = *(ULng32 *)op_data[1] * *(unsigned short *)op_data[2]; break; case MUL_BIN32U_BIN32U_BIN32U: *(ULng32 *)op_data[0] = *(ULng32 *)op_data[1] * *(ULng32 *)op_data[2]; break; case MUL_FLOAT32_FLOAT32_FLOAT32: *(float *)op_data[0] = *(float *)op_data[1] * *(float *)op_data[2]; break; case MUL_FLOAT64_FLOAT64_FLOAT64: { short ov; *(double *)op_data[0] = MathReal64Mul(*(double *)op_data[1], *(double *)op_data[2], &ov); if (ov) { ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; } } break; /* DIV operation */ case DIV_BIN16S_BIN16S_BIN16S: if (*(short *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } #pragma nowarn(1506) // warning elimination *(short *)op_data[0] = *(short *)op_data[1] / *(short *)op_data[2]; #pragma warn(1506) // warning elimination break; case DIV_BIN16S_BIN16S_BIN32S: if (*(short *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } *(Lng32 *)op_data[0] = *(short *)op_data[1] / *(short *)op_data[2]; break; case DIV_BIN16S_BIN32S_BIN32S: if (*(Lng32 *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } *(Lng32 *)op_data[0] = *(short *)op_data[1] / *(Lng32 *)op_data[2]; break; case DIV_BIN32S_BIN16S_BIN32S: if (*(short *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } *(Lng32 *)op_data[0] = *(Lng32 *)op_data[1] / *(short *)op_data[2]; break; case DIV_BIN32S_BIN32S_BIN32S: if (*(Lng32 *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } *(Lng32 *)op_data[0] = *(Lng32 *)op_data[1] / *(Lng32 *)op_data[2]; break; case DIV_BIN64S_BIN64S_BIN64S: { if (*(Int64 *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } short ov; *(Int64 *)op_data[0] = EXP_FIXED_OV_DIV(*(Int64 *)op_data[1], *(Int64 *)op_data[2], &ov); if (ov) { ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; } // *(Int64 *)op_data[0] = *(Int64 *)op_data[1] / *(Int64 *)op_data[2]; } break; case DIV_BIN64S_BIN64S_BIN64S_ROUND: { if (*(Int64 *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } short ov; // upscale numerator by 1 NABoolean upscaled; Int64 temp; if (getDivToDownscale()) { temp = *(Int64 *)op_data[2] / 10; temp = *(Int64 *)op_data[1] / temp; upscaled = TRUE; } else { temp = EXP_FIXED_OV_MUL(*(Int64 *)op_data[1], 10, &ov); if (ov) { // couldn't upscale. Use the original value and don't do // any rounding. upscaled = FALSE; temp = *(Int64 *)op_data[1]; } else { upscaled = TRUE; } temp = EXP_FIXED_OV_DIV(temp, *(Int64 *)op_data[2], &ov); if (ov) { ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; } } if (upscaled) { short nsign = 0; // indicates negative sign when set to 1. // get the last digit Lng32 v = (Lng32) (temp % (Int64)10); if( v < 0 ) v = -v; if(temp < 0) nsign = 1; // downscale the result temp = temp / (Int64)10; if (arithRoundingMode_ == 1) { // ROUND HALF UP MODE if (v >= 5) { // round up the result by 1 temp = nsign ? temp-1 : temp+1; } } else if (arithRoundingMode_ == 2) { // ROUND HALF EVEN MODE if (v > 5) { // round up the result by 1 temp = nsign ? temp-1 : temp+1; } else if (v == 5) { // Roundup 'w' only if all the trailing digits following // 'v' is zero and 'w' is even. If 'w' is odd, irrespective // of trailing digits following 'v', 'w' is rounded up. // w is second last digit. Lng32 w = (Lng32) (temp % (Int64)10); if ((w & 0x1) != 0) { // odd number, round up. temp = nsign ? temp-1 : temp+1; } else { // Since 'w' is an even digit, we need to determine if // all the trailing digits following 'v' is zero. // If any digit following 'v' is nonzero, then it is // similar to v > 5. NABoolean vGT5 = FALSE; if(! getDivToDownscale()) { //Figure out if digits following 'v' is non zero. Int64 multiplier = 100;//For digit following 'v'. Int64 temp1; NABoolean biggerPrecision = FALSE; while(!vGT5) { temp1 = EXP_FIXED_OV_MUL(*(Int64 *)op_data[1], multiplier, &ov); if (ov) { //end of digits. //When we reach here, temp1 is overflowed over Int64. //In this rear but possible situation, we should try checking //for additional digits using BigNum datatype. biggerPrecision = TRUE; break; } temp1 = EXP_FIXED_OV_DIV(temp1, *(Int64 *)op_data[2], &ov); if (ov) { //Something went wrong, lets consider //it as end of digits. break; } if(temp1 % (Int64)10) { vGT5 = TRUE; break; } multiplier = EXP_FIXED_OV_MUL(multiplier, 10, &ov); if (ov) { //end of digits. break; } } if(biggerPrecision) { short rc = 0; Int64 dividend = *(Int64 *)op_data[1]; Int64 divisor = *(Int64 *)op_data[2]; char *op_data[3]; char result1[100]; char result2[100]; Int64 result3 = 0; Int64 ten = 10; SimpleType opST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); BigNum opBN(16, 38, 0, 0); while(!vGT5) { op_data[0] = result1; op_data[1] = (char *) ÷nd; op_data[2] = (char *) &multiplier; rc = EXP_FIXED_BIGN_OV_MUL(&opST, &opST, op_data); if (rc) { //end of digits. break; } op_data[0] = result2; op_data[1] = result1; op_data[2] = (char *) &divisor; rc = EXP_FIXED_BIGN_OV_DIV(&opBN, &opST, op_data); if (rc) { //Something went wrong, lets consider //it as end of digits. break; } op_data[0] = result2; op_data[1] = (char *) &ten; result3 = EXP_FIXED_BIGN_OV_MOD(&opBN, &opST, op_data, &ov); if (ov) { //end of digits. break; } if(result3) { vGT5 = TRUE; break; } multiplier = EXP_FIXED_OV_MUL(multiplier, 10, &ov); if (ov) { //end of digits. break; } } } } else { Int64 divisor = 100;//devisor=10 corresponds to v digit. Int64 temp1; while(!vGT5) { temp1 = *(Int64 *)op_data[2] /divisor; if(!temp1) //reached end of digits. { break; } temp1 = *(Int64 *)op_data[1]/ temp1; if(temp1 % (Int64)10) { vGT5 = TRUE; break; } divisor = EXP_FIXED_OV_MUL(divisor, 10, &ov); if (ov) { //end of digits. break; } } } if(vGT5) { //irrespective of w being an even number, //round up the value; temp = nsign ? temp-1 : temp+1; } } } } else { ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; } } *(Int64 *)op_data[0] = temp; } break; case DIV_BIN16U_BIN16U_BIN16U: if (*(unsigned short *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } #pragma nowarn(1506) // warning elimination *(unsigned short *)op_data[0] = *(unsigned short *)op_data[1] / *(unsigned short *)op_data[2]; #pragma warn(1506) // warning elimination break; case DIV_BIN16U_BIN16U_BIN32U: if (*(unsigned short *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } *(ULng32 *)op_data[0] = *(unsigned short *)op_data[1] / *(unsigned short *)op_data[2]; break; case DIV_BIN16U_BIN32U_BIN32U: if (*(ULng32 *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } *(ULng32 *)op_data[0] = *(unsigned short *)op_data[1] / *(ULng32 *)op_data[2]; break; case DIV_BIN32U_BIN16U_BIN32U: if (*(unsigned short *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } *(ULng32 *)op_data[0] = *(ULng32 *)op_data[1] / *(unsigned short *)op_data[2]; break; case DIV_BIN32U_BIN32U_BIN32U: if (*(ULng32 *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } *(ULng32 *)op_data[0] = *(ULng32 *)op_data[1] / *(ULng32 *)op_data[2]; break; case DIV_FLOAT64_FLOAT64_FLOAT64: { if (*(double *)op_data[2] == 0) { ExRaiseSqlError(heap, diagsArea, EXE_DIVISION_BY_ZERO); return ex_expr::EXPR_ERROR; } short ov; *(double *)op_data[0] = MathReal64Div(*(double *)op_data[1], *(double *)op_data[2], &ov); if (ov) { ExRaiseSqlError(heap, diagsArea, EXE_NUMERIC_OVERFLOW); return ex_expr::EXPR_ERROR; } } break; // COMPLEX datatype operations case ADD_COMPLEX: ((ComplexType *)getOperand(0))->add(getOperand(1), getOperand(2), op_data); break; case SUB_COMPLEX: ((ComplexType *)getOperand(0))->sub(getOperand(1), getOperand(2), op_data); break; case MUL_COMPLEX: ((ComplexType *)getOperand(0))->mul(getOperand(1), getOperand(2), op_data); break; case DIV_COMPLEX: if (((ComplexType *)getOperand(0))->div(getOperand(1), getOperand(2), op_data, heap, diagsArea)) return ex_expr::EXPR_ERROR; break; case ARITH_NOT_SUPPORTED: { // this arith operation not supported. // See if it could still be evaluated by doing some intermediate // operations. if (evalUnsupportedOperations(op_data, heap, diagsArea) != ex_expr::EXPR_OK) return ex_expr::EXPR_ERROR; } break; default: ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); return ex_expr::EXPR_ERROR; } return ex_expr::EXPR_OK; }
// LCOV_EXCL_STOP ex_expr::exp_return_type ExFunctionMath::eval(char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { ex_expr::exp_return_type retcode = ex_expr::EXPR_OK; short err = 0; errno = 0; if ((getOperand()) && (getOperand(0)->getDatatype() != REC_FLOAT64)) { return evalUnsupportedOperations(op_data, heap, diagsArea); } switch (getOperType()) { case ITM_DEGREES: // radians to degrees *(double *)op_data[0] = (*(double *)op_data[1] * 180E0) / PIVALUE; break; case ITM_PI: *(double *)op_data[0] = PIVALUE; break; case ITM_RADIANS: // degrees to radians *(double *)op_data[0] = (*(double *)op_data[1] / 180E0) * PIVALUE; break; case ITM_ROUND: { double op, res; short err1 = 0, err2 = 0, err3 = 0; Int32 roundTo; roundTo = (getNumOperands() > 2) ? (Int32)(*((double*)op_data[2])) : 0; switch (getOperand(1)->getDatatype()) { case REC_IEEE_FLOAT32: op = *((float*)op_data[1]); break; case REC_IEEE_FLOAT64: op = *((double*)op_data[1]); break; default: // LCOV_EXCL_START ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("ROUND"); return ex_expr::EXPR_ERROR; // LCOV_EXCL_STOP } // // For commenting purposes, assume the following: // // op = -12.58 // roundTo = 0 // // double pow1 = MathPow(10.0, roundTo, err1); // = 1 double pow2 = MathPow(10.0, -roundTo, err2); // = 1 double pow3 = MathPow(10.0, roundTo+1, err3); // = 10 double abs1 = (op < 0.0) ? -op : op; // = 12.58 double sign = (op < 0.0) ? -1.0 : 1.0; // = -1.0 double floor1 = MathFloor(abs1*pow3, err); // = 125 double floor2 = 10.0 * MathFloor(floor1 / 10.0, err); // = 120 double floor3 = floor1 - floor2; // = 5 double floor4 = MathFloor(abs1*pow1, err); // = 12 double floor5 = pow2 * sign; // = -1.0 // Is digit at rounding position less than 5? if (floor3 < 5.0) { res = floor4 * floor5; // = -12.0 } // Is digit at rounding position greater than 5? else if (floor3 > 5.0) { res = (floor4 + 1.0) * floor5; // = -13.0 } else { // Are digits after rounding position greater than 0? if (((abs1*pow3) - floor1) > 0.0) res = (floor4 + 1.0) * floor5; // = -13.0 else { double floor6 = 2.0 * MathFloor(floor4 / 2.0, err); // = 12.0 // Now round to even if ((floor4 - floor6) == 1.0) res = (floor4 + 1.0) * floor5; // = -13.0 else res = floor4 * floor5; // = -12.0 } } *(double *)op_data[0] = res; break; } case ITM_SCALE_TRUNC: { // LCOV_EXCL_START ExRaiseSqlError(heap, diagsArea, EXE_MATH_FUNC_NOT_SUPPORTED); if (getOperType() == ITM_ROUND) **diagsArea << DgString0("ROUND"); else **diagsArea << DgString0("TRUNCATE"); retcode = ex_expr::EXPR_ERROR; } break; // LCOV_EXCL_STOP case ITM_ACOS: if ((*(double *)op_data[1] < -1) || (*(double *)op_data[1] > 1)) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("ACOS"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathAcos(*(double *)op_data[1], err); break; case ITM_ASIN: if ((*(double *)op_data[1] < -1) || (*(double *)op_data[1] > 1)) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("ASIN"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathAsin(*(double *)op_data[1], err); break; case ITM_ATAN: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathAtan(*(double *)op_data[1], err); break; case ITM_ATAN2: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathAtan2(*(double *)op_data[1], *(double *)op_data[2], err); break; case ITM_CEIL: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathCeil(*(double *)op_data[1], err); break; case ITM_COS: *(double *)op_data[0] = MathCos(*(double *)op_data[1], err); break; case ITM_COSH: *(double *)op_data[0] = MathCosh(*(double *)op_data[1], err); if (*(double *)op_data[0] == HUGE_VAL) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("COSH"); return ex_expr::EXPR_ERROR; } break; case ITM_EXP: *(double *)op_data[0] = MathExp(*(double *)op_data[1], err); // Check for overflow. if (err) // if (*(double *)op_data[0] == HUGE_VAL_REAL64) { // Overflow ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("EXP"); return ex_expr::EXPR_ERROR; } break; case ITM_FLOOR: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathFloor(*(double *)op_data[1], err); break; case ITM_LOG: if (*(double *)op_data[1] <= 0) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("LOG"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathLog(*(double *)op_data[1], err); break; case ITM_LOG10: if (*(double *)op_data[1] <= 0) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("LOG10"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathLog10(*(double *)op_data[1], err); break; case ITM_SIN: *(double *)op_data[0] = MathSin(*(double *)op_data[1], err); break; case ITM_SINH: *(double *)op_data[0] = MathSinh(*(double *)op_data[1], err); if (*(double *)op_data[0] == HUGE_VAL) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("SINH"); return ex_expr::EXPR_ERROR; } break; case ITM_SQRT: if (*(double *)op_data[1] < 0) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("SQRT"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathSqrt(*(double *)op_data[1], err); break; case ITM_TAN: *(double *)op_data[0] = MathTan(*(double *)op_data[1], err); break; case ITM_TANH: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathTanh(*(double *)op_data[1], err); break; case ITM_EXPONENT: case ITM_POWER: if (((*(double *)op_data[1] == 0) && (*(double *)op_data[2] <= 0)) || ((*(double *)op_data[1] < 0) && (MathFloor(*(double *)op_data[2], err) != *(double *)op_data[2]))) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("POWER"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathPow(*(double *)op_data[1], *(double *)op_data[2], err); if (errno == ERANGE) { // Overflow ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("POWER"); return ex_expr::EXPR_ERROR; } break; default: { ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); retcode = ex_expr::EXPR_ERROR; } break; } return retcode; }