Source code: org/apache/derby/impl/sql/conn/TempTableInfo.java
1 /*
2
3 Derby - Class org.apache.derby.impl.sql.conn.TempTableInfo
4
5 Copyright 2003, 2004 The Apache Software Foundation or its licensors, as applicable.
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18
19 */
20
21 package org.apache.derby.impl.sql.conn;
22
23 import org.apache.derby.iapi.error.StandardException;
24 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
25
26 //this class is for temporary tables. The information kept here is necessary to implement the rollback
27 //and commit behavior for temporary tables.
28
29 /**
30 The temp tables will have following data structure
31 TableDescriptor
32 Declared in savepoint level
33 Dropped in savepoint level
34 Modified in savepoint level
35
36 The actual logic
37
38 LanguageConnectionContext will keep the "current savepoint level". At any point in
39 time, this is the total number of savepoints defined for a transaction.
40 At the start of any new transaction, the "current savepoint level" will be set to 0.
41
42 Everytime a new user defined savepoint is set, store returns the total number of savepoints
43 for the connection at that point.
44 For eg, in a new transaction,
45 "current savepoint level' will be 0. When the first savepoint is set, store will return
46 1 and "current savepoint level" will be set to 1. For next savepoint, store will return 2 and so on
47 and so forth.
48
49 When language calls rollback or release of a savepoint, store will again return the total number of savepoints
50 for the connection after rollback or release and we will set "current savepoint level" to that number. For eg,
51 start tran ("current savepoint level"=0)
52 set savepoint 1 ("current savepoint level"=1)
53 set savepoint 2 ("current savepoint level"=2)
54 set savepoint 3 ("current savepoint level"=3)
55 set savepoint 4 ("current savepoint level"=4)
56 release savepoint 3 ("current savepoint level"=2)
57 rollback savepoint 1 ("current savepoint level"=0)
58
59 If the temporary table was declared with ON ROLLBACK DELETE ROWS and contents of that temporary table
60 were modified in a transaction or within a savepoint unit, then we keep track of that by saving the
61 savepoint level in dataModifiedInSavepointLevel. This information will be used at rollback of savepoint or transaction.
62 Also, when a savepoint is released, we check if the table was modified in any of the savepoints that
63 are getting released. If yes, then we put the current savepoint level as dataModifiedInSavepointLevel.
64 eg
65 start tran ("current savepoint level"=0)
66 declare temp table 0 ON ROLLBACK DELETE ROWS("declared in savepoint level"=0, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
67 commit (temp table 0 ("declared in savepoint level"=-1, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1))
68 start tran ("current savepoint level = 0)
69 temp table 0 ("declared in savepoint level"=-1, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
70 set savepoint 1("current savepoint level = 1")
71 temp table 0 ("declared in savepoint level"=-1, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
72 set savepoint 2("current savepoint level = 2")
73 delete 1 row from temp table 0
74 temp table 0 ("declared in savepoint level"=-1, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=2)
75 release savepoint 2 ("current savepoint level"=1) and reset the modified in savepoint level as follows
76 temp table 0 ("declared in savepoint level"=-1, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=1)
77 rollback ("current savepoint level"=0) All the rows from the temp table 0 will be removed
78 At the time of commit, we set dataModifiedInSavepointLevel to -1.
79 At the time of rollback (transaction / savepoint), first we check if the table was modified in the unit of work
80 getting rolled back. If yes, then we delete all the data from the temp table and we set dataModifiedInSavepointLevel to -1.
81
82 When language calls release of a savepoint, store will again return the total number of savepoints
83 in the system after release. We will go through all the temp tables and reset their declared or
84 dropped or modified in savepoint level to the value returned by the release savepoint if those tables had their
85 declared or dropped or modified in savepoint levels higher than what was returned by the release savepoint.
86 eg
87 start tran ("current savepoint level"=0)
88 declare temp table 0 ("declared in savepoint level"=0, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
89 set savepoint 1("current savepoint level = 1")
90 declare temp table 1 ("declared in savepoint level"=1, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
91 set savepoint 2("current savepoint level = 2")
92 declare temp table 2 ("declared in savepoint level"=2, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
93 release savepoint 1 ("current savepoint level"=0) and reset the savepoint levels as follows
94 temp table 1 ("declared in savepoint level"=0, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
95 temp table 2 ("declared in savepoint level"=0, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
96 set savepoint 3("current savepoint level = 1")
97 rollback savepoint 3 ("current savepoint level"=0) and temp table info will look as follows
98 temp table 0 ("declared in savepoint level"=0, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
99 temp table 1 ("declared in savepoint level"=0, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
100 temp table 2 ("declared in savepoint level"=0, "dropped in savepoint level"=-1, "dataModifiedInSavepointLevel"=-1)
101
102 When you declare a temp table, it will have "declared in savepoint level" as the current savepoint
103 level of the LanguageConnectionContext (which will be 0 in a transaction with no user-defined savepoints).
104 The "dropped in savepoint level" for new temp tables will be set to -1.
105 The "dataModifiedInSavepointLevel" for new temp tables will be set to -1 as well.
106
107 When a temp table is dropped, we will first check if the table was declared in a savepoint level
108 equal to the current savepoint level.
109 If yes, then we will remove it from the temp tables list for the LanguageConnectionContext .
110 eg
111 start tran ("current savepoint level = 0")
112 set savepoint 1("current savepoint level = 1")
113 declare temp table 1 ("declared in savepoint level"=1, "dropped in savepoint level"=-1)
114 drop temp table 1 (declared in savepoint level same as current savepoint level and hence will remove it from list of temp tables)
115 If no, then we will set the dropped in savepoint level as the current savepoint level of the
116 LanguageConnectionContext (which will be 0 in a transaction without savepoints and it also means
117 that the table was declared in a previous transaction).
118
119 At the time of commit, go through all the temp tables with "dropped in savepoint level" != -1 (meaning dropped in this transaction)
120 and remove them from the temp tables list for the LanguageConnectionContext. All the rest of the temp tables with
121 "dropped in savepoint level" = -1, we will set their "declared in savepoint level" to -1 and , "dataModifiedInSavepointLevel" to -1.
122 eg
123 start tran ("current savepoint level = 0)
124 declare temp table t1("declared in savepoint level" = 0, "dropped in savepoint level"=-1)
125 commit (temp table 1 ("declared in savepoint level"=-1, "dropped in savepoint level"=-1))
126 start tran ("current savepoint level = 0)
127 drop temp table t1 ("declared in savepoint level" = -1, "dropped in savepoint level"=0)
128 commit (temp table t1 will be removed from list of temp tables)
129
130 At the time of rollback
131 if rolling back transaction, first set the "current savepoint level" to 0
132 if rolling back to a savepoint, first set the "current savepoint level" to savepoint level returned by Store
133 for the rollback to savepoint command
134 Now go through all the temp tables.
135 If "declared in savepoint level" of temp table is greater than or equal to "current savepoint level"
136 (ie table was declared in this unit of work)
137 And if table was not dropped in this unit of work ie "dropped in savepoint level" = -1
138 Then we should remove the table from the list of temp tables and drop the conglomerate created for it
139 eg
140 start tran ("current savepoint level = 0)
141 declare temp table t2("declared in savepoint level" = 0, "dropped in savepoint level"=-1)
142 rollback tran
143 (temp table t2 will be removed from list of tables and conglomerate associated with it will be dropped)
144 And if table was dropped in this unit of work ie "dropped in savepoint level" >= "current savepoint level"
145 Then we should remove the table from the list of temp tables
146 eg
147 start tran ("current savepoint level = 0)
148 set savepoint 1("current savepoint level = 1")
149 declare temp table t2("declared in savepoint level" = 1, "dropped in savepoint level"=-1)
150 set savepoint 2("current savepoint level = 2")
151 drop temp table t1 ("declared in savepoint level" = 1, "dropped in savepoint level"=2)
152 rollback savepoint 1 ("current savepoint level = 0) temp table t1 will be removed from the list of temp tables
153 Else if the "dropped in savepoint level" of temp table is greate than or equal to "current savepoint level"
154 it mean that table was dropped in this unit of work (and was declared in an earlier savepoint unit / transaction) and we will
155 restore it as part of rollback ie replace the existing entry for this table in valid temp tables list with restored temp table.
156 At the end of restoring, "declared in savepoint level" will remain unchanged and "dropped in savepoint level" will be -1.
157 eg
158 start tran ("current savepoint level = 0)
159 declare temp table t1 with definition 1("declared in savepoint level" = 0, "dropped in savepoint level"=-1, definition 1(stored in table descriptor))
160 commit (temp table t1 "declared in savepoint level" = -1, "dropped in savepoint level"=-1)
161 start tran ("current savepoint level = 0)
162 set savepoint 1("current savepoint level = 1")
163 drop temp table t1 ("declared in savepoint level" = -1, "dropped in savepoint level"=1, definition 1(stored in table descriptor))
164 declare temp table t1 with definition 2(say different than definition 1)
165 ("declared in savepoint level" = -1, "dropped in savepoint level"=1, definition 1(stored in table descriptor)) ,
166 ("declared in savepoint level" = 1, "dropped in savepoint level"=-1, definition 2(stored in table descriptor))
167 set savepoint 2("current savepoint level = 2")
168 drop temp table t1("declared in savepoint level" = -1, "dropped in savepoint level"=1, definition 1(stored in table descriptor)) ,
169 ("declared in savepoint level" = 1, "dropped in savepoint level"=2, definition 2(stored in table descriptor))
170 rollback tran
171 (Remove : temp table t1("declared in savepoint level" = 1, "dropped in savepoint level"=2, definition 2(stored in table descriptor)
172 (Restore : temp table t1"declared in savepoint level" = -1, "dropped in savepoint level"=-1, definition 1(stored in table descriptor))
173 Else if the "dataModifiedInSavepointLevel" of temp table is greate than or equal to "current savepoint level"
174 it means that table was declared in an earlier savepoint unit / transaction and was modified in the current UOW. And hence we will delete all the
175 data from it.
176 */
177 class TempTableInfo
178 {
179
180 private TableDescriptor td;
181 private int declaredInSavepointLevel;
182 private int droppededInSavepointLevel;
183 private int dataModifiedInSavepointLevel;
184
185 TempTableInfo(TableDescriptor td, int declaredInSavepointLevel)
186 {
187 this.td = td;
188 this.declaredInSavepointLevel = declaredInSavepointLevel;
189 this.droppededInSavepointLevel = -1;
190 this.dataModifiedInSavepointLevel = -1;
191 }
192
193 /**
194 * Return the table descriptor
195 */
196 TableDescriptor getTableDescriptor() {
197 return td;
198 }
199
200 /**
201 * Set the table descriptor. Will be called while temporary is being restored
202 */
203 void setTableDescriptor(TableDescriptor td) {
204 this.td = td;
205 }
206
207 /**
208 * Matches by name and only temp tables that have not been dropped (that's when droppededInSavepointLevel will be -1)
209 */
210 boolean matches(String tableName) {
211 return (td.getName().equals(tableName) && droppededInSavepointLevel == -1);
212 }
213
214 /**
215 * Return the savepoint level when the table was last modified
216 */
217 int getModifiedInSavepointLevel() {
218 return dataModifiedInSavepointLevel;
219 }
220
221 /**
222 * Set the savepoint level when the table was last modified
223 */
224 void setModifiedInSavepointLevel(int dataModifiedInSavepointLevel) {
225 this.dataModifiedInSavepointLevel = dataModifiedInSavepointLevel;
226 }
227
228 /**
229 * Return the savepoint level when the table was declared
230 */
231 int getDeclaredInSavepointLevel() {
232 return declaredInSavepointLevel;
233 }
234
235 /**
236 * Set the savepoint level when the table was declared
237 */
238 void setDeclaredInSavepointLevel(int declaredInSavepointLevel) {
239 this.declaredInSavepointLevel = declaredInSavepointLevel;
240 }
241
242 /**
243 * Return the savepoint level when the table was dropped
244 */
245 int getDroppedInSavepointLevel() {
246 return droppededInSavepointLevel;
247 }
248
249 /**
250 * Return the savepoint level when the table was dropped
251 */
252 public void setDroppedInSavepointLevel(int droppededInSavepointLevel) {
253 this.droppededInSavepointLevel = droppededInSavepointLevel;
254 }
255 }