NAString TDBDlgExprList::ExprNodeFlagsToString(ex_expr* exprNode) { NAString string; if (exprNode->getFixupConstsAndTemps()) string += "FIXUP_CONSTS_AND_TEMPS|"; if (exprNode->generateNoPCode()) string += "GENERATE_NO_PCODE|"; if (exprNode->getPCodeGenCompile()) string += "PCODE_GEN_COMPILE|"; if (exprNode->getPCodeMoveFastpath()) string += "PCODE_MOVE_FASTPATH|"; if (exprNode->forInsertUpdate()) string += "FOR_INSERT_UPDATE|"; if (exprNode->usePCodeEvalAligned()) string += "PCODE_EVAL_ALIGNED|"; if (exprNode->handleIndirectVC()) string += "HANDLE_INDIRECT_VC|"; if (exprNode-> getPCodeNative()) string += "PCODE_EVAL_NATIVE"; int len = string.length(); string.remove(len-1); return string; }
// // data (begin or end) is in this format: // <length><data> ... <length><data> // // a). length is 2-bytes long // b). data is <length>-bytes long // c). there are <n> such pairs, where <n> is determined by // the total length of the source and the length of each pair. // static NABoolean extractKeyValuePairs(const NAString& source, NAString& result) { char buf[1024]; const char* data = source.data(); const char* end = data + source.length(); NABoolean hasData = ( data < end); while ( data < end ) { UInt16 len = 0; memcpy((char*)&len, data, sizeof(len)); memcpy(buf, data+sizeof(len), len); buf[len] = NULL; result.append(buf); data += sizeof(len) + len; if ( data < end ) result.append(","); } return hasData; }
// ----------------------------------------------------------------------- // Translate ANSI SQL names from Default ANSI SQL Name character set // to UCS-2 encoding values. The contents of the outWcs parameter is // clear and set to the newly computed UCS2 string // ----------------------------------------------------------------------- void CmAnsiNameToUCS2(const NAString &inMbs, NAWString &outWcs) { outWcs.remove(0); // set to an empty string if (inMbs.length() <= 0) { return; } NAWString * pTargetNAWString = charToUnicode ( (Lng32)ComGetNameInterfaceCharSet() // in - Lng32 strCharSet , inMbs.data() // in - const char * str , (Int32)inMbs.length() // in - Int32 len , (NAMemory *)STMTHEAP // in - NAMemory * h ); ComASSERT(pTargetNAWString != NULL AND pTargetNAWString->length() > 0 AND pTargetNAWString->length() <= ComMAX_ANSI_IDENTIFIER_INTERNAL_LEN/*in NAWchars*/); outWcs.append(pTargetNAWString->data(), pTargetNAWString->length()); delete pTargetNAWString; }
//LCOV_EXCL_START /* : cnu -- not used on Linux */ // ----------------------------------------------------------------------- // makeSafeFilenamePart() and // QualifiedName::getQualifiedNameAsAnsiNTFilenameString() // // Genesis 10-990113-5782 // Make sure that the end result of this function results in a valid // file name for the system -- whether NT or OSS. // // Convert any invalid NT filename characters to underscores. // // A valid NT (or OSS) filename may be up to 255 characters including spaces. // The characters // \/:*?<>|" // are not allowed in the filename at all. // Furthermore, a POSIX shell (MKS KornShell on NT, OSS on NSK) // treats the following specially, so they do not make good chars for filenames: // $%&();' and space // // SQL identifiers can be up to 128 characters long in regular or // delimited format. // // Regular identifiers begin with A-Z or a-z and can contain digits 0-9 or // underscores. Regular identifiers are not case sensitive. Reserved words // may not be used in a regular identifier. // // Delimited identifiers always begin with a " character, and can contain // both upper and lowercase Latin-1 characters, as well as // \/|<>*?:" // $%&();' and space // +-=[],. // digits 0-9 and underscore // // This routine will convert all non-alphanumeric chars // to the underscore character, and result in a filename which when treated // as an Ansi qualified name (a MODULE name), is composed only of regular // identifiers -- no "quoting" needed. // // The length of a module name that might get generated // could be a string of over 255 characters. 128 for each of the three parts. // 2 characters for each part if delimited plus the period separators not // counting any quotes which are embedded and doubled which might be // singled again. // // There might still be problems because NT is not case sensitive but // SQL is where delimited identifiers are concerned and that is not being // addressed here. We're just going to assume that we won't have two // catalogs and schemas that are the same delimited if case is not considered // that will cause problems in NT. We will be replacing all characters // that cause the name to be delimited with underscore. // // If we need to truncate any one of the three parts (not generally the // user supplied portion (mainly just the module name portion), then we // will need to verify that the truncated result does not result in a // reserved word. Might possibly happen depending on how we decide to // handle the case where the length of 2 of the parts nears the 255 // character file name limit for NT and we decide to truncate one part // down to a size that might result in a reserved word. // ----------------------------------------------------------------------- // static void makeSafeFilenamePart(NAString &ns, const NAString &prefix) { size_t len = ns.length(); for (size_t i=0; i<len; i++) { if (!isalnum(ns[i]) && ns[i] != '_') ns[i] = '_'; } if (!len || !isalpha(ns[(size_t)0])) // must begin with an alphabetic ns.prepend(prefix); }
void CmpSqlSession::setSessionId(NAString &sessionID) { sessionID_ = sessionID; if (NOT sessionID_.isNull()) { volatileSchemaName_ = COM_VOLATILE_SCHEMA_PREFIX; volatileSchemaName_ += COM_SESSION_ID_PREFIX; char sName[200]; Int64 cpu_l; Int64 pin_l; Int64 schemaNameCreateTime = 0; Int64 sessionUniqNum; Lng32 userNameLen = 0; Lng32 userSessionNameLen = 0; ComSqlId::extractSqlSessionIdAttrs ((char*)sessionID.data(), sessionID.length(), segmentNum_, cpu_l, pin_l, schemaNameCreateTime, sessionUniqNum, userNameLen, NULL, userSessionNameLen, NULL); str_sprintf(sName, "%02d%03Ld%06Ld%018Ld%010Ld", ComSqlId::SQ_SQL_ID_VERSION, segmentNum_, pin_l, schemaNameCreateTime, sessionUniqNum); volatileSchemaName_ += sName; volatileSchemaName_.toUpper(); // get segment name segmentName_ = "NSK"; sessionInUse_ = TRUE; volatileSchemaInUse_ = FALSE; // // it's a new session numSessions_++; } else { sessionInUse_ = FALSE; volatileSchemaInUse_ = FALSE; } }
// ---------------------------------------------------------------------------- // method: isAuthNameReserved // // Checks to see if proposed name is reserved // // Input: authorization name // // Output: // true - name is reserved // false - name is not reserved // ---------------------------------------------------------------------------- bool CmpSeabaseDDLauth::isAuthNameReserved (const NAString &authName) { bool result; result = authName.length() >= strlen(RESERVED_AUTH_NAME_PREFIX) && authName.operator()(0,strlen(RESERVED_AUTH_NAME_PREFIX)) == RESERVED_AUTH_NAME_PREFIX || authName == "_SYSTEM" || authName == "PUBLIC" || authName == "NONE"; return result; }
// Retrieve the external database user ID from CLI Int32 SqlciEnv::getExternalUserName(NAString &username) { HandleCLIErrorInit(); char buf[1024] = ""; Int32 rc = SQL_EXEC_GetSessionAttr(SESSION_EXTERNAL_USER_NAME, NULL, buf, 1024, NULL); HandleCLIError(rc, this); if (rc >= 0) username = buf; if (username.length() == 0) username = "******"; return rc; }
// traverse queryExpr and put together its cacheKey void CacheWA::generateCacheKey(RelExpr *queryExpr, const char *sText, Lng32 charset, const NAString& viewsUsed) { if (viewsUsed.length() > 0) { qryText_ += "v:"; qryText_ += viewsUsed.data(); useView_ = TRUE; } if (isViewJoin_) { // prepend view join's text into its cache key qryText_ += sText; char cs[20]; sprintf(cs, "%d", charset); qryText_ += cs; } // save parameterized statement text into cwa.qryText_ queryExpr->generateCacheKey(*this); }
NABoolean NAClusterInfo::NODE_ID_TO_NAME(Int32 nodeId, char *nodeName, short maxLen, short *actualLen) { //Currently, this method behaves as same as NODENUMBER_TO_NODENAME_(), //which always returns "\\NSK", the only reason for doing this is to //avoid diff in regression test and core file dumped when exiting sqlci.(don't know why.) NODENUMBER_TO_NODENAME_(nodeId, nodeName, maxLen, actualLen); return TRUE; //Following code may be used in future to provide real node id to name map. *actualLen = 0; if (nodeIdToNodeNameMap_->contains(&nodeId)) { NAString * value = nodeIdToNodeNameMap_->getFirstValue(&nodeId); *actualLen = value->length(); strncpy(nodeName, value->data(), maxLen < (*actualLen) ? maxLen : (*actualLen)); return TRUE; } return FALSE; }
NABoolean CmpSqlSession::validateVolatileName(const char * name) { ComObjectName volTabName(name); NAString schemaNamePart = volTabName.getSchemaNamePartAsAnsiString(TRUE); schemaNamePart.toUpper(); ULng32 len = MINOF(schemaNamePart.length(), strlen(COM_VOLATILE_SCHEMA_PREFIX)); if ((len < strlen(COM_VOLATILE_SCHEMA_PREFIX)) || (strncmp(schemaNamePart.data(), COM_VOLATILE_SCHEMA_PREFIX, len) != 0)) { return FALSE; } return TRUE; }
// ----------------------------------------------------------------------- // Translate ANSI SQL names from UCS-2/UTF-16 encoding values to // the Default ANSI SQL Name character set. // ----------------------------------------------------------------------- void CmAnsiNameToUTF8(const NAWString &inWcs, NAString &outMbs) { outMbs.remove(0); // set to an empty string if (inWcs.length() <= 0) { return; } NAString *pConvStr = unicodeToChar ( inWcs.data() // in - const char * str , (Int32)inWcs.length() // in - Int32 len , (Lng32)ComGetNameInterfaceCharSet() // in - Lng32 strCharSet , (NAMemory *)STMTHEAP // in - NAMemory * h , FALSE // in - NABoolean allowInvalidChar ); if (pConvStr != NULL AND pConvStr->length() > 0) { outMbs = *pConvStr; } delete pConvStr; }
Int32 parseMVAge(const NAString& mvAge) { Int32 result = 0; float number=0; char textChars[20]; if (mvAge.length() < 15) { if (sscanf(mvAge.data(), "%f %s", &number, textChars) == 2) { const NAString text(textChars); if (!text.compareTo("Seconds", NAString::ignoreCase)) { result = (Int32)floor(number); } else if (!text.compareTo("Minutes", NAString::ignoreCase)) { result = (Int32)floor(number*60); } else if (!text.compareTo("Hours", NAString::ignoreCase)) { result = (Int32)floor(number*60*60); } else if (!text.compareTo("Days", NAString::ignoreCase)) { result = (Int32)floor(number*60*60*24); } } } if (result == 0) { QRLogger::log(CAT_MVCAND, LL_ERROR, "Invalid setting for MV_AGE default value: %s, Using only fresh MVs.", mvAge.data()); } return result; }
// ---------------------------------------------------------------------------- // Method: glueQueryFragments // // This method combines the pieces of the metadata query into a single // statement. As part of this process, the leading spaces are removed. // // Input: queryArraySize - number of fragments to glue together // QueryString - the fragments // // Output: gluedQuery - the concatenated fragments // gluedQuerySize - the final length // // Space is allocated for the gluedQuery // ---------------------------------------------------------------------------- void ExExeUtilTcb::glueQueryFragments(Lng32 queryArraySize, const QueryString * queryArray, char * &gluedQuery, Lng32 &gluedQuerySize) { Int32 i = 0; gluedQuerySize = 0; gluedQuery = NULL; NAString concatenatedQuery; NAString tempStr; for (i = 0; i < queryArraySize; i++) { tempStr = queryArray[i].str; concatenatedQuery += tempStr.strip(NAString::leading, ' '); } gluedQuerySize = concatenatedQuery.length(); gluedQuery = new(getMyHeap()) char[gluedQuerySize + 100]; strncpy(gluedQuery, concatenatedQuery.data(), gluedQuerySize); gluedQuery[gluedQuerySize] = '\0'; }
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; }
NABoolean HHDFSMasterHostList::initializeWithSeaQuestNodes() { NABoolean result = FALSE; FILE *pp; NAString fakeNodeNames = ActiveSchemaDB()->getDefaults().getValue(HIVE_USE_FAKE_SQ_NODE_NAMES); if (fakeNodeNames.length() <= 1) { // execute the command "sqshell -c node" and open a pipe to the output of this command. pp = popen("sqshell -c node", "r"); if (pp != NULL) { // we want to add all the nodes returned by sqshell such that their HostIds // assigned here in class HHDFSMasterHostList matches their SeaQuest host number HostId nextHostId = getHosts()->entries(); while (1) { char *line; char buf[1000]; line = fgets(buf, sizeof buf, pp); if (line == NULL) { // if we inserted anything without encountering an error, consider that success numSQNodes_ = getHosts()->entries(); result = (numSQNodes_ > 0); break; } char *nodeNum = strstr(line, "Node["); if (nodeNum) { nodeNum += 5; // skip the matched text int nodeId = atoi(nodeNum); if (nodeId != nextHostId) break; // out-of-sequence host ids are not supported char *nodeName = strstr(nodeNum, "="); if (nodeName == NULL) break; // expecting "=" sign in the sqshell output nodeName++; char *nodeEnd = strstr(nodeName, ","); if (nodeEnd == NULL) break; // couldn't find the end of the node name *nodeEnd = 0; // resolve the found name to make it a fully qualified DNS name, // like HDFS also uses it struct hostent * h = gethostbyname(nodeName); if (h) nodeName = h->h_name; HostId checkId = getHostNumInternal(nodeName); if (checkId != nodeId) if (checkId > nodeId) break; // something must have gone wrong, this should not happen else { // checkId < nodeId, this can happen if we have duplicate // node ids. In this case, insert a dummy node to take up the // number, so we stay in sync sprintf(buf, "dummy.node.%d.nosite.com", nodeId); HostId checkId2 = getHostNumInternal(buf); if (checkId2 != nodeId) break; // again, not expecting to get here // remember that we mave multiple SQ nodes // on the same physical node hasVirtualSQNodes_ = TRUE; } nextHostId++; } } pclose(pp); } } else { // seed the host name list with fake SQ node names from the CQD insted const char delim = ','; const char *nodeStart = fakeNodeNames; const char *nodeEnd; do { // this is debug code, no error check, no blanks in this string!!! char buf[500]; nodeEnd = strchrnul(nodeStart, delim); strncpy(buf, nodeStart, nodeEnd-nodeStart); getHostNumInternal(buf); nodeStart = nodeEnd+1; } while (*nodeEnd != 0); numSQNodes_ = getHosts()->entries(); result = (numSQNodes_ > 0); } return result; }
Lng32 HSSqTableDef::DescribeColumnNames() { Lng32 entry, len; NAString query; char colName[ComMAX_1_PART_INTERNAL_UTF8_NAME_LEN_IN_BYTES + 2]; HSLogMan *LM = HSLogMan::Instance(); SQLMODULE_ID module; init_SQLMODULE_ID(&module); SQLSTMT_ID *stmt = new(STMTHEAP) SQLSTMT_ID; init_SQLCLI_OBJ_ID(stmt); stmt->module = &module; stmt->name_mode = stmt_handle; SQLDESC_ID *srcDesc = new(STMTHEAP) SQLDESC_ID; init_SQLCLI_OBJ_ID(srcDesc); srcDesc->module = &module; srcDesc->name_mode = desc_handle; SQLDESC_ID *outputDesc = new(STMTHEAP) SQLDESC_ID; init_SQLCLI_OBJ_ID(outputDesc); outputDesc->module = &module; outputDesc->name_mode = desc_handle; // Use the header information from a 'select *' to get the column names. // Note that this works for SJIS and UTF8 since the names returned through // CLI are encoded correctly. retcode_ = setHasSyskeyFlag(); HSHandleError(retcode_); if (hasSyskey_) query = "SELECT SYSKEY, * FROM "; else query = "SELECT * FROM "; if(objActualFormat_ == SQLMP) query += getTableName(tableName_->data(), nameSpace_); else query += getTableName(ansiName_->data(), nameSpace_); retcode_ = SQL_EXEC_ClearDiagnostics(stmt); // to prevent false alarms for statement heap memory allocation "smt" // coverity[leaked_storage] HSHandleError(retcode_); retcode_ = SQL_EXEC_AllocStmt(stmt, 0); HSHandleError(retcode_); retcode_ = SQL_EXEC_AllocDesc(srcDesc, 1); HSHandleError(retcode_); retcode_ = SQL_EXEC_AllocDesc(outputDesc, 4096); HSHandleError(retcode_); retcode_ = SQL_EXEC_SetDescItem(srcDesc, 1, SQLDESC_TYPE_FS, REC_BYTE_V_ANSI, 0); HSHandleError(retcode_); retcode_ = SQL_EXEC_SetDescItem(srcDesc, 1, SQLDESC_VAR_PTR, (Long)query.data(), 0); HSHandleError(retcode_); retcode_ = SQL_EXEC_SetDescItem(srcDesc, 1, SQLDESC_LENGTH, #pragma nowarn(1506) // warning elimination query.length() + 1, 0); #pragma warn(1506) // warning elimination HSHandleError(retcode_); // SQLDESC_CHAR_SET must be the last descriptor item set, otherwise // it may get reset by other calls to SQL_EXEC_SetDescItem(). NAString charSet = ActiveSchemaDB()->getDefaults().getValue(ISO_MAPPING); NAString defCS = ActiveSchemaDB()->getDefaults().getValue(DEFAULT_CHARSET); retcode_ = SQL_EXEC_SetDescItem(srcDesc, 1, SQLDESC_CHAR_SET, SQLCHARSETCODE_UTF8 , 0); HSHandleError(retcode_); // --------------------------------------------------------------------- // Prepare the statement // --------------------------------------------------------------------- SQL_QUERY_COST_INFO query_cost_info; SQL_QUERY_COMPILER_STATS_INFO comp_stats_info; retcode_ = SQL_EXEC_Prepare2(stmt, srcDesc,NULL,0,NULL,&query_cost_info, &comp_stats_info,NULL,0,0); HSHandleError( retcode_); // --------------------------------------------------------------------- // describe the column information into the output descriptor // --------------------------------------------------------------------- retcode_ = SQL_EXEC_DescribeStmt(stmt, 0, outputDesc); HSHandleError(retcode_); retcode_ = SQL_EXEC_GetDescEntryCount(outputDesc, &numCols_); HSHandleError(retcode_); colInfo_ = new(STMTHEAP) HSColumnStruct[numCols_]; for (Int32 i = 0; i < numCols_; i++) { /*== GET COLUMN NAME ==*/ entry = i + 1; retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_NAME, 0, colName, sizeof(colName), &len, 0); if ((retcode_ == 0) && (len >= sizeof(colName) )) retcode_ = -1; HSHandleError(retcode_); colName[len] = '\0'; *colInfo_[i].colname = &*colName; /*== GET COLUMN DATATYPE ==*/ retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_TYPE_FS, &colInfo_[i].datatype, 0, 0, 0, 0); HSHandleError(retcode_); retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_NULLABLE, &colInfo_[i].nullflag, 0, 0, 0, 0); HSHandleError(retcode_); /*== GET COLUMN LENGTH ==*/ retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_OCTET_LENGTH, &colInfo_[i].length, 0, 0, 0, 0); HSHandleError(retcode_); // If applicable, get the character set, precision and scale if (DFS2REC::isAnyCharacter(colInfo_[i].datatype)) { retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_CHAR_SET, (Lng32*)&colInfo_[i].charset, 0, 0, 0, 0); HSHandleError(retcode_); // UCS2 cols not supported in MODE_SPECIAL_1 or 2 and do not support case insensitivity. retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_CASEINSENSITIVE, (Lng32*)&colInfo_[i].caseInsensitive, 0, 0, 0, 0); HSHandleError(retcode_); retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_COLLATION, (Lng32*)&colInfo_[i].colCollation, 0, 0, 0, 0); HSHandleError(retcode_); } else if ((colInfo_[i].datatype >= REC_MIN_BINARY && // May be type NUMERIC colInfo_[i].datatype <= REC_MAX_BINARY) // instead of INT || (colInfo_[i].datatype >= REC_MIN_DECIMAL && colInfo_[i].datatype <= REC_MAX_DECIMAL)) { retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_PRECISION, &colInfo_[i].precision, 0, 0, 0, 0); HSHandleError(retcode_); retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_SCALE, &colInfo_[i].scale, 0, 0, 0, 0); HSHandleError(retcode_); } else if (DFS2REC::isDateTime(colInfo_[i].datatype)) { retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_DATETIME_CODE, &colInfo_[i].precision, 0, 0, 0, 0); HSHandleError(retcode_); retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_PRECISION, &colInfo_[i].scale, 0, 0, 0, 0); HSHandleError(retcode_); } else if (DFS2REC::isInterval(colInfo_[i].datatype)) { retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_INT_LEAD_PREC, &colInfo_[i].precision, 0, 0, 0, 0); HSHandleError(retcode_); retcode_ = SQL_EXEC_GetDescItem(outputDesc, entry, SQLDESC_PRECISION, &colInfo_[i].scale, 0, 0, 0, 0); HSHandleError(retcode_); } else { /* No additional information about column attributes needed */ } if (LM->LogNeeded()) { sprintf(LM->msg, "COLUMN [%s]: (%d, %d, %d, %d, %d, %d)" , colInfo_[i].colname->data() , colInfo_[i].datatype , colInfo_[i].nullflag , colInfo_[i].charset , colInfo_[i].length , colInfo_[i].precision , colInfo_[i].scale ); LM->Log(LM->msg); } } retcode_ = SQL_EXEC_DeallocStmt(stmt); HSHandleError(retcode_); return 0; }
// // This is the LmUtility.nativeUtils method. It takes one string as // input and produces one string as output. The output string gets // written to the first element of the String[] array object passed in // as the jobjectArray parameter. // // Although we do not document this method for customers, there is // nothing preventing customer code from calling this method. So don't // put anything in the method that you wouldn't want customers // doing. Currently this function just serves as an entry point to // various systems calls such as TMF operations and getting/setting // environment variables. There is nothing here that customers could // not do on their own if they wanted to. // JNIEXPORT void JNICALL Java_org_trafodion_sql_udr_LmUtility_nativeUtils (JNIEnv * env, jclass jc, jstring js, jobjectArray joa) { const char *input = env->GetStringUTFChars(js, NULL); if (input == NULL) { // OutOfMemory error already thrown return; } NAString action(input); TrimNAStringSpace(action); short error; NAString result("OK"); static MXStatement staticStmt; // LCOV_EXCL_START if (action.compareTo("GetTxName", NAString::ignoreCase) == 0) { Int64 transid; error = GETTRANSID((short *) &transid); if (error) { if (error == 75) { result = "No active transaction"; } else { result = "GETTRANSID returned "; result += LongToNAString((Lng32) error); } Throw(env, result.data()); } else { short actualLen; char text[256]; error = TRANSIDTOTEXT(transid, text, 255, &actualLen); if (error) { result = "TRANSIDTOTEXT returned "; result += LongToNAString((Lng32) error); Throw(env, result); } else { text[actualLen] = 0; result = text; } } } // GetTxName else if (action.compareTo("BeginTx", NAString::ignoreCase) == 0) { Int32 tag; error = BEGINTRANSACTION(&tag); if (error) { result = "BEGINTRANSACTION returned "; result += LongToNAString((Lng32) error); Throw(env, result); } } // BeginTx else if (action.compareTo("CommitTx", NAString::ignoreCase) == 0) { error = ENDTRANSACTION(); if (error) { if (error == 75) { result = "No active transaction"; } else { result = "ENDTRANSACTION returned "; result += LongToNAString((Lng32) error); } Throw(env, result); } } // CommitTx else if (action.compareTo("RollbackTx", NAString::ignoreCase) == 0) { error = ABORTTRANSACTION(); if (error) { if (error == 75) { result = "No active transaction"; } else { result = "ABORTTRANSACTION returned "; result += LongToNAString((Lng32) error); } Throw(env, result); } } // RollbackTx else if (action.compareTo("GetProcessId", NAString::ignoreCase) == 0) { Lng32 pid = GETPID(); result = LongToNAString(pid); } // GetProcessId else if (action.index("GetEnv ", 0, NAString::ignoreCase) == 0) { NAString name = action; name.remove(0, str_len("GetEnv ")); TrimNAStringSpace(name); char *value = getenv(name.data()); if (value != NULL) { result = value; } else { result = ""; } } // GetEnv else if (action.index("PutEnv ", 0, NAString::ignoreCase) == 0) { NAString nameAndValue = action; nameAndValue.remove(0, str_len("PutEnv ")); TrimNAStringSpace(nameAndValue); Int32 retcode = putenv((char *) nameAndValue.data()); if (retcode != 0) { result = "putenv returned "; result += LongToNAString((Lng32) retcode); Throw(env, result); } } // PutEnv else if (action.index("LmDebug ", 0, NAString::ignoreCase) == 0) { NAString name = action; name.remove(0, str_len("LmDebug ")); LM_DEBUG0(name.data()); } // LmDebug else if (action.index("ExecSql ", 0, NAString::ignoreCase) == 0) { NAString stmtText = action.remove(0, str_len("ExecSql ")); MXStatement s; const char *status = "OK"; Lng32 retcode = 0; retcode = s.init(status); if (retcode == 0) { retcode = s.prepare(stmtText.data()); if (retcode != 0) { status = "PREPARE failed"; } } if (retcode == 0) { retcode = s.execute(); if (retcode != 0) { status = "EXECUTE failed"; } } if (retcode == 0) { retcode = s.fetchEOD(); if (retcode != 0) { status = "FETCH failed"; } } if (retcode == 0) { retcode = s.close(); if (retcode != 0) { status = "CLOSE failed"; } } if (retcode != 0) { char msg[256]; sprintf(msg, "[UdrSqlException %d] %s", retcode, status); Throw(env, msg); } } // ExecSql else if (action.index("FetchSql ", 0, NAString::ignoreCase) == 0) { // The incoming string is SQL statement text. The code below will // prepare and execute the statement then fetch only the first // row. It will build one long multi-line string containing all // column values, one on each line. The multi-line string can be // split by the Java caller into an array of Strings with the // split("\n") method. Lng32 i; NAString stmtText = action.remove(0, str_len("FetchSql ")); MXStatement s; const char *status = "OK"; Lng32 retcode = 0; retcode = s.init(status); if (!retcode) { retcode = s.prepare(stmtText.data()); if (retcode) status = "PREPARE failed"; } if (!retcode) { retcode = s.execute(); if (retcode) status = "EXECUTE failed"; } Lng32 numOutColumns = s.getNumOutColumns(); NABoolean stringsAllocated = FALSE; char **argv = NULL; if (!retcode && numOutColumns > 0) { argv = new char *[numOutColumns]; Lng32 bufLen = 1000; for (i = 0; i < numOutColumns; i++) argv[i] = new char[bufLen + 1]; stringsAllocated = TRUE; retcode = s.fetchStrings(argv, bufLen); if (retcode) status = "FETCH STRINGS failed"; if (!retcode) { result = argv[0]; for (i = 1; i < numOutColumns; i++) { result += "\n"; result += argv[i]; } } } if (!retcode) { retcode = s.fetchEOD(); if (retcode) status = "FETCH EOD failed"; } if (!retcode) { retcode = s.close(); if (retcode) status = "CLOSE failed"; } if (stringsAllocated) { for (i = 0; i < numOutColumns; i++) delete [] argv[i]; delete [] argv; } if (retcode) { char msg[256]; sprintf(msg, "[UdrSqlException %d] %s", retcode, status); Throw(env, msg); } } // FetchSql else if (action.index("Prepare ", 0, NAString::ignoreCase) == 0) { NAString stmtText = action.remove(0, str_len("Prepare ")); const char *status = "OK"; Lng32 retcode = 0; retcode = staticStmt.init(status); if (retcode == 0) { retcode = staticStmt.prepare(stmtText.data()); if (retcode != 0) { status = "PREPARE failed"; } } if (retcode) { char msg[256]; sprintf(msg, "[UdrSqlException %d] %s", retcode, status); Throw(env, msg); } } // Prepare else if (action.index("ExecUsingString ", 0, NAString::ignoreCase) == 0) { NAString data = action.remove(0, str_len("ExecUsingString ")); const char *status = "OK"; Lng32 retcode = 0; if (retcode == 0) { retcode = staticStmt.executeUsingString(data.data(), (Lng32) data.length()); if (retcode != 0) { status = "EXECUTE failed"; } } if (retcode == 0) { retcode = staticStmt.fetchEOD(); if (retcode != 0) { status = "FETCH failed"; } } if (retcode == 0) { retcode = staticStmt.close(); if (retcode != 0) { status = "CLOSE failed"; } } if (retcode != 0) { char msg[256]; sprintf(msg, "[UdrSqlException %d] %s", retcode, status); Throw(env, msg); } } // ExecUsingString else if (action.index("FetchUsingString ", 0, NAString::ignoreCase) == 0) { NAString data = action.remove(0, str_len("FetchUsingString ")); const char *status = "OK"; Lng32 retcode = 0; Int32 i = 0; if (!retcode) { retcode = staticStmt.executeUsingString(data.data(), (Lng32) data.length()); if (retcode) status = "EXECUTE failed"; } Lng32 numOutColumns = staticStmt.getNumOutColumns(); NABoolean stringsAllocated = FALSE; char **argv = NULL; if (!retcode && numOutColumns > 0) { argv = new char *[numOutColumns]; Lng32 bufLen = 1000; for (i = 0; i < numOutColumns; i++) argv[i] = new char[bufLen + 1]; stringsAllocated = TRUE; retcode = staticStmt.fetchStrings(argv, bufLen); if (retcode) status = "FETCH STRINGS failed"; if (!retcode) { result = argv[0]; for (i = 1; i < numOutColumns; i++) { result += "\n"; result += argv[i]; } } } if (!retcode) { retcode = staticStmt.fetchEOD(); if (retcode) status = "FETCH EOD failed"; } if (!retcode) { retcode = staticStmt.close(); if (retcode) status = "CLOSE failed"; } if (stringsAllocated) { for (i = 0; i < numOutColumns; i++) delete [] argv[i]; delete [] argv; } if (retcode) { char msg[256]; sprintf(msg, "[UdrSqlException %d] %s", retcode, status); Throw(env, msg); } } // FetchUsingString else { // // Over time other operations can be supported // result = "Invalid action: "; result += action; Throw(env, result); } // LCOV_EXCL_STOP // // Create the Java output string // if (env->ExceptionCheck() == JNI_FALSE) { jobject j = env->NewStringUTF(result.data()); env->SetObjectArrayElement(joa, 0, j); } }
Lng32 AddColumnSet(HSColSet &colSet) { HSGlobalsClass *hs_globals = GetHSContext(); Lng32 retcode = 0; HSColGroupStruct *newGroup = NULL; Lng32 colCount = 0; NABoolean badColList = FALSE; NAString colNames = ""; NAString temp; HSLogMan *LM = HSLogMan::Instance(); Int32 numCols = colSet.entries(); Int32 i; if (numCols < 2) // Must have at least 2 columns in multi-col set. { if (LM->LogNeeded()) { sprintf(LM->msg, "\t\tIgnoring Column Group with single unique entry (%s)", colSet[0].colname->data()); LM->Log(LM->msg); } return HS_WARNING; } for (i=0; i<numCols; i++) // update column numbers, position & NO DUPLICATES { HSColumnStruct &col = colSet[i]; temp = " "; temp += ToAnsiIdentifier(col.colname->data()); // Note: ToAnsiIdentifier() determines whether a name needs to be delimited // with quotes. This function works for shift-JIS but may not work for other // non-ISO88591 char sets such as Korean, BIG5, GB2312, and GB18030, ... temp += ","; if (colNames.contains(temp)) badColList = TRUE; else { col.colnum = hs_globals->objDef->getColNum((char*)col.colname->data()); if (col.colnum < 0) { retcode = -1; HSHandleError(retcode); } col.position = colCount; colCount++; } colNames += temp; } colNames.remove(0,1); // remove first blank colNames.remove(colNames.length() - 1); // remove last comma if (badColList) // column list contains repeating columns { if (LM->LogNeeded()) { sprintf(LM->msg, "\t\tNon-Unique Column Group (%s)", colNames.data()); LM->Log(LM->msg); } HSFuncMergeDiags(- UERR_COLUMNLIST_NOT_UNIQUE, colNames.data()); retcode = -1; HSHandleError(retcode); } else { if (GroupExists(colSet)) { if (LM->LogNeeded()) { sprintf(LM->msg, "\t\tDuplicate Column Group (%s) has been ignored.", colNames.data()); LM->Log(LM->msg); } retcode = HS_WARNING; } else { newGroup = new(STMTHEAP) HSColGroupStruct; newGroup->colSet = colSet; newGroup->colCount = colCount; *newGroup->colNames = colNames.data(); if (hs_globals->multiGroup == NULL) // first group entry { hs_globals->multiGroup = newGroup; } else // append to front of list { newGroup->next = hs_globals->multiGroup; hs_globals->multiGroup->prev = newGroup; hs_globals->multiGroup = newGroup; } hs_globals->groupCount++; } } return retcode; }
// // Scans (parses) input external-format schema name. // // This method assumes that the parameter externalSchemaName only // contains the external-format schema name. The syntax of an // schema name is // // [ <catalog-name-part> ] . <schema-name-part> // // A schema name part must be specified; the catalog name part is optional. // // The method returns the number of bytes scanned via the parameter // bytesScanned. If the scanned schema name is illegal, bytesScanned // contains the number of bytes examined when the name is determined // to be invalid. // // If the specified external-format schema name is valid, this method // returns TRUE and saves the parsed ANSI SQL name part into data // members catalogNamePart_ and schemaNamePart_; otherwise, it returns // FALSE and does not changes the contents of the data members. // NABoolean ComSchemaName::scan(const NAString &externalSchemaName, size_t &bytesScanned) { size_t count; size_t externalSchemaNameLen = externalSchemaName.length(); bytesScanned = 0; #define COPY_VALIDATED_STRING(x) \ ComAnsiNamePart(x, ComAnsiNamePart::INTERNAL_FORMAT) if (( SqlParser_Initialized() && SqlParser_NAMETYPE == DF_NSK) || (!SqlParser_Initialized() && *externalSchemaName.data() == '\\')) { ComMPLoc loc(externalSchemaName); switch (loc.getFormat()) { case ComMPLoc::SUBVOL: catalogNamePart_ = COPY_VALIDATED_STRING(loc.getSysDotVol()); schemaNamePart_ = COPY_VALIDATED_STRING(loc.getSubvolName()); bytesScanned = externalSchemaNameLen; return TRUE; case ComMPLoc::FILE: if (!loc.hasSubvolName()) { catalogNamePart_ = ""; schemaNamePart_ = COPY_VALIDATED_STRING(loc.getFileName()); bytesScanned = externalSchemaNameLen; return TRUE; } } } // Each ComAnsiNamePart ctor below must be preceded by "count = 0;" // -- see ComAnsiNamePart.cpp, and for a better scan implementation, // see ComObjectName::scan() + ComObjectName(bytesScanned) ctor. // --------------------------------------------------------------------- // Scan the leftmost ANSI SQL name part. // --------------------------------------------------------------------- count = 0; ComAnsiNamePart part1(externalSchemaName, count); bytesScanned += count; if (NOT part1.isValid()) return FALSE; if (bytesScanned >= externalSchemaNameLen) { ComASSERT(bytesScanned == externalSchemaNameLen); schemaNamePart_ = part1; return TRUE; // "sch" } // Get past the period separator if (NOT ComSqlText.isPeriod(externalSchemaName[bytesScanned++])) return FALSE; // --------------------------------------------------------------------- // Scan the last ANSI SQL name part // --------------------------------------------------------------------- #pragma nowarn(1506) // warning elimination Int32 remainingLen = externalSchemaNameLen - bytesScanned; #pragma warn(1506) // warning elimination NAString remainingName = externalSchemaName(bytesScanned, remainingLen); count = 0; ComAnsiNamePart part2(remainingName, count); bytesScanned += count; if (NOT part2.isValid()) return FALSE; if (bytesScanned == externalSchemaNameLen) { catalogNamePart_ = part1; schemaNamePart_ = part2; return TRUE; // "cat.sch" } // The specified external-format object name contains some extra // trailing characters -- illegal. // return FALSE; } // ComSchemaName::scan()
Lng32 AddKeyGroups() { HSGlobalsClass *hs_globals = GetHSContext(); if (HSGlobalsClass::isHiveCat(hs_globals->objDef->getCatName())) { // HSHiveTableDef::getKeyList()/getIndexArray() not yet implemented. *CmpCommon::diags() << DgSqlCode(-UERR_NO_ONEVERYKEY) << DgString0("hive"); return -1; } Lng32 retcode = 0; Lng32 numColsInGroup = 0; HSColumnStruct col; NAString tempColList = ""; NAString tempCol; NAString autoGroup; ULng32 numKeys; ULng32 i, j; NATable* naTbl = hs_globals->objDef->getNATable(); HSLogMan *LM = HSLogMan::Instance(); // ---------------------------------------------------------- // Generate histograms for KEY // ---------------------------------------------------------- // The clustering index is included in the list of indices returned by // NATable::getIndexList(), so we store its pointer so we can skip it // when the other indexes are processed below. NAFileSet* clusteringIndex = naTbl->getClusteringIndex(); const NAColumnArray& keyCols = clusteringIndex->getIndexKeyColumns(); Lng32 colPos; numKeys = keyCols.entries(); if (numKeys == 1) // SINGLE-COLUMN KEY { colPos = keyCols[0]->getPosition(); if (LM->LogNeeded()) { sprintf(LM->msg, "\t\tKEY:\t\t(%s)", hs_globals->objDef->getColName(colPos)); LM->Log(LM->msg); } if (ColumnExists(colPos)) // avoid duplicates { LM->Log("\t\t** duplicate column group has been ignored."); } else // add to single-column group list { retcode = AddSingleColumn(colPos); } } else if (numKeys > 1) // MULTI-COLUMN KEY { // Create multiple MC group(s) if numkeys > 1. Subset MC groups will // also be created if numkeys > 2, E.g. If numkeys = 5, then // MC groups with 5, 4, 3, and 2 columns will be created using // the key columns. Note that if numkeys is larger than CQD // USTAT_NUM_MC_GROUPS_FOR_KEYS (default = 5), then the number // of groups created will be limited by this value. So, e.g. if // numkeys = 10, then MC groups with 5, 4, 3, and 2 columns will // be created (that is, 5 groups will be created - incl the single). ULng32 minMCGroupSz = 2; ULng32 maxMCGroups = (ULng32) CmpCommon::getDefaultNumeric(USTAT_NUM_MC_GROUPS_FOR_KEYS); // Generate no MCs with more cols than specified by the cqd. if (numKeys > maxMCGroups) numKeys = maxMCGroups; // For salted table, generate only the longest MC for the key (subject // to max cols determined above) unless a cqd is set to gen all MCs of // allowable sizes. if (CmpCommon::getDefault(USTAT_ADD_SALTED_KEY_PREFIXES_FOR_MC) == DF_OFF && hs_globals->objDef->getColNum("_SALT_", FALSE) >= 0) minMCGroupSz = numKeys; while (numKeys >= minMCGroupSz) // Create only MC groups not single cols { HSColSet colSet; autoGroup = "("; for (j = 0; j < numKeys; j++) { colPos = keyCols[j]->getPosition(); col = hs_globals->objDef->getColInfo(colPos); col.colnum = colPos; colSet.insert(col); autoGroup += col.colname->data(); autoGroup += ","; } if (LM->LogNeeded()) { autoGroup.replace(autoGroup.length()-1,1,")"); // replace comma with close parenthesis sprintf(LM->msg, "\t\tKEY:\t\t%s", autoGroup.data()); LM->Log(LM->msg); } if (retcode = AddColumnSet(colSet)) { HSHandleError(retcode); } numKeys--; } } // ---------------------------------------------------------- // Generate histograms for all INDEXES // ---------------------------------------------------------- const NAFileSetList& indexes = naTbl->getIndexList(); NAFileSet* index; for (i = 0; i < indexes.entries(); i++ ) { index = indexes[i]; if (index == clusteringIndex) continue; // clustering index processed above already const NAColumnArray& keyCols = index->getIndexKeyColumns(); numKeys = keyCols.entries(); if (numKeys == 1) // SINGLE-COLUMN INDEX { colPos = keyCols[0]->getPosition(); if (LM->LogNeeded()) { sprintf(LM->msg, "\t\tINDEX[%d]\t(%s)", i, hs_globals->objDef->getColName(colPos)); LM->Log(LM->msg); } if (ColumnExists(colPos)) // avoid duplicates { LM->Log("\t\t*** duplicate column group has been ignored."); } else // add to single-column group list { retcode = AddSingleColumn(colPos); } } else // MULTI-COLUMN INDEX { // Create multiple MC group(s) if numkeys > 1. Subset MC groups will // also be created if numkeys > 2, E.g. If numkeys = 5, then // MC groups with 5, 4, 3, and 2 columns will be created using // the key columns. Note that if numkeys is larger than CQD // USTAT_NUM_MC_GROUPS_FOR_KEYS (default = 5), then the number // of groups created will be limited by this value. So, e.g. if // numkeys = 10, then MC groups with 10, 9, 8, 7, 6 columns will // be created (that is, 5 groups will be created). ULng32 minMCGroupSz = 2; ULng32 maxMCGroups = (ULng32) CmpCommon::getDefaultNumeric(USTAT_NUM_MC_GROUPS_FOR_KEYS); if (numKeys > maxMCGroups) minMCGroupSz = numKeys - maxMCGroups + 1; while (numKeys >= minMCGroupSz) // MinMCGroupSz is greater than 1. { HSColSet colSet; tempColList = ""; autoGroup = "("; for (j = 0; j < numKeys; j++) { colPos = keyCols[j]->getPosition(); tempCol = "."; tempCol += LongToNAString(colPos); tempCol += "."; // Eliminate duplicate columns in the index; // They may have been introduced by appending the key to the specified index. if (!tempColList.contains(tempCol)) { col = hs_globals->objDef->getColInfo(colPos); col.colnum = colPos; colSet.insert((const struct HSColumnStruct) col); tempColList += tempCol.data(); numColsInGroup++; autoGroup += col.colname->data(); autoGroup += ","; } } if (colSet.entries()) { if (numColsInGroup > 1) { if (LM->LogNeeded()) { autoGroup.replace(autoGroup.length()-1,1,")"); // replace comma with close parenthesis sprintf(LM->msg, "\t\tINDEX[%d]\t%s", i, autoGroup.data()); LM->Log(LM->msg); } if (retcode = AddColumnSet(colSet)) { HSHandleError(retcode); } } numColsInGroup = 0; } numKeys--; } } } return retcode; }
short Param::convertValue(SqlciEnv * sqlci_env, short targetType, Lng32 &targetLen, Lng32 targetPrecision, Lng32 targetScale, Lng32 vcIndLen, ComDiagsArea* diags) { // get rid of the old converted value if (converted_value) { delete [] converted_value; converted_value = 0; }; short sourceType; Lng32 sourceLen; // set up the source and its length based on the how the value is passed-in. if ( isInSingleByteForm() == FALSE ) { sourceLen = (Lng32)(NAWstrlen((NAWchar*)value) * BYTES_PER_NAWCHAR); switch (getCharSet()) { case CharInfo::UNICODE: sourceType = REC_NCHAR_F_UNICODE; break; case CharInfo::KANJI_MP: case CharInfo::KSC5601_MP: sourceType = REC_BYTE_F_ASCII; // KANJI/KSC passed in as NAWchar* break; default: return SQL_Error; // error case } } else { sourceLen = (Lng32)strlen(value); // for any source in single-byte format sourceType = REC_BYTE_F_ASCII; } char * pParamValue = value; if ( DFS2REC::isAnyCharacter(targetType) ) { if (termCS_ == CharInfo::UnknownCharSet) termCS_ = sqlci_env->getTerminalCharset(); if (cs == CharInfo::UnknownCharSet) { isQuotedStrWithoutCharSetPrefix_ = TRUE; cs = termCS_; } // If the target is CHARACTER and param is set as [_cs_prefix]'...', then // make sure the source is assignment compatible with the target. CharInfo::CharSet targetCharSet = (CharInfo::CharSet)targetScale; if ( targetCharSet == CharInfo::UNICODE ) { if (getUTF16StrLit() == (NAWchar*)NULL) { utf16StrLit_ = new NAWchar [ sourceLen * 2 + 1 ]; // plenty of room Lng32 utf16StrLenInNAWchars = LocaleStringToUnicode(cs/*sourceCS*/, /*sourceStr*/value, sourceLen, utf16StrLit_/*outputBuf*/, sourceLen+1/*outputBufSizeInNAWchars*/, TRUE /* in - NABoolean addNullAtEnd*/); if (sourceLen > 0 && utf16StrLenInNAWchars == 0) return SQL_Error; // ComASSERT(utf16StrLenInNAWchars == NAWstrlen(getUTF16StrLit())); // Resize the NAWchar buffer to save space NAWchar *pNAWcharBuf = new NAWchar [ utf16StrLenInNAWchars + 1 ]; NAWstrncpy (pNAWcharBuf, utf16StrLit_, utf16StrLenInNAWchars + 1); pNAWcharBuf[utf16StrLenInNAWchars] = NAWCHR('\0'); // play it safe delete [] utf16StrLit_; utf16StrLit_ = pNAWcharBuf; // do not deallocate pNAWcharBuf } sourceLen = (Lng32)(NAWstrlen(getUTF16StrLit()) * BYTES_PER_NAWCHAR); // check to see if the parameter utf16 string fits in the target if ( sourceLen > targetLen ) return SQL_Error; pParamValue = (char *)getUTF16StrLit(); sourceType = REC_NCHAR_F_UNICODE; } } else { // MP NCHAR (KANJI/KSC) can not be converted to non-character objects if ( CharInfo::is_NCHAR_MP(cs) ) return SQL_Error; } switch(targetType) { case REC_BIN16_SIGNED: case REC_BIN16_UNSIGNED: case REC_BPINT_UNSIGNED: case REC_BIN32_SIGNED: case REC_BIN32_UNSIGNED: case REC_BIN64_SIGNED: case REC_DECIMAL_UNSIGNED: case REC_DECIMAL_LSE: case REC_FLOAT32: case REC_FLOAT64: case REC_TDM_FLOAT32: case REC_TDM_FLOAT64: case REC_BYTE_F_ASCII: case REC_BYTE_V_ASCII: case REC_BYTE_V_ASCII_LONG: case REC_NCHAR_F_UNICODE: case REC_NCHAR_V_UNICODE: { char *VCLen = NULL; short VCLenSize = 0; // 5/27/98: added VARNCHAR cases if ((targetType == REC_BYTE_V_ASCII) || (targetType == REC_BYTE_V_ASCII_LONG) || (targetType == REC_NCHAR_V_UNICODE)) { // add bytes for variable length field VCLenSize = vcIndLen; //sizeof(short); VCLen = converted_value = new char[targetLen + VCLenSize]; } else converted_value = new char[targetLen]; #pragma nowarn(1506) // warning elimination ex_expr::exp_return_type ok; CharInfo::CharSet TCS = sqlci_env->getTerminalCharset(); CharInfo::CharSet ISOMAPCS = sqlci_env->getIsoMappingCharset(); NAString* tempstr; if ( DFS2REC::isAnyCharacter(sourceType) && DFS2REC::isAnyCharacter(targetType) && !(getUTF16StrLit() != NULL && sourceType == REC_NCHAR_F_UNICODE && targetScale == CharInfo::UCS2) && /*source*/cs != targetScale/*i.e., targetCharSet*/ ) { charBuf cbuf((unsigned char*)pParamValue, sourceLen); NAWcharBuf* wcbuf = 0; Int32 errorcode = 0; wcbuf = csetToUnicode(cbuf, 0, wcbuf, cs/*sourceCharSet*/ , errorcode); if (errorcode != 0) return SQL_Error; tempstr = unicodeToChar(wcbuf->data(),wcbuf->getStrLen(), targetScale/*i.e., targetCharSet*/ ); if (tempstr == NULL) return SQL_Error; //Avoid NULL ptr reference if conversion error sourceType = targetType; // we just converted it to the target type sourceLen = tempstr->length(); pParamValue = (char *)tempstr->data(); if ( sourceLen > targetLen ) return SQL_Error; } ok = convDoIt(pParamValue, sourceLen, sourceType, 0, // source Precision targetScale, // new charset we converted to &converted_value[VCLenSize], targetLen, targetType, targetPrecision, targetScale, VCLen, VCLenSize, 0, &diags); if ( ok != ex_expr::EXPR_OK) { // No need to delete allocated memory before return because class member // converted_value still points to allocated memory that is deleted in // desctructor. return SQL_Error; // error case } #pragma warn(1506) // warning elimination }; break; case REC_DATETIME: { char *VCLen = NULL; short VCLenSize = 0; converted_value = new char[targetLen + 1]; #pragma nowarn(1506) // warning elimination ex_expr::exp_return_type ok = convDoIt(value, sourceLen, sourceType, 0, // source Precision 0, // source Scale converted_value, targetLen, targetType, targetPrecision, targetScale, VCLen, VCLenSize, 0, &diags); if ( ok != ex_expr::EXPR_OK) { return SQL_Error; // error case } #pragma warn(1506) // warning elimination }; break; case REC_INT_YEAR: case REC_INT_MONTH: case REC_INT_YEAR_MONTH: case REC_INT_DAY: case REC_INT_HOUR: case REC_INT_DAY_HOUR: case REC_INT_MINUTE: case REC_INT_HOUR_MINUTE: case REC_INT_DAY_MINUTE: case REC_INT_SECOND: case REC_INT_MINUTE_SECOND: case REC_INT_HOUR_SECOND: case REC_INT_DAY_SECOND: { // convert target back to string. converted_value = new char[targetLen]; Lng32 convFlags = CONV_ALLOW_SIGN_IN_INTERVAL; #pragma nowarn(1506) // warning elimination short ok = convDoItMxcs(value, sourceLen, sourceType, 0, // source Precision 0, // source Scale converted_value, targetLen, targetType, targetPrecision, targetScale, convFlags); if ( ok != 0 ) { // No need to delete allocated memory before return because class member // converted_value still points to allocated memory that is deleted in // desctructor. return SQL_Error; // error case } #pragma warn(1506) // warning elimination }; break; case REC_NUM_BIG_UNSIGNED: case REC_NUM_BIG_SIGNED: { converted_value = new char[targetLen]; #pragma nowarn(1506) // warning elimination short ok = convDoItMxcs(value, sourceLen, sourceType, 0, // source Precision 0, // source Scale converted_value, targetLen, targetType, targetPrecision, targetScale, 0); if ( ok != 0 ) { // No need to delete allocated memory before return because class member // converted_value still points to allocated memory that is deleted in // desctructor. return SQL_Error; // error case } #pragma warn(1506) // warning elimination }; break; default: break; }; return 0; }
short Env::process(SqlciEnv *sqlci_env) { // ## Should any of this text come from the message file, // ## i.e. from a translatable file for I18N? // When adding new variables, please keep the information in // alphabetic order Logfile *log = sqlci_env->get_logfile(); log->WriteAll("----------------------------------"); log->WriteAll("Current Environment"); log->WriteAll("----------------------------------"); bool authenticationEnabled = false; bool authorizationEnabled = false; bool authorizationReady = false; bool auditingEnabled = false; Int32 rc = sqlci_env->getAuthState(authenticationEnabled, authorizationEnabled, authorizationReady, auditingEnabled); // TDB: add auditing state log->WriteAllWithoutEOL("AUTHENTICATION "); if (authenticationEnabled) log->WriteAll("enabled"); else log->WriteAll("disabled"); log->WriteAllWithoutEOL("AUTHORIZATION "); if (authorizationEnabled) log->WriteAll("enabled"); else log->WriteAll("disabled"); log->WriteAllWithoutEOL("CURRENT DIRECTORY "); // NT_PORT (bv 10/24/96) Added NA_MAX_PATH here and in common/Platform.h log->WriteAll(getcwd((char *)NULL, NA_MAX_PATH)); log->WriteAllWithoutEOL("LIST_COUNT "); char buf[100]; Int32 len = sprintf(buf, "%u", sqlci_env->getListCount()); if (len-- > 0) if (buf[len] == 'L' || buf[len] == 'l') buf[len] = '\0'; log->WriteAll(buf); if (log->IsOpen()) { log->WriteAllWithoutEOL("LOG FILE "); log->WriteAll(log->Logname()); } else { log->WriteAll("LOG FILE"); } log->WriteAllWithoutEOL("MESSAGEFILE "); const char *mf = GetErrorMessageFileName(); log->WriteAll(mf ? mf : ""); #if 0 log->WriteAllWithoutEOL("ISO88591 MAPPING "); log->WriteAll(CharInfo::getCharSetName(sqlci_env->getIsoMappingCharset())); log->WriteAllWithoutEOL("DEFAULT CHARSET "); log->WriteAll(CharInfo::getCharSetName(sqlci_env->getDefaultCharset())); log->WriteAllWithoutEOL("INFER CHARSET "); log->WriteAll((sqlci_env->getInferCharset())?"ON":"OFF"); #endif // ## These need to have real values detected from the env and written out: // "US English" is more "politically correct" than "American English". // log->WriteAllWithoutEOL("MESSAGEFILE LANG US English\n"); log->WriteAllWithoutEOL("MESSAGEFILE VRSN "); char vmsgcode[10]; sprintf(vmsgcode, "%d", SQLERRORS_MSGFILE_VERSION_INFO); #pragma nowarn(1506) // warning elimination Error vmsg(vmsgcode, strlen(vmsgcode), Error::ENVCMD_); #pragma warn(1506) // warning elimination vmsg.process(sqlci_env); ComAnsiNamePart defaultCat; ComAnsiNamePart defaultSch; sqlci_env->getDefaultCatAndSch (defaultCat, defaultSch); CharInfo::CharSet TCS = sqlci_env->getTerminalCharset(); CharInfo::CharSet ISOMAPCS = sqlci_env->getIsoMappingCharset(); if(TCS != CharInfo::UTF8 ) { NAString dCat = defaultCat.getExternalName(); NAString dSch = defaultSch.getExternalName(); charBuf cbufCat((unsigned char*)dCat.data(), dCat.length()); charBuf cbufSch((unsigned char*)dSch.data(), dSch.length()); NAWcharBuf* wcbuf = 0; Int32 errorcode = 0; wcbuf = csetToUnicode(cbufCat, 0, wcbuf, CharInfo::UTF8, errorcode); NAString* tempstr; if (errorcode != 0){ tempstr = new NAString(defaultCat.getExternalName().data()); } else { tempstr = unicodeToChar(wcbuf->data(),wcbuf->getStrLen(), TCS, NULL, TRUE); TrimNAStringSpace(*tempstr, FALSE, TRUE); // trim trailing blanks } log->WriteAllWithoutEOL("SQL CATALOG "); log->WriteAll(tempstr->data()); // Default Schema wcbuf = 0; // must 0 out to get next call to allocate memory. wcbuf = csetToUnicode(cbufSch, 0, wcbuf, CharInfo::UTF8, errorcode); if (errorcode != 0){ tempstr = new NAString(defaultSch.getExternalName().data()); } else { tempstr = unicodeToChar(wcbuf->data(),wcbuf->getStrLen(), TCS, NULL, TRUE); TrimNAStringSpace(*tempstr, FALSE, TRUE); // trim trailing blanks } log->WriteAllWithoutEOL("SQL SCHEMA "); log->WriteAll(tempstr->data()); } else { log->WriteAllWithoutEOL("SQL CATALOG "); log->WriteAll(defaultCat.getExternalName()); log->WriteAllWithoutEOL("SQL SCHEMA "); log->WriteAll(defaultSch.getExternalName()); } // On Linux we include the database user name and user ID in the // command output NAString username; rc = sqlci_env->getExternalUserName(username); log->WriteAllWithoutEOL("SQL USER CONNECTED "); if (rc >= 0) log->WriteAll(username.data()); else log->WriteAll("?"); rc = sqlci_env->getDatabaseUserName(username); log->WriteAllWithoutEOL("SQL USER DB NAME "); if (rc >= 0) log->WriteAll(username.data()); else log->WriteAll("?"); Int32 uid = 0; rc = sqlci_env->getDatabaseUserID(uid); log->WriteAllWithoutEOL("SQL USER ID "); if (rc >= 0) sprintf(buf, "%d", (int) uid); else strcpy(buf, "?"); log->WriteAll(buf); log->WriteAllWithoutEOL("TERMINAL CHARSET "); log->WriteAll(CharInfo::getCharSetName(sqlci_env->getTerminalCharset())); Int64 transid; if (sqlci_env->statusTransaction(&transid)) { // transaction is active. char transid_str[20]; convertInt64ToAscii(transid, transid_str); log->WriteAllWithoutEOL("TRANSACTION ID "); log->WriteAll(transid_str); log->WriteAll("TRANSACTION STATE in progress"); } else { log->WriteAll("TRANSACTION ID "); log->WriteAll("TRANSACTION STATE not in progress"); } if (log->isVerbose()) log->WriteAll("WARNINGS on"); else log->WriteAll("WARNINGS off"); return 0; }