[ 
https://issues.apache.org/jira/browse/DERBY-712?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Rick Hillegas updated DERBY-712:
--------------------------------

    Attachment: derby-712-05-af-sequenceGenerator.diff

Attaching derby-712-05-af-sequenceGenerator.diff. This patch adds cached 
sequence generators to the data dictionary and makes the NEXT VALUE FOR clause 
yield the expected results. Regression tests have passed for me but I am 
re-running them just to be safe.

User-visible behavior changes as follows:

A) When you issue a NEXT VALUE FOR clause, the value of the sequence generator 
really advances as expected.

B) If you shutdown the database after using a sequence generator, the generator 
may leak up to 5 values. That is, when you reboot, the next value for the 
generator may be up to 5 steps beyond what you expected.

Here is the approach I adopted:

1) SequenceGenerator - This is a general class which manages ranges of sequence 
values. It advances a counter and hands out the next sequence value in a range. 
In addition, it calculates chunk sizes for sub-ranges which can be 
pre-allocated. Right now, pre-allocation is pretty dumb: we just pre-allocate 5 
numbers at a time. In the future we could do something fancier. For instance, 
we could give the user a property for tuning the size of pre-allocated ranges, 
or Derby could auto-tune this number itself based on run-time behavior.

2) SequenceUpdater - This is an abstract class. It is a Cacheable to be stored 
in the data dictionary. Concrete subclasses are responsible for particular 
types of sequences. For instance, there is an inner subclass which is 
responsible for ANSI/ISO sequence generators. In the future, we could add 
another inner subclass which is responsible for identity columns. There is also 
a testing subclass which I used to test boundary conditions related to the 
currently unimplemented optional clauses of the CREATE SEQUENCE statement. The 
SequenceUpdater does the following tasks:

a) It calls its corresponding SequenceGenerator to calculate the next value in 
a sequence.

b) It manages the updating of the system tables when a pre-allocated range 
needs to be recorded on disk.

c) It reclaims unused pre-allocated values when the data dictionary caches have 
to be flushed. This prevents us from leaking values when DDL is performed. In 
the future, similar reclamation could be performed during the orderly shutdown 
of a database. This probably requires some discussion.

There are some tricky bits in the implementation:

i) There are a couple synchronized methods in SequenceGenerator. It is my hope 
that these critical sections are short.

ii) The on-disk catalog value (in this case, SYS.SYSSEQUENCES.CURRENTVALUE) is 
updated in a read/write subtransaction of the session's execution transaction 
if possible--and that subtransaction is then immediately committed. However, if 
it is not possible to obtain an immediate lock on the catalog row, we fall back 
to updating the row in the parent transaction, that is, in the session's 
execution transaction. This is similar to what is done for identity columns 
today.

iii) Updating the value in the catalog row is managed by a little hopping back 
and forth among the DataDictionary, the SequenceUpdater, and the 
SequenceGenerator. Here's what the flow of control looks like:

o An Activation asks the DataDictionary for the next value in a sequence.

o The DataDictionary forwards the request to the SequenceUpdater.

o The SequenceUpdater forwards the request to the SequenceGenerator.

o If the SequenceGenerator determines that a new range needs to be allocated, 
it calculates the new endpoint of the range. Then the SequenceGenerator asks 
the SequenceUpdater to allocate the new range.

o The SequenceUpdater forwards that request to the DataDictionary.

o The DataDictionary updates the catalog row.

o Everyone returns and the Activation gets the value it asked for.


Touches the following files:

-------

A      java/engine/org/apache/derby/impl/sql/catalog/SequenceGenerator.java

The SequenceGenerator described in (1) above.

-------


A      java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java

The SequenceUpdater described in (2) above.

-------


M      java/engine/org/apache/derby/iapi/reference/Property.java
M      java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java
M      java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
M      java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java

DataDictionary support for cached sequence generators.

-------


M      java/engine/org/apache/derby/iapi/sql/dictionary/SequenceDescriptor.java
M      java/engine/org/apache/derby/impl/sql/catalog/SYSSEQUENCESRowFactory.java
M      
java/engine/org/apache/derby/iapi/sql/dictionary/DataDescriptorGenerator.java
M      
java/engine/org/apache/derby/impl/sql/execute/CreateSequenceConstantAction.java

A null in SYS.SYSSEQUENCES.CURRENTVALUE now means that a non-cycling sequence 
generator is exhausted. That is, it has run through its range of legal values.


-------

M      java/engine/org/apache/derby/loc/messages.xml
M      java/shared/org/apache/derby/shared/common/reference/SQLState.java

New error message for exhausted sequence generators.


-------

M      java/engine/org/apache/derby/impl/sql/compile/NextSequenceNode.java

Code-generation for the NEXT VALUE FOR clause.

-------

M      java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java

Run-time support for the NEXT VALUE FOR clause.


-------

A      
java/testing/org/apache/derbyTesting/functionTests/tests/lang/SGVetter.java
M      
java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
M      
java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceTest.java
M      java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
M      
java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java
A      
java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceGeneratorTest.java

Regression tests for cached sequence generators. SGVetter is a 
re-implementation of sequence generation used to test the correctness of the 
production SequenceGenerator. SGVetter is less efficient than SequenceGenerator 
but it is easier to reason about its correctness.

-------


> Support for sequences
> ---------------------
>
>                 Key: DERBY-712
>                 URL: https://issues.apache.org/jira/browse/DERBY-712
>             Project: Derby
>          Issue Type: Improvement
>          Components: SQL
>         Environment: feature request 
>            Reporter: Tony Dahbura
>            Assignee: Suran Jayathilaka
>             Fix For: 10.6.0.0
>
>         Attachments: altertable.diff, catalogs_a.patch, catalogs_b.patch, 
> catalogs_c.patch, catalogs_d.patch, catalogs_e.patch, catalogs_f.patch, 
> catalogs_f_2.patch, catalogs_g.diff, catalogs_h.diff, 
> create_drop_sequence_a.patch, create_drop_sequence_b.patch, 
> create_drop_sequence_c.patch, create_drop_sequence_d.patch, 
> create_sequence_a.patch, createseq_args_bind_a.diff, 
> derby-712-02-aa-privilegeNodeCleanup.diff, 
> derby-712-03-aa-usagePrivilege.diff, derby-712-03-ac-usagePrivilege.diff, 
> derby-712-04-aa-dblook.diff, derby-712-05-af-sequenceGenerator.diff, 
> SequenceGenerator.html, sequences_next_value_a.patch
>
>
> Would like to see support added for sequences.  This would permit a select 
> against the sequence to always obtain a ever increasing/decreasing value.  
> The identity column works fine but there are times for applications where the 
> application needs to obtain the sequence number and use it prior to the 
> database write.  Subsequent calls to the table/column would result in a new 
> number on each call.
> SQL such as the following:
> SELECT NEXT VALUE FOR sequence_name FROM sometable ; would result in a next 
> value.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to