OpenJPA
  1. OpenJPA
  2. OPENJPA-612

Add support for calculating update value in QueryImpl.updateInMemory

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.2.0
    • Component/s: None
    • Labels:
      None

      Description

      Since Informix does not support update with in/exists subquery in the where clause, when doing the bulk update against informix, e.g.,

      "update DeptBeanAno d set d.budget = (d.budget * ?1 + ?2) where d.reportsTo.no = ?3"

      we encounter the error of "only-update-primitives" during updateInMemory.

      The attached patch fixes this problem by beefing up the support for arithmetic calcuation of the update value for updateInMemory.

      1. openjpa0528a.patch
        22 kB
        Fay Wang
      2. openjpa0526.patch
        12 kB
        Fay Wang
      3. openjpa.patch
        13 kB
        Fay Wang
      There are no Sub-Tasks for this issue.

        Activity

        Hide
        Albert Lee added a comment -

        I am wondering if evaluate() in the abstract base class should throw an exception rather than returning a null?

        Index: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java
        ===================================================================
        — openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java (revision 659216)
        +
        + public Object evaluate(Object value, Object ob, Object[] params,
        + OpenJPAStateManager sm)

        { + return null; + }

        Otherwise, val will be null and could it cause undesirable/different behavior for AbstractStoreQuery subclass that has no implementation and/or NPE further on?

        Index: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java
        ===================================================================
        — openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java (revision 659216)
        } else {

        • throw new UserException(_loc.get("only-update-primitives"));
          + try { + val = evaluate(value, ob, params, sm, q); + }

          catch (UnsupportedException e1)

          { + throw new UserException(_loc.get("fail-to-get-update-value")); + }

          }

        Albert Lee.

        Show
        Albert Lee added a comment - I am wondering if evaluate() in the abstract base class should throw an exception rather than returning a null? Index: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java =================================================================== — openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractStoreQuery.java (revision 659216) + + public Object evaluate(Object value, Object ob, Object[] params, + OpenJPAStateManager sm) { + return null; + } Otherwise, val will be null and could it cause undesirable/different behavior for AbstractStoreQuery subclass that has no implementation and/or NPE further on? Index: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java =================================================================== — openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java (revision 659216) } else { throw new UserException(_loc.get("only-update-primitives")); + try { + val = evaluate(value, ob, params, sm, q); + } catch (UnsupportedException e1) { + throw new UserException(_loc.get("fail-to-get-update-value")); + } } Albert Lee.
        Hide
        Fay Wang added a comment -

        This patch is per Albert's comments to throw UnsupportedException in AbstractStoreQuery.

        Show
        Fay Wang added a comment - This patch is per Albert's comments to throw UnsupportedException in AbstractStoreQuery.
        Hide
        Fay Wang added a comment -

        I have streamlined the code and added string function supports to the updateInMemory. The following queries have been tested against Informix backend:

        query="update DeptBeanAno d set d.name = CONCAT(d.name, '288') where d.reportsTo.no = ?1"
        query="update DeptBeanAno d set d.name = SUBSTRING(d.name, 1, LENGTH(d.name)) where d.reportsTo.no = ?1"
        query="update DeptBeanAno d set d.name = UPPER(d.name) where d.reportsTo.no = ?1"
        query="update DeptBeanAno d set d.name = LOWER(d.name) where d.reportsTo.no = ?1"
        query="update DeptBeanAno d set d.name = TRIM(LEADING ' ' FROM d.name) where d.reportsTo.no = ?1"
        query="update DeptBeanAno d set d.name = TRIM(TRAILING ' ' FROM d.name) where d.reportsTo.no = ?1"
        query="update DeptBeanAno d set d.name = TRIM(' ' FROM d.name) where d.reportsTo.no = ?1"
        query="update DeptBeanAno d set d.name = SUBSTRING(d.name, 1, LOCATE(d.name, 'e', 1)) where d.reportsTo.no = ?1"
        query="update DeptBeanAno d set d.idx = LOCATE(d.name, 'e', 3) where d.reportsTo.no = ?1"

        Show
        Fay Wang added a comment - I have streamlined the code and added string function supports to the updateInMemory. The following queries have been tested against Informix backend: query="update DeptBeanAno d set d.name = CONCAT(d.name, '288') where d.reportsTo.no = ?1" query="update DeptBeanAno d set d.name = SUBSTRING(d.name, 1, LENGTH(d.name)) where d.reportsTo.no = ?1" query="update DeptBeanAno d set d.name = UPPER(d.name) where d.reportsTo.no = ?1" query="update DeptBeanAno d set d.name = LOWER(d.name) where d.reportsTo.no = ?1" query="update DeptBeanAno d set d.name = TRIM(LEADING ' ' FROM d.name) where d.reportsTo.no = ?1" query="update DeptBeanAno d set d.name = TRIM(TRAILING ' ' FROM d.name) where d.reportsTo.no = ?1" query="update DeptBeanAno d set d.name = TRIM(' ' FROM d.name) where d.reportsTo.no = ?1" query="update DeptBeanAno d set d.name = SUBSTRING(d.name, 1, LOCATE(d.name, 'e', 1)) where d.reportsTo.no = ?1" query="update DeptBeanAno d set d.idx = LOCATE(d.name, 'e', 3) where d.reportsTo.no = ?1"
        Hide
        Catalina Wei added a comment -

        InMemoryUpdate support for Math function and String function evaluation are done.
        The remaining work for functions returning numeric value such as ABS, SQRT, SIZE etc. will be done on needed basis.
        A subtask will be opened for that.

        Show
        Catalina Wei added a comment - InMemoryUpdate support for Math function and String function evaluation are done. The remaining work for functions returning numeric value such as ABS, SQRT, SIZE etc. will be done on needed basis. A subtask will be opened for that.

          People

          • Assignee:
            Unassigned
            Reporter:
            Fay Wang
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development