Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-5027

Remove a row from a QSqlRelationalTableModel fails

    XMLWordPrintable

Details

    • Bug
    • Resolution: Out of scope
    • P4: Low
    • Some future release
    • 4.5.2
    • SQL Support
    • None

    Description

      Platform
      Linux
      Platform details
      cat /proc/version
      Linux version 2.6.28 (root@tux) (gcc version 4.3.2 (GCC) ) #2 SMP PREEMPT Sun Apr 19 17:33:52 CEST 2009
      glibc 2.7
      gcc 4.3.3
      uname -m
      i686
      Compilers
      GCC
      Compiler details
      gcc version 4.3.3

      Steps to reproduce / test case
      Given is a small database schema consisting of three tables. First table ("products") consists of two columns "id" and "name". "id" is the primary key. The second table ("parts") looks exactly the same. The third table ("parts_used_by_product") is used to model a n:m relation between both tables. It consists of two columns which together form the primary key of that table and are each a foreign key to "products" and to "parts". See "dbschema.sql" in the attached example for details. If an instance of QSqlRelationalTableModel is used on the table "parts_used_by_products", and via QSqlRelation the second column is mapped to the table "parts", a call to "removeRow()" of that model will fail. Even worse, the call returns true, but does not remove the record from the database. On stderr the program writes:
      "QSqlQuery::value: not positioned on a valid record"

      If the QSqlRelationalTableModel instance is replaced with an instance of QSqlTable model, everything works fine. I tried it with a sqlite3 database and also with a postgres 8.3 database, with the same result so I dont't think there's a problem with the used DBMS. Please see the attached example program for better understanding.

      There might be a problem in "qsqltablemodel.cpp" in line 236. Snipped is from Qt 4.5.2 as shipped with qtsdk 2009.03.

       
      QSqlRecord QSqlTableModelPrivate::primaryValues(int row) 
      { 
          QSqlRecord record; 
          if (!query.seek(row)) { 
              error = query.lastError(); 
              return record; 
          } 
          if (primaryIndex.isEmpty()) { 
              record = rec; 
          for (int i = 0; i < record.count(); ++i) 
              record.setValue(i, query.value(i)); 
          } else { 
              record = primaryIndex; 
              for (int i = 0; i < record.count(); ++i) 
                  record.setValue(i, query.value(rec.indexOf(record.fieldName(i))));   <------236
          } 
          return record; 
      }
      

      There seem to be two problems:

      1. "record" containts the field names "products_id" and "parts_id", but "rec" contains "products_id" and "name". So the value for
        the second field is always an empty QVariant which leads later to a SQL command like this: "DELETE FROM parts_used_by_product WHERE products_id = 1 AND parts_id IS NULL;" This statement will not delete any rows ever, because parts_id is never NULL.
      2. "query" contains not the two numeric fields from table "parts_used_by_product" but the first numeric column and the textual replacement for the second column defined via the QSqlRelation. So even if first is fixed, the call to "removeRows()" would still fail.

      The SQL used by "query" for reference:

      SELECT "parts_used_by_product"."products_id", "relTblAl_1"."name" FROM 
      "parts_used_by_product", "parts" "relTblAl_1" WHERE 
      ("parts_used_by_product"."parts_id" = "relTblAl_1"."id") AND (products_id = 1) 
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            mabrand Mark Brand
            dajansen Damian Jansen (closed Nokia identity) (Inactive)
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes