2
Licensed Materials - Property of IBM
3
DB2 Storage Engine Enablement
4
Copyright IBM Corporation 2007,2008
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
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
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
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"
47
const char FID_EXT[] = ".FID";
58
ILEMemHandle dataHandle;
66
uint16 getType() const { return *(uint16*)(&definition.ColType); }
67
uint16 getByteLengthInRecord() const { return definition.ColLen; }
68
uint16 getDataLengthInRecord() const
70
return (getType() == QMY_VARCHAR || getType() == QMY_VARGRAPHIC ? definition.ColLen - 2 : definition.ColLen);
72
uint16 getCCSID() const { return *(uint16*)(&definition.ColCCSID); }
75
uint16 type = getType();
76
return (type == QMY_BLOBCLOB || type == QMY_DBCLOB);
78
uint16 getBufferOffset() const { return definition.ColBufOff; }
79
uint16 calcBlobPad() const
81
DBUG_ASSERT(isBlob());
82
return getByteLengthInRecord() - sizeof (DB2LobField);
84
DB2LobField* asBlobField(char* buf) const
86
DBUG_ASSERT(isBlob());
87
return (DB2LobField*)(buf + getBufferOffset() + calcBlobPad());
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.
113
db2i_table(const TABLE_SHARE* myTable, const char* path = NULL);
117
int32 initDB2Objects(const char* path);
119
const TABLE_SHARE* getMySQLTable() const
124
uint64 getStartId() const
129
void updateStartId(uint64 newStartId)
131
db2StartId = newStartId;
134
bool hasBlobs() const
136
return (blobFieldCount > 0);
139
uint16 getBlobCount() const
141
return blobFieldCount;
144
uint getBlobFieldActualSize(uint fieldIndex) const
146
return blobFieldActualSizes[getBlobIdFromField(fieldIndex)];
149
void updateBlobFieldActualSize(uint fieldIndex, uint32 newSize)
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,
154
uint16 blobID = getBlobIdFromField(fieldIndex);
155
DBUG_ASSERT(blobID < blobFieldCount);
157
if (blobFieldActualSizes[blobID] < newSize)
159
blobFieldActualSizes[blobID] = newSize;
165
const char* getDB2LibName(NameFormatFlags format = EBCDIC_NATIVE)
170
return db2LibNameEbcdic; break;
172
return db2LibNameAscii; break;
174
return db2LibNameSQLAscii; break;
181
const char* getDB2TableName(NameFormatFlags format = EBCDIC_NATIVE) const
186
return db2TableNameEbcdic; break;
188
return db2TableNameAscii; break;
190
return db2TableNameAscii; break;
198
DB2Field& db2Field(int fieldID) const { return db2Fields[fieldID]; }
199
DB2Field& db2Field(const Field* field) const { return db2Field(field->field_index); }
201
void processFormatSpace();
203
void* getFormatSpace(size_t& spaceNeeded)
205
DBUG_ASSERT(formatSpace == NULL);
206
spaceNeeded = sizeof(format_hdr_t) + mysqlTable->fields * sizeof(DB2Field);
207
formatSpace.alloc(spaceNeeded);
208
return (void*)formatSpace;
211
bool isTemporary() const
213
return isTemporaryTable;
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,
223
NameFormatFlags format=ASCII_SQL,
224
enum_DB2I_INDEX_TYPE type=typeDefault);
226
uint16 getBlobIdFromField(uint16 fieldID) const
228
for (int i = 0; i < blobFieldCount; ++i)
230
if (blobFields[i] == fieldID)
237
iconv_t& getConversionDefinition(enum_conversionDirection direction,
240
if (conversionDefinitions[direction][fieldID] == (iconv_t)(-1))
241
findConversionDefinition(direction, fieldID);
243
return conversionDefinitions[direction][fieldID];
246
const db2i_file* dataFile() const
251
const db2i_file* indexFile(uint idx) const
253
return logicalFiles[idx];
256
const char* getFileLevelID() const
261
static void deleteAssocFiles(const char* name);
262
static void renameAssocFiles(const char* from, const char* to);
264
int fastInitForCreate(const char* path);
265
int initDiscoveredTable(const char* path);
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,
278
output[0] = input[0];
284
output[o++] = input[i];
285
if (input[i] == '"' && input[i+1])
287
} while (input[++i]);
289
output[o] = 0; // This isn't the most user-friendly way to handle overflows,
290
// but at least its safe.
293
bool doFileIDsMatch(const char* path);
295
ValidatedPointer<format_hdr_t> formatSpace;
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];
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;
313
db2i_file* physicalFile;
314
db2i_file** logicalFiles;
316
bool isTemporaryTable;
317
char fileLevelID[13];
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.
336
uint16 readRowNullOffset;
338
uint16 writeRowNullOffset;
344
// Construct an instance for a physical file.
345
db2i_file(db2i_table* table);
347
// Construct an instance for a logical file.
348
db2i_file(db2i_table* table, int index);
353
db2i_ileBridge::getBridgeForThread()->deallocateFile(masterDefn);
355
if (db2FileName != (char*)db2Table->getDB2TableName(db2i_table::EBCDIC_NATIVE))
356
my_free(db2FileName, MYF(0));
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
365
rc = db2i_ileBridge::getBridgeForThread()->allocateFileInstance(masterDefn,
369
if (rc) *newHandle = 0;
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,
379
const RowFormat** activeFormat) const
381
DBUG_ENTER("db2i_file::obtainRowFormat");
382
RowFormat* rowFormat;
384
if (intent == QMY_UPDATABLE)
385
rowFormat = &(formats[readWrite]);
386
else if (intent == QMY_READ_ONLY)
387
rowFormat = &(formats[readOnly]);
389
if (unlikely(!rowFormat->inited))
391
int rc = db2i_ileBridge::getBridgeForThread()->
392
initFileForIO(instanceHandle,
395
&(rowFormat->writeRowLen),
396
&(rowFormat->writeRowNullOffset),
397
&(rowFormat->readRowLen),
398
&(rowFormat->readRowNullOffset));
399
if (rc) DBUG_RETURN(rc);
400
rowFormat->inited = 1;
403
*activeFormat = rowFormat;
407
const char* getDB2FileName() const
412
void fillILEDefn(ShrDef* defn, bool readInArrivalSeq);
414
void setMasterDefnHandle(FILE_HANDLE handle)
419
FILE_HANDLE getMasterDefnHandle() const
432
mutable RowFormat formats[maxRowFormats];
434
void commonCtorInit();
436
char* db2FileName; // Quoted and in EBCDIC
438
db2i_table* db2Table; // The logical SQL table contained by this file.
442
FILE_HANDLE masterDefn;