diff --git a/sql/inc/TSQLClassInfo.h b/sql/inc/TSQLClassInfo.h
index 81576a9b2d738d44066c567b786cd62cee86c59a..a084dba85ad09d4b72291027cb46dbeed194c7f0 100644
--- a/sql/inc/TSQLClassInfo.h
+++ b/sql/inc/TSQLClassInfo.h
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLClassInfo.h,v 1.2 2005/11/22 20:42:36 pcanal Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLClassInfo.h,v 1.3 2005/12/07 14:59:57 rdm Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -38,7 +38,7 @@ public:
    virtual ~TSQLClassInfo();
    
    virtual const char* GetName() const { return fClassName.Data(); }
-   Int_t GetClassVarsion() const { return fClassVersion; }
+   Int_t GetClassVersion() const { return fClassVersion; }
    
    const char* GetClassTableName() const { return fClassTable.Data(); }
    const char* GetRawTableName() const { return fRawTable.Data(); }
diff --git a/sql/inc/TSQLFile.h b/sql/inc/TSQLFile.h
index 46cd185247112721fea77f9e8bb8c9cdf90f0067..407bfae97e042a7d8a71ec3ce78684f6fc13e667 100644
--- a/sql/inc/TSQLFile.h
+++ b/sql/inc/TSQLFile.h
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLFile.h,v 1.6 2005/12/07 14:59:57 rdm Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLFile.h,v 1.7 2006/02/01 18:57:41 pcanal Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -29,12 +29,12 @@ class TStreamerElement;
 class TStreamerInfo;
 
 class TSQLServer;
+class TSQLStatement;
 class TSQLResult;
 class TSQLRow;
 class TKeySQL;
 class TBufferSQL2;
 class TSQLClassInfo;
-class TSQLObjectData;
 
 class TSQLFile : public TFile {
     
@@ -96,6 +96,7 @@ protected:
    TSQLClassInfo*    FindSQLClassInfo(const char* clname, Int_t version);
    TSQLClassInfo*    RequestSQLClassInfo(const char* clname, Int_t version, Bool_t force = kFALSE);
    TSQLClassInfo*    RequestSQLClassInfo(const TClass* cl, Bool_t force = kFALSE);
+   Bool_t            SyncSQLClassInfoRawTables(TSQLClassInfo* sqlinfo, Bool_t hasrawdata);
    Bool_t            SyncSQLClassInfo(TSQLClassInfo* sqlinfo, TObjArray* columns, Bool_t hasrawdata);
    Bool_t            ProduceClassSelectQuery(TStreamerInfo* info, TSQLClassInfo* sqlinfo, TString& columns, TString& tables, Int_t& tablecnt);
 
@@ -112,7 +113,7 @@ protected:
    TSQLResult*       GetNormalClassData(Long64_t objid, TSQLClassInfo* sqlinfo);
    TSQLResult*       GetNormalClassDataAll(Long64_t minobjid, Long64_t maxobjid, TSQLClassInfo* sqlinfo);
    TSQLResult*       GetBlobClassData(Long64_t objid, TSQLClassInfo* sqlinfo);
-   TSQLObjectData*   GetObjectClassData(Long64_t objid, TSQLClassInfo* sqlinfo);
+   TSQLStatement*    GetBlobClassDataStmt(Long64_t objid, TSQLClassInfo* sqlinfo);
    Long64_t          StoreObjectInTables(Long64_t keyid, const void* obj, const TClass* cl);
    Bool_t            WriteSpecialObject(Long64_t keyid, TObject* obj, const char* name, const char* title);
    TObject*          ReadSpecialObject(Long64_t keyid, TObject* obj = 0);
@@ -224,6 +225,7 @@ public:
    Bool_t            IsMySQL() const;
    virtual Bool_t    IsOpen() const;
    Bool_t            IsOracle() const;
+   Bool_t            IsODBC() const;
 
    virtual void      MakeFree(Long64_t, Long64_t) {}
    virtual void      MakeProject(const char *, const char* ="*", Option_t* ="new") {} // *MENU*
diff --git a/sql/inc/TSQLObjectData.h b/sql/inc/TSQLObjectData.h
index 3b0b5ae59968c3d7db047ef160919346437a7bdb..84a61e9817856243ead7709f8ec7629c5a13d0d9 100644
--- a/sql/inc/TSQLObjectData.h
+++ b/sql/inc/TSQLObjectData.h
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLObjectData.h,v 1.6 2006/05/11 10:29:45 brun Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLObjectData.h,v 1.7 2006/05/12 08:17:02 brun Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -33,6 +33,7 @@ class TList;
 class TSQLClassInfo;
 class TSQLResult;
 class TSQLRow;
+class TSQLStatement;
 
 
 class TSQLObjectInfo : public TObject {
@@ -68,7 +69,8 @@ public:
                   Long64_t       objid,
                   TSQLResult*    classdata,
                   TSQLRow*       classrow,
-                  TSQLResult*    blobdata);
+                  TSQLResult*    blobdata,
+                  TSQLStatement* blobstmt);
    
    virtual ~TSQLObjectData();
    
@@ -84,33 +86,35 @@ public:
    
    const char*       GetValue() const { return fLocatedValue; }
    const char*       GetColumnName() const { return fLocatedField; }
-   const char*       GetBlobName1() const { return fBlobName1.Data(); }
-   const char*       GetBlobName2() const { return fBlobName2.Data(); }
+   const char*       GetBlobPrefixName() const { return fBlobPrefixName; }
+   const char*       GetBlobTypeName() const { return fBlobTypeName; }
    
    Bool_t            VerifyDataType(const char* tname, Bool_t errormsg = kTRUE);
    Bool_t            PrepareForRawData();
    
 protected: 
    Bool_t            ExtractBlobValues();
+   Bool_t            ShiftBlobRow();
    
    Int_t             GetNumClassFields();
    const char*       GetClassFieldName(Int_t n);
    
-   TSQLClassInfo*    fInfo;          //!
-   Long64_t          fObjId;         //!
-   Bool_t            fOwner;         //!
-   TSQLResult*       fClassData;     //!
-   TSQLResult*       fBlobData;      //!
-   Int_t             fLocatedColumn; //!
-   Int_t             fLocatedBlob;   //!
-   TSQLRow*          fClassRow;      //!
-   TSQLRow*          fBlobRow;       //!
-   const char*       fLocatedField;  //!
-   const char*       fLocatedValue;  //!
-   Bool_t            fCurrentBlob;   //!
-   TString           fBlobName1;     //!
-   TString           fBlobName2;     //!
-   TObjArray*        fUnpack;        //! 
+   TSQLClassInfo*    fInfo;           //!
+   Long64_t          fObjId;          //!
+   Bool_t            fOwner;          //!
+   TSQLResult*       fClassData;      //!
+   TSQLResult*       fBlobData;       //!
+   TSQLStatement*    fBlobStmt;      //!
+   Int_t             fLocatedColumn;  //!
+   Int_t             fLocatedBlob;    //!
+   TSQLRow*          fClassRow;       //!
+   TSQLRow*          fBlobRow;        //!
+   const char*       fLocatedField;   //!
+   const char*       fLocatedValue;   //!
+   Bool_t            fCurrentBlob;    //!
+   const char*       fBlobPrefixName; //! name prefix in current blob row
+   const char*       fBlobTypeName;   //! name type (without prefix) in current blob row
+   TObjArray*        fUnpack;         //! 
    
    ClassDef(TSQLObjectData, 1) // Keeps the data requested from the SQL server for an object.
       
@@ -136,7 +140,7 @@ protected:
    Bool_t            fIsMoreRows;    //!  indicates if class data has not yet read rows
    TList*            fRowsPool;      //!  pool of extrcted, but didnot used rows
 
