Derby
  1. Derby
  2. DERBY-3944

CHECK constraints involving user-coded functions may return different results depending on who performs the triggering INSERT/UPDATE

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 10.5.1.1
    • Fix Version/s: 10.5.3.2, 10.6.2.4, 10.7.1.1
    • Component/s: SQL
    • Labels:
      None
    • Urgency:
      Normal
    • Issue & fix info:
      Known fix, Repro attached
    • Bug behavior facts:
      Data corruption

      Description

      When compiling a CHECK constraint on behalf of an INSERT/UPDATE statement, Derby uses the current schema in order to resolve unqualified function names which appear in the CHECK constraint. This means that the CHECK constraint may evaluate true for some users, false for others, and for others the CHECK constraint may raise an error saying that Derby can't resolve the function reference. This behavior violates the "retrospective determinacy" of CHECK constraints as specified by part 2 of the ANSI/ISO standard:

      1) section 11.9 (<check constraint definition>), syntax rule 5
      2) same section, general rule 1
      3) section 11.6 (<table constraint definition>), general rule 3
      4) section 4.16 (Determinism)

      For more discussion, please see this email thread: http://www.nabble.com/Problem-with-CHECK-constraints-td20445344.html#a20445344

      The following script demonstrates this problem:

      connect 'jdbc:derby:derbyauth;create=true;user=test_dbo;password=test_dbopassword' as test_dbo_conn;

      drop table t_bp_2;
      drop function f_fp_minus;

      create function f_fp_minus
      (
      a int
      )
      returns int
      language java
      deterministic
      parameter style java
      no sql
      external name 'org.apache.derbyTesting.functionTests.tests.lang.GeneratedColumnsTest.minus'
      ;

      create table t_bp_2( a int, constraint t_bp_2_check check ( f_fp_minus( a ) < 0 ) );

      grant insert on t_bp_2 to public;

      insert into test_dbo.t_bp_2( a ) values ( 100 );

      connect 'jdbc:derby:derbyauth;create=true;user=janet;password=janetpassword' as janet_conn;

      insert into test_dbo.t_bp_2( a ) values ( 100 );

        Issue Links

          Activity

          Hide
          Rick Hillegas added a comment -

          Hopefully, the same patch will fix this issue and DERBY-3945.

          Show
          Rick Hillegas added a comment - Hopefully, the same patch will fix this issue and DERBY-3945 .
          Hide
          Andrew McIntyre added a comment -

          Did a quick check as I happened to have several different DBs handy. DB2 v9 only allows user defined functions that can be expressed in SQL, and IDS 11, Oracle 9, and MS SQL Server 2005 all disallow user-defined functions in check constraints.

          Show
          Andrew McIntyre added a comment - Did a quick check as I happened to have several different DBs handy. DB2 v9 only allows user defined functions that can be expressed in SQL, and IDS 11, Oracle 9, and MS SQL Server 2005 all disallow user-defined functions in check constraints.
          Hide
          Rick Hillegas added a comment -

          Thanks, Andrew. When you've got a moment, can you let us know what schema DB2 assigns to the function references if they aren't qualified with an explicit schema name?

          Show
          Rick Hillegas added a comment - Thanks, Andrew. When you've got a moment, can you let us know what schema DB2 assigns to the function references if they aren't qualified with an explicit schema name?
          Hide
          Andrew McIntyre added a comment -

          DB2 assigns it to the current schema. In the default case, this is the schema corresponding to the user id.

          FWIW, the copy of the SQL standard I have says in sec. 5.4, 4a that the unqualified identifiers should resolve to the current schema for the SQL session and the definition of routine invocation has no language to contradict that and simply says that it's a qualified identifier. While it seems logical to me that an unqualified function name in a check constraint would resolve to the schema containing the table with the constraint, it could be useful to have the function resolve to different functions in each schema, e.g. allowing different users to insert data into a table with different constraints.

          Show
          Andrew McIntyre added a comment - DB2 assigns it to the current schema. In the default case, this is the schema corresponding to the user id. FWIW, the copy of the SQL standard I have says in sec. 5.4, 4a that the unqualified identifiers should resolve to the current schema for the SQL session and the definition of routine invocation has no language to contradict that and simply says that it's a qualified identifier. While it seems logical to me that an unqualified function name in a check constraint would resolve to the schema containing the table with the constraint, it could be useful to have the function resolve to different functions in each schema, e.g. allowing different users to insert data into a table with different constraints.
          Hide
          Rick Hillegas added a comment -

          Thanks, Andrew. I agree that there are applications which might want CHECK constraints to behave as you describe. That behavior, however, violates my understanding of "retrospective determinacy". It may be that the standard did a poor job of integrating user-defined functions with CHECK constraints. I will ask around for more guidance.

          Show
          Rick Hillegas added a comment - Thanks, Andrew. I agree that there are applications which might want CHECK constraints to behave as you describe. That behavior, however, violates my understanding of "retrospective determinacy". It may be that the standard did a poor job of integrating user-defined functions with CHECK constraints. I will ask around for more guidance.
          Hide
          Andrew McIntyre added a comment -

          I checked yesterday and contrary to the way the docs read, DB2 doesn't actually allow user defined functions in SQL in check constraints either. I suspect this may simply be an overlooked corner in the SQL spec, since none of the major vendors support user-defined functions in check constraints and built-in functions never need a schema qualifier.

          Show
          Andrew McIntyre added a comment - I checked yesterday and contrary to the way the docs read, DB2 doesn't actually allow user defined functions in SQL in check constraints either. I suspect this may simply be an overlooked corner in the SQL spec, since none of the major vendors support user-defined functions in check constraints and built-in functions never need a schema qualifier.
          Hide
          Rick Hillegas added a comment -

          Thanks for the extra information, Andrew. In the meantime, discussion has continued on the email thread mentioned above. Dag's eagle eyes spotted the following chapter and verse, which appears to settle the spec issues:

          section 4.27.2 Characteristics of SQL-invoked routines:

          > > If a <routine invocation> is contained in a <query expression> of a
          > > view, a check constraint, or an assertion, the <triggered action> of a
          ****************
          > > trigger, or in an <SQL-invoked routine>, then the subject routine for
          > > that invocation is determined at the time the view is created, the
          > > check constraint is defined, the assertion is created, the trigger is
          > > created, or the SQL-invoked routine is created.

          Show
          Rick Hillegas added a comment - Thanks for the extra information, Andrew. In the meantime, discussion has continued on the email thread mentioned above. Dag's eagle eyes spotted the following chapter and verse, which appears to settle the spec issues: section 4.27.2 Characteristics of SQL-invoked routines: > > If a <routine invocation> is contained in a <query expression> of a > > view, a check constraint, or an assertion, the <triggered action> of a **************** > > trigger, or in an <SQL-invoked routine>, then the subject routine for > > that invocation is determined at the time the view is created, the > > check constraint is defined, the assertion is created, the trigger is > > created, or the SQL-invoked routine is created.
          Hide
          Kristian Waagan added a comment -

          Triaged July 3, 2009: Assigned normal urgency, marked Known fix and Repro attached.

          Show
          Kristian Waagan added a comment - Triaged July 3, 2009: Assigned normal urgency, marked Known fix and Repro attached.
          Hide
          Rick Hillegas added a comment -

          Attaching derby-3944-01-aa-useOriginalSchema.diff. This causes CHECK constraints compile in the schema of the target table rather than in the current schema of the INSERT/UPDATE statement. I will run tests.

          Touches the following files:

          -----------

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

          Changes the current schema while compiling check constraints.

          -----------

          M java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsPermsTest.java

          Adds a test for this behavior.

          Show
          Rick Hillegas added a comment - Attaching derby-3944-01-aa-useOriginalSchema.diff. This causes CHECK constraints compile in the schema of the target table rather than in the current schema of the INSERT/UPDATE statement. I will run tests. Touches the following files: ----------- M java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java Changes the current schema while compiling check constraints. ----------- M java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsPermsTest.java Adds a test for this behavior.
          Hide
          Rick Hillegas added a comment -

          Attaching second rev of the patch, derby-3944-01-ab-useOriginalSchema.diff. This rev adds a test case to verify that DERBY-3953 has also been fixed.

          DERBY-3953 appears to have been fixed by some other patch. This additional test case merely tracks that fact. I will close DERBY-3953 when I commit this patch.

          Show
          Rick Hillegas added a comment - Attaching second rev of the patch, derby-3944-01-ab-useOriginalSchema.diff. This rev adds a test case to verify that DERBY-3953 has also been fixed. DERBY-3953 appears to have been fixed by some other patch. This additional test case merely tracks that fact. I will close DERBY-3953 when I commit this patch.
          Hide
          Rick Hillegas added a comment -

          Tests passed cleanly for me except for the known regression having to do with port numbers. Committed at subversion revision 964402.

          Show
          Rick Hillegas added a comment - Tests passed cleanly for me except for the known regression having to do with port numbers. Committed at subversion revision 964402.
          Hide
          Kathey Marsden added a comment -

          Reopen for backport

          Show
          Kathey Marsden added a comment - Reopen for backport
          Hide
          Mike Matrigali added a comment -

          backported to 10.6 and 10.5 branches. Resolving and resetting original owner back.

          Show
          Mike Matrigali added a comment - backported to 10.6 and 10.5 branches. Resolving and resetting original owner back.

            People

            • Assignee:
              Rick Hillegas
              Reporter:
              Rick Hillegas
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development