// This returns the position in contentLine of the first non-whitespace // character after the substring of contentLine which matches the indices // in indicesVector. If the indices are not matched, std::string::npos is // returned. (Also, if the line is nothing but the indices, // std::string::npos will be returned in this case as well.) inline size_t ParsingUtilities::StartOfMatchedContent( std::string const& contentLine, std::vector< int > const& indicesVector ) { size_t contentStart( contentLine.find_first_not_of( WhitespaceChars() ) ); for( std::vector< int >::const_iterator indexValue( indicesVector.begin() ); indexValue != indicesVector.end(); ++indexValue ) { contentStart = MatchesIndex( contentLine, contentStart, *indexValue ); if( contentStart == std::string::npos ) { return std::string::npos; } } return contentStart; }
short PhysUnPackRows::codeGen(Generator *generator) { // Get handles on expression generator, map table, and heap allocator // ExpGenerator *expGen = generator->getExpGenerator(); Space *space = generator->getSpace(); // Allocate a new map table for this operation // MapTable *localMapTable = generator->appendAtEnd(); // Generate the child and capture the task definition block and a description // of the reply composite row layout and the explain information. // child(0)->codeGen(generator); ComTdb *childTdb = (ComTdb*)(generator->getGenObj()); ex_cri_desc *childCriDesc = generator->getCriDesc(Generator::UP); ExplainTuple *childExplainTuple = generator->getExplainTuple(); // Make all of my child's outputs map to ATP 1. Since they are // not needed above, they will not be in the work ATP (0). // (Later, they will be removed from the map table) // localMapTable->setAllAtp(1); // Generate the given and returned composite row descriptors. // unPackRows adds a tupp (for the generated outputs) to the // row given by the parent. The workAtp will have the 2 more // tupps (1 for the generated outputs and another for the // indexValue) than the given. // ex_cri_desc *givenCriDesc = generator->getCriDesc(Generator::DOWN); ex_cri_desc *returnedCriDesc = #pragma nowarn(1506) // warning elimination new(space) ex_cri_desc(givenCriDesc->noTuples() + 1, space); #pragma warn(1506) // warning elimination ex_cri_desc *workCriDesc = #pragma nowarn(1506) // warning elimination new(space) ex_cri_desc(givenCriDesc->noTuples() + 2, space); #pragma warn(1506) // warning elimination // unPackCols is the next to the last Tp in Atp 0, the work ATP. // and the last Tp in the returned ATP. // const Int32 unPackColsAtpIndex = workCriDesc->noTuples() - 2; const Int32 unPackColsAtp = 0; // The length of the new tuple which will contain the columns // generated by unPackRows // ULng32 unPackColsTupleLen; // The Tuple Desc describing the tuple containing the new unPacked columns // It is generated when the expression is generated. // ExpTupleDesc *unPackColsTupleDesc = 0; // indexValue is the last Tp in Atp 0, the work ATP. // const Int32 indexValueAtpIndex = workCriDesc->noTuples() - 1; const Int32 indexValueAtp = 0; // The length of the work tuple which will contain the value // of the index. This should always be sizeof(int). // ULng32 indexValueTupleLen = 0; // The Tuple Desc describing the tuple containing the new unPacked columns // It is generated when the expression is generated. // ExpTupleDesc *indexValueTupleDesc = 0; ValueIdList indexValueList; if (indexValue() != NULL_VALUE_ID) { indexValueList.insert(indexValue()); expGen->processValIdList(indexValueList, ExpTupleDesc::SQLARK_EXPLODED_FORMAT, indexValueTupleLen, indexValueAtp, indexValueAtpIndex, &indexValueTupleDesc, ExpTupleDesc::SHORT_FORMAT); GenAssert(indexValueTupleLen == sizeof(Int32), "UnPackRows::codeGen: Internal Error"); } // If a packingFactor exists, generate a move expression for this. // It is assumed that the packingFactor expression evaluates to a // 4 byte integer. // ex_expr *packingFactorExpr = 0; ULng32 packingFactorTupleLen; if(packingFactor().entries() > 0) { expGen->generateContiguousMoveExpr(packingFactor(), -1, unPackColsAtp, unPackColsAtpIndex, ExpTupleDesc::SQLARK_EXPLODED_FORMAT, packingFactorTupleLen, &packingFactorExpr); GenAssert(packingFactorTupleLen == sizeof(Int32), "UnPackRows::codeGen: Internal Error"); } // Generate the UnPack expressions. // // characteristicOutputs() - refers to the list of expressions // to be move to another tuple. // // 0 - Do not add conv. nodes. // // unPackColsAtp - this expression will move data to the // unPackColsAtp (0) ATP. // // unPackColsAtpIndex - within the unPackColsAtp (0) ATP, the destination // for this move expression will be the unPackColsAtpIndex TP. This should // be the next to the last TP of the work ATP. (The indexValue will be in // the last position) // // SQLARK_EXPLODED_FORMAT - generate the move expression to construct // the destination tuple in EXPLODED FORMAT. // // unPackColsTupleLen - This is an output which will contain the length // of the destination Tuple. // // &unPackColsExpr - The address of the pointer to the expression // which will be generated. // // &unPackColsTupleDesc - The address of the tuple descriptor which is // generated. This describes the destination tuple of the move expression. // // SHORT_FORMAT - generate the unPackColsTupleDesc in the SHORT FORMAT. // ex_expr *unPackColsExpr = 0; expGen-> genGuardedContigMoveExpr(selectionPred(), getGroupAttr()->getCharacteristicOutputs(), 0, // No Convert Nodes added unPackColsAtp, unPackColsAtpIndex, ExpTupleDesc::SQLARK_EXPLODED_FORMAT, unPackColsTupleLen, &unPackColsExpr, &unPackColsTupleDesc, ExpTupleDesc::SHORT_FORMAT); #pragma nowarn(1506) // warning elimination workCriDesc->setTupleDescriptor(unPackColsAtpIndex, #pragma warn(1506) // warning elimination unPackColsTupleDesc); #pragma nowarn(1506) // warning elimination returnedCriDesc->setTupleDescriptor(unPackColsAtpIndex, #pragma warn(1506) // warning elimination unPackColsTupleDesc); // expressions for rowwise rowset implementation. ex_expr * rwrsInputSizeExpr = 0; ex_expr * rwrsMaxInputRowlenExpr = 0; ex_expr * rwrsBufferAddrExpr = 0; ULng32 rwrsInputSizeExprLen = 0; ULng32 rwrsMaxInputRowlenExprLen = 0; ULng32 rwrsBufferAddrExprLen = 0; const Int32 rwrsAtp = 1; const Int32 rwrsAtpIndex = workCriDesc->noTuples() - 2; ExpTupleDesc * rwrsTupleDesc = 0; ValueIdList rwrsVidList; if (rowwiseRowset()) { rwrsVidList.insert(this->rwrsInputSizeExpr()->getValueId()); expGen->generateContiguousMoveExpr(rwrsVidList, 0 /*don't add conv nodes*/, rwrsAtp, rwrsAtpIndex, ExpTupleDesc::SQLARK_EXPLODED_FORMAT, rwrsInputSizeExprLen, &rwrsInputSizeExpr, &rwrsTupleDesc,ExpTupleDesc::SHORT_FORMAT); rwrsVidList.clear(); rwrsVidList.insert(this->rwrsMaxInputRowlenExpr()->getValueId()); expGen->generateContiguousMoveExpr(rwrsVidList, 0 /*don't add conv nodes*/, rwrsAtp, rwrsAtpIndex, ExpTupleDesc::SQLARK_EXPLODED_FORMAT, rwrsMaxInputRowlenExprLen, &rwrsMaxInputRowlenExpr, &rwrsTupleDesc,ExpTupleDesc::SHORT_FORMAT); rwrsVidList.clear(); rwrsVidList.insert(this->rwrsBufferAddrExpr()->getValueId()); expGen->generateContiguousMoveExpr(rwrsVidList, 0 /*don't add conv nodes*/, rwrsAtp, rwrsAtpIndex, ExpTupleDesc::SQLARK_EXPLODED_FORMAT, rwrsBufferAddrExprLen, &rwrsBufferAddrExpr, &rwrsTupleDesc,ExpTupleDesc::SHORT_FORMAT); expGen->assignAtpAndAtpIndex(rwrsOutputVids(), unPackColsAtp, unPackColsAtpIndex); } // Move the generated maptable entries, to the localMapTable, // so that all other entries can later be removed. // for(ValueId outputValId = getGroupAttr()->getCharacteristicOutputs().init(); getGroupAttr()->getCharacteristicOutputs().next(outputValId); getGroupAttr()->getCharacteristicOutputs().advance(outputValId)) { generator->addMapInfoToThis(localMapTable, outputValId, generator->getMapInfo(outputValId)-> getAttr()); // Indicate that code was generated for this map table entry. // generator->getMapInfoFromThis(localMapTable, outputValId)->codeGenerated(); } NABoolean tolerateNonFatalError = FALSE; if (isRowsetIterator() && (generator->getTolerateNonFatalError())) { tolerateNonFatalError = TRUE; setTolerateNonFatalError(RelExpr::NOT_ATOMIC_); } // Allocate the UnPack TDB // ComTdbUnPackRows *unPackTdb = NULL; if (rowwiseRowset()) { unPackTdb = new (space) ComTdbUnPackRows(NULL, //childTdb, rwrsInputSizeExpr, rwrsMaxInputRowlenExpr, rwrsBufferAddrExpr, rwrsAtpIndex, givenCriDesc, returnedCriDesc, workCriDesc, 16, 1024, (Cardinality) getGroupAttr()-> getOutputLogPropList()[0]-> getResultCardinality().value(), 2, 20000); } else { // Base the initial queue size on the est. cardinality. // UnPackRows does not do dyn queue resize, so passed in // queue size values represent initial (and final) queue // sizes (not max queue sizes). // queue_index upQueueSize = (queue_index)getGroupAttr()->getOutputLogPropList()[0]->getResultCardinality().value(); // Make sure it is at least 1024. upQueueSize = (upQueueSize < 1024 ? 1024 : upQueueSize); // Make sure that it is not more the 64K. upQueueSize = (upQueueSize > 65536 ? 65536 : upQueueSize); unPackTdb = new (space) ComTdbUnPackRows(childTdb, packingFactorExpr, unPackColsExpr, #pragma nowarn(1506) // warning elimination unPackColsTupleLen, unPackColsAtpIndex, indexValueAtpIndex, givenCriDesc, returnedCriDesc, workCriDesc, 16, upQueueSize, (Cardinality) getGroupAttr()-> getOutputLogPropList()[0]-> getResultCardinality().value(), isRowsetIterator(), tolerateNonFatalError); } #pragma warn(1506) // warning elimination generator->initTdbFields(unPackTdb); // Remove child's outputs from mapTable, They are not needed // above. // generator->removeAll(localMapTable); // Add the explain Information for this node to the EXPLAIN // Fragment. Set the explainTuple pointer in the generator so // the parent of this node can get a handle on this explainTuple. // if(!generator->explainDisabled()) { generator->setExplainTuple(addExplainInfo(unPackTdb, childExplainTuple, 0, generator)); } // Restore the Cri Desc's and set the return object. // generator->setCriDesc(givenCriDesc, Generator::DOWN); generator->setCriDesc(returnedCriDesc, Generator::UP); generator->setGenObj(this, unPackTdb); return 0; }
// UnPackRows::copyTopNode ---------------------------------------------- // Copy a chain of derived nodes (Calls RelExpr::copyTopNode). // Needs to copy all relevant fields. // Used by the Cascades engine. // // Inputs: derivedNode - If Non-NULL this should point to a node // which is derived from this node. If NULL, then this // node is the top of the derivation chain and a node must // be constructed. // // Outputs: RelExpr * - A Copy of this node. // // If the 'derivedNode is non-NULL, then this method is being called // from a copyTopNode method on a class derived from this one. If it // is NULL, then this is the top of the derivation chain and an UnPackRows // node must be constructed. // // In either case, the relevant data members must be copied to 'derivedNode' // and 'derivedNode' is passed to the copyTopNode method of the class // below this one in the derivation chain (RelExpr::copyTopNode() in this // case). // RelExpr * UnPackRows::copyTopNode(RelExpr *derivedNode, CollHeap *outHeap) { UnPackRows *result; if (derivedNode == NULL) // This is the top of the derivation chain // Create an empty UnPackRows node. // { if (rowwiseRowset()) result = new (outHeap) UnPackRows(0, (ItemExpr*)NULL, (ItemExpr*)NULL, (ItemExpr*)NULL, NULL); else result = new (outHeap) UnPackRows(); } else // A node has already been constructed as a derived class. // result = (UnPackRows *) derivedNode; // Copy the relavant fields. result->unPackedTable() = unPackedTable(); result->unPackExpr() = unPackExpr(); result->packingFactor() = packingFactor(); result->maxPackingFactor_ = getMaxPackingFactor(); result->indexValue() = indexValue(); result->sysKeyId() = sysKeyId(); result->originalPreds() = originalPreds(); result->rewrittenPreds() = rewrittenPreds(); result->setRowwiseRowset(rowwiseRowset()); // copy pointer to expressions // These are not available after bindNode() // if (unPackExprTree() != NULL) result->unPackExprTree() = unPackExprTree()->copyTree(outHeap)->castToItemExpr(); if (packingFactorTree() != NULL) result->packingFactorTree() = packingFactorTree()->copyTree(outHeap)->castToItemExpr(); if (rwrsInputSizeExpr_ != NULL) result->rwrsInputSizeExpr_ = rwrsInputSizeExpr_->copyTree(outHeap)->castToItemExpr(); if (rwrsMaxInputRowlenExpr_ != NULL) result->rwrsMaxInputRowlenExpr_ = rwrsMaxInputRowlenExpr_->copyTree(outHeap)->castToItemExpr(); if (rwrsInputSizeExpr_ != NULL) result->rwrsBufferAddrExpr_ = rwrsBufferAddrExpr_->copyTree(outHeap)->castToItemExpr(); result->rwrsOutputVids_ = rwrsOutputVids_; // Copy any data members from the classes lower in the derivation chain. // return RelExpr::copyTopNode(result, outHeap); }
int jb() { JET_ERR err; eseInstance instance; if (instance.init(0) != JET_errSuccess) { return instance.getLastError(); } eseSession session; if (session.init(instance.id()) != JET_errSuccess) { return session.getLastError();; } eseDatabase db(session.id()); err = db.open("test2.edb"); if (err == JET_errDatabaseDuplicate ) { err = db.create("test2.edb"); } if (err != JET_errSuccess) { return err; } eseColumn* col0 = new eseColumn("PK", JET_coltypLong, JET_bitColumnAutoincrement); // will be destroyed by table's destructor eseColumn* col1 = new eseColumn("Value", JET_coltypText, 0, 1024, 1200); // will be destroyed by table's destructor eseIndex indexKey("PK_index", IndexKey("+PK"), JET_bitIndexPrimary); eseIndex indexValue("Value_index", IndexKey("+Value"), JET_bitIndexUnique); eseTable table(db.id(), session.id()); switch (err = table.open("TestTable")) { case JET_errSuccess: break; case JET_errObjectNotFound: // Table does not exists, open it err = table.create("TestTable", col0, col1, indexKey, indexValue); if (err != JET_errSuccess) return err; break; default: return err; } // Inserting Values wchar_t* stringsTolnsert[] = { L"FirstInsertedRow2", L"InSecondInsertedRow2", L"ThirdInsertedRow2", L"FourinsertedRow2", L"Fourinse" }; for (size_t n = 0; n != sizeof(stringsTolnsert) / sizeof(stringsTolnsert[0]); ++n) { err = table.insert(1, stringsTolnsert[n]); // insert to the second column (numbering starts from zero) } // List content of the table err = table.setCurrentIndex(indexValue); if (err != JET_errSuccess) return err; for (err = table.setCursor(JET_MoveFirst); JET_errSuccess == err; err = table.setCursor(JET_MoveNext)) { int nPK = 0; err = table.get_column(0, &nPK); if (JET_errSuccess != err) break; std::wcout << nPK; wchar_t buffer[1024] = { 0 }; err = table.get_column(1, buffer, 1024); std::wcout << L'\t' << buffer << std::endl; } if (JET_errNoCurrentRecord != err) return err; std::wcout << std::endl; // Search value in the table err = table.setCursor(JET_MoveFirst); // first movce to begining using the current index if (JET_errSuccess != err) return err; wchar_t bufferSearchCriteria[] = L"Fo"; // then set the search criteria err = ::JetMakeKey(session.id(), table.id(), &bufferSearchCriteria, sizeof(bufferSearchCriteria), JET_bitNewKey); if (JET_errSuccess != err) return err; for (err = ::JetSeek(session.id(), table.id(), JET_bitSeekGE); !(err < 0); err = table.setCursor(JET_MoveNext) ) { int nPK = 0; err = table.get_column(0, &nPK); if (JET_errSuccess != err) break; std::wcout << nPK; wchar_t buffer[1024] = { 0 }; err = table.get_column(1, buffer, 1024); std::wcout << L'\t' << buffer << std::endl; } if (JET_errNoCurrentRecord != err) return err; std::wcout << std::endl; // Another search in the table err = table.setCursor(JET_MoveFirst); if (JET_errSuccess != err) return err; err = ::JetMakeKey(session.id(), table.id(), &bufferSearchCriteria, sizeof(bufferSearchCriteria), JET_bitNewKey | JET_bitPartialColumnStartLimit); if (JET_errSuccess != err) return err; err = ::JetSeek(session.id(), table.id(), JET_bitSeekGE); if (err < 0) return err; err = ::JetMakeKey(session.id(), table.id(), &bufferSearchCriteria, sizeof(bufferSearchCriteria), JET_bitNewKey | JET_bitPartialColumnEndLimit); if (JET_errSuccess != err) return err; for (err = ::JetSetIndexRange(session.id(), table.id(), JET_bitRangeInclusive | JET_bitRangeUpperLimit); !(err < 0); table.setCursor(JET_MoveNext) ) { int nPK = 0; err = table.get_column(0, &nPK); if (JET_errSuccess != err) break; std::wcout << nPK; wchar_t buffer[1024] = { 0 }; err = table.get_column(1, buffer, 1024); std::wcout << L'\t' << buffer << std::endl; } return 0; }