~mathiaz/ubuntu/lucid/mysql-dfsg-5.1/zap-bug-552053

« back to all changes in this revision

Viewing changes to storage/ibmdb2i/db2i_file.h

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2009-06-25 12:55:45 UTC
  • mfrom: (1.1.2 upstream) (0.1.3 experimental)
  • Revision ID: james.westby@ubuntu.com-20090625125545-m8ogs96zzsri74xe
Tags: 5.1.34-1ubuntu1
* Merge from debian experimental (and 5.0 from main), remaining changes:
  - debian/mysql-server-5.1.config:
    + ask for MySQL root password at priority high instead of medium so
      that the password prompt is seen on a default install. (LP: #319843)
    + don't ask for root password when upgrading from a 5.0 install.
  - debian/control:
    + Make libmysqlclient16-dev a transitional package depending on
      libmysqlclient-dev.
    + Make libmysqlclient-dev conflict with libmysqlclient15-dev.
    + Don't build mysql-server, mysql-client, mysql-common and
      libmysqlclient15-dev binary packages since they're still provided
      by mysql-dfsg-5.0.
    + Make mysql-{client,server}-5.1 packages conflict and
      replace mysql-{client,server}-5.0, but not provide
      mysql-{client,server}.
    + Depend on a specific version of mysql-common rather than the src
      version of mysql-dfsg-5.1 since mysql-common is currently part of
      mysql-dfsg-5.0.
    + Lower mailx from a Recommends to a Suggests to avoid pulling in
      a full MTA on all installs of mysql-server. (LP: #259477)
  - debian/rules:
    + added -fno-strict-aliasing to CFLAGS to get around mysql testsuite
      build failures.
    + install mysql-test and sql-bench to /usr/share/mysql/ rather than
      /usr/.
  - debian/additions/debian-start.inc.sh: support ANSI mode (LP: #310211)
  - Add AppArmor profile:
    - debian/apparmor-profile: apparmor profile.
    - debian/rules, debian/mysql-server-5.0.files: install apparmor profile.
    - debian/mysql-server-5.0.dirs: add etc/apparmor.d/force-complain
    - debian/mysql-server-5.0.postrm: remove symlink in force-complain/ on
      purge.
    - debian/mysql-server-5.1.README.Debian: add apparmor documentation.
    - debian/additions/my.cnf: Add warning about apparmor. (LP: #201799)
    - debian/mysql-server-5.1.postinst: reload apparmor profiles.
  - debian/additions/my.cnf: remove language option. Error message files are
    located in a different directory in MySQL 5.0. Setting the language
    option to use /usr/share/mysql/english breaks 5.0. Both 5.0 and 5.1
    use a default value that works. (LP: #316974)
  - debian/mysql-server-5.1.mysql.init:
    + Clearly indicate that we do not support running multiple instances
      of mysqld by duplicating the init script.
      (closes: #314785, #324834, #435165, #444216)
    + Properly parameterize all existing references to the mysql config
      file (/etc/mysql/my.cnf).
  - debian/mysql-server-5.0.postinst: Clear out the second password
    when setting up mysql. (LP: #344816)
  - mysql-server-core-5.1 package for files needed by Akonadi:
    + debian/control: create mysql-server-core-5.1 package.
    + debian/mysql-server-core-5.1.files, debian/mysql-server-5.1.files:
      move core mysqld files to mysql-server-core-5.1 package.
  - Don't package sql-bench and mysql-test file.
* Dropped changes:
  - debian/patches/92_ssl_test_cert.dpatch: certificate expiration in
    test suite (LP: #323755). Included upstream.
* Dropped from 5.0:
  - apparmor profile:
    - debian/control: Recommends apparmor >= 2.1+1075-0ubuntu6. All version
      of apparmor-profile (>hardy) are higher than this version.
    - debian/mysql-server-5.0.preinst: create symlink for force-complain/
      on pre-feisty upgrades, upgrades where apparmor-profiles profile is
      unchanged (ie non-enforcing) and upgrades where the profile
      doesn't exist. Support for pre-hardy upgrades is no longer needed.
* debian/mysql-server-5.1.postinst: fix debian-sys-maint user creation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Licensed Materials - Property of IBM
 
3
DB2 Storage Engine Enablement
 
4
Copyright IBM Corporation 2007,2008
 
5
All rights reserved
 
6
 
 
7
Redistribution and use in source and binary forms, with or without modification,
 
8
are permitted provided that the following conditions are met: 
 
9
 (a) Redistributions of source code must retain this list of conditions, the
 
10
     copyright notice in section {d} below, and the disclaimer following this
 
11
     list of conditions. 
 
12
 (b) Redistributions in binary form must reproduce this list of conditions, the
 
13
     copyright notice in section (d) below, and the disclaimer following this
 
14
     list of conditions, in the documentation and/or other materials provided
 
15
     with the distribution. 
 
16
 (c) The name of IBM may not be used to endorse or promote products derived from
 
17
     this software without specific prior written permission. 
 
18
 (d) The text of the required copyright notice is: 
 
19
       Licensed Materials - Property of IBM
 
20
       DB2 Storage Engine Enablement 
 
21
       Copyright IBM Corporation 2007,2008 
 
22
       All rights reserved
 
23
 
 
24
THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
 
25
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
26
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 
27
SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 
29
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
30
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
31
CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 
32
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 
33
OF SUCH DAMAGE.
 
34
*/
 
35
 
 
36
 
 
37
#ifndef DB2I_FILE_H
 
38
#define DB2I_FILE_H
 
39
 
 
40
#include "db2i_global.h"
 
41
#include "db2i_ileBridge.h"
 
42
#include "db2i_validatedPointer.h"
 
43
#include "my_atomic.h"
 
44
#include "db2i_iconv.h"
 
45
#include "db2i_charsetSupport.h"
 
46
 
 
47
const char FID_EXT[] = ".FID";
 
48
 
 
49
class db2i_file;
 
50
  
 
51
#pragma pack(1)
 
52
struct DB2LobField
 
53
{
 
54
  char reserved1;
 
55
  uint32 length;
 
56
  char reserved2[4];
 
57
  uint32 ordinal;
 
58
  ILEMemHandle dataHandle;
 
59
  char reserved3[8];
 
60
};
 
61
#pragma pack(pop)
 
62
 
 
63
class DB2Field
 
64
 
65
  public:
 
66
    uint16 getType() const { return *(uint16*)(&definition.ColType); }
 
67
    uint16 getByteLengthInRecord() const { return definition.ColLen; }
 
68
    uint16 getDataLengthInRecord() const
 
69
    { 
 
70
      return (getType() == QMY_VARCHAR || getType() == QMY_VARGRAPHIC ? definition.ColLen - 2 : definition.ColLen); 
 
71
    }
 
72
    uint16 getCCSID() const { return *(uint16*)(&definition.ColCCSID); }
 
73
    bool isBlob() const
 
74
    { 
 
75
      uint16 type = getType();
 
76
      return (type == QMY_BLOBCLOB || type == QMY_DBCLOB); 
 
77
    }
 
78
    uint16 getBufferOffset() const { return definition.ColBufOff; }
 
79
    uint16 calcBlobPad() const
 
80
    {
 
81
      DBUG_ASSERT(isBlob());
 
82
      return getByteLengthInRecord() - sizeof (DB2LobField);
 
83
    }
 
84
    DB2LobField* asBlobField(char* buf) const
 
85
    {
 
86
      DBUG_ASSERT(isBlob());
 
87
      return (DB2LobField*)(buf + getBufferOffset() + calcBlobPad());
 
88
    }
 
89
  private:
 
90
   col_def_t definition;
 
91
};
 
92
  
 
93
 
 
94
/**
 
95
  @class db2i_table
 
96
  
 
97
  @details 
 
98
  This class describes the logical SQL table provided by DB2. 
 
99
  It stores "table-scoped" information such as the name of the
 
100
  DB2 schema, BLOB descriptions, and the corresponding MySQL table definition.
 
101
  Only one instance exists per SQL table.
 
102
*/
 
103
class db2i_table
 
104
{
 
105
  public: 
 
106
  enum NameFormatFlags
 
107
  {
 
108
    ASCII_SQL,
 
109
    ASCII_NATIVE,
 
110
    EBCDIC_NATIVE
 
111
  };
 
112
    
 
113
  db2i_table(const TABLE_SHARE* myTable, const char* path = NULL);
 
114
  
 
115
  ~db2i_table();
 
116
 
 
117
  int32 initDB2Objects(const char* path);
 
118
 
 
119
  const TABLE_SHARE* getMySQLTable() const
 
120
  {
 
121
    return mysqlTable;
 
122
  }
 
123
  
 
124
  uint64 getStartId() const
 
125
  {
 
126
    return db2StartId;
 
127
  }
 
128
 
 
129
  void updateStartId(uint64 newStartId)
 
130
  {
 
131
     db2StartId = newStartId;
 
132
  }
 
133
 
 
134
  bool hasBlobs() const
 
135
  {
 
136
    return (blobFieldCount > 0);
 
137
  }
 
138
  
 
139
  uint16 getBlobCount() const
 
140
  {
 
141
    return blobFieldCount;
 
142
  }
 
143
  
 
144
  uint getBlobFieldActualSize(uint fieldIndex) const
 
145
  {
 
146
    return blobFieldActualSizes[getBlobIdFromField(fieldIndex)];
 
147
  }
 
148
 
 
149
  void updateBlobFieldActualSize(uint fieldIndex, uint32 newSize)
 
150
  {
 
151
    // It's OK that this isn't threadsafe, since this is just an advisory
 
152
    // value. If a race condition causes the lesser of two values to be stored,
 
153
    // that's OK.
 
154
    uint16 blobID = getBlobIdFromField(fieldIndex);
 
155
    DBUG_ASSERT(blobID < blobFieldCount);
 
156
    
 
157
    if (blobFieldActualSizes[blobID] < newSize)
 
158
    {
 
159
      blobFieldActualSizes[blobID] = newSize;
 
160
    }
 
161
  }
 
162
 
 
163
  
 
164
  
 
165
  const char* getDB2LibName(NameFormatFlags format = EBCDIC_NATIVE)
 
166
  {
 
167
    switch (format)
 
168
    {
 
169
      case EBCDIC_NATIVE:
 
170
        return db2LibNameEbcdic; break;
 
171
      case ASCII_NATIVE:
 
172
        return db2LibNameAscii; break;
 
173
      case ASCII_SQL:
 
174
        return db2LibNameSQLAscii; break;
 
175
      default:
 
176
        DBUG_ASSERT(0);
 
177
    }
 
178
    return NULL;
 
179
  }
 
180
  
 
181
  const char* getDB2TableName(NameFormatFlags format = EBCDIC_NATIVE) const
 
182
  {
 
183
    switch (format)
 
184
    {
 
185
      case EBCDIC_NATIVE:
 
186
        return db2TableNameEbcdic; break;
 
187
      case ASCII_NATIVE:
 
188
        return db2TableNameAscii; break;
 
189
      case ASCII_SQL:
 
190
        return db2TableNameAscii; break;
 
191
        break;
 
192
      default:
 
193
        DBUG_ASSERT(0);
 
194
    }
 
195
    return NULL;
 
196
  }
 
197
  
 
198
  DB2Field& db2Field(int fieldID) const { return db2Fields[fieldID]; }
 
199
  DB2Field& db2Field(const Field* field) const { return db2Field(field->field_index); }
 
200
 
 
201
  void processFormatSpace();
 
202
  
 
203
  void* getFormatSpace(size_t& spaceNeeded)
 
204
  {
 
205
    DBUG_ASSERT(formatSpace == NULL);
 
206
    spaceNeeded = sizeof(format_hdr_t) + mysqlTable->fields * sizeof(DB2Field);
 
207
    formatSpace.alloc(spaceNeeded);
 
208
    return (void*)formatSpace;
 
209
  }  
 
210
  
 
211
  bool isTemporary() const
 
212
  {
 
213
    return isTemporaryTable;
 
214
  }
 
215
  
 
216
  void getDB2QualifiedName(char* to);
 
217
  static void getDB2LibNameFromPath(const char* path, char* lib, NameFormatFlags format=ASCII_SQL);
 
218
  static void getDB2FileNameFromPath(const char* path, char* file, NameFormatFlags format=ASCII_SQL);
 
219
  static void getDB2QualifiedNameFromPath(const char* path, char* to);
 
220
  static int32 appendQualifiedIndexFileName(const char* indexName, 
 
221
                                            const char* tableName, 
 
222
                                            String& to, 
 
223
                                            NameFormatFlags format=ASCII_SQL,
 
224
                                            enum_DB2I_INDEX_TYPE type=typeDefault);
 
225
  
 
226
  uint16 getBlobIdFromField(uint16 fieldID) const
 
227
  {
 
228
    for (int i = 0; i < blobFieldCount; ++i)
 
229
    {
 
230
      if (blobFields[i] == fieldID)
 
231
        return i;
 
232
    }
 
233
    DBUG_ASSERT(0);
 
234
    return 0;
 
235
  }
 
236
    
 
237
  iconv_t& getConversionDefinition(enum_conversionDirection direction,
 
238
                                   uint16 fieldID)
 
239
  {
 
240
    if (conversionDefinitions[direction][fieldID] == (iconv_t)(-1))
 
241
      findConversionDefinition(direction, fieldID);
 
242
    
 
243
    return conversionDefinitions[direction][fieldID];
 
244
  }
 
245
  
 
246
  const db2i_file* dataFile() const
 
247
  {
 
248
    return physicalFile;
 
249
  }
 
250
  
 
251
  const db2i_file* indexFile(uint idx) const
 
252
  {    
 
253
    return logicalFiles[idx];
 
254
  }
 
255
  
 
256
  const char* getFileLevelID() const
 
257
  {
 
258
    return fileLevelID;
 
259
  }
 
260
 
 
261
  static void deleteAssocFiles(const char* name);
 
262
  static void renameAssocFiles(const char* from, const char* to);
 
263
 
 
264
  int fastInitForCreate(const char* path);
 
265
  int initDiscoveredTable(const char* path);
 
266
      
 
267
  uint16* blobFields;
 
268
 
 
269
private: 
 
270
 
 
271
  void findConversionDefinition(enum_conversionDirection direction, uint16 fieldID);
 
272
  static void filenameToTablename(const char* in, char* out, size_t outlen);  
 
273
  static size_t smartFilenameToTableName(const char *in, char* out, size_t outlen);
 
274
  void convertNativeToSQLName(const char* input, 
 
275
                              char* output) 
 
276
  {
 
277
    
 
278
    output[0] = input[0];
 
279
    
 
280
    uint o = 1;
 
281
    uint i = 1;
 
282
    do
 
283
    {
 
284
      output[o++] = input[i];
 
285
      if (input[i] == '"' && input[i+1])
 
286
        output[o++] = '"';
 
287
    } while (input[++i]);
 
288
 
 
289
    output[o] = 0; // This isn't the most user-friendly way to handle overflows,
 
290
                                    // but at least its safe.
 
291
  }
 
292
 
 
293
  bool doFileIDsMatch(const char* path);
 
294
    
 
295
  ValidatedPointer<format_hdr_t> formatSpace;
 
296
  DB2Field* db2Fields;
 
297
  uint64 db2StartId;          // Starting value for identity column
 
298
  uint16 blobFieldCount; // Count of LOB fields in the DB2 table
 
299
  uint* blobFieldActualSizes; // Array of LOB field lengths (actual vs. allocated).
 
300
                              // This is updated as LOBs are read and will contain
 
301
                              // the length of the longest known LOB in that field.
 
302
  iconv_t* conversionDefinitions[2];
 
303
  
 
304
  const TABLE_SHARE* mysqlTable;
 
305
  uint16 logicalFileCount;
 
306
  char* db2LibNameEbcdic; // Quoted and in EBCDIC
 
307
  char* db2LibNameAscii;
 
308
  char* db2TableNameEbcdic;
 
309
  char* db2TableNameAscii;
 
310
  char* db2TableNameSQLAscii;
 
311
  char* db2LibNameSQLAscii;
 
312
          
 
313
  db2i_file* physicalFile;
 
314
  db2i_file** logicalFiles;
 
315
  
 
316
  bool isTemporaryTable;
 
317
  char fileLevelID[13];
 
318
};
 
319
 
 
320
/**
 
321
  @class db2i_file
 
322
 
 
323
  @details  This class describes a file object underlaying a particular SQL
 
324
  table. Both "physical files" (data) and "logical files" (indices) are
 
325
  described by this class. Only one instance of the class exists per DB2 file
 
326
  object. The single instance is responsible for de/allocating the multiple
 
327
  handles used by the handlers.
 
328
*/
 
329
class db2i_file
 
330
{
 
331
 
 
332
public: 
 
333
  struct RowFormat
 
334
  {
 
335
    uint16 readRowLen;
 
336
    uint16 readRowNullOffset;
 
337
    uint16 writeRowLen;
 
338
    uint16 writeRowNullOffset;
 
339
    char inited;
 
340
  };
 
341
  
 
342
public:
 
343
 
 
344
  // Construct an instance for a physical file.
 
345
  db2i_file(db2i_table* table);
 
346
    
 
347
  // Construct an instance for a logical file.
 
348
  db2i_file(db2i_table* table, int index);
 
349
   
 
350
  ~db2i_file()
 
351
  {
 
352
    if (masterDefn)
 
353
      db2i_ileBridge::getBridgeForThread()->deallocateFile(masterDefn);
 
354
    
 
355
    if (db2FileName != (char*)db2Table->getDB2TableName(db2i_table::EBCDIC_NATIVE))
 
356
      my_free(db2FileName, MYF(0));    
 
357
  }
 
358
 
 
359
  // This is roughly equivalent to an "open". It tells ILE to allocate a descriptor
 
360
  // for the file. The associated handle is returned to the caller.
 
361
  int allocateNewInstance(FILE_HANDLE* newHandle, ILEMemHandle inuseSpace) const
 
362
  {
 
363
    int rc;
 
364
    
 
365
    rc = db2i_ileBridge::getBridgeForThread()->allocateFileInstance(masterDefn,
 
366
                                                                    inuseSpace,
 
367
                                                                    newHandle);
 
368
    
 
369
    if (rc) *newHandle = 0;
 
370
       
 
371
    return rc;
 
372
  }
 
373
  
 
374
  // This obtains the row layout associated with a particular access intent for
 
375
  // an open instance of the file.
 
376
  int obtainRowFormat(FILE_HANDLE instanceHandle, 
 
377
                       char intent,
 
378
                       char commitLevel,
 
379
                       const RowFormat** activeFormat) const
 
380
  {
 
381
    DBUG_ENTER("db2i_file::obtainRowFormat");    
 
382
    RowFormat* rowFormat;
 
383
        
 
384
    if (intent == QMY_UPDATABLE)
 
385
      rowFormat = &(formats[readWrite]);
 
386
    else if (intent == QMY_READ_ONLY)
 
387
      rowFormat = &(formats[readOnly]);
 
388
        
 
389
    if (unlikely(!rowFormat->inited))
 
390
    {
 
391
      int rc = db2i_ileBridge::getBridgeForThread()->
 
392
                                 initFileForIO(instanceHandle,
 
393
                                               intent,
 
394
                                               commitLevel,
 
395
                                               &(rowFormat->writeRowLen),
 
396
                                               &(rowFormat->writeRowNullOffset),
 
397
                                               &(rowFormat->readRowLen),
 
398
                                               &(rowFormat->readRowNullOffset));
 
399
      if (rc) DBUG_RETURN(rc);
 
400
      rowFormat->inited = 1;
 
401
    }
 
402
 
 
403
    *activeFormat = rowFormat;
 
404
    DBUG_RETURN(0);
 
405
  }  
 
406
    
 
407
  const char* getDB2FileName() const
 
408
  {
 
409
    return db2FileName; 
 
410
  }
 
411
  
 
412
  void fillILEDefn(ShrDef* defn, bool readInArrivalSeq);
 
413
 
 
414
  void setMasterDefnHandle(FILE_HANDLE handle)
 
415
  {
 
416
    masterDefn = handle;
 
417
  }
 
418
  
 
419
  FILE_HANDLE getMasterDefnHandle() const 
 
420
  {
 
421
    return masterDefn;
 
422
  }
 
423
  
 
424
private:  
 
425
  enum RowFormats
 
426
  {
 
427
    readOnly = 0,
 
428
    readWrite,
 
429
    maxRowFormats
 
430
  };
 
431
    
 
432
  mutable RowFormat formats[maxRowFormats];
 
433
  
 
434
  void commonCtorInit();
 
435
  
 
436
  char* db2FileName; // Quoted and in EBCDIC
 
437
 
 
438
  db2i_table* db2Table;  // The logical SQL table contained by this file.
 
439
  
 
440
  bool db2CanSort;
 
441
  
 
442
  FILE_HANDLE masterDefn;
 
443
};
 
444
 
 
445
 
 
446
#endif