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