Bug #48851 Ndbapi : Violated index not easily determined in duplicate key error situation
Submitted: 17 Nov 2009 20:53 Modified: 10 Dec 2009 15:43
Reporter: Frazer Clement Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Cluster: NDB API Severity:S3 (Non-critical)
Version:mysql-5.1-telco-6.2 OS:Any
Assigned to: Frazer Clement CPU Architecture:Any

[17 Nov 2009 20:53] Frazer Clement
Description:
When a table has more than one unique index, and a DML operation fails due to a uniqueness violation, it is not clear how to determine which of the constraints caused the failure.

 

How to repeat:
CREATE TABLE T1 (a int primary key,
                 b int,
                 c int,
                 d int,
                 unique(c),
                 unique(d)) engine=ndb;

// In NdbApi :

INSERT INTO T1 VALUES (1,1,1,1);
INSERT INTO T1 VALUES (2,2,2,2);

UPDATE T1 SET c = 3, d = 1 WHERE a = 2; // Fails

// How to determine that the constraint on d caused the failure?

Suggested fix:
Document how the violated constraint can be determined.
[3 Dec 2009 8:21] Martin Zaun
Hi Frazer, great you implemented this.  Some comments on the API.

My summary on function signature and its Java mapping: +1
=> local optimum: better than any signature alternative I can think of
- usage: sufficient
- consistency: better fit into existing usage patterns
- not a high-level, end-user interface anyway (e.g., maps to ByteBuffer)
- very easy to map, won't take me long to implement
- not super Java-mapping-efficient but not worse than the alternatives
- as you pointed out, no need to optimize performance for the error path

Details on the signature and mapping:
- maps to: String getNdbErrorDetail(NdbErrorConst, ByteBuffer, int)

- mem contract: caller allocates & releases message buffer
  - ok but not great, due to actual message length unknown to caller
  - only theoretical potential for message truncation (or over-allocation)
  - fits existing patterns

- alternative: callee allocates & caller releases ?
  - inconsistent with existing patterns
  - error-prone
  - difficult to map to Java

- alternative: statically allocated message buffer ?
  - bad, prohibits multi-threading

- alternative: message buffer managed by object XXX ?
  - existing pattern for more complex objects like Operations etc
  - needs to be documented
  - not clear at first sight what the natural managing object would be
  - single-threaded usage
  - error-prone since caller's reference becomes invalid at some point
  - caller will likely have to copy message

- return type:
  - null-terminated 'const char *' will be utf8-converted to Java String
  - content- but not format-redundant: message in ByteBuffer and as String

- alternative: status code
  - caller would have to decode buffer into String requiring a bit of code
  - only useful more status/error information to be provided to caller

- separate length and pointer parameters (instead of, say, a vector class):
  - error-prone (also, difficult for JTie to apply consistency checks)
  - but existing, dominant pattern in NDBAPI and C in general
  - just checking: Is Uint32 the predominant length-type in NDBAPI ?

- on splitting/merging db, schema, table, index etc:
  - can be added by documenting message format/convention
  - if not sufficient, should be rather addressed API-wide than ad-hoc for
    - caller-defined formatting of messages
    - internationalization/localization of messages

- on the doxygen function header comment: would mention that
  - return value is passed buffer (i.e., NULL if passed NULL)

Will be happy to have a look at the implementation tomorrow, but doubt I'll find or have much to contribute.

Regards, Martin
[3 Dec 2009 9:49] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/92622

3042 Frazer Clement	2009-12-03
      Bug#48851 : Ndbapi : Violated index not easily determined in duplicate key error situation
      modified:
        storage/ndb/include/ndbapi/Ndb.hpp
        storage/ndb/include/ndbapi/NdbDictionary.hpp
        storage/ndb/include/ndbapi/NdbError.hpp
        storage/ndb/src/ndbapi/Ndb.cpp
        storage/ndb/src/ndbapi/NdbDictionary.cpp
        storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
        storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
        storage/ndb/test/ndbapi/testIndex.cpp
        storage/ndb/test/run-test/daily-basic-tests.txt
