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()
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); }
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; } }
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()
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()); }
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; } }
// 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; } } }
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; }