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; }
// ----------------------------------------------------------------------- // Add the single-column groups from startColumn to endColumn. If these // parameters are NULL, the function has been called for the ON EVERY COLUMN // clause, and we will add all single column groups, as well as key groups. // ----------------------------------------------------------------------- Lng32 AddEveryColumn(const char *startColumn, const char *endColumn) { HSGlobalsClass *hs_globals = GetHSContext(); Lng32 colNumber, retcode; NAString colName; Lng32 start, upto; HSLogMan *LM = HSLogMan::Instance(); hs_globals->parserError = HSGlobalsClass::ERROR_SEMANTICS; // Can't use EVERYCOL_OPT flag for this test, it may have been set on a // previous call (making this a redundant, or incorrect, request to ustat // an individual column name). startColumn will always be NULL if this fn // is called to add all the columns for a table. if (!startColumn) { HS_ASSERT(hs_globals->optFlags & EVERYCOL_OPT); start = 0; upto = hs_globals->objDef->getNumCols() - 1; } else { start = hs_globals->objDef->getColNum(startColumn); // LCOV_EXCL_START :rfi if (start < 0) { retcode = -1; HSHandleError(retcode); } // LCOV_EXCL_STOP upto = hs_globals->objDef->getColNum(endColumn); // LCOV_EXCL_START :rfi if (upto < 0) { retcode = -1; HSHandleError(retcode); } // LCOV_EXCL_STOP if (start > upto) { Lng32 tmp = upto; upto = start; start = tmp; } } for (colNumber = start; colNumber <= upto; colNumber++) { if (ColumnExists(colNumber)) // avoid duplicates { colName = hs_globals->objDef->getColName(colNumber); if (LM->LogNeeded()) { sprintf(LM->msg, "\t\t****Duplicate Column group (%s) has been ignored", colName.data()); LM->Log(LM->msg); } } else // add to single-column group list { retcode = AddSingleColumn(colNumber); } } if (!startColumn && // ON EVERY COLUMN causes key groups to be added as well !HSGlobalsClass::isHiveCat(hs_globals->objDef->getCatName())) // No ustat on keys yet for hive tables { retcode = AddKeyGroups(); HSHandleError(retcode); } hs_globals->parserError = HSGlobalsClass::ERROR_SYNTAX; return 0; }
// ----------------------------------------------------------------------- // Construct a fully qualified table name. // ----------------------------------------------------------------------- Lng32 AddTableName( const hs_table_type type , const char *table , const char *schema , const char *catalog ) { HSGlobalsClass *hs_globals = GetHSContext(); NAString catName, schName, objName; NAString extName; NAString defaultCat, defaultSch; NAString userLocation; Lng32 retcode = 0; hs_globals->tableType = type; HSLogMan *LM = HSLogMan::Instance(); // SET MPLOC is converted to CQD (setting values for default // attributes MP_SYSTEM, MP_VOLUME, MP_SUBVOLUME). It does not // update the global MPLOC value stored in SqlParser_MPLOC. The // following updates the global MPLOC value to be consistent with // the default attribute values set by SET MPLOC/CQD. ActiveSchemaDB()->getDefaults().getSqlParser_NADefaults(); if (type == GUARDIAN_TABLE) { if (*table == '$') { // Qualify with system name. extName = SqlParser_MPLOC.getSystemName(); extName += "."; extName += table; } else extName = table; hs_globals->tableFormat = SQLMP; } else { // When CQD DEFAULT_SCHEMA_ACCESS_ONLY is on, // users cannot update stats on tables not in the default/public schemas. if ( schema && ActiveSchemaDB()->getDefaults().getToken(DEFAULT_SCHEMA_ACCESS_ONLY)==DF_ON ) { SchemaName objSchName; NAString curSchName(schema); NAString curCatName; objSchName.setSchemaName(curSchName); if (catalog) { curCatName = catalog; objSchName.setCatalogName(curCatName); } else curCatName = ActiveSchemaDB()->getDefaultSchema().getCatalogName(); // If the schema is neither default nor public, // issue inaccessible error. if (!objSchName.matchDefaultPublicSchema()) { NAString dataObj(curCatName); if (!dataObj.isNull()) dataObj += "."; dataObj += curSchName + "."; dataObj += table; HSFuncMergeDiags(-UERR_OBJECT_INACCESSIBLE, dataObj.data()); retcode = -1; HSHandleError(retcode); } } if (catalog) catName = catalog; else { // LCOV_EXCL_START :nsk if (SqlParser_NAMETYPE == DF_NSK) { catName = SqlParser_MPLOC.getSysDotVol(); hs_globals->tableType = GUARDIAN_TABLE; hs_globals->tableFormat = SQLMP; } else // LCOV_EXCL_STOP catName = ActiveSchemaDB()->getDefaultSchema().getCatalogName(); } if (schema) schName = schema; else { // LCOV_EXCL_START :nsk if (SqlParser_NAMETYPE == DF_NSK) { schName = SqlParser_MPLOC.getSubvolName(); hs_globals->tableFormat = SQLMP; } else // LCOV_EXCL_STOP schName = ActiveSchemaDB()->getDefaultSchema().getSchemaName(); } objName = table; extName = catName + "." + schName + "." + objName; } // LCOV_EXCL_START :nsk if (hs_globals->tableFormat == SQLMP) { ComMPLoc loc(extName, ComMPLoc::FILE); if (loc.getFormat() == ComMPLoc::INVALID) { HSFuncMergeDiags(-UERR_OBJECT_INACCESSIBLE, extName); retcode = -1; HSHandleError(retcode); } catName = loc.getSysDotVol(); schName = loc.getSubvolName(); objName = loc.getFileName(); } // LCOV_EXCL_STOP hs_globals->objDef = NULL; // Search in volatile schema first. If not found, search in regular cat/sch. if ((CmpCommon::context()->sqlSession()->volatileSchemaInUse()) && (type != GUARDIAN_TABLE) && (! catalog)) { // search using the volatile schema name. NAString &volCatName = CmpCommon::context()->sqlSession()->volatileCatalogName(); NAString &volSchName = CmpCommon::context()->sqlSession()->volatileSchemaName(); NAString volObjName = table; ComObjectName volIntName(volCatName, volSchName, volObjName, COM_UNKNOWN_NAME, ComAnsiNamePart::INTERNAL_FORMAT); if (NOT volIntName.isValid()) { LM->Log("***[ERROR] Unable to create an ObjectClass"); HSFuncMergeDiags(-UERR_OBJECT_INACCESSIBLE, extName); retcode = -1; HSHandleError(retcode); } if (LM->LogNeeded()) { LM->Log("Searching in volatile schema, since catalog not specified.\n"); sprintf(LM->msg, "Checking volatile name (volIntName) %s.%s.%s\n", volIntName.getCatalogNamePart().getInternalName().data(), volIntName.getSchemaNamePart().getInternalName().data(), volIntName.getObjectNamePart().getInternalName().data()); LM->Log(LM->msg); } hs_globals->objDef = HSTableDef::create(STMTHEAP, volIntName, hs_globals->tableType, hs_globals->nameSpace); if (NOT hs_globals->objDef->objExists(hs_globals->isUpdatestatsStmt)) { // now look into the regular schema delete hs_globals->objDef; hs_globals->objDef = NULL; } else { // if schema name was specified, validate that it is the // current username. if (schema) { QualifiedName qn(volObjName, schName); if (NOT CmpCommon::context()->sqlSession()->validateVolatileQualifiedName(qn)) { // table was found in the volatile schema but it is // not a valid volatile name. // Look for it in regular schema. // error info was moved to CmpCommon::diags. Clear it. CmpCommon::diags()->clear(); delete hs_globals->objDef; hs_globals->objDef = NULL; } } } } if (hs_globals->objDef == NULL) { ComObjectName intName(catName, schName, objName, COM_UNKNOWN_NAME, ComAnsiNamePart::INTERNAL_FORMAT); if (NOT intName.isValid()) { LM->Log("***[ERROR] Unable to create an ObjectClass"); HSFuncMergeDiags(-UERR_OBJECT_INACCESSIBLE, extName); retcode = -1; HSHandleError(retcode); } hs_globals->objDef = HSTableDef::create(STMTHEAP, intName, hs_globals->tableType, hs_globals->nameSpace); // try public schema if an object is not qualified and not found if ((NOT schema) && (NOT hs_globals->objDef->objExists(hs_globals->isUpdatestatsStmt))) { NAString pubSch = ActiveSchemaDB()->getDefaults().getValue(PUBLIC_SCHEMA_NAME); ComSchemaName pubSchema(pubSch); if (NOT pubSchema.getSchemaNamePart().isEmpty()) { NAString pubSchName = pubSchema.getSchemaNamePart().getInternalName(); NAString pubCatName = (pubSchema.getCatalogNamePart().isEmpty() ? catName:pubSchema.getCatalogNamePart().getInternalName()); ComObjectName pubIntName(pubCatName, pubSchName, objName, COM_UNKNOWN_NAME, ComAnsiNamePart::INTERNAL_FORMAT); if (pubIntName.isValid()) { HSTableDef *pubObjDef = HSTableDef::create(STMTHEAP, pubIntName, hs_globals->tableType, hs_globals->nameSpace); if (pubObjDef->objExists(hs_globals->isUpdatestatsStmt)) { hs_globals->objDef = pubObjDef; } } } } if (NOT hs_globals->objDef->objExists(hs_globals->isUpdatestatsStmt)) { HSFuncMergeDiags(-UERR_OBJECT_INACCESSIBLE, extName); retcode = -1; HSHandleError(retcode); } } //10-040123-2660 We only support tables. We do not allow views. // Tables can be metadata tables. if ((hs_globals->objDef->getObjectType() != COM_BASE_TABLE_OBJECT) && (hs_globals->objDef->getObjectType() != COM_MV_OBJECT)) { HSFuncMergeDiags(-UERR_INVALID_OBJECT, extName); retcode = -1; HSHandleError(retcode); } retcode = hs_globals->objDef->getColumnNames(); HSFuncExecQuery("CONTROL QUERY DEFAULT DISPLAY_DIVISION_BY_COLUMNS RESET"); HSHandleError(retcode); hs_globals->tableFormat = hs_globals->objDef->getObjectFormat(); *hs_globals->catSch = hs_globals->objDef->getPrimaryLoc(HSTableDef::EXTERNAL_FORMAT); *hs_globals->user_table = hs_globals->objDef->getObjectFullName(); hs_globals->tableFormat = hs_globals->objDef->getObjectFormat(); hs_globals->isHbaseTable = HSGlobalsClass::isHbaseCat(catName); hs_globals->isHiveTable = HSGlobalsClass::isHiveCat(catName); if (hs_globals->tableFormat == SQLMX) { // Determine the schema version for this MX table. if (LM->LogNeeded()) { sprintf(LM->msg, "\nCHECK SCHEMA VERSION FOR TABLE: %s\n", hs_globals->user_table->data()); LM->Log(LM->msg); } HSGlobalsClass::schemaVersion = getTableSchemaVersion(hs_globals->user_table->data()); // LCOV_EXCL_START :rfi if (HSGlobalsClass::schemaVersion == COM_VERS_UNKNOWN) { HSFuncMergeDiags(-UERR_INTERNAL_ERROR, "GET_SCHEMA_VERSION"); return -1; } // LCOV_EXCL_STOP if (HSGlobalsClass::schemaVersion >= COM_VERS_2300) HSGlobalsClass::autoInterval = CmpCommon::getDefaultLong(USTAT_AUTOMATION_INTERVAL); if (LM->LogNeeded()) { sprintf(LM->msg, "\nUpdateStats: TABLE: %s; SCHEMA VERSION: %d; AUTOMATION INTERVAL: %d\n", hs_globals->user_table->data(), HSGlobalsClass::schemaVersion, HSGlobalsClass::autoInterval); LM->Log(LM->msg); } NAString catName(hs_globals->objDef->getCatName()); *hs_globals->hstogram_table = getHistogramsTableLocation(hs_globals->catSch->data(), FALSE); *hs_globals->hsintval_table = getHistogramsTableLocation(hs_globals->catSch->data(), FALSE); NABoolean isHbaseOrHive = HSGlobalsClass::isHbaseCat(catName) || HSGlobalsClass::isHiveCat(catName); if (isHbaseOrHive) { hs_globals->hstogram_table->append(".").append(HBASE_HIST_NAME); hs_globals->hsintval_table->append(".").append(HBASE_HISTINT_NAME); } else { hs_globals->hstogram_table->append(".HISTOGRAMS"); hs_globals->hsintval_table->append(".HISTOGRAM_INTERVALS"); } } else { // LCOV_EXCL_START :nsk *hs_globals->hstogram_table = hs_globals->objDef->getCatalogLoc(HSTableDef::EXTERNAL_FORMAT); hs_globals->hstogram_table->append(".HISTOGRM"); *hs_globals->hsintval_table = hs_globals->objDef->getCatalogLoc(HSTableDef::EXTERNAL_FORMAT); hs_globals->hsintval_table->append(".HISTINTS"); // RESET CQDS: HSFuncExecQuery("CONTROL QUERY DEFAULT ALLOW_DP2_ROW_SAMPLING RESET"); HSFuncExecQuery("CONTROL QUERY DEFAULT POS RESET"); HSFuncExecQuery("CONTROL QUERY DEFAULT POS_NUM_OF_PARTNS RESET"); // LCOV_EXCL_STOP } return 0; }
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; }