[3 Dec 2009 11:45] Bugs System
Pushed into 5.1.39-ndb-7.1.0 (revid:frazer@mysql.com-20091203114326-bmahiezacu5s71qs) (version source revid:frazer@mysql.com-20091203114326-bmahiezacu5s71qs) (merge vers: 5.1.39-ndb-7.1.0) (pib:13)
[3 Dec 2009 18:46] Frazer Clement
Fix pushed to 6.2.19, 6.3.29, 7.0.10, 7.1.0
[7 Dec 2009 11:58] Frazer Clement
Second patch to add max-buffer length constant.

Attachment: bug48851-2.patch (text/x-patch), 1.54 KiB.

[8 Dec 2009 11:39] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/93161

3048 Frazer Clement	2009-12-08
      Bug#48851 : Use BaseString::split() correctly
      modified:
        storage/ndb/src/ndbapi/Ndb.cpp
[8 Dec 2009 12:36] Bugs System
Pushed into 5.1.39-ndb-7.1.0 (revid:frazer@mysql.com-20091208123451-i9y1rcmfy6r720tv) (version source revid:frazer@mysql.com-20091208123451-i9y1rcmfy6r720tv) (merge vers: 5.1.39-ndb-7.1.0) (pib:13)
[8 Dec 2009 12:37] Bugs System
Pushed into 5.1.39-ndb-7.0.10 (revid:frazer@mysql.com-20091208122928-rghq27rk7eqgt1sv) (version source revid:frazer@mysql.com-20091208122928-rghq27rk7eqgt1sv) (merge vers: 5.1.39-ndb-7.0.10) (pib:13)
[8 Dec 2009 12:40] Bugs System
Pushed into 5.1.39-ndb-6.2.19 (revid:frazer@mysql.com-20091208113909-tbiws9qtw5j06gzs) (version source revid:frazer@mysql.com-20091208113909-tbiws9qtw5j06gzs) (merge vers: 5.1.39-ndb-6.2.19) (pib:13)
[8 Dec 2009 12:40] Bugs System
Pushed into 5.1.39-ndb-6.3.29 (revid:frazer@mysql.com-20091208121058-cr2c2sij4vwodgpl) (version source revid:frazer@mysql.com-20091208121058-cr2c2sij4vwodgpl) (merge vers: 5.1.39-ndb-6.3.29) (pib:13)
[8 Dec 2009 13:59] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/93199

3181 Martin Skold	2009-12-08 [merge]
      Merge
      modified:
        configure.in
        mysql-test/std_data/ndb_config_mycnf1.cnf
        mysql-test/suite/ndb/r/ndb_config.result
        mysql-test/suite/ndb/t/ndb_config.test
        sql/ha_ndbcluster_binlog.cc
        storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
        storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
        storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
        storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
        storage/ndb/src/ndbapi/Ndb.cpp
        storage/ndb/test/ndbapi/testBlobs.cpp
[10 Dec 2009 15:43] Jon Stephens
Documented in the NDB-6.2.19, 6.3.29, and 7.0.10 changelogs, as follows:

        When a DML operation failed due to a uniqueness violation on a
        table having more than one unique index, it was difficult to
        determine which constraint caused the failure; it was necessary
        to obtain an NdbError object, then decode its details property,
        which in some instances could be NULL, and which in any case
        could lead to memory management issues in application code.

        To help solve this problem, a new API method
        Ndb::getNdbErrorDetail() is added, providing a well-formatted
        string containing more precise information about the index that
        caused the unque constraint violation. The following additional changes
        are also made in the NDB API:

          ·NdbError.details is now deprecated in favor of the new method.

          ·The Dictionary::listObjects() method has been extended to 
          provide more information.

        For more information, see 'The Ndb::getErrorDetail() Method', 
        'The NdbError Structure', and 'The Dictionary::listObjects() 
        Method'.

Also: Added description of new method to Ndb class documentation, updated NdbError and Dictionary::listObjects() descriptions.

Closed.