void ElemDDLUdfOptimizationHint::synthesize(void)
{
  if (getOptimizationKind() NEQ COM_UDF_NUMBER_OF_UNIQUE_OUTPUT_VALUES OR
      uniqueOutputValuesParseTree_ EQU NULL)
    return;

  NABoolean    isErrMsgIssued = FALSE;
  ComSInt64    value = 0;
  ItemExpr   * pItemExpr = NULL;
  ConstValue * pConstVal = NULL;
  for (CollIndex i = 0; i < uniqueOutputValuesParseTree_->entries(); i++)
  {
    pItemExpr = (*uniqueOutputValuesParseTree_)[i];
    pConstVal = (ConstValue *)pItemExpr;
    if (NOT pConstVal->canGetExactNumericValue() AND NOT isErrMsgIssued)
    {
      *SqlParser_Diags << DgSqlCode(-3017) << DgString0(pConstVal->getConstStr());
      isErrMsgIssued = TRUE;
    }
    value = pConstVal->getExactNumericValue();
    uniqueOutputValues_.insert(value);
    if (value < -1 AND NOT isErrMsgIssued) // only issue the error message once
    {
      // Error: Expected a positive value or -1 (representing the default SYSTEM setting option)
      NAString valueStr = Int64ToNAString(value);
      *SqlParser_Diags << DgSqlCode(-3017) << DgString0(valueStr);
      isErrMsgIssued = TRUE;
    }
  } // for
} // ElemDDLUdfOptimizationHint::synthesize()
Exemple #2
0
void LocalView::updateDocLk(const ConstValue& doc) {
	ConstStrA docId = doc["_id"].getStringA();
	eraseDocLk(docId);
	ConstValue delFlag = doc["_deleted"];
	if (delFlag == null || delFlag.getBool() == false) {
		curDoc=doc;
		map(doc);
		curDoc = null;
	}
}
// ItmSeqOffset::preCodeGen
//
// Casts the second child to SqlInt.
//
ItemExpr *ItmSeqOffset::preCodeGen(Generator *generator)
{
  if (nodeIsPreCodeGenned())
    return this;
  
  CollHeap *wHeap = generator->wHeap();

  // The following code is being disabled (0 && ...) since it will
  // sometimes incorrectly think that the output of a tuple list of
  // contants is a single constant.  For example:
  //   SELECT a, b, c, MOVINGSUM(c,b) as MSUM, MOVINGAVG(c,b) as MAVG
  //   FROM (values
  //             (1,1, 1),
  //             (2,0, 2),
  //             (3,2, NULL),
  //             (4,0, 6),
  //             (5,3, 7)) as T(a,b,c)
  //   SEQUENCE BY a;
  //
  // For this query it will think that the offset index (b) is a
  // constant and it will use the value 3 for the
  // offsetConstantValue_.
  //
  if (0 && getArity() > 1)
  {
    NABoolean negate;
    ConstValue *cv = child(1)->castToConstValue(negate);
    if (cv AND cv->canGetExactNumericValue())
      {
        Lng32 scale;
        Int64 value = cv->getExactNumericValue(scale);

        if(scale == 0 && value >= 0 && value < INT_MAX) 
          {
            value = (negate ? -value : value);
            offsetConstantValue_ = (Int32)value;
            child(1) = NULL;
          }
      }
  }
    
  if (getArity() > 1)
  {

    const NAType &cType = child(1)->getValueId().getType();

    // (must be) signed; nulls allowed (if allowed by child1)   
   ItemExpr *castExpr   = new (wHeap) Cast (child(1),
                                           new (wHeap)
                                           SQLInt(wHeap, TRUE, cType.supportsSQLnullLogical()));
   castExpr->synthTypeAndValueId(TRUE);
   child (1) = castExpr;
  }
  return ItemExpr::preCodeGen(generator);
}
Exemple #4
0
static ConstValue sliceKey(const ConstValue &key, natural groupLevel, const Json &json) {
	if (key->isArray()) {
		if (key.length() <= groupLevel) return key;
		Container out = json.array();
		for (natural i = 0; i < groupLevel; i++)
			out.add(key[i]);
		return out;
	} else {
		return key;
	}

}
Exemple #5
0
ConstValue LocalView::runReduce(const ConstValue &rows) const {

	AutoArray<KeyAndDocId, SmallAlloc<256> > keylist;
	AutoArray<ConstValue, SmallAlloc<256> > values;
	keylist.reserve(rows.length());
	values.reserve(rows.length());
	for (JSON::ConstIterator iter = rows->getFwConstIter(); iter.hasItems();) {
		const JSON::ConstValue &v = iter.getNext();
		keylist.add(KeyAndDocId(v["key"],v["id"].getStringA()));
		values.add(v["value"]);
	}
	return reduce(keylist,values,false);

}
NATraceList
ElemDDLPartitionRange::getDetailInfo() const
{
  //
  // Note that class ElemDDLPartitionRange is derived
  // from class ElemDDLPartitionSystem.
  //
  NAString        detailText;
  NATraceList detailTextList = ElemDDLPartitionSystem::getDetailInfo();

  const ItemConstValueArray & keyValues = getKeyValueArray();

  if (keyValues.entries() NEQ 0)
  {
    detailText = "Key value list [";
    detailText += LongToNAString((Lng32)keyValues.entries());
    detailText += " key value(s)]:";
    detailTextList.append(detailText);
  }
  else
  {
    //
    // only primary (range) partition node is
    // allowed not to contain a list of key values.
    //
    detailText = "Key value not specified.";
    detailTextList.append(detailText);
  }
  for (CollIndex j = 0; j < keyValues.entries(); j++)
  {
    ConstValue * keyVal = keyValues[j];
    
    detailText = "  [key value ";
    detailText += LongToNAString((Lng32)j);
    detailText += "]";
    detailTextList.append(detailText);
    
    detailText = "    Key value:      ";
    detailText += keyVal->getText();
    detailTextList.append(detailText);
    
    detailText = "    Key value type: ";
    detailText += keyVal->getType()->getTypeSQLname();
    detailTextList.append(detailText);
  }

  return detailTextList;

} // ElemDDLPartitionRange::getDetailInfo()
Exemple #7
0
ConstValue LocalView::searchKeys(const ConstValue &keys, natural groupLevel) const {

	Shared _(lock);

	Container rows = json.array();
	bool grouped = groupLevel > 0 && groupLevel < naturalNull;

	for (natural i = 0; i < keys.length(); i++) {

		ConstValue subrows = searchOneKey(keys[i]);
		if (grouped) {
			ConstValue r = runReduce(subrows);
			if (r == null) grouped = false;
			else {
				subrows = json("key", keys[i])
					      ("value", r);
			}
		}

		rows.load(subrows);

	}

	if (groupLevel == 0) {
		 ConstValue r = runReduce(rows);
		 if (r != null) {
			 rows = json << json("key",null)
			 	 	 	 	    ("value",r);
		 }

	}
	return json("rows",rows)("total_rows",keyToValueMap.length());

}
Exemple #8
0
static bool canGroupKeys(const ConstValue &subj, const ConstValue &sliced) {
	if (sliced == null) return false;
	if (subj->isArray()) {
		natural cnt = subj.length();
		if (cnt >= sliced.length()) {
			cnt = sliced.length();
		} else {
			return false;
		}

		for (natural i = 0; i < cnt; i++) {
			if (compareJson(subj[i],sliced[i]) != cmpResultEqual) return false;
		}
		return true;
	} else {
		return compareJson(subj,sliced) == cmpResultEqual;
	}
}
Exemple #9
0
// change literals of a cacheable query into ConstantParameters 
ItemExpr* Assign::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }
  if (cwa.getPhase() == CmpMain::PARSE) {
    child(1) = child(1)->normalizeForCache(cwa, bindWA);
  }
  else if (cwa.getPhase() >= CmpMain::BIND) {
    ItemExpr *leftC=child(0), *rightC=child(1);
    OperatorTypeEnum leftO = leftC->getOperatorType();
    OperatorTypeEnum rightO = rightC->getOperatorType();
    ConstantParameter *cParam;
    if (leftO == ITM_BASECOLUMN && rightO == ITM_CONSTANT
        // normalizeForCache only constants that can be safely backpatched.
        // part of fix to CR 10-010726-4109.
        && isSafelyCoercible(cwa)  
        // normalizeForCache only constants that are contained in the original
        // SQL query so that each parameter can be backpatched by the
        // corresponding constant from the query. This is to fix regression 
        // failure MP core/test055 where a SystemLiteral was inserted when the 
        // Keytag for a MP table column is not zero. see LeafInsert::bindNode().
        // The offending query in MP core/test055 is
        //   update t055t9v set b = b + 1 where current of c10;
        && NOT ((ConstValue*)rightC)->isSystemProvided() ) {

      ConstValue *val = (ConstValue*)rightC;
      if (!val->isNull()) {
        cParam = new (cwa.wHeap()) ConstantParameter
          ((ConstValue*)rightC, cwa.wHeap(),
          ((BaseColumn*)leftC)->getNAColumn()->getType());
        cwa.addConstParam(cParam, bindWA);
        child(1) = cParam;
      }
         // else val is null; keep null as is.
         // this is part of a fix to genesis case: 10-010618-3484.
    }
    else {
      child(1) = child(1)->normalizeForCache(cwa, bindWA);
    }
  }
  markAsNormalizedForCache();
  return this;
}
ItemExpr * buildEncodeTree(desc_struct * column,
                           desc_struct * key,
                           NAString * dataBuffer, //IN:contains original value
                           Generator * generator,
                           ComDiagsArea * diagsArea)
{
  ExpGenerator * expGen = generator->getExpGenerator();

  // values are encoded by evaluating the expression:
  //    encode (cast (<dataBuffer> as <datatype>))
  // where <dataBuffer> points to the string representation of the
  //      data value to be encoded, and <datatype> contains the
  //      PIC repsentation of the columns's datatype.

  // create the CAST part of the expression using the parser.
  
  // if this is a nullable column and the key value passed in
  // is a NULL value, then treat it as a special case. A NULL value
  // is passed in as an unquoted string of characters NULL in the
  // dataBuffer. This case has to be treated different since the
  // parser doesn't recognize the syntax "CAST (NULL as <datatype>)".
  NAString ns;
  ItemExpr * itemExpr;
  NABoolean nullValue = FALSE;

  NABoolean caseinsensitiveEncode = FALSE;
  if (column->body.columns_desc.caseinsensitive)
    caseinsensitiveEncode = TRUE;

  if (column->body.columns_desc.null_flag &&
      dataBuffer->length() >= 4 &&
      str_cmp(*dataBuffer, "NULL", 4) == 0)
    {
      nullValue = TRUE;

      ns = "CAST ( @A1 AS ";
      ns += column->body.columns_desc.pictureText;
      ns += ");";
  
      // create a NULL constant
      ConstValue * nullConst = new(expGen->wHeap()) ConstValue();
      nullConst->synthTypeAndValueId();

      itemExpr = expGen->createExprTree(ns,
                                        CharInfo::UTF8,
					ns.length(),
					1, nullConst);
    }
  else
    {
      ns = "CAST ( ";
      ns += *dataBuffer;
      ns += " AS ";
      ns += column->body.columns_desc.pictureText;
      ns += ");";
  
      itemExpr = expGen->createExprTree(ns,
                                        CharInfo::UTF8,
					ns.length());
    }

  CMPASSERT(itemExpr != NULL);
  ItemExpr *boundItemExpr =
  itemExpr->bindNode(generator->getBindWA());
  if (boundItemExpr == NULL)
    return NULL;

  // make sure that the source and target values have compatible type.
  // Do this only if source is not a null value.
  NAString srcval;
  srcval = "";
  srcval += *dataBuffer;
  srcval += ";";
  ItemExpr * srcNode = expGen->createExprTree(srcval, CharInfo::UTF8, srcval.length());
  CMPASSERT(srcNode != NULL);
  srcNode->synthTypeAndValueId();
  if ((NOT nullValue) &&
      (NOT srcNode->getValueId().getType().isCompatible(itemExpr->getValueId().getType())))
    {
      if (diagsArea)
	{
	  emitDyadicTypeSQLnameMsg(-4039, 
				   itemExpr->getValueId().getType(),
				   srcNode->getValueId().getType(),
				   column->body.columns_desc.colname,
				   NULL,
				   diagsArea);
	}

      return NULL;
    }

  if (column->body.columns_desc.null_flag)
    ((NAType *)&(itemExpr->getValueId().getType()))->setNullable(TRUE);
  else
    ((NAType *)&(itemExpr->getValueId().getType()))->setNullable(FALSE);
  
  // Explode varchars by moving them to a fixed field
  // whose length is equal to the max length of varchar.
  ////collation??
  DataType datatype = column->body.columns_desc.datatype;
  if (DFS2REC::isSQLVarChar(datatype))
    {
      char lenBuf[10];
      NAString vc((NASize_T)100);	// preallocate a big-enough buf

      size_t len = column->body.columns_desc.length;
      if (datatype == REC_BYTE_V_DOUBLE) len /= SQL_DBCHAR_SIZE;

      vc = "CAST (@A1 as CHAR(";
      vc += str_itoa(len, lenBuf);
      if ( column->body.columns_desc.character_set == CharInfo::UTF8 ||
           ( column->body.columns_desc.character_set == CharInfo::SJIS &&
             column->body.columns_desc.encoding_charset == CharInfo::SJIS ) )
        {
          vc += " BYTE";
          if (len > 1)
            vc += "S";
        }
      vc += ") CHARACTER SET ";
      vc += CharInfo::getCharSetName(column->body.columns_desc.character_set);
      vc += ");";

      itemExpr = expGen->createExprTree(vc, CharInfo::UTF8, vc.length(), 1, itemExpr);
      itemExpr->synthTypeAndValueId();

      ((NAType *)&(itemExpr->getValueId().getType()))->
        setNullable(column->body.columns_desc.null_flag);
  }

  // add the encode node on top of it.
  short desc_flag = TRUE;
  if (key->body.keys_desc.ordering == 0) // ascending
    desc_flag = FALSE;
  
  itemExpr = new(expGen->wHeap()) CompEncode(itemExpr, desc_flag);
  
  itemExpr->synthTypeAndValueId();
  
  ((CompEncode*)itemExpr)->setCaseinsensitiveEncode(caseinsensitiveEncode);

  return itemExpr;
}
// computeHistoryBuffer
//
// Helper function that traverses the set of root sequence functions
// supplied by the compiler and dynamically determines the size
// of the history buffer.
// 
void PhysSequence::computeHistoryRows(const ValueIdSet &sequenceFunctions,//historyIds
                                      Lng32 &computedHistoryRows,
                                      Lng32 &unableToCalculate,
                                      NABoolean &unboundedFollowing, 
                                      Lng32 &minFollowingRows,
                                      const ValueIdSet &outputFromChild) 
{
  ValueIdSet children;
  ValueIdSet historyAttributes;
  Lng32 value = 0;

  for(ValueId valId = sequenceFunctions.init();
      sequenceFunctions.next(valId);
      sequenceFunctions.advance(valId)) 
  {
    if(valId.getItemExpr()->isASequenceFunction()) 
    {
      ItemExpr *itmExpr = valId.getItemExpr();

      switch(itmExpr->getOperatorType())
        {

        // THIS and NOT THIS are not dynamically computed
        //
        case ITM_THIS:
        case ITM_NOT_THIS:
          break;

        // The RUNNING functions and LastNotNull all need to go back just one row.
        //
        case ITM_RUNNING_SUM:
        case ITM_RUNNING_COUNT:
        case ITM_RUNNING_MIN:
        case ITM_RUNNING_MAX:
        case ITM_RUNNING_CHANGE:   
        case ITM_LAST_NOT_NULL:
          computedHistoryRows = MAXOF(computedHistoryRows, 2);
          break;
        ///set to unable to compute for now-- will change later to compte values from frameStart_ and frameEnd_
        case ITM_OLAP_SUM:
        case ITM_OLAP_COUNT:
        case ITM_OLAP_MIN:
        case ITM_OLAP_MAX:
        case ITM_OLAP_RANK:
        case ITM_OLAP_DRANK:
        {
          if ( !outputFromChild.contains(itmExpr->getValueId()))
          {
            ItmSeqOlapFunction * olap = (ItmSeqOlapFunction*)itmExpr;

            if (olap->isFrameStartUnboundedPreceding()) //(olap->getframeStart() == - INT_MAX)
            {
              computedHistoryRows = MAXOF(computedHistoryRows, 2);
            }
            else
            {
              computedHistoryRows = MAXOF(computedHistoryRows, ABS(olap->getframeStart()) + 2);
            }
            if (!olap->isFrameEndUnboundedFollowing()) //(olap->getframeEnd() != INT_MAX)
            {
              computedHistoryRows = MAXOF(computedHistoryRows, ABS(olap->getframeEnd()) + 1);
            }

            if (olap->isFrameEndUnboundedFollowing()) //(olap->getframeEnd() == INT_MAX)
            {
              unboundedFollowing = TRUE;
              if (olap->getframeStart() > 0) 
              {
                minFollowingRows = ((minFollowingRows > olap->getframeStart()) ?  
                                    minFollowingRows : olap->getframeStart());
              }
            } else  if (olap->getframeEnd() > 0)
            {
              minFollowingRows = ((minFollowingRows > olap->getframeEnd()) ?  
                                  minFollowingRows : olap->getframeEnd());
            }
          }
        }

        break;

        // If 'rows since', we cannot determine how much history is needed.  
        case ITM_ROWS_SINCE:
          unableToCalculate = 1;
          break;

        // The MOVING and OFFSET functions need to go back as far as the value
        // of their second child.
        //
        //  The second argument can be:
        //    Constant: for these, we can use the constant value to set the upper bound
        //              for the history buffer.
        //    ItmScalarMinMax(child0, child1) (with operType = ITM_SCALAR_MIN)  
        //      - if child0 or child1 is a constant, then we can use either one
        //        to set the upper bound.
        
        case ITM_MOVING_MIN:
        case ITM_MOVING_MAX:
        case ITM_OFFSET:
         
          for(Lng32 i = 1; i < itmExpr->getArity(); i++)
          {
            if (itmExpr->child(i)->getOperatorType() != ITM_NOTCOVERED)
            {
              ItemExpr * exprPtr = itmExpr->child(i);
              NABoolean negate;
              ConstValue *cv = exprPtr->castToConstValue(negate);
              if (cv AND cv->canGetExactNumericValue())
                {
                  Lng32 scale;
                  Int64 value64 = cv->getExactNumericValue(scale);

                  if(scale == 0 && value64 >= 0 && value64 < INT_MAX) 
                    {
                      value64 = (negate ? -value64 : value64);
                      value = MAXOF((Lng32)value64, value);
                    }
                 }
              else
                {
                  if (exprPtr->getOperatorType() == ITM_SCALAR_MIN)
                    {
                      for(Lng32 j = 0; j < exprPtr->getArity(); j++)
                        {
                          if (exprPtr->child(j)->getOperatorType()
                            != ITM_NOTCOVERED)
                            {
                               ItemExpr * exprPtr1 = exprPtr->child(j);
                               NABoolean negate1;
                               ConstValue *cv1 = exprPtr1->castToConstValue(negate1);
                               if (cv1 AND cv1->canGetExactNumericValue())
                                 {
                                   Lng32 scale1;
                                   Int64 value64_1 = cv1->getExactNumericValue(scale1);

                                   if(scale1 == 0 && value64_1 >= 0 && value64_1 < INT_MAX) 
                                     {
                                       value64_1 = (negate1 ? -value64_1 : value64_1);
                                       value = MAXOF((Lng32)value64_1, value);
                                     }
                                  }
                              }
                          }   
                     }   
                }  // end of inner else
            }// end of if

          }// end of for

          // Check if the value is greater than zero.
          // If it is, then save the value, but first
          // increment the returned ConstValue by one.
          // Otherwise, the offset or moving value was unable
          // to be calculated.

          if (value > 0)
          {
            value++;
            computedHistoryRows = MAXOF(computedHistoryRows, value);
            value = 0;
          }
          else
            unableToCalculate = 1;

          break;

        default:
          CMPASSERT(0);
        }
    }
   
    // Gather all the children, and if not empty, recurse down to the
    // next level of the tree.
    //

    for(Lng32 i = 0; i < valId.getItemExpr()->getArity(); i++) {
      if (//valId.getItemExpr()->child(i)->getOperatorType() != ITM_NOTCOVERED //old stuff
          !outputFromChild.contains(valId.getItemExpr()->child(i)->getValueId()))
      {
        children += valId.getItemExpr()->child(i)->getValueId();
      }
    }
  }
  
  if (NOT children.isEmpty())
  {
    computeHistoryRows(children, 
                       computedHistoryRows, 
                       unableToCalculate, 
                       unboundedFollowing, 
                       minFollowingRows,
                       outputFromChild);  
  }
} // PhysSequence::computeHistoryRows
void
ElemDDLColDef::setDefaultAttribute(ElemDDLNode * pColDefaultNode)
{
  ElemDDLColDefault * pColDefault = NULL;
  ComBoolean isIdentityColumn = FALSE;

  NAType * pColumnDataType = columnDataType_;

  if (pColDefaultNode NEQ NULL)
    {
      ComASSERT(pColDefaultNode->castToElemDDLColDefault() NEQ NULL);
      pColDefault = pColDefaultNode->castToElemDDLColDefault();
    }

  if (pColDefault NEQ NULL)
    {
      switch (pColDefault->getColumnDefaultType())
        {
        case ElemDDLColDefault::COL_NO_DEFAULT:
          defaultClauseStatus_ = NO_DEFAULT_CLAUSE_SPEC;
          break;
        case ElemDDLColDefault::COL_DEFAULT:
          {
            defaultClauseStatus_ = DEFAULT_CLAUSE_SPEC;
            
            if (pColDefault->getSGOptions())
              {
                isIdentityColumn = TRUE;
                pSGOptions_ = pColDefault->getSGOptions();
                pSGLocation_ = pColDefault->getSGLocation();
              }
            else
              {
                ComASSERT(pColDefault->getDefaultValueExpr() NEQ NULL);
                pDefault_ = pColDefault->getDefaultValueExpr();
              }
            
            // The cast ItemExpr to ConstValue for (ConstValue *)pDefault_; 
            // statement below sets arbitary value for the isNULL_. 
            // Bypass these checks for ID column (basically ITM_IDENTITY).
            ConstValue *cvDef = (ConstValue *)pDefault_;
            if ((cvDef && !cvDef->isNull()) && (!isIdentityColumn))
              {
                const NAType *cvTyp = cvDef->getType();
                NABoolean isAnErrorAlreadyIssued = FALSE;
                
                if ( cvTyp->getTypeQualifier() == NA_CHARACTER_TYPE )
                  {
                    CharInfo::CharSet defaultValueCS = ((const CharType *)cvTyp)->getCharSet();
                    // Always check for INFER_CHARSET setting before the ICAT setting.
                    NAString inferCharSetFlag;
                    if (getCharSetInferenceSetting(inferCharSetFlag) == TRUE &&
                        NOT cvDef->isStrLitWithCharSetPrefixSpecified())
                      {
                        if (pColumnDataType->getTypeQualifier() == NA_CHARACTER_TYPE
                            && ((const CharType *)pColumnDataType)->getCharSet() == CharInfo::UCS2
                            && SqlParser_DEFAULT_CHARSET == CharInfo::UCS2
                            && defaultValueCS == CharInfo::ISO88591
                            )
                          {
                            *SqlParser_Diags << DgSqlCode(-1186)
                                             << DgColumnName(ToAnsiIdentifier(getColumnName()))
                                             << DgString0(pColumnDataType->getTypeSQLname(TRUE/*terse*/))
                                             << DgString1(cvTyp->getTypeSQLname(TRUE/*terse*/));
                            isAnErrorAlreadyIssued = TRUE;
                          }
                        else
                          {
                            cvTyp = cvDef -> pushDownType(*columnDataType_, NA_CHARACTER_TYPE);
                          }
                      }
                    else if (CmpCommon::getDefault(ALLOW_IMPLICIT_CHAR_CASTING) == DF_ON &&
                             NOT cvDef->isStrLitWithCharSetPrefixSpecified() &&
                             cvTyp->getTypeQualifier() == NA_CHARACTER_TYPE &&
                             SqlParser_DEFAULT_CHARSET == CharInfo::ISO88591 &&
                             defaultValueCS == CharInfo::UnknownCharSet)
                      {
                        cvTyp = cvDef -> pushDownType(*columnDataType_, NA_CHARACTER_TYPE);
                      }
                    
                  } // column default value has character data type
                
                if (NOT isAnErrorAlreadyIssued &&
                    pColumnDataType->getTypeQualifier() == NA_CHARACTER_TYPE &&
                    cvTyp->getTypeQualifier() == NA_CHARACTER_TYPE &&
                    (
                         CmpCommon::getDefault(ALLOW_IMPLICIT_CHAR_CASTING) == DF_ON ||
                         NOT cvDef->isStrLitWithCharSetPrefixSpecified()))
                  {
                    const CharType *cdCharType = (const CharType *)pColumnDataType;
                    const CharType *cvCharType = (const CharType *)cvTyp;
                    CharInfo::CharSet cdCharSet = cdCharType->getCharSet(); // cd = column definition
                    CharInfo::CharSet cvCharSet = cvCharType->getCharSet(); // cv = constant value
                    if (cvCharSet == CharInfo::ISO88591)  // default value is a _ISO88591 str lit
                      {
                        
                      }
                    else if ( (cvCharSet == CharInfo::UNICODE ||  // default value is a _UCS2 string literal
                               cvCharSet == CharInfo::UTF8)   &&  // or a _UTF8 string literal
                              cdCharSet != cvCharSet )
                      {
                        //
                        // Check to see if all characters in the specified column default
                        // string literal value can be successfully converted/translated
                        // to the actual character set of the column.
                        //
                        char buf[2032];  // the output buffer - should be big enough
                        buf[0] = '\0';
                        enum cnv_charset eCnvCS = convertCharsetEnum( cdCharSet );
                        const char * pInStr = cvDef->getRawText()->data();
                        Int32 inStrLen = cvDef->getRawText()->length();
                        char * p1stUnstranslatedChar = NULL;
                        UInt32 outStrLenInBytes = 0;
                        unsigned charCount = 0;  // number of characters translated/converted
                        Int32 cnvErrStatus = 0;
                        char *pSubstitutionChar = NULL;
                        Int32 convFlags = 0;
                        
                        if ( cvCharSet == CharInfo::UNICODE )
                          {
                            cnvErrStatus =
                              UTF16ToLocale
                              ( cnv_version1            // in  - const enum cnv_version version
                                , pInStr                  // in  - const char *in_bufr
                                , inStrLen                // in  - const int in_len
                                , buf                     // out - const char *out_bufr
                                , 2016                    // in  - const int out_len
                                , eCnvCS                  // in  - enum cnv_charset charset
                                , p1stUnstranslatedChar   // out - char * & first_untranslated_char
                                , &outStrLenInBytes       // out - unsigned int *output_data_len_p
                                , convFlags               // in  - const int cnv_flags
                                , (Int32)TRUE               // in  - const int addNullAtEnd_flag
                                , (Int32)FALSE              // in  - const int allow_invalids
                                , &charCount              // out - unsigned int * translated_char_cnt_p
                                , pSubstitutionChar       // in  - const char *substitution_char
                                );
                          }
                        else // cvCharSet must be CharInfo::UTF8
                          {
                            cnvErrStatus =
                              UTF8ToLocale
                              ( cnv_version1            // in  - const enum cnv_version version
                                , pInStr                  // in  - const char *in_bufr
                                , inStrLen                // in  - const int in_len
                                , buf                     // out - const char *out_bufr
                                , 2016                    // in  - const int out_len
                                , eCnvCS                  // in  - enum cnv_charset charset
                                , p1stUnstranslatedChar   // out - char * & first_untranslated_char
                                , &outStrLenInBytes       // out - unsigned int *output_data_len_p
                                , (Int32)TRUE               // in  - const int addNullAtEnd_flag
                                , (Int32)FALSE              // in  - const int allow_invalids
                                , &charCount              // out - unsigned int * translated_char_cnt_p
                                , pSubstitutionChar       // in  - const char *substitution_char
                                );
                          }
                        switch (cnvErrStatus)
                          {
                          case 0: // success
                          case CNV_ERR_NOINPUT: // an empty input string will get this error code
                            {
                              ConstValue *pMBStrLitConstValue ;
                              // convert the string literal saved in cvDef (column default value)
                              // from UNICODE (e.g. UTF16) to the column character data type
                              if ( cdCharSet != CharInfo::UNICODE)
                                {
                                  NAString mbs2(buf, PARSERHEAP());  // note that buf is NULL terminated
                                  pMBStrLitConstValue =
                                    new(PARSERHEAP()) ConstValue ( mbs2
                                                                   , cdCharSet // use this for str lit prefix
                                                                   , CharInfo::DefaultCollation
                                                                   , CharInfo::COERCIBLE
                                                                   , PARSERHEAP()
                                                                   );
                                }
                              else
                                {
                                  NAWString mbs2((NAWchar*)buf, PARSERHEAP());  // note that buf is NULL terminated
                                  pMBStrLitConstValue = 
                                    new(PARSERHEAP()) ConstValue ( mbs2
                                                                   , cdCharSet // use this for str lit prefix
                                                                   , CharInfo::DefaultCollation
                                                                   , CharInfo::COERCIBLE
                                                                   , PARSERHEAP()
                                                                   );
                                }
                              delete pDefault_; // deallocate the old ConstValue object
                              cvDef = NULL;     // do not use cvDef anymore
                              pDefault_ = pMBStrLitConstValue;
                              pColDefault->setDefaultValueExpr(pDefault_);
                            }
                            break;
                          case CNV_ERR_INVALID_CHAR:
                            {
                              // 1401 ==  CAT_UNABLE_TO_CONVERT_COLUMN_DEFAULT_VALUE_TO_CHARSET
                              *SqlParser_Diags << DgSqlCode(-1401)
                                               << DgColumnName(ToAnsiIdentifier(getColumnName()))
                                               << DgString0(CharInfo::getCharSetName(cdCharSet));
                            }
                            break;
                          case CNV_ERR_BUFFER_OVERRUN: // output buffer not big enough
                          case CNV_ERR_INVALID_CS:
                          default:
                            CMPABORT_MSG("Parser internal logic error");
                            break;
                          } // switch
                      }
                    else if(!pColumnDataType->isCompatible(*cvTyp))
                      {
                        if (NOT isAnErrorAlreadyIssued)
                          {
                            *SqlParser_Diags << DgSqlCode(-1186)
                                             << DgColumnName(ToAnsiIdentifier(getColumnName()))
                                             << DgString0(pColumnDataType->getTypeSQLname(TRUE/*terse*/))
                                             << DgString1(cvTyp->getTypeSQLname(TRUE/*terse*/));
                            isAnErrorAlreadyIssued = TRUE;
                          }
                      }
                  } // column has character data type
                else
                  // if interval data type, the default value must have the same
                  // interval qualifier as the column.
                  if (NOT isAnErrorAlreadyIssued &&
                      (!pColumnDataType->isCompatible(*cvTyp) ||
                       (pColumnDataType->getTypeQualifier() == NA_INTERVAL_TYPE &&
                        pColumnDataType->getFSDatatype() != cvTyp->getFSDatatype())))
                    {
                      *SqlParser_Diags << DgSqlCode(-1186)
                                       << DgColumnName(ToAnsiIdentifier(getColumnName()))
                                       << DgString0(pColumnDataType->getTypeSQLname(TRUE/*terse*/))
                                       << DgString1(cvTyp->getTypeSQLname(TRUE/*terse*/));
                      isAnErrorAlreadyIssued = TRUE;
                    }
              }
          }
          break;
        case ElemDDLColDefault::COL_COMPUTED_DEFAULT:
          {
            defaultClauseStatus_ = DEFAULT_CLAUSE_SPEC;
            computedDefaultExpr_ = pColDefault->getComputedDefaultExpr();
          }
          break;
        default:
          CMPABORT_MSG("Parser internal logic error");
          break;
        }
    }

}
Exemple #13
0
NABoolean CmpSPOutputFormat::ElemDDLColDef2ColumnDescStruct
  (ElemDDLColDef* elem,
  const char* tableName,
  columns_desc_struct* colDesc)
{
  // Just copy the pointer for this name --
  // no need to alloc + strcpy a la copyString
  colDesc->tablename = (char *)tableName;

  colDesc->colname = copyString(elem->getColumnName());

  // colDesc->colnumber, filled outside
  
  NAType* genericType = elem->getColumnDataType();  
  colDesc->datatype = (DataType) genericType->getFSDatatype();
  colDesc->length = genericType->getNominalSize();
  colDesc->pictureText = (char *)emptyString;

  // The logic for converting from an NAType to column_desc is also
  // in the catman code -- readRealArk.cpp::convertColumn(). Any changes
  // there must be reflected here as well and vice versa.

  if ( genericType->getTypeQualifier() == NA_NUMERIC_TYPE )
    {
      NumericType & nt = *((NumericType*)genericType);
      colDesc->scale = nt.getScale();

      // if this is a float (real or double) datatype,
      // then get the precision. Otherwise, for other
      // numeric type, get the precision only if it
      // is not binary precision.
      if(nt.isExact() && nt.binaryPrecision() &&
       (nt.getFSDatatype() != REC_BPINT_UNSIGNED))
      {
        colDesc->precision = 0;
      }
      else
      {
        colDesc->precision = nt.getPrecision();
      }
    }
  else 
    {
      colDesc->scale = 0;
      colDesc->precision = 0;      
    }

#pragma nowarn(1506)   // warning elimination 
  if ( genericType->getTypeQualifier() == NA_CHARACTER_TYPE )
    {
      CharType & charType = (CharType &) *genericType;
      colDesc->character_set	  = charType.getCharSet();
      colDesc->encoding_charset	  = charType.getEncodingCharSet();
      colDesc->collation_sequence = charType.getCollation();
      colDesc->upshift		  = charType.isUpshifted();
    }

  if ( genericType->getTypeQualifier() == NA_DATETIME_TYPE ||
       genericType->getTypeQualifier() == NA_INTERVAL_TYPE )
  {
      DatetimeIntervalCommonType& dti = 
        (DatetimeIntervalCommonType& )*genericType;
      colDesc->datetimestart = dti.getStartField();
      colDesc->datetimeend = dti.getEndField();
      colDesc->datetimefractprec = dti.getFractionPrecision();
      colDesc->intervalleadingprec = dti.getLeadingPrecision();
  }
#pragma warn(1506)   // warning elimination 
  
  // offset, to be done (do we need it?)

  colDesc->null_flag = NOT elem->isNotNullConstraintSpecified();
  
  colDesc->colclass = 'U';
  colDesc->addedColumn = 0;
  colDesc->uec = (Cardinality)0;
  colDesc->highval = colDesc->lowval = 0;
  
  // defaultclass, to be done? (not referenced, not needed)

  ConstValue *pDefVal = (ConstValue*)elem->getDefaultValueExpr();
  if (!pDefVal || pDefVal->isNull())
    colDesc->defaultvalue = NULL;
  else
    colDesc->defaultvalue = copyString(pDefVal->getConstStr());
  
  return TRUE;
}