LmResult LmParameter::setOutDecimal(void *dataPtr, const char *source, CollHeap *heap, ComDiagsArea *diags) { LmResult result = LM_OK; // Note that this file also gets linked as lmcomp library // which is used in utilities. But this function gets called // only when this file is linked into UDR server. #ifdef LANGMAN NABoolean callerWantsDiags = (diags ? TRUE : FALSE); ex_expr::exp_return_type expRetcode = convDoIt((char*)source, str_len(source), REC_BYTE_F_ASCII, 0, 0, (char*)dataPtr + outDataOffset() , (Lng32)outSize_, fsType_, prec_, scale_, NULL, 0, heap, &diags, CONV_ASCII_DEC, NULL, 0); if (expRetcode == ex_expr::EXPR_ERROR) result = LM_ERR; // If the caller did not pass in a diags area, but convDoIt // generated a new one, we need to release the new one. if (!callerWantsDiags && diags) diags->decrRefCount(); #endif return result; }
// LCOV_EXCL_START Float32 ComTdb::getTandemFloatValue(char * v) const { Float32 f = 0; double d; // convert tandem REAL(4 byte) to IEEE FLOAT(4 byte). // If overflow, return FLT max. if (convDoIt(v, 4, REC_TDM_FLOAT32, 0, 0, (char*)&d, (Lng32)sizeof(double), REC_FLOAT64, 0, 0, NULL, 0, NULL, NULL, CONV_UNKNOWN) != ex_expr::EXPR_OK) f = -1; else if (d > FLT_MAX) f = FLT_MAX; else f = (Float32) d; return f; }
Float64 ComTdb::getTandemDoubleValue(char * v) const { Float64 f = 0; // convert tandem DOUBLE(8 bytes) to IEEE DOUBLE(8 bytes). // If overflow, return FLT max. if (convDoIt(v, 4, REC_TDM_FLOAT64, 0, 0, (char*)&f, (Lng32)sizeof(double), REC_FLOAT64, 0, 0, NULL, 0, NULL, NULL, CONV_UNKNOWN) != ex_expr::EXPR_OK) f = -1; return f; }
Int64 EXP_FIXED_OV_ADD(Int64 op1, Int64 op2, short * ov) { short rc = 0; *ov = 0; BigNum op1BN(16, 20, 0, 0); BigNum op2BN(16, 20, 0, 0); char op1BNdata[100]; char op2BNdata[100]; SimpleType op1ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); SimpleType op2ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); char * op1_data[2]; char * op2_data[2]; op1_data[0] = op1BNdata; op1_data[1] = (char*)&op1; op2_data[0] = op2BNdata; op2_data[1] = (char*)&op2; op1BN.castFrom(&op1ST, op1_data, NULL, NULL); op2BN.castFrom(&op2ST, op2_data, NULL, NULL); char * add_data[3]; char addBNdata[100]; add_data[0] = addBNdata; add_data[1] = op1BNdata; add_data[2] = op2BNdata; BigNum addBN(16, 20, 0, 0); rc = addBN.add(&op1BN, &op2BN, add_data); if (rc) { *ov = 1; return -1; } SimpleType resultST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); Int64 result; op1_data[0] = (char*)&result; op1_data[1] = add_data[0]; // rc = addBN.castTo(&resultST, op1_data); rc = convDoIt(op1_data[1], 16, REC_NUM_BIG_SIGNED, 20, 0, op1_data[0], 8, REC_BIN64_SIGNED, 0, 0, NULL, 0, NULL, NULL); if (rc) { *ov = 1; return -1; } return result; }
NA_EIDPROC SQLEXP_LIB_FUNC Int64 EXP_FIXED_BIGN_OV_MOD(Attributes * op1, Attributes * op2, char * op_data[], short * ov) { short rc = 0; *ov = 0; BigNum op1BN(16, 38, 0, 0); BigNum op2BN(16, 38, 0, 0); char op1BNdata[100]; char op2BNdata[100]; char * mod_data[3]; //convert op1 & op2 to bignum if not already bignum if(op1->isSimpleType()) { // LCOV_EXCL_START char * op1_data[2]; op1_data[0] = op1BNdata; op1_data[1] = op_data[0]; rc = op1BN.castFrom(op1, op1_data, NULL, NULL); if(rc) { *ov = 1; return -1; } mod_data[1] = op1BNdata; // LCOV_EXCL_STOP } else mod_data[1] = op_data[0]; if(op2->isSimpleType()) { char * op2_data[2]; op2_data[0] = op2BNdata; op2_data[1] = op_data[1]; rc = op2BN.castFrom(op2, op2_data, NULL, NULL); if(rc) { // LCOV_EXCL_START *ov = 1; return -1; // LCOV_EXCL_STOP } mod_data[2] = op2BNdata; } else mod_data[2] = op_data[1]; //Now begin MOD processing. Calculated //using basic operators: //z=MOD(x,y) then z = x - ((x/y)*(y)) BigNum modBN(16, 38, 0, 0); char * temp_data[3]; //calculate (x/y) char xByY[100]; temp_data[0] = xByY; temp_data[1] = mod_data[1]; temp_data[2] = mod_data[2]; char tempSpace[200]; modBN.setTempSpaceInfo(ITM_DIVIDE, (ULong)tempSpace, 200); rc = modBN.div(&op1BN, &op2BN, temp_data, NULL, NULL); if(rc) { // LCOV_EXCL_START *ov = 1; return -1; // LCOV_EXCL_STOP } //calculate (x/y) * y char xByYTimesY[100]; temp_data[0] = xByYTimesY; temp_data[1] = xByY; //temp_data[2] already contains y. rc = modBN.mul(&op1BN, &op2BN, temp_data); if(rc) { // LCOV_EXCL_START *ov = 1; return -1; // LCOV_EXCL_STOP } //Calculate final result z = x - xByYTimesY //initialize result place holder. char resultBNdata[100]; mod_data[0] = resultBNdata; //mod_data[1] already contains x. mod_data[2] = xByYTimesY; rc = modBN.sub(&op1BN, &op2BN, mod_data); if(rc) { *ov = 1; return -1; } SimpleType resultST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); Int64 result; temp_data[0] = (char*)&result; temp_data[1] = mod_data[0]; //rc = divBN.castTo(&resultST, op1_data); rc = convDoIt(temp_data[1], 16, REC_NUM_BIG_SIGNED, 38, 0, temp_data[0], 8, REC_BIN64_SIGNED, 0, 0, NULL, 0, NULL, NULL); if (rc) { *ov = 1; return -1; } return result; }
Int64 EXP_FIXED_OV_DIV(Int64 op1, Int64 op2, short * ov) { short rc = 0; *ov = 0; BigNum op1BN(16, 38, 0, 0); BigNum op2BN(16, 38, 0, 0); char op1BNdata[100]; char op2BNdata[100]; SimpleType op1ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); SimpleType op2ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); char * op1_data[2]; char * op2_data[2]; op1_data[0] = op1BNdata; op1_data[1] = (char*)&op1; op2_data[0] = op2BNdata; op2_data[1] = (char*)&op2; op1BN.castFrom(&op1ST, op1_data, NULL, NULL); op2BN.castFrom(&op2ST, op2_data, NULL, NULL); char * div_data[3]; char divBNdata[100]; div_data[0] = divBNdata; div_data[1] = op1BNdata; div_data[2] = op2BNdata; BigNum divBN(16, 38, 0, 0); char tempSpace[200]; divBN.setTempSpaceInfo(ITM_DIVIDE, (ULong)tempSpace, 200); rc = divBN.div(&op1BN, &op2BN, div_data, NULL, NULL); if (rc) { *ov = 1; return -1; } SimpleType resultST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0, ExpTupleDesc::SQLMX_FORMAT, 8, 0, 0, 0, Attributes::NO_DEFAULT, 0); Int64 result; op1_data[0] = (char*)&result; op1_data[1] = div_data[0]; //rc = divBN.castTo(&resultST, op1_data); rc = convDoIt(op1_data[1], 16, REC_NUM_BIG_SIGNED, 38, 0, op1_data[0], 8, REC_BIN64_SIGNED, 0, 0, NULL, 0, NULL, NULL); if (rc) { *ov = 1; return -1; } return result; }
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; }
void ExConvertErrorToString(CollHeap* heap, ComDiagsArea** diagsArea, char *src, Int32 srcLength, Int16 srcType, Int32 srcScale, char *result, Int32 maxResultSize ) { ex_expr::exp_return_type retCode = ex_expr::EXPR_OK; Int32 vcharLen = 0; Int32 counter; Int32 errorMark = ComDiagsArea::INVALID_MARK_VALUE; Int32 warningMark = ComDiagsArea::INVALID_MARK_VALUE; Int32 errorMark1; Int32 warningMark1; if (DFS2REC::isBinaryString(srcType)) { if(convertToHexAscii(src, srcLength, result, maxResultSize) == 0 ){ return; } result[0] = '?'; result[1] = '\0'; return; } if(*diagsArea){ errorMark = (*diagsArea)->getNumber(DgSqlCode::ERROR_); warningMark = (*diagsArea)->getNumber(DgSqlCode::WARNING_); } retCode = convDoIt( src, srcLength, //source length srcType, //source type 0, //source precision srcScale, //source scale result, //target maxResultSize, //targetlength REC_BYTE_V_ASCII, //target type 0, //target precision SQLCHARSETCODE_UTF8, //target scale (char*)&vcharLen, //vcharlength sizeof(vcharLen), //vchar length size heap, diagsArea, CONV_UNKNOWN, 0, CONV_CONTROL_LOOPING | CONV_ALLOW_INVALID_CODE_VALUE); //Before proceeding, delete any errors and warnings that may have //been introduced by convDoIt from above. if(*diagsArea){ errorMark1 = (*diagsArea)->getNumber(DgSqlCode::ERROR_); warningMark1 = (*diagsArea)->getNumber(DgSqlCode::WARNING_); counter = errorMark1 - errorMark; while(counter){ (*diagsArea)->deleteError(errorMark1 - counter); counter--; } counter = warningMark1 - warningMark; while(counter){ (*diagsArea)->deleteWarning(warningMark1 - counter); counter--; } } if (retCode == ex_expr::EXPR_OK ){ // need to zero terminate the result buffer to printf error string if (vcharLen < maxResultSize - 1) result[vcharLen] = '\0'; else result[maxResultSize - 1] = '\0'; return; } //Once we reach this point, all we can do is just dump the source memory. if(convertToHexAscii(src, srcLength, result, maxResultSize) == 0 ){ return; } // Once we reach this point, there is nothing we can do much. // Attempt to display "-E" indicating error, else NULL. if(maxResultSize >=3){ result[0] = '-'; result[1] = 'E'; result[2] = '\0'; } else result[0] = '\0'; return; }
void SessionDefaults::setSessionDefaultAttributeValue (SessionDefaultMap sda, char * attrValue, Lng32 attrValueLen) { Lng32 defaultValueAsLong = -1; NABoolean defaultValueAsBoolean = FALSE; if (attrValue) { if (sda.attributeType == SessionDefaults::SDT_BINARY_SIGNED) { ex_expr::exp_return_type rc = convDoIt(attrValue, attrValueLen, REC_BYTE_F_ASCII, 0, 0, (char*)&defaultValueAsLong, sizeof(Lng32), REC_BIN32_SIGNED, 0, 0, NULL, 0); if (rc != ex_expr::EXPR_OK) { return; // error } } else if (sda.attributeType == SessionDefaults::SDT_BOOLEAN) { if ((strcmp(attrValue, "ON") == 0) || (strcmp(attrValue, "TRUE") == 0)) defaultValueAsBoolean = TRUE; } } switch (sda.attribute) { case AQR_ENTRIES: { aqrInfo()->setAQREntriesFromInputStr(attrValue, attrValueLen); } break; case AUTO_QUERY_RETRY_WARNINGS: { if (defaultValueAsBoolean) setAQRWarnings(1); else setAQRWarnings(0); } break; case DBTR_PROCESS: { setDbtrProcess(defaultValueAsBoolean); } break; case MXCMP_PRIORITY: { setMxcmpPriority(defaultValueAsLong); } break; case MXCMP_PRIORITY_DELTA: { setMxcmpPriorityDelta(defaultValueAsLong); } break; case ESP_PRIORITY: { setEspPriority(defaultValueAsLong); } break; case ESP_PRIORITY_DELTA: { setEspPriorityDelta(defaultValueAsLong); } break; case ESP_FIXUP_PRIORITY: { setEspFixupPriority(defaultValueAsLong); } break; case ESP_FIXUP_PRIORITY_DELTA: { setEspFixupPriorityDelta(defaultValueAsLong); } break; case ESP_ASSIGN_DEPTH: { setEspAssignDepth(defaultValueAsLong); } break; case ESP_ASSIGN_TIME_WINDOW: { setEspAssignTimeWindow(defaultValueAsLong); } break; case ESP_STOP_IDLE_TIMEOUT: { setEspStopIdleTimeout(defaultValueAsLong); } break; case ESP_IDLE_TIMEOUT: { setEspIdleTimeout(defaultValueAsLong); } break; case COMPILER_IDLE_TIMEOUT: { setCompilerIdleTimeout(defaultValueAsLong); } break; case ESP_INACTIVE_TIMEOUT: { setEspInactiveTimeout(defaultValueAsLong); } break; case ESP_RELEASE_WORK_TIMEOUT: { setEspReleaseWorkTimeout(defaultValueAsLong); } break; case MAX_POLLING_INTERVAL: { setMaxPollingInterval(defaultValueAsLong); } break; case PERSISTENT_OPENS: { setPersistentOpens(defaultValueAsLong); } break; case ESP_CLOSE_ERROR_LOGGING: { setEspCloseErrorLogging(defaultValueAsBoolean); } break; case CATALOG: { setCatalog(attrValue, attrValueLen); }; break; case SCHEMA: { setSchema(attrValue, attrValueLen); }; break; case USE_LIBHDFS: { setUseLibHdfs(defaultValueAsBoolean); } break; case USER_EXPERIENCE_LEVEL: { setUEL(attrValue, attrValueLen); }; break; case RTS_TIMEOUT: { setRtsTimeout(defaultValueAsLong); } break; case ALTPRI_MASTER: { setAltpriMaster(defaultValueAsBoolean); } break; case ALTPRI_MASTER_SEQ_EXE: { setAltpriMasterSeqExe(defaultValueAsBoolean); } break; case ALTPRI_FIRST_FETCH: { setAltpriFirstFetch(defaultValueAsBoolean); } break; case ALTPRI_ESP: { setAltpriEsp(defaultValueAsBoolean); } break; case INTERNAL_FORMAT_IO: { setInternalFormatIO(defaultValueAsBoolean); } break; case ISO_MAPPING: { if (attrValueLen != strlen(SQLCHARSETSTRING_ISO88591) || strcmp(attrValue, SQLCHARSETSTRING_ISO88591) != 0) { // Ignore the specified ISO_MAPPING setting } setIsoMappingName(SQLCHARSETSTRING_ISO88591, strlen(SQLCHARSETSTRING_ISO88591)); } break; case PARENT_QID: setParentQid(attrValue, attrValueLen); break; case PARENT_QID_SYSTEM: setParentQidSystem(attrValue, attrValueLen); break; case WMS_PROCESS: setWmsProcess(defaultValueAsBoolean); break; case ESP_FREEMEM_TIMEOUT: { setEspFreeMemTimeout(defaultValueAsLong); } break; case STATISTICS_VIEW_TYPE: setStatisticsViewType(defaultValueAsLong); break; case RECLAIM_MEMORY_AFTER: setReclaimTotalMemorySize(defaultValueAsLong); break; case RECLAIM_FREE_MEMORY_RATIO: setReclaimFreeMemoryRatio(defaultValueAsLong); break; case RECLAIM_FREE_PFS_RATIO: setReclaimFreePFSRatio(defaultValueAsLong); break; case CANCEL_ESCALATION_INTERVAL: { setCancelEscalationInterval(defaultValueAsLong); } break; case CANCEL_ESCALATION_MXOSRVR_INTERVAL: { setCancelEscalationMxosrvrInterval(defaultValueAsLong); } break; case CANCEL_ESCALATION_SAVEABEND: { setCancelEscalationSaveabend(defaultValueAsBoolean); } break; case CANCEL_LOGGING: { setCancelLogging(defaultValueAsBoolean); } break; case CANCEL_QUERY_ALLOWED: { setCancelQueryAllowed(defaultValueAsBoolean); } break; case CANCEL_UNIQUE_QUERY: { setCancelUniqueQuery(defaultValueAsBoolean); } break; case SUSPEND_LOGGING: { setSuspendLogging(defaultValueAsBoolean); } break; case CALL_EMBEDDED_ARKCMP: { setCallEmbeddedArkcmp(defaultValueAsBoolean); } break; default: { } break; }; }
short Param::convertValue(SqlciEnv * sqlci_env, short targetType, Lng32 &targetLen, Lng32 targetPrecision, Lng32 targetScale, Lng32 vcIndLen, ComDiagsArea* diags) { // get rid of the old converted value if (converted_value) { delete [] converted_value; converted_value = 0; }; short sourceType; Lng32 sourceLen; // set up the source and its length based on the how the value is passed-in. if ( isInSingleByteForm() == FALSE ) { sourceLen = (Lng32)(NAWstrlen((NAWchar*)value) * BYTES_PER_NAWCHAR); switch (getCharSet()) { case CharInfo::UNICODE: sourceType = REC_NCHAR_F_UNICODE; break; case CharInfo::KANJI_MP: case CharInfo::KSC5601_MP: sourceType = REC_BYTE_F_ASCII; // KANJI/KSC passed in as NAWchar* break; default: return SQL_Error; // error case } } else { sourceLen = (Lng32)strlen(value); // for any source in single-byte format sourceType = REC_BYTE_F_ASCII; } char * pParamValue = value; if ( DFS2REC::isAnyCharacter(targetType) ) { if (termCS_ == CharInfo::UnknownCharSet) termCS_ = sqlci_env->getTerminalCharset(); if (cs == CharInfo::UnknownCharSet) { isQuotedStrWithoutCharSetPrefix_ = TRUE; cs = termCS_; } // If the target is CHARACTER and param is set as [_cs_prefix]'...', then // make sure the source is assignment compatible with the target. CharInfo::CharSet targetCharSet = (CharInfo::CharSet)targetScale; if ( targetCharSet == CharInfo::UNICODE ) { if (getUTF16StrLit() == (NAWchar*)NULL) { utf16StrLit_ = new NAWchar [ sourceLen * 2 + 1 ]; // plenty of room Lng32 utf16StrLenInNAWchars = LocaleStringToUnicode(cs/*sourceCS*/, /*sourceStr*/value, sourceLen, utf16StrLit_/*outputBuf*/, sourceLen+1/*outputBufSizeInNAWchars*/, TRUE /* in - NABoolean addNullAtEnd*/); if (sourceLen > 0 && utf16StrLenInNAWchars == 0) return SQL_Error; // ComASSERT(utf16StrLenInNAWchars == NAWstrlen(getUTF16StrLit())); // Resize the NAWchar buffer to save space NAWchar *pNAWcharBuf = new NAWchar [ utf16StrLenInNAWchars + 1 ]; NAWstrncpy (pNAWcharBuf, utf16StrLit_, utf16StrLenInNAWchars + 1); pNAWcharBuf[utf16StrLenInNAWchars] = NAWCHR('\0'); // play it safe delete [] utf16StrLit_; utf16StrLit_ = pNAWcharBuf; // do not deallocate pNAWcharBuf } sourceLen = (Lng32)(NAWstrlen(getUTF16StrLit()) * BYTES_PER_NAWCHAR); // check to see if the parameter utf16 string fits in the target if ( sourceLen > targetLen ) return SQL_Error; pParamValue = (char *)getUTF16StrLit(); sourceType = REC_NCHAR_F_UNICODE; } } else { // MP NCHAR (KANJI/KSC) can not be converted to non-character objects if ( CharInfo::is_NCHAR_MP(cs) ) return SQL_Error; } switch(targetType) { case REC_BIN16_SIGNED: case REC_BIN16_UNSIGNED: case REC_BPINT_UNSIGNED: case REC_BIN32_SIGNED: case REC_BIN32_UNSIGNED: case REC_BIN64_SIGNED: case REC_DECIMAL_UNSIGNED: case REC_DECIMAL_LSE: case REC_FLOAT32: case REC_FLOAT64: case REC_TDM_FLOAT32: case REC_TDM_FLOAT64: case REC_BYTE_F_ASCII: case REC_BYTE_V_ASCII: case REC_BYTE_V_ASCII_LONG: case REC_NCHAR_F_UNICODE: case REC_NCHAR_V_UNICODE: { char *VCLen = NULL; short VCLenSize = 0; // 5/27/98: added VARNCHAR cases if ((targetType == REC_BYTE_V_ASCII) || (targetType == REC_BYTE_V_ASCII_LONG) || (targetType == REC_NCHAR_V_UNICODE)) { // add bytes for variable length field VCLenSize = vcIndLen; //sizeof(short); VCLen = converted_value = new char[targetLen + VCLenSize]; } else converted_value = new char[targetLen]; #pragma nowarn(1506) // warning elimination ex_expr::exp_return_type ok; CharInfo::CharSet TCS = sqlci_env->getTerminalCharset(); CharInfo::CharSet ISOMAPCS = sqlci_env->getIsoMappingCharset(); NAString* tempstr; if ( DFS2REC::isAnyCharacter(sourceType) && DFS2REC::isAnyCharacter(targetType) && !(getUTF16StrLit() != NULL && sourceType == REC_NCHAR_F_UNICODE && targetScale == CharInfo::UCS2) && /*source*/cs != targetScale/*i.e., targetCharSet*/ ) { charBuf cbuf((unsigned char*)pParamValue, sourceLen); NAWcharBuf* wcbuf = 0; Int32 errorcode = 0; wcbuf = csetToUnicode(cbuf, 0, wcbuf, cs/*sourceCharSet*/ , errorcode); if (errorcode != 0) return SQL_Error; tempstr = unicodeToChar(wcbuf->data(),wcbuf->getStrLen(), targetScale/*i.e., targetCharSet*/ ); if (tempstr == NULL) return SQL_Error; //Avoid NULL ptr reference if conversion error sourceType = targetType; // we just converted it to the target type sourceLen = tempstr->length(); pParamValue = (char *)tempstr->data(); if ( sourceLen > targetLen ) return SQL_Error; } ok = convDoIt(pParamValue, sourceLen, sourceType, 0, // source Precision targetScale, // new charset we converted to &converted_value[VCLenSize], targetLen, targetType, targetPrecision, targetScale, VCLen, VCLenSize, 0, &diags); if ( ok != ex_expr::EXPR_OK) { // No need to delete allocated memory before return because class member // converted_value still points to allocated memory that is deleted in // desctructor. return SQL_Error; // error case } #pragma warn(1506) // warning elimination }; break; case REC_DATETIME: { char *VCLen = NULL; short VCLenSize = 0; converted_value = new char[targetLen + 1]; #pragma nowarn(1506) // warning elimination ex_expr::exp_return_type ok = convDoIt(value, sourceLen, sourceType, 0, // source Precision 0, // source Scale converted_value, targetLen, targetType, targetPrecision, targetScale, VCLen, VCLenSize, 0, &diags); if ( ok != ex_expr::EXPR_OK) { return SQL_Error; // error case } #pragma warn(1506) // warning elimination }; break; case REC_INT_YEAR: case REC_INT_MONTH: case REC_INT_YEAR_MONTH: case REC_INT_DAY: case REC_INT_HOUR: case REC_INT_DAY_HOUR: case REC_INT_MINUTE: case REC_INT_HOUR_MINUTE: case REC_INT_DAY_MINUTE: case REC_INT_SECOND: case REC_INT_MINUTE_SECOND: case REC_INT_HOUR_SECOND: case REC_INT_DAY_SECOND: { // convert target back to string. converted_value = new char[targetLen]; Lng32 convFlags = CONV_ALLOW_SIGN_IN_INTERVAL; #pragma nowarn(1506) // warning elimination short ok = convDoItMxcs(value, sourceLen, sourceType, 0, // source Precision 0, // source Scale converted_value, targetLen, targetType, targetPrecision, targetScale, convFlags); if ( ok != 0 ) { // No need to delete allocated memory before return because class member // converted_value still points to allocated memory that is deleted in // desctructor. return SQL_Error; // error case } #pragma warn(1506) // warning elimination }; break; case REC_NUM_BIG_UNSIGNED: case REC_NUM_BIG_SIGNED: { converted_value = new char[targetLen]; #pragma nowarn(1506) // warning elimination short ok = convDoItMxcs(value, sourceLen, sourceType, 0, // source Precision 0, // source Scale converted_value, targetLen, targetType, targetPrecision, targetScale, 0); if ( ok != 0 ) { // No need to delete allocated memory before return because class member // converted_value still points to allocated memory that is deleted in // desctructor. return SQL_Error; // error case } #pragma warn(1506) // warning elimination }; break; default: break; }; return 0; }
// error denoted by negative return code int ex_expr::formatARow2(const char** srcFldsPtr, const int* srcFldsLength, const int * srcFieldsConvIndex, char* formattedRow, int& formattedRowLength, int numAttrs, AttributesPtr * attrs, ExpTupleDesc *tupleDesc, UInt16 firstFixedOffset, UInt16 bitmapEntryOffset, UInt16 bitmapOffset, NABoolean sysKeyTable, CollHeap *heap, ComDiagsArea **diags) { formattedRowLength = tupleDesc->tupleDataLength(); //need to fix this later for other types //char *sourceData = (char*)asciiRow; //char *sourceDataEnd =(char*)asciiRow + rowLength; //assert (sourceDataEnd); //set the headers in tuple. ExpTupleDesc::setFirstFixedOffset(formattedRow, firstFixedOffset, tupleDesc->getTupleDataFormat()); //Bitmap offset value is zero if bitmap is not preset. But bitmap offset //still exists. ExpAlignedFormat::setBitmapOffset(formattedRow + bitmapEntryOffset, - bitmapOffset); char *targetData = NULL; //for varchars UInt32 vcActualLen = 0; UInt32 voaOffset = 0; UInt32 vOffset = 0; Int32 vcLenIndOffset = 0; bool firstvc = true; char paddedTimestampVal[27] = "2000-01-01 00:00:00.000000" ; int startCol = 0; if (sysKeyTable) { startCol =1; } for(int index= startCol; index < numAttrs ; index++) { //Attributes * attr = myTdb().getOutputAttr(index); Attributes * attr = attrs[index]; //loop thru all the columns in the row. For each column, //find its corresponding offset in ascii row. Corresponding //offset is identified and converted. char * srcColData = (char*)srcFldsPtr[index - startCol]; int srcColLen = srcFldsLength[index - startCol]; //set null bit map if column is nullable. //if ( attr->getDefaultClass() == Attributes::DEFAULT_NULL ) // ExpAlignedFormat::setNullValue( formattedRow, attr->getNullBitIndex() ); if (! srcColLen ) { ExpAlignedFormat::setNullValue( formattedRow, attr->getNullBitIndex() ); continue; } if((!firstvc) && attr->getVCIndicatorLength() > 0) targetData = (char*) formattedRow + vOffset; else targetData = (char*) formattedRow + attr->getOffset(); if (attr->getDatatype() == REC_DATETIME && srcColLen == 10) { srcColData = &(paddedTimestampVal[0]); srcColLen = 26; } ex_expr::exp_return_type err = convDoIt(srcColData, srcColLen, REC_BYTE_F_ASCII, 0,0, targetData, attr->getLength(), attr->getDatatype(), attr->getPrecision(), attr->getScale(), (char*)&vcActualLen, sizeof(vcActualLen), heap, diags, (conv_case_index)srcFieldsConvIndex[index] ); if(err == ex_expr::EXPR_ERROR) return -1; //update var fields parameters and adjust for subsequent var columns. if(attr->getVCIndicatorLength() > 0) { if(firstvc) { voaOffset = attr->getVoaOffset(); vOffset = attr->getOffset(); vcLenIndOffset = attr->getVCLenIndOffset(); } //obtain actual len of varchar field and update VCIndicatorLength setVCLength(formattedRow + vcLenIndOffset, attr->getVCIndicatorLength(), vcActualLen); //update voa offset location with value of offset ExpTupleDesc::setVoaValue(formattedRow, voaOffset, vcLenIndOffset, tupleDesc->getTupleDataFormat()); //update all offset vars for next varchar column ExpAlignedFormat::incrVoaOffset(voaOffset); vcLenIndOffset += (vcActualLen + attr->getVCIndicatorLength()); vOffset = vcLenIndOffset + attr->getVCIndicatorLength(); //vcIndLen remains same. firstvc = false; //update formatted row length to reflect actual len formattedRowLength = vcLenIndOffset; } } //finally adjust the data length to alignment size. See header file for more info. formattedRowLength = ExpAlignedFormat::adjustDataLength(formattedRow, formattedRowLength, ExpAlignedFormat::ALIGNMENT, TRUE); return 0; };
short BigNum::castFrom (Attributes * source, char * op_data[], NAMemory *heap, ComDiagsArea** diagsArea) { SimpleType * source1 = (SimpleType *) source; short sourceType = source1->getDatatype(); unsigned short * thisDataInShorts = (unsigned short *) op_data[0]; if ((sourceType >= REC_MIN_INTERVAL) && (sourceType <= REC_MAX_INTERVAL)) { switch (source1->getLength()) { case SQL_SMALL_SIZE: sourceType = REC_BIN16_SIGNED; break; case SQL_INT_SIZE: sourceType = REC_BIN32_SIGNED; break; case SQL_LARGE_SIZE: sourceType = REC_BIN64_SIGNED; break; } } // Initialize magnitude of Big Num to zeros. for (Int32 k = 0; k < getLength(); k++) op_data[0][k] = 0; switch (sourceType) { case REC_BIN16_SIGNED: { if ( *((short *) op_data[1]) < 0) { thisDataInShorts[0] = -*((short *) op_data[1]); BIGN_SET_SIGN(op_data[0], getLength()); } else { thisDataInShorts[0] = *((short *) op_data[1]); } } break; case REC_BPINT_UNSIGNED: case REC_BIN16_UNSIGNED: { thisDataInShorts[0] = *((unsigned short *) op_data[1]); } break; case REC_BIN32_SIGNED: { if ( *((Lng32 *) op_data[1]) < 0) { *((ULng32 *) op_data[0]) = -*((Lng32 *) op_data[1]); BIGN_SET_SIGN(op_data[0], getLength()); } else { *((ULng32 *) op_data[0]) = *((Lng32 *) op_data[1]); } #ifdef NA_LITTLE_ENDIAN // Do nothing, target is already in right format. #else // Reverse the shorts in the target. unsigned short temp = thisDataInShorts[0]; thisDataInShorts[0] = thisDataInShorts[1]; thisDataInShorts[1] = temp; #endif } break; case REC_BIN32_UNSIGNED: { *((ULng32 *) op_data[0]) = *((ULng32 *) op_data[1]); #ifdef NA_LITTLE_ENDIAN // Do nothing, target is already in right format. #else // Reverse the shorts in the target. unsigned short temp = thisDataInShorts[0]; thisDataInShorts[0] = thisDataInShorts[1]; thisDataInShorts[1] = temp; #endif } break; case REC_BIN64_SIGNED: { // Since this case is a little more complex, we call a helper method. BigNumHelper::ConvInt64ToBigNumWithSignHelper(getLength(), *((Int64 *) op_data[1]), op_data[0], FALSE); } break; case REC_BIN64_UNSIGNED: { // Since this case is a little more complex, we call a helper method. BigNumHelper::ConvInt64ToBigNumWithSignHelper(getLength(), *((Int64 *) op_data[1]), op_data[0], TRUE); } break; case REC_DECIMAL_LSE: { // Remember first char of source in temp char temp = op_data[1][0]; // Temporarily suppress sign bit in source op_data[1][0] = op_data[1][0] & 0177; // Convert source from ASCII to Big Num without sign and store in this. BigNumHelper::ConvAsciiToBigNumHelper(source1->getLength(), getLength(), op_data[1], op_data[0]); // Set sign in this (must be done after conversion to prevent overwrite) if (temp & 0200) BIGN_SET_SIGN(op_data[0], getLength()); // Restore first char in source op_data[1][0] = temp; } break; case REC_DECIMAL_UNSIGNED: { // Convert source from ASCII to Big Num without sign and store in this. BigNumHelper::ConvAsciiToBigNumHelper(source1->getLength(), getLength(), op_data[1], op_data[0]); } break; case REC_FLOAT32: { // The code below is modeled on the corresponding code in large decimals. char tempTarget[SQL_REAL_DISPLAY_SIZE + 1]; // Map of tempTarget: -d.dddddddE+dddn // 0123456789012345 // 1 // where '-' is '-' or ' '; '+' is '+' or '-'; n is null character; // and 'd' is a digit in ascii. if (convDoIt(op_data[1], 4, REC_FLOAT32, 0, 0, tempTarget, SQL_REAL_DISPLAY_SIZE, REC_BYTE_F_ASCII, 0, 0, NULL, 0, heap, diagsArea, CONV_UNKNOWN_LEFTPAD) != ex_expr::EXPR_OK) return -1; Lng32 i; // Compute the 8-digit mantissa by skipping the decimal point. ULng32 mantissa = 0; for (i = 1; i <= 9; i++) { if (i != 2) mantissa = mantissa * 10 + (tempTarget[i] - '0'); } // Get the exponent - absolute value only Lng32 exponent = 0; Lng32 multiplier = 100; for (i = 12; i < 15; i++) { exponent += (tempTarget[i] - '0') * multiplier; multiplier /= 10; } // If we're dealing with a positive exponent, then we have at least // "exponent" number of digits before a decimal point followed by "scale" // digits. Make sure that the number of digits to the left of the // decimal point (i.e. precision - scale) is >= "exponent" number of // digits. Special care is taken when the float is less than 1 - in this // case, the 0 digit before the decimal point should not count towards // the precision, since it will be ignored. if (tempTarget[11] != '-') { Int32 includeFirstDigit = (tempTarget[1] == '0') ? 0 : 1; if ((exponent + includeFirstDigit) > (getPrecision() - getScale())) return -1; } if (tempTarget[11] == '-') exponent = -exponent; // Subtract 7 from the exponent. This will set the exponent exactly // where the decimal point should be in the mantissa. exponent -= 7; // Shift down the mantissa so as to leave "scale" digits to the right of // the decimal point. Lng32 scaleBy = getScale() + exponent; if (scaleBy < 0) { Int8 roundMe= 0; for (i = 0; i < -scaleBy; i++) { roundMe = ( mantissa %10 ) > 4? 1:0; mantissa /= 10; } if(roundMe == 1) //round it mantissa++; scaleBy = 0; } // At this stage, our source is effectively = mantissa * 10^exponent. // We need to create the target Big Num by multiplying the mantissa // with 10^(scale + exponent). // Create a Big Num (without sign) for 10^(scale + exponent); // This can be stored in the temporary area pointed to by tempSpacePtr_. char * tempPowersOfTen = (char *) tempSpacePtr_; Lng32 tempPowersOfTenLength; BigNumHelper::ConvPowersOfTenToBigNumHelper(scaleBy, tempSpaceLength_, &tempPowersOfTenLength, tempPowersOfTen); // Convert the mantissa into a Big Num representation (without sign). unsigned short * mantissaDataInShorts = (unsigned short *) &mantissa; #ifdef NA_LITTLE_ENDIAN // Do nothing, mantissaData is already in the correct format. #else // Swap the two shorts in mantissaData. unsigned short temp = mantissaDataInShorts[0]; mantissaDataInShorts[0] = mantissaDataInShorts[1]; mantissaDataInShorts[1] = temp; #endif // Multiply mantissaData with tempPowersOfTen and store in this. BigNumHelper::MulHelper(getLength(), 4, tempPowersOfTenLength, (char *) &mantissa, tempPowersOfTen, op_data[0]); // Set sign of this. if ( tempTarget[0] == '-') BIGN_SET_SIGN(op_data[0], getLength()); } break; case REC_FLOAT64: { // The code below is modeled on the corresponding code in large decimals. char tempTarget[SQL_FLOAT_DISPLAY_SIZE + 1]; // Map of tempTarget: -d.dddddddddddddddddE+dddn // 01234567890123456789012345 // 1 2 // where '-' is '-' or ' '; '+' is '+' or '-'; n is null character; // and 'd' is a digit in ascii. if (convDoIt(op_data[1], 8, REC_FLOAT64, 0, 0, tempTarget, SQL_FLOAT_DISPLAY_SIZE, REC_BYTE_F_ASCII, 0, 0, NULL, 0, heap, diagsArea, CONV_UNKNOWN_LEFTPAD) != ex_expr::EXPR_OK) return -1; Lng32 i; // Compute the 18-digit mantissa by skipping the decimal point. Int64 mantissa = 0; for (i = 1; i <= 19; i++) { if (i != 2) mantissa = mantissa * 10 + (tempTarget[i] - '0'); } // Get the exponent - absolute value only Lng32 exponent = 0; Lng32 multiplier = 100; for (i = 22; i < 25; i++) { exponent += (tempTarget[i] - '0') * multiplier; multiplier /= 10; } // If we're dealing with a positive exponent, then we have at least // "exponent" number of digits before a decimal point followed by "scale" // digits. Make sure that the number of digits to the left of the // decimal point (i.e. precision - scale) is >= "exponent" number of // digits. Special care is taken when the float is less than 1 - in this // case, the 0 digit before the decimal point should not count towards // the precision, since it will be ignored. if (tempTarget[21] != '-') { Int32 includeFirstDigit = (tempTarget[1] == '0') ? 0 : 1; if ((exponent + includeFirstDigit) > (getPrecision() - getScale())) return -1; } if (tempTarget[21] == '-') exponent = -exponent; // Subtract 17 from the exponent. This will set the exponent exactly // where the decimal point should be in the mantissa. exponent -= 17; // Shift down the mantissa so as to leave "scale" digits to the right of // the decimal point. Lng32 scaleBy = getScale() + exponent; if (scaleBy < 0) { Int8 roundMe = 0; for (i = 0; i < -scaleBy; i++) { roundMe = ( mantissa %10 ) > 4? 1:0; mantissa /= 10; } if(roundMe == 1) mantissa++; scaleBy = 0; } // At this stage, our source is effectively = mantissa * 10^exponent. // We need to create the target Big Num by multiplying the mantissa // with 10^(scale + exponent). // Create a Big Num (without sign) for 10^(scale + exponent); // This can be stored in the temporary area pointed to by tempSpacePtr_. char * tempPowersOfTen = (char *) tempSpacePtr_; if (tempSpacePtr_ == 0) { tempPowersOfTen = new(heap) char[tempSpaceLength_]; } Lng32 tempPowersOfTenLength; BigNumHelper::ConvPowersOfTenToBigNumHelper(scaleBy, tempSpaceLength_, &tempPowersOfTenLength, tempPowersOfTen); // Convert the mantissa into a Big Num representation (without sign). unsigned short * mantissaDataInShorts = (unsigned short *) &mantissa; #ifdef NA_LITTLE_ENDIAN // Do nothing, mantissaData is already in the correct format. #else // Reverse the four shorts in mantissaData. unsigned short temp = mantissaDataInShorts[0]; mantissaDataInShorts[0] = mantissaDataInShorts[3]; mantissaDataInShorts[3] = temp; temp = mantissaDataInShorts[1]; mantissaDataInShorts[1] = mantissaDataInShorts[2]; mantissaDataInShorts[2] = temp; #endif // Multiply mantissaData with tempPowersOfTen and store in this. BigNumHelper::MulHelper(getLength(), 8, tempPowersOfTenLength, (char *) &mantissa, tempPowersOfTen, op_data[0]); // Set sign of this. if ( tempTarget[0] == '-') // This originally set sign to 0! //*thisSign = 0; BIGN_SET_SIGN(op_data[0], getLength()); if ((Long)tempPowersOfTen != tempSpacePtr_) NADELETEBASIC(tempPowersOfTen, heap); } break; default: { // Inform the caller that the conversion is not supported. return -1; } break; } return 0; };
void ExHdfsFastExtractTcb::convertSQRowToString(ULng32 nullLen, ULng32 recSepLen, ULng32 delimLen, tupp_descriptor* dataDesc, char* targetData, NABoolean & convError) { char* childRow = dataDesc->getTupleAddress(); ULng32 childRowLen = dataDesc->getAllocatedSize(); UInt32 vcActualLen = 0; for (UInt32 i = 0; i < myTdb().getChildTuple()->numAttrs(); i++) { Attributes * attr = myTdb().getChildTableAttr(i); Attributes * attr2 = myTdb().getChildTableAttr2(i); char *childColData = NULL; //childRow + attr->getOffset(); UInt32 childColLen = 0; UInt32 maxTargetColLen = attr2->getLength(); //format is aligned format-- //---------- // field is varchar if (attr->getVCIndicatorLength() > 0) { childColData = childRow + *((UInt32*) (childRow + attr->getVoaOffset())); childColLen = attr->getLength(childColData); childColData += attr->getVCIndicatorLength(); } else { //source is fixed length childColData = childRow + attr->getOffset(); childColLen = attr->getLength(); if ((attr->getCharSet() == CharInfo::ISO88591 || attr->getCharSet() == CharInfo::UTF8) && childColLen > 0) { // trim trailing blanks while (childColLen > 0 && childColData[childColLen - 1] == ' ') { childColLen--; } } else if (attr->getCharSet() == CharInfo::UCS2 && childColLen > 1) { ex_assert(childColLen % 2 == 0, "invalid ucs2"); NAWchar* wChildColData = (NAWchar*) childColData; Int32 wChildColLen = childColLen / 2; while (wChildColLen > 0 && wChildColData[wChildColLen - 1] == L' ') { wChildColLen--; } childColLen = wChildColLen * 2; } } if (attr->getNullFlag() && ExpAlignedFormat::isNullValue(childRow + attr->getNullIndOffset(), attr->getNullBitIndex())) { // source is a null value. nullLen = 0; if (myTdb().getNullString()) { nullLen = strlen(myTdb().getNullString()); memcpy(targetData, myTdb().getNullString(), nullLen); } targetData += nullLen; currBuffer_->bytesLeft_ -= nullLen; } else { switch ((conv_case_index) sourceFieldsConvIndex_[i]) { case CONV_ASCII_V_V: case CONV_ASCII_F_V: case CONV_UNICODE_V_V: case CONV_UNICODE_F_V: { if (childColLen > 0) { memcpy(targetData, childColData, childColLen); targetData += childColLen; currBuffer_->bytesLeft_ -= childColLen; } } break; default: ex_expr::exp_return_type err = convDoIt(childColData, childColLen, attr->getDatatype(), attr->getPrecision(), attr->getScale(), targetData, attr2->getLength(), attr2->getDatatype(), attr2->getPrecision(), attr2->getScale(), (char*) &vcActualLen, sizeof(vcActualLen), 0, 0, // diags may need to be added (conv_case_index) sourceFieldsConvIndex_[i]); if (err == ex_expr::EXPR_ERROR) { convError = TRUE; // not exit loop -- we will log the errenous row later // do not cancel processing for this type of error??? } targetData += vcActualLen; currBuffer_->bytesLeft_ -= vcActualLen; break; } //switch } if (i == myTdb().getChildTuple()->numAttrs() - 1) { strncpy(targetData, myTdb().getRecordSeparator(), recSepLen); targetData += recSepLen; currBuffer_->bytesLeft_ -= recSepLen; } else { strncpy(targetData, myTdb().getDelimiter(), delimLen); targetData += delimLen; currBuffer_->bytesLeft_ -= delimLen; } } }
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; }
// LCOV_EXCL_START ex_expr::exp_return_type ExFunctionMath::evalUnsupportedOperations( char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { if (getOperand(0)->getDatatype() == REC_TDM_FLOAT64) { // convert all child operands to double. // Do the math function 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; 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); for (Int32 i = 1; i < getNumOperands(); i++) { #pragma nowarn(1506) // warning elimination if (convDoIt(op_data[i], getOperand(i)->getLength(), getOperand(i)->getDatatype(), getOperand(i)->getPrecision(), getOperand(i)->getScale(), opDoubleData[i], (Lng32)sizeof(double), REC_FLOAT64, 0, 0, NULL, 0, heap, diagsArea, CONV_UNKNOWN) != ex_expr::EXPR_OK) return ex_expr::EXPR_ERROR; #pragma warn(1506) // warning elimination } ExFunctionMath tempMath(getOperType(), getNumOperands(), NULL, NULL); if (tempMath.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; }
Lng32 MXCI_RW_convDoIt (void *sqlciEnv, char* srcPtr, AttributeDetails* srcEntry, char *tgtPtr, AttributeDetails* tgtEntry, short formatting, ErrorValue* &e) { Lng32 retcode = 0; ULng32 convFlags = 0; if (formatting) { // if formatting, blankpad target before doing the conversion. str_pad (tgtPtr,tgtEntry->displayLen_,' '); // the formatted target will be left blank padded (blanks to the left). convFlags |= CONV_LEFT_PAD; } else convFlags = 0; // SqlciEnv * sqlci_env = (SqlciEnv *)sqlciEnv; // Check for nullability. The logic for this code // is in w:/exp/exp_conv.cpp::processNulls function // Source is nullable if (srcEntry->nullable_) { //if data is null - if source data is acutally null if ((srcPtr[0] != '\0') || (srcPtr[1] != '\0')) { if (formatting) { //if Target is not nullable if (!(tgtEntry->nullable_) ) { tgtPtr[0] = '?'; return SUCCESS; // Conversion has taken place. } else { if (e == NULL) { e = new ErrorValue; } SetError(e, -SQLCI_RW_INVALID_FORMATTING); ReportWriterError(e); return ERR; } } // end of formatting else // if not formatting { // source is nullable , source is null and target is nullable if (tgtEntry->nullable_) { str_pad (tgtPtr,2,'\377'); return SUCCESS; // Conversion has taken place. } else { if (e == NULL) { e = new ErrorValue; } SetError(e, -SQLCI_CONV_NULL_TO_NOT_NULL); ReportWriterError(e); return ERR; } }// end of else of if not formatting }// end of source data is null // source is nullable but the source data is not null else { srcPtr = (char*)srcPtr + 2; // skip the null indicator bytes } // end of else if source is nullable but source data is not null //if source is not null and target is nullable // set null indicator in target if needed. if (tgtEntry->nullable_ ) { str_pad (tgtPtr,2,'\0'); // indicate that tgt is not null. Move the ptr by 2 bytes. tgtPtr = (char*)tgtPtr + 2; } } // end of source is nullable char * VCLen = NULL; short VCLenSize = 0; if (DFS2REC::isAnyVarChar(tgtEntry->dataType_)) { VCLen = tgtPtr; VCLenSize = 2; tgtPtr = (char*)tgtPtr + VCLenSize; } // If the datatype is of time INTERVAL or of type DATETIME, then // Set the datatype to _SQLDT_ASCII_F (char) // Set the length to the display length. // Set the precision to 0. // Set the scale to 0. Lng32 length_; Lng32 dataType_; Lng32 precision_; Lng32 scale_; if ( srcEntry->dataType_ == _SQLDT_DATETIME || ( srcEntry->dataType_ >= _SQLDT_INT_Y_Y && srcEntry->dataType_ <= _SQLDT_INT_D_F) ) { length_ = srcEntry->displayLen_ ; dataType_ = 0; precision_ = 0; scale_ = 0; } else { length_ = srcEntry->length_; dataType_ = srcEntry->dataType_; precision_ = srcEntry->precision_; scale_ = srcEntry->scale_; } #pragma warning (disable : 4244) //warning elimination #pragma nowarn(1506) // warning elimination retcode = convDoIt(srcPtr, length_, dataType_, precision_, scale_, tgtPtr, tgtEntry->length_, tgtEntry->dataType_, tgtEntry->precision_, tgtEntry->scale_, VCLen, //varCharLen VCLenSize, //varCharLenSize = 2 0, //heap 0, //diagsarea CONV_UNKNOWN, 0, convFlags); #pragma warn(1506) // warning elimination #pragma warning (default : 4244) //warning elimination if (retcode) { return ERR; } else return SUCCESS; }