[tinysql] [Fwd: tinySQL and locking?]

Thomas Siedschlag thomas.siedschlag@x-cellent.com
Tue, 23 Mar 2004 14:05:22 +0100


Hi,

thank you for your answers.

> the DBF-type field is a combined field:
> 
> bit 0-2 describe the DBase-Version used
> bit 3 indicates whether the memo-field is used
> bit 4-6 are reserved for SQL (no clue what that part of the specs
> really means)
> bit 7 also indicates that the file is a dBaseIII with memos
> 
> Source:
> http://www.dbase.com/KnowledgeBase/int/db7_file_fmt.htm
> 

I don't understand the reserved bits for the SQL support too. But I was
wondering, why doesn't exist a DBF-type in tinySQL for a normal DBase4
version (without SQL and memos), and therefore I expect a DBF-type field
with 0x04h.

I wrote some test programs with tinySQL and I found two possible bugs.
Maybe soemone have time to reproduce this.

1. Delete Statement

If I execute a delete statement on a DBF file, then the affected rows
shouldn't deleted physical, but should marked with an asterisk to
indicate a deletion. But I found a 0x00h 0x2Ah instead of a simple 0x2Ah
at the affected positions. You can find in the dbfFileTable.java

   public void deleteRow(int row) throws tinySQLException
   {
     if (row >= getRowCount())
       throw new tinySQLException("Row is >= rowcount");
     try
     {
       deletedRows[row] = ROW_DELETED;
       ftbl.seek(calcRowPos(row));
       ftbl.writeChar(RECORD_IS_DELETED);
     }
     catch (IOException ioe)
     {
       throw new tinySQLException("Unable to delete record " + row);
     }
   }

The RandomAccesFile.writeChar() writes a two-byte value! You should
better use RandomAccesFile.writeByte().

2. Select with Where

I have a select statement something like that

SELECT * FROM person WHERE surname='xxxxx'

If I execute this, I was wondering, why I got no results, although in
the DBF-file records exist, which match the 'where' clause.

I think the bug is in the WhereClause.java.

   public boolean isMatch(tsRow matchRow) throws tinySQLException
   {
     boolean reevaluate = false;

     if (tableColumns.size() > 0)
     {
       /**
        * fill cache on start needed
        */
       if (cache == null)
       {
         cache = new Object[tableColumns.size()];
         cachePos = new int[tableColumns.size()];

         int size = cache.length;
         for (int i = 0; i < size; i++)
         {
           tsColumn col = (tsColumn) tableColumns.elementAt(i);
           int idx = matchRow.findColumn(col.getPhysicalName());

           cachePos[i] = idx;
           cache[i] = matchRow.get(idx);
         }
         reevaluate = true;
       }
       else
       {
         int size = cache.length;
         for (int i = 0; i < size; i++)
         {
           int idx = cachePos[i];
           Object myObject = cache[i];
           Object rowObject = matchRow.get(i);
// --> Bug: should be: Object rowObject = matchRow.get(idx);

           // O1 and O2 should be the same type, so try an equals
           if (rowObject != null)
           {
             if (myObject != null)
             {

               if ((rowObject != myObject) &&
(rowObject.equals(myObject) == false))
               {
                 cache[i] = rowObject;
                 reevaluate = true;
               }
             }
             else
             {
               cache[i] = rowObject;
               reevaluate = true;
             }
           }
         }
       }
     }
     else
     {
       if (!evaluatedOnce)
       {
         reevaluate = true;
       }
     }
     if (reevaluate)
     {
       evaluatedOnce = true;
       Boolean b =
ParserUtils.convertToBoolean(expression.evaluate(matchRow));
       lastReturnValue = b.booleanValue();
     }
     return lastReturnValue;
   }

In isMatch() the cache column is compared with a potential wrong column
value of tha actual row. This may lead to wrong results, because the
cache compare matchs, although the actual row would return a different
result as the 'lastReturnValue'.


Regards
-- 
Thomas Siedschlag
x-cellent technologies GmbH
Rosenkavalierplatz 5
81925 Muenchen
Germany
e-mail thomas.siedschlag@x-cellent.com
http://www.x-cellent.com