///////////////////////////////////////////////////////////////////// // // Contents: // // RelStoredProc::codeGen() // ////////////////////////////////////////////////////////////////////// short generateSPIOExpr(RelInternalSP * sp, Generator * generator, ExSPInputOutput * &inputExpr, ExSPInputOutput * &outputExpr) { ExpGenerator * expGen = generator->getExpGenerator(); Space * genSpace = generator->getSpace(); // Generate input(extract) expr FragmentDir * compFragDir = generator->getFragmentDir(); // create the fragment (independent code space) for this expression CollIndex myFragmentId = compFragDir->pushFragment(FragmentDir::MASTER); Space * space = generator->getSpace(); // Start generation by creating the ExSPInputOutput class. //It will be initialized later. ExSPInputOutput * lInputExpr = new(space) ExSPInputOutput(); ULng32 recordLen; ExpTupleDesc * tupleDesc = NULL; if (expGen->processValIdList(sp->procTypes(), ExpTupleDesc::SQLARK_EXPLODED_FORMAT, recordLen, 0, 1, &tupleDesc, ExpTupleDesc::LONG_FORMAT) == -1) return -1; ConvInstruction * cia = (ConvInstruction *)space->allocateMemory(sp->procTypes().entries() * sizeof(ConvInstruction)); ULng32 totalLen = space->getAllocatedSpaceSize(); lInputExpr->initialize(tupleDesc, totalLen, cia); ExSPInputOutputPtr(lInputExpr).pack(space); // the generated expr is generated in chunks internally by // the space class. Make it contiguous by allocating and // moving it to a contiguous area. char * expr = new(generator->wHeap()) char[totalLen]; space->makeContiguous((char *)expr, totalLen); inputExpr = (ExSPInputOutput *)(genSpace->allocateAndCopyToAlignedSpace((char *)expr, totalLen, 0)); compFragDir->removeFragment(); // Delete expr NADELETEBASIC(expr, generator->wHeap()); expr = NULL; // Now generate the move to output row expr myFragmentId = compFragDir->pushFragment(FragmentDir::MASTER); space = generator->getSpace(); ExSPInputOutput * lOutputExpr = new(space) ExSPInputOutput(); if (expGen->processValIdList(sp->getTableDesc()->getColumnList(), ExpTupleDesc::SQLARK_EXPLODED_FORMAT, recordLen, 0, 1, &tupleDesc, ExpTupleDesc::LONG_FORMAT) == -1) return -1; cia = (ConvInstruction *)space->allocateMemory(sp->getTableDesc()->getColumnList().entries() * sizeof(ConvInstruction)); for (short i = 0; i < (short) tupleDesc->numAttrs(); i++) { ex_conv_clause tempClause; cia[i] = tempClause.findInstruction(REC_BYTE_V_ASCII, -1, // no op tupleDesc->getAttr(i)->getDatatype(), tupleDesc->getAttr(i)->getLength(), 0); } totalLen = space->getAllocatedSpaceSize(); lOutputExpr->initialize(tupleDesc, totalLen, cia); ExSPInputOutputPtr(lOutputExpr).pack(space); expr = new(generator->wHeap()) char[totalLen]; space->makeContiguous((char *)expr, totalLen); outputExpr = (ExSPInputOutput *)(genSpace->allocateAndCopyToAlignedSpace((char *)expr, totalLen, 0)); compFragDir->removeFragment(); // Delete expr NADELETEBASIC(expr, generator->wHeap()); expr = NULL; return 0; }
/////////////////////////////////////////////////////////////////// // This function takes as input an array of key values, where each // key value is in ASCII string format (the way it is stored in // catalogs). It encodes the key values and returns the encoded // value in the encodedKeyBuffer. // RETURNS: -1, if error. 0, if all Ok. /////////////////////////////////////////////////////////////////// short encodeKeyValues(desc_struct * column_descs, desc_struct * key_descs, NAString * inValuesArray[], // INPUT NABoolean isIndex, char * encodedKeyBuffer, // OUTPUT CollHeap * h, ComDiagsArea * diagsArea) { short error = 0; // assume all will go well NABoolean deleteLater = FALSE; // set up binder/generator stuff so expressions could be generated. InitSchemaDB(); CmpStatement cmpStatement(CmpCommon::context()); ActiveSchemaDB()->createStmtTables(); BindWA bindWA(ActiveSchemaDB(), CmpCommon::context()); Generator generator(CmpCommon::context()); ExpGenerator expGen(&generator); generator.appendAtEnd(); // alloc a new map table generator.setBindWA(&bindWA); generator.setExpGenerator(&expGen); FragmentDir * compFragDir = generator.getFragmentDir(); // create the fragment (independent code space) for this expression CollIndex myFragmentId = compFragDir->pushFragment(FragmentDir::MASTER); // space where RCB will be generated Space * space = generator.getSpace(); // Let's start with a list of size 4 rather than resizing continuously ValueIdList encodedValueIdList(4); desc_struct * column = column_descs; desc_struct * key = key_descs; Int32 i = 0; if (inValuesArray == NULL) deleteLater = TRUE; while (key) { // for an index, keys_desc has columns in the same order as columns_desc, // the following for loop is not needed. if (!isIndex) { column = column_descs; for (Int32 j = 0; j < key->body.keys_desc.tablecolnumber; j++) column = column->header.next; } if (inValuesArray[i] == NULL) inValuesArray[i] = getMinMaxValue(column, key, FALSE, h); ItemExpr * itemExpr = buildEncodeTree(column, key, inValuesArray[i], &generator, diagsArea); if (! itemExpr) return -1; encodedValueIdList.insert(itemExpr->getValueId()); i++; key = key->header.next; if (isIndex) column = column->header.next; } // allocate a work cri desc to encode keys. It has // 3 entries: 0, for consts. 1, for temps. // 2, for the encoded key. ex_cri_desc * workCriDesc = new(space) ex_cri_desc(3, space); short keyAtpIndex = 2; // where the encoded key will be built ULng32 encodedKeyLen; ex_expr * keExpr = 0; expGen.generateContiguousMoveExpr(encodedValueIdList, 0 /*don't add conv nodes*/, 0 /*atp*/, keyAtpIndex, ExpTupleDesc::SQLMX_KEY_FORMAT, encodedKeyLen, &keExpr); // create a DP2 expression and initialize it with the key encode expr. ExpDP2Expr * keyEncodeExpr = new(space) ExpDP2Expr(keExpr, workCriDesc, space); keyEncodeExpr->getExpr()->fixup(0,expGen.getPCodeMode(), (ex_tcb *)space,space, h, FALSE, NULL); atp_struct * workAtp = keyEncodeExpr->getWorkAtp(); workAtp->getTupp(keyAtpIndex).setDataPointer(encodedKeyBuffer); if (keyEncodeExpr->getExpr()->eval(workAtp, 0, space) == ex_expr::EXPR_ERROR) error = -1; if (deleteLater) delete [] inValuesArray; generator.removeAll(NULL); return error; }