short ExExeUtilTcb::setSystemVersion() { Lng32 cliRC = 0; if (sysVersionStrLen_ == 0) { // since SUBSTRING isn't currently supported for UTF-8 strings // and GET VERSION OF SYSTEM returns a UTF-8 string, convert it // to UCS2, do the substring, then convert to ISO88591 (we // expect a number here so it would be an error to get anything // other than ISO88591 characters). cliRC = cliInterface()->executeImmediate("select translate(substring(translate(a using utf8toucs2), 10, 4) using ucs2toiso88591) from (get version of system) x(a)", sysVersionStr_, &sysVersionStrLen_); if (cliRC < 0) { cliInterface()->retrieveSQLDiagnostics(getDiagsArea()); return -1; } sysVersionStr_[sysVersionStrLen_] = 0; } return 0; }
short ExExeUtilTcb::alterCorruptBit(short val, char * tableName, char * failReason, Queue* indexList) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // change the corrupt bit in the label str_sprintf(buf, "LABEL_ALTER TABLE %s PARALLEL EXECUTION ON OPCODE 9 '%s'", tableName, (val == 1 ? "1" : "0")); // set sqlparserflags to allow 'label_alter' syntax masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); if (cliRC < 0) { str_sprintf(failReason, "Could not %s the corrupt bit on table %s.", (val == 1 ? "set" : "reset"), tableName); return -1; } if (indexList) { indexList->position(); while (NOT indexList->atEnd()) { char * indexName = (char*)indexList->getNext(); str_sprintf(buf, "LABEL_ALTER INDEX_TABLE %s PARALLEL EXECUTION ON OPCODE 9 '%s'", indexName, (val == 1 ? "1" : "0")); // set sqlparserflags to allow 'label_alter' syntax masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); if (cliRC < 0) { str_sprintf(failReason, "Could not %s the corrupt bit on index %s.", (val == 1 ? "set" : "reset"), indexName); return -1; } } // while } // index present return 0; }
short ExExeUtilTcb::getObjectUid(char * catName, char * schName, char * objName, NABoolean isIndex, NABoolean isMv, char* uid) { Lng32 cliRC = 0; ex_queue_entry * pentry_down = qparent_.down->getHeadEntry(); ExExeUtilPrivateState & pstate = *((ExExeUtilPrivateState*) pentry_down->pstate); ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); const QueryString * qs; Int32 sizeOfqs = 0; versionStrLen_ = 0; qs = getObjectUidQuery; sizeOfqs = sizeof(getObjectUidQuery); Int32 qryArraySize = sizeOfqs / sizeof(QueryString); char * gluedQuery; Lng32 gluedQuerySize; glueQueryFragments(qryArraySize, qs, gluedQuery, gluedQuerySize); Lng32 extraSpace = 10 /*segment name*/+ ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES/*cat/sch/obj name in UTF8*/ + 100; char * infoQuery = new(getHeap()) char[gluedQuerySize + extraSpace + 1]; str_sprintf(infoQuery, gluedQuery, catName, schName, objName, (isIndex ? "IX" : "TA"), (isMv ? "MV" : (isIndex ? "IX" : "BT"))); NADELETEBASIC(gluedQuery, getMyHeap()); Lng32 uidLen; cliRC = cliInterface()->executeImmediate(infoQuery, uid, &uidLen); if (cliRC < 0) { cliInterface()->retrieveSQLDiagnostics(getDiagsArea()); return -1; } uid[uidLen] = 0; return 0; }
short ExExeUtilTcb::alterAuditFlag(NABoolean audited, char * tableName, NABoolean isIndex) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // change the corrupt bit in the label if (isIndex) str_sprintf(buf, "LABEL_ALTER INDEX_TABLE %s PARALLEL EXECUTION ON OPCODE %s ''", tableName, (audited ? "65" : "66")); else str_sprintf(buf, "LABEL_ALTER TABLE %s PARALLEL EXECUTION ON OPCODE %s ''", tableName, (audited ? "65" : "66")); // set sqlparserflags to allow 'label_alter' syntax masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); if (cliRC < 0) { return -1; } return 0; }
short ExExeUtilTcb::alterObjectState(NABoolean online, char * tableName, char * failReason, NABoolean forPurgedata) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // make object online str_sprintf(buf, "ALTER TABLE %s %s %s", tableName, (online ? "ONLINE" : "OFFLINE"), (forPurgedata ? "FOR PURGEDATA" : " ")); // set sqlparserflags to allow 'FOR PURGEDATA' syntax masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); if (cliRC < 0) { str_sprintf(failReason, "Could not alter the state of table %s to %s.", tableName, (online ? "online" : "offline")); return -1; } return 0; }
// ***************************************************************************** // * * // * Function: PrivMgrMDTable::selectCountWhere * // * * // * * // * This method returns the number of rows in table that match the * // * criteria in a WHERE clause. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <whereClause> const std::string & In * // * is the WHERE clause (including the keyword WHERE). * // * * // * <whereClause> int64_t & Out * // * passes back the number of rows read. * // * * // ***************************************************************************** // * * // * Returns: PrivStatus * // * * // * STATUS_GOOD: Statement executed successfully, valid row count returned. * // * STATUS_ERROR: Execution failed. A CLI error is put into the diags area. * // * * // ***************************************************************************** PrivStatus PrivMgrMDTable::selectCountWhere( const std::string & whereClause, int64_t & rowCount) { rowCount = 0; std::string selectStmt ("SELECT COUNT(*) FROM "); selectStmt += tableName_; selectStmt += " "; selectStmt += whereClause; int32_t length = 0; ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); int32_t cliRC = cliInterface.executeImmediate(selectStmt.c_str(), (char*)&rowCount, &length,NULL); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); return STATUS_ERROR; } return STATUS_GOOD; }
// ***************************************************************************** // * * // * Function: PrivMgrMDTable::executeFetchAll * // * * // * This method calls the CLI to fetch rows from a table. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <SQLStatement> const std::string & In * // * is the SQL statement to be executed. * // * * // * <queue> Queue * & Out * // * passes back a pointer to the queue containing the rows. * // * * // ***************************************************************************** // * * // * Returns: PrivStatus * // * * // * STATUS_GOOD: Row(s) read successfully. * // * STATUS_NOTFOUND: Statement executed successfully, but there were no rows. * // * *: Read failed. A CLI error is put into the diags area. * // * * // ***************************************************************************** PrivStatus PrivMgrMDTable::executeFetchAll( const std::string & SQLStatement, Queue * & queue) { ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); queue = NULL; // set pointer in diags area int32_t diagsMark = pDiags_->mark(); int32_t cliRC = cliInterface.fetchAllRows(queue,(char *)SQLStatement.c_str(),0, false,false,true); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(pDiags_); return STATUS_ERROR; } if (cliRC == 100) // did not find the row { pDiags_->rewind(diagsMark); return STATUS_NOTFOUND; } return STATUS_GOOD; }
short ExExeUtilLongRunningTcb::processContinuing(Lng32 &rc) { Int64 rowsAffected = 0; rc = cliInterface()->execContinuingRows(getContinuingOutputVarPtrList(), rowsAffected); if (rc < 0) { return -1; } if (rowsAffected > 0) addRowsDeleted(rowsAffected); #ifdef _DEBUG if ((rowsAffected > 0) && lrTdb().longRunningQueryPlan()) { char lruQPInfo[100]; str_sprintf(lruQPInfo, "Continuing rows deleted: %ld\n\n", rowsAffected); ComDiagsArea * diagsArea = getDiagAreaFromUpQueueTail(); (*diagsArea) << DgSqlCode(8427) << DgString0(lruQPInfo); } #endif return 0; }
// ---------------------------------------------------------------------------- // method: authExists // // Input: none // // Output: // Returns true if authorization row exists in the metadata // Returns false if authorization row does not exist in the metadata // // An exception is thrown if any unexpected errors occurred. // ---------------------------------------------------------------------------- bool CmpSeabaseDDLauth::authExists (bool isExternal) { // Read the auths table based on the auth_db_name NAString sysCat = CmpSeabaseDDL::getSystemCatalogStatic(); NAString colName = (isExternal) ? "auth_ext_name" : "auth_db_name"; NAString authName = (isExternal) ? getAuthExtName() : getAuthDbName(); char buf[1000]; str_sprintf(buf, "select count(*) from %s.\"%s\".%s where %s = '%s' ", sysCat.data(), SEABASE_MD_SCHEMA, SEABASE_AUTHS, colName.data(), authName.data()); Lng32 len = 0; Int64 rowCount = 0; ExeCliInterface cliInterface(STMTHEAP); Lng32 cliRC = cliInterface.executeImmediate(buf, (char*)&rowCount, &len, NULL); // If unexpected error occurred, return an exception if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); UserException excp (NULL, 0); excp.throwException(); } return (rowCount > 0) ? true : false; }
// ***************************************************************************** // * * // * Function: CmpSeabaseDDL::createSeabaseSchema * // * * // * Implements the CREATE SCHEMA command. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <createSchemaNode> StmtDDLCreateSchema * In * // * is a pointer to a create schema parser node. * // * * // * <currentCatalogName> NAString & In * // * is the name of the current catalog. * // * * // ***************************************************************************** void CmpSeabaseDDL::createSeabaseSchema( StmtDDLCreateSchema * createSchemaNode, NAString & currentCatalogName) { ComSchemaName schemaName (createSchemaNode->getSchemaName()); if (schemaName.getCatalogNamePart().isEmpty()) schemaName.setCatalogNamePart(currentCatalogName); NAString catName = schemaName.getCatalogNamePartAsAnsiString(); ComAnsiNamePart schNameAsComAnsi = schemaName.getSchemaNamePart(); NAString schName = schNameAsComAnsi.getInternalName(); ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); ComSchemaClass schemaClass; Int32 objectOwner = NA_UserIdDefault; Int32 schemaOwner = NA_UserIdDefault; int32_t retCode = verifyDDLCreateOperationAuthorized(&cliInterface, SQLOperation::CREATE_SCHEMA, catName, schName, schemaClass, objectOwner, schemaOwner); if (retCode != 0) { handleDDLCreateAuthorizationError(retCode,catName,schName); return; } Int32 schemaOwnerID = NA_UserIdDefault; // If the AUTHORIZATION clause was not specified, the current user becomes // the schema owner. if (createSchemaNode->getAuthorizationID().isNull()) schemaOwnerID = ComUser::getCurrentUser(); else if (ComUser::getAuthIDFromAuthName(createSchemaNode->getAuthorizationID().data(), schemaOwnerID) != 0) { *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR) << DgString0(createSchemaNode->getAuthorizationID().data()); return; } addSchemaObject(cliInterface, schemaName, createSchemaNode->getSchemaClass(), schemaOwnerID, createSchemaNode->createIfNotExists()); }
short ExExeUtilTcb::restoreCQS() { Lng32 rc = cliInterface()-> executeImmediate("control query shape restore;"); if (rc < 0) { handleErrors(rc); return -1; } return 0; }
short ExExeUtilTcb::lockUnlockObject(char * tableName, NABoolean lock, NABoolean parallel, char * failReason) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // lock or unlock the table. if (parallel) { if (lock) str_sprintf(buf, "LOCK TABLE %s IN PROTECTED MODE NO INDEX LOCK PARALLEL EXECUTION ON", tableName); else str_sprintf(buf, "UNLOCK TABLE %s PARALLEL EXECUTION ON", tableName); } else { if (lock) str_sprintf(buf, "LOCK TABLE %s IN PROTECTED MODE", tableName); else str_sprintf(buf, "UNLOCK TABLE %s", tableName); } masterGlob->getStatement()->getContext()->setSqlParserFlags(0x100001); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x100001); if (cliRC < 0) { if (lock) str_sprintf(failReason, "Could not lock table %s in protected mode using parallel execution.", tableName); else str_sprintf(failReason, "Could not unlock table %s using parallel execution.", tableName); return -1; } return 0; }
Lng32 ExExeUtilTcb::changeAuditAttribute(char * tableName, NABoolean makeAudited, NABoolean isVolatile, NABoolean isIndex, NABoolean parallelAlter) { Lng32 retcode = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // set sqlparserflags to allow change of audit attribute masterGlob->getStatement()->getContext()->setSqlParserFlags(0x400); // ALLOW_AUDIT_CHANGE // make table unaudited char stmt[500]; strcpy(stmt, "alter "); if (isVolatile) strcat(stmt, "volatile "); strcat(stmt, "table "); strcat(stmt, tableName); if (makeAudited) strcat(stmt, " attribute audit"); else strcat(stmt, " attribute no audit"); if (parallelAlter) strcat(stmt, " no label update"); strcat(stmt, ";"); retcode = cliInterface()->executeImmediate (stmt, NULL, NULL, TRUE, NULL, 0, &(masterGlob->getStatement()->getContext()->diags())); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x400); // ALLOW_AUDIT_CHANGE if (retcode < 0) return retcode; if (parallelAlter) { retcode = alterAuditFlag(makeAudited, tableName, isIndex); if (retcode < 0) return retcode; } return 0; }
short ExExeUtilTcb::resetCS(const char * csName, ComDiagsArea * globalDiags) { Lng32 cliRC; cliRC = resetCS(csName, cliInterface(), globalDiags); if (cliRC < 0) { handleErrors(cliRC); return -1; } return 0; }
short ExExeUtilTcb::disableCQS() { // disable any CQS in affect Lng32 rc = cliInterface()-> executeImmediate("control query shape hold;"); if (rc < 0) { handleErrors(rc); return -1; } return 0; }
// ***************************************************************************** // * * // * Function: PrivMgrMDTable::CLIImmediate * // * * // * This method calls the CLI to execute a SQL statement. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <SQLStatement> const std::string & In * // * is the SQL statement to be executed. Note, it can be any SQL * // * statement, but if you need to access the data that was read, you need * // * to use CLIFetch and provide a CLI Interface. * // * * // ***************************************************************************** // * * // * Returns: PrivStatus * // * * // * STATUS_GOOD: Statement executed successfully. * // * STATUS_ERROR: Execution failed. A CLI error is put into the diags area. * // * * // ***************************************************************************** PrivStatus PrivMgrMDTable::CLIImmediate(const std::string & SQLStatement) { ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); int32_t cliRC = cliInterface.executeImmediate(SQLStatement.c_str()); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(pDiags_); return STATUS_ERROR; } return STATUS_GOOD; }
// Delete a row from the AUTHS table based on the AUTH_ID void CmpSeabaseDDLauth::deleteRow(const NAString &authName) { NAString systemCatalog = CmpSeabaseDDL::getSystemCatalogStatic(); char buf[1000]; ExeCliInterface cliInterface(STMTHEAP); str_sprintf(buf, "delete from %s.\"%s\".%s where auth_db_name = '%s'", systemCatalog.data(), SEABASE_MD_SCHEMA, SEABASE_AUTHS, authName.data()); Lng32 cliRC = cliInterface.executeImmediate(buf); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); UserException excp (NULL, 0); excp.throwException(); } }
short ExExeUtilTcb::holdAndSetCQD(const char * defaultName, const char * defaultValue, ComDiagsArea * globalDiags) { Lng32 cliRC; cliRC = holdAndSetCQD(defaultName, defaultValue, cliInterface(), globalDiags); if (cliRC < 0) { handleErrors(cliRC); return -1; } return 0; }
short ExExeUtilTcb::fetchAllRows(Queue * &infoList, char * query, Lng32 numOutputEntries, NABoolean varcharFormat, short &rc, NABoolean monitorThis) { rc = cliInterface()->fetchAllRows(infoList, query, numOutputEntries, varcharFormat, monitorThis); if (rc < 0) { handleErrors(rc); return -1; } return 0; }
// Insert a row into the AUTHS table void CmpSeabaseDDLauth::insertRow() { char buf[1000]; ExeCliInterface cliInterface(STMTHEAP); NAString authType; switch (getAuthType()) { case COM_ROLE_CLASS: authType = COM_ROLE_CLASS_LIT; break; case COM_USER_CLASS: authType = COM_USER_CLASS_LIT; break; default: authType = COM_UNKNOWN_ID_CLASS_LIT; } NAString authValid = isAuthValid() ? "Y" : "N"; NAString immutable = isAuthImmutable() ? "Y" : "N"; NAString sysCat = CmpSeabaseDDL::getSystemCatalogStatic(); str_sprintf(buf, "insert into %s.\"%s\".%s values (%d, '%s', '%s', '%s', %d, '%s', %Ld, %Ld)", sysCat.data(), SEABASE_MD_SCHEMA, SEABASE_AUTHS, getAuthID(), getAuthDbName().data(), getAuthExtName().data(), authType.data(), getAuthCreator(), authValid.data(), getAuthCreateTime(), getAuthRedefTime()); Int32 cliRC = cliInterface.executeImmediate(buf); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); UserException excp (NULL, 0); excp.throwException(); } }
// ---------------------------------------------------------------------------- // method: getUniqueUserID // // This method returns a unique user ID // // Input: none // // Output: returns a unique user ID // An exception is generated, if a unique ID could not be generated // ---------------------------------------------------------------------------- Int32 CmpSeabaseDDLuser::getUniqueUserID() { NAString sysCat = CmpSeabaseDDL::getSystemCatalogStatic(); char buf[400]; str_sprintf(buf, "select max (auth_id) from %s.\"%s\".%s where auth_id >= 0 and auth_id < 1000000" , sysCat.data(), SEABASE_MD_SCHEMA, SEABASE_AUTHS); Lng32 len = 0; Int32 maxValue = 0; ExeCliInterface cliInterface(STMTHEAP); Lng32 cliRC = cliInterface.executeImmediate(buf, (char *)&maxValue, &len, true); if (cliRC != 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); UserException excp (NULL, 0); excp.throwException(); } maxValue++; return maxValue; }
short ExExeUtilLongRunningTcb::finalizeDoLongRunning() { // Close the statements Lng32 rc = cliInterface()->prepareAndExecRowsEpilogue(); NADELETE(initialOutputVarPtrList_, Queue, getHeap()); NADELETE(continuingOutputVarPtrList_, Queue, getHeap()); NADELETEBASIC(lruStmtAndPartInfo_, getHeap()); NADELETEBASIC(lruStmtWithCKAndPartInfo_, getHeap()); // if this is an ESP, deallocate transaction CliGlobals *cliGlobals = GetCliGlobals(); if (cliGlobals->isESPProcess()) { NADELETEBASIC(currTransaction_, getHeap()); currTransaction_ = NULL; } return 0; }
// ***************************************************************************** // * * // * Function: PrivMgrMDTable::updateWhere * // * * // * This method updates rows in table based on a SET an d WHERE clause. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <setClause> const std::string & In * // * is the SET clause (including the keyword SET). * // * * // * <whereClause> const std::string & In * // * is the WHERE clause (including the keyword WHERE). * // * * // ***************************************************************************** // * * // * Returns: PrivStatus * // * * // * STATUS_ERROR: Execution failed. A CLI error is put into the diags area. * // * STATUS_GOOD: Statement executed successfully. * // * STATUS_NOTFOUND: No row found that match WHERE clause. * // * STATUS_WARNING: Statement executed to completion but with a warning. See * // * the CLI diags area. * // * * // ***************************************************************************** PrivStatus PrivMgrMDTable::updateWhere( const std::string & setClause, const std::string & whereClause) { std::string updateStmt("UPDATE "); updateStmt += tableName_; updateStmt += " "; updateStmt += setClause; updateStmt += " "; updateStmt += whereClause; // set pointer in diags area int32_t diagsMark = pDiags_->mark(); ExeCliInterface cliInterface(STMTHEAP,NULL,NULL, CmpCommon::context()->sqlSession()->getParentQid()); int32_t cliRC = cliInterface.executeImmediate(updateStmt.c_str()); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(pDiags_); return STATUS_ERROR; } if (cliRC == 100) // did not find any rows { pDiags_->rewind(diagsMark); return STATUS_NOTFOUND; } if (cliRC > 0) return STATUS_WARNING; return STATUS_GOOD; }
void ExExeUtilTcb::restoreMaintainControlTableTimeout(char * catalog) { Lng32 cliRC; char buf[400+ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES]; Lng32 markValue = -1; // If the restoration timeout flag is not set, // then just return. if (!restoreTimeout_) return; markValue = getDiagsArea()->mark(); // Reset the timeout to its previous setting. // Errors are ignored. strcpy(buf, "SET TABLE "); strcat(buf, catalog); strcat(buf, ".\"@MAINTAIN_SCHEMA@\".\"@MAINTAIN_CONTROL_INFO@\" "); strcat(buf, " TIMEOUT RESET;"); cliRC = cliInterface()->executeImmediate(buf); if (cliRC < 0) { // ignore any error occurring from the executeImmediate call // rewind to not report this one error getDiagsArea()->rewind(markValue); SQL_EXEC_ClearDiagnostics(NULL); return; } restoreTimeout_ = FALSE; return; }
void ExExeUtilTcb::setMaintainControlTableTimeout(char * catalog) { Lng32 cliRC; char buf[400+ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES]; Lng32 markValue = -1; char timeoutHoldBuf[100]; Lng32 timeoutHoldBufLen = 0; // The MAINTAIN_CONTROL_TABLE_TIMEOUT CQD default is '30000', 5 minutes restoreTimeout_ = FALSE; strcpy(buf, "showcontrol default "); strcat(buf, "MAINTAIN_CONTROL_TABLE_TIMEOUT"); strcat(buf, " , match full, no header;"); markValue = getDiagsArea()->mark(); // get the current value of MAINTAIN_CONTROL_TABLE_TIMEOUT cliRC = cliInterface()-> executeImmediate(buf, timeoutHoldBuf, &timeoutHoldBufLen); // If we were unable to obtain the default value, // then just return and allow the 60 second general // timeout for a table to remain. if (cliRC < 0) { // Ignore any error occurring from the executeImmediate call. // Rewind to not report this one error. getDiagsArea()->rewind(markValue); SQL_EXEC_ClearDiagnostics(NULL); return; } // The timeout setting will be retained for the duration // of executing the maintain tasks. // Execute the set table timeout statement. // The SET TABLE TIMEOUT statement sets a dynamic timeout value for a lock timeout // or a stream timeout in the environment of the current session. The dynamic timeout // value overrides the compiled static timeout value in the execution of subsequent DML // statements. markValue = getDiagsArea()->mark(); strcpy(buf, "SET TABLE "); strcat(buf, catalog); strcat(buf, ".\"@MAINTAIN_SCHEMA@\".\"@MAINTAIN_CONTROL_INFO@\" "); strcat(buf, " TIMEOUT "); strcat(buf, " '"); strcat(buf, timeoutHoldBuf); strcat(buf, "';"); cliRC = cliInterface()->executeImmediate(buf); if (cliRC < 0) { // Ignore any error occurring from the executeImmediate call. // Rewind to not report this one error. getDiagsArea()->rewind(markValue); SQL_EXEC_ClearDiagnostics(NULL); return; } // Set the flag to indicate the timeout // should be restored restoreTimeout_ = TRUE; return; }
short ExExeUtilTcb::executeQuery(char * task, char * object, char * query, NABoolean displayStartTime, NABoolean displayEndTime, short &rc, short * warning, Lng32 * ec, NABoolean moveErrorRow, NABoolean continueOnError, NABoolean monitorThis) { short retcode = 0; char buf[BUFFER_SIZE]; while (1) { switch (pqStep_) { case PROLOGUE_: { warning_ = 0; startTime_ = NA_JulianTimestamp(); elapsedTime_ = 0; if (displayStartTime) { getStatusString(task, "Started", object, buf); if (moveRowToUpQueue(buf, 0, &rc)) return 1; } pqStep_ = EXECUTE_; rc = WORK_RESCHEDULE_AND_RETURN; return 1; } break; case EXECUTE_: { retcode = cliInterface()->fetchRowsPrologue(query,FALSE,monitorThis); if (retcode < 0) { pqStep_ = ERROR_RETURN_; break; } pqStep_ = FETCH_ROW_; } break; case FETCH_ROW_: { retcode = (short)cliInterface()->fetch(); if (retcode < 0) { pqStep_ = ERROR_RETURN_; break; } if ((retcode > 0) && (retcode != 100)) warning_ = retcode; if ((retcode != 100) && (cliInterface()->outputBuf())) pqStep_ = RETURN_ROW_; else pqStep_ = CLOSE_; } break; case RETURN_ROW_: { char * ptr; Lng32 len; cliInterface()->getPtrAndLen(1, ptr, len); retcode = moveRowToUpQueue(ptr, len, &rc); if (retcode) return 1; pqStep_ = FETCH_ROW_; } break; case CLOSE_: { retcode = cliInterface()->fetchRowsEpilogue(""); if (retcode < 0) { pqStep_ = ERROR_RETURN_; break; } pqStep_ = EPILOGUE_; } break; case EPILOGUE_: { endTime_ = NA_JulianTimestamp(); elapsedTime_ = endTime_ - startTime_; if (displayEndTime) { char timeBuf[200]; getTimeAsString(elapsedTime_, timeBuf); getStatusString(task, "Ended", object, buf, timeBuf); if (moveRowToUpQueue(buf, 0, &rc)) return 1; } pqStep_ = ALL_DONE_; rc = WORK_RESCHEDULE_AND_RETURN; return 1; } break; case ERROR_RETURN_: { Lng32 sqlcode = 0; char * stringParam1 = NULL; Lng32 intParam1 = ComDiags_UnInitialized_Int; retcode = (short)cliInterface()->retrieveSQLDiagnostics(getDiagsArea()); if (moveErrorRow) { if (retcode == 0) { ComDiagsArea * da = getDiagsArea(); sqlcode = (short)da->mainSQLCODE(); ComCondition * cc; if (sqlcode < 0) cc = da->getErrorEntry(1); else cc = da->getWarningEntry(1); if (sqlcode < 0 && ec != NULL) *ec = sqlcode; if (cc->getOptionalStringCharSet(0) == CharInfo::ISO88591 || cc->getOptionalStringCharSet(0) == CharInfo::UTF8) stringParam1 = (char*)cc->getOptionalString(0); else stringParam1 = NULL; intParam1 = cc->getOptionalInteger(0); } else { sqlcode = retcode; } Lng32 errorBufLen = 200 + (stringParam1 ? strlen(stringParam1) : 0); char * errorBuf = new(getHeap()) char[errorBufLen]; str_sprintf(errorBuf, "%d", sqlcode); if (stringParam1) str_sprintf(&errorBuf[strlen(errorBuf)], ", %s", stringParam1); if (intParam1 != ComDiags_UnInitialized_Int) str_sprintf(&errorBuf[strlen(errorBuf)], ", %d", intParam1); char * outBuf = new(getHeap()) char[errorBufLen+400]; getStatusString(task, "Error", NULL, outBuf, NULL, NULL, errorBuf); NADELETEBASIC(errorBuf, getHeap()); if ((moveErrorRow) && (moveRowToUpQueue(outBuf, 0, &rc))) { NADELETEBASIC(outBuf, getHeap()); return 1; } NADELETEBASIC(outBuf, getHeap()); } // close cursor, etc. Ignore errors. cliInterface()->fetchRowsEpilogue(""); if (continueOnError) { pqStep_ = ALL_DONE_; rc = WORK_RESCHEDULE_AND_RETURN; return 1; } else { pqStep_ = PROLOGUE_; return -1; } } break; case ALL_DONE_: { pqStep_ = PROLOGUE_; if (warning) *warning = warning_; return 0; } break; } } }
short ExExeUtilTcb::initializeInfoList(Queue* &infoList) { return cliInterface()->initializeInfoList(infoList, infoListIsOutputInfo_); }
void ExExeUtilTcb::handleErrors(Lng32 rc) { cliInterface()->retrieveSQLDiagnostics(getDiagsArea()); }
// ---------------------------------------------------------------------------- // method: authorizationEnabled // // Input: pointer to the error structure // // Returns: // PRIV_INITIALIZED means all metadata tables exist // PRIV_UNINITIALIZED means no metadata tables exist // PRIV_PARTIALLY_INITIALIZED means only part of the metadata tables exist // PRIV_INITIALIZE_UNKNOWN means unable to retrieve metadata table info // // A cli error is put into the diags area if there is an error // ---------------------------------------------------------------------------- PrivMgr::PrivMDStatus PrivMgr::authorizationEnabled( std::set<std::string> &existingObjectList) { // Will require QI to reset on INITIALIZE AUTHORIZATION [,DROP] // get the list of tables from the schema // if the catalog name ever allows an embedded '.', this code will need // to change. std::string metadataLocation = getMetadataLocation(); size_t period = metadataLocation.find("."); std::string catName = metadataLocation.substr(0, period); std::string schName = metadataLocation.substr(period+1); char buf[1000]; sprintf(buf, "get tables in schema %s.%s, no header", catName.c_str(), schName.c_str()); ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); Queue * schemaQueue = NULL; // set pointer in diags area int32_t diagsMark = pDiags_->mark(); int32_t cliRC = cliInterface.fetchAllRows(schemaQueue, buf, 0, FALSE, FALSE, TRUE); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(pDiags_); return PRIV_INITIALIZE_UNKNOWN; } if (cliRC == 100) // did not find the row { pDiags_->rewind(diagsMark); return PRIV_UNINITIALIZED; } // Not sure how this can happen but code I cloned had the check if (schemaQueue->numEntries() == 0) return PRIV_UNINITIALIZED; // Gather the returned list of tables in existingObjectList schemaQueue->position(); for (int idx = 0; idx < schemaQueue->numEntries(); idx++) { OutputInfo * row = (OutputInfo*)schemaQueue->getNext(); std::string theName = row->get(0); existingObjectList.insert(theName); } // Gather the list of expected tables in expectedObjectList std::set<string> expectedObjectList; size_t numTables = sizeof(privMgrTables)/sizeof(PrivMgrTableStruct); for (int ndx_tl = 0; ndx_tl < numTables; ndx_tl++) { const PrivMgrTableStruct &tableDefinition = privMgrTables[ndx_tl]; expectedObjectList.insert(tableDefinition.tableName); } // Compare the existing with the expected std::set<string> diffsObjectList; std::set_difference (expectedObjectList.begin(), expectedObjectList.end(), existingObjectList.begin(), existingObjectList.end(), std::inserter(diffsObjectList, diffsObjectList.end())); // If the number of existing tables match the expected, diffsObjectList // is empty -> return initialized if (diffsObjectList.empty()) return PRIV_INITIALIZED; // If the number of existing tables does not match the expected, // initialization is required -> return not initialized if (existingObjectList.size() == diffsObjectList.size()) return PRIV_UNINITIALIZED; // Otherwise, mismatch is found, return partially initialized return PRIV_PARTIALLY_INITIALIZED; }
// lockType: COM_UTIL_PURGEDATA (= 9), COM_UTIL_REPLICATE (= 19). // (definition in common/ComSmallDefs.h). short ExExeUtilTcb::alterDDLLock(NABoolean add, char * tableName, char * failReason, NABoolean isMV, Int32 lockType, const char * lockSuffix, NABoolean skipDDLLockCheck) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); AnsiOrNskName aonn(tableName); aonn.convertAnsiOrNskName(FALSE); char * parts[4]; Lng32 numParts; aonn.extractParts(numParts, parts); char * quotedParts0 = NULL; char * quotedParts1 = NULL; if (numParts == 3) { quotedParts0 = new(getGlobals()->getDefaultHeap()) char[strlen(parts[0]) * 2 + 1]; quotedParts1 = new(getGlobals()->getDefaultHeap()) char[strlen(parts[1]) * 2 + 1]; doubleQuoteStr(parts[0], quotedParts0, FALSE); doubleQuoteStr(parts[1], quotedParts1, FALSE); } //////////////////////////////////////////////////////////////// // see sqlshare/catapirequest.h for details on CAT API params. // CatApi has the form: // CREATE TANDEM_CAT_REQUEST&1 <request-type> <num-params> // <lock-name> <object-name> <object-type> <operation-type> // request-type: 1 (create lock) or 2 (drop lock) // num-params: 5 // lock-name: getTableName() appended with _DDL_LOCK // object-name: getTableName() // object-type: 0 (table) or 2 (MV) // operation-type: 9 (purgedata) // lockStatus: 9 (parallel purgedata) //////////////////////////////////////////////////////////////// char sdlc[200]; if (skipDDLLockCheck) { str_sprintf(sdlc, "<> <0> <1>"); } // alter(add or drop) DDL lock if (numParts == 3) { char lockNameSuffix[200]; str_sprintf(lockNameSuffix, "_DDL_LOCK%s", (lockSuffix ? lockSuffix : "")); generateLockName(parts[2], lockNameSuffix, buf, sizeof buf - 20); char quotedLockName[ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES+200]; // a big buffer doubleQuoteStr(buf, quotedLockName, FALSE); str_sprintf(buf, "CREATE TANDEM_CAT_REQUEST&1 %s %d <\"%s\".\"%s\".\"%s\"> <%s%s> <%s> <%d> %s %s", (add ? "1" : "2"), (skipDDLLockCheck ? 8 : 5), //(lockType == COM_UTIL_PURGEDATA ? 5 : 4), quotedParts0, quotedParts1, quotedLockName, tableName, "", (isMV ? "2" : "0"), lockType, (lockType == COM_UTIL_PURGEDATA ? "<9>" : "<0>"), skipDDLLockCheck ? sdlc : ""); } else str_sprintf(buf, "CREATE TANDEM_CAT_REQUEST&1 %s %d <%s_DDL_LOCK%s> <%s%s> <%s> <%d> %s %s", (add ? "1" : "2"), // (lockType == COM_UTIL_PURGEDATA ? 5 : 4), (skipDDLLockCheck ? 8 : 5), //(lockType == COM_UTIL_PURGEDATA ? 5 : 4), tableName, (lockSuffix ? lockSuffix : ""), tableName, "", (isMV ? "2" : "0"), lockType, (lockType == COM_UTIL_PURGEDATA ? "<9>" : "<0>"), skipDDLLockCheck ? sdlc : ""); // set sqlparserflags to allow CAT_API_REQUEST masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); NADELETEBASIC(quotedParts0, getGlobals()->getDefaultHeap()); NADELETEBASIC(quotedParts1, getGlobals()->getDefaultHeap()); if (cliRC < 0) { str_sprintf(failReason, "Could not %s ddl lock for object %s.", (add ? "add" : "drop"), tableName); return (short)cliRC; } else return 0; }