use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class T_AccessFactory method alterTable.
/**
* Test the access level alter table interface for adding columns.
* <p>
*
* @return true if the test succeeded.
*
* @param tc The transaction controller to use in the test.
* @param temporary flag which tells whether or not the conglomerate
* used in the test should be temporary
*
* @exception StandardException Standard exception policy.
* @exception T_Fail Unexpected behaviour from the API
*/
private boolean alterTable(TransactionController tc, boolean temporary) throws StandardException, T_Fail {
int key_value;
REPORT("(alterTable) starting");
// Create a heap conglomerate.
T_AccessRow template_row = new T_AccessRow(1);
int temporaryFlag = temporary ? TransactionController.IS_TEMPORARY : TransactionController.IS_DEFAULT;
long conglomid = tc.createConglomerate(// create a heap conglomerate
"heap", // 1 column template.
template_row.getRowArray(), // column sort order not required for heap
null, // default collation
null, // default properties
null, temporaryFlag);
// Open the conglomerate.
ConglomerateController cc = tc.openConglomerate(conglomid, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE);
// Create a 1 column row. int column = 1.
T_AccessRow r1 = new T_AccessRow(1);
SQLInteger c1 = new SQLInteger(1);
r1.setCol(0, c1);
// Get a location template
RowLocation rowloc1 = cc.newRowLocationTemplate();
// Insert the row and remember its location.
cc.insertAndFetchLocation(r1.getRowArray(), rowloc1);
// create another 1 column row. int column = 2.
// Get a location template
r1.setCol(0, new SQLInteger(2));
RowLocation rowloc2 = cc.newRowLocationTemplate();
// Insert the row and remember its location.
cc.insertAndFetchLocation(r1.getRowArray(), rowloc2);
// RESOLVE - should this be a runtime error?
if (SanityManager.DEBUG) {
try {
T_AccessRow two_column_row = new T_AccessRow(2);
SQLInteger col1 = new SQLInteger(3);
SQLInteger col2 = new SQLInteger(3);
cc.insert(two_column_row.getRowArray());
throw T_Fail.testFailMsg("(alterTable) Allowed insert of bad row.");
} catch (StandardException t) {
// expected error continue the test.
}
}
// RESOLVE - (mikem) should we check for this in released runtime?
if (SanityManager.DEBUG) {
try {
T_AccessRow two_column_row = new T_AccessRow(2);
if (!cc.fetch(rowloc1, two_column_row.getRowArray(), (FormatableBitSet) null)) {
throw T_Fail.testFailMsg("(alterTable) Allowed fetch of bad row, bad ret val.");
}
throw T_Fail.testFailMsg("(alterTable) Allowed fetch of bad row.");
} catch (StandardException t) {
// expected error continue the test.
}
}
// RESOLVE - (mikem) should we check for this in released runtime?
if (SanityManager.DEBUG) {
try {
DataValueDescriptor[] third_column_row = new DataValueDescriptor[3];
third_column_row[2] = new SQLInteger(3);
FormatableBitSet fetch_desc = new FormatableBitSet(3);
fetch_desc.set(2);
if (!cc.fetch(rowloc1, third_column_row, fetch_desc)) {
throw T_Fail.testFailMsg("(alterTable) Allowed fetch of bad row, bad ret val.");
}
throw T_Fail.testFailMsg("(alterTable) Allowed fetch of bad row.");
} catch (StandardException t) {
// expected error continue the test.
}
}
// RESOLVE - (mikem) should we check for this in released runtime?
if (SanityManager.DEBUG) {
try {
T_AccessRow two_column_row = new T_AccessRow(2);
SQLInteger col1 = new SQLInteger(3);
SQLInteger col2 = new SQLInteger(3);
cc.replace(rowloc1, two_column_row.getRowArray(), null);
throw T_Fail.testFailMsg("(alterTable) Allowed replace of bad row.");
} catch (StandardException t) {
// expected error continue the test.
}
}
// Test that we can't replace data columns that don't exist
if (SanityManager.DEBUG) {
try {
DataValueDescriptor[] second_column_row = new DataValueDescriptor[2];
second_column_row[1] = new SQLInteger(3);
FormatableBitSet update_desc = new FormatableBitSet(2);
update_desc.set(1);
cc.replace(rowloc1, second_column_row, update_desc);
throw T_Fail.testFailMsg("(alterTable) Allowed partial row update of bad column.");
} catch (StandardException t) {
// expected error continue the test.
}
}
// Make sure commitNoSync gets executed sometimes.
tc.commitNoSync(TransactionController.RELEASE_LOCKS);
// now alter the conglomerate, add another int column
tc.addColumnToConglomerate(conglomid, 1, c1, StringDataValue.COLLATION_TYPE_UCS_BASIC);
// Open the table after the close done by commit.
cc = tc.openConglomerate(conglomid, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE);
T_AccessRow two_column_row = new T_AccessRow(2);
SQLInteger col1 = new SQLInteger(3);
SQLInteger col2 = new SQLInteger(3);
// fetch the rows and make sure you get null's in new fields.
if (!cc.fetch(rowloc1, two_column_row.getRowArray(), (FormatableBitSet) null)) {
throw T_Fail.testFailMsg("(alterTable) Row not there.");
}
if ((((SQLInteger) two_column_row.getCol(0)).getInt() != 1) || (!two_column_row.getCol(1).isNull())) {
throw T_Fail.testFailMsg("(alterTable) Bad column value after alter.");
}
if (!cc.fetch(rowloc2, two_column_row.getRowArray(), (FormatableBitSet) null)) {
throw T_Fail.testFailMsg("(alterTable) Row not there.");
}
if ((((SQLInteger) two_column_row.getCol(0)).getInt() != 2) || (!two_column_row.getCol(1).isNull())) {
throw T_Fail.testFailMsg("(alterTable) Bad column value after alter.");
}
// make sure insert of 2 column row works.
two_column_row = new T_AccessRow(2);
two_column_row.setCol(0, new SQLInteger(3));
two_column_row.setCol(1, new SQLInteger(300));
cc.insert(two_column_row.getRowArray());
// At this point the table looks like:
// col1 col2
// ---- ----
// 1 NA
// 2 NA
// 3 300
ScanController scan = tc.openScan(conglomid, // don't hold
false, // for update
TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE, // all columns, all as objects
(FormatableBitSet) null, // start position - first row in conglomerate
null, // unused if start position is null.
0, // qualifier - accept all rows
null, // stop position - last row in conglomerate
null, // unused if stop position is null.
0);
while (scan.next()) {
scan.fetch(two_column_row.getRowArray());
key_value = ((SQLInteger) two_column_row.getCol(0)).getInt();
switch(key_value) {
case 1:
{
// Set non-existent column value to 100
if (!two_column_row.getCol(1).isNull()) {
throw T_Fail.testFailMsg("(alterTable) Bad column value after alter.");
}
// test that replace field works on alter added column
// make result row be: (1, 100)
two_column_row.setCol(1, new SQLInteger(100));
scan.replace(two_column_row.getRowArray(), (FormatableBitSet) null);
break;
}
case 2:
{
if (!two_column_row.getCol(1).isNull()) {
throw T_Fail.testFailMsg("(alterTable) Bad column value after alter.");
}
// test that replace row works on alter added column row.
// make result row be: (2, 200)
two_column_row.setCol(1, new SQLInteger(200));
scan.replace(two_column_row.getRowArray(), (FormatableBitSet) null);
break;
}
case 3:
{
break;
}
default:
{
throw T_Fail.testFailMsg("(alterTable) bad row value found in table.");
}
}
}
// reposition the scan
scan.reopenScan(// start position - first row in conglomerate
null, // unused if start position is null.
0, // qualifier - accept all rows
null, // stop position - last row in conglomerate
null, // unused if stop position is null.
0);
while (scan.next()) {
scan.fetch(two_column_row.getRowArray());
key_value = ((SQLInteger) two_column_row.getCol(0)).getInt();
switch(key_value) {
case 1:
case 2:
case 3:
{
int second_col_val = ((SQLInteger) two_column_row.getCol(1)).getInt();
if (second_col_val != (key_value * 100)) {
throw T_Fail.testFailMsg("(alterTable) Bad column value after alter." + "expected: (" + key_value + ", " + key_value * 100 + ")\n" + "got : (" + key_value + ", " + second_col_val + ")\n");
}
break;
}
default:
{
throw T_Fail.testFailMsg("(alterTable) bad row value found in table.");
}
}
}
scan.close();
tc.commit();
REPORT("(alterTable) completed");
return true;
}
use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class T_RawStoreFactory method P039.
/**
* Test space reclaimation - shrink a head row piece.
*
* @exception T_Fail Unexpected behaviour from the API
* @exception StandardException Unexpected exception from the implementation
*/
protected void P039() throws StandardException, T_Fail {
// insert 3 2K rows of 3 columns, size (100, 1500, 400), into an 8K
// page, then fill up the page with 1K rows.
//
// 1. Update the first 2K row so that the 2nd and 3rd column gets moved
// to another page. See that we can insert at least 1 more 1K row into
// the page.
//
// 2. Update the second 2K row so that the 2nd column becomes a long
// column. See that we can insert at least 1 more 1K row into the
// page.
//
// 3. Update the third 2K row so that the column size shrinks to (200,
// 200, 200). See that we can insert at least 1 more 1K row into the
// page.
long segment = 0;
Transaction t = t_util.t_startTransaction();
long cid = t_util.t_addContainer(t, segment, 8 * 1024);
T_RawStoreRow bigRow = new T_RawStoreRow(3);
// remember each char takes 2 bytes
bigRow.setColumn(0, 50, REC_001);
bigRow.setColumn(1, 750, REC_002);
bigRow.setColumn(2, 200, REC_003);
ContainerHandle c = t_util.t_openContainer(t, segment, cid, true);
Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
try {
RecordHandle rh1 = t_util.t_insert(page, bigRow);
RecordHandle rh2 = t_util.t_insert(page, bigRow);
RecordHandle rh3 = t_util.t_insert(page, bigRow);
t_util.t_checkFetch(page, rh1, bigRow);
t_util.t_checkFetch(page, rh2, bigRow);
t_util.t_checkFetch(page, rh3, bigRow);
// now fill up the page with smaller rows
T_RawStoreRow smallRow = new T_RawStoreRow(1);
smallRow.setColumn(0, 500, REC_004);
while (page.spaceForInsert()) {
if (t_util.t_insert(page, smallRow) == null)
break;
}
REPORT("P039: " + (page.recordCount() - 3) + " small rows have been inserted");
page.unlatch();
page = null;
t_util.t_commit(t);
// (1) update rh1 so that column 2 and 3 are moved off page
bigRow.setColumn(1, 2000, REC_005);
c = t_util.t_openContainer(t, segment, cid, true);
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
int slot1 = page.getSlotNumber(rh1);
page.updateAtSlot(slot1, bigRow.getRow(), null);
t_util.t_checkFetch(page, rh1, bigRow);
page.unlatch();
page = null;
t_util.t_commit(t);
// wait for post commit to get processed.
t_util.t_wait(10);
c = t_util.t_openContainer(t, segment, cid, true);
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
if (t_util.t_insert(page, smallRow) == null)
throw T_Fail.testFailMsg("expect row to have shrunk (1)");
// fill it up again
while (page.spaceForInsert()) {
if (t_util.t_insert(page, smallRow) == null)
break;
}
REPORT("P039: " + (page.recordCount() - 3) + " small rows have been inserted");
page.unlatch();
page = null;
t_util.t_commit(t);
// (2) update rh2 so that column 2 becomes a long column
FormatableBitSet colList = new FormatableBitSet(2);
// update column 1, the second column
colList.set(1);
// use sparse rows
T_RawStoreRow partialRow = new T_RawStoreRow(2);
partialRow.setColumn(1, 8000, REC_006);
c = t_util.t_openContainer(t, segment, cid, true);
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
int slot2 = page.getSlotNumber(rh2);
page.updateAtSlot(slot2, partialRow.getRow(), colList);
bigRow.setColumn(1, 8000, REC_006);
t_util.t_checkFetch(page, rh2, bigRow);
page.unlatch();
page = null;
t_util.t_commit(t);
// wait for post commit to get processed.
t_util.t_wait(10);
c = t_util.t_openContainer(t, segment, cid, true);
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
if (t_util.t_insert(page, smallRow) == null)
throw T_Fail.testFailMsg("expect row to have shrunk (2)");
// fill it up again
while (page.spaceForInsert()) {
if (t_util.t_insert(page, smallRow) == null)
break;
}
REPORT("P039: " + (page.recordCount() - 3) + " small rows have been inserted");
page.unlatch();
page = null;
t_util.t_commit(t);
// (3) - update rh3 to have (200, 400, 400) bytes columns
bigRow.setColumn(0, 100, REC_001);
bigRow.setColumn(1, 200, REC_002);
bigRow.setColumn(2, 200, REC_003);
c = t_util.t_openContainer(t, segment, cid, true);
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
int slot3 = page.getSlotNumber(rh3);
page.updateAtSlot(slot3, bigRow.getRow(), null);
t_util.t_checkFetch(page, rh3, bigRow);
page.unlatch();
page = null;
t_util.t_commit(t);
// wait for post commit to get processed.
t_util.t_wait(10);
c = t_util.t_openContainer(t, segment, cid, true);
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
if (t_util.t_insert(page, smallRow) == null)
throw T_Fail.testFailMsg("expect row to have shrunk (3)");
page.unlatch();
page = null;
// cleanup
t_util.t_dropContainer(t, segment, cid);
} finally {
if (page != null)
page.unlatch();
t_util.t_commit(t);
t.close();
}
PASS("P039");
}
use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class T_RawStoreFactory method P705.
/**
* Same as 704 but update fields in the reverse order.
*
* @exception T_Fail Unexpected behaviour from the API
* @exception StandardException Unexpected exception from the implementation
*/
protected void P705(long segment) throws StandardException, T_Fail {
Transaction t = t_util.t_startTransaction();
long cid = t_util.t_addContainer(t, segment, 4096);
ContainerHandle c = t_util.t_openContainer(t, segment, cid, true);
Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
t_util.t_checkEmptyPage(page);
// row has 15 cols, each with 200 (ish) bytes (100 null chars)
// thus we would expect at least 3 pages
T_RawStoreRow row = new T_RawStoreRow(15);
for (int i = 0; i < 15; i++) {
row.setColumn(i, 100, "XX" + i + "YY");
}
RecordHandle rh = t_util.t_insertAtSlot(page, 0, row, (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
t_util.t_checkFetch(page, rh, row);
page.unlatch();
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
// update the each column to grow to be a single page (800 bytes ish)
for (int i = 14; i >= 0; i--) {
REPORT("P705 - col " + i);
FormatableBitSet colList = new FormatableBitSet(i + 1);
colList.set(i);
T_RawStoreRow rowU = new T_RawStoreRow(i + 1);
rowU.setColumn(i, 400, "WW" + i + "UU");
int slot = page.getSlotNumber(rh);
page.updateAtSlot(slot, rowU.getRow(), colList);
page.unlatch();
row.setColumn(i, 400, "WW" + i + "UU");
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
t_util.t_checkFetch(page, rh, row);
}
page.unlatch();
if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
// cleanup
t_util.t_dropContainer(t, segment, cid);
}
t_util.t_commit(t);
t.close();
PASS("P705: segment = " + segment);
}
use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class T_RawStoreFactory method P704.
/**
* Insert a single row with multiple portions.
* Update fields in the various portions that grow.
*
* @exception T_Fail Unexpected behaviour from the API
* @exception StandardException Unexpected exception from the implementation
*/
protected void P704(long segment) throws StandardException, T_Fail {
Transaction t = t_util.t_startTransaction();
long cid = t_util.t_addContainer(t, segment, 4096);
ContainerHandle c = t_util.t_openContainer(t, segment, cid, true);
Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
t_util.t_checkEmptyPage(page);
// row has 15 cols, each with 200 (ish) bytes (100 null chars)
// thus we would expect at least 3 pages
T_RawStoreRow row = new T_RawStoreRow(15);
for (int i = 0; i < 15; i++) {
row.setColumn(i, 100, "XX" + i + "YY");
}
RecordHandle rh = t_util.t_insertAtSlot(page, 0, row, (byte) (Page.INSERT_INITIAL | Page.INSERT_OVERFLOW));
t_util.t_checkFetch(page, rh, row);
page.unlatch();
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
// update the each column to grow to be a single page (800 bytes ish)
for (int i = 0; i < 15; i++) {
REPORT("P704 - col " + i);
FormatableBitSet colList = new FormatableBitSet(i + 1);
colList.set(i);
T_RawStoreRow rowU = new T_RawStoreRow(i + 1);
rowU.setColumn(i, 400, "WW" + i + "UU");
int slot = page.getSlotNumber(rh);
page.updateAtSlot(slot, rowU.getRow(), colList);
page.unlatch();
row.setColumn(i, 400, "WW" + i + "UU");
page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
t_util.t_checkFetch(page, rh, row);
}
page.unlatch();
if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
// cleanup
t_util.t_dropContainer(t, segment, cid);
}
t_util.t_commit(t);
t.close();
PASS("P704: segment = " + segment);
}
use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class T_RawStoreFactory method P012.
/**
* P012
*
* this test exercises updateAtSlot
*
* @exception T_Fail Unexpected behaviour from the API
* @exception StandardException Unexpected exception from the implementation
*/
protected void P012(long segment) throws StandardException, T_Fail {
Transaction t = t_util.t_startTransaction();
long cid = t_util.t_addContainer(t, segment);
ContainerHandle c = t_util.t_openContainer(t, segment, cid, true);
Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
// REPORT("insert 3 records");
T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
T_RawStoreRow row2 = new T_RawStoreRow(2);
row2.setColumn(0, (String) null);
row2.setColumn(1, REC_001);
T_RawStoreRow row3 = new T_RawStoreRow(3);
row3.setColumn(0, REC_001);
row3.setColumn(1, REC_002);
row3.setColumn(2, REC_003);
RecordHandle r1, r2, r3;
r1 = t_util.t_insertAtSlot(page, 0, row1);
r2 = r3 = null;
r2 = t_util.t_insertAtSlot(page, 1, row2);
if (r2 == null) {
REPORT("P012 not completed - cannot insert second row");
return;
}
r3 = t_util.t_insertAtSlot(page, 2, row3);
if (r3 == null) {
REPORT("P012 not completed - cannot insert third row");
return;
}
// check that they are inserted correctly
t_util.t_checkFetch(page, r1, row1);
t_util.t_checkFetch(page, r2, row2);
t_util.t_checkFetch(page, r3, row3);
// REPORT("update that grows the #columns in row");
T_RawStoreRow upd1 = new T_RawStoreRow(2);
upd1.setColumn(0, (String) null);
upd1.setColumn(1, REC_001);
r1 = page.updateAtSlot(0, upd1.getRow(), (FormatableBitSet) null);
t_util.t_checkFetch(page, r1, upd1);
t_util.t_checkFetch(page, r2, row2);
t_util.t_checkFetch(page, r3, row3);
// REPORT("update that shrinks the #columns in row");
T_RawStoreRow upd2 = new T_RawStoreRow(REC_004);
r2 = page.updateAtSlot(1, upd2.getRow(), (FormatableBitSet) null);
t_util.t_checkFetch(page, r1, upd1);
t_util.t_checkFetch(page, r2, upd2);
t_util.t_checkFetch(page, r3, row3);
// REPORT("update same #columns in row");
T_RawStoreRow upd3 = new T_RawStoreRow(3);
upd3.setColumn(0, REC_003);
upd3.setColumn(1, REC_002);
upd3.setColumn(2, REC_001);
r3 = page.updateAtSlot(2, upd3.getRow(), (FormatableBitSet) null);
t_util.t_checkFetch(page, r1, upd1);
t_util.t_checkFetch(page, r2, upd2);
t_util.t_checkFetch(page, r3, upd3);
if (segment != ContainerHandle.TEMPORARY_SEGMENT) {
// cleanup
t_util.t_dropContainer(t, segment, cid);
}
t_util.t_commit(t);
t.close();
PASS("P012");
}
Aggregations