void PhysSequence::computeHistoryParams(Lng32 histRecLength, Lng32 &maxRowsInOLAPBuffer, Lng32 &minNumberOfOLAPBuffers, Lng32 &numberOfWinOLAPBuffers, Lng32 &maxNumberOfOLAPBuffers, Lng32 &olapBufferSize) { Lng32 maxFWAdditionalBuffers = getDefault(OLAP_MAX_FIXED_WINDOW_EXTRA_BUFFERS); maxNumberOfOLAPBuffers = getDefault(OLAP_MAX_NUMBER_OF_BUFFERS); // For testing we may force a smaller max # rows in a buffer Lng32 forceMaxRowsInOLAPBuffer = getDefault(OLAP_MAX_ROWS_IN_OLAP_BUFFER); minNumberOfOLAPBuffers = 0; numberOfWinOLAPBuffers = 0; olapBufferSize = getDefault(OLAP_BUFFER_SIZE); Lng32 olapAvailableBufferSize = olapBufferSize - ROUND8(sizeof(HashBufferHeader)); // header // also consider the trailer reserved for DP2's checksum, for overflow only if ( getUnboundedFollowing() ) olapAvailableBufferSize -= 8 ; if ( histRecLength > olapAvailableBufferSize) { // history row exceeds size limit fir the overflow if (getUnboundedFollowing()) { *CmpCommon::diags() << DgSqlCode(-4390) << DgInt0(olapAvailableBufferSize); GenExit(); return ; } else { olapAvailableBufferSize = histRecLength; // Buffer needs to accomodate the header, but not the trailer (no O/F) olapBufferSize = histRecLength + ROUND8(sizeof(HashBufferHeader)) ; } } // Calculate the max # rows in a buffer maxRowsInOLAPBuffer = olapAvailableBufferSize / histRecLength ; // For testing - we may override the above max # rows if ( forceMaxRowsInOLAPBuffer > 0 && forceMaxRowsInOLAPBuffer < maxRowsInOLAPBuffer ) maxRowsInOLAPBuffer = forceMaxRowsInOLAPBuffer ; minNumberOfOLAPBuffers = numHistoryRows_ / maxRowsInOLAPBuffer; if ( numHistoryRows_ % maxRowsInOLAPBuffer >0) { minNumberOfOLAPBuffers++; } if (getUnboundedFollowing()) { numberOfWinOLAPBuffers = minFollowingRows_/maxRowsInOLAPBuffer ; if (minFollowingRows_ % maxRowsInOLAPBuffer >0) { numberOfWinOLAPBuffers++; } if (numberOfWinOLAPBuffers +1 > minNumberOfOLAPBuffers) { minNumberOfOLAPBuffers = numberOfWinOLAPBuffers +1 ; } //produce an error here if maxNumberOfOLAPBuffers < minNumberOfOLAPBuffers } else { maxNumberOfOLAPBuffers = minNumberOfOLAPBuffers + maxFWAdditionalBuffers; } }
short PhysSample::codeGen(Generator *generator) { // Get a local handle on some of the generator objects. // CollHeap *wHeap = generator->wHeap(); Space *space = generator->getSpace(); MapTable *mapTable = generator->getMapTable(); ExpGenerator *expGen = generator->getExpGenerator(); // Allocate a new map table for this node. This must be done // before generating the code for my child so that this local // map table will be sandwiched between the map tables already // generated and the map tables generated by my offspring. // // Only the items available as output from this node will // be put in the local map table. Before exiting this function, all of // my offsprings map tables will be removed. Thus, none of the outputs // from nodes below this node will be visible to nodes above it except // those placed in the local map table and those that already exist in // my ancestors map tables. This is the standard mechanism used in the // generator for managing the access to item expressions. // MapTable *localMapTable = generator->appendAtEnd(); // Since this operation doesn't modify the row on the way down the tree, // go ahead and generate the child subtree. Capture the given composite row // descriptor and the child's returned TDB and composite row descriptor. // ex_cri_desc * givenCriDesc = generator->getCriDesc(Generator::DOWN); child(0)->codeGen(generator); ComTdb *childTdb = (ComTdb*)generator->getGenObj(); ex_cri_desc * childCriDesc = generator->getCriDesc(Generator::UP); ExplainTuple *childExplainTuple = generator->getExplainTuple(); // Geneate the sampling expression. // ex_expr *balExpr = NULL; Int32 returnFactorOffset = 0; ValueId val; val = balanceExpr().init(); if(balanceExpr().next(val)) expGen->generateSamplingExpr(val, &balExpr, returnFactorOffset); // Alias the sampleColumns() so that they reference the underlying // expressions directly. This is done to avoid having to generate and // execute a project expression that simply moves the columns from // one tupp to another to reflect the application of the sampledCol // function. // // ValueId valId; // for(valId = sampledColumns().init(); // sampledColumns().next(valId); // sampledColumns().advance(valId)) // { // MapInfo *mapInfoChild = localMapTable->getMapInfoAsIs // (valId.getItemExpr()->child(0)->castToItemExpr()->getValueId()); // GenAssert(mapInfoChild, "Sample::codeGen -- no child map info."); // Attributes *attr = mapInfoChild->getAttr(); // MapInfo *mapInfo = localMapTable->addMapInfoToThis(valId, attr); // mapInfo->codeGenerated(); // } // check if any of the columns inthe sampled columns are lob columns. If so, return an error. ValueId valId; for(valId = sampledColumns().init(); sampledColumns().next(valId); sampledColumns().advance(valId)) { const NAType &colType = valId.getType(); if ((colType.getFSDatatype() == REC_BLOB) || (colType.getFSDatatype() == REC_CLOB)) { *CmpCommon::diags() << DgSqlCode(-4322); GenExit(); } } // Now, remove all attributes from the map table except the // the stuff in the local map table -- the result of this node. // // localMapTable->removeAll(); // Generate the expression to evaluate predicate on the sampled row. // ex_expr *postPred = 0; if (!selectionPred().isEmpty()) { ItemExpr * newPredTree = selectionPred().rebuildExprTree(ITM_AND,TRUE,TRUE); expGen->generateExpr(newPredTree->getValueId(), ex_expr::exp_SCAN_PRED, &postPred); } // Construct the Sample TDB. // ComTdbSample *sampleTdb = new(space) ComTdbSample(NULL, balExpr, returnFactorOffset, postPred, childTdb, givenCriDesc, childCriDesc, (queue_index)getDefault(GEN_SAMPLE_SIZE_DOWN), (queue_index)getDefault(GEN_SAMPLE_SIZE_UP)); generator->initTdbFields(sampleTdb); if(!generator->explainDisabled()) { generator-> setExplainTuple(addExplainInfo(sampleTdb, childExplainTuple, 0, generator)); } generator->setCriDesc(givenCriDesc, Generator::DOWN); generator->setCriDesc(childCriDesc, Generator::UP); generator->setGenObj(this, sampleTdb); return 0; }