-ClassDef(TSQLObjectDataPool,1) //XML object keeper class     
+   ClassDef(TSQLObjectDataPool,1) // XML object keeper class     
     
 };
 
diff --git a/sql/src/TBufferSQL2.cxx b/sql/src/TBufferSQL2.cxx
index 6954b24bc2a7d46b4ec1724d67fc227f4e06711e..a3415d13b0a79a732e3093887dd6bde9c2df070d 100644
--- a/sql/src/TBufferSQL2.cxx
+++ b/sql/src/TBufferSQL2.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TBufferSQL2.cxx,v 1.10 2006/04/12 20:54:30 rdm Exp $
+// @(#)root/sql:$Name:  $:$Id: TBufferSQL2.cxx,v 1.11 2006/05/11 10:29:45 brun Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -238,45 +238,60 @@ Bool_t TBufferSQL2::SqlObjectInfo(Long64_t objid, TString& clname, Version_t& ve
 //______________________________________________________________________________
 TSQLObjectData* TBufferSQL2::SqlObjectData(Long64_t objid, TSQLClassInfo* sqlinfo)
 {
-   //please Sergey document this function
-   if (!sqlinfo->IsClassTableExist()) 
-      return fSQL->GetObjectClassData(objid, sqlinfo); 
+   // creates TSQLObjectData for specifed object id and specified class
+   // Object data for each class can be stored in two different tables.
+   // First table contains data in column-wise form for simple types like integer, 
+   // strings and so on when second table contains any other data which cannot
+   // be converted into column-wise representation. 
+   // TSQLObjectData will contain results of the requests to both such tables for 
+   // concrete object id.
    
-   TSQLObjectDataPool* pool = 0;
+   TSQLResult *classdata = 0;   
+   TSQLRow *classrow = 0;
    
-   if (fPoolsMap!=0)
-      pool = (TSQLObjectDataPool*) fPoolsMap->GetValue(sqlinfo);
+   if (sqlinfo->IsClassTableExist()) {
+   
+      TSQLObjectDataPool* pool = 0;
+   
+      if (fPoolsMap!=0)
+        pool = (TSQLObjectDataPool*) fPoolsMap->GetValue(sqlinfo);
+      
+      if ((pool==0) && (fLastObjId>=fFirstObjId)) {
+         if (gDebug>4) Info("SqlObjectData","Before request to %s",sqlinfo->GetClassTableName());
+         TSQLResult *alldata = fSQL->GetNormalClassDataAll(fFirstObjId, fLastObjId, sqlinfo);
+         if (gDebug>4) Info("SqlObjectData","After request res = %x",alldata);
+         if (alldata==0) {
+            Error("SqlObjectData","Cannot get data from table %s",sqlinfo->GetClassTableName());
+            return 0;
+         }
    
-   if ((pool==0) && (fLastObjId>=fFirstObjId)) {
-      if (gDebug>4) Info("SqlObjectData","Before request to %s",sqlinfo->GetClassTableName());
-      TSQLResult *alldata = fSQL->GetNormalClassDataAll(fFirstObjId, fLastObjId, sqlinfo);
-      if (gDebug>4) Info("SqlObjectData","After request res = %x",alldata);
-      if (alldata==0) {
-         Error("SqlObjectData","Cannot get data from table %s",sqlinfo->GetClassTableName());
+         if (fPoolsMap==0) fPoolsMap = new TMap();
+         pool = new TSQLObjectDataPool(sqlinfo, alldata);
+         fPoolsMap->Add(sqlinfo, pool);
+      }
+   
+      if (pool==0) return 0;
+   
+      if (pool->GetSqlInfo()!=sqlinfo) {
+         Error("SqlObjectData","Missmatch in pools map !!! CANNOT BE !!!");
          return 0;
       }
+   
+      classdata = pool->GetClassData();
+      
+      classrow = pool->GetObjectRow(objid);
+      if (classrow==0) {
+         Error("SqlObjectData","Can not find row for objid = %lld in table %s", objid, sqlinfo->GetClassTableName());
+         return 0;
+      }
+   }   
+   
+   TSQLResult *blobdata = 0;
+   TSQLStatement* stmt = fSQL->GetBlobClassDataStmt(objid, sqlinfo);
 
-      if (fPoolsMap==0) fPoolsMap = new TMap();
-      pool = new TSQLObjectDataPool(sqlinfo, alldata);
-      fPoolsMap->Add(sqlinfo, pool);
-   }
-
-   if (pool==0) return 0;
-
-   if (pool->GetSqlInfo()!=sqlinfo) {
-      Error("SqlObjectData","Missmatch in pools map !!! CANNOT BE !!!");
-      return 0;
-   }
-
-   TSQLResult *classdata = pool->GetClassData();
+   if (stmt==0) blobdata = fSQL->GetBlobClassData(objid, sqlinfo);
    
-   TSQLRow* row = pool->GetObjectRow(objid);
-   if (row==0) {
-      Error("SqlObjectData","Can not find row for objid = %lld in table %s", objid, sqlinfo->GetClassTableName());
-      return 0;
-   }
-   TSQLResult *blobdata = fSQL->GetBlobClassData(objid, sqlinfo);
-   return new TSQLObjectData(sqlinfo, objid, classdata, row, blobdata);
+   return new TSQLObjectData(sqlinfo, objid, classdata, classrow, blobdata, stmt);
 }
 
 //______________________________________________________________________________
@@ -349,9 +364,6 @@ void* TBufferSQL2::SqlReadObject(void* obj, TClass** cl, TMemberStreamer *stream
 {
    // Read object from the buffer
 
-   if (gDebug>2)
-      cout << "TBufferSQL2::SqlReadObject " << fCurrentData->GetBlobName2() << endl;
-
    if (cl) *cl = 0;
 
    if (fErrorFlag>0) return obj;
@@ -368,6 +380,9 @@ void* TBufferSQL2::SqlReadObject(void* obj, TClass** cl, TMemberStreamer *stream
    Long64_t objid = -1;
    sscanf(refid, FLong64, &objid);
 
+   if (gDebug>2) 
+      Info("SqlReadObject","Starting objid = %lld column=%s", objid, fCurrentData->GetColumnName());
+
    if (!fCurrentData->IsBlobData() ||
        fCurrentData->VerifyDataType(sqlio::ObjectPtr,kFALSE))
       if (objid==0) {
@@ -545,7 +560,7 @@ void TBufferSQL2::SetStreamerElementNumber(Int_t number)
       return;
    }
    TStreamerElement* elem = info->GetStreamerElementReal(number, 0);
-
+   
    Int_t comp_type = info->GetTypes()[number];
 
    Int_t elem_type = elem->GetType();
@@ -768,7 +783,10 @@ void TBufferSQL2::WorkWithClass(const char* classname, Version_t classversion)
 
    if (IsReading()) {
       Long64_t objid = 0;
-
+      
+//      if ((fCurrentData!=0) && fCurrentData->VerifyDataType(sqlio::ObjectInst, kFALSE))
+//        if (!fCurrentData->IsBlobData()) Info("WorkWithClass","Big problem %s", fCurrentData->GetValue());
+      
       if ((fCurrentData!=0) && fCurrentData->IsBlobData() &&
           fCurrentData->VerifyDataType(sqlio::ObjectInst, kFALSE)) {
          objid = atoi(fCurrentData->GetValue());
@@ -813,7 +831,7 @@ void TBufferSQL2::WorkWithElement(TStreamerElement* elem, Int_t number)
    // when several data memebers of the same basic type streamed with single ...FastArray call
 
    if (gDebug>2)
-      cout << " TBufferSQL2::WorkWithElement " << elem->GetName() << endl;
+      Info("WorkWithElement","elem = %s",elem->GetName());
 
    if (number>=0)
       PushStack()->SetStreamerElement(elem, number);
@@ -829,7 +847,7 @@ void TBufferSQL2::WorkWithElement(TStreamerElement* elem, Int_t number)
       }
 
       fCurrentData = Stack()->GetObjectData(kTRUE);
-
+      
       Int_t located = Stack()->LocateElementColumn(fSQL, this, fCurrentData);
 
       if (located==TSQLStructure::kColUnknown) {
@@ -905,7 +923,7 @@ Version_t TBufferSQL2::ReadVersion(UInt_t *start, UInt_t *bcnt, const TClass *)
       TString value = fCurrentData->GetValue();
       res = value.Atoi();
       if (gDebug>3)
-         cout << "TBufferSQL2::ReadVersion from blob " << fCurrentData->GetBlobName1() << " = " << res << endl;
+         cout << "TBufferSQL2::ReadVersion from blob " << fCurrentData->GetBlobPrefixName() << " = " << res << endl;
       fCurrentData->ShiftToNextValue();
    } else {
       Error("ReadVersion", "No correspondent tags to read version");
@@ -965,11 +983,11 @@ void TBufferSQL2::WriteObject(const void *actualObjStart, const TClass *actualCl
 #define SQLReadArrayCompress(vname, arrsize)                            \
    {                                                                    \
       while(indx<arrsize) {                                             \
-         const char* name = fCurrentData->GetBlobName1();               \
+         const char* name = fCurrentData->GetBlobPrefixName();          \
          Int_t first, last, res;                                        \
          if (strstr(name,sqlio::IndexSepar)==0) {                       \
-            res = sscanf(name,"[%d]", &first); last = first;            \
-         } else res = sscanf(name,"[%d..%d]", &first, &last);           \
+            res = sscanf(name,"[%d", &first); last = first;             \
+         } else res = sscanf(name,"[%d..%d", &first, &last);            \
          if (gDebug>5) cout << name << " first = " << first << " last = " << last << " res = " << res << endl; \
          if ((first!=indx) || (last<first) || (last>=arrsize)) {        \
             Error("SQLReadArrayCompress","Error reading array content %s", name); \
@@ -1420,7 +1438,7 @@ void TBufferSQL2::ReadFastArray(void  *start, const TClass *cl, Int_t n, TMember
    // object data is started and finished 
 
    if (gDebug>2)
-      cout << "TBufferSQL2::ReadFastArray(* " << endl; 
+      Info("ReadFastArray","(void *"); 
 
    if (streamer) {
       StreamObject(start, streamer, cl, 0); 
@@ -1447,7 +1465,7 @@ void TBufferSQL2::ReadFastArray(void **start, const TClass *cl, Int_t n, Bool_t
    // object data is started and finished 
 
    if (gDebug>2)
-      cout << "TBufferSQL2::ReadFastArray(** " << endl; 
+      Info("ReadFastArray","(void **  pre = %d  n = %d", isPreAlloc, n); 
   
    if (streamer) {
       if (isPreAlloc) {
@@ -1476,6 +1494,9 @@ void TBufferSQL2::ReadFastArray(void **start, const TClass *cl, Int_t n, Bool_t
       }
    }
 
+   if (gDebug>2)
+      Info("ReadFastArray","(void ** Done" ); 
+
    //   TBuffer::ReadFastArray(startp, cl, n, isPreAlloc, s);
 }
 
diff --git a/sql/src/TKeySQL.cxx b/sql/src/TKeySQL.cxx
index e5980d31446b96e763961080ff4a50509f055136..67d664c5c5fce1106301e4993a419c97a280fdab 100644
--- a/sql/src/TKeySQL.cxx
+++ b/sql/src/TKeySQL.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TKeySQL.cxx,v 1.7 2006/02/01 18:57:41 pcanal Exp $
+// @(#)root/sql:$Name:  $:$Id: TKeySQL.cxx,v 1.8 2006/05/11 10:29:45 brun Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -149,13 +149,15 @@ void TKeySQL::Delete(Option_t * /*option*/)
 Long64_t TKeySQL::GetDBDirId() const
 {
    // return sql id of parent directory
+   
    return GetMotherDir() ? GetMotherDir()->GetSeekDir() : 0;
 }
 
 //______________________________________________________________________________
 void TKeySQL::StoreKeyObject(const void* obj, const TClass* cl)
 {
-   //please Sergey: document this function
+   // Stores object, associated with key, into data tables
+   
    TSQLFile* f = (TSQLFile*) GetFile(); 
     
    fCycle = GetMotherDir()->AppendKey(this);
@@ -170,7 +172,7 @@ void TKeySQL::StoreKeyObject(const void* obj, const TClass* cl)
       fDatime.Set();
       if (!f->WriteKeyData(this)) {
          // cannot add entry to keys table                          
-         Error("StoreObject","Cannot write data to key tables");
+         Error("StoreKeyObject","Cannot write data to key tables");
          // delete everything relevant for that key
          f->DeleteKeyFromDB(GetDBKeyId());
          fObjId = -1;
@@ -233,7 +235,7 @@ void* TKeySQL::ReadObjectAny(const TClass* expectedClass)
 //______________________________________________________________________________
 void* TKeySQL::ReadKeyObject(void* obj, const TClass* expectedClass)
 {
-   //please Sergey: document this function
+   // Read object, associated with key, from database
 
    TSQLFile* f = (TSQLFile*) GetFile(); 
 
diff --git a/sql/src/TSQLFile.cxx b/sql/src/TSQLFile.cxx
index bf229f35ccd120385872fc8f04ca376e7cf97b2a..3bff48d358ca728c6519872bf24e9c08f949bbb5 100644
--- a/sql/src/TSQLFile.cxx
+++ b/sql/src/TSQLFile.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLFile.cxx,v 1.8 2006/03/20 21:43:44 pcanal Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLFile.cxx,v 1.9 2006/05/11 10:29:45 brun Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -180,6 +180,7 @@
 #include "TClass.h"
 
 #include "TSQLServer.h"
+#include "TSQLStatement.h"
 #include "TSQLResult.h"
 #include "TSQLRow.h"
 #include "TBufferSQL2.h"
@@ -504,6 +505,7 @@ TSQLFile::TSQLFile(const char* dbname, Option_t* option, const char* user, const
    gROOT->cd();
 
    fSQL = TSQLServer::Connect(dbname, user, pass);
+   
    if (fSQL==0) {
       Error("TSQLFile", "Cannot connect to DB %s", dbname);
       goto zombie;
@@ -610,6 +612,16 @@ Bool_t TSQLFile::IsOracle() const
    return strcmp(fSQL->ClassName(),"TOracleServer")==0;
 }
 
+//______________________________________________________________________________
+Bool_t TSQLFile::IsODBC() const
+{
+   // checks, if ODBC driver used for database connection
+
+   if (fSQL==0) return kFALSE;
+   return strcmp(fSQL->ClassName(),"TODBCServer")==0;
+   
+}
+
 //______________________________________________________________________________
 void TSQLFile::SetUseSuffixes(Bool_t on)
 {
@@ -912,10 +924,8 @@ void TSQLFile::WriteHeader()
 void TSQLFile::WriteStreamerInfo()
 {
    // Store all TStreamerInfo, used in file, in sql database
-   // For the moment function is disabled while no proper reader is
-   // existing
 
-   return;
+   // return;
 
    // do not write anything when no basic tables was created
    if (!IsTablesExists()) return;
@@ -1001,11 +1011,8 @@ TList* TSQLFile::GetStreamerInfoList()
    // Read back streamer infos from database
    // List of streamer infos is always stored with key:id 0,
    // which is not shown in normal keys list
-   // Method is not active while TStreamerElement and TStreamerBase has custom
-   // streamers, which can not be handled by TBufferSQL2.
-   // Hopefully, problem will be solved soon
 
-   return new TList;
+//   return new TList;
    
    if (gDebug>1)
       Info("GetStreamerInfoList","Start reading of streamer infos");
@@ -1057,10 +1064,12 @@ Int_t TSQLFile::StreamKeysForDirectory(TDirectory* dir, Bool_t doupdate, Long64_
 
    if (res==0) return -1;
    
-   Int_t nkeys = res->GetRowCount();
+   Int_t nkeys = 0;
+   
+   TSQLRow* row = 0;
 
-   for(Int_t nrow=0;nrow<nkeys;nrow++) {
-      TSQLRow* row = res->Next();
+   while ((row = res->Next()) != 0) {
+      nkeys++; 
    
       Long64_t keyid = sqlio::atol64((*row)[0]);
       //      Int_t dirid = atoi((*row)[1]);
@@ -1072,18 +1081,18 @@ Int_t TSQLFile::StreamKeysForDirectory(TDirectory* dir, Bool_t doupdate, Long64_
       const char* classname = (*row)[7];
       
       if (gDebug>4) 
-         cout << "  Reading keyid = " << keyid << " name = " << keyname << endl;
+        cout << "  Reading keyid = " << keyid << " name = " << keyname << endl;
 
       if ((keyid>=sqlio::Ids_FirstKey) || (keyid==specialkeyid))
          if (doupdate) {
-            TKeySQL* key = FindSQLKey(dir, keyid);
+           TKeySQL* key = FindSQLKey(dir, keyid);
            
-            if (key==0) {
-               Error("StreamKeysForDirectory","Key with id %d not exist in list", keyid);
-               nkeys = -1; // this will finish execution
-            } else 
-               if (key->IsKeyModified(keyname, keytitle, keydatime, cycle, classname))
-               UpdateKeyData(key);
+           if (key==0) {
+              Error("StreamKeysForDirectory","Key with id %d not exist in list", keyid);
+              nkeys = -1; // this will finish execution
+           } else 
+           if (key->IsKeyModified(keyname, keytitle, keydatime, cycle, classname))
+              UpdateKeyData(key);
              
          } else {
             TKeySQL* key = new TKeySQL(dir, keyid, objid, 
@@ -1187,9 +1196,9 @@ Bool_t TSQLFile::ReadConfigurations()
      if ((field.CompareTo(name, TString::kIgnoreCase)==0))  \
         target = value; else 
    
+   TSQLRow* row = 0;
 
-   for(Int_t nrow=0;nrow<res->GetRowCount();nrow++) {
-      TSQLRow* row = res->Next();
+   while ((row = res->Next()) != 0) {
 
       TString field = row->GetField(0);
       TString value = row->GetField(1);
@@ -1300,7 +1309,11 @@ void TSQLFile::CreateBasicTables()
 //______________________________________________________________________________
 void TSQLFile::IncrementModifyCounter()
 {
-   //please Sergey: document this function
+   // Update value of modify counter in config table
+   // Modify counter used to indicate that something was changed in database.
+   // It will be used when multiple instances of TSQLFile for the same data base
+   // will be connected.
+   
    if (!IsWritable()) {
       Error("IncrementModifyCounter","Cannot update tables without write accsess");
       return;
@@ -1526,8 +1539,8 @@ TSQLResult* TSQLFile::SQLQuery(const char* cmd, Int_t flag, Bool_t* ok)
       delete res;
       return 0;
    }
-   if ((flag==2) && IsOracle())
-      res = new TSQLResultCopy(res);
+//   if ((flag==2) && IsOracle())
+//      res = new TSQLResultCopy(res);
    return res;
 }
 
@@ -1568,11 +1581,9 @@ TObjArray* TSQLFile::SQLTablesList(const char* searchtable)
       TString sqlcmd;
       TString user = fUserName;
       user.ToUpper();
-      sqlcmd.Form("SELECT object_name FROM ALL_OBJECTS WHERE object_type='TABLE' and owner='%s'",user.Data());
-      if (searchtable!=0) {
-         TString table = searchtable;
-         sqlcmd += Form(" and object_name='%s'",table.Data());
-      }
+      sqlcmd.Form("SELECT table_name FROM all_tables WHERE owner='%s'",user.Data());
+      if (searchtable!=0) 
+         sqlcmd += ::Form(" and table_name LIKE '%s'",searchtable);
 
       TSQLResult* tables = SQLQuery(sqlcmd.Data(), 1);
       if (tables==0) return 0;
@@ -1588,6 +1599,20 @@ TObjArray* TSQLFile::SQLTablesList(const char* searchtable)
          row = tables->Next();
       }
       delete tables;
+   } else 
+   if (IsODBC()) {
+      TSQLResult* tables = fSQL->GetTables("",searchtable);
+      if (tables==0) return 0;
+
+      TSQLRow* row = tables->Next();
+      while (row!=0) {
+         if (res==0) res = new TObjArray;
+         res->Add(new TObjString(row->GetField(2)));
+         delete row;
+         row = tables->Next();
+      }
+      delete tables;
+      
    } else {
       TSQLResult* tables = fSQL->GetTables(GetDataBaseName(), searchtable);
       if (tables==0) return 0;
@@ -1640,6 +1665,20 @@ TObjArray* TSQLFile::SQLTableColumns(const char* tablename)
          res->Add(col);
       }
       delete cols;
+   } else 
+   if (IsODBC()) {
+      TSQLResult* cols = fSQL->GetColumns("", tablename);
+      if (cols==0) return 0;
+
+      TSQLRow* row = cols->Next();
+      while (row!=0) {
+         TNamed* col = new TNamed(row->GetField(3), row->GetField(5));
+         if (res==0) res = new TObjArray;
+         res->Add(col);
+         delete row;
+         row = cols->Next();
+      }
+      delete cols;
    } else {
       TSQLResult* cols = fSQL->GetColumns(GetDataBaseName(), tablename, "");
 
@@ -1875,7 +1914,8 @@ Bool_t TSQLFile::WriteKeyData(TKeySQL* key)
 //______________________________________________________________________________
 Bool_t TSQLFile::UpdateKeyData(TKeySQL* key)
 {
-   //please Sergey: document this function
+   // updates (overwrites) key data in KeysTable
+   
    if ((fSQL==0) || (key==0)) return kFALSE;
 
    TString sqlcmd;
@@ -1926,7 +1966,7 @@ TSQLClassInfo* TSQLFile::FindSQLClassInfo(const char* clname, Int_t version)
 
    while ((info = (TSQLClassInfo*) iter()) !=0 ) {
       if (strcmp(info->GetName(), clname)==0)
-         if (info->GetClassVarsion()==version) return info;
+         if (info->GetClassVersion()==version) return info;
    }
    return 0;
 }
@@ -2029,7 +2069,7 @@ Bool_t TSQLFile::SyncSQLClassInfo(TSQLClassInfo* sqlinfo, TObjArray* columns, Bo
       sqlinfo->SetColumns(newcolumns);
       
       if (GetUseIndexes()>kIndexesBasic) {
-         sqlcmd.Form("CREATE UNIQUE INDEX %s%s_Index%s ON %s%s%s (%s%s%s)",
+         sqlcmd.Form("CREATE UNIQUE INDEX %s%s_I1%s ON %s%s%s (%s%s%s)",
                      quote, sqlinfo->GetClassTableName(), quote,
                      quote, sqlinfo->GetClassTableName(), quote,
                      quote, SQLObjectIdColumn(), quote);
@@ -2037,6 +2077,9 @@ Bool_t TSQLFile::SyncSQLClassInfo(TSQLClassInfo* sqlinfo, TObjArray* columns, Bo
       }
    }
 
+   SyncSQLClassInfoRawTables(sqlinfo, hasrawdata);
+
+/*
    if (hasrawdata && !sqlinfo->IsRawTableExist()) {
       TString sqlcmd;
 
@@ -2065,6 +2108,51 @@ Bool_t TSQLFile::SyncSQLClassInfo(TSQLClassInfo* sqlinfo, TObjArray* columns, Bo
       }
 
    }
+*/
+
+   return kTRUE;
+}
+
+//______________________________________________________________________________
+Bool_t TSQLFile::SyncSQLClassInfoRawTables(TSQLClassInfo* sqlinfo, Bool_t hasrawdata)
+{
+   // creates table for class raw data, if it is not exists
+    
+   if (sqlinfo==0) return kFALSE;
+
+   const char* quote = SQLIdentifierQuote();
+
+   if (hasrawdata && !sqlinfo->IsRawTableExist()) {
+       if (gDebug>2)
+         Info("SyncSQLClassInfoRawTables", sqlinfo->GetName());
+
+      TString sqlcmd;
+
+      sqlcmd.Form("CREATE TABLE %s%s%s (%s%s%s %s, %s%s%s %s, %s %s, %s %s)",
+                  quote, sqlinfo->GetRawTableName(), quote,
+                  quote, SQLObjectIdColumn(), quote, SQLIntType(),
+                  quote, SQLRawIdColumn(), quote, SQLIntType(),
+                  sqlio::BT_Field, SQLSmallTextType(),
+                  sqlio::BT_Value, SQLSmallTextType());
+                  
+      if ((fTablesType.Length()>0) && IsMySQL()) {
+         sqlcmd +=" TYPE=";
+         sqlcmd += fTablesType;
+      }
+
+      SQLQuery(sqlcmd.Data());
+      sqlinfo->SetRawExist(kTRUE);
+      
+      if (GetUseIndexes()>kIndexesClass) {
+         sqlcmd.Form("CREATE UNIQUE INDEX %s%s_I2%s ON %s%s%s (%s%s%s, %s%s%s)",
+                     quote, sqlinfo->GetClassTableName(), quote,
+                     quote, sqlinfo->GetRawTableName(), quote,
+                     quote, SQLObjectIdColumn(), quote,
+                     quote, SQLRawIdColumn(), quote);
+         SQLQuery(sqlcmd.Data());    
+      }
+
+   }
 
    return kTRUE;
 }
@@ -2259,10 +2347,37 @@ TObjArray* TSQLFile::SQLObjectsInfo(Long64_t keyid)
                quote, sqlio::ObjectsTable, quote,
                quote, SQLKeyIdColumn(), quote, keyid,
                quote, SQLObjectIdColumn(), quote);
+
+   TObjArray* arr = 0;
+   
+   if (fLogFile!=0)
+      *fLogFile << sqlcmd << endl;
+   if (gDebug>2) Info("SQLObjectsInfo",sqlcmd);
+   fQuerisCounter++;
+
+   TSQLStatement* stmt = fSQL->Statement(sqlcmd.Data(), 1000);
+   
+   if (stmt!=0) {
+      stmt->Process();
+      stmt->StoreResult();
+      
+      while (stmt->NextResultRow()) {
+         Long64_t objid = stmt->GetLong64(0); 
+         const char* clname = stmt->GetString(1);
+         Int_t version = stmt->GetInt(2); 
+         
+         TSQLObjectInfo* info = new TSQLObjectInfo(objid, clname, version);
+         if (arr==0) arr = new TObjArray();
+         arr->Add(info);
+      }
+   
+      delete stmt;
+      return arr;
+   }
+
    TSQLResult* res = SQLQuery(sqlcmd.Data(), 1);
    if (res==0) return 0;
    
-   TObjArray* arr = 0;
    TSQLRow* row = 0;
    while ((row = res->Next()) != 0) {
       Long64_t objid = atoi(row->GetField(0)); 
@@ -2296,7 +2411,8 @@ TSQLResult* TSQLFile::GetNormalClassData(Long64_t objid, TSQLClassInfo* sqlinfo)
 //______________________________________________________________________________
 TSQLResult* TSQLFile::GetNormalClassDataAll(Long64_t minobjid, Long64_t maxobjid, TSQLClassInfo* sqlinfo)
 {
-   //please Sergey: document this function
+   // return data for several objects from the range from normal class table
+   
    if (!sqlinfo->IsClassTableExist()) return 0;
    TString sqlcmd;
    const char* quote = SQLIdentifierQuote();
@@ -2312,41 +2428,46 @@ TSQLResult* TSQLFile::GetBlobClassData(Long64_t objid, TSQLClassInfo* sqlinfo)
 {
 //  Method return request results for specified objid from _streamer_ classtable 
 
-   if (sqlinfo->IsRawTableExist()) {
-      TString sqlcmd;
-      const char* quote = SQLIdentifierQuote();
-      sqlcmd.Form("SELECT %s, %s FROM %s%s%s WHERE %s%s%s=%lld ORDER BY %s%s%s",
-                  sqlio::BT_Field, sqlio::BT_Value,
-                  quote, sqlinfo->GetRawTableName(), quote,
-                  quote, SQLObjectIdColumn(), quote, objid,
-                  quote, SQLRawIdColumn(), quote);
-      return SQLQuery(sqlcmd.Data(), 2);
-   }
-   
-   return 0;
+   if (!sqlinfo->IsRawTableExist()) return 0;
+   TString sqlcmd;
+   const char* quote = SQLIdentifierQuote();
+   sqlcmd.Form("SELECT %s, %s FROM %s%s%s WHERE %s%s%s=%lld ORDER BY %s%s%s",
+               sqlio::BT_Field, sqlio::BT_Value,
+               quote, sqlinfo->GetRawTableName(), quote,
+               quote, SQLObjectIdColumn(), quote, objid,
+               quote, SQLRawIdColumn(), quote);
+   return SQLQuery(sqlcmd.Data(), 2);
 }
 
 //______________________________________________________________________________
-TSQLObjectData* TSQLFile::GetObjectClassData(Long64_t objid, TSQLClassInfo* sqlinfo)
+TSQLStatement* TSQLFile::GetBlobClassDataStmt(Long64_t objid, TSQLClassInfo* sqlinfo)
 {
-   // Get data for specified object from particular class table
-   // Returns TSQLObjectData object, which contains one row from
-   // normal class table and data from _streamer_ table.
-   // TSQLObjectData object used later in TBufferSQL2 to unstream object
-
-   if ((fSQL==0) || (objid<0) || (sqlinfo==0)) return 0;
-
-   if (gDebug>1)
-      Info("GetObjectClassData","Request for %s id = %lld", sqlinfo->GetName(), objid);
+//  Method return request results for specified objid from _streamer_ classtable 
+//  Data returned in form of statement, where direct access to values are possible
 
-   TSQLResult *classdata = GetNormalClassData(objid, sqlinfo);
+   if (!sqlinfo->IsRawTableExist()) return 0;
    
-   TSQLResult *blobdata = GetBlobClassData(objid, sqlinfo);
-
-   if (gDebug>3)
-      Info("GetObjectClassData","normal = %x blobdata = %x", classdata, blobdata);
-
-   return new TSQLObjectData(sqlinfo, objid, classdata, 0, blobdata);
+   TString sqlcmd;
+   const char* quote = SQLIdentifierQuote();
+   sqlcmd.Form("SELECT %s, %s FROM %s%s%s WHERE %s%s%s=%lld ORDER BY %s%s%s",
+               sqlio::BT_Field, sqlio::BT_Value,
+               quote, sqlinfo->GetRawTableName(), quote,
+               quote, SQLObjectIdColumn(), quote, objid,
+               quote, SQLRawIdColumn(), quote);
+               
+   if (fLogFile!=0)
+      *fLogFile << sqlcmd << endl;
+   if (gDebug>2) Info("BuildStatement",sqlcmd);
+   fQuerisCounter++;
+               
+   TSQLStatement* stmt = fSQL->Statement(sqlcmd.Data(), 1000);
+   if (stmt==0) return 0;
+   
+   stmt->Process();
+   
+   stmt->StoreResult();
+   
+   return stmt;
 }
 
 //______________________________________________________________________________
@@ -2382,11 +2503,11 @@ Long64_t TSQLFile::StoreObjectInTables(Long64_t keyid, const void* obj, const TC
          }
           
          if (!SQLApplyCommands(&cmds)) {
-            Error("StoreObject","Cannot correctly store object data in database");
-            objid = -1;
-            if (needcommit) SQLRollback();
+           Error("StoreObject","Cannot correctly store object data in database");
+           objid = -1;
+           if (needcommit) SQLRollback();
          } else {
-            if (needcommit) SQLCommit();
+           if (needcommit) SQLCommit();
          }
       }
       cmds.Delete();
diff --git a/sql/src/TSQLObjectData.cxx b/sql/src/TSQLObjectData.cxx
index a41b7bad51645a00650d0dfdba5e86c9e04fe8fa..7653019535b5d15ee2b3eafb791e3579d7a2cf6e 100644
--- a/sql/src/TSQLObjectData.cxx
+++ b/sql/src/TSQLObjectData.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLObjectData.cxx,v 1.5 2006/04/27 10:19:43 brun Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLObjectData.cxx,v 1.6 2006/05/11 10:29:45 brun Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -28,6 +28,7 @@
 #include "TSQLResult.h"
 #include "TSQLClassInfo.h"
 #include "TSQLStructure.h"
+#include "TSQLStatement.h"
 
 ClassImp(TSQLObjectInfo)
 
@@ -66,14 +67,15 @@ TSQLObjectData::TSQLObjectData() :
       fOwner(kFALSE),
       fClassData(0),
       fBlobData(0),
+      fBlobStmt(0),
       fLocatedColumn(-1),
       fClassRow(0),
       fBlobRow(0),
       fLocatedField(0),
       fLocatedValue(0),
       fCurrentBlob(kFALSE),
-      fBlobName1(),
-      fBlobName2(),
+      fBlobPrefixName(0),
+      fBlobTypeName(0),
       fUnpack(0)
 {
    // default contrsuctor
@@ -84,21 +86,23 @@ TSQLObjectData::TSQLObjectData(TSQLClassInfo* sqlinfo,
                                Long64_t       objid,
                                TSQLResult*    classdata,
                                TSQLRow*       classrow,
-                               TSQLResult*    blobdata) :
+                               TSQLResult*    blobdata,
+                               TSQLStatement* blobstmt) :
    TObject(),
    fInfo(sqlinfo),
    fObjId(objid),
    fOwner(kFALSE),
    fClassData(classdata),
    fBlobData(blobdata),
+   fBlobStmt(blobstmt),
    fLocatedColumn(-1),
    fClassRow(classrow),
    fBlobRow(0),
    fLocatedField(0),
    fLocatedValue(0),
    fCurrentBlob(kFALSE),
-   fBlobName1(),
-   fBlobName2(),
+   fBlobPrefixName(0),
+   fBlobTypeName(0),
    fUnpack(0)
 {
    // normal contrsuctor,
@@ -108,8 +112,8 @@ TSQLObjectData::TSQLObjectData(TSQLClassInfo* sqlinfo,
       fOwner = kTRUE;
       fClassRow = fClassData->Next();
    }
-   if (fBlobData!=0)
-      fBlobRow = fBlobData->Next();
+
+   ShiftBlobRow();
 }
 
 //______________________________________________________________________________
@@ -122,6 +126,7 @@ TSQLObjectData::~TSQLObjectData()
    if (fBlobRow!=0) delete fBlobRow;
    if (fBlobData!=0) delete fBlobData;
    if (fUnpack!=0) { fUnpack->Delete(); delete fUnpack; }
+   if (fBlobStmt!=0) delete fBlobStmt;
 }
 
 //______________________________________________________________________________
@@ -175,7 +180,7 @@ Bool_t TSQLObjectData::LocateColumn(const char* colname, Bool_t isblob)
 
    if (!isblob) return kTRUE;
 
-   if (fBlobRow==0) return kFALSE;
+   if ((fBlobRow==0) && (fBlobStmt==0)) return kFALSE;
 
    fCurrentBlob = kTRUE;
 
@@ -184,28 +189,66 @@ Bool_t TSQLObjectData::LocateColumn(const char* colname, Bool_t isblob)
    return kTRUE;
 }
 
+//______________________________________________________________________________
+Bool_t TSQLObjectData::ShiftBlobRow()
+{
+   // shift cursor to next blob value 
+    
+   if (fBlobStmt!=0) {
+      Bool_t res = fBlobStmt->NextResultRow();
+      if (!res) { delete fBlobStmt; fBlobStmt = 0; }
+      return res;
+   }
+   
+   delete fBlobRow;
+   fBlobRow = fBlobData ? fBlobData->Next() : 0;
+   return fBlobRow!=0;
+}
+
 //______________________________________________________________________________
 Bool_t TSQLObjectData::ExtractBlobValues()
 {
-   // extract from blob table value and names
+   // extract from curent blob row value and names identifiers
 
-   if (fBlobRow==0) return kFALSE;
+   const char* name = 0;
+   
+   Bool_t hasdata = kFALSE;
 
-   fLocatedValue = fBlobRow->GetField(1);
+   if (fBlobStmt!=0) {
+      name = fBlobStmt->GetString(0);
+      fLocatedValue = fBlobStmt->GetString(1);
+      hasdata = kTRUE;
+   }
 
-   const char* name = fBlobRow->GetField(0);
+   if (!hasdata) {
+      if (fBlobRow!=0) {
+         fLocatedValue = fBlobRow->GetField(1);
+         name = fBlobRow->GetField(0);
+      }
+   }
+   
+   if (name==0) {
+      fBlobPrefixName = 0;
+      fBlobTypeName = 0; 
+      return kFALSE;
+   }
+   
    const char* separ = strstr(name, ":"); //SQLNameSeparator()
 
    if (separ==0) {
-      fBlobName1 = "";
-      fBlobName2 = name;
+      fBlobPrefixName = 0;
+      fBlobTypeName = name;
    } else {
-      fBlobName1 = "";
-      fBlobName1.Append(name, separ-name);
+      fBlobPrefixName = name;
       separ+=strlen(":"); //SQLNameSeparator()
-      fBlobName2 = separ;
+      fBlobTypeName = separ;
    }
 
+//   if (gDebug>4)
+//      Info("ExtractBlobValues","Prefix:%s Type:%s",
+//            (fBlobPrefixName ? fBlobPrefixName : "null"),
+//            (fBlobTypeName ? fBlobTypeName : "null"));
+
    return kTRUE;
 }
 
@@ -218,8 +261,8 @@ void TSQLObjectData::AddUnpack(const char* tname, const char* value)
    TNamed* str = new TNamed(tname, value);
    if (fUnpack==0) {
       fUnpack = new TObjArray();
-      fBlobName1 = "";
-      fBlobName2 = str->GetName();
+      fBlobPrefixName = 0;
+      fBlobTypeName = str->GetName();
       fLocatedValue = str->GetTitle();
    }
 
@@ -250,8 +293,8 @@ void TSQLObjectData::ShiftToNextValue()
       fUnpack->Compress();
       if (fUnpack->GetLast()>=0) {
          TNamed* curr = (TNamed*) fUnpack->First();
-         fBlobName1 = "";
-         fBlobName2 = curr->GetName();
+         fBlobPrefixName = 0;
+         fBlobTypeName = curr->GetName();
          fLocatedValue = curr->GetTitle();
          return;
       }
@@ -261,10 +304,7 @@ void TSQLObjectData::ShiftToNextValue()
    }
 
    if (fCurrentBlob) {
-      if (doshift) {
-         delete fBlobRow;
-         fBlobRow = fBlobData->Next();
-      }
+      if (doshift) ShiftBlobRow();
       ExtractBlobValues();
    } else
       if (fClassData!=0) {
@@ -293,9 +333,20 @@ Bool_t TSQLObjectData::VerifyDataType(const char* tname, Bool_t errormsg)
    // here maybe type of column can be checked
    if (!IsBlobData()) return kTRUE;
 
-   if (fBlobName2!=tname) {
+   if (gDebug>4) 
+      if (fBlobTypeName==0) {
+         Error("VerifyDataType","fBlobTypeName is null");
+         return kFALSE;
+      }
+
+
+   TString v1(fBlobTypeName);
+   TString v2(tname);
+
+//   if (strcmp(fBlobTypeName,tname)!=0) {
+   if (v1!=v2) { 
       if (errormsg)
-         Error("VerifyDataType","Data type meissmatch %s - %s", fBlobName2.Data(), tname);
+         Error("VerifyDataType","Data type missmatch %s - %s", fBlobTypeName, tname);
       return kFALSE;
    }
 
@@ -316,6 +367,17 @@ Bool_t TSQLObjectData::PrepareForRawData()
 
 //===================================================================================
 
+//________________________________________________________________________
+//
+// TSQLObjectDataPool contains list (pool) of data from single class table 
+// for differents objects, all belonging to the same key.
+// This is typical situation when list of objects stored as single key.
+// To optimize reading of such data, one query is submitted and results of that
+// query kept in TSQLObjectDataPool object
+//
+//________________________________________________________________________
+
+
 ClassImp(TSQLObjectDataPool);
 
 //______________________________________________________________________________
@@ -341,7 +403,9 @@ TSQLObjectDataPool::TSQLObjectDataPool(TSQLClassInfo* info, TSQLResult* data) :
 //______________________________________________________________________________
 TSQLObjectDataPool::~TSQLObjectDataPool()
 {
-   //please Sergey: document this function
+   // Destructor of TSQLObjectDataPool class
+   // Deletes not used rows and class data table
+   
    if (fClassData!=0) delete fClassData;
    if (fRowsPool!=0) {
       fRowsPool->Delete();
@@ -352,7 +416,8 @@ TSQLObjectDataPool::~TSQLObjectDataPool()
 //______________________________________________________________________________
 TSQLRow* TSQLObjectDataPool::GetObjectRow(Long64_t objid)
 {
-   //please Sergey: document this function
+   // Returns single sql row with object data for that class
+   
    if (fClassData==0) return 0;
    
    Long64_t rowid;
diff --git a/sql/src/TSQLStructure.cxx b/sql/src/TSQLStructure.cxx
index 474ee804aa039011615a0245cf2c0c652ce149ef..0775ac63fc2a293498b666a9541d65efaaf9d81f 100644
--- a/sql/src/TSQLStructure.cxx
+++ b/sql/src/TSQLStructure.cxx
@@ -1,4 +1,4 @@
-// @(#)root/sql:$Name:  $:$Id: TSQLStructure.cxx,v 1.10 2006/05/11 10:29:45 brun Exp $
+// @(#)root/sql:$Name:  $:$Id: TSQLStructure.cxx,v 1.11 2006/05/12 08:17:02 brun Exp $
 // Author: Sergey Linev  20/11/2005
 
 /*************************************************************************
@@ -36,6 +36,10 @@
 #include "TSQLObjectData.h"
 #include "TBufferSQL2.h"
 
+#include "TSQLStatement.h"
+#include "TSQLServer.h"
+#include "TDataType.h"
+
 namespace sqlio {
    const Int_t Ids_NullPtr       = 0; // used to identify NULL pointer in tables
    const Int_t Ids_RootDir       = 0; // dir:id, used for keys stored in root directory.
@@ -300,7 +304,8 @@ void TSQLStructure::SetStreamerElement(const TStreamerElement* elem, Int_t numbe
 //________________________________________________________________________
 void TSQLStructure::SetCustomClass(const TClass* cl, Version_t version)
 {
-   //please Sergey: document this function
+   // set structure type as kSqlCustomClass
+   
    fType = kSqlCustomClass;
    fPointer = (void*) cl;
    fArrayIndex = version;
@@ -309,7 +314,8 @@ void TSQLStructure::SetCustomClass(const TClass* cl, Version_t version)
 //________________________________________________________________________
 void TSQLStructure::SetCustomElement(TStreamerElement* elem)
 {
-   //please Sergey: document this function
+   // set structure type as kSqlCustomElement
+   
    fType = kSqlCustomElement;
    fPointer = elem;
 }
@@ -412,21 +418,24 @@ const char* TSQLStructure::GetValueType() const
 //________________________________________________________________________
 TClass* TSQLStructure::GetCustomClass() const
 {
-   //please Sergey: document this function
+   // return element custom class if strutures is kSqlCustomClass
+   
    return (fType==kSqlCustomClass) ? (TClass*) fPointer : 0;
 }
 
 //________________________________________________________________________
 Version_t TSQLStructure::GetCustomClassVersion() const
 {
-   //please Sergey: document this function
+   // return custom class version if strutures is kSqlCustomClass
+   
    return (fType==kSqlCustomClass) ? fArrayIndex : 0;
 }
 
 //________________________________________________________________________
 Bool_t TSQLStructure::GetClassInfo(TClass* &cl, Version_t &version)
 {
-   //please Sergey: document this function
+   // provides class info if structure kSqlStreamerInfo or kSqlCustomClass
+   
    if (GetType()==kSqlStreamerInfo) {
       TStreamerInfo* info = GetStreamerInfo();
       if (info==0) return kFALSE;
@@ -492,6 +501,7 @@ Long64_t TSQLStructure::DefineObjectId(Bool_t recursive)
    TSQLStructure* curr = this;
    while (curr!=0) {
       if ((curr->GetType()==kSqlObject) ||
+          (curr->GetType()==kSqlPointer) || 
          // workaround to store object id in element structure
           (curr->GetType()==kSqlElement) ||
           (curr->GetType()==kSqlCustomElement) ||
@@ -675,7 +685,9 @@ class TSqlCmdsBuffer : public TObject {
 public:
    TSqlCmdsBuffer(TSQLClassInfo* info = 0) :
       TObject(),
-      fInfo(info)
+      fInfo(info),
+      fBlobStmt(0),
+      fNormStmt(0)
    {
    }
 
@@ -683,6 +695,8 @@ public:
    {
       fNormCmds.Delete();
       fBlobCmds.Delete();
+      if (fBlobStmt!=0) delete fBlobStmt;
+      if (fNormStmt!=0) delete fNormStmt;
    }
 
    void AddValues(Bool_t isnorm, const char* values)
@@ -695,6 +709,8 @@ public:
    TSQLClassInfo* fInfo;
    TObjArray fNormCmds;
    TObjArray fBlobCmds;
+   TSQLStatement* fBlobStmt;
+   TSQLStatement* fNormStmt;
 };
 
 
@@ -715,7 +731,8 @@ public:
       fLastLongStrId(0),
       fPool(),
       fLongStrValues(),
-      fRegValues()
+      fRegValues(),
+      fRegStmt(0)
    {
    }
 
@@ -733,12 +750,16 @@ public:
    TMap       fPool;
    TObjArray  fLongStrValues;
    TObjArray  fRegValues;
+   
+   TSQLStatement* fRegStmt;
+
 
    virtual ~TSqlRegistry()
    {
       fPool.DeleteValues();
       fLongStrValues.Delete();
       fRegValues.Delete();
+      if (fRegStmt) delete fRegStmt;
    }
 
    Long64_t GetNextObjId() { return ++fLastObjId; }
@@ -807,10 +828,15 @@ public:
          if (buf==0) continue;
          ConvertSqlValues(buf->fNormCmds, sqlinfo->GetClassTableName());
          ConvertSqlValues(buf->fBlobCmds, sqlinfo->GetRawTableName());
+         if (buf->fBlobStmt)
+            buf->fBlobStmt->Process();
+         if (buf->fNormStmt)
+            buf->fNormStmt->Process();
       }
 
       ConvertSqlValues(fLongStrValues, sqlio::StringsTable);
       ConvertSqlValues(fRegValues, sqlio::ObjectsTable);
+      if (fRegStmt) fRegStmt->Process();
    }
 
 
@@ -821,6 +847,27 @@ public:
          Error("AddRegCmd","Something wrong with objid = %lld", objid);
          return;
       }
+      
+      if (f->IsOracle()) {
+         if (fRegStmt==0) {
+            const char* quote = f->SQLIdentifierQuote();
+            TString sqlcmd;  
+            sqlcmd.Form("INSERT INTO %s%s%s VALUES (:1, :2, :3, :4)", 
+                     quote, sqlio::ObjectsTable, quote);
+            fRegStmt = f->fSQL->Statement(sqlcmd.Data(), 1000);
+            f->fQuerisCounter++;
+         }
+         
+         fRegStmt->NextIteration();
+         
+         fRegStmt->SetLong64(0, fKeyId);
+         fRegStmt->SetLong64(1, objid);
+         fRegStmt->SetString(2, cl->GetName());
+         fRegStmt->SetInt(3, cl->GetClassVersion());
+         
+         return;   
+      }      
+      
       const char* valuequote = f->SQLValueQuote();
       TString cmd;
       cmd.Form("%lld, %lld, %s%s%s, %d",
@@ -848,12 +895,83 @@ public:
 
       return strid;
    }
+   
+   void ConvertBlobsOracle(TObjArray* blobs, TSQLClassInfo* sqlinfo, Int_t& rawid)
+   {
+      TSqlCmdsBuffer* buf = GetCmdsBuffer(sqlinfo);
+      if (buf==0) return;
+      
+      TSQLStatement* stmt = buf->fBlobStmt;
+      if (stmt==0) {
+         const char* quote = f->SQLIdentifierQuote();
+         TString sqlcmd;
+         sqlcmd.Form("INSERT INTO %s%s%s VALUES (:1, :2, :3, :4)", 
+                     quote, sqlinfo->GetRawTableName(), quote);
+         stmt = f->fSQL->Statement(sqlcmd.Data(), 2000);
+         f->fQuerisCounter++;
+         buf->fBlobStmt = stmt;
+      }
 
-   void ConvertBlobs(TObjArray* blobs, TSQLClassInfo* sqlinfo, Int_t& rawid)
+      TIter iter(blobs);
+      TNamed* cmd = 0;
+      
+      while ((cmd = (TNamed*)iter())!=0) {
+         stmt->NextIteration();
+          
+         stmt->SetLong64(0, fCurrentObjId);
+         stmt->SetInt(1, rawid);
+         stmt->SetString(2, cmd->GetName());
+         stmt->SetString(3, cmd->GetTitle());
+         
+         rawid++; 
+      }
+   }
+
+   void InsertToNormalTableOracle(TObjArray* columns, TSQLClassInfo* sqlinfo)
    {
       TSqlCmdsBuffer* buf = GetCmdsBuffer(sqlinfo);
       if (buf==0) return;
+      
+      TSQLStatement* stmt = buf->fNormStmt;
+      if (stmt==0) {
+         const char* quote = f->SQLIdentifierQuote();
+         TString sqlcmd;
+         sqlcmd.Form("INSERT INTO %s%s%s VALUES (:", 
+                     quote, sqlinfo->GetClassTableName(), quote);
+         for (int n=0;n<=columns->GetLast();n++) {
+            if (n>0) sqlcmd +=", :";
+            sqlcmd += (n+1);
+         }
+         sqlcmd += ")";
+                     
+         stmt = f->fSQL->Statement(sqlcmd.Data(), 1000);
+         f->fQuerisCounter++;
+         buf->fNormStmt = stmt;
+      }
+      
+      stmt->NextIteration(); 
+       
+      TIter iter(columns);
+      TSQLColumnData* col;
+      Int_t ncol = 0;
+      while ((col=(TSQLColumnData*)iter())!=0) {
+         const char* value = col->GetValue();
+         stmt->SetString(ncol, value);
+         ncol++; 
+      }
+   }
+
+   void ConvertBlobs(TObjArray* blobs, TSQLClassInfo* sqlinfo, Int_t& rawid)
+   {
 
+      if (f->IsOracle()) {
+         ConvertBlobsOracle(blobs, sqlinfo, rawid);
+         return;
+      }
+       
+      TSqlCmdsBuffer* buf = GetCmdsBuffer(sqlinfo);
+      if (buf==0) return; 
+       
       TString value, onecmd, cmdmask;
 
       const char* valuequote = f->SQLValueQuote();
@@ -874,17 +992,22 @@ public:
    {
       // produce SQL query to insert object data into normal table
 
+      if (f->IsOracle()) {
+         InsertToNormalTableOracle(columns, sqlinfo);
+         return;
+      }
+
       TIter iter(columns);
       TSQLColumnData* col;
       const char* valuequote = f->SQLValueQuote();
 
       TString values;
-
+      
       Bool_t first = kTRUE;
 
       while ((col=(TSQLColumnData*)iter())!=0) {
-         if (first) first = kFALSE;
-               else values+=", ";
+         if (first) first = kFALSE; 
+               else values+=", "; 
          if (col->IsNumeric())
             values+=col->GetValue();
          else {
@@ -893,10 +1016,9 @@ public:
             values += value;
          }
       }
-
+     
       TSqlCmdsBuffer* buf = GetCmdsBuffer(sqlinfo);
       if (buf!=0) buf->AddValues(kTRUE, values.Data());
-
    }
 };
 
@@ -1108,9 +1230,9 @@ Bool_t TSQLStructure::StoreObject(TSqlRegistry* reg, Long64_t objid, TClass* cl,
          res = kFALSE;
       else {
          sqlinfo = reg->f->RequestSQLClassInfo(cl);
+         reg->f->SyncSQLClassInfo(sqlinfo, 0, kTRUE);
          Int_t currrawid = 0;
          reg->ConvertBlobs(&objblobs, sqlinfo, currrawid);
-         reg->f->SyncSQLClassInfo(sqlinfo, 0, kTRUE);
       }
 
       objblobs.Delete();
@@ -1193,6 +1315,7 @@ Bool_t TSQLStructure::StoreClassInNormalForm(TSqlRegistry* reg)
 
       Int_t blobid = -1;
       if (blobs.GetLast()>=0) {
+         reg->f->SyncSQLClassInfoRawTables(sqlinfo, kTRUE);
          blobid = currrawid; // column will contain first raw id
          reg->ConvertBlobs(&blobs, sqlinfo, currrawid);
          needblob = kTRUE;
@@ -1327,8 +1450,10 @@ Bool_t TSQLStructure::StoreElementInNormalForm(TSqlRegistry* reg, TObjArray* col
       Long64_t objid = -1;
 
       if (child->GetType()==kSqlObject) {
-         objid = child->DefineObjectId(kFALSE);
+         objid = child->DefineObjectId(kFALSE); 
          normal = child->StoreObject(reg, objid, child->GetObjectClass());
+      } else {
+         objid = child->DefineObjectId(kFALSE);
       }
 
       if (!normal) {