DERBY-1489 Provide ALTER TABLE DROP COLUMN functionality
Reference
This issue relates to:
DERBY-1909 ALTER TABLE DROP COLUMN needs to update GRANTed column privileges
DERBY-1489 Provide ALTER TABLE DROP COLUMN functionality
This issue is related to:
DERBY-464 Enhance Derby by adding grant/revoke support. Grant/Revoke provide finner level of privileges than currently provided by Derby that is especially useful in network configurations.
Following script causes the select statement below to assert in sane build.
ij> connect 'jdbc:derby:wombat;create=true' user 'user1' as user1;
WARNING 01J14: SQL authorization is being used without first enabling authentication.
ij> create table t1 (c1 int, c2 int);
0 rows inserted/updated/deleted
ij> grant select(c1,c2) on t1 to user2;
0 rows inserted/updated/deleted
ij> connect 'jdbc:derby:wombat;create=true' user 'user2' as user2;
WARNING 01J01: Database 'wombat' not created, connection made to existing database instead.
WARNING 01J14: SQL authorization is being used without first enabling authentication.
ij(USER2)> set connection user1;
ij(USER1)> alter table t1 add c3 int;
0 rows inserted/updated/deleted
ij(USER1)> set connection user2;
ij(USER2)> select c3 from user1.t1;
ERROR XJ001: Java exception: 'ASSERT FAILED Attempt to get a bit position (2)that exceeds the max length (2): org.apache.derby.shared.common.sanity.AssertFailure'.
stack trace:
org.apache.derby.shared.common.sanity.AssertFailure: ASSERT FAILED Attempt to get a bit position (1)that exceeds the max length (1)
at org.apache.derby.shared.common.sanity.SanityManager.THROWASSERT(SanityManager.java:149)
at org.apache.derby.iapi.services.io.FormatableBitSet.isSet(FormatableBitSet.java:614)
at org.apache.derby.iapi.services.io.FormatableBitSet.get(FormatableBitSet.java:643)
at org.apache.derby.iapi.sql.dictionary.StatementColumnPermission.check(StatementColumnPermission.java:119)
at org.apache.derby.impl.sql.conn.GenericAuthorizer.authorize(GenericAuthorizer.java:158)
at org.apache.derby.exe.ac601a400fx010dxaa5bx09e8x00000013b9400.fillResultSet(Unknown Source)
at org.apache.derby.exe.ac601a400fx010dxaa5bx09e8x00000013b9400.execute(Unknown Source)
at org.apache.derby.impl.sql.GenericActivationHolder.execute(GenericActivationHolder.java:327)
at org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:356)
at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1182)
at org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:585)
at org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:517)
at org.apache.derby.impl.tools.ij.ij.executeImmediate(ij.java:321)
at org.apache.derby.impl.tools.ij.utilMain.doCatch(utilMain.java:517)
at org.apache.derby.impl.tools.ij.utilMain.runScriptGuts(utilMain.java:370)
at org.apache.derby.impl.tools.ij.utilMain.go(utilMain.java:268)
at org.apache.derby.impl.tools.ij.Main.go(Main.java:204)
at org.apache.derby.impl.tools.ij.Main.mainCore(Main.java:170)
at org.apache.derby.impl.tools.ij.Main14.main(Main14.java:56)
at org.apache.derby.tools.ij.main(ij.java:71)
sysinfo:
------------------ Java Information ------------------
Java Version: 1.4.2_12
Java Vendor: Sun Microsystems Inc.
Java home: C:\Program Files\Java\j2re1.4.2_12
Java classpath: classes;.
OS name: Windows XP
OS architecture: x86
OS version: 5.1
Java user name: Yip
Java user home: C:\Documents and Settings\Yip
Java user dir: C:\work3\derby\trunk
java.specification.name: Java Platform API Specification
java.specification.version: 1.4
--------- Derby Information --------
JRE - JDBC: J2SE 1.4.2 - JDBC 3.0
[C:\work3\derby\trunk\classes] 10.3.0.0 alpha - (443080)
------------------------------------------------------
----------------- Locale Information -----------------
Current Locale : [English/United States [en_US]]
Found support for locale: [de_DE]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [es]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [fr]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [it]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [ja_JP]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [ko_KR]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [pt_BR]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [zh_CN]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [zh_TW]
version: 10.3.0.0 alpha - (443080)
------------------------------------------------------
Description
Following script causes the select statement below to assert in sane build.
ij> connect 'jdbc:derby:wombat;create=true' user 'user1' as user1;
WARNING 01J14: SQL authorization is being used without first enabling authentication.
ij> create table t1 (c1 int, c2 int);
0 rows inserted/updated/deleted
ij> grant select(c1,c2) on t1 to user2;
0 rows inserted/updated/deleted
ij> connect 'jdbc:derby:wombat;create=true' user 'user2' as user2;
WARNING 01J01: Database 'wombat' not created, connection made to existing database instead.
WARNING 01J14: SQL authorization is being used without first enabling authentication.
ij(USER2)> set connection user1;
ij(USER1)> alter table t1 add c3 int;
0 rows inserted/updated/deleted
ij(USER1)> set connection user2;
ij(USER2)> select c3 from user1.t1;
ERROR XJ001: Java exception: 'ASSERT FAILED Attempt to get a bit position (2)that exceeds the max length (2): org.apache.derby.shared.common.sanity.AssertFailure'.
stack trace:
org.apache.derby.shared.common.sanity.AssertFailure: ASSERT FAILED Attempt to get a bit position (1)that exceeds the max length (1)
at org.apache.derby.shared.common.sanity.SanityManager.THROWASSERT(SanityManager.java:149)
at org.apache.derby.iapi.services.io.FormatableBitSet.isSet(FormatableBitSet.java:614)
at org.apache.derby.iapi.services.io.FormatableBitSet.get(FormatableBitSet.java:643)
at org.apache.derby.iapi.sql.dictionary.StatementColumnPermission.check(StatementColumnPermission.java:119)
at org.apache.derby.impl.sql.conn.GenericAuthorizer.authorize(GenericAuthorizer.java:158)
at org.apache.derby.exe.ac601a400fx010dxaa5bx09e8x00000013b9400.fillResultSet(Unknown Source)
at org.apache.derby.exe.ac601a400fx010dxaa5bx09e8x00000013b9400.execute(Unknown Source)
at org.apache.derby.impl.sql.GenericActivationHolder.execute(GenericActivationHolder.java:327)
at org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:356)
at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1182)
at org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:585)
at org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:517)
at org.apache.derby.impl.tools.ij.ij.executeImmediate(ij.java:321)
at org.apache.derby.impl.tools.ij.utilMain.doCatch(utilMain.java:517)
at org.apache.derby.impl.tools.ij.utilMain.runScriptGuts(utilMain.java:370)
at org.apache.derby.impl.tools.ij.utilMain.go(utilMain.java:268)
at org.apache.derby.impl.tools.ij.Main.go(Main.java:204)
at org.apache.derby.impl.tools.ij.Main.mainCore(Main.java:170)
at org.apache.derby.impl.tools.ij.Main14.main(Main14.java:56)
at org.apache.derby.tools.ij.main(ij.java:71)
sysinfo:
------------------ Java Information ------------------
Java Version: 1.4.2_12
Java Vendor: Sun Microsystems Inc.
Java home: C:\Program Files\Java\j2re1.4.2_12
Java classpath: classes;.
OS name: Windows XP
OS architecture: x86
OS version: 5.1
Java user name: Yip
Java user home: C:\Documents and Settings\Yip
Java user dir: C:\work3\derby\trunk
java.specification.name: Java Platform API Specification
java.specification.version: 1.4
--------- Derby Information --------
JRE - JDBC: J2SE 1.4.2 - JDBC 3.0
[C:\work3\derby\trunk\classes] 10.3.0.0 alpha - (443080)
------------------------------------------------------
----------------- Locale Information -----------------
Current Locale : [English/United States [en_US]]
Found support for locale: [de_DE]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [es]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [fr]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [it]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [ja_JP]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [ko_KR]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [pt_BR]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [zh_CN]
version: 10.3.0.0 alpha - (443080)
Found support for locale: [zh_TW]
version: 10.3.0.0 alpha - (443080)
------------------------------------------------------
DERBY-1847
contributed by Mamta Satoor
patch: DERBY1846_V1_diff_AddColumnAndGrantRevoke.txt
To recap the problem, in SQL Authorization mode, when a new column is added to a table, the rows in SYSCOLPERMS for the table in question were not getting updated to incorporate the new column. This caused ASSERT failure when a non-table owner attempted to select the new column.
Some background information on system table involved: SYSCOLPERMS keeps track of column level privileges on a given table. One of the columns in SYSCOLPERMS is "COLUMNS" and it has a bit map to show which columns have the given permission granted on them. When a new column is added to the user table, the "COLUMNS" need to be expanded by one bit and that bit should be initialized to zero since no privileges have been granted on that column at the ALTER TABLE...ADD COLUMN time.
I have fixed this problem by having AlterTableConstantAction.addNewColumnToTable call the new method in DataDictionary called updateSYSCOLPERMSforAddColumnToUserTable. At this point, we know of only the TableDescriptor's uuid which can help us determine all the rows in SYSCOLPERMS for that given table uuid. I get ColPermsDescriptor for each one of those rows and then use the ColPermsDescriptor's uuid to update the "COLUMNS" column so SYSCOLPERMS is aware of the newly added column in user table. This fixes the problem because at the time of SELECT, when we do privilege lookup in SYSCOLPERMS, we have info on the newly added column.
DERBY-1847
contributed by Mamta Satoor
backporting via merge change 453352 from trunk to 10.2 branch.
To recap the problem, in SQL Authorization mode, when a new column is added to
a table, the rows in SYSCOLPERMS for the table in question were not getting
updated to incorporate the new column. This caused ASSERT failure when a
non-table owner attempted to select the new column.
Some background information on system table involved: SYSCOLPERMS keeps track
of column level privileges on a given table. One of the columns in SYSCOLPERMS
is "COLUMNS" and it has a bit map to show which columns have the given
permission granted on them. When a new column is added to the user table,
the "COLUMNS" need to be expanded by one bit and that bit should be initialized
to zero since no privileges have been granted on that column at the ALTER
TABLE...ADD COLUMN time.
I have fixed this problem by having
AlterTableConstantAction.addNewColumnToTable call the new method in
DataDictionary called updateSYSCOLPERMSforAddColumnToUserTable. At this point,
we know of only the TableDescriptor's uuid which can help us determine all the
rows in SYSCOLPERMS for that given table uuid. I get ColPermsDescriptor for
each one of those rows and then use the ColPermsDescriptor's uuid to update
the "COLUMNS" column so SYSCOLPERMS is aware of the newly added column in user
table. This fixes the problem because at the time of SELECT, when we do
privilege lookup in SYSCOLPERMS, we have info on the newly added column.
DERBY-1847: SELECT statement asserts with added column in sqlAuth mode
This is a follow-on patch for DERBY-1847. The problem is that
when DataDictionaryImpl.updateSYSCOLPERMSforAddColumnToUserTable
updates the SYSCOLPERMS table, it updates the table by partial
key value. That means that each time the updateRow() call is made,
the COLUMNS column in SYSCOLPERMS is updated for *all* the
SYSCOLPERMS in that particular table, not just for the particular
SYSCOLPERMS row that we are working with at that instant.
The routine uses a partial key to find all the ColPermsDescriptor
entries for this table, but when it updates those rows, it needs
to use a full key, not a partial key.
DataDictionaryImpl.updateSYSCOLPERMSforAddColumnToUserTable
actually has the correct index row available, because it's just used
that row to fetch the base table row to update. So the fix is
to pass that index row to the ti.updateRow() call and
specify the COLPERMSID_INDEX_NUM rather than the TABLEID_INDEX_NUM.
DERBY-1909: ALTER TABLE DROP COLUMN needs to update GRANTed privileges
When ALTER TABLE DROP COLUMN is used to drop a column from a table, it needs to update the GRANTed column privileges on that table.
The core of this proposed patch involves refactoring and reusing the DERBY-1847 method which knows how to rewrite SYSCOLPERMS rows
to update the COLUMNS column. The DERBY-1847 version of that code
only handled the case of adding a bit to the COLUMNS column; this patch
extends that method to support removing a bit from the COLUMNS
column as well, then calls the method from the AlterTable execution logic.