Derby
  1. Derby
  2. DERBY-4428

Add proper delete mechanism for in-memory databases

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 10.6.1.0
    • Fix Version/s: 10.6.1.0
    • Component/s: JDBC, Services, Store
    • Labels:
      None

      Description

      The current mechanism for deleting in-memory databases isn't good enough, and a proper one must be added.
      It is also important to be able to delete in-memory databases, since they occupy valuable main memory that should be discarded when the database is no longer needed.

      I intend to implement the mechanism by using the JDBC connection URL:
      "jdbc:derby:memory:myDatabase;delete=true[;user=X;password=Y]

      The connection attempt will throw an exception in any case, either because the request failed or because it succeeded.
      Reasons for a failure can be invalid user and/or password, lacking encryption attributes, or conflicting attributes.
      For the time being, only the database owner will be allowed to delete databases (note: do we have a way to control/limit in-memory database creation?)

      1. derby-4428-3b-canonical_name_handling.diff
        5 kB
        Kristian Waagan
      2. derby-4428-3a-canonical_name_handling.diff
        6 kB
        Kristian Waagan
      3. derby-4428-2b-generic_db_drop.diff
        15 kB
        Kristian Waagan
      4. derby-4428-2a-generic_db_drop.diff
        14 kB
        Kristian Waagan
      5. derby-4428-1b-in_memory_specific_delete_code.diff
        8 kB
        Kristian Waagan
      6. derby-4428-1a-in_memory_specific_delete_code.stat
        0.1 kB
        Kristian Waagan
      7. derby-4428-1a-in_memory_specific_delete_code.diff
        5 kB
        Kristian Waagan
      8. derby-4428-0a-preview_patch.diff
        58 kB
        Kristian Waagan

        Issue Links

          Activity

          Hide
          Kristian Waagan added a comment -

          Attached patch 0a, which is a preview patch for implementing the database delete mechanism through the JDBC connection URL.

          The patch isn't pure, it contains a few other fixes and there are things that have to be addressed. However, it should serve well as a point for discussion. Main parts of the patch:

          • implementation of the delete mechanism itself.
            Split into the in-memory specific part and the storage factory agnostic part. Also includes additions of error messages and some constants.
          • refactoring of the URL attribute handling in EmbedConnection.
            BootActions now contain the code dealing with examining the attributes. I'm interested in feedback on whether this is something worth keeping or not. Note that attribute parsing is still spread around, for instance the "lower level" attributes like restoreFrom and createFrom are handled elsewhere (store).
          • other changes to the VFMemSF, where I added a guard to avoid potential OOMEs when trying to boot a lot of non-existing databases.
          • refactoring and addition of some new tests.

          Some general issues to consider / note:

          • the delete mechanism is generic (all storage factories that is writable). Should the feature be in-memory specific, or also be allowed for the on-disk back end?
          • authorization (currently it checks if the user is the database owner if authentication is on, doesn't require SQL authorization to be on).
          • how to control/limit the creation of in-memory databases?
            (could be used for DoS attack on a server?)
          • the implementation of deletion isn't sufficient for on-disk databases where the log is stored in a non-default location (logDevice=...).
          • I had to disable an assert due to a mismatch between canonical names (haven't investigated too much yet, this part of the code still confuses me...)

          I plan to split the changes into somewhat smaller patches before committing.

          Show
          Kristian Waagan added a comment - Attached patch 0a, which is a preview patch for implementing the database delete mechanism through the JDBC connection URL. The patch isn't pure, it contains a few other fixes and there are things that have to be addressed. However, it should serve well as a point for discussion. Main parts of the patch: implementation of the delete mechanism itself. Split into the in-memory specific part and the storage factory agnostic part. Also includes additions of error messages and some constants. refactoring of the URL attribute handling in EmbedConnection. BootActions now contain the code dealing with examining the attributes. I'm interested in feedback on whether this is something worth keeping or not. Note that attribute parsing is still spread around, for instance the "lower level" attributes like restoreFrom and createFrom are handled elsewhere (store). other changes to the VFMemSF, where I added a guard to avoid potential OOMEs when trying to boot a lot of non-existing databases. refactoring and addition of some new tests. Some general issues to consider / note: the delete mechanism is generic (all storage factories that is writable). Should the feature be in-memory specific, or also be allowed for the on-disk back end? authorization (currently it checks if the user is the database owner if authentication is on, doesn't require SQL authorization to be on). how to control/limit the creation of in-memory databases? (could be used for DoS attack on a server?) the implementation of deletion isn't sufficient for on-disk databases where the log is stored in a non-default location (logDevice=...). I had to disable an assert due to a mismatch between canonical names (haven't investigated too much yet, this part of the code still confuses me...) I plan to split the changes into somewhat smaller patches before committing.
          Hide
          Dag H. Wanvik added a comment -

          SQL uses the keyword "DROP", is there a reason you prefer "delete" over drop in the URL?

          > authorization (currently it checks if the user is the database owner
          > if authentication is on, doesn't require SQL authorization to be
          > on).

          Database shutdown is restricted to DBO when authentication AND
          authorization are both enabled; I think because it was felt that doing
          it for authentication only could cause problems for existing
          apps. Since thre is no prior use here, that would not be a
          problem. But it would be slightly asymmetrical. What do you think?

          The system privileges work was intended to control who can create
          databases and would probably be required for dropping (deletion), at
          least if we enable it for on-disk databases. But since that work is still
          pending, I think limiting this to DBO is a good choice.

          I think enabling dropping of on-disk databases is interesting. What would the cons be?

          Show
          Dag H. Wanvik added a comment - SQL uses the keyword "DROP", is there a reason you prefer "delete" over drop in the URL? > authorization (currently it checks if the user is the database owner > if authentication is on, doesn't require SQL authorization to be > on). Database shutdown is restricted to DBO when authentication AND authorization are both enabled; I think because it was felt that doing it for authentication only could cause problems for existing apps. Since thre is no prior use here, that would not be a problem. But it would be slightly asymmetrical. What do you think? The system privileges work was intended to control who can create databases and would probably be required for dropping (deletion), at least if we enable it for on-disk databases. But since that work is still pending, I think limiting this to DBO is a good choice. I think enabling dropping of on-disk databases is interesting. What would the cons be?
          Hide
          Rick Hillegas added a comment -

          Thanks for working on this, Kristian. Some comments follow:

          > - the delete mechanism is generic (all storage factories that is writable). Should the feature be in-memory specific, or also be allowed for the on-disk back end?

          I think the feature should be designed so that it can be extended to the on-disk back end. However, I would treat on-disk back ends as a separate JIRA--particularly because they have extra problems as evidenced by your comment about the log.

          > - authorization (currently it checks if the user is the database owner if authentication is on, doesn't require SQL authorization to be on).

          I wonder if we need to check whether authentication is on? In an embedded application with no authentication, the default DBO will be APP. I think that in such a situation it would be attractive if APP could delete her in-memory databases. In such a situation, I think it's enough to require that there be no open connections to the database.

          > - how to control/limit the creation of in-memory databases?
          > (could be used for DoS attack on a server?)

          I agree that there is a DoS attack here. It's related to the DoS attack allowed by unlimited creation of on-disk databases, and compounded by the extra memory which an in-memory database chews up. The half-checked-in work on system privileges (DERBY-2109) defines a Java privilege for creating databases. That privilege includes the specification of where you are allowed to create databases. I believe that we should build on that work.

          Thanks,
          -Rick

          Show
          Rick Hillegas added a comment - Thanks for working on this, Kristian. Some comments follow: > - the delete mechanism is generic (all storage factories that is writable). Should the feature be in-memory specific, or also be allowed for the on-disk back end? I think the feature should be designed so that it can be extended to the on-disk back end. However, I would treat on-disk back ends as a separate JIRA--particularly because they have extra problems as evidenced by your comment about the log. > - authorization (currently it checks if the user is the database owner if authentication is on, doesn't require SQL authorization to be on). I wonder if we need to check whether authentication is on? In an embedded application with no authentication, the default DBO will be APP. I think that in such a situation it would be attractive if APP could delete her in-memory databases. In such a situation, I think it's enough to require that there be no open connections to the database. > - how to control/limit the creation of in-memory databases? > (could be used for DoS attack on a server?) I agree that there is a DoS attack here. It's related to the DoS attack allowed by unlimited creation of on-disk databases, and compounded by the extra memory which an in-memory database chews up. The half-checked-in work on system privileges ( DERBY-2109 ) defines a Java privilege for creating databases. That privilege includes the specification of where you are allowed to create databases. I believe that we should build on that work. Thanks, -Rick
          Hide
          Kristian Waagan added a comment -

          Thanks for the comments, Dag and Rick.
          See my replies below, which address comments from both of you.

          (Dag)> SQL uses the keyword "DROP", is there a reason you prefer "delete" over drop in the URL?
          No, I wouldn't mind changing it to "drop" if that is more in line with the SQL spec. Is there something like "drop database" in the SQL spec?
          Note that I don't have any plans at this time to implement a way to delete databases using SQL.

          (Dag)> ... [authentication and authorization] ... But it would be slightly asymmetrical. What do you think?
          (Rick)> I wonder if we need to check whether authentication is on?
          I think we need two different paths here. Assuming SQL authorization will be used to control who can delete a database in the future, what about this?
          if (authenticationOn && sqlAuthorizationOn)

          { checkPrivileges(); // May also want to see if the user is the DBO here, depending on implementation details. }

          else

          { checkIsDBOwner(); }

          Since we don't have the required functionality to use system privileges through GRANT/REVOKE yet, we can just check for DBO unconditionally as Rick suggests.
          Note that this will allow only the DBO to delete the database. Another option is to allow everyone to delete a database if no authentication/authorization is enabled, but this is of course very liberal.

          (Rick)> ... [authentication] ... In such a situation, I think it's enough to require that there be no open connections to the database.
          This doesn't happen on shutdown, does it? Why should it happen on drop/delete, in which case the data goes away anyway?
          The only reason I can think of, is to allow the existing connections to finish their queries.
          As an experiment, I implemented a simple mechanism to block database access. The mechanism was activated by the delete request, but could also be made available through the JDBC connection URL (would make it possible for the DBO to block access for maintenance work). My test, which ran 3 - 20 concurrent threads accessing the database to be deleted and then executing a simple query, gave much better results when the block mechanism was used. There are levels of consideration:

          • wait for ongoing connection attempts to finish (with the block mechanism, new connections won't be allowed)
          • wait for a given time to allow [some] queries to complete (issue with long running queries)
          • wait for all connected clients to disconnect (with timeout?)

          Especially ongoing connection attempts result in lots of different error messages. I've seen the shutdown exception (which is fine, I think), NPEs, conglomerate not found exceptions, and others. It is also a question of when one should signal / perform shutdown, as this will cause the connections to be dropped at some point.

          (Dag)> I think enabling dropping of on-disk databases is interesting. What would the cons be?
          I'm thinking mostly about the security aspect. Are there other issues?
          A possible add-on feature here would be a property disabling the JDBC delete mechanism for production systems, but this could be problematic if deleting some databases in the system should be allowed. Maybe SQL authorization could be used instead, if the drop/delete privilege can't be granted again if it has been revoked?

          (Rick)> I think the feature should be designed so that it can be extended to the on-disk back end. However, I would treat on-disk back ends as a separate JIRA - ...
          I agree. This will require some extra code right away, because the functionality is already used internally (to re-create the service root). I know about several ways deletion can be disabled for a specific storage factory, but they all have drawbacks... Maybe there is a better way I haven't found yet, but I'll get back to the details later.

          (Rick)> ... [system privileges] ... That privilege includes the specification of where you are allowed to create databases.
          Even though "where" isn't quite as well-defined in the in-memory back end as in the on-disk/directory back end, I think such a privilege may be enough. However, the Java security manager, or a custom one, would have to be faulted in since the in-memory back end doesn't access the virtual files through java.io.File.
          It is not clear to me if such a privilege would allow us to differentiate between back ends, or rather subsubprotocols.
          Would the system privileges also allow us to say who are allowed to create databases?

          I now have the following known tasks on my list:

          • add in-memory specific code required for drop
          • add generic code required for drop (includes URL handling)
          • add database access block mechanism
          • disable drop/delete for on-disk back end (the rest of the back ends are read only)
          • add drop tests (for in-memory back end primarily)
          • add mechanism to control / limit database creation (we can already use the Java security manager for on-disk databases, but not for in-memory databases)
            (- improve handling of unsuccessful boots in the in-memory storage factory (resource management issue))

          Further comments are welcome.

          Show
          Kristian Waagan added a comment - Thanks for the comments, Dag and Rick. See my replies below, which address comments from both of you. (Dag)> SQL uses the keyword "DROP", is there a reason you prefer "delete" over drop in the URL? No, I wouldn't mind changing it to "drop" if that is more in line with the SQL spec. Is there something like "drop database" in the SQL spec? Note that I don't have any plans at this time to implement a way to delete databases using SQL. (Dag)> ... [authentication and authorization] ... But it would be slightly asymmetrical. What do you think? (Rick)> I wonder if we need to check whether authentication is on? I think we need two different paths here. Assuming SQL authorization will be used to control who can delete a database in the future, what about this? if (authenticationOn && sqlAuthorizationOn) { checkPrivileges(); // May also want to see if the user is the DBO here, depending on implementation details. } else { checkIsDBOwner(); } Since we don't have the required functionality to use system privileges through GRANT/REVOKE yet, we can just check for DBO unconditionally as Rick suggests. Note that this will allow only the DBO to delete the database. Another option is to allow everyone to delete a database if no authentication/authorization is enabled, but this is of course very liberal. (Rick)> ... [authentication] ... In such a situation, I think it's enough to require that there be no open connections to the database. This doesn't happen on shutdown, does it? Why should it happen on drop/delete, in which case the data goes away anyway? The only reason I can think of, is to allow the existing connections to finish their queries. As an experiment, I implemented a simple mechanism to block database access. The mechanism was activated by the delete request, but could also be made available through the JDBC connection URL (would make it possible for the DBO to block access for maintenance work). My test, which ran 3 - 20 concurrent threads accessing the database to be deleted and then executing a simple query, gave much better results when the block mechanism was used. There are levels of consideration: wait for ongoing connection attempts to finish (with the block mechanism, new connections won't be allowed) wait for a given time to allow [some] queries to complete (issue with long running queries) wait for all connected clients to disconnect (with timeout?) Especially ongoing connection attempts result in lots of different error messages. I've seen the shutdown exception (which is fine, I think), NPEs, conglomerate not found exceptions, and others. It is also a question of when one should signal / perform shutdown, as this will cause the connections to be dropped at some point. (Dag)> I think enabling dropping of on-disk databases is interesting. What would the cons be? I'm thinking mostly about the security aspect. Are there other issues? A possible add-on feature here would be a property disabling the JDBC delete mechanism for production systems, but this could be problematic if deleting some databases in the system should be allowed. Maybe SQL authorization could be used instead, if the drop/delete privilege can't be granted again if it has been revoked? (Rick)> I think the feature should be designed so that it can be extended to the on-disk back end. However, I would treat on-disk back ends as a separate JIRA - ... I agree. This will require some extra code right away, because the functionality is already used internally (to re-create the service root). I know about several ways deletion can be disabled for a specific storage factory, but they all have drawbacks... Maybe there is a better way I haven't found yet, but I'll get back to the details later. (Rick)> ... [system privileges] ... That privilege includes the specification of where you are allowed to create databases. Even though "where" isn't quite as well-defined in the in-memory back end as in the on-disk/directory back end, I think such a privilege may be enough. However, the Java security manager, or a custom one, would have to be faulted in since the in-memory back end doesn't access the virtual files through java.io.File. It is not clear to me if such a privilege would allow us to differentiate between back ends, or rather subsubprotocols. Would the system privileges also allow us to say who are allowed to create databases? I now have the following known tasks on my list: add in-memory specific code required for drop add generic code required for drop (includes URL handling) add database access block mechanism disable drop/delete for on-disk back end (the rest of the back ends are read only) add drop tests (for in-memory back end primarily) add mechanism to control / limit database creation (we can already use the Java security manager for on-disk databases, but not for in-memory databases) (- improve handling of unsuccessful boots in the in-memory storage factory (resource management issue)) Further comments are welcome.
          Hide
          Kristian Waagan added a comment -

          Patch 1a is a suggestion for the code required in the in-memory module to support drop database.
          The idea is to delete all traces of the database when the storage factory is shut down and the database has been scheduled for deletion. The latter part is true if the data store has detected that the service root has been deleted.

          Patch ready for review.

          Missing pieces of code:
          a) Introduction and handling of new URL attribute, including a new SQLState / message. Most of this will probably go into EmbedConnection.
          b) Actually shutting down and deleting the database. Code will go into EmbedConnection and maybe into one of the context classes.
          c) Database access block mechanism (not really required to implement drop database, but not having it will make the drop database process more messy). This code will most likely go into EmbedConnection, BasicDatabase/Database and maybe BaseMonitor.

          I think I'll combine (a) and (b), and add (c) as a later step.

          Show
          Kristian Waagan added a comment - Patch 1a is a suggestion for the code required in the in-memory module to support drop database. The idea is to delete all traces of the database when the storage factory is shut down and the database has been scheduled for deletion. The latter part is true if the data store has detected that the service root has been deleted. Patch ready for review. Missing pieces of code: a) Introduction and handling of new URL attribute, including a new SQLState / message. Most of this will probably go into EmbedConnection. b) Actually shutting down and deleting the database. Code will go into EmbedConnection and maybe into one of the context classes. c) Database access block mechanism (not really required to implement drop database, but not having it will make the drop database process more messy). This code will most likely go into EmbedConnection, BasicDatabase/Database and maybe BaseMonitor. I think I'll combine (a) and (b), and add (c) as a later step.
          Hide
          Kristian Waagan added a comment -

          Patch 2a adds the generic drop mechanism. Dropping databases works with patch 2a alone, but will cause memory leaks without patch 1a.

          I expect there will be another revision once the patch has been reviewed. Two things I need feedback on:

          • error messages. (the language of the new ones, do we need another message for the drop database operation, do we need a special message when denying the drop for non-in-memory databases etc)
          • to authenticate/authorize or not. Patch 1a breaks the current pattern used elsewhere, i.e. only check if the user is the DBO if both authentication and SQL authorization are enabled.

          Running regression tests.
          Patch ready for review.

          Show
          Kristian Waagan added a comment - Patch 2a adds the generic drop mechanism. Dropping databases works with patch 2a alone, but will cause memory leaks without patch 1a. I expect there will be another revision once the patch has been reviewed. Two things I need feedback on: error messages. (the language of the new ones, do we need another message for the drop database operation, do we need a special message when denying the drop for non-in-memory databases etc) to authenticate/authorize or not. Patch 1a breaks the current pattern used elsewhere, i.e. only check if the user is the DBO if both authentication and SQL authorization are enabled. Running regression tests. Patch ready for review.
          Hide
          Kristian Waagan added a comment -

          Patches 1a and 2a ready for review.

          Show
          Kristian Waagan added a comment - Patches 1a and 2a ready for review.
          Hide
          Kristian Waagan added a comment -

          Attached patch 1b and committed it to trunk with revision 883297.

          Patch 1b handles the removal of the data store in two places; on init or shutdown. I discovered a weakness when testing create, drop, shutdown and connect in a highly multithreaded test, where all connection attempts were made against the same database. Since the delete is a two step process from when you do File.deleteAll to StorageFactory.shutdown, there was a small window where another thread could slip in and get a handle on the data store that was just deleted.
          In my test this didn't trigger anything else than my assert-style check in VFMemSF.shutdown, but I found it safer to deal with it. The required changes were also small.

          All regression tests passed.

          Show
          Kristian Waagan added a comment - Attached patch 1b and committed it to trunk with revision 883297. Patch 1b handles the removal of the data store in two places; on init or shutdown. I discovered a weakness when testing create, drop, shutdown and connect in a highly multithreaded test, where all connection attempts were made against the same database. Since the delete is a two step process from when you do File.deleteAll to StorageFactory.shutdown, there was a small window where another thread could slip in and get a handle on the data store that was just deleted. In my test this didn't trigger anything else than my assert-style check in VFMemSF.shutdown, but I found it safer to deal with it. The required changes were also small. All regression tests passed.
          Hide
          Kristian Waagan added a comment -

          Attaching patch 3a, which changes how StorageFactoryService handles canonical names.
          I have to admit the name handling puzzles me somewhat, but I hope I got it right now. It seems that this code never expected to get canonical names from other storage factories than the default. The value passed in will have the storage factory type name, whereas the storage factory itself doesn't append it's type. With the old code, every attempt to delete a service would fail, except for when the default storage factory is used (the on-disk directory based back end).

          This patch caused me some trouble already, and I want to test it on Windows before I commit it. An extra pair of eyes would be good as well!
          So far the only errors observed have been assert errors, but I haven't verified that everything works in insane mode despite the triggered asserts.

          Patch ready for review.

          Show
          Kristian Waagan added a comment - Attaching patch 3a, which changes how StorageFactoryService handles canonical names. I have to admit the name handling puzzles me somewhat, but I hope I got it right now. It seems that this code never expected to get canonical names from other storage factories than the default. The value passed in will have the storage factory type name, whereas the storage factory itself doesn't append it's type. With the old code, every attempt to delete a service would fail, except for when the default storage factory is used (the on-disk directory based back end). This patch caused me some trouble already, and I want to test it on Windows before I commit it. An extra pair of eyes would be good as well! So far the only errors observed have been assert errors, but I haven't verified that everything works in insane mode despite the triggered asserts. Patch ready for review.
          Hide
          Kristian Waagan added a comment -

          Attached patch 3b, and committed it to trunk with revision 884105.

          I chose not to rename the method argument to canonicalServiceName, as I don't think this isn't strictly necessary. It would also mean that the argument names in the interface and the implementation would differ (not a problem by itself, but might cause some confusion). That said, the monitor code (and friends) is confusing on this matter - do you have to use the canonical service name, or will the code obtain the canonical service name for you? I observe that the latter is the case in many places, but I haven't gone through the code to confirm this is the principle behind the code.

          I need to make a few adjustments to patch 2a, and then the drop functionality will be working - although not very well in cases where there are concurrent connection attempts to the database being dropped.

          Show
          Kristian Waagan added a comment - Attached patch 3b, and committed it to trunk with revision 884105. I chose not to rename the method argument to canonicalServiceName, as I don't think this isn't strictly necessary. It would also mean that the argument names in the interface and the implementation would differ (not a problem by itself, but might cause some confusion). That said, the monitor code (and friends) is confusing on this matter - do you have to use the canonical service name, or will the code obtain the canonical service name for you? I observe that the latter is the case in many places, but I haven't gone through the code to confirm this is the principle behind the code. I need to make a few adjustments to patch 2a, and then the drop functionality will be working - although not very well in cases where there are concurrent connection attempts to the database being dropped.
          Hide
          Kristian Waagan added a comment -

          Attached patch 2b.
          Major changes from 2a:

          • adjusted test ErrorCodeTest (failed due to the newly added messages)
          • the requirement for the user to be the DBO when dropping is only enforced when authentication and authorization are enabled (this follows the current pattern in EmbedConnection)

          Committed to trunk with revision 884542.
          I didn't get any comments on the patch, but it's not too late to review of course

          Things to consider:

          • How long should we wait before dropping the database? (see the sleep in EmbedConnection)
            I expect this will change when the block mechanism has been implemented. The longer the wait, the higher the chance that connected clients will get a reasonable exception.
          • I have reused some messages, for instance if the user isn't the DBO and when trying to delete a on-disk database. Is this ok, or should I add new ones?

          I'll continue working on the access block mechanism (DERBY-4447), and the new feature has to be documented. I also think I have to do some more testing with the client driver, as I've found at least one Jira issue indicating the error handling isn't good enough.

          Show
          Kristian Waagan added a comment - Attached patch 2b. Major changes from 2a: adjusted test ErrorCodeTest (failed due to the newly added messages) the requirement for the user to be the DBO when dropping is only enforced when authentication and authorization are enabled (this follows the current pattern in EmbedConnection) Committed to trunk with revision 884542. I didn't get any comments on the patch, but it's not too late to review of course Things to consider: How long should we wait before dropping the database? (see the sleep in EmbedConnection) I expect this will change when the block mechanism has been implemented. The longer the wait, the higher the chance that connected clients will get a reasonable exception. I have reused some messages, for instance if the user isn't the DBO and when trying to delete a on-disk database. Is this ok, or should I add new ones? I'll continue working on the access block mechanism ( DERBY-4447 ), and the new feature has to be documented. I also think I have to do some more testing with the client driver, as I've found at least one Jira issue indicating the error handling isn't good enough.
          Hide
          Kristian Waagan added a comment -

          Closing this issue.

          Work on DERBY-4447 has been postponed.

          Show
          Kristian Waagan added a comment - Closing this issue. Work on DERBY-4447 has been postponed.

            People

            • Assignee:
              Kristian Waagan
              Reporter:
              Kristian Waagan
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development