diff --git a/sql/src/deleterow.cpp b/sql/src/deleterow.cpp new file mode 100644 index 0000000..e861810 --- /dev/null +++ b/sql/src/deleterow.cpp @@ -0,0 +1,138 @@ +//------------------------------------------------------------------------------ +// Desc: This module contains the routines for inserting a row into a table. +// +// Tabs: 3 +// +// Copyright (c) 2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id$ +//------------------------------------------------------------------------------ + +#include "flaimsys.h" + +//------------------------------------------------------------------------------ +// Desc: Delete a row from the database. +//------------------------------------------------------------------------------ +RCODE F_Db::deleteRow( + FLMUINT uiTableNum, + FLMUINT64 ui64RowId, + FLMBOOL bLogDelete) +{ + RCODE rc = NE_SFLM_OK; + FLMBYTE ucKeyBuf[ FLM_MAX_NUM_BUF_SIZE]; + FLMUINT uiKeyLen; + F_Row * pRow = NULL; + F_Btree * pBTree = NULL; + FLMBOOL bStartedTrans = FALSE; + + // Make sure we are in an update transaction. + + if (RC_BAD( rc = checkTransaction( SFLM_UPDATE_TRANS, &bStartedTrans))) + { + goto Exit; + } + + // Cannot delete from internal system tables, unless it is an + // internal delete. + + if (bLogDelete) + { + F_TABLE * pTable = m_pDict->getTable( uiTableNum); + if (pTable->bSystemTable) + { + rc = RC_SET( NE_SFLM_CANNOT_DELETE_IN_SYSTEM_TABLE); + goto Exit; + } + } + + // First we need to retrieve the row and update any index keys. + + if (RC_BAD( rc = gv_SFlmSysData.pRowCacheMgr->retrieveRow( this, + uiTableNum, ui64RowId, &pRow))) + { + goto Exit; + } + + // Delete any index keys for the row. + + if (RC_BAD( rc = updateIndexKeys( uiTableNum, pRow, NULL))) + { + goto Exit; + } + + // Get a B-Tree object to delete the row from the b-tree. + + if( RC_BAD( rc = getCachedBTree( uiTableNum, &pBTree))) + { + goto Exit; + } + uiKeyLen = sizeof( ucKeyBuf); + if( RC_BAD( rc = flmNumber64ToStorage( ui64RowId, &uiKeyLen, ucKeyBuf, + FALSE, TRUE))) + { + goto Exit; + } + if (RC_BAD( rc = pBTree->btRemoveEntry( ucKeyBuf, uiKeyLen))) + { + goto Exit; + } + + // Remove the row from row cache if it is there. + + gv_SFlmSysData.pRowCacheMgr->removeRow( this, pRow, TRUE, FALSE); + pRow = NULL; + + if (bLogDelete) + { + if (RC_BAD( rc = m_pDatabase->m_pRfl->logDeleteRow( this, uiTableNum, ui64RowId))) + { + goto Exit; + } + } + + // Commit the transaction if we started it + + if (bStartedTrans) + { + bStartedTrans = FALSE; + if (RC_BAD( rc = transCommit())) + { + goto Exit; + } + } + +Exit: + + if (bStartedTrans) + { + transAbort(); + } + + if (pRow) + { + pRow->ReleaseRow(); + } + + if (pBTree) + { + pBTree->Release(); + } + + return( rc); +} + diff --git a/sql/src/dropindex.cpp b/sql/src/dropindex.cpp new file mode 100644 index 0000000..c8744d9 --- /dev/null +++ b/sql/src/dropindex.cpp @@ -0,0 +1,324 @@ +//------------------------------------------------------------------------------ +// Desc: This module contains routines that will drop an index. +// +// Tabs: 3 +// +// Copyright (c) 2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id$ +//------------------------------------------------------------------------------ + +#include "flaimsys.h" + +//------------------------------------------------------------------------------ +// Desc: Drop an index. +//------------------------------------------------------------------------------ +RCODE F_Db::dropIndex( + FLMUINT uiIndexNum) +{ + RCODE rc = NE_SFLM_OK; + F_INDEX * pIndex; + ICD * pIcd; + FLMUINT uiLoop; + FLMBOOL bStartedTrans = FALSE; + IXD_FIXUP * pIxdFixup; + IXD_FIXUP * pPrevIxdFixup; + + // Make sure we are in an update transaction. + + if (RC_BAD( rc = checkTransaction( SFLM_UPDATE_TRANS, &bStartedTrans))) + { + goto Exit; + } + + // Create a new dictionary, if we don't already have one. + + if (!(m_uiFlags & FDB_UPDATED_DICTIONARY)) + { + if (RC_BAD( rc = dictClone())) + { + goto Exit; + } + } + + pIndex = m_pDict->getIndex( uiIndexNum); + flmAssert( pIndex); + + // Cannot drop internal system indexes. + + if (pIndex->uiFlags & IXD_SYSTEM) + { + rc = RC_SET( NE_SFLM_CANNOT_DROP_SYSTEM_INDEX); + goto Exit; + } + + // Delete the row for the index in the index table. + + if (RC_BAD( rc = deleteRow( SFLM_TBLNUM_INDEXES, + pIndex->ui64DefRowId, FALSE))) + { + goto Exit; + } + + // Delete all of the rows that define the key components. + + for (pIcd = pIndex->pKeyIcds, uiLoop = 0; + uiLoop < pIndex->uiNumKeyComponents; + uiLoop++, pIcd++) + { + if (RC_BAD( rc = deleteRow( SFLM_TBLNUM_INDEX_COMPONENTS, + pIcd->ui64DefRowId, FALSE))) + { + goto Exit; + } + } + + // Delete all of the rows that define the data components. + + for (pIcd = pIndex->pDataIcds, uiLoop = 0; + uiLoop < pIndex->uiNumDataComponents; + uiLoop++, pIcd++) + { + if (RC_BAD( rc = deleteRow( SFLM_TBLNUM_INDEX_COMPONENTS, + pIcd->ui64DefRowId, FALSE))) + { + + // The row may have been deleted in the loop above where key + // components are defined. It is possible to define both a + // key component and a data component in a single row in the + // database. + + if (rc == NE_SFLM_ROW_NOT_FOUND) + { + rc = NE_SFLM_OK; + } + else + { + goto Exit; + } + } + } + + // Initiate the background process to delete the b-tree. + + if (RC_BAD( rc = m_pDatabase->lFileDelete( this, &pIndex->lfInfo, + pIndex->uiFlags & IXD_ABS_POS + ? TRUE + : FALSE, + pIndex->uiNumDataComponents + ? TRUE + : FALSE))) + { + goto Exit; + } + + // If the index was being built in the background, stop the indexing + // thread. NOTE: No indexing thread will be going if we are replaying + // the RFL. + + if ((pIndex->uiFlags & IXD_OFFLINE) && !(pIndex->uiFlags & IXD_SUSPENDED) && + !(m_uiFlags & FDB_REPLAYING_RFL)) + { + if (RC_BAD( rc = addToStopList( uiIndexNum))) + { + goto Exit; + } + } + + // Remove any fixups for this index. + + pIxdFixup = m_pIxdFixups; + pPrevIxdFixup = NULL; + while (pIxdFixup) + { + if (pIndex->uiIndexNum == pIxdFixup->uiIndexNum) + { + IXD_FIXUP * pDeleteIxdFixup = pIxdFixup; + + pIxdFixup = pIxdFixup->pNext; + f_free( &pDeleteIxdFixup); + if (pPrevIxdFixup) + { + pPrevIxdFixup->pNext = pIxdFixup; + } + else + { + m_pIxdFixups = pIxdFixup; + } + } + else + { + pPrevIxdFixup = pIxdFixup; + pIxdFixup = pIxdFixup->pNext; + } + } + + // Remove the index name from the index name table. + + m_pDict->m_pIndexNames->removeName( pIndex->pszIndexName); + + // Remove the index from the in-memory dictionary. This is done + // simply by zeroing out the entire structure. + + f_memset( pIndex, sizeof( F_INDEX), 0); + + // Log the operation + + if (RC_BAD( rc = m_pDatabase->m_pRfl->logDropIndex( this, uiIndexNum))) + { + goto Exit; + } + + // Commit the transaction if we started it + + if (bStartedTrans) + { + bStartedTrans = FALSE; + if (RC_BAD( rc = transCommit())) + { + goto Exit; + } + } + +Exit: + + if (bStartedTrans) + { + transAbort(); + } + + return( rc); +} + +//------------------------------------------------------------------------------ +// Desc: Process the drop index statement. The "DROP INDEX" keywords +// have already been parsed. +//------------------------------------------------------------------------------ +RCODE SQLStatement::processDropIndex( void) +{ + RCODE rc = NE_SFLM_OK; + FLMBOOL bStartedTrans = FALSE; + char szIndexName [MAX_SQL_NAME_LEN + 1]; + FLMUINT uiIndexNameLen; + char szTableName [MAX_SQL_NAME_LEN + 1]; + FLMUINT uiTableNameLen; + F_TABLE * pTable; + F_INDEX * pIndex; + + // If we are in a read transaction, we cannot do this operation + + if (RC_BAD( rc = m_pDb->checkTransaction( SFLM_UPDATE_TRANS, &bStartedTrans))) + { + goto Exit; + } + + // SYNTAX: DROP INDEX [ON ] + + // Whitespace must follow the "DROP INDEX" + + if (RC_BAD( rc = skipWhitespace( TRUE))) + { + goto Exit; + } + + // Get the index name - index name must exist + + if (RC_BAD( rc = getIndexName( TRUE, szIndexName, sizeof( szIndexName), + &uiIndexNameLen, &pIndex))) + { + goto Exit; + } + + // Cannot drop system indexes + + if (pIndex->uiFlags & IXD_SYSTEM) + { + setErrInfo( m_uiCurrLineNum, + m_uiCurrLineOffset - 1, + SQL_ERR_CANNOT_DROP_SYSTEM_INDEX, + m_uiCurrLineFilePos, + m_uiCurrLineBytes); + rc = RC_SET( NE_SFLM_INVALID_SQL); + goto Exit; + } + + // See if the keyword "ON" is present + + if (RC_BAD( rc = haveToken( "on", TRUE))) + { + if (rc == NE_SFLM_NOT_FOUND || rc == NE_SFLM_EOF_HIT) + { + rc = NE_SFLM_OK; + } + else + { + goto Exit; + } + } + else + { + + // Get the table name - must exist, and must be the same as + // the table the index is associated with. + + if (RC_BAD( rc = getTableName( TRUE, szTableName, sizeof( szTableName), + &uiTableNameLen, &pTable))) + { + goto Exit; + } + + if (pTable->uiTableNum != pIndex->uiTableNum) + { + setErrInfo( m_uiCurrLineNum, + m_uiCurrLineOffset - 1, + SQL_ERR_TABLE_NOT_FOR_INDEX, + m_uiCurrLineFilePos, + m_uiCurrLineBytes); + rc = RC_SET( NE_SFLM_INVALID_SQL); + goto Exit; + } + } + + // Drop the index. + + if (RC_BAD( rc = m_pDb->dropIndex( pIndex->uiIndexNum))) + { + goto Exit; + } + + // Commit the transaction if we started it + + if (bStartedTrans) + { + bStartedTrans = FALSE; + if (RC_BAD( rc = m_pDb->transCommit())) + { + goto Exit; + } + } + +Exit: + + if (bStartedTrans) + { + m_pDb->transAbort(); + } + + return( rc); +} + diff --git a/sql/src/droptable.cpp b/sql/src/droptable.cpp new file mode 100644 index 0000000..e3793a2 --- /dev/null +++ b/sql/src/droptable.cpp @@ -0,0 +1,215 @@ +//------------------------------------------------------------------------------ +// Desc: This module contains routines that will drop an index. +// +// Tabs: 3 +// +// Copyright (c) 2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id$ +//------------------------------------------------------------------------------ + +#include "flaimsys.h" + +//------------------------------------------------------------------------------ +// Desc: Drop a table. +//------------------------------------------------------------------------------ +RCODE F_Db::dropTable( + FLMUINT uiTableNum) +{ + RCODE rc = NE_SFLM_OK; + F_TABLE * pTable; + F_COLUMN * pColumn; + FLMUINT uiLoop; + FLMBOOL bStartedTrans = FALSE; + + // Make sure we are in an update transaction. + + if (RC_BAD( rc = checkTransaction( SFLM_UPDATE_TRANS, &bStartedTrans))) + { + goto Exit; + } + + // Create a new dictionary, if we don't already have one. + + if (!(m_uiFlags & FDB_UPDATED_DICTIONARY)) + { + if (RC_BAD( rc = dictClone())) + { + goto Exit; + } + } + + pTable = m_pDict->getTable( uiTableNum); + flmAssert( pTable); + + // Cannot drop internal system tables. + + if (pTable->bSystemTable) + { + rc = RC_SET( NE_SFLM_CANNOT_DROP_SYSTEM_TABLE); + goto Exit; + } + + // Delete the row for the table in the table table. + + if (RC_BAD( rc = deleteRow( SFLM_TBLNUM_TABLES, + pTable->ui64DefRowId, FALSE))) + { + goto Exit; + } + + // Delete all of the rows that define the table's columns + + for (pColumn = pTable->pColumns, uiLoop = 0; + uiLoop < pTable->uiNumColumns; + uiLoop++, pColumn++) + { + if (RC_BAD( rc = deleteRow( SFLM_TBLNUM_COLUMNS, + pColumn->ui64DefRowId, FALSE))) + { + goto Exit; + } + } + + // Initiate the background process to delete the b-tree. + + if (RC_BAD( rc = m_pDatabase->lFileDelete( this, &pTable->lfInfo, + FALSE, TRUE))) + { + goto Exit; + } + + // Remove the column name table. + + pTable->pColumnNames->Release(); + pTable->pColumnNames = NULL; + + // Remove the table name from the table name table. + + m_pDict->m_pTableNames->removeName( pTable->pszTableName); + + // Remove the table from the in-memory dictionary. This is done + // simply by zeroing out the entire structure. + + f_memset( pTable, sizeof( F_TABLE), 0); + + // Log the operation + + if (RC_BAD( rc = m_pDatabase->m_pRfl->logDropTable( this, uiTableNum))) + { + goto Exit; + } + + // Commit the transaction if we started it + + if (bStartedTrans) + { + bStartedTrans = FALSE; + if (RC_BAD( rc = transCommit())) + { + goto Exit; + } + } + +Exit: + + if (bStartedTrans) + { + transAbort(); + } + + return( rc); +} + +//------------------------------------------------------------------------------ +// Desc: Process the drop index statement. The "DROP INDEX" keywords +// have already been parsed. +//------------------------------------------------------------------------------ +RCODE SQLStatement::processDropTable( void) +{ + RCODE rc = NE_SFLM_OK; + FLMBOOL bStartedTrans = FALSE; + char szTableName [MAX_SQL_NAME_LEN + 1]; + FLMUINT uiTableNameLen; + F_TABLE * pTable; + + // If we are in a read transaction, we cannot do this operation + + if (RC_BAD( rc = m_pDb->checkTransaction( SFLM_UPDATE_TRANS, &bStartedTrans))) + { + goto Exit; + } + + // SYNTAX: DROP INDEX [ON ] + + // Whitespace must follow the "DROP INDEX" + + if (RC_BAD( rc = skipWhitespace( TRUE))) + { + goto Exit; + } + + // Get the table name - table name must exist + + if (RC_BAD( rc = getTableName( TRUE, szTableName, sizeof( szTableName), + &uiTableNameLen, &pTable))) + { + goto Exit; + } + + // Cannot drop system tables + + if (pTable->bSystemTable) + { + setErrInfo( m_uiCurrLineNum, + m_uiCurrLineOffset - 1, + SQL_ERR_CANNOT_DROP_SYSTEM_TABLE, + m_uiCurrLineFilePos, + m_uiCurrLineBytes); + rc = RC_SET( NE_SFLM_INVALID_SQL); + goto Exit; + } + + // Drop the table. + + if (RC_BAD( rc = m_pDb->dropTable( pTable->uiTableNum))) + { + goto Exit; + } + + // Commit the transaction if we started it + + if (bStartedTrans) + { + bStartedTrans = FALSE; + if (RC_BAD( rc = m_pDb->transCommit())) + { + goto Exit; + } + } + +Exit: + + if (bStartedTrans) + { + m_pDb->transAbort(); + } + + return( rc); +} +