Skip to content

UniDAC: index descriptions fail without an IndexInfoTemplate, and TBoldUniDACTable leaks its TUniTable #116

Open

Description

@bero

On the UniDAC adapter, index descriptions fail for every engine without an IndexInfoTemplate, SQLite among them, and TBoldUniDACTable never frees the TUniTable it wraps. Found while adding the UniDAC twin of the evolutor tests for #112.

Symptom

  • On UniDAC with SQLite (dbeGenericANSISQL92), every IBoldDatabase.GetIndexDescriptions call raises TBoldUniDACTable.GetIndexDefs: not supported/implemented. The database evolutor (TBoldDataBaseEvolutor.CalculateScript) and the structure validator's index check cannot run there.
  • After such a run, FastMM reports the internals of a TUniTable as leaked (TFieldDefs, TUniDataSetOptions, TUniParams, ...).

On UniDAC with SQL Server and PostgreSQL the same tests pass: those engines have an IndexInfoTemplate and never reach the table path.

Root cause

  1. TBoldDatabaseWrapper.GetIndexDescriptions (Source/Persistence/DB/BoldDBInterfaces.pas) falls back to GetIndexDescriptionsViaTable when SQLDatabaseConfig.IndexInfoTemplate is empty. That reads IBoldTable.IndexDefs, and TBoldUniDACTable.GetIndexDefs (Source/Persistence/UniDAC/BoldUniDACInterfaces.pas) raises EBold unconditionally. On FireDAC the same fallback works through TFDTable.IndexDefs.
  2. TBoldUniDACTable has no destructor. TBoldUniDACConnection.GetTable creates its TUniTable without an owner, so neither ReleaseTable (when the cache is occupied) nor ReleaseCachedObjects frees the dataset when it frees the wrapper. TBoldFireDACTable.Destroy frees its TFDTable.

Change

  • TBoldUniDACTable: a destructor frees the wrapped TUniTable, like TBoldFireDACTable.
  • Index descriptions on SQLite: TBoldUniDACConnection overrides GetIndexDescriptions. On the SQLite provider without an IndexInfoTemplate it reads pragma_index_list and pragma_index_info (UniDAC datasets have no IndexDefs, so implementing GetIndexDefs would have meant building them from metadata). The index with origin pk is the primary key. An INTEGER PRIMARY KEY has no index (it is the rowid alias), so it is added from pragma_table_info under the constraint name in sqlite_master, as SQLite: Bold sees no primary key, so evolve re-plans the BOLD_ID indexes and cannot move data #110 does on FireDAC.
  • Other UniDAC providers without an IndexInfoTemplate keep the table path and still raise in GetIndexDefs, as before.

Commit: 0426f46

Testing

  • Test.BoldDbEvolutorUniDAC (Run the test suite on PostgreSQL in run_matrix.ps1 (UniDAC first) #112) green on UniDAC x SQLite: 5/5 with UniDAC 11.0.1. The early pass that named this issue is gone.
  • No leak: the new TestFreedTablesFreeTheirTUniTable frees table wrappers both ways (ReleaseTable with an occupied cache, ReleaseCachedObjects) and failed before the fix with 4 leaked TUniTables. Matrix green: FireDAC 2224 on SQLite and SQL Server; UniDAC 2243 on SQLite and SQL Server with -UniDACFull; UniDAC x PostgreSQL 19; vendored UniDAC 10.4 on Delphi 12 green as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions