Exemplo n.º 1
0
/////////////////////////////////////////////////////////////////////
//
// 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;
}