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