const NAString QualifiedName::getQualifiedNameAsAnsiNTFilenameString() const { // Preallocate a result buffer that'll be big enough most of the time // (so += won't reallocate+copy most of the time). NAString result((NASize_T)40, CmpCommon::statementHeap()); NAString catName(CmpCommon::statementHeap()); NAString schName(CmpCommon::statementHeap()); NAString objName(CmpCommon::statementHeap()); formatAsAnsiIdentifier = TRUE; // put quotes on delimited identifiers if ( NOT getCatalogName().isNull() ) { catName = FORMAT(getCatalogName()); makeSafeFilenamePart(catName, "SQLMX_DEFAULT_CATALOG_"); } if ( NOT getSchemaName().isNull() ) { schName = FORMAT(getSchemaName()); makeSafeFilenamePart(schName, "SQLMX_DEFAULT_SCHEMA_"); } if ( NOT getObjectName().isNull() ) { objName = FORMAT(getObjectName()); } makeSafeFilenamePart(objName, "SQLMX_DEFAULT_FILE_"); formatAsAnsiIdentifier = FALSE; // reset to initial value size_t totlen = catName.length() + schName.length() + objName.length() + 2; if ( totlen > 255 ) { // need to truncate // +1 so round off doesn't give us less than what we need to chop size_t chopLen = totlen - 255 + 1; if ( catName.length() - chopLen/2 <= 0 ) // cat too short schName.remove( schName.length() - chopLen ); else if ( schName.length() - chopLen/2 <= 0 ) // sch too short catName.remove( catName.length() - chopLen ); else { // chop from both // remember position starts at 0 and length is 1 more chopLen /= 2; catName.remove( catName.length() - chopLen - 1 ); schName.remove( schName.length() - chopLen - 1 ); } } if (NOT catName.isNull()) { result = catName; result += "."; } if (NOT schName.isNull()) { result += schName; result += "."; } result += objName; return result; }
// ----------------------------------------------------------------------- // 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(HSTableDef::MAX_INFO)) { // 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(HSTableDef::MAX_INFO))) { 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(HSTableDef::MAX_INFO)) { hs_globals->objDef = pubObjDef; } } } } if (NOT hs_globals->objDef->objExists(HSTableDef::MAX_INFO)) { 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); 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); } const char* period = strchr(hs_globals->catSch->data(), '.'); NAString catName(hs_globals->catSch->data(), period - hs_globals->catSch->data()); NABoolean isHbaseOrHive = HSGlobalsClass::isHbaseCat(catName) || HSGlobalsClass::isHiveCat(catName); *hs_globals->hstogram_table = getHistogramsTableLocation(hs_globals->catSch->data(), FALSE); if (isHbaseOrHive) hs_globals->hstogram_table->append(".").append(HBASE_HIST_NAME); else hs_globals->hstogram_table->append(".HISTOGRAMS"); *hs_globals->hsintval_table = getHistogramsTableLocation(hs_globals->catSch->data(), FALSE); if (isHbaseOrHive) hs_globals->hsintval_table->append(".").append(HBASE_HISTINT_NAME); else 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 DETAILED_STATISTICS RESET"); 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; }
// Apply defaults to self, and then (ANSI 12.1 SR 3) apply self to SchemaDB. NABoolean StmtModule::applyDefaults(NABoolean wantR18behavior) { NABoolean err = FALSE; if (charSet().isNull()) charSet() = CharInfo::getCharSetName(CharInfo::DefaultCharSet); if (CharInfo::isCharSetSupported(charSet())) { // Get charset name in canonical format (the name of the enum of the name). charSet() = CharInfo::getCharSetName(CharInfo::getCharSetEnum(charSet())); } else { *CmpCommon::diags() << DgSqlCode(-3010) << DgString0(charSet()); err = TRUE; } if (!CharInfo::isModuleCharSetSupported(CharInfo::getCharSetEnum(charSet()))) { *CmpCommon::diags() << DgSqlCode(-3404) << DgString0(charSet()); err = TRUE; } // Here we're using internal-format names if (name().getCatalogName().isNull()) { // Must be an Ansi name, not an MPLOC. const SchemaName& defcs = ActiveSchemaDB()->getDefaultSchema( SchemaDB::REFRESH_CACHE | SchemaDB::FORCE_ANSI_NAMETYPE); if (name().getSchemaName().isNull()) { if (name().getObjectName().isNull()) { name().setObjectName("SQLMX_DEFAULT_MODULE_"); } name().setSchemaName(defcs.getSchemaName()); } name().setCatalogName(defcs.getCatalogName()); } if (wantR18behavior) { // And now we use external-format names, for the ANSI 12.1 SR 3 stuff. NAString catName(name().getCatalogNameAsAnsiString()); if (!ActiveSchemaDB()->getDefaults().setCatalog(catName)) err = TRUE; NAString schName(name().getUnqualifiedSchemaNameAsAnsiString()); if (!ActiveSchemaDB()->getDefaults().setSchema(schName)) err = TRUE; } else { // want R2 (correct) behavior // We used to take the catalog & schema of the module directive and apply // them above as the default catalog & schema. This was a misguided // attempt to "use external-format names, for the ANSI 12.1 SR 3 stuff" // in the SQL92 std. // // In SQL99, this has been clarified in section 13.1 of ISO/IEC FDIS // 9075-2:1999 (aka the 1999 Foundation doc) where syntax rules 3 & 4 // specify that: // // "If the explicit or implicit <schema name> does not specify a <catalog // name>, then an implementation-defined <catalog name> is implicit." // // "The implicit or explicit <catalog name> is the implicit <catalog name> // for all unqualified <schema name>s in the <SQL-client module // definition>." // // Three observations may be worth pointing out here: // 1) SQL/MX client modules do not have a <module authorization clause> as // specified by the SQL99 std. // 2) Even if (in the future) SQL/MX tries to conform to the SQL99 std for // client module definition(s), the SQL99 std itself (syntax rule 3) // allows us to use "an implementation-defined <catalog name>" to // implicitly qualify unqualified <schema name>s. // 3) This current "implementation is a deviation from ANSI in // that the module name is a 3-part name. This deviation and the use of // cat/sch name to qualify unqualified SQL objects in the module are // also 'valid' implementation of the 2 syntax rules 13.1, rules 3 & 4 // of ANSI." // Similar logic can be applied to using an implementation-defined // <schema name> to implicitly qualify unqualified table names, etc. // // In other words, our technique of using CQD default CATALOG & SCHEMA // settings to qualify unqualified table names, view names, etc is allowed // for by the SQL99 std. // // Deleting the old code that was here is part of the fix to genesis // cases 10-030725-8215, 10-030730-8326, 10-030826-0792. } return err; }