Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

  • edulid
    started a topic allowMultiupdate

    allowMultiupdate

    If you forget to write in a server-side DSRequest "allowMultiupdate(true)" together with an update all records are updated!
    Example:

    Code:
    DSRequest updateReq = new DSRequest("myDS", DataSource.OP_UPDATE, rpcManager);
    
    List<Criterion> criterions = new ArrayList<>();
    Criterion c = new SimpleCriterion("myCriteria", DefaultOperators.Equals, 1);
    criterions.add(c);
    
    AdvancedCriteria ac = new AdvancedCriteria(DefaultOperators.Or, criterions.toArray(new Criterion[] {}));
    updateReq.setAllowMultiUpdate(true);
    
    Map<String, Object> clearedValues = new HashMap<>();
    
    clearedValues.put("f_myValue", null);
    updateReq.setValues(clearedValues);
    updateReq.setAdvancedCriteria(ac);
    updateReq.execute();
    This creates (correctly) the following sql:
    Code:
     UPDATE myTable SET f_myValue=NULL WHERE ( myCriteria = 1) ;
    If I comment out "updateReq.setAllowMultiUpdate(true);" I get the following sql:
    Code:
     UPDATE myTable SET f_myValue=NULL WHERE ('1'='1')
    so this means setting setAllowMultiUpdate(false) updates ALL the records ! Is this by-design? Isn't this a contradiction?

    Using smartgwt 6.1p power 6.1-p20180208
    Last edited by edulid; 25th Mar 2018, 07:17.

  • edulid
    replied
    Hi Isomorphic

    yes, thanks, it seems to work now.
    This is my output now.
    java.lang.Exception: Received null criteria for update operation - would update all records - ignoring.
    Last edited by edulid; 28th Mar 2018, 04:23.

    Leave a comment:


  • Isomorphic
    replied
    Please try again with 28-03 build. Most likely the fix did not make it into 27-03 build. Also, please make sure that your code uses the intended build exactly to exclude possible miss-dependency issues.
    Last edited by Isomorphic; 28th Mar 2018, 02:52.

    Leave a comment:


  • edulid
    replied
    Hi Isomorphic
    the testcase in #3 is still creating

    UPDATE minimalTestcase SET f_firstname=NULL WHERE ('1'='1')

    with the 27-03 builds.
    Last edited by edulid; 27th Mar 2018, 05:12.

    Leave a comment:


  • Isomorphic
    replied
    Our automated tests covered many different cases of detecting nested AdvancedCriteria to make sure a primaryKey was always included, and correctly removing extraneous criteria, and other edge cases, but did not cover the case where our own criteria-simplifying logic could lead to a request that, once simplified, was then invalid. Definitely a lesson in which and how many tests to write.

    Leave a comment:


  • edulid
    replied
    Hi Isomorphic
    thank you, I will check with the new builds.
    Why didn't the autotests you mentioned catch this error?

    Leave a comment:


  • Isomorphic
    replied
    This is fixed and will be available for download in nightly builds since Mar 27 (tomorrow).

    Leave a comment:


  • edulid
    replied
    Hi @Isomorphic,

    as you requested, I tested with the newest nightly: 2018-03-22

    and I get exactly the same results:
    UPDATE minimalTestcase SET f_firstname=NULL WHERE ('1'='1')

    Leave a comment:


  • edulid
    replied
    Hi Isomorphic

    this seems not to be the case in my simple testcase:

    It relies on the following table:
    Code:
    create table minimalTestcase
    (f_id int identity(1,1) primary key,
    f_lastname varchar(50) null,
    f_firstname varchar(50) null
    );
    
    insert into minimalTestcase (f_lastname, f_firstname) values ('A', 'X');
    insert into minimalTestcase (f_lastname, f_firstname) values ('B', 'Y');
    insert into minimalTestcase (f_lastname, f_firstname) values ('C', 'Z');
    and the following minimalTestcase.ds.xml:
    Code:
    <DataSource ID="minimalTestcase" serverType="sql" tableName="minimalTestcase">
    <fields>
       <field name="f_id" type="integer" primaryKey="true" />
       <field name="f_lastname" type="text" />
       <field name="f_firstname" type="text" />
    </fields>
    </DataSource>
    1. With the following server-side code:
    Code:
    public DSResponse doCallServer(DSRequest dsRequest, HttpServletResponse servletResponse, RPCManager rpcManager) throws Exception {
    
            System.out.println("doCallServer");
    
            DSRequest updateReq = new DSRequest("minimalTestcase", DataSource.OP_UPDATE, rpcManager);
    
            List<Criterion> criterions = new ArrayList<>();
            Criterion c = new SimpleCriterion("f_lastname", DefaultOperators.Equals, 'A');
            criterions.add(c);
    
            AdvancedCriteria ac = new AdvancedCriteria(DefaultOperators.Or, criterions.toArray(new Criterion[] {}));
            updateReq.setAllowMultiUpdate(true);
    
            Map<String, Object> clearedValues = new HashMap<>();
    
            clearedValues.put("f_firstname", null);
            updateReq.setValues(clearedValues);
            updateReq.setAdvancedCriteria(ac);
            updateReq.execute();
    
            return new DSResponse();
        }
    I get:
    Code:
    UPDATE minimalTestcase SET f_firstname=NULL WHERE (minimalTestcase.f_lastname = 'A' AND minimalTestcase.f_lastname IS NOT NULL)
    2. while only commenting setAllowMultiUpdate(true), thus with the following code:

    Code:
    public DSResponse doCallServer(DSRequest dsRequest, HttpServletResponse servletResponse, RPCManager rpcManager) throws Exception {
    
            System.out.println("doCallServer");
    
            DSRequest updateReq = new DSRequest("minimalTestcase", DataSource.OP_UPDATE, rpcManager);
    
            List<Criterion> criterions = new ArrayList<>();
            Criterion c = new SimpleCriterion("f_lastname", DefaultOperators.Equals, 'A');
            criterions.add(c);
    
            AdvancedCriteria ac = new AdvancedCriteria(DefaultOperators.Or, criterions.toArray(new Criterion[] {}));
    //        updateReq.setAllowMultiUpdate(true);
    
            Map<String, Object> clearedValues = new HashMap<>();
    
            clearedValues.put("f_firstname", null);
            updateReq.setValues(clearedValues);
            updateReq.setAdvancedCriteria(ac);
            updateReq.execute();
    
            return new DSResponse();
        }
    I get:
    Code:
    UPDATE minimalTestcase SET f_firstname=NULL WHERE ('1'='1')
    I didn't change defaultMultiUpdatePolicy anywhere. It has all default settings.

    Leave a comment:


  • Isomorphic
    replied
    Updates without primary key are not allowed, and we have multiple autotests verifying this. You may have changed the DataSource.defaultMultiUpdatePolicy, or perhaps changed it system-wide?

    Note also, you can only get that 1=1 effect if you specify invalid criteria (eg field does not exist), so there is a second error here too.

    Leave a comment:

Working...
X