http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/681cad66/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp b/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp index fb9c802..d6325e7 100644 --- a/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp +++ b/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp @@ -1,4 +1,4 @@ - /********************************************************************** +/********************************************************************** // @@@ START COPYRIGHT @@@ // // Licensed to the Apache Software Foundation (ASF) under one @@ -1530,11 +1530,18 @@ short CmpSeabaseDDL::createSeabaseTable2( objectOwnerID = schemaOwnerID; // check if SYSKEY is specified as a column name. - NABoolean explicitSyskeySpecified = FALSE; for (Lng32 i = 0; i < colArray.entries(); i++) { - if (colArray[i]->getColumnName() == "SYSKEY") - explicitSyskeySpecified = TRUE; + if ((CmpCommon::getDefault(TRAF_ALLOW_RESERVED_COLNAMES) == DF_OFF) && + (ComTrafReservedColName(colArray[i]->getColumnName()))) + { + *CmpCommon::diags() << DgSqlCode(-1269) + << DgString0(colArray[i]->getColumnName()); + + deallocEHI(ehi); + processReturn(); + return -1; + } } NABoolean implicitPK = FALSE; @@ -1562,18 +1569,6 @@ short CmpSeabaseDDL::createSeabaseTable2( numSysCols++; } - if ((implicitPK) && (explicitSyskeySpecified)) - { - *CmpCommon::diags() << DgSqlCode(-1080) - << DgColumnName("SYSKEY"); - - deallocEHI(ehi); - - processReturn(); - - return -1; - } - int numSaltPartns = 0; // # of "_SALT_" values int numSplits = 0; // # of initial region splits @@ -1582,7 +1577,7 @@ short CmpSeabaseDDL::createSeabaseTable2( if ((createTableNode->getSaltOptions()) || ((numSaltPartnsFromCQD > 0) && - (NOT (implicitPK || explicitSyskeySpecified)))) + (NOT implicitPK))) { // add a system column SALT INTEGER NOT NULL with a computed // default value HASH2PARTFUNC(<salting cols> FOR <num salt partitions>) @@ -1615,7 +1610,17 @@ short CmpSeabaseDDL::createSeabaseTable2( { const NAString &colName = (*saltArray)[i]->getColumnName(); ComAnsiNamePart cnp(colName, ComAnsiNamePart::INTERNAL_FORMAT); - CollIndex colIx = colArray.getColumnIndex(colName); + Lng32 colIx = colArray.getColumnIndex(colName); + if (colIx < 0) + { + *CmpCommon::diags() << DgSqlCode(-1009) + << DgColumnName(colName); + + deallocEHI(ehi); + processReturn(); + return -1; + } + NAType *colType = colArray[colIx]->getColumnDataType(); NAString typeText; short rc = colType->getMyTypeAsText(&typeText, FALSE); @@ -1904,7 +1909,7 @@ short CmpSeabaseDDL::createSeabaseTable2( if (colType->getFSDatatype() == REC_BLOB || colType->getFSDatatype() == REC_CLOB) //Cannot allow LOB in primary or clustering key { - *CmpCommon::diags() << DgSqlCode(CAT_LOB_COL_CANNOT_BE_INDEX_OR_KEY) + *CmpCommon::diags() << DgSqlCode(-CAT_LOB_COL_CANNOT_BE_INDEX_OR_KEY) << DgColumnName(colName); deallocEHI(ehi); @@ -2224,8 +2229,13 @@ short CmpSeabaseDDL::createSeabaseTable2( } Int64 lobMaxSize = CmpCommon::getDefaultNumeric(LOB_MAX_SIZE)*1024*1024; + + const char *lobHdfsServer = CmpCommon::getDefaultString(LOB_HDFS_SERVER); + Int32 lobHdfsPort = (Lng32)CmpCommon::getDefaultNumeric(LOB_HDFS_PORT); + if (j > 0) { + Int32 rc = sendAllControls(FALSE, FALSE, TRUE); //if the table is a volatile table return an error if (createTableNode->isVolatile()) { @@ -2241,13 +2251,13 @@ short CmpSeabaseDDL::createSeabaseTable2( catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(), COM_BASE_TABLE_OBJECT_LIT); - + ComString newSchName = "\""; newSchName += catalogNamePart; newSchName.append("\".\""); newSchName.append(schemaNamePart); newSchName += "\""; - Lng32 rc = SQL_EXEC_LOBddlInterface((char*)newSchName.data(), + rc = SQL_EXEC_LOBddlInterface((char*)newSchName.data(), newSchName.length(), objUID, j, @@ -2255,8 +2265,10 @@ short CmpSeabaseDDL::createSeabaseTable2( lobNumList, lobTypList, lobLocList, + (char *)lobHdfsServer, + lobHdfsPort, lobMaxSize); - + if (rc < 0) { //sss TBD need to retrive the cli diags here. @@ -2264,11 +2276,12 @@ short CmpSeabaseDDL::createSeabaseTable2( << DgTableName(extTableName); deallocEHI(ehi); processReturn(); - + return -2; } - } // j > 0 - + } + + // if not a compound create, update valid def to true. if (NOT ((createTableNode->getAddConstraintUniqueArray().entries() > 0) || (createTableNode->getAddConstraintRIArray().entries() > 0) || @@ -3050,7 +3063,9 @@ short CmpSeabaseDDL::dropSeabaseTable2( } else if (dropTableNode->getDropBehavior() == COM_CASCADE_DROP_BEHAVIOR) { - cliRC = getUsingViews(cliInterface, objUID, usingViewsQueue); + cliRC = getAllUsingViews(cliInterface, + catalogNamePart, schemaNamePart, objectNamePart, + usingViewsQueue); if (cliRC < 0) { deallocEHI(ehi); @@ -3099,13 +3114,14 @@ short CmpSeabaseDDL::dropSeabaseTable2( // Drop referencing objects char query[4000]; + // drop the views. + // usingViewsQueue contain them in ascending order of their create + // time. Drop them from last to first. if (usingViewsQueue) { - usingViewsQueue->position(); - for (int idx = 0; idx < usingViewsQueue->numEntries(); idx++) + for (int idx = usingViewsQueue->numEntries()-1; idx >= 0; idx--) { - OutputInfo * vi = (OutputInfo*)usingViewsQueue->getNext(); - + OutputInfo * vi = (OutputInfo*)usingViewsQueue->get(idx); char * viewName = vi->get(0); if (dropOneTableorView(*cliInterface,viewName,COM_VIEW_OBJECT,false)) @@ -3334,8 +3350,7 @@ short CmpSeabaseDDL::dropSeabaseTable2( processReturn(); return -1; - } - + } } // drop all check constraints from metadata if 'no check' is not specified. @@ -3553,6 +3568,8 @@ short CmpSeabaseDDL::dropSeabaseTable2( short *lobNumList = new (STMTHEAP) short[numCols]; short *lobTypList = new (STMTHEAP) short[numCols]; char **lobLocList = new (STMTHEAP) char*[numCols]; + const char *lobHdfsServer = CmpCommon::getDefaultString(LOB_HDFS_SERVER); + Int32 lobHdfsPort = (Lng32)CmpCommon::getDefaultNumeric(LOB_HDFS_PORT); Lng32 j = 0; for (Int32 i = 0; i < nacolArr.entries(); i++) { @@ -3573,7 +3590,7 @@ short CmpSeabaseDDL::dropSeabaseTable2( const char* f = ActiveSchemaDB()->getDefaults(). getValue(LOB_STORAGE_FILE_DIR); - + strcpy(loc, f); lobLocList[j] = loc; @@ -3582,6 +3599,7 @@ short CmpSeabaseDDL::dropSeabaseTable2( } if (j > 0) { + Int32 rc = sendAllControls(FALSE, FALSE, TRUE); Int64 objUID = getObjectUID(cliInterface, catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(), @@ -3592,14 +3610,14 @@ short CmpSeabaseDDL::dropSeabaseTable2( newSchName.append("\".\""); newSchName.append(schemaNamePart); newSchName += "\""; - Lng32 rc = SQL_EXEC_LOBddlInterface((char*)newSchName.data(), + rc = SQL_EXEC_LOBddlInterface((char*)newSchName.data(), newSchName.length(), objUID, j, LOB_CLI_DROP, lobNumList, lobTypList, - lobLocList,0); + lobLocList,(char *)lobHdfsServer, lobHdfsPort,0); if (rc < 0) { *CmpCommon::diags() << DgSqlCode(-CAT_UNABLE_TO_DROP_OBJECT) @@ -3888,7 +3906,29 @@ void CmpSeabaseDDL::renameSeabaseTable( return; } - Int64 objUID = getObjectUID(&cliInterface, + // cascade option not supported + if (renameTableNode->isCascade()) + { + *CmpCommon::diags() << DgSqlCode(-1427) + << DgString0("Reason: Cascade option not supported."); + + processReturn(); + return; + } + + const CheckConstraintList &checkList = naTable->getCheckConstraints(); + if (checkList.entries() > 0) + { + *CmpCommon::diags() + << DgSqlCode(-1427) + << DgString0("Reason: Operation not allowed if check constraints are present. Drop the constraints and recreate them after rename."); + + processReturn(); + + return; + } + + Int64 objUID = getObjectUID(&cliInterface, catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(), COM_BASE_TABLE_OBJECT_LIT); @@ -3913,7 +3953,7 @@ void CmpSeabaseDDL::renameSeabaseTable( if (usingViewsQueue->numEntries() > 0) { *CmpCommon::diags() << DgSqlCode(-1427) - << DgString0("Reason: Dependent views exist."); + << DgString0("Reason: Operation not allowed if dependent views exist. Drop the views and recreate them after rename."); processReturn(); return; @@ -4261,26 +4301,6 @@ short CmpSeabaseDDL::cloneSeabaseTable( return 0; } -short CmpSeabaseDDL::recreateViews(ExeCliInterface &cliInterface, - NAList<NAString> &viewNameList, - NAList<NAString> &viewDefnList) -{ - Lng32 cliRC = 0; - - for (Lng32 i = 0; i < viewDefnList.entries(); i++) - { - cliRC = cliInterface.executeImmediate(viewDefnList[i]); - if (cliRC < 0) - { - cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); - - return -1; - } - } - - return 0; -} - void CmpSeabaseDDL::alterSeabaseTableAddColumn( StmtDDLAlterTableAddColumn * alterAddColNode, NAString &currCatName, NAString &currSchName) @@ -4333,6 +4353,16 @@ void CmpSeabaseDDL::alterSeabaseTableAddColumn( return; } + if (retcode == 0) // does not exist + { + *CmpCommon::diags() << DgSqlCode(-CAT_CANNOT_ALTER_WRONG_TYPE) + << DgString0(extTableName); + + processReturn(); + + return; + } + ActiveSchemaDB()->getNATableDB()->useCache(); BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), FALSE/*inDDL*/); @@ -4454,6 +4484,17 @@ void CmpSeabaseDDL::alterSeabaseTableAddColumn( return; } + if ((CmpCommon::getDefault(TRAF_ALLOW_RESERVED_COLNAMES) == DF_OFF) && + (ComTrafReservedColName(colName))) + { + *CmpCommon::diags() << DgSqlCode(-1269) + << DgString0(colName); + + deallocEHI(ehi); + processReturn(); + return; + } + if (colFamily.isNull()) { colFamily = naTable->defaultColFam(); @@ -4844,101 +4885,390 @@ short CmpSeabaseDDL::updateMDforDropCol(ExeCliInterface &cliInterface, return 0; } -void CmpSeabaseDDL::alterSeabaseTableDropColumn( - StmtDDLAlterTableDropColumn * alterDropColNode, - NAString &currCatName, NAString &currSchName) +/////////////////////////////////////////////////////////////////////// +// +// An aligned table constains all columns in one hbase cell. +// To drop a column, we need to read each row, create a +// new row with the removed column and insert into the original table. +// +// Steps to drop a column from an aligned table: +// +// -- make a copy of the source aligned table using hbase copy +// -- truncate the source table +// -- Update metadata and remove the dropped column. +// -- bulk load data from copied table into the source table +// -- drop the copied temp table +// +// If an error happens after the source table has been truncated, then +// it will be restored from the copied table. +// +/////////////////////////////////////////////////////////////////////// +short CmpSeabaseDDL::alignedFormatTableDropColumn +( + const NAString &catalogNamePart, + const NAString &schemaNamePart, + const NAString &objectNamePart, + const NATable * naTable, + const NAString &altColName, + ElemDDLColDef *pColDef, + NABoolean ddlXns, + NAList<NAString> &viewNameList, + NAList<NAString> &viewDefnList) { Lng32 cliRC = 0; - Lng32 retcode = 0; - const NAString &tabName = alterDropColNode->getTableName(); + const NAFileSet * naf = naTable->getClusteringIndex(); + + CorrName cn(objectNamePart, STMTHEAP, schemaNamePart, catalogNamePart); - ComObjectName tableName(tabName, COM_TABLE_NAME); - ComAnsiNamePart currCatAnsiName(currCatName); - ComAnsiNamePart currSchAnsiName(currSchName); - tableName.applyDefaults(currCatAnsiName, currSchAnsiName); + ComUID comUID; + comUID.make_UID(); + Int64 objUID = comUID.get_value(); + + char objUIDbuf[100]; - const NAString catalogNamePart = tableName.getCatalogNamePartAsAnsiString(); - const NAString schemaNamePart = tableName.getSchemaNamePartAsAnsiString(TRUE); - const NAString objectNamePart = tableName.getObjectNamePartAsAnsiString(TRUE); - const NAString extTableName = tableName.getExternalName(TRUE); - const NAString extNameForHbase = catalogNamePart + "." + schemaNamePart + "." + objectNamePart; + NAString tempTable(naTable->getTableName().getQualifiedNameAsAnsiString()); + tempTable += "_"; + tempTable += str_ltoa(objUID, objUIDbuf); - ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, - CmpCommon::context()->sqlSession()->getParentQid()); + ExpHbaseInterface * ehi = allocEHI(); + ExeCliInterface cliInterface + (STMTHEAP, NULL, NULL, + CmpCommon::context()->sqlSession()->getParentQid()); - if ((isSeabaseReservedSchema(tableName)) && - (!Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))) + Int64 tableUID = naTable->objectUid().castToInt64(); + const NAColumnArray &naColArr = naTable->getNAColumnArray(); + const NAColumn * altNaCol = naColArr.getColumn(altColName); + Lng32 altColNum = altNaCol->getPosition(); + + NAString tgtCols; + NAString srcCols; + + NABoolean xnWasStartedHere = FALSE; + + char buf[4000]; + + if (cloneSeabaseTable(cn, naTable, tempTable, ehi, &cliInterface)) { - *CmpCommon::diags() << DgSqlCode(-CAT_CANNOT_ALTER_DEFINITION_METADATA_SCHEMA); - processReturn(); - return; + cliRC = -1; + goto label_drop; } - - ExpHbaseInterface * ehi = allocEHI(); - if (ehi == NULL) + + if (truncateHbaseTable(catalogNamePart, schemaNamePart, objectNamePart, + (NATable*)naTable, ehi)) { - processReturn(); - - return; + cliRC = -1; + goto label_restore; } - retcode = existsInSeabaseMDTable(&cliInterface, - catalogNamePart, schemaNamePart, objectNamePart, - COM_BASE_TABLE_OBJECT, - (Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL) - ? FALSE : TRUE), - TRUE, TRUE); - if (retcode < 0) + if (beginXnIfNotInProgress(&cliInterface, xnWasStartedHere)) { - processReturn(); - - return; + cliRC = -1; + goto label_restore; } - ActiveSchemaDB()->getNATableDB()->useCache(); - - BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), FALSE/*inDDL*/); - CorrName cn(tableName.getObjectNamePart().getInternalName(), - STMTHEAP, - tableName.getSchemaNamePart().getInternalName(), - tableName.getCatalogNamePart().getInternalName()); + if (updateMDforDropCol(cliInterface, naTable, altColNum)) + { + cliRC = -1; + goto label_restore; + } + + ActiveSchemaDB()->getNATableDB()->removeNATable + (cn, + ComQiScope::REMOVE_FROM_ALL_USERS, + COM_BASE_TABLE_OBJECT, ddlXns, FALSE); - const NATable *naTable = bindWA.getNATable(cn); - if (naTable == NULL || bindWA.errStatus()) + for (Int32 c = 0; c < naColArr.entries(); c++) { - *CmpCommon::diags() - << DgSqlCode(-4082) - << DgTableName(cn.getExposedNameAsAnsiString()); - - processReturn(); + const NAColumn * nac = naColArr[c]; + if (nac->getColName() == altColName) + continue; - return; - } + if (nac->isComputedColumn()) + continue; - // Make sure user has the privilege to perform the drop column - if (!isDDLOperationAuthorized(SQLOperation::ALTER_TABLE, - naTable->getOwner(),naTable->getSchemaOwner())) - { - *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); + if (nac->isSystemColumn()) + continue; - processReturn (); + tgtCols += nac->getColName(); + tgtCols += ","; + } // for - return; - } + tgtCols = tgtCols.strip(NAString::trailing, ','); - // return an error if trying to drop a column from a volatile table - if (naTable->isVolatileTable()) + str_sprintf(buf, "upsert using load into %s(%s) select %s from %s", + naTable->getTableName().getQualifiedNameAsAnsiString().data(), + tgtCols.data(), + tgtCols.data(), + tempTable.data()); + cliRC = cliInterface.executeImmediate(buf); + if (cliRC < 0) { - *CmpCommon::diags() << DgSqlCode(-CAT_REGULAR_OPERATION_ON_VOLATILE_OBJECT); - - processReturn (); - - return; + cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); + goto label_restore; } - const NAColumnArray &nacolArr = naTable->getNAColumnArray(); - const NAString &colName = alterDropColNode->getColName(); + if ((cliRC = recreateUsingViews(&cliInterface, viewNameList, viewDefnList, + ddlXns)) < 0) + { + NAString reason = "Error occurred while recreating views due to dependency on older column definition. Drop dependent views before doing the alter."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(altColName) + << DgString0(reason); + goto label_restore; + } + + endXnIfStartedHere(&cliInterface, xnWasStartedHere, 0); + + str_sprintf(buf, "drop table %s", tempTable.data()); + cliRC = cliInterface.executeImmediate(buf); + if (cliRC < 0) + { + cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); + goto label_restore; + } + + deallocEHI(ehi); + + return 0; + + label_restore: + endXnIfStartedHere(&cliInterface, xnWasStartedHere, -1); + + cloneHbaseTable(tempTable, + naTable->getTableName().getQualifiedNameAsAnsiString(), + ehi); + + label_drop: + str_sprintf(buf, "drop table %s", tempTable.data()); + Lng32 cliRC2 = cliInterface.executeImmediate(buf); + + deallocEHI(ehi); + + return (cliRC < 0 ? -1 : 0); +} + +short CmpSeabaseDDL::hbaseFormatTableDropColumn( + ExpHbaseInterface *ehi, + const NAString &catalogNamePart, + const NAString &schemaNamePart, + const NAString &objectNamePart, + const NATable * naTable, + const NAString &altColName, + const NAColumn * nacol, + NABoolean ddlXns, + NAList<NAString> &viewNameList, + NAList<NAString> &viewDefnList) +{ + Lng32 cliRC = 0; + + const NAString extNameForHbase = + catalogNamePart + "." + schemaNamePart + "." + objectNamePart; + + ExeCliInterface cliInterface( + STMTHEAP, NULL, NULL, + CmpCommon::context()->sqlSession()->getParentQid()); + + Lng32 colNumber = nacol->getPosition(); + + NABoolean xnWasStartedHere = FALSE; + if (beginXnIfNotInProgress(&cliInterface, xnWasStartedHere)) + { + cliRC = -1; + goto label_error; + } + + if (updateMDforDropCol(cliInterface, naTable, colNumber)) + { + cliRC = -1; + goto label_error; + } + + // remove column from all rows of the base table + HbaseStr hbaseTable; + hbaseTable.val = (char*)extNameForHbase.data(); + hbaseTable.len = extNameForHbase.length(); + + { + NAString column(nacol->getHbaseColFam(), heap_); + column.append(":"); + + char * colQualPtr = (char*)nacol->getHbaseColQual().data(); + Lng32 colQualLen = nacol->getHbaseColQual().length(); + Int64 colQval = str_atoi(colQualPtr, colQualLen); + if (colQval <= UCHAR_MAX) + { + unsigned char c = (unsigned char)colQval; + column.append((char*)&c, 1); + } + else if (colQval <= USHRT_MAX) + { + unsigned short s = (unsigned short)colQval; + column.append((char*)&s, 2); + } + else if (colQval <= ULONG_MAX) + { + Lng32 l = (Lng32)colQval; + column.append((char*)&l, 4); + } + else + column.append((char*)&colQval, 8); + + HbaseStr colNameStr; + char * col = (char *) heap_->allocateMemory(column.length() + 1, FALSE); + if (col) + { + memcpy(col, column.data(), column.length()); + col[column.length()] = 0; + colNameStr.val = col; + colNameStr.len = column.length(); + } + else + { + cliRC = -EXE_NO_MEM_TO_EXEC; + *CmpCommon::diags() << DgSqlCode(-EXE_NO_MEM_TO_EXEC); // error -8571 + + goto label_error; + } + + cliRC = ehi->deleteColumns(hbaseTable, colNameStr); + if (cliRC < 0) + { + *CmpCommon::diags() << DgSqlCode(-8448) + << DgString0((char*)"ExpHbaseInterface::deleteColumns()") + << DgString1(getHbaseErrStr(-cliRC)) + << DgInt0(-cliRC) + << DgString2((char*)GetCliGlobals()->getJniErrorStr().data()); + + goto label_error; + } + } + + if ((cliRC = recreateUsingViews(&cliInterface, viewNameList, viewDefnList, + ddlXns)) < 0) + { + NAString reason = "Error occurred while recreating views due to dependency on older column definition. Drop dependent views before doing the alter."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(altColName) + << DgString0(reason); + goto label_error; + } + + endXnIfStartedHere(&cliInterface, xnWasStartedHere, 0); + + return 0; + + label_error: + endXnIfStartedHere(&cliInterface, xnWasStartedHere, -1); + + return -1; +} + +void CmpSeabaseDDL::alterSeabaseTableDropColumn( + StmtDDLAlterTableDropColumn * alterDropColNode, + NAString &currCatName, NAString &currSchName) +{ + Lng32 cliRC = 0; + Lng32 retcode = 0; + + const NAString &tabName = alterDropColNode->getTableName(); + + ComObjectName tableName(tabName, COM_TABLE_NAME); + ComAnsiNamePart currCatAnsiName(currCatName); + ComAnsiNamePart currSchAnsiName(currSchName); + tableName.applyDefaults(currCatAnsiName, currSchAnsiName); + + const NAString catalogNamePart = tableName.getCatalogNamePartAsAnsiString(); + const NAString schemaNamePart = tableName.getSchemaNamePartAsAnsiString(TRUE); + const NAString objectNamePart = tableName.getObjectNamePartAsAnsiString(TRUE); + const NAString extTableName = tableName.getExternalName(TRUE); + const NAString extNameForHbase = catalogNamePart + "." + schemaNamePart + "." + objectNamePart; + + ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, + CmpCommon::context()->sqlSession()->getParentQid()); + + if ((isSeabaseReservedSchema(tableName)) && + (!Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))) + { + *CmpCommon::diags() << DgSqlCode(-CAT_CANNOT_ALTER_DEFINITION_METADATA_SCHEMA); + processReturn(); + return; + } + + ExpHbaseInterface * ehi = allocEHI(); + if (ehi == NULL) + { + processReturn(); + + return; + } + + retcode = existsInSeabaseMDTable(&cliInterface, + catalogNamePart, schemaNamePart, objectNamePart, + COM_BASE_TABLE_OBJECT, + (Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL) + ? FALSE : TRUE), + TRUE, TRUE); + if (retcode < 0) + { + processReturn(); + + return; + } + + if (retcode == 0) // does not exist + { + *CmpCommon::diags() << DgSqlCode(-CAT_CANNOT_ALTER_WRONG_TYPE) + << DgString0(extTableName); + + processReturn(); + + return; + } + + ActiveSchemaDB()->getNATableDB()->useCache(); + + BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), FALSE/*inDDL*/); + CorrName cn(tableName.getObjectNamePart().getInternalName(), + STMTHEAP, + tableName.getSchemaNamePart().getInternalName(), + tableName.getCatalogNamePart().getInternalName()); + + const NATable *naTable = bindWA.getNATable(cn); + if (naTable == NULL || bindWA.errStatus()) + { + *CmpCommon::diags() + << DgSqlCode(-4082) + << DgTableName(cn.getExposedNameAsAnsiString()); + + processReturn(); + + return; + } + + // Make sure user has the privilege to perform the drop column + if (!isDDLOperationAuthorized(SQLOperation::ALTER_TABLE, + naTable->getOwner(),naTable->getSchemaOwner())) + { + *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); + + processReturn (); + + return; + } + + // return an error if trying to drop a column from a volatile table + if (naTable->isVolatileTable()) + { + *CmpCommon::diags() << DgSqlCode(-CAT_REGULAR_OPERATION_ON_VOLATILE_OBJECT); + + processReturn (); + + return; + } + + const NAColumnArray &nacolArr = naTable->getNAColumnArray(); + const NAString &colName = alterDropColNode->getColName(); const NAColumn * nacol = nacolArr.getColumn(colName); if (! nacol) @@ -5016,7 +5346,8 @@ void CmpSeabaseDDL::alterSeabaseTableDropColumn( // this operation cannot be done if a xn is already in progress. if (xnInProgress(&cliInterface)) { - *CmpCommon::diags() << DgSqlCode(-20123); + *CmpCommon::diags() << DgSqlCode(-20123) + << DgString0("ALTER"); processReturn(); return; @@ -5024,6 +5355,20 @@ void CmpSeabaseDDL::alterSeabaseTableDropColumn( Int64 objUID = naTable->objectUid().castToInt64(); + NAList<NAString> viewNameList; + NAList<NAString> viewDefnList; + if (saveAndDropUsingViews(objUID, &cliInterface, viewNameList, viewDefnList)) + { + NAString reason = "Error occurred while saving views."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + + processReturn(); + + return; + } + NABoolean xnWasStartedHere = FALSE; Lng32 colNumber = nacol->getPosition(); @@ -5035,81 +5380,27 @@ void CmpSeabaseDDL::alterSeabaseTableDropColumn( catalogNamePart, schemaNamePart, objectNamePart, naTable, alterDropColNode->getColName(), - NULL, alterDropColNode->ddlXns())) + NULL, alterDropColNode->ddlXns(), + viewNameList, viewDefnList)) { - processReturn(); - return; + cliRC = -1; + goto label_error; } } else { - if (beginXnIfNotInProgress(&cliInterface, xnWasStartedHere)) - return; - - if (updateMDforDropCol(cliInterface, naTable, colNumber)) + if (hbaseFormatTableDropColumn + ( + ehi, + catalogNamePart, schemaNamePart, objectNamePart, + naTable, + alterDropColNode->getColName(), + nacol, alterDropColNode->ddlXns(), + viewNameList, viewDefnList)) { - goto label_return; + cliRC = -1; + goto label_error; } - - // remove column from all rows of the base table - HbaseStr hbaseTable; - hbaseTable.val = (char*)extNameForHbase.data(); - hbaseTable.len = extNameForHbase.length(); - - { - NAString column(nacol->getHbaseColFam(), heap_); - column.append(":"); - - char * colQualPtr = (char*)nacol->getHbaseColQual().data(); - Lng32 colQualLen = nacol->getHbaseColQual().length(); - Int64 colQval = str_atoi(colQualPtr, colQualLen); - if (colQval <= UCHAR_MAX) - { - unsigned char c = (unsigned char)colQval; - column.append((char*)&c, 1); - } - else if (colQval <= USHRT_MAX) - { - unsigned short s = (unsigned short)colQval; - column.append((char*)&s, 2); - } - else if (colQval <= ULONG_MAX) - { - Lng32 l = (Lng32)colQval; - column.append((char*)&l, 4); - } - else - column.append((char*)&colQval, 8); - - HbaseStr colNameStr; - col = (char *) heap_->allocateMemory(column.length() + 1, FALSE); - if (col) - { - memcpy(col, column.data(), column.length()); - col[column.length()] = 0; - colNameStr.val = col; - colNameStr.len = column.length(); - } - else - { - cliRC = -EXE_NO_MEM_TO_EXEC; - *CmpCommon::diags() << DgSqlCode(-EXE_NO_MEM_TO_EXEC); // error -8571 - - goto label_return; - } - - cliRC = ehi->deleteColumns(hbaseTable, colNameStr); - if (cliRC < 0) - { - *CmpCommon::diags() << DgSqlCode(-8448) - << DgString0((char*)"ExpHbaseInterface::deleteColumns()") - << DgString1(getHbaseErrStr(-retcode)) - << DgInt0(-retcode) - << DgString2((char*)GetCliGlobals()->getJniErrorStr().data()); - - goto label_return; - } - } } // hbase format table cliRC = updateObjectRedefTime(&cliInterface, @@ -5117,21 +5408,40 @@ void CmpSeabaseDDL::alterSeabaseTableDropColumn( COM_BASE_TABLE_OBJECT_LIT); if (cliRC < 0) { - goto label_return; + goto label_error; } label_return: endXnIfStartedHere(&cliInterface, xnWasStartedHere, cliRC); - - deallocEHI(ehi); - heap_->deallocateMemory(col); ActiveSchemaDB()->getNATableDB()->removeNATable (cn, ComQiScope::REMOVE_FROM_ALL_USERS, COM_BASE_TABLE_OBJECT, alterDropColNode->ddlXns(), FALSE); - processReturn(); + return; + + label_error: + endXnIfStartedHere(&cliInterface, xnWasStartedHere, cliRC); + + if ((cliRC = recreateUsingViews(&cliInterface, viewNameList, viewDefnList, + alterDropColNode->ddlXns())) < 0) + { + NAString reason = "Error occurred while recreating views due to dependency on older column definition. Drop dependent views before doing the alter."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + } + + deallocEHI(ehi); + heap_->deallocateMemory(col); + + ActiveSchemaDB()->getNATableDB()->removeNATable + (cn, + ComQiScope::REMOVE_FROM_ALL_USERS, COM_BASE_TABLE_OBJECT, + alterDropColNode->ddlXns(), FALSE); + + processReturn(); return; } @@ -5302,155 +5612,151 @@ void CmpSeabaseDDL::alterSeabaseTableAlterIdentityColumn( return; } -/////////////////////////////////////////////////////////////////////// -// -// An aligned table constains all columns in one hbase cell. -// To drop a column, we need to read each row, create a -// new row with the removed column and insert into the original table. -// -// Steps to drop a column from an aligned table: -// -// -- make a copy of the source aligned table using hbase copy -// -- truncate the source table -// -- Update metadata and remove the dropped column. -// -- bulk load data from copied table into the source table -// -- drop the copied temp table -// -// If an error happens after the source table has been truncated, then -// it will be restored from the copied table. -// -/////////////////////////////////////////////////////////////////////// -short CmpSeabaseDDL::alignedFormatTableDropColumn -( - const NAString &catalogNamePart, - const NAString &schemaNamePart, - const NAString &objectNamePart, - const NATable * naTable, - const NAString &altColName, - ElemDDLColDef *pColDef, - NABoolean ddlXns) +short CmpSeabaseDDL::saveAndDropUsingViews(Int64 objUID, + ExeCliInterface *cliInterface, + NAList<NAString> &viewNameList, + NAList<NAString> &viewDefnList) { Lng32 cliRC = 0; - const NAFileSet * naf = naTable->getClusteringIndex(); - - CorrName cn(objectNamePart, STMTHEAP, schemaNamePart, catalogNamePart); - - ComUID comUID; - comUID.make_UID(); - Int64 objUID = comUID.get_value(); - - char objUIDbuf[100]; - - NAString tempTable(naTable->getTableName().getQualifiedNameAsAnsiString()); - tempTable += "_"; - tempTable += str_ltoa(objUID, objUIDbuf); - - ExpHbaseInterface * ehi = allocEHI(); - ExeCliInterface cliInterface - (STMTHEAP, NULL, NULL, - CmpCommon::context()->sqlSession()->getParentQid()); - - Int64 tableUID = naTable->objectUid().castToInt64(); - const NAColumnArray &naColArr = naTable->getNAColumnArray(); - const NAColumn * altNaCol = naColArr.getColumn(altColName); - Lng32 altColNum = altNaCol->getPosition(); - - NAString tgtCols; - NAString srcCols; - - NABoolean xnWasStartedHere = FALSE; - - char buf[4000]; - - if (cloneSeabaseTable(cn, naTable, tempTable, ehi, &cliInterface)) - { - cliRC = -1; - goto label_drop; - } - - if (truncateHbaseTable(catalogNamePart, schemaNamePart, objectNamePart, - (NATable*)naTable, ehi)) + NAString catName, schName, objName; + cliRC = getObjectName(cliInterface, objUID, + catName, schName, objName); + if (cliRC < 0) { - cliRC = -1; - goto label_restore; + processReturn(); + + return -1; } - if (beginXnIfNotInProgress(&cliInterface, xnWasStartedHere)) + Queue * usingViewsQueue = NULL; + cliRC = getAllUsingViews(cliInterface, + catName, schName, objName, + usingViewsQueue); + if (cliRC < 0) { - cliRC = -1; - goto label_restore; + processReturn(); + + return -1; } - if (updateMDforDropCol(cliInterface, naTable, altColNum)) + if (usingViewsQueue->numEntries() == 0) + return 0; + + NABoolean xnWasStartedHere = FALSE; + if (beginXnIfNotInProgress(cliInterface, xnWasStartedHere)) + return -1; + + // find out any views on this table. + // save their definition and drop them. + // they will be recreated before return. + usingViewsQueue->position(); + for (int idx = 0; idx < usingViewsQueue->numEntries(); idx++) { - cliRC = -1; - goto label_restore; + OutputInfo * vi = (OutputInfo*)usingViewsQueue->getNext(); + char * viewName = vi->get(0); + + viewNameList.insert(viewName); + + ComObjectName viewCO(viewName, COM_TABLE_NAME); + + const NAString catName = viewCO.getCatalogNamePartAsAnsiString(); + const NAString schName = viewCO.getSchemaNamePartAsAnsiString(TRUE); + const NAString objName = viewCO.getObjectNamePartAsAnsiString(TRUE); + + Int64 viewUID = getObjectUID(cliInterface, + catName.data(), schName.data(), objName.data(), + COM_VIEW_OBJECT_LIT); + if (viewUID < 0 ) + { + endXnIfStartedHere(cliInterface, xnWasStartedHere, -1); + + return -1; + } + + NAString viewText; + if (getTextFromMD(cliInterface, viewUID, COM_VIEW_TEXT, 0, viewText)) + { + endXnIfStartedHere(cliInterface, xnWasStartedHere, -1); + + return -1; + } + + viewDefnList.insert(viewText); } - - ActiveSchemaDB()->getNATableDB()->removeNATable - (cn, - ComQiScope::REMOVE_FROM_ALL_USERS, - COM_BASE_TABLE_OBJECT, ddlXns, FALSE); - for (Int32 c = 0; c < naColArr.entries(); c++) + // drop the views. + // usingViewsQueue contain them in ascending order of their create + // time. Drop them from last to first. + for (int idx = usingViewsQueue->numEntries()-1; idx >= 0; idx--) { - const NAColumn * nac = naColArr[c]; - if (nac->getColName() == altColName) - continue; - - if (nac->isComputedColumn()) - continue; + OutputInfo * vi = (OutputInfo*)usingViewsQueue->get(idx); + char * viewName = vi->get(0); - if (nac->isSystemColumn()) - continue; + if (dropOneTableorView(*cliInterface,viewName,COM_VIEW_OBJECT,false)) + { + endXnIfStartedHere(cliInterface, xnWasStartedHere, -1); + + processReturn(); + + return -1; + } + } - tgtCols += nac->getColName(); - tgtCols += ","; - } // for + endXnIfStartedHere(cliInterface, xnWasStartedHere, 0); + + return 0; +} - tgtCols = tgtCols.strip(NAString::trailing, ','); +short CmpSeabaseDDL::recreateUsingViews(ExeCliInterface *cliInterface, + NAList<NAString> &viewNameList, + NAList<NAString> &viewDefnList, + NABoolean ddlXns) +{ + Lng32 cliRC = 0; - str_sprintf(buf, "upsert using load into %s(%s) select %s from %s", - naTable->getTableName().getQualifiedNameAsAnsiString().data(), - tgtCols.data(), - tgtCols.data(), - tempTable.data()); - cliRC = cliInterface.executeImmediate(buf); - if (cliRC < 0) - { - cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); - goto label_restore; - } + if (viewDefnList.entries() == 0) + return 0; - endXnIfStartedHere(&cliInterface, xnWasStartedHere, 0); + NABoolean xnWasStartedHere = FALSE; + if (beginXnIfNotInProgress(cliInterface, xnWasStartedHere)) + return -1; - str_sprintf(buf, "drop table %s", tempTable.data()); - cliRC = cliInterface.executeImmediate(buf); - if (cliRC < 0) + for (Lng32 i = 0; i < viewDefnList.entries(); i++) { - cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); - goto label_restore; + cliRC = cliInterface->executeImmediate(viewDefnList[i]); + if (cliRC < 0) + { + cliInterface->retrieveSQLDiagnostics(CmpCommon::diags()); + + cliRC = -1; + goto label_return; + } } + + cliRC = 0; - deallocEHI(ehi); - - return 0; +label_return: + for (Lng32 i = 0; i < viewDefnList.entries(); i++) + { + ComObjectName tableName(viewNameList[i], COM_TABLE_NAME); + const NAString catalogNamePart = + tableName.getCatalogNamePartAsAnsiString(); + const NAString schemaNamePart = + tableName.getSchemaNamePartAsAnsiString(TRUE); + const NAString objectNamePart = + tableName.getObjectNamePartAsAnsiString(TRUE); - label_restore: - endXnIfStartedHere(&cliInterface, xnWasStartedHere, -1); + CorrName cn(objectNamePart, STMTHEAP, schemaNamePart, catalogNamePart); + ActiveSchemaDB()->getNATableDB()->removeNATable + (cn, + ComQiScope::REMOVE_MINE_ONLY, COM_VIEW_OBJECT, + ddlXns, FALSE); + } - cloneHbaseTable(tempTable, - naTable->getTableName().getQualifiedNameAsAnsiString(), - ehi); + endXnIfStartedHere(cliInterface, xnWasStartedHere, cliRC); - label_drop: - str_sprintf(buf, "drop table %s", tempTable.data()); - Lng32 cliRC2 = cliInterface.executeImmediate(buf); - - deallocEHI(ehi); - - return (cliRC < 0 ? -1 : 0); + return cliRC; } /////////////////////////////////////////////////////////////////////// @@ -5459,19 +5765,24 @@ short CmpSeabaseDDL::alignedFormatTableDropColumn // To alter a column, we need to read each row, create a // new row with the altered column and insert into the original table. // +// Validation that altered col datatype is compatible with the +// original datatype has already been done before this method +// is called. +// // Steps to alter a column from an aligned table: // // -- make a copy of the source aligned table using hbase copy // -- truncate the source table // -- Update metadata column definition with the new definition // -- bulk load data from copied table into the source table +// -- recreate views, if existed, based on the new definition // -- drop the copied temp table // // If an error happens after the source table has been truncated, then // it will be restored from the copied table. // /////////////////////////////////////////////////////////////////////// -short CmpSeabaseDDL::alignedFormatTableAlterColumn +short CmpSeabaseDDL::alignedFormatTableAlterColumnAttr ( const NAString &catalogNamePart, const NAString &schemaNamePart, @@ -5479,7 +5790,9 @@ short CmpSeabaseDDL::alignedFormatTableAlterColumn const NATable * naTable, const NAString &altColName, ElemDDLColDef *pColDef, - NABoolean ddlXns) + NABoolean ddlXns, + NAList<NAString> &viewNameList, + NAList<NAString> &viewDefnList) { Lng32 cliRC = 0; @@ -5608,13 +5921,33 @@ short CmpSeabaseDDL::alignedFormatTableAlterColumn goto label_restore; } - deallocEHI(ehi); - + if ((cliRC = recreateUsingViews(&cliInterface, viewNameList, viewDefnList, + ddlXns)) < 0) + { + NAString reason = "Error occurred while recreating views due to dependency on older column definition. Drop dependent views before doing the alter."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(altColName) + << DgString0(reason); + goto label_restore; + } + endXnIfStartedHere(&cliInterface, xnWasStartedHere, 0); + str_sprintf(buf, "drop table %s", tempTable.data()); + cliRC = cliInterface.executeImmediate(buf); + if (cliRC < 0) + { + cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); + goto label_restore; + } + + deallocEHI(ehi); + return 0; label_restore: + endXnIfStartedHere(&cliInterface, xnWasStartedHere, -1); + cloneHbaseTable(tempTable, naTable->getTableName().getQualifiedNameAsAnsiString(), ehi); @@ -5630,44 +5963,98 @@ short CmpSeabaseDDL::alignedFormatTableAlterColumn return (cliRC < 0 ? -1 : 0); } -short CmpSeabaseDDL::alterColumnAttr( +///////////////////////////////////////////////////////////////////// +// this method is called if alter could be done by metadata changes +// only and without affecting table data. +///////////////////////////////////////////////////////////////////// +short CmpSeabaseDDL::mdOnlyAlterColumnAttr( const NAString &catalogNamePart, const NAString &schemaNamePart, const NAString &objectNamePart, const NATable * naTable, const NAColumn * naCol, NAType * newType, - StmtDDLAlterTableAlterColumnDatatype * alterColNode) + StmtDDLAlterTableAlterColumnDatatype * alterColNode, + NAList<NAString> &viewNameList, + NAList<NAString> &viewDefnList) { + Lng32 cliRC = 0; + ExeCliInterface cliInterface (STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); + + Int64 objUID = naTable->objectUid().castToInt64(); + + Lng32 colNumber = naCol->getPosition(); + + NABoolean xnWasStartedHere = FALSE; + if (beginXnIfNotInProgress(&cliInterface, xnWasStartedHere)) + return -1; - // this operation cannot be done if a xn is already in progress. - if (xnInProgress(&cliInterface)) + char buf[4000]; + str_sprintf(buf, "update %s.\"%s\".%s set column_size = %d, column_class = '%s' where object_uid = %Ld and column_number = %d", + getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_COLUMNS, + newType->getNominalSize(), + COM_ALTERED_USER_COLUMN_LIT, + objUID, + colNumber); + + cliRC = cliInterface.executeImmediate(buf); + if (cliRC < 0) { - *CmpCommon::diags() << DgSqlCode(-20123); - - processReturn(); - return -1; + cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); + + goto label_error; } - - if (naTable->isSQLMXAlignedTable()) + + cliRC = recreateUsingViews(&cliInterface, viewNameList, viewDefnList, + alterColNode->ddlXns()); + if (cliRC < 0) { - ElemDDLColDef *pColDef = - alterColNode->getColToAlter()->castToElemDDLColDef(); - - if (alignedFormatTableAlterColumn - ( - catalogNamePart, schemaNamePart, objectNamePart, - naTable, - naCol->getColName(), - pColDef, - alterColNode->ddlXns())) - { - processReturn(); - return -1; - } - - return 0; + NAString reason = "Error occurred while recreating views due to dependency on older column definition. Drop dependent views before doing the alter."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(naCol->getColName().data()) + << DgString0(reason); + + goto label_error; } + + endXnIfStartedHere(&cliInterface, xnWasStartedHere, cliRC); + + return 0; + + label_error: + endXnIfStartedHere(&cliInterface, xnWasStartedHere, cliRC); + + return -1; +} + +/////////////////////////////////////////////////////////////////////// +// +// Steps to alter a column from an hbase format table: +// +// Validation that altered col datatype is compatible with the +// original datatype has already been done before this method +// is called. +// +// -- add a temp column based on the altered datatype +// -- update temp col with data from the original col +// -- update metadata column definition with the new col definition +// -- update original col with data from temp col +// -- recreate views, if existed, based on the new definition +// -- drop the temp col. Dependent views will be recreated during drop. +// +// If an error happens after the source table has been truncated, then +// it will be restored from the copied table. +// +/////////////////////////////////////////////////////////////////////// +short CmpSeabaseDDL::hbaseFormatTableAlterColumnAttr( + const NAString &catalogNamePart, const NAString &schemaNamePart, + const NAString &objectNamePart, + const NATable * naTable, const NAColumn * naCol, NAType * newType, + StmtDDLAlterTableAlterColumnDatatype * alterColNode) +{ + ExeCliInterface cliInterface + (STMTHEAP, NULL, NULL, + CmpCommon::context()->sqlSession()->getParentQid()); CorrName cn(objectNamePart, STMTHEAP, schemaNamePart,catalogNamePart); @@ -5793,37 +6180,377 @@ short CmpSeabaseDDL::alterColumnAttr( processReturn(); goto label_error1; } - - str_sprintf(buf, "alter table %s drop column %s", - naTable->getTableName().getQualifiedNameAsAnsiString().data(), - tempCol.data()); - cliRC = cliInterface.executeImmediate(buf); + + str_sprintf(buf, "alter table %s drop column %s", + naTable->getTableName().getQualifiedNameAsAnsiString().data(), + tempCol.data()); + cliRC = cliInterface.executeImmediate(buf); + if (cliRC < 0) + { + cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); + + processReturn(); + return -1; + } + + return 0; + + label_error1: + str_sprintf(buf, "alter table %s drop column %s", + naTable->getTableName().getQualifiedNameAsAnsiString().data(), + tempCol.data()); + cliRC = cliInterface.executeImmediate(buf); + if (cliRC < 0) + { + processReturn(); + return -1; + } + + return -1; +} + +void CmpSeabaseDDL::alterSeabaseTableAlterColumnDatatype( + StmtDDLAlterTableAlterColumnDatatype * alterColNode, + NAString &currCatName, NAString &currSchName) +{ + Lng32 cliRC = 0; + Lng32 retcode = 0; + + const NAString &tabName = alterColNode->getTableName(); + + ComObjectName tableName(tabName, COM_TABLE_NAME); + ComAnsiNamePart currCatAnsiName(currCatName); + ComAnsiNamePart currSchAnsiName(currSchName); + tableName.applyDefaults(currCatAnsiName, currSchAnsiName); + + const NAString catalogNamePart = tableName.getCatalogNamePartAsAnsiString(); + const NAString schemaNamePart = tableName.getSchemaNamePartAsAnsiString(TRUE); + const NAString objectNamePart = tableName.getObjectNamePartAsAnsiString(TRUE); + const NAString extTableName = tableName.getExternalName(TRUE); + const NAString extNameForHbase = catalogNamePart + "." + schemaNamePart + "." + objectNamePart; + + ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, + CmpCommon::context()->sqlSession()->getParentQid()); + + if ((isSeabaseReservedSchema(tableName)) && + (!Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))) + { + *CmpCommon::diags() << DgSqlCode(-CAT_CANNOT_ALTER_DEFINITION_METADATA_SCHEMA); + processReturn(); + return; + } + + retcode = existsInSeabaseMDTable(&cliInterface, + catalogNamePart, schemaNamePart, objectNamePart, + COM_BASE_TABLE_OBJECT, + (Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL) + ? FALSE : TRUE), + TRUE, TRUE); + if (retcode < 0) + { + processReturn(); + + return; + } + + if (retcode == 0) // does not exist + { + *CmpCommon::diags() << DgSqlCode(-CAT_CANNOT_ALTER_WRONG_TYPE) + << DgString0(extTableName); + + processReturn(); + + return; + } + + ActiveSchemaDB()->getNATableDB()->useCache(); + + BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), FALSE/*inDDL*/); + CorrName cn(tableName.getObjectNamePart().getInternalName(), + STMTHEAP, + tableName.getSchemaNamePart().getInternalName(), + tableName.getCatalogNamePart().getInternalName()); + + NATable *naTable = bindWA.getNATable(cn); + if (naTable == NULL || bindWA.errStatus()) + { + *CmpCommon::diags() + << DgSqlCode(-4082) + << DgTableName(cn.getExposedNameAsAnsiString()); + + processReturn(); + + return; + } + + // Make sure user has the privilege to perform the alter column + if (!isDDLOperationAuthorized(SQLOperation::ALTER_TABLE, + naTable->getOwner(),naTable->getSchemaOwner())) + { + *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); + + processReturn (); + + return; + } + + // return an error if trying to alter a column from a volatile table + if (naTable->isVolatileTable()) + { + *CmpCommon::diags() << DgSqlCode(-CAT_REGULAR_OPERATION_ON_VOLATILE_OBJECT); + + processReturn (); + + return; + } + + ElemDDLColDef *pColDef = alterColNode->getColToAlter()->castToElemDDLColDef(); + + const NAColumnArray &nacolArr = naTable->getNAColumnArray(); + const NAString &colName = pColDef->getColumnName(); + + const NAColumn * nacol = nacolArr.getColumn(colName); + if (! nacol) + { + // column doesnt exist. Error. + *CmpCommon::diags() << DgSqlCode(-CAT_COLUMN_DOES_NOT_EXIST_ERROR) + << DgColumnName(colName); + + processReturn(); + + return; + } + + const NAType * currType = nacol->getType(); + NAType * newType = pColDef->getColumnDataType(); + + // If column is a LOB column , error + if ((currType->getFSDatatype() == REC_BLOB) || (currType->getFSDatatype() == REC_CLOB)) + { + *CmpCommon::diags() << DgSqlCode(-CAT_LOB_COLUMN_ALTER) + << DgColumnName(colName); + processReturn(); + return; + } + + const NAFileSet * naFS = naTable->getClusteringIndex(); + const NAColumnArray &naKeyColArr = naFS->getIndexKeyColumns(); + if (naKeyColArr.getColumn(colName)) + { + // key column cannot be altered + *CmpCommon::diags() << DgSqlCode(-1420) + << DgColumnName(colName); + + processReturn(); + + return; + } + + if (naTable->hasSecondaryIndexes()) + { + const NAFileSetList &naFsList = naTable->getIndexList(); + + for (Lng32 i = 0; i < naFsList.entries(); i++) + { + naFS = naFsList[i]; + + // skip clustering index + if (naFS->getKeytag() == 0) + continue; + + const NAColumnArray &naIndexColArr = naFS->getAllColumns(); + if (naIndexColArr.getColumn(colName)) + { + // secondary index column cannot be altered + *CmpCommon::diags() << DgSqlCode(-1421) + << DgColumnName(colName) + << DgTableName(naFS->getExtFileSetName()); + + processReturn(); + + return; + } + } // for + } // secondary indexes present + + if ((NOT currType->isCompatible(*newType)) && + (NOT ((currType->getTypeQualifier() == NA_CHARACTER_TYPE) && + (newType->getTypeQualifier() == NA_CHARACTER_TYPE)))) + { + NAString reason = "Old and New datatypes must be compatible."; + + // column cannot be altered + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + + processReturn(); + + return; + } + + // Column that can be altered by updating metadata only + // must meet these conditions: + // -- old and new column datatype must be VARCHAR + // -- old and new datatype must have the same nullable attr + // -- new col length must be greater than or equal to old length + // -- old and new character sets must be the same + NABoolean mdAlterOnly = FALSE; + if ((DFS2REC::isSQLVarChar(currType->getFSDatatype())) && + (DFS2REC::isSQLVarChar(newType->getFSDatatype())) && + (currType->getFSDatatype() == newType->getFSDatatype()) && + (currType->supportsSQLnull() == newType->supportsSQLnull()) && + (currType->getNominalSize() <= newType->getNominalSize()) && + (((CharType*)currType)->getCharSet() == ((CharType*)newType)->getCharSet())) + mdAlterOnly = TRUE; + + if ((NOT mdAlterOnly) && + (CmpCommon::getDefault(TRAF_ALTER_COL_ATTRS) == DF_OFF)) + { + NAString reason; + if (NOT ((DFS2REC::isSQLVarChar(currType->getFSDatatype())) && + (DFS2REC::isSQLVarChar(newType->getFSDatatype())))) + reason = "Old and New datatypes must be VARCHAR."; + else if (currType->getFSDatatype() != newType->getFSDatatype()) + reason = "Old and New datatypes must be the same."; + else if (((CharType*)currType)->getCharSet() != ((CharType*)newType)->getCharSet()) + reason = "Old and New character sets must be the same."; + else if (currType->getNominalSize() > newType->getNominalSize()) + reason = "New length must be greater than or equal to old length."; + else if (currType->supportsSQLnull() != newType->supportsSQLnull()) + reason = "Old and New nullability must be the same."; + + // column cannot be altered + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + + processReturn(); + + return; + } + + // this operation cannot be done if a xn is already in progress. + if ((NOT mdAlterOnly) && (xnInProgress(&cliInterface))) + { + *CmpCommon::diags() << DgSqlCode(-20123) + << DgString0("ALTER"); + + processReturn(); + return; + } + + Int64 objUID = naTable->objectUid().castToInt64(); + + // if there are views on the table, save the definition and drop + // the views. + // At the end of alter, views will be recreated. If an error happens + // during view recreation, alter will fail. + NAList<NAString> viewNameList; + NAList<NAString> viewDefnList; + if (saveAndDropUsingViews(objUID, &cliInterface, viewNameList, viewDefnList)) + { + NAString reason = "Error occurred while saving views."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + + processReturn(); + + return; + } + + if (mdAlterOnly) + { + if (mdOnlyAlterColumnAttr + (catalogNamePart, schemaNamePart, objectNamePart, + naTable, nacol, newType, alterColNode, + viewNameList, viewDefnList)) + { + cliRC = -1; + + goto label_error; + } + } + else if (naTable->isSQLMXAlignedTable()) + { + ElemDDLColDef *pColDef = + alterColNode->getColToAlter()->castToElemDDLColDef(); + + if (alignedFormatTableAlterColumnAttr + (catalogNamePart, schemaNamePart, objectNamePart, + naTable, + colName, + pColDef, + alterColNode->ddlXns(), + viewNameList, viewDefnList)) + { + cliRC = -1; + goto label_error; + } + } + else if (hbaseFormatTableAlterColumnAttr + (catalogNamePart, schemaNamePart, objectNamePart, + naTable, nacol, newType, alterColNode)) + { + cliRC = -1; + + goto label_error; + } + + cliRC = updateObjectRedefTime(&cliInterface, + catalogNamePart, schemaNamePart, objectNamePart, + COM_BASE_TABLE_OBJECT_LIT); if (cliRC < 0) { - cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); - - processReturn(); - return -1; + goto label_error; } + +label_return: + ActiveSchemaDB()->getNATableDB()->removeNATable + (cn, + ComQiScope::REMOVE_FROM_ALL_USERS, COM_BASE_TABLE_OBJECT, + alterColNode->ddlXns(), FALSE); - return 0; + processReturn(); + + return; - label_error1: - str_sprintf(buf, "alter table %s drop column %s", - naTable->getTableName().getQualifiedNameAsAnsiString().data(), - tempCol.data()); - cliRC = cliInterface.executeImmediate(buf); - if (cliRC < 0) +label_error: + if ((cliRC = recreateUsingViews(&cliInterface, viewNameList, viewDefnList, + alterColNode->ddlXns())) < 0) { - processReturn(); - return -1; - } - - return -1; + NAString reason = "Error occurred while recreating views due to dependency on older column definition. Drop dependent views before doing the alter."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + } + + ActiveSchemaDB()->getNATableDB()->removeNATable + (cn, + ComQiScope::REMOVE_FROM_ALL_USERS, COM_BASE_TABLE_OBJECT, + alterColNode->ddlXns(), FALSE); + + processReturn(); + + return; } -void CmpSeabaseDDL::alterSeabaseTableAlterColumnDatatype( - StmtDDLAlterTableAlterColumnDatatype * alterColNode, +///////////////////////////////////////////////////////////////////// +// this method renames an existing column to the specified new name. +// +// A column cannot be renamed if it is a system, salt, division by, +// computed or a lob column. +// +// If any index exists on the renamed column, then the index column +// is also renamed. +// +// If views exist on the table, they are dropped and recreated after +// rename. If recreation runs into an error, then alter fails. +// +/////////////////////////////////////////////////////////////////// +void CmpSeabaseDDL::alterSeabaseTableAlterColumnRename( + StmtDDLAlterTableAlterColumnRename * alterColNode, NAString &currCatName, NAString &currSchName) { Lng32 cliRC = 0; @@ -5866,6 +6593,16 @@ void CmpSeabaseDDL::alterSeabaseTableAlterColumnDatatype( return; } + if (retcode == 0) // does not exist + { + *CmpCommon::diags() << DgSqlCode(-CAT_CANNOT_ALTER_WRONG_TYPE) + << DgString0(extTableName); + + processReturn(); + + return; + } + ActiveSchemaDB()->getNATableDB()->useCache(); BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), FALSE/*inDDL*/); @@ -5907,10 +6644,9 @@ void CmpSeabaseDDL::alterSeabaseTableAlterColumnDatatype( return; } - ElemDDLColDef *pColDef = alterColNode->getColToAlter()->castToElemDDLColDef(); - const NAColumnArray &nacolArr = naTable->getNAColumnArray(); - const NAString &colName = pColDef->getColumnName(); + const NAString &colName = alterColNode->getColumnName(); + const NAString &renamedColName = alterColNode->getRenamedColumnName(); const NAColumn * nacol = nacolArr.getColumn(colName); if (! nacol) @@ -5924,8 +6660,46 @@ void CmpSeabaseDDL::alterSeabaseTableAlterColumnDatatype( return; } + if ((CmpCommon::getDefault(TRAF_ALLOW_RESERVED_COLNAMES) == DF_OFF) && + (ComTrafReservedColName(renamedColName))) + { + NAString reason = "Renamed column " + renamedColName + " is reserved for internal system usage."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + + processReturn(); + + return; + } + + if (nacol->isComputedColumn() || nacol->isSystemColumn()) + { + NAString reason = "Cannot rename system or computed column."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + + processReturn(); + + return; + } + + const NAColumn * renNacol = nacolArr.getColumn(renamedColName); + if (renNacol) + { + // column already exist. Error. + NAString reason = "Renamed column " + renamedColName + " already exist in the table."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + + processReturn(); + + return; + } + const NAType * currType = nacol->getType(); - NAType * newType = pColDef->getColumnDataType(); // If column is a LOB column , error if ((currType->getFSDatatype() == REC_BLOB) || (currType->getFSDatatype() == REC_CLOB)) @@ -5938,17 +6712,88 @@ void CmpSeabaseDDL::alterSeabaseTableAlterColumnDatatype( const NAFileSet * naFS = naTable->getClusteringIndex(); const NAColumnArray &naKeyColArr = naFS->getIndexKeyColumns(); + NABoolean isPkeyCol = FALSE; if (naKeyColArr.getColumn(colName)) { - // key column cannot be altered - *CmpCommon::diags() << DgSqlCode(-1420) - << DgColumnName(colName); + isPkeyCol = TRUE; + } + Int64 objUID = naTable->objectUid().castToInt64(); + + NAList<NAString> viewNameList; + NAList<NAString> viewDefnList; + if (saveAndDropUsingViews(objUID, &cliInterface, viewNameList, viewDefnList)) + { + NAString reason = "Error occurred while saving dependent views."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + processReturn(); + + return; + } + Lng32 colNumber = nacol->getPosition(); + + char buf[4000]; + str_sprintf(buf, "update %s.\"%s\".%s set column_name = '%s', column_class = '%s' where object_uid = %Ld and column_number = %d", + getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_COLUMNS, + renamedColName.data(), + COM_ALTERED_USER_COLUMN_LIT, + objUID, + colNumber); + + cliRC = cliInterface.executeImmediate(buf); + if (cliRC < 0) + { + cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); + + processReturn(); return; } + if (isPkeyCol) + { + Lng32 divColPos = -1; + if ((naTable->hasDivisioningColumn(&divColPos))) + { + NAString reason = "Not supported with DIVISION BY clause."; + *CmpCommon::diags() << DgSqlCode(-1404) + << DgColumnName(colName) + << DgString0(reason); + + processReturn(); + + return; + } + + Lng32 saltColPos = -1; + if ((naTable->hasSaltedColumn(&saltColPos))) + { + NAString saltText; + cliRC = getTextFromMD(&cliInterface, objUID, COM_COMPUTED_COL_TEXT, + saltColPos, saltText); + if (cliRC < 0) + { + processReturn(); + return; + } + + // replace col reference with renamed col + NAString quotedColName = "\"" + colName + "\""; + NAString renamedQuotedColName = "\"" + renamedColName + "\""; + saltText = replaceAll(saltText, quotedColName, renamedQuotedColName); + cliRC = updateTextTable(&cliInterface, objUID, COM_COMPUTED_COL_TEXT, + saltColPos, saltText, TRUE); + if (cliRC < 0) + { + processReturn(); + return; + } + } // saltCol + } // pkeyCol being renamed + if (naTable->hasSecondaryIndexes()) { const NAFileSetList &naFsList = naTable->getIndexList(); @@ -5961,69 +6806,43 @@ void CmpSeabaseDDL::alterSeabaseTableAlterColumnDatatype( if (naFS->getKeytag() == 0) continue; - const NAColumnArray &naIndexColArr = naFS->getAllColumns(); - if (naIndexColArr.getColumn(colName)) + str_sprintf(buf, "update %s.\"%s\".%s set column_name = '%s' || '@' where object_uid = %Ld and column_name = '%s' || '@'", + getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_COLUMNS, + renamedColName.data(), + naFS->getIndexUID(), + colName.data()); + + cliRC = cliInterface.executeImmediate(buf); + if (cliRC < 0) { - // secondary index column cannot be altered - *CmpCommon::diags() << DgSqlCode(-1421) - << DgColumnName(colName) - << DgTableName(naFS->getExtFileSetName()); - + cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); + processReturn(); + return; + } + str_sprintf(buf, "update %s.\"%s\".%s set column_name = '%s' where object_uid = %Ld and column_name = '%s'", + getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_COLUMNS, + renamedColName.data(), + naFS->getIndexUID(), + colName.data()); + + cliRC = cliInterface.executeImmediate(buf); + if (cliRC < 0) + { + cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); + + processReturn(); return; } } // for } // secondary indexes present - if ((NOT currType->isCompatible(*newType)) && - (NOT ((currType->getTypeQualifier() == NA_CHARACTER_TYPE) && - (newType->getTypeQualifier() == NA_CHARACTER_TYPE)))) - { - NAString reason = "Old and New datatypes must be compatible."; - - // column cannot be altered - *CmpCommon::diags() << DgSqlCode(-1404) - << DgColumnName(colName) - << DgString0(reason); - - processReturn(); - - return; - } - - // Column that can be altered by updating metadata only - // must meet these conditions: - // -- old and new column datatype must be VARCHAR - // -- old and new datatype must have the same nullable attr - // -- new col length must be greater than or equal to old length - // -- old and new character sets must be the same - NABoolean mdAlterOnly = FALSE; - if ((DFS2REC::isSQLVarChar(currType->getFSDatatype())) && - (DFS2REC::isSQLVarChar(newType->getFSDatatype())) && - (currType->getFSDatatype() == newType->getFSDatatype()) && - (currType->supportsSQLnull() == newType->supportsSQLnull()) && - (currType->getNominalSize() <= newType->getNominalSize()) && - (((CharType*)currType)->getCharSet() == ((CharType*)newType)->getCharSet())) - mdAlterOnly = TRUE; - - if ((NOT mdAlterOnly) && - (CmpCommon::getDefault(TRAF_ALTER_COL_ATTRS) == DF_OFF)) + cliRC = recreateUsingViews(&cliInterface, viewNameList, viewDefnList, + alterColNode->ddlXns()); + if (cliRC < 0) { - NAString reason; - if (NOT ((DFS2REC::isSQLVarChar(currType->getFSDatatype())) && - (DFS2REC::isSQLVarChar(newType->getFSDatatype())))) - reason = "Old and New datatypes must be VARCHAR."; - else if (currType->getFSDatatype() != newType->getFSDatatype()) - reason = "Old and New datatypes must be the same."; - else if (((CharType*)currType)->getCharSet() != ((CharType*)newType)->getCharSet()) - reason = "Old and New character sets must be the same."; - else if (currType->getNominalSize() > newType->getNominalSize()) - reason = "New length must be greater than or equal to old length."; - else if (currType->supportsSQLnull() != newType->supportsSQLnull()) - reason = "Old and New nullability must be the same."; - - // column cannot be altered + NAString reason = "Error occurred while recreating views due to dependency on older column definition. Drop dependent views before doing the alter."; *CmpCommon::diags() << DgSqlCode(-1404) << DgColumnName(colName) << DgString0(reason); @@ -6033,36 +6852,6 @@ void CmpSeabaseDDL::alterSeabaseTableAlterColumnDatatype( return; } - if (mdAlterOnly) - { - Int64 objUID = naTable->objectUid().castToInt64(); - - Lng32 colNumber = nacol->getPosition(); - - char buf[4000]; - str_sprintf(buf, "update %s.\"%s\".%s set column_size = %d, column_class = '%s' where object_uid = %Ld and column_number = %d", - getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_COLUMNS, - newType->getNominalSize(), - COM_ALTERED_USER_COLUMN_LIT, - objUID, - colNumber); - - cliRC = cliInterface.executeImmediate(buf); - if (cliRC < 0) - { - cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); - - processReturn(); - return; - } - } - else - { - if (alterColumnAttr(catalogNamePart, schemaNamePart, objectNamePart, - naTable, nacol, newType, alterColNode)) - return; - } - cliRC = updateObjectRedefTime(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_BASE_TABLE_OBJECT_LIT); @@ -6073,9 +6862,10 @@ void CmpSeabaseDDL::alterSeabaseTableAlterColumnDatatype( ActiveSchemaDB()->getNATableDB()->removeNATable (cn, - ComQiScope::REMOVE_FROM_ALL_USERS, COM_BASE_TABLE_OBJECT, + ComQiScope::REMOVE_FROM_ALL_USERS, + COM_BASE_TABLE_OBJECT, alterColNode->ddlXns(), FALSE); - + processReturn(); return; @@ -6133,7 +6923,6 @@ void CmpSeabaseDDL::alterSeabaseTableAddPKeyConstraint( return; } - BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), FALSE/*inDDL*/); CorrName cn(tableName.getObjectNamePart().getInternalName(), STMTHEAP, @@ -6192,6 +6981,19 @@ void CmpSeabaseDDL::alterSeabaseTableAddPKeyConstraint( return; } + // if table already has a primary key, return error. + if ((naTable->getClusteringIndex()) && + (NOT naTable->getClusteringIndex()->hasOnlySyskey())) + { + *CmpCommon::diags() + << DgSqlCode(-1256) + << DgString0(extTableName); + + processReturn(); + + return; + } + // update unique key constraint info NAString uniqueStr; if (genUniqueName(alterAddConstraint, uniqueStr)) @@ -7718,6 +8520,17 @@ void CmpSeabaseDDL::alterSeabaseTableDropConstraint( return; } + + if (isPkeyConstr) + { + *CmpCommon::diags() << DgSqlCode(-1255) + << DgString0(dropConstrName) + << DgString1(extTableName); + + processReturn(); + + return; + } } NATable *otherNaTable = NULL; @@ -9410,7 +10223,7 @@ desc_struct * CmpSeabaseDDL::getSeabaseUserTableDesc(const NAString &catName, populateKeyInfo(keyInfoArray[idx], vi); } - str_sprintf(query, "select O.catalog_name, O.schema_name, O.object_name, I.keytag, I.is_unique, I.is_explicit, I.key_colcount, I.nonkey_colcount, T.num_salt_partns, T.row_format from %s.\"%s\".%s I, %s.\"%s\".%s O , %s.\"%s\".%s T where I.base_table_uid = %Ld and I.index_uid = O.object_uid %s and I.index_uid = T.table_uid for read committed access order by 1,2,3", + str_sprintf(query, "select O.catalog_name, O.schema_name, O.object_name, I.keytag, I.is_unique, I.is_explicit, I.key_colcount, I.nonkey_colcount, T.num_salt_partns, T.row_format, I.index_uid from %s.\"%s\".%s I, %s.\"%s\".%s O , %s.\"%s\".%s T where I.base_table_uid = %Ld and I.index_uid = O.object_uid %s and I.index_uid = T.table_uid for read committed access order by 1,2,3", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_INDEXES, getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS, getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TABLES, @@ -9479,6 +10292,7 @@ desc_struct * CmpSeabaseDDL::getSeabaseUserTableDesc(const NAString &catName, Lng32 nonKeyColCount = *(Lng32*)vi->get(7); Lng32 idxNumSaltPartns = *(Lng32*)vi->get(8); char * format = vi->get(9); + Int64 indexUID = *(Int64*)vi->get(10); ComRowFormat idxRowFormat; if (memcmp(format, COM_ALIGNED_FORMAT_LIT, 2) == 0) @@ -9530,6 +10344,7 @@ desc_struct * CmpSeabaseDDL::getSeabaseUserTableDesc(const NAString &catName, new(STMTHEAP) NAString(coIdxName.getExternalName(TRUE)); indexInfoArray[idx].indexName = (char*)extIndexName->data(); + indexInfoArray[idx].indexUID = indexUID; indexInfoArray[idx].keytag = keyTag; indexInfoArray[idx].isUnique = isUnique; indexInfoArray[idx].isExplicit = isExplicit;
http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/681cad66/core/sql/sqlcomp/DefaultConstants.h ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/DefaultConstants.h b/core/sql/sqlcomp/DefaultConstants.h index 20fefca..7e20226 100644 --- a/core/sql/sqlcomp/DefaultConstants.h +++ b/core/sql/sqlcomp/DefaultConstants.h @@ -3297,6 +3297,7 @@ enum DefaultConstants LOB_HDFS_SERVER, LOB_HDFS_PORT, + LOB_GC_LIMIT_SIZE, // Should the DISK POOL be turned on when replicating the DDL using COPY DDL REPLICATE_DISK_POOL, @@ -3800,7 +3801,13 @@ enum DefaultConstants // If this cqd is on, then other alters (name, datatype) are also supported. TRAF_ALTER_COL_ATTRS, - // if ON, upsert into the table will use the default value for the omitted columns + // if set, let users create system reserved names. Default is OFF. + // This cqd should only be used to debug or if system column names are + // REALLY needed by users. + // Currently syskey, _salt_, _division_. + TRAF_ALLOW_RESERVED_COLNAMES, + + // if ON, upsert into the table will use the default value for the omitted columns // with default value TRAF_UPSERT_WITH_INSERT_DEFAULT_SEMANTICS, http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/681cad66/core/sql/sqlcomp/PrivMgrComponentOperations.cpp ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/PrivMgrComponentOperations.cpp b/core/sql/sqlcomp/PrivMgrComponentOperations.cpp index f6b68fd..b58d400 100644 --- a/core/sql/sqlcomp/PrivMgrComponentOperations.cpp +++ b/core/sql/sqlcomp/PrivMgrComponentOperations.cpp @@ -468,11 +468,18 @@ PrivStatus PrivMgrComponentOperations::createOperationInternal( const std::string & operationDescription, const int32_t granteeID, const std::string & granteeName, - const int32_t grantDepth) + const int32_t grantDepth, + const bool checkExistence) { -MyRow row(fullTableName_); + PrivStatus privStatus = STATUS_GOOD; + + // If operation already created, no need to create + if (checkExistence && nameExists(componentUID,operationName)) + return STATUS_GOOD; + + MyRow row(fullTableName_); row.componentUID_ = componentUID; row.operationCode_ = operationCode; @@ -480,17 +487,17 @@ MyRow row(fullTableName_); row.isSystem_ = isSystemOperation; row.operationDescription_ = operationDescription; -MyTable &myTable = static_cast<MyTable &>(myTable_); + MyTable &myTable = static_cast<MyTable &>(myTable_); -PrivStatus privStatus = myTable.insert(row); + privStatus = myTable.insert(row); if (privStatus != STATUS_GOOD) return privStatus; -// Grant authority to creator -PrivMgrComponentPrivileges componentPrivileges(metadataLocation_,pDiags_); + // Grant authority to creator + PrivMgrComponentPrivileges componentPrivileges(metadataLocation_,pDiags_); -std::vector<std::string> operationCodes; + std::vector<std::string> operationCodes; operationCodes.push_back(operationCode); @@ -499,7 +506,8 @@ std::vector<std::string> operationCodes; SYSTEM_USER, ComUser::getSystemUserName(), granteeID, - granteeName,grantDepth); + granteeName,grantDepth, + checkExistence); return privStatus; http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/681cad66/core/sql/sqlcomp/PrivMgrComponentOperations.h ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/PrivMgrComponentOperations.h b/core/sql/sqlcomp/PrivMgrComponentOperations.h index a506d2f..7d0069d 100644 --- a/core/sql/sqlcomp/PrivMgrComponentOperations.h +++ b/core/sql/sqlcomp/PrivMgrComponentOperations.h @@ -71,7 +71,8 @@ public: const std::string & operationDescription, const int32_t granteeID, const std::string & granteeName, - const int32_t grantDepth); + const int32_t grantDepth, + const bool checkExistence); PrivStatus describeComponentOperations( const std::string & componentUIDString, http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/681cad66/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp b/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp index fae5d0e..70dd089 100644 --- a/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp +++ b/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp @@ -854,12 +854,13 @@ PrivStatus PrivMgrComponentPrivileges::grantPrivilegeInternal( const std::string & grantorName, const int32_t granteeID, const std::string & granteeName, - const int32_t grantDepth) + const int32_t grantDepth, + const bool checkExistence) { -MyTable &myTable = static_cast<MyTable &>(myTable_); -MyRow row(fullTableName_); + MyTable &myTable = static_cast<MyTable &>(myTable_); + MyRow row(fullTableName_); row.componentUID_ = componentUID; row.grantDepth_ = grantDepth; @@ -868,9 +869,17 @@ MyRow row(fullTableName_); row.grantorID_ = grantorID; row.grantorName_ = grantorName; + const std::string componentUIDString = to_string((long long int)componentUID); + for (size_t oc = 0; oc < operationCodes.size(); oc++) { row.operationCode_ = operationCodes[oc]; + + if (checkExistence && + grantExists(componentUIDString, row.operationCode_, row.grantorID_, + row.granteeID_, row.grantDepth_)) + continue; + PrivStatus privStatus = myTable.insert(row); if (privStatus != STATUS_GOOD) http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/681cad66/core/sql/sqlcomp/PrivMgrComponentPrivileges.h ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/PrivMgrComponentPrivileges.h b/core/sql/sqlcomp/PrivMgrComponentPrivileges.h index 0b798a5..566b051 100644 --- a/core/sql/sqlcomp/PrivMgrComponentPrivileges.h +++ b/core/sql/sqlcomp/PrivMgrComponentPrivileges.h @@ -102,7 +102,8 @@ public: const std::string & grantorName, const int32_t granteeID, const std::string & granteeName, - const int32_t grantDepth); + const int32_t grantDepth, + const bool checkExistence); PrivStatus grantPrivilegeToCreator( const int64_t componentUID,
