Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
c61fab93
Commit
c61fab93
authored
Mar 09, 2009
by
Timothy Smith
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import the ibmdb2i-ga4-src snapshot from IBM
parent
9c3c97db
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
837 additions
and
301 deletions
+837
-301
storage/ibmdb2i/db2i_blobCollection.h
storage/ibmdb2i/db2i_blobCollection.h
+5
-0
storage/ibmdb2i/db2i_charsetSupport.cc
storage/ibmdb2i/db2i_charsetSupport.cc
+1
-1
storage/ibmdb2i/db2i_collationSupport.cc
storage/ibmdb2i/db2i_collationSupport.cc
+9
-10
storage/ibmdb2i/db2i_collationSupport.h
storage/ibmdb2i/db2i_collationSupport.h
+4
-1
storage/ibmdb2i/db2i_constraints.cc
storage/ibmdb2i/db2i_constraints.cc
+2
-3
storage/ibmdb2i/db2i_conversion.cc
storage/ibmdb2i/db2i_conversion.cc
+310
-32
storage/ibmdb2i/db2i_errors.cc
storage/ibmdb2i/db2i_errors.cc
+3
-2
storage/ibmdb2i/db2i_errors.h
storage/ibmdb2i/db2i_errors.h
+4
-2
storage/ibmdb2i/db2i_file.cc
storage/ibmdb2i/db2i_file.cc
+58
-15
storage/ibmdb2i/db2i_file.h
storage/ibmdb2i/db2i_file.h
+29
-24
storage/ibmdb2i/db2i_ileBridge.cc
storage/ibmdb2i/db2i_ileBridge.cc
+14
-3
storage/ibmdb2i/db2i_ileBridge.h
storage/ibmdb2i/db2i_ileBridge.h
+19
-8
storage/ibmdb2i/db2i_ioBuffers.cc
storage/ibmdb2i/db2i_ioBuffers.cc
+1
-1
storage/ibmdb2i/db2i_ioBuffers.h
storage/ibmdb2i/db2i_ioBuffers.h
+8
-3
storage/ibmdb2i/db2i_misc.h
storage/ibmdb2i/db2i_misc.h
+12
-0
storage/ibmdb2i/db2i_rir.cc
storage/ibmdb2i/db2i_rir.cc
+35
-11
storage/ibmdb2i/ha_ibmdb2i.cc
storage/ibmdb2i/ha_ibmdb2i.cc
+274
-159
storage/ibmdb2i/ha_ibmdb2i.h
storage/ibmdb2i/ha_ibmdb2i.h
+49
-26
No files found.
storage/ibmdb2i/db2i_blobCollection.h
View file @
c61fab93
...
@@ -65,6 +65,11 @@ class ProtectedBuffer
...
@@ -65,6 +65,11 @@ class ProtectedBuffer
len
=
size
;
len
=
size
;
if
(
protectBuf
)
if
(
protectBuf
)
mprotect
(
protectedPage
(),
0x1000
,
PROT_NONE
);
mprotect
(
protectedPage
(),
0x1000
,
PROT_NONE
);
#ifndef DBUG_OFF
// Prevents a problem with DBUG_PRINT over-reading in recent versions of
// MySQL
*
((
char
*
)
protectedPage
()
-
1
)
=
0
;
#endif
}
}
}
}
...
...
storage/ibmdb2i/db2i_charsetSupport.cc
View file @
c61fab93
...
@@ -703,7 +703,7 @@ static int32 openNewConversion(enum_conversionDirection direction,
...
@@ -703,7 +703,7 @@ static int32 openNewConversion(enum_conversionDirection direction,
*/
*/
int32
getConversion
(
enum_conversionDirection
direction
,
const
CHARSET_INFO
*
cs
,
uint16
db2CCSID
,
iconv_t
&
conversion
)
int32
getConversion
(
enum_conversionDirection
direction
,
const
CHARSET_INFO
*
cs
,
uint16
db2CCSID
,
iconv_t
&
conversion
)
{
{
DBUG_ENTER
(
"db2i_charsetSupport::
convChars
"
);
DBUG_ENTER
(
"db2i_charsetSupport::
getConversion
"
);
int32
rc
;
int32
rc
;
...
...
storage/ibmdb2i/db2i_collationSupport.cc
View file @
c61fab93
...
@@ -277,33 +277,32 @@ static int32 getAssociatedSortSequence(const CHARSET_INFO *fieldCharSet, const c
...
@@ -277,33 +277,32 @@ static int32 getAssociatedSortSequence(const CHARSET_INFO *fieldCharSet, const c
This function accumulates information about a key as it is called for each
This function accumulates information about a key as it is called for each
field composing the key. The caller should invoke the function for each field
field composing the key. The caller should invoke the function for each field
and (with the exception of the c
urField
parm) preserve the values for the
and (with the exception of the c
harset
parm) preserve the values for the
parms across invocations, until a particular key has been evaluated. Once
parms across invocations, until a particular key has been evaluated. Once
the last field in the key has been evaluated, the fileSortSequence and
the last field in the key has been evaluated, the fileSortSequence and
fileSortSequenceLibrary parms will contain the correct information for
fileSortSequenceLibrary parms will contain the correct information for
creating the corresponding DB2 key.
creating the corresponding DB2 key.
@param c
urField The field
under consideration
@param c
harset The character set
under consideration
@param[in, out] fileSortSequenceType The type of the current key's sort seq
@param[in, out] fileSortSequenceType The type of the current key's sort seq
@param[in, out] fileSortSequence The IBM i identifier for the DB2 sort sequence
@param[in, out] fileSortSequence The IBM i identifier for the DB2 sort sequence
that corresponds
that corresponds
@return 0 if successful. Failure otherwise
@return 0 if successful. Failure otherwise
*/
*/
int32
updateAssociatedSortSequence
(
const
Field
*
curField
,
int32
updateAssociatedSortSequence
(
const
CHARSET_INFO
*
charset
,
char
*
fileSortSequenceType
,
char
*
fileSortSequenceType
,
char
*
fileSortSequence
,
char
*
fileSortSequence
,
char
*
fileSortSequenceLibrary
)
char
*
fileSortSequenceLibrary
)
{
{
DBUG_ENTER
(
"ha_ibmdb2i::updateAssociatedSortSequence"
);
DBUG_ENTER
(
"ha_ibmdb2i::updateAssociatedSortSequence"
);
DBUG_ASSERT
(
curField
);
DBUG_ASSERT
(
charset
);
CHARSET_INFO
*
fieldCharSet
=
curField
->
charset
();
if
(
strcmp
(
charset
->
csname
,
"binary"
)
!=
0
)
if
(
strcmp
(
fieldCharSet
->
csname
,
"binary"
)
!=
0
)
{
{
char
newSortSequence
[
11
]
=
""
;
char
newSortSequence
[
11
]
=
""
;
char
newSortSequenceType
=
' '
;
char
newSortSequenceType
=
' '
;
const
char
*
foundSortSequence
;
const
char
*
foundSortSequence
;
int
rc
=
getAssociatedSortSequence
(
fieldCharS
et
,
&
foundSortSequence
);
int
rc
=
getAssociatedSortSequence
(
chars
et
,
&
foundSortSequence
);
if
(
rc
)
DBUG_RETURN
(
rc
);
if
(
rc
)
DBUG_RETURN
(
rc
);
switch
(
foundSortSequence
[
0
])
switch
(
foundSortSequence
[
0
])
{
{
...
@@ -313,11 +312,11 @@ int32 updateAssociatedSortSequence(const Field *curField,
...
@@ -313,11 +312,11 @@ int32 updateAssociatedSortSequence(const Field *curField,
break
;
break
;
case
'Q'
:
// Non-ICU sort sequence
case
'Q'
:
// Non-ICU sort sequence
strcat
(
newSortSequence
,
foundSortSequence
);
strcat
(
newSortSequence
,
foundSortSequence
);
if
((
fieldCharS
et
->
state
&
MY_CS_BINSORT
)
!=
0
)
if
((
chars
et
->
state
&
MY_CS_BINSORT
)
!=
0
)
{
{
strcat
(
newSortSequence
,
"U"
);
strcat
(
newSortSequence
,
"U"
);
}
}
else
if
((
fieldCharS
et
->
state
&
MY_CS_CSSORT
)
!=
0
)
else
if
((
chars
et
->
state
&
MY_CS_CSSORT
)
!=
0
)
{
{
strcat
(
newSortSequence
,
"U"
);
strcat
(
newSortSequence
,
"U"
);
}
}
...
@@ -329,7 +328,7 @@ int32 updateAssociatedSortSequence(const Field *curField,
...
@@ -329,7 +328,7 @@ int32 updateAssociatedSortSequence(const Field *curField,
break
;
break
;
default:
// ICU sort sequence
default:
// ICU sort sequence
{
{
if
((
fieldCharS
et
->
state
&
MY_CS_CSSORT
)
==
0
)
if
((
chars
et
->
state
&
MY_CS_CSSORT
)
==
0
)
{
{
if
(
osVersion
.
v
>=
6
)
if
(
osVersion
.
v
>=
6
)
strcat
(
newSortSequence
,
"I34"
);
// ICU 3.4
strcat
(
newSortSequence
,
"I34"
);
// ICU 3.4
...
...
storage/ibmdb2i/db2i_collationSupport.h
View file @
c61fab93
...
@@ -40,6 +40,9 @@ OF SUCH DAMAGE.
...
@@ -40,6 +40,9 @@ OF SUCH DAMAGE.
#include "db2i_global.h"
#include "db2i_global.h"
#include "mysql_priv.h"
#include "mysql_priv.h"
int32
updateAssociatedSortSequence
(
const
Field
*
curField
,
char
*
fileSortSequenceType
,
char
*
fileSortSequence
,
char
*
fileSortSequenceLibrary
);
int32
updateAssociatedSortSequence
(
const
CHARSET_INFO
*
charset
,
char
*
fileSortSequenceType
,
char
*
fileSortSequence
,
char
*
fileSortSequenceLibrary
);
#endif
#endif
storage/ibmdb2i/db2i_constraints.cc
View file @
c61fab93
...
@@ -150,7 +150,7 @@ int ha_ibmdb2i::buildDB2ConstraintString(LEX* lex,
...
@@ -150,7 +150,7 @@ int ha_ibmdb2i::buildDB2ConstraintString(LEX* lex,
{
{
if
(
strcmp
((
*
field
)
->
field_name
,
curColumn
->
field_name
)
==
0
)
if
(
strcmp
((
*
field
)
->
field_name
,
curColumn
->
field_name
)
==
0
)
{
{
int
rc
=
updateAssociatedSortSequence
((
*
field
),
int
rc
=
updateAssociatedSortSequence
((
*
field
)
->
charset
()
,
fileSortSequenceType
,
fileSortSequenceType
,
fileSortSequence
,
fileSortSequence
,
fileSortSequenceLibrary
);
fileSortSequenceLibrary
);
...
@@ -447,14 +447,13 @@ int ha_ibmdb2i::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_lis
...
@@ -447,14 +447,13 @@ int ha_ibmdb2i::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_lis
cst_name
*
fieldName
;
// Pointer to field name structure
cst_name
*
fieldName
;
// Pointer to field name structure
const
char
*
method
;
const
char
*
method
;
ulong
methodLen
;
ulong
methodLen
;
bool
gotShare
=
FALSE
;
// Indicator for local get_share
char
*
tempPtr
;
// Temp pointer for traversing constraint space
char
*
tempPtr
;
// Temp pointer for traversing constraint space
char
convName
[
128
];
char
convName
[
128
];
// Allocate space to retrieve the DB2 constraint information.
if
(
!
(
share
=
get_share
(
table_share
->
path
.
str
,
table
)))
if
(
!
(
share
=
get_share
(
table_share
->
path
.
str
,
table
)))
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
// Allocate space to retrieve the DB2 constraint information.
constraintSpaceLength
=
5000
;
// Try allocating 5000 bytes and see if enough.
constraintSpaceLength
=
5000
;
// Try allocating 5000 bytes and see if enough.
constraintSpace
.
alloc
(
constraintSpaceLength
);
constraintSpace
.
alloc
(
constraintSpaceLength
);
...
...
storage/ibmdb2i/db2i_conversion.cc
View file @
c61fab93
...
@@ -43,6 +43,12 @@ OF SUCH DAMAGE.
...
@@ -43,6 +43,12 @@ OF SUCH DAMAGE.
#include "db2i_errors.h"
#include "db2i_errors.h"
#include "wchar.h"
#include "wchar.h"
const
char
ZERO_DATETIME_VALUE
[]
=
"0000-00-00 00:00:00"
;
const
char
ZERO_DATETIME_VALUE_SUBST
[]
=
"0001-01-01 00:00:00"
;
const
char
ZERO_DATE_VALUE
[]
=
"0000-00-00"
;
const
char
ZERO_DATE_VALUE_SUBST
[]
=
"0001-01-01"
;
/**
/**
Put a BCD digit into a BCD string.
Put a BCD digit into a BCD string.
...
@@ -149,7 +155,6 @@ int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction,
...
@@ -149,7 +155,6 @@ int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction,
}
}
size_t
initOLen
=
olen
;
size_t
initOLen
=
olen
;
ilen
=
min
(
ilen
,
olen
);
// Handle partial translation
size_t
substitutedChars
=
0
;
size_t
substitutedChars
=
0
;
int
rc
=
iconv
(
conversion
,
(
char
**
)
&
input
,
&
ilen
,
&
output
,
&
olen
,
&
substitutedChars
);
int
rc
=
iconv
(
conversion
,
(
char
**
)
&
input
,
&
ilen
,
&
output
,
&
olen
,
&
substitutedChars
);
if
(
unlikely
(
rc
<
0
))
if
(
unlikely
(
rc
<
0
))
...
@@ -176,6 +181,178 @@ int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction,
...
@@ -176,6 +181,178 @@ int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction,
return
(
0
);
return
(
0
);
}
}
/**
Append the appropriate default value clause onto a CREATE TABLE definition
This was inspired by get_field_default_value in sql/sql_show.cc.
@param field The field whose value is to be obtained
@param statement The string to receive the DEFAULT clause
@param quoteIt Does the data type require single quotes around the value?
@param ccsid The ccsid of the field value (if a string type); 0 if no conversion needed
*/
static
void
get_field_default_value
(
Field
*
field
,
String
&
statement
,
bool
quoteIt
,
uint32
ccsid
,
bool
substituteZeroDates
)
{
if
((
field
->
type
()
!=
FIELD_TYPE_BLOB
&&
!
(
field
->
flags
&
NO_DEFAULT_VALUE_FLAG
)
&&
field
->
unireg_check
!=
Field
::
NEXT_NUMBER
))
{
my_ptrdiff_t
old_ptr
=
(
my_ptrdiff_t
)
(
field
->
table
->
s
->
default_values
-
field
->
table
->
record
[
0
]);
field
->
move_field_offset
(
old_ptr
);
String
defaultClause
(
64
);
defaultClause
.
length
(
0
);
defaultClause
.
append
(
" DEFAULT "
);
if
(
!
field
->
is_null
())
{
my_bitmap_map
*
old_map
=
tmp_use_all_columns
(
field
->
table
,
field
->
table
->
read_set
);
char
tmp
[
MAX_FIELD_WIDTH
];
if
(
field
->
real_type
()
==
MYSQL_TYPE_ENUM
||
field
->
real_type
()
==
MYSQL_TYPE_SET
)
{
CHARSET_INFO
*
cs
=
&
my_charset_bin
;
uint
len
=
(
uint
)(
cs
->
cset
->
longlong10_to_str
)(
cs
,
tmp
,
sizeof
(
tmp
),
10
,
field
->
val_int
());
tmp
[
len
]
=
0
;
defaultClause
.
append
(
tmp
);
}
else
{
String
type
(
tmp
,
sizeof
(
tmp
),
field
->
charset
());
field
->
val_str
(
&
type
);
if
(
type
.
length
())
{
if
(
field
->
type
()
==
MYSQL_TYPE_DATE
&&
memcmp
(
type
.
ptr
(),
STRING_WITH_LEN
(
ZERO_DATE_VALUE
))
==
0
)
{
if
(
substituteZeroDates
)
type
.
set
(
STRING_WITH_LEN
(
ZERO_DATE_VALUE_SUBST
),
field
->
charset
());
else
{
warning
(
current_thd
,
DB2I_ERR_WARN_COL_ATTRS
,
field
->
field_name
);
return
;
}
}
else
if
((
field
->
type
()
==
MYSQL_TYPE_DATETIME
||
field
->
type
()
==
MYSQL_TYPE_TIMESTAMP
)
&&
memcmp
(
type
.
ptr
(),
STRING_WITH_LEN
(
ZERO_DATETIME_VALUE
))
==
0
)
{
if
(
substituteZeroDates
)
type
.
set
(
STRING_WITH_LEN
(
ZERO_DATETIME_VALUE_SUBST
),
field
->
charset
());
else
{
warning
(
current_thd
,
DB2I_ERR_WARN_COL_ATTRS
,
field
->
field_name
);
return
;
}
}
if
(
field
->
type
()
!=
MYSQL_TYPE_STRING
&&
field
->
type
()
!=
MYSQL_TYPE_VARCHAR
&&
field
->
type
()
!=
MYSQL_TYPE_BLOB
&&
field
->
type
()
!=
MYSQL_TYPE_BIT
)
{
if
(
quoteIt
)
defaultClause
.
append
(
'\''
);
defaultClause
.
append
(
type
);
if
(
quoteIt
)
defaultClause
.
append
(
'\''
);
}
else
{
int
length
;
char
*
out
;
// If a ccsid is specified, we need to make sure that the DEFAULT
// string is converted to that encoding.
if
(
ccsid
!=
0
)
{
iconv_t
iconvD
;
if
(
getConversion
(
toDB2
,
field
->
charset
(),
ccsid
,
iconvD
))
{
warning
(
current_thd
,
DB2I_ERR_WARN_COL_ATTRS
,
field
->
field_name
);
return
;
}
size_t
ilen
=
type
.
length
();
size_t
olen
=
6
*
ilen
;
size_t
origOlen
=
olen
;
const
char
*
in
=
type
.
ptr
();
const
char
*
tempIn
=
in
;
out
=
(
char
*
)
my_malloc
(
olen
,
MYF
(
MY_WME
));
char
*
tempOut
=
out
;
size_t
substitutedChars
;
if
(
iconv
(
iconvD
,
(
char
**
)
&
tempIn
,
&
ilen
,
&
tempOut
,
&
olen
,
&
substitutedChars
)
<
0
)
{
warning
(
current_thd
,
DB2I_ERR_WARN_COL_ATTRS
,
field
->
field_name
);
my_free
(
out
,
MYF
(
0
));
return
;
}
// Now we process the converted string to represent it as
// hexadecimal values.
length
=
origOlen
-
olen
;
}
else
{
length
=
type
.
length
();
out
=
(
char
*
)
my_malloc
(
length
*
2
,
MYF
(
MY_WME
));
memcpy
(
out
,
(
char
*
)
type
.
ptr
(),
length
);
}
if
(
length
>
16370
)
{
warning
(
current_thd
,
DB2I_ERR_WARN_COL_ATTRS
,
field
->
field_name
);
my_free
(
out
,
MYF
(
0
));
return
;
}
if
(
ccsid
==
1200
)
defaultClause
.
append
(
"ux'"
);
else
if
(
ccsid
==
13488
)
defaultClause
.
append
(
"gx'"
);
else
if
(
field
->
charset
()
==
&
my_charset_bin
)
defaultClause
.
append
(
"binary(x'"
);
else
defaultClause
.
append
(
"x'"
);
const
char
hexMap
[]
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
};
for
(
int
c
=
length
-
1
;
c
>=
0
;
--
c
)
{
out
[
c
*
2
+
1
]
=
hexMap
[
out
[
c
]
&
0xF
];
out
[
c
*
2
]
=
hexMap
[
out
[
c
]
>>
4
];
}
defaultClause
.
append
(
out
,
length
*
2
);
defaultClause
.
append
(
'\''
);
if
(
field
->
charset
()
==
&
my_charset_bin
)
defaultClause
.
append
(
")"
);
my_free
(
out
,
MYF
(
0
));
}
}
else
defaultClause
.
length
(
0
);
}
tmp_restore_column_map
(
field
->
table
->
read_set
,
old_map
);
}
else
if
(
field
->
maybe_null
())
defaultClause
.
append
(
STRING_WITH_LEN
(
"NULL"
));
if
(
old_ptr
)
field
->
move_field_offset
(
-
old_ptr
);
statement
.
append
(
defaultClause
);
}
}
/**
/**
Convert a MySQL field definition into its corresponding DB2 type.
Convert a MySQL field definition into its corresponding DB2 type.
...
@@ -189,10 +366,15 @@ int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction,
...
@@ -189,10 +366,15 @@ int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction,
int
ha_ibmdb2i
::
getFieldTypeMapping
(
Field
*
field
,
int
ha_ibmdb2i
::
getFieldTypeMapping
(
Field
*
field
,
String
&
mapping
,
String
&
mapping
,
enum_TimeFormat
timeFormat
,
enum_TimeFormat
timeFormat
,
enum_BlobMapping
blobMapping
)
enum_BlobMapping
blobMapping
,
enum_ZeroDate
zeroDateHandling
,
bool
propagateDefaults
,
enum_YearFormat
yearFormat
)
{
{
char
stringBuildBuffer
[
257
];
char
stringBuildBuffer
[
257
];
uint32
fieldLength
;
uint32
fieldLength
;
bool
defaultNeedsQuotes
=
false
;
uint16
db2Ccsid
=
0
;
CHARSET_INFO
*
fieldCharSet
=
field
->
charset
();
CHARSET_INFO
*
fieldCharSet
=
field
->
charset
();
switch
(
field
->
type
())
switch
(
field
->
type
())
...
@@ -257,19 +439,69 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
...
@@ -257,19 +439,69 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
case
MYSQL_TYPE_DATE
:
case
MYSQL_TYPE_DATE
:
case
MYSQL_TYPE_NEWDATE
:
case
MYSQL_TYPE_NEWDATE
:
mapping
.
append
(
STRING_WITH_LEN
(
"DATE"
));
mapping
.
append
(
STRING_WITH_LEN
(
"DATE"
));
defaultNeedsQuotes
=
true
;
break
;
break
;
case
MYSQL_TYPE_TIME
:
case
MYSQL_TYPE_TIME
:
if
(
timeFormat
==
TIME_OF_DAY
)
if
(
timeFormat
==
TIME_OF_DAY
)
{
mapping
.
append
(
STRING_WITH_LEN
(
"TIME"
));
mapping
.
append
(
STRING_WITH_LEN
(
"TIME"
));
defaultNeedsQuotes
=
true
;
}
else
else
mapping
.
append
(
STRING_WITH_LEN
(
"INTEGER"
));
mapping
.
append
(
STRING_WITH_LEN
(
"INTEGER"
));
break
;
break
;
case
MYSQL_TYPE_TIMESTAMP
:
case
MYSQL_TYPE_DATETIME
:
case
MYSQL_TYPE_DATETIME
:
mapping
.
append
(
STRING_WITH_LEN
(
"TIMESTAMP"
));
mapping
.
append
(
STRING_WITH_LEN
(
"TIMESTAMP"
));
defaultNeedsQuotes
=
true
;
break
;
case
MYSQL_TYPE_TIMESTAMP
:
mapping
.
append
(
STRING_WITH_LEN
(
"TIMESTAMP"
));
if
(
table_share
->
timestamp_field
==
field
&&
propagateDefaults
)
{
switch
(((
Field_timestamp
*
)
field
)
->
get_auto_set_type
())
{
case
TIMESTAMP_NO_AUTO_SET
:
break
;
case
TIMESTAMP_AUTO_SET_ON_INSERT
:
mapping
.
append
(
STRING_WITH_LEN
(
" DEFAULT CURRENT_TIMESTAMP"
));
break
;
case
TIMESTAMP_AUTO_SET_ON_UPDATE
:
if
(
osVersion
.
v
>=
6
&&
!
field
->
is_null
())
{
mapping
.
append
(
STRING_WITH_LEN
(
" GENERATED BY DEFAULT FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP"
));
warning
(
ha_thd
(),
DB2I_ERR_WARN_COL_ATTRS
,
field
->
field_name
);
}
else
warning
(
ha_thd
(),
DB2I_ERR_WARN_COL_ATTRS
,
field
->
field_name
);
break
;
case
TIMESTAMP_AUTO_SET_ON_BOTH
:
if
(
osVersion
.
v
>=
6
&&
!
field
->
is_null
())
mapping
.
append
(
STRING_WITH_LEN
(
" GENERATED BY DEFAULT FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP"
));
else
{
mapping
.
append
(
STRING_WITH_LEN
(
" DEFAULT CURRENT_TIMESTAMP"
));
warning
(
ha_thd
(),
DB2I_ERR_WARN_COL_ATTRS
,
field
->
field_name
);
}
break
;
}
}
else
defaultNeedsQuotes
=
true
;
break
;
break
;
case
MYSQL_TYPE_YEAR
:
case
MYSQL_TYPE_YEAR
:
if
(
yearFormat
==
CHAR4
)
{
mapping
.
append
(
STRING_WITH_LEN
(
"CHAR(4) CCSID 1208"
));
mapping
.
append
(
STRING_WITH_LEN
(
"CHAR(4) CCSID 1208"
));
defaultNeedsQuotes
=
true
;
}
else
{
mapping
.
append
(
STRING_WITH_LEN
(
"SMALLINT"
));
defaultNeedsQuotes
=
false
;
}
break
;
break
;
case
MYSQL_TYPE_BIT
:
case
MYSQL_TYPE_BIT
:
sprintf
(
stringBuildBuffer
,
"BINARY(%d)"
,
(
field
->
max_display_length
()
/
8
)
+
1
);
sprintf
(
stringBuildBuffer
,
"BINARY(%d)"
,
(
field
->
max_display_length
()
/
8
)
+
1
);
...
@@ -286,6 +518,8 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
...
@@ -286,6 +518,8 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
}
}
else
else
{
{
defaultNeedsQuotes
=
true
;
fieldLength
=
field
->
max_display_length
();
// Get field byte length
fieldLength
=
field
->
max_display_length
();
// Get field byte length
if
(
fieldCharSet
==
&
my_charset_bin
)
if
(
fieldCharSet
==
&
my_charset_bin
)
...
@@ -300,12 +534,11 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
...
@@ -300,12 +534,11 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
{
{
sprintf
(
stringBuildBuffer
,
"VARBINARY(%d)"
,
max
(
fieldLength
,
1
));
sprintf
(
stringBuildBuffer
,
"VARBINARY(%d)"
,
max
(
fieldLength
,
1
));
}
}
/*
else if (blobMapping == AS_VARCHAR &&
else
if
(
blobMapping
==
AS_VARCHAR
&&
get_blob_type_from_length(fieldLength) == MYSQL_TYPE_BLOB
)
(
field
->
flags
&
PART_KEY_FLAG
)
)
{
{
sprintf(stringBuildBuffer, "LONG VARBINARY "
, max(fieldLength, 1)
);
sprintf
(
stringBuildBuffer
,
"LONG VARBINARY "
);
}
}
*/
else
else
{
{
fieldLength
=
min
(
MAX_BLOB_LENGTH
,
fieldLength
);
fieldLength
=
min
(
MAX_BLOB_LENGTH
,
fieldLength
);
...
@@ -316,7 +549,6 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
...
@@ -316,7 +549,6 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
}
}
else
else
{
{
uint16
db2Ccsid
=
0
;
// No override CCSID
if
(
field
->
type
()
==
MYSQL_TYPE_STRING
)
if
(
field
->
type
()
==
MYSQL_TYPE_STRING
)
{
{
if
(
fieldLength
>
MAX_CHAR_LENGTH
)
if
(
fieldLength
>
MAX_CHAR_LENGTH
)
...
@@ -375,7 +607,7 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
...
@@ -375,7 +607,7 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
}
}
}
}
else
if
(
blobMapping
==
AS_VARCHAR
&&
else
if
(
blobMapping
==
AS_VARCHAR
&&
get_blob_type_from_length
(
fieldLength
)
==
MYSQL_TYPE_BLOB
)
(
field
->
flags
&
PART_KEY_FLAG
)
)
{
{
if
(
fieldCharSet
->
mbmaxlen
>
1
)
if
(
fieldCharSet
->
mbmaxlen
>
1
)
{
{
...
@@ -447,6 +679,13 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
...
@@ -447,6 +679,13 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field,
}
}
if
(
propagateDefaults
)
get_field_default_value
(
field
,
mapping
,
defaultNeedsQuotes
,
db2Ccsid
,
(
zeroDateHandling
==
SUBSTITUTE_0001_01_01
));
return
0
;
return
0
;
}
}
...
@@ -552,7 +791,6 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
...
@@ -552,7 +791,6 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
case
MYSQL_TYPE_DATETIME
:
case
MYSQL_TYPE_DATETIME
:
{
{
String
tempString
(
27
);
String
tempString
(
27
);
const
char
*
ZERO_VALUE
=
"0000-00-00 00:00:00"
;
if
(
data
==
NULL
)
if
(
data
==
NULL
)
{
{
field
->
val_str
(
&
tempString
,
&
tempString
);
field
->
val_str
(
&
tempString
,
&
tempString
);
...
@@ -563,11 +801,16 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
...
@@ -563,11 +801,16 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
}
}
memset
(
db2Buf
,
'0'
,
26
);
memset
(
db2Buf
,
'0'
,
26
);
memcpy
(
db2Buf
,
tempString
.
ptr
(),
tempString
.
length
());
memcpy
(
db2Buf
,
tempString
.
ptr
(),
tempString
.
length
());
if
(
strncmp
(
db2Buf
,
ZERO_
VALUE
,
strlen
(
ZERO
_VALUE
))
==
0
)
if
(
strncmp
(
db2Buf
,
ZERO_
DATETIME_VALUE
,
strlen
(
ZERO_DATETIME
_VALUE
))
==
0
)
{
{
getErrTxt
(
DB2I_ERR_INVALID_COL_VALUE
,
ZERO_VALUE
,
field
->
field_name
);
if
(
cachedZeroDateOption
==
SUBSTITUTE_0001_01_01
)
memcpy
(
db2Buf
,
ZERO_DATETIME_VALUE_SUBST
,
sizeof
(
ZERO_DATETIME_VALUE_SUBST
));
else
{
getErrTxt
(
DB2I_ERR_INVALID_COL_VALUE
,
field
->
field_name
);
return
(
DB2I_ERR_INVALID_COL_VALUE
);
return
(
DB2I_ERR_INVALID_COL_VALUE
);
}
}
}
(
db2Buf
)[
10
]
=
'-'
;
(
db2Buf
)[
10
]
=
'-'
;
(
db2Buf
)[
13
]
=
(
db2Buf
)[
16
]
=
(
db2Buf
)[
19
]
=
'.'
;
(
db2Buf
)[
13
]
=
(
db2Buf
)[
16
]
=
(
db2Buf
)[
19
]
=
'.'
;
...
@@ -620,7 +863,6 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
...
@@ -620,7 +863,6 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
case
MYSQL_TYPE_DATE
:
case
MYSQL_TYPE_DATE
:
case
MYSQL_TYPE_NEWDATE
:
case
MYSQL_TYPE_NEWDATE
:
{
{
const
char
*
ZERO_VALUE
=
"0000-00-00"
;
String
tempString
(
11
);
String
tempString
(
11
);
if
(
data
==
NULL
)
if
(
data
==
NULL
)
{
{
...
@@ -631,11 +873,16 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
...
@@ -631,11 +873,16 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
field
->
val_str
(
&
tempString
,
data
);
field
->
val_str
(
&
tempString
,
data
);
}
}
memcpy
(
db2Buf
,
tempString
.
ptr
(),
10
);
memcpy
(
db2Buf
,
tempString
.
ptr
(),
10
);
if
(
strncmp
(
db2Buf
,
ZERO_VALUE
,
strlen
(
ZERO_VALUE
))
==
0
)
if
(
strncmp
(
db2Buf
,
ZERO_DATE_VALUE
,
strlen
(
ZERO_DATE_VALUE
))
==
0
)
{
if
(
cachedZeroDateOption
==
SUBSTITUTE_0001_01_01
)
memcpy
(
db2Buf
,
ZERO_DATE_VALUE_SUBST
,
sizeof
(
ZERO_DATE_VALUE_SUBST
));
else
{
{
getErrTxt
(
DB2I_ERR_INVALID_COL_VALUE
,
ZERO
_VALUE
,
field
->
field_name
);
getErrTxt
(
DB2I_ERR_INVALID_COL
_VALUE
,
field
->
field_name
);
return
(
DB2I_ERR_INVALID_COL_VALUE
);
return
(
DB2I_ERR_INVALID_COL_VALUE
);
}
}
}
convertNumericToEbcdicFast
(
db2Buf
,
10
);
convertNumericToEbcdicFast
(
db2Buf
,
10
);
}
}
...
@@ -668,6 +915,8 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
...
@@ -668,6 +915,8 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
case
MYSQL_TYPE_YEAR
:
case
MYSQL_TYPE_YEAR
:
{
{
String
tempString
(
5
);
String
tempString
(
5
);
if
(
db2Field
.
getType
()
==
QMY_CHAR
)
{
if
(
data
==
NULL
)
if
(
data
==
NULL
)
{
{
field
->
val_str
(
&
tempString
,
(
String
*
)
NULL
);
field
->
val_str
(
&
tempString
,
(
String
*
)
NULL
);
...
@@ -678,10 +927,16 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
...
@@ -678,10 +927,16 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
}
}
memcpy
(
db2Buf
,
tempString
.
ptr
(),
4
);
memcpy
(
db2Buf
,
tempString
.
ptr
(),
4
);
}
}
else
{
uint8
temp
=
*
(
uint8
*
)(
data
==
NULL
?
field
->
ptr
:
data
);
*
(
uint16
*
)(
db2Buf
)
=
(
temp
?
temp
+
1900
:
0
);
}
}
break
;
break
;
case
MYSQL_TYPE_BIT
:
case
MYSQL_TYPE_BIT
:
{
{
int
bytesToCopy
=
(
db2Field
.
getByteLengthInRecord
()
-
1
)
/
8
+
1
;
int
bytesToCopy
=
db2Field
.
getByteLengthInRecord
()
;
if
(
data
==
NULL
)
if
(
data
==
NULL
)
{
{
...
@@ -745,11 +1000,19 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
...
@@ -745,11 +1000,19 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char
break
;
break
;
case
MYSQL_TYPE_BLOB
:
case
MYSQL_TYPE_BLOB
:
{
{
DBUG_ASSERT
(
data
==
NULL
);
if
(
data
==
NULL
)
{
bytesToStore
=
((
Field_blob
*
)
field
)
->
get_length
();
bytesToStore
=
((
Field_blob
*
)
field
)
->
get_length
();
bytesToPad
=
maxDisplayLength
-
bytesToStore
;
bytesToPad
=
maxDisplayLength
-
bytesToStore
;
((
Field_blob
*
)
field
)
->
get_ptr
((
uchar
**
)
&
dataToStore
);
((
Field_blob
*
)
field
)
->
get_ptr
((
uchar
**
)
&
dataToStore
);
}
}
else
{
// Key lens are stored little-endian
bytesToStore
=
*
(
uint8
*
)
data
+
((
*
(
uint8
*
)(
data
+
1
))
<<
8
);
dataToStore
=
data
+
2
;
}
}
break
;
break
;
}
}
...
@@ -1028,6 +1291,10 @@ int32 ha_ibmdb2i::convertDB2toMySQL(const DB2Field& db2Field, Field* field, cons
...
@@ -1028,6 +1291,10 @@ int32 ha_ibmdb2i::convertDB2toMySQL(const DB2Field& db2Field, Field* field, cons
a2toi_ebcdic
((
uchar
*
)
bufPtr
+
5
)
*
100
+
a2toi_ebcdic
((
uchar
*
)
bufPtr
+
5
)
*
100
+
a2toi_ebcdic
((
uchar
*
)
bufPtr
+
8
);
a2toi_ebcdic
((
uchar
*
)
bufPtr
+
8
);
if
(
cachedZeroDateOption
==
SUBSTITUTE_0001_01_01
&&
value
==
(
10000
+
100
+
1
))
value
=
0
;
storeRC
=
field
->
store
(
value
);
storeRC
=
field
->
store
(
value
);
}
}
break
;
break
;
...
@@ -1055,18 +1322,29 @@ int32 ha_ibmdb2i::convertDB2toMySQL(const DB2Field& db2Field, Field* field, cons
...
@@ -1055,18 +1322,29 @@ int32 ha_ibmdb2i::convertDB2toMySQL(const DB2Field& db2Field, Field* field, cons
a2toi_ebcdic
((
uchar
*
)
bufPtr
+
14
)
*
100
+
a2toi_ebcdic
((
uchar
*
)
bufPtr
+
14
)
*
100
+
a2toi_ebcdic
((
uchar
*
)
bufPtr
+
17
));
a2toi_ebcdic
((
uchar
*
)
bufPtr
+
17
));
if
(
cachedZeroDateOption
==
SUBSTITUTE_0001_01_01
&&
value
==
(
10000
+
100
+
1
)
*
1000000LL
)
value
=
0
;
storeRC
=
field
->
store
(
value
);
storeRC
=
field
->
store
(
value
);
}
}
break
;
break
;
case
MYSQL_TYPE_YEAR
:
case
MYSQL_TYPE_YEAR
:
{
if
(
db2Field
.
getType
()
==
QMY_CHAR
)
{
{
storeRC
=
field
->
store
(
bufPtr
,
4
,
&
my_charset_bin
);
storeRC
=
field
->
store
(
bufPtr
,
4
,
&
my_charset_bin
);
}
}
else
{
storeRC
=
field
->
store
(
*
((
uint16
*
)
bufPtr
));
}
}
break
;
break
;
case
MYSQL_TYPE_BIT
:
case
MYSQL_TYPE_BIT
:
{
{
uint64
temp
=
0
;
uint64
temp
=
0
;
int
bytesToCopy
=
(
db2Field
.
getByteLengthInRecord
()
-
1
)
/
8
+
1
;
int
bytesToCopy
=
db2Field
.
getByteLengthInRecord
()
;
memcpy
(((
char
*
)
&
temp
)
+
(
sizeof
(
temp
)
-
bytesToCopy
),
bufPtr
,
bytesToCopy
);
memcpy
(((
char
*
)
&
temp
)
+
(
sizeof
(
temp
)
-
bytesToCopy
),
bufPtr
,
bytesToCopy
);
storeRC
=
field
->
store
(
temp
,
TRUE
);
storeRC
=
field
->
store
(
temp
,
TRUE
);
}
}
...
...
storage/ibmdb2i/db2i_errors.cc
View file @
c61fab93
...
@@ -63,9 +63,9 @@ static const char* engineErrors[MAX_MSGSTRING] =
...
@@ -63,9 +63,9 @@ static const char* engineErrors[MAX_MSGSTRING] =
{
"Error in iconv() function during character set conversion (errno = %d)"
},
{
"Error in iconv() function during character set conversion (errno = %d)"
},
{
"Error from Get Encoding Scheme (QTQGESP) API: %d, %d, %d"
},
{
"Error from Get Encoding Scheme (QTQGESP) API: %d, %d, %d"
},
{
"Error from Get Related Default CCSID (QTQGRDC) API: %d, %d, %d"
},
{
"Error from Get Related Default CCSID (QTQGRDC) API: %d, %d, %d"
},
{
"
Invalid value '%-.128s'
for column '%.192s'"
},
{
"
Data out of range
for column '%.192s'"
},
{
"Schema name '%.128s' exceeds maximum length of %d characters"
},
{
"Schema name '%.128s' exceeds maximum length of %d characters"
},
{
"Multiple collations not supported in a single index"
},
{
"Multiple collations not supported in a single index
or constraint
"
},
{
"Sort sequence was not found"
},
{
"Sort sequence was not found"
},
{
"One or more characters in column %.128s were substituted during conversion"
},
{
"One or more characters in column %.128s were substituted during conversion"
},
{
"A decimal column exceeded the maximum precision. Data may be truncated."
},
{
"A decimal column exceeded the maximum precision. Data may be truncated."
},
...
@@ -76,6 +76,7 @@ static const char* engineErrors[MAX_MSGSTRING] =
...
@@ -76,6 +76,7 @@ static const char* engineErrors[MAX_MSGSTRING] =
{
"A duplicate key was encountered for index '%.128s'"
},
{
"A duplicate key was encountered for index '%.128s'"
},
{
"A table with the same name exists but has incompatible column definitions."
},
{
"A table with the same name exists but has incompatible column definitions."
},
{
"The created table was discovered as an existing DB2 object."
},
{
"The created table was discovered as an existing DB2 object."
},
{
"Some attribute(s) defined for column '%.128s' may not be honored by accesses from DB2."
},
};
};
/*
/*
...
...
storage/ibmdb2i/db2i_errors.h
View file @
c61fab93
...
@@ -78,7 +78,8 @@ enum DB2I_errors
...
@@ -78,7 +78,8 @@ enum DB2I_errors
DB2I_ERR_UNKNOWN_IDX
,
DB2I_ERR_UNKNOWN_IDX
,
DB2I_ERR_DISCOVERY_MISMATCH
,
DB2I_ERR_DISCOVERY_MISMATCH
,
DB2I_ERR_WARN_CREATE_DISCOVER
,
DB2I_ERR_WARN_CREATE_DISCOVER
,
DB2I_LAST_ERR
=
DB2I_ERR_WARN_CREATE_DISCOVER
DB2I_ERR_WARN_COL_ATTRS
,
DB2I_LAST_ERR
=
DB2I_ERR_WARN_COL_ATTRS
};
};
void
getErrTxt
(
int
errcode
,
...);
void
getErrTxt
(
int
errcode
,
...);
...
@@ -86,6 +87,7 @@ void reportSystemAPIError(int errCode, const Qmy_Error_output *errInfo);
...
@@ -86,6 +87,7 @@ void reportSystemAPIError(int errCode, const Qmy_Error_output *errInfo);
void
warning
(
THD
*
thd
,
int
errCode
,
...);
void
warning
(
THD
*
thd
,
int
errCode
,
...);
const
char
*
DB2I_SQL0350
=
"
\xE2\xD8\xD3\xF0\xF3\xF5\xF0
"
;
// SQL0350 in EBCDIC
const
char
*
DB2I_SQL0350
=
"
\xE2\xD8\xD3\xF0\xF3\xF5\xF0
"
;
// SQL0350 in EBCDIC
const
char
*
DB2I_CPF503A
=
"
\xC3\xD7\xC6\xF5\xF0\xF3\xC1
"
;
// CPF503A in EBCDIC
const
char
*
DB2I_SQL0538
=
"
\xE2\xD8\xD3\xF0\xF5\xF3\xF8
"
;
// SQL0538 in EBCDIC
#endif
#endif
storage/ibmdb2i/db2i_file.cc
View file @
c61fab93
...
@@ -97,10 +97,11 @@ int32 db2i_table::initDB2Objects(const char* path)
...
@@ -97,10 +97,11 @@ int32 db2i_table::initDB2Objects(const char* path)
physicalFile
=
new
db2i_file
(
this
);
physicalFile
=
new
db2i_file
(
this
);
physicalFile
->
fillILEDefn
(
&
fileDefnSpace
[
0
],
true
);
physicalFile
->
fillILEDefn
(
&
fileDefnSpace
[
0
],
true
);
if
(
fileObjects
>
1
)
logicalFileCount
=
mysqlTable
->
keys
;
if
(
logicalFileCount
>
0
)
{
{
logicalFiles
=
new
db2i_file
*
[
fileObjects
-
1
];
logicalFiles
=
new
db2i_file
*
[
logicalFileCount
];
for
(
int
k
=
0
;
k
<
mysqlTable
->
keys
;
k
++
)
for
(
int
k
=
0
;
k
<
logicalFileCount
;
k
++
)
{
{
logicalFiles
[
k
]
=
new
db2i_file
(
this
,
k
);
logicalFiles
[
k
]
=
new
db2i_file
(
this
,
k
);
logicalFiles
[
k
]
->
fillILEDefn
(
&
fileDefnSpace
[
k
+
1
],
false
);
logicalFiles
[
k
]
->
fillILEDefn
(
&
fileDefnSpace
[
k
+
1
],
false
);
...
@@ -111,7 +112,9 @@ int32 db2i_table::initDB2Objects(const char* path)
...
@@ -111,7 +112,9 @@ int32 db2i_table::initDB2Objects(const char* path)
size_t
formatSpaceLen
=
sizeof
(
format_hdr_t
)
+
mysqlTable
->
fields
*
sizeof
(
DB2Field
);
size_t
formatSpaceLen
=
sizeof
(
format_hdr_t
)
+
mysqlTable
->
fields
*
sizeof
(
DB2Field
);
formatSpace
.
alloc
(
formatSpaceLen
);
formatSpace
.
alloc
(
formatSpaceLen
);
int
rc
=
db2i_ileBridge
::
getBridgeForThread
()
->
allocateFileDefn
(
fileDefnSpace
,
int
rc
=
db2i_ileBridge
::
getBridgeForThread
()
->
expectErrors
(
QMY_ERR_RTNFMT
)
->
allocateFileDefn
(
fileDefnSpace
,
fileDefnHandles
,
fileDefnHandles
,
fileObjects
,
fileObjects
,
db2LibNameEbcdic
,
db2LibNameEbcdic
,
...
@@ -120,7 +123,18 @@ int32 db2i_table::initDB2Objects(const char* path)
...
@@ -120,7 +123,18 @@ int32 db2i_table::initDB2Objects(const char* path)
formatSpaceLen
);
formatSpaceLen
);
if
(
rc
)
if
(
rc
)
{
// We have to handle a format space error as a special case of a FID
// mismatch. We should only get the space error if columns have been added
// to the DB2 table without MySQL's knowledge, which is effectively a
// FID problem.
if
(
rc
==
QMY_ERR_RTNFMT
)
{
rc
=
QMY_ERR_LVLID_MISMATCH
;
getErrTxt
(
rc
);
}
return
rc
;
return
rc
;
}
convFromEbcdic
(((
format_hdr_t
*
)
formatSpace
)
->
FilLvlId
,
fileLevelID
,
sizeof
(
fileLevelID
));
convFromEbcdic
(((
format_hdr_t
*
)
formatSpace
)
->
FilLvlId
,
fileLevelID
,
sizeof
(
fileLevelID
));
...
@@ -274,7 +288,7 @@ db2i_table::~db2i_table()
...
@@ -274,7 +288,7 @@ db2i_table::~db2i_table()
if
(
logicalFiles
)
if
(
logicalFiles
)
{
{
for
(
int
k
=
0
;
k
<
mysqlTable
->
keys
;
++
k
)
for
(
int
k
=
0
;
k
<
logicalFileCount
;
++
k
)
{
{
delete
logicalFiles
[
k
];
delete
logicalFiles
[
k
];
}
}
...
@@ -302,11 +316,40 @@ void db2i_table::getDB2QualifiedNameFromPath(const char* path, char* to)
...
@@ -302,11 +316,40 @@ void db2i_table::getDB2QualifiedNameFromPath(const char* path, char* to)
}
}
size_t
db2i_table
::
smartFilenameToTableName
(
const
char
*
in
,
char
*
out
,
size_t
outlen
)
{
if
(
strchr
(
in
,
'@'
)
==
NULL
)
{
return
filename_to_tablename
(
in
,
out
,
outlen
);
}
char
*
test
=
(
char
*
)
my_malloc
(
outlen
,
MYF
(
MY_WME
));
filename_to_tablename
(
in
,
test
,
outlen
);
char
*
cur
=
test
;
while
(
*
cur
)
{
if
((
*
cur
<=
0x20
)
||
(
*
cur
>=
0x80
))
{
strncpy
(
out
,
in
,
outlen
);
my_free
(
test
,
MYF
(
0
));
return
min
(
outlen
,
strlen
(
out
));
}
++
cur
;
}
strncpy
(
out
,
test
,
outlen
);
my_free
(
test
,
MYF
(
0
));
return
min
(
outlen
,
strlen
(
out
));
}
void
db2i_table
::
filenameToTablename
(
const
char
*
in
,
char
*
out
,
size_t
outlen
)
void
db2i_table
::
filenameToTablename
(
const
char
*
in
,
char
*
out
,
size_t
outlen
)
{
{
if
(
strchr
(
in
,
'#'
)
==
NULL
)
if
(
strchr
(
in
,
'#'
)
==
NULL
)
{
{
filename_to_tablen
ame
(
in
,
out
,
outlen
);
smartFilenameToTableN
ame
(
in
,
out
,
outlen
);
return
;
return
;
}
}
...
@@ -326,7 +369,7 @@ void db2i_table::filenameToTablename(const char* in, char* out, size_t outlen)
...
@@ -326,7 +369,7 @@ void db2i_table::filenameToTablename(const char* in, char* out, size_t outlen)
memcpy
(
temp
,
part1
,
min
(
outlen
,
part2
-
part1
));
memcpy
(
temp
,
part1
,
min
(
outlen
,
part2
-
part1
));
temp
[
min
(
outlen
-
1
,
part2
-
part1
)]
=
0
;
temp
[
min
(
outlen
-
1
,
part2
-
part1
)]
=
0
;
int32
accumLen
=
filename_to_tablen
ame
(
temp
,
out
,
outlen
);
int32
accumLen
=
smartFilenameToTableN
ame
(
temp
,
out
,
outlen
);
if
(
part2
&&
(
accumLen
+
4
<
outlen
))
if
(
part2
&&
(
accumLen
+
4
<
outlen
))
{
{
...
@@ -337,7 +380,7 @@ void db2i_table::filenameToTablename(const char* in, char* out, size_t outlen)
...
@@ -337,7 +380,7 @@ void db2i_table::filenameToTablename(const char* in, char* out, size_t outlen)
memcpy
(
temp
,
part3
,
min
(
outlen
,
part4
-
part3
));
memcpy
(
temp
,
part3
,
min
(
outlen
,
part4
-
part3
));
temp
[
min
(
outlen
-
1
,
part4
-
part3
)]
=
0
;
temp
[
min
(
outlen
-
1
,
part4
-
part3
)]
=
0
;
accumLen
+=
filename_to_tablen
ame
(
temp
,
strend
(
out
),
outlen
-
accumLen
);
accumLen
+=
smartFilenameToTableN
ame
(
temp
,
strend
(
out
),
outlen
-
accumLen
);
if
(
part4
&&
(
accumLen
+
(
strend
(
in
)
-
part4
+
1
)
<
outlen
))
if
(
part4
&&
(
accumLen
+
(
strend
(
in
)
-
part4
+
1
)
<
outlen
))
{
{
...
...
storage/ibmdb2i/db2i_file.h
View file @
c61fab93
...
@@ -270,6 +270,7 @@ class db2i_table
...
@@ -270,6 +270,7 @@ class db2i_table
void
findConversionDefinition
(
enum_conversionDirection
direction
,
uint16
fieldID
);
void
findConversionDefinition
(
enum_conversionDirection
direction
,
uint16
fieldID
);
static
void
filenameToTablename
(
const
char
*
in
,
char
*
out
,
size_t
outlen
);
static
void
filenameToTablename
(
const
char
*
in
,
char
*
out
,
size_t
outlen
);
static
size_t
smartFilenameToTableName
(
const
char
*
in
,
char
*
out
,
size_t
outlen
);
void
convertNativeToSQLName
(
const
char
*
input
,
void
convertNativeToSQLName
(
const
char
*
input
,
char
*
output
)
char
*
output
)
{
{
...
@@ -301,6 +302,7 @@ class db2i_table
...
@@ -301,6 +302,7 @@ class db2i_table
iconv_t
*
conversionDefinitions
[
2
];
iconv_t
*
conversionDefinitions
[
2
];
const
TABLE_SHARE
*
mysqlTable
;
const
TABLE_SHARE
*
mysqlTable
;
uint16
logicalFileCount
;
char
*
db2LibNameEbcdic
;
// Quoted and in EBCDIC
char
*
db2LibNameEbcdic
;
// Quoted and in EBCDIC
char
*
db2LibNameAscii
;
char
*
db2LibNameAscii
;
char
*
db2TableNameEbcdic
;
char
*
db2TableNameEbcdic
;
...
@@ -326,22 +328,18 @@ class db2i_table
...
@@ -326,22 +328,18 @@ class db2i_table
*/
*/
class
db2i_file
class
db2i_file
{
{
enum
RowFormats
{
readOnly
=
0
,
readWrite
,
maxRowFormats
};
public:
public:
mutable
struct
RowFormat
struct
RowFormat
{
{
uint16
readRowLen
;
uint16
readRowLen
;
uint16
readRowNullOffset
;
uint16
readRowNullOffset
;
uint16
writeRowLen
;
uint16
writeRowLen
;
uint16
writeRowNullOffset
;
uint16
writeRowNullOffset
;
char
inited
;
char
inited
;
}
formats
[
maxRowFormats
];
};
public:
// Construct an instance for a physical file.
// Construct an instance for a physical file.
db2i_file
(
db2i_table
*
table
);
db2i_file
(
db2i_table
*
table
);
...
@@ -375,25 +373,23 @@ class db2i_file
...
@@ -375,25 +373,23 @@ class db2i_file
// This obtains the row layout associated with a particular access intent for
// This obtains the row layout associated with a particular access intent for
// an open instance of the file.
// an open instance of the file.
int
useFile
(
FILE_HANDLE
instanceHandle
,
int
obtainRowFormat
(
FILE_HANDLE
instanceHandle
,
char
intent
,
char
intent
,
char
commitLevel
,
char
commitLevel
,
const
RowFormat
**
activeFormat
)
const
const
RowFormat
**
activeFormat
)
const
{
{
DBUG_ENTER
(
"db2i_file::
useFile
"
);
DBUG_ENTER
(
"db2i_file::
obtainRowFormat
"
);
RowFormat
*
rowFormat
;
RowFormat
*
rowFormat
;
if
(
intent
==
QMY_UPDATABLE
)
if
(
intent
==
QMY_UPDATABLE
)
rowFormat
=
&
(
formats
[
readWrite
]);
rowFormat
=
&
(
formats
[
readWrite
]);
else
if
(
intent
==
QMY_READ_ONLY
)
else
if
(
intent
==
QMY_READ_ONLY
)
rowFormat
=
&
(
formats
[
readOnly
]);
rowFormat
=
&
(
formats
[
readOnly
]);
else
DBUG_ASSERT
(
0
);
if
(
!
rowFormat
->
inited
)
if
(
unlikely
(
!
rowFormat
->
inited
)
)
{
{
int
rc
;
int
rc
=
db2i_ileBridge
::
getBridgeForThread
()
->
rc
=
db2i_ileBridge
::
getBridgeForThread
()
->
initFileForIO
(
instanceHandle
,
initFileForIO
(
instanceHandle
,
intent
,
intent
,
commitLevel
,
commitLevel
,
&
(
rowFormat
->
writeRowLen
),
&
(
rowFormat
->
writeRowLen
),
...
@@ -426,6 +422,15 @@ class db2i_file
...
@@ -426,6 +422,15 @@ class db2i_file
}
}
private:
private:
enum
RowFormats
{
readOnly
=
0
,
readWrite
,
maxRowFormats
};
mutable
RowFormat
formats
[
maxRowFormats
];
void
commonCtorInit
();
void
commonCtorInit
();
char
*
db2FileName
;
// Quoted and in EBCDIC
char
*
db2FileName
;
// Quoted and in EBCDIC
...
...
storage/ibmdb2i/db2i_ileBridge.cc
View file @
c61fab93
...
@@ -894,6 +894,7 @@ int32 db2i_ileBridge::savepoint(uint8 function,
...
@@ -894,6 +894,7 @@ int32 db2i_ileBridge::savepoint(uint8 function,
return
rc
;
return
rc
;
}
}
static
ILEMemHandle
traceSpcHandle
;
/**
/**
Do initialization for the QMY_* APIs.
Do initialization for the QMY_* APIs.
...
@@ -902,7 +903,8 @@ int32 db2i_ileBridge::savepoint(uint8 function,
...
@@ -902,7 +903,8 @@ int32 db2i_ileBridge::savepoint(uint8 function,
@return 0 if successful; error otherwise
@return 0 if successful; error otherwise
*/
*/
int32
db2i_ileBridge
::
initILE
(
const
char
*
aspName
)
int32
db2i_ileBridge
::
initILE
(
const
char
*
aspName
,
uint16
*
traceCtlPtr
)
{
{
// We forego the typical thread-based parms space because MySQL doesn't
// We forego the typical thread-based parms space because MySQL doesn't
// allow us to clean it up before checking for memory leaks. As a result
// allow us to clean it up before checking for memory leaks. As a result
...
@@ -916,6 +918,8 @@ int32 db2i_ileBridge::initILE(const char* aspName)
...
@@ -916,6 +918,8 @@ int32 db2i_ileBridge::initILE(const char* aspName)
return
rc
;
return
rc
;
}
}
registerPtr
(
traceCtlPtr
,
&
traceSpcHandle
);
struct
ParmBlock
struct
ParmBlock
{
{
Qmy_MINI0100
parms
;
Qmy_MINI0100
parms
;
...
@@ -936,6 +940,9 @@ int32 db2i_ileBridge::initILE(const char* aspName)
...
@@ -936,6 +940,9 @@ int32 db2i_ileBridge::initILE(const char* aspName)
memcpy
(
paddedName
,
aspName
,
strlen
(
aspName
));
memcpy
(
paddedName
,
aspName
,
strlen
(
aspName
));
convToEbcdic
(
paddedName
,
parmBlock
->
parms
.
RDBName
,
strlen
(
paddedName
));
convToEbcdic
(
paddedName
,
parmBlock
->
parms
.
RDBName
,
strlen
(
paddedName
));
parmBlock
->
parms
.
RDBNamLen
=
strlen
(
paddedName
);
parmBlock
->
parms
.
TrcSpcHnd
=
traceSpcHandle
;
rc
=
doIt
();
rc
=
doIt
();
if
(
rc
)
if
(
rc
)
...
@@ -964,6 +971,8 @@ int32 db2i_ileBridge::exitILE()
...
@@ -964,6 +971,8 @@ int32 db2i_ileBridge::exitILE()
reportSystemAPIError
(
rc
,
(
Qmy_Error_output_t
*
)
parmBlock
->
outParms
);
reportSystemAPIError
(
rc
,
(
Qmy_Error_output_t
*
)
parmBlock
->
outParms
);
}
}
unregisterPtr
(
traceSpcHandle
);
DBUG_PRINT
(
"db2i_ileBridge::exitILE"
,
(
"Registered ptrs remaining: %d"
,
registeredPtrs
));
DBUG_PRINT
(
"db2i_ileBridge::exitILE"
,
(
"Registered ptrs remaining: %d"
,
registeredPtrs
));
#ifndef DBUG_OFF
#ifndef DBUG_OFF
if
(
registeredPtrs
!=
0
)
if
(
registeredPtrs
!=
0
)
...
@@ -1267,7 +1276,7 @@ int32 db2i_ileBridge::quiesceFileInstance(FILE_HANDLE rfileHandle)
...
@@ -1267,7 +1276,7 @@ int32 db2i_ileBridge::quiesceFileInstance(FILE_HANDLE rfileHandle)
return
rc
;
return
rc
;
}
}
void
db2i_ileBridge
::
PreservedHandleList
::
add
(
const
char
*
newname
,
FILE_HANDLE
newhandle
)
void
db2i_ileBridge
::
PreservedHandleList
::
add
(
const
char
*
newname
,
FILE_HANDLE
newhandle
,
IBMDB2I_SHARE
*
share
)
{
{
NameHandlePair
*
newPair
=
(
NameHandlePair
*
)
my_malloc
(
sizeof
(
NameHandlePair
),
MYF
(
MY_WME
));
NameHandlePair
*
newPair
=
(
NameHandlePair
*
)
my_malloc
(
sizeof
(
NameHandlePair
),
MYF
(
MY_WME
));
...
@@ -1276,11 +1285,12 @@ void db2i_ileBridge::PreservedHandleList::add(const char* newname, FILE_HANDLE n
...
@@ -1276,11 +1285,12 @@ void db2i_ileBridge::PreservedHandleList::add(const char* newname, FILE_HANDLE n
strcpy
(
newPair
->
name
,
newname
);
strcpy
(
newPair
->
name
,
newname
);
newPair
->
handle
=
newhandle
;
newPair
->
handle
=
newhandle
;
newPair
->
share
=
share
;
DBUG_PRINT
(
"db2i_ileBridge"
,
(
"Added handle %d for %s"
,
uint32
(
newhandle
),
newname
));
DBUG_PRINT
(
"db2i_ileBridge"
,
(
"Added handle %d for %s"
,
uint32
(
newhandle
),
newname
));
}
}
FILE_HANDLE
db2i_ileBridge
::
PreservedHandleList
::
findAndRemove
(
const
char
*
fileName
)
FILE_HANDLE
db2i_ileBridge
::
PreservedHandleList
::
findAndRemove
(
const
char
*
fileName
,
IBMDB2I_SHARE
**
share
)
{
{
NameHandlePair
*
current
=
head
;
NameHandlePair
*
current
=
head
;
NameHandlePair
*
prev
=
NULL
;
NameHandlePair
*
prev
=
NULL
;
...
@@ -1291,6 +1301,7 @@ FILE_HANDLE db2i_ileBridge::PreservedHandleList::findAndRemove(const char* fileN
...
@@ -1291,6 +1301,7 @@ FILE_HANDLE db2i_ileBridge::PreservedHandleList::findAndRemove(const char* fileN
if
(
strcmp
(
fileName
,
current
->
name
)
==
0
)
if
(
strcmp
(
fileName
,
current
->
name
)
==
0
)
{
{
FILE_HANDLE
tmp
=
current
->
handle
;
FILE_HANDLE
tmp
=
current
->
handle
;
*
share
=
current
->
share
;
if
(
prev
)
if
(
prev
)
prev
->
next
=
next
;
prev
->
next
=
next
;
if
(
current
==
head
)
if
(
current
==
head
)
...
...
storage/ibmdb2i/db2i_ileBridge.h
View file @
c61fab93
...
@@ -62,6 +62,7 @@ enum db2i_InfoRequestSpec
...
@@ -62,6 +62,7 @@ enum db2i_InfoRequestSpec
};
};
extern
handlerton
*
ibmdb2i_hton
;
extern
handlerton
*
ibmdb2i_hton
;
struct
IBMDB2I_SHARE
;
const
uint32
db2i_ileBridge_MAX_INPARM_SIZE
=
512
;
const
uint32
db2i_ileBridge_MAX_INPARM_SIZE
=
512
;
const
uint32
db2i_ileBridge_MAX_OUTPARM_SIZE
=
512
;
const
uint32
db2i_ileBridge_MAX_OUTPARM_SIZE
=
512
;
...
@@ -220,7 +221,8 @@ class db2i_ileBridge
...
@@ -220,7 +221,8 @@ class db2i_ileBridge
uint32
*
outLen
,
uint32
*
outLen
,
uint32
*
outCnt
);
uint32
*
outCnt
);
int32
optimizeTable
(
FILE_HANDLE
rfileHandle
);
int32
optimizeTable
(
FILE_HANDLE
rfileHandle
);
static
int32
initILE
(
const
char
*
aspName
);
static
int32
initILE
(
const
char
*
aspName
,
uint16
*
traceCtlPtr
);
int32
initFileForIO
(
FILE_HANDLE
rfileHandle
,
int32
initFileForIO
(
FILE_HANDLE
rfileHandle
,
char
accessIntent
,
char
accessIntent
,
char
commitLevel
,
char
commitLevel
,
...
@@ -336,9 +338,9 @@ class db2i_ileBridge
...
@@ -336,9 +338,9 @@ class db2i_ileBridge
@param newhandle The handle associated with newname
@param newhandle The handle associated with newname
*/
*/
void
preserveHandle
(
const
char
*
newname
,
FILE_HANDLE
newhandle
)
void
preserveHandle
(
const
char
*
newname
,
FILE_HANDLE
newhandle
,
IBMDB2I_SHARE
*
share
)
{
{
pendingLockedHandles
.
add
(
newname
,
newhandle
);
pendingLockedHandles
.
add
(
newname
,
newhandle
,
share
);
}
}
/**
/**
...
@@ -348,9 +350,10 @@ class db2i_ileBridge
...
@@ -348,9 +350,10 @@ class db2i_ileBridge
@return The handle associated with name
@return The handle associated with name
*/
*/
FILE_HANDLE
findAndRemovePreservedHandle
(
const
char
*
name
)
FILE_HANDLE
findAndRemovePreservedHandle
(
const
char
*
name
,
IBMDB2I_SHARE
**
share
)
{
{
return
pendingLockedHandles
.
findAndRemove
(
name
);
FILE_HANDLE
hdl
=
pendingLockedHandles
.
findAndRemove
(
name
,
share
);
return
hdl
;
}
}
/**
/**
...
@@ -380,7 +383,7 @@ class db2i_ileBridge
...
@@ -380,7 +383,7 @@ class db2i_ileBridge
@return A pointer to the 7 character message ID.
@return A pointer to the 7 character message ID.
*/
*/
const
char
*
getErrorMsgID
()
static
const
char
*
getErrorMsgID
()
{
{
return
((
Qmy_Error_output_t
*
)
parms
()
->
outParms
)
->
MsgId
;
return
((
Qmy_Error_output_t
*
)
parms
()
->
outParms
)
->
MsgId
;
}
}
...
@@ -413,6 +416,13 @@ class db2i_ileBridge
...
@@ -413,6 +416,13 @@ class db2i_ileBridge
return
HA_ERR_NO_SUCH_TABLE
;
return
HA_ERR_NO_SUCH_TABLE
;
case
QMY_ERR_NON_UNIQUE_KEY
:
case
QMY_ERR_NON_UNIQUE_KEY
:
return
ER_DUP_ENTRY
;
return
ER_DUP_ENTRY
;
case
QMY_ERR_MSGID
:
{
if
(
memcmp
(
getErrorMsgID
(),
DB2I_CPF503A
,
7
)
==
0
)
return
HA_ERR_ROW_IS_REFERENCED
;
if
(
memcmp
(
getErrorMsgID
(),
DB2I_SQL0538
,
7
)
==
0
)
return
HA_ERR_CANNOT_ADD_FOREIGN
;
}
}
}
return
rc
;
return
rc
;
}
}
...
@@ -458,14 +468,15 @@ class db2i_ileBridge
...
@@ -458,14 +468,15 @@ class db2i_ileBridge
{
{
friend
db2i_ileBridge
*
db2i_ileBridge
::
createNewBridge
(
CONNECTION_HANDLE
);
friend
db2i_ileBridge
*
db2i_ileBridge
::
createNewBridge
(
CONNECTION_HANDLE
);
public:
public:
void
add
(
const
char
*
newname
,
FILE_HANDLE
newhandle
);
void
add
(
const
char
*
newname
,
FILE_HANDLE
newhandle
,
IBMDB2I_SHARE
*
share
);
FILE_HANDLE
findAndRemove
(
const
char
*
fileName
);
FILE_HANDLE
findAndRemove
(
const
char
*
fileName
,
IBMDB2I_SHARE
**
share
);
private:
private:
struct
NameHandlePair
struct
NameHandlePair
{
{
char
name
[
FN_REFLEN
];
char
name
[
FN_REFLEN
];
FILE_HANDLE
handle
;
FILE_HANDLE
handle
;
IBMDB2I_SHARE
*
share
;
NameHandlePair
*
next
;
NameHandlePair
*
next
;
}
*
head
;
}
*
head
;
}
pendingLockedHandles
;
}
pendingLockedHandles
;
...
...
storage/ibmdb2i/db2i_ioBuffers.cc
View file @
c61fab93
...
@@ -257,7 +257,7 @@ void IOAsyncReadBuffer::newReadRequest(FILE_HANDLE infile,
...
@@ -257,7 +257,7 @@ void IOAsyncReadBuffer::newReadRequest(FILE_HANDLE infile,
int
fildes
[
2
];
int
fildes
[
2
];
int
ileDescriptor
=
QMY_REUSE
;
int
ileDescriptor
=
QMY_REUSE
;
closePipe
();
interruptRead
();
if
(
likely
(
useAsync
))
if
(
likely
(
useAsync
))
{
{
...
...
storage/ibmdb2i/db2i_ioBuffers.h
View file @
c61fab93
...
@@ -73,10 +73,12 @@ class IORowBuffer
...
@@ -73,10 +73,12 @@ class IORowBuffer
Sets up the buffer to hold the size indicated.
Sets up the buffer to hold the size indicated.
@param rowLen length of the rows that will be stored in this buffer
@param rowLen length of the rows that will be stored in this buffer
@param nullMapOffset position of null map within each row
@param size buffer size requested
@param size buffer size requested
*/
*/
void
allocBuf
(
uint32
rowLen
,
uint32
size
)
void
allocBuf
(
uint32
rowLen
,
uint
16
nullMapOffset
,
uint
32
size
)
{
{
nullOffset
=
nullMapOffset
;
uint32
newSize
=
size
+
sizeof
(
BufferHdr_t
);
uint32
newSize
=
size
+
sizeof
(
BufferHdr_t
);
// If the internal structure of the row is changing, we need to
// If the internal structure of the row is changing, we need to
// remember this and notify the subclasses via initAfterAllocate();
// remember this and notify the subclasses via initAfterAllocate();
...
@@ -129,6 +131,8 @@ class IORowBuffer
...
@@ -129,6 +131,8 @@ class IORowBuffer
};
};
uint32
getRowCapacity
()
const
{
return
rowCapacity
;}
uint32
getRowCapacity
()
const
{
return
rowCapacity
;}
uint32
getRowNullOffset
()
const
{
return
nullOffset
;}
uint32
getRowLength
()
const
{
return
rowLength
;}
protected:
protected:
/**
/**
...
@@ -150,6 +154,7 @@ class IORowBuffer
...
@@ -150,6 +154,7 @@ class IORowBuffer
uint32
allocSize
;
uint32
allocSize
;
uint32
rowCapacity
;
uint32
rowCapacity
;
uint32
rowLength
;
uint32
rowLength
;
uint16
nullOffset
;
uint32
&
usedRows
()
const
{
return
((
BufferHdr_t
*
)(
char
*
)
data
)
->
UsedRowCnt
;
}
uint32
&
usedRows
()
const
{
return
((
BufferHdr_t
*
)(
char
*
)
data
)
->
UsedRowCnt
;
}
uint32
&
maxRows
()
const
{
return
((
BufferHdr_t
*
)(
char
*
)
data
)
->
MaxRowCnt
;
}
uint32
&
maxRows
()
const
{
return
((
BufferHdr_t
*
)(
char
*
)
data
)
->
MaxRowCnt
;
}
};
};
...
@@ -207,7 +212,7 @@ class IOReadBuffer : public IORowBuffer
...
@@ -207,7 +212,7 @@ class IOReadBuffer : public IORowBuffer
IOReadBuffer
()
{;}
IOReadBuffer
()
{;}
IOReadBuffer
(
uint32
rows
,
uint32
rowLength
)
IOReadBuffer
(
uint32
rows
,
uint32
rowLength
)
{
{
allocBuf
(
rows
,
rows
*
rowLength
);
allocBuf
(
rows
,
0
,
rows
*
rowLength
);
maxRows
()
=
rows
;
maxRows
()
=
rows
;
}
}
...
...
storage/ibmdb2i/db2i_misc.h
View file @
c61fab93
...
@@ -92,4 +92,16 @@ bool convertMySQLNameToDB2Name(const char* input,
...
@@ -92,4 +92,16 @@ bool convertMySQLNameToDB2Name(const char* input,
return
(
o
<=
outlen
-
1
);
return
(
o
<=
outlen
-
1
);
}
}
bool
isUpperOrQuote
(
const
CHARSET_INFO
*
cs
,
const
char
*
s
)
{
while
(
*
s
)
{
if
(
my_isupper
(
cs
,
*
s
)
||
(
*
s
==
'"'
))
++
s
;
else
return
false
;
}
return
true
;
}
#endif
#endif
storage/ibmdb2i/db2i_rir.cc
View file @
c61fab93
...
@@ -140,6 +140,17 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx,
...
@@ -140,6 +140,17 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx,
}
}
keyCnt
=
maxKeyCnt
>=
minKeyCnt
?
maxKeyCnt
:
minKeyCnt
;
keyCnt
=
maxKeyCnt
>=
minKeyCnt
?
maxKeyCnt
:
minKeyCnt
;
/*
Handle the special case where MySQL does not pass either a min or max
key range. In this case, set the key count to 1 (knowing that there
is at least one key field) to flow through and create one bounds structure.
When both the min and max key ranges are nil, the bounds structure will
specify positive and negative infinity and DB2 will estimate the total
number of rows. */
if
(
keyCnt
==
0
)
keyCnt
=
1
;
/*
/*
Allocate the space needed to pass range information to DB2. The
Allocate the space needed to pass range information to DB2. The
space must be large enough to store the following:
space must be large enough to store the following:
...
@@ -197,7 +208,6 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx,
...
@@ -197,7 +208,6 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx,
is not null, the data offset and length must be set, and the literal
is not null, the data offset and length must be set, and the literal
value stored for access by DB2.
value stored for access by DB2.
*/
*/
for
(
int
partsInUse
=
0
;
partsInUse
<
keyCnt
;
++
partsInUse
)
for
(
int
partsInUse
=
0
;
partsInUse
<
keyCnt
;
++
partsInUse
)
{
{
Field
*
field
=
curKey
.
key_part
[
partsInUse
].
field
;
Field
*
field
=
curKey
.
key_part
[
partsInUse
].
field
;
...
@@ -298,20 +308,29 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx,
...
@@ -298,20 +308,29 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx,
else
else
tempLen
=
field
->
field_length
;
tempLen
=
field
->
field_length
;
if
(
litDefPtr
->
DataType
==
QMY_CHAR
||
litDefPtr
->
DataType
==
QMY_VARCHAR
||
/* Determine if we are dealing with a partial key and if so, find the end of the partial key. */
(
strncmp
(
fieldCharSet
->
csname
,
"utf8"
,
sizeof
(
"utf8"
))
==
0
)
)
if
(
litDefPtr
->
DataType
==
QMY_CHAR
||
litDefPtr
->
DataType
==
QMY_VARCHAR
)
{
{
/* Char or varchar. If UTF8, no conversion is done to DB2 graphic.) */
endOfMinPtr
=
(
char
*
)
memchr
(
tempMinPtr
,
field
->
charset
()
->
min_sort_char
,
tempLen
);
endOfMinPtr
=
(
char
*
)
memchr
(
tempMinPtr
,
field
->
charset
()
->
min_sort_char
,
tempLen
);
if
(
endOfMinPtr
)
if
(
endOfMinPtr
)
endOfLiteralPtr
=
tempPtr
+
(((
uint32_t
)(
endOfMinPtr
-
tempMinPtr
))
*
endOfLiteralPtr
=
tempPtr
+
((
uint32_t
)(
endOfMinPtr
-
tempMinPtr
));
(
litDefPtr
->
DataType
==
QMY_CHAR
||
litDefPtr
->
DataType
==
QMY_VARCHAR
?
1
:
2
));
}
}
else
else
{
{
if
(
strncmp
(
fieldCharSet
->
csname
,
"utf8"
,
sizeof
(
"utf8"
))
==
0
)
{
/* The MySQL charset is UTF8 but we are converting to graphic on DB2. Divide number of UTF8 bytes
by 3 to get the number of characters, then multiple by 2 for double-byte graphic.*/
endOfMinPtr
=
(
char
*
)
memchr
(
tempMinPtr
,
field
->
charset
()
->
min_sort_char
,
tempLen
);
if
(
endOfMinPtr
)
endOfLiteralPtr
=
tempPtr
+
(((
uint32_t
)((
endOfMinPtr
-
tempMinPtr
))
/
3
)
*
2
);
}
else
{
/* The DB2 data type is graphic or vargraphic, and we are not converting from UTF8 to graphic. */
endOfMinPtr
=
(
char
*
)
wmemchr
((
wchar_t
*
)
tempMinPtr
,
field
->
charset
()
->
min_sort_char
,
tempLen
/
2
);
endOfMinPtr
=
(
char
*
)
wmemchr
((
wchar_t
*
)
tempMinPtr
,
field
->
charset
()
->
min_sort_char
,
tempLen
/
2
);
if
(
endOfMinPtr
)
if
(
endOfMinPtr
)
endOfLiteralPtr
=
tempPtr
+
(
endOfMinPtr
-
tempMinPtr
);
endOfLiteralPtr
=
tempPtr
+
(
endOfMinPtr
-
tempMinPtr
);
}
}
}
/* Enforce here that a partial is only allowed on the last field position
/* Enforce here that a partial is only allowed on the last field position
of the key composite */
of the key composite */
if
(
endOfLiteralPtr
)
if
(
endOfLiteralPtr
)
...
@@ -354,6 +373,11 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx,
...
@@ -354,6 +373,11 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx,
}
}
else
// max_key field is not null
else
// max_key field is not null
{
{
if
(
boundsPtr
->
LoBound
.
IsNull
[
0
]
==
QMY_YES
)
// select where x < 10 or x is null
{
rc
=
HA_POS_ERROR
;
break
;
}
if
(
!
reuseLiteral
)
if
(
!
reuseLiteral
)
{
{
if
(
literalCnt
)
if
(
literalCnt
)
...
...
storage/ibmdb2i/ha_ibmdb2i.cc
View file @
c61fab93
...
@@ -78,7 +78,7 @@ static MYSQL_SYSVAR_STR(rdb_name, ibmdb2i_rdb_name,
...
@@ -78,7 +78,7 @@ static MYSQL_SYSVAR_STR(rdb_name, ibmdb2i_rdb_name,
static
MYSQL_THDVAR_BOOL
(
transaction_unsafe
,
static
MYSQL_THDVAR_BOOL
(
transaction_unsafe
,
0
,
0
,
"
True auto-commit mode.
"
,
"
Disable support for commitment control
"
,
NULL
,
NULL
,
NULL
,
NULL
,
FALSE
);
FALSE
);
...
@@ -113,16 +113,26 @@ static MYSQL_THDVAR_UINT(max_write_buffer_size,
...
@@ -113,16 +113,26 @@ static MYSQL_THDVAR_UINT(max_write_buffer_size,
64
*
1024
*
1024
,
64
*
1024
*
1024
,
1
);
1
);
static
MYSQL_THDVAR_BOOL
(
c
reate_time_columns_as_TOD
,
static
MYSQL_THDVAR_BOOL
(
c
ompat_opt_time_as_duration
,
0
,
0
,
"Control how new TIME columns should be defined in DB2.
1=time-of-day (default), 0
=duration."
,
"Control how new TIME columns should be defined in DB2.
0=time-of-day (default), 1
=duration."
,
NULL
,
NULL
,
NULL
,
NULL
,
TRUE
);
FALSE
);
static
MYSQL_THDVAR_UINT
(
compat_opt_year_as_int
,
0
,
"Control how new YEAR columns should be defined in DB2. 0=CHAR(4) (default), 1=SMALLINT."
,
NULL
,
NULL
,
0
,
0
,
1
,
1
);
static
MYSQL_THDVAR_UINT
(
map_blob_to_varchar
,
static
MYSQL_THDVAR_UINT
(
compat_opt_blob_cols
,
0
,
0
,
"Control how new TEXT
columns should be defined in DB2. 0=CLOB (default), 1=VARCHAR
"
,
"Control how new TEXT
and BLOB columns should be defined in DB2. 0=CLOB/BLOB (default), 1=VARCHAR/VARBINARY
"
,
NULL
,
NULL
,
NULL
,
NULL
,
0
,
0
,
...
@@ -130,6 +140,23 @@ static MYSQL_THDVAR_UINT(map_blob_to_varchar,
...
@@ -130,6 +140,23 @@ static MYSQL_THDVAR_UINT(map_blob_to_varchar,
1
,
1
,
1
);
1
);
static
MYSQL_THDVAR_UINT
(
compat_opt_allow_zero_date_vals
,
0
,
"Allow substitute values to be used when storing a column with a 0000-00-00 date component. 0=No substitution (default), 1=Substitute '0001-01-01'"
,
NULL
,
NULL
,
0
,
0
,
1
,
1
);
static
MYSQL_THDVAR_BOOL
(
propagate_default_col_vals
,
0
,
"Should DEFAULT column values be propagated to the DB2 table definition."
,
NULL
,
NULL
,
TRUE
);
static
my_bool
ibmdb2i_assume_exclusive_use
;
static
my_bool
ibmdb2i_assume_exclusive_use
;
static
MYSQL_SYSVAR_BOOL
(
assume_exclusive_use
,
ibmdb2i_assume_exclusive_use
,
static
MYSQL_SYSVAR_BOOL
(
assume_exclusive_use
,
ibmdb2i_assume_exclusive_use
,
0
,
0
,
...
@@ -155,7 +182,7 @@ static MYSQL_THDVAR_UINT(create_index_option,
...
@@ -155,7 +182,7 @@ static MYSQL_THDVAR_UINT(create_index_option,
1
,
1
,
1
);
1
);
static
MYSQL_THDVAR_UINT
(
discovery_mode
,
/*
static MYSQL_THDVAR_UINT(discovery_mode,
0,
0,
"Unsupported",
"Unsupported",
NULL,
NULL,
...
@@ -163,6 +190,17 @@ static MYSQL_THDVAR_UINT(discovery_mode,
...
@@ -163,6 +190,17 @@ static MYSQL_THDVAR_UINT(discovery_mode,
0,
0,
0,
0,
1,
1,
1); */
static
uint32
ibmdb2i_system_trace
;
static
MYSQL_SYSVAR_UINT
(
system_trace_level
,
ibmdb2i_system_trace
,
0
,
"Set system tracing level"
,
NULL
,
NULL
,
0
,
0
,
63
,
1
);
1
);
...
@@ -276,7 +314,7 @@ static int ibmdb2i_init_func(void *p)
...
@@ -276,7 +314,7 @@ static int ibmdb2i_init_func(void *p)
ibmdb2i_rdb_name
[
i
]
=
my_toupper
(
system_charset_info
,
(
uchar
)
ibmdb2i_rdb_name
[
i
]);
ibmdb2i_rdb_name
[
i
]
=
my_toupper
(
system_charset_info
,
(
uchar
)
ibmdb2i_rdb_name
[
i
]);
}
}
rc
=
db2i_ileBridge
::
initILE
(
ibmdb2i_rdb_name
);
rc
=
db2i_ileBridge
::
initILE
(
ibmdb2i_rdb_name
,
(
uint16
*
)(((
char
*
)
&
ibmdb2i_system_trace
)
+
2
)
);
if
(
rc
==
0
)
if
(
rc
==
0
)
{
{
was_ILE_inited
=
true
;
was_ILE_inited
=
true
;
...
@@ -386,6 +424,8 @@ int ha_ibmdb2i::free_share(IBMDB2I_SHARE *share)
...
@@ -386,6 +424,8 @@ int ha_ibmdb2i::free_share(IBMDB2I_SHARE *share)
thr_lock_delete
(
&
share
->
lock
);
thr_lock_delete
(
&
share
->
lock
);
pthread_mutex_destroy
(
&
share
->
mutex
);
pthread_mutex_destroy
(
&
share
->
mutex
);
my_free
(
share
,
MYF
(
0
));
my_free
(
share
,
MYF
(
0
));
pthread_mutex_unlock
(
&
ibmdb2i_mutex
);
return
1
;
}
}
pthread_mutex_unlock
(
&
ibmdb2i_mutex
);
pthread_mutex_unlock
(
&
ibmdb2i_mutex
);
...
@@ -528,6 +568,8 @@ ha_ibmdb2i::ha_ibmdb2i(handlerton *hton, TABLE_SHARE *table_arg)
...
@@ -528,6 +568,8 @@ ha_ibmdb2i::ha_ibmdb2i(handlerton *hton, TABLE_SHARE *table_arg)
ha_ibmdb2i
::~
ha_ibmdb2i
()
ha_ibmdb2i
::~
ha_ibmdb2i
()
{
{
DBUG_ASSERT
(
activeReferences
==
0
||
outstanding_start_bulk_insert
);
if
(
indexHandles
)
if
(
indexHandles
)
my_free
(
indexHandles
,
MYF
(
0
));
my_free
(
indexHandles
,
MYF
(
0
));
if
(
indexReadSizeEstimates
)
if
(
indexReadSizeEstimates
)
...
@@ -554,13 +596,17 @@ int ha_ibmdb2i::open(const char *name, int mode, uint test_if_locked)
...
@@ -554,13 +596,17 @@ int ha_ibmdb2i::open(const char *name, int mode, uint test_if_locked)
initBridge
();
initBridge
();
if
(
!
(
share
=
get_share
(
name
,
table
)))
dataHandle
=
bridge
()
->
findAndRemovePreservedHandle
(
name
,
&
share
);
if
(
share
)
db2Table
=
share
->
db2Table
;
if
(
!
share
&&
(
!
(
share
=
get_share
(
name
,
table
))))
DBUG_RETURN
(
my_errno
);
DBUG_RETURN
(
my_errno
);
thr_lock_data_init
(
&
share
->
lock
,
&
lock
,
NULL
);
thr_lock_data_init
(
&
share
->
lock
,
&
lock
,
NULL
);
info
(
HA_STATUS_NO_LOCK
|
HA_STATUS_CONST
|
HA_STATUS_VARIABLE
);
info
(
HA_STATUS_NO_LOCK
|
HA_STATUS_CONST
|
HA_STATUS_VARIABLE
);
dataHandle
=
bridge
()
->
findAndRemovePreservedHandle
(
name
);
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -572,13 +618,17 @@ int ha_ibmdb2i::close(void)
...
@@ -572,13 +618,17 @@ int ha_ibmdb2i::close(void)
{
{
DBUG_ENTER
(
"ha_ibmdb2i::close"
);
DBUG_ENTER
(
"ha_ibmdb2i::close"
);
int32
rc
=
0
;
int32
rc
=
0
;
bool
preserveShare
=
false
;
db2i_ileBridge
*
bridge
=
db2i_ileBridge
::
getBridgeForThread
();
db2i_ileBridge
*
bridge
=
db2i_ileBridge
::
getBridgeForThread
();
if
(
dataHandle
)
if
(
dataHandle
)
{
{
if
(
bridge
->
expectErrors
(
QMY_ERR_PEND_LOCKS
)
->
deallocateFile
(
dataHandle
,
FALSE
)
==
QMY_ERR_PEND_LOCKS
)
if
(
bridge
->
expectErrors
(
QMY_ERR_PEND_LOCKS
)
->
deallocateFile
(
dataHandle
,
FALSE
)
==
QMY_ERR_PEND_LOCKS
)
bridge
->
preserveHandle
(
share
->
table_name
,
dataHandle
);
{
bridge
->
preserveHandle
(
share
->
table_name
,
dataHandle
,
share
);
preserveShare
=
true
;
}
dataHandle
=
0
;
dataHandle
=
0
;
}
}
...
@@ -592,7 +642,11 @@ int ha_ibmdb2i::close(void)
...
@@ -592,7 +642,11 @@ int ha_ibmdb2i::close(void)
cleanupBuffers
();
cleanupBuffers
();
free_share
(
share
);
if
(
!
preserveShare
)
{
if
(
free_share
(
share
))
share
=
NULL
;
}
DBUG_RETURN
(
rc
);
DBUG_RETURN
(
rc
);
}
}
...
@@ -608,26 +662,28 @@ int ha_ibmdb2i::write_row(uchar * buf)
...
@@ -608,26 +662,28 @@ int ha_ibmdb2i::write_row(uchar * buf)
DBUG_RETURN
(
last_start_bulk_insert_rc
);
DBUG_RETURN
(
last_start_bulk_insert_rc
);
ha_statistic_increment
(
&
SSV
::
ha_write_count
);
ha_statistic_increment
(
&
SSV
::
ha_write_count
);
int
rc
;
int
rc
=
0
;
bool
fileHandleNeedsRelease
=
false
;
bool
fileHandleNeedsRelease
=
false
;
if
(
!
activeHandle
)
if
(
!
activeHandle
)
{
{
rc
=
useDataFile
(
QMY_UPDATABLE
);
rc
=
useDataFile
();
if
(
rc
)
DBUG_RETURN
(
rc
);
if
(
rc
)
DBUG_RETURN
(
rc
);
fileHandleNeedsRelease
=
true
;
fileHandleNeedsRelease
=
true
;
}
}
if
(
!
outstanding_start_bulk_insert
)
if
(
!
outstanding_start_bulk_insert
)
prepWriteBuffer
(
1
);
rc
=
prepWriteBuffer
(
1
,
getFileForActiveHandle
()
);
if
(
!
rc
)
{
if
(
table
->
timestamp_field_type
&
TIMESTAMP_AUTO_SET_ON_INSERT
)
if
(
table
->
timestamp_field_type
&
TIMESTAMP_AUTO_SET_ON_INSERT
)
table
->
timestamp_field
->
set_time
();
table
->
timestamp_field
->
set_time
();
char
*
writeBuffer
=
activeWriteBuf
->
addRow
();
char
*
writeBuffer
=
activeWriteBuf
->
addRow
();
rc
=
prepareRowForWrite
(
writeBuffer
,
rc
=
prepareRowForWrite
(
writeBuffer
,
writeBuffer
+
activeFormat
->
writeRowNullOffset
,
writeBuffer
+
activeWriteBuf
->
getRowNullOffset
()
,
true
);
true
);
if
(
rc
==
0
)
if
(
rc
==
0
)
{
{
...
@@ -659,7 +715,7 @@ int ha_ibmdb2i::write_row(uchar * buf)
...
@@ -659,7 +715,7 @@ int ha_ibmdb2i::write_row(uchar * buf)
}
}
else
else
activeWriteBuf
->
deleteRow
();
activeWriteBuf
->
deleteRow
();
}
if
(
fileHandleNeedsRelease
)
if
(
fileHandleNeedsRelease
)
releaseActiveHandle
();
releaseActiveHandle
();
...
@@ -748,7 +804,7 @@ int ha_ibmdb2i::update_row(const uchar * old_data, uchar * new_data)
...
@@ -748,7 +804,7 @@ int ha_ibmdb2i::update_row(const uchar * old_data, uchar * new_data)
char
*
writeBuf
=
activeWriteBuf
->
addRow
();
char
*
writeBuf
=
activeWriteBuf
->
addRow
();
rc
=
prepareRowForWrite
(
writeBuf
,
rc
=
prepareRowForWrite
(
writeBuf
,
writeBuf
+
active
Format
->
writeRowNullOffset
,
writeBuf
+
active
WriteBuf
->
getRowNullOffset
()
,
onDupUpdate
);
onDupUpdate
);
char
*
lastDupKeyNamePtr
=
NULL
;
char
*
lastDupKeyNamePtr
=
NULL
;
...
@@ -819,9 +875,28 @@ int ha_ibmdb2i::index_init(uint idx, bool sorted)
...
@@ -819,9 +875,28 @@ int ha_ibmdb2i::index_init(uint idx, bool sorted)
active_index
=
idx
;
active_index
=
idx
;
rc
=
useIndexFile
(
accessIntent
,
idx
);
rc
=
useIndexFile
(
idx
);
if
(
accessIntent
!=
QMY_READ_ONLY
)
prepWriteBuffer
(
1
);
if
(
!
rc
)
{
// THD* thd = ha_thd();
// if (accessIntent == QMY_UPDATABLE &&
// thd_tx_isolation(thd) == ISO_REPEATABLE_READ &&
// !THDVAR(thd, transaction_unsafe))
// {
// readAccessIntent = QMY_READ_ONLY;
// }
// else
// {
readAccessIntent
=
accessIntent
;
// }
if
(
!
rc
&&
accessIntent
!=
QMY_READ_ONLY
)
rc
=
prepWriteBuffer
(
1
,
db2Table
->
indexFile
(
idx
));
if
(
rc
)
releaseIndexFile
(
idx
);
}
DBUG_RETURN
(
rc
);
DBUG_RETURN
(
rc
);
}
}
...
@@ -839,16 +914,18 @@ int ha_ibmdb2i::index_read(uchar * buf, const uchar * key,
...
@@ -839,16 +914,18 @@ int ha_ibmdb2i::index_read(uchar * buf, const uchar * key,
int
rc
;
int
rc
;
ha_rows
estimatedRows
=
getIndexReadEstimate
(
active_index
);
ha_rows
estimatedRows
=
getIndexReadEstimate
(
active_index
);
rc
=
prepReadBuffer
(
estimatedRows
);
rc
=
prepReadBuffer
(
estimatedRows
,
db2Table
->
indexFile
(
active_index
),
readAccessIntent
);
if
(
unlikely
(
rc
))
DBUG_RETURN
(
rc
);
if
(
unlikely
(
rc
))
DBUG_RETURN
(
rc
);
DBUG_ASSERT
(
activeReadBuf
);
DBUG_ASSERT
(
activeReadBuf
);
keyBuf
.
allocBuf
(
activeFormat
->
readRowLen
,
activeFormat
->
readRowLen
);
keyBuf
.
allocBuf
(
activeReadBuf
->
getRowLength
(),
activeReadBuf
->
getRowNullOffset
(),
activeReadBuf
->
getRowLength
());
keyBuf
.
zeroBuf
();
keyBuf
.
zeroBuf
();
char
*
db2KeyBufPtr
=
keyBuf
.
ptr
();
char
*
db2KeyBufPtr
=
keyBuf
.
ptr
();
char
*
nullKeyMap
=
db2KeyBufPtr
+
active
Format
->
readRowNullOffset
;
char
*
nullKeyMap
=
db2KeyBufPtr
+
active
ReadBuf
->
getRowNullOffset
()
;
const
uchar
*
keyBegin
=
key
;
const
uchar
*
keyBegin
=
key
;
int
partsInUse
;
int
partsInUse
;
...
@@ -990,7 +1067,9 @@ int ha_ibmdb2i::index_first(uchar * buf)
...
@@ -990,7 +1067,9 @@ int ha_ibmdb2i::index_first(uchar * buf)
if
(
unlikely
(
last_index_init_rc
))
DBUG_RETURN
(
last_index_init_rc
);
if
(
unlikely
(
last_index_init_rc
))
DBUG_RETURN
(
last_index_init_rc
);
int
rc
=
prepReadBuffer
(
DEFAULT_MAX_ROWS_TO_BUFFER
);
int
rc
=
prepReadBuffer
(
DEFAULT_MAX_ROWS_TO_BUFFER
,
db2Table
->
indexFile
(
active_index
),
readAccessIntent
);
if
(
rc
==
0
)
if
(
rc
==
0
)
{
{
...
@@ -1010,7 +1089,9 @@ int ha_ibmdb2i::index_last(uchar * buf)
...
@@ -1010,7 +1089,9 @@ int ha_ibmdb2i::index_last(uchar * buf)
if
(
unlikely
(
last_index_init_rc
))
DBUG_RETURN
(
last_index_init_rc
);
if
(
unlikely
(
last_index_init_rc
))
DBUG_RETURN
(
last_index_init_rc
);
int
rc
=
prepReadBuffer
(
DEFAULT_MAX_ROWS_TO_BUFFER
);
int
rc
=
prepReadBuffer
(
DEFAULT_MAX_ROWS_TO_BUFFER
,
db2Table
->
indexFile
(
active_index
),
readAccessIntent
);
if
(
rc
==
0
)
if
(
rc
==
0
)
{
{
...
@@ -1045,18 +1126,29 @@ int ha_ibmdb2i::rnd_init(bool scan)
...
@@ -1045,18 +1126,29 @@ int ha_ibmdb2i::rnd_init(bool scan)
rowsToBlockOnRead
=
DEFAULT_MAX_ROWS_TO_BUFFER
;
rowsToBlockOnRead
=
DEFAULT_MAX_ROWS_TO_BUFFER
;
}
}
rc
=
useDataFile
(
accessIntent
);
rc
=
useDataFile
();
if
(
rc
==
0
)
if
(
!
rc
)
{
{
if
(
accessIntent
!=
QMY_READ_ONLY
)
// THD* thd = ha_thd();
prepWriteBuffer
(
1
);
// if (accessIntent == QMY_UPDATABLE &&
rc
=
prepReadBuffer
(
rowsToBlockOnRead
);
// thd_tx_isolation(thd) == ISO_REPEATABLE_READ &&
// !THDVAR(thd, transaction_unsafe))
// {
// readAccessIntent = QMY_READ_ONLY;
// }
// else
// {
readAccessIntent
=
accessIntent
;
// }
if
(
rc
==
0
&&
scan
)
rc
=
prepReadBuffer
(
rowsToBlockOnRead
,
db2Table
->
dataFile
(),
readAccessIntent
);
{
if
(
!
rc
&&
accessIntent
!=
QMY_READ_ONLY
)
rc
=
prepWriteBuffer
(
1
,
db2Table
->
dataFile
());
if
(
!
rc
&&
scan
)
doInitialRead
(
QMY_FIRST
,
rowsToBlockOnRead
);
doInitialRead
(
QMY_FIRST
,
rowsToBlockOnRead
);
}
if
(
rc
)
if
(
rc
)
releaseDataFile
();
releaseDataFile
();
...
@@ -1167,7 +1259,10 @@ int ha_ibmdb2i::rnd_pos(uchar * buf, uchar *pos)
...
@@ -1167,7 +1259,10 @@ int ha_ibmdb2i::rnd_pos(uchar * buf, uchar *pos)
if
(
likely
(
rc
==
0
))
if
(
likely
(
rc
==
0
))
{
{
rc
=
prepReadBuffer
(
1
);
rc
=
prepReadBuffer
(
1
,
getFileForActiveHandle
(),
accessIntent
);
if
(
likely
(
rc
==
0
)
&&
accessIntent
==
QMY_UPDATABLE
)
rc
=
prepWriteBuffer
(
1
,
getFileForActiveHandle
());
if
(
likely
(
rc
==
0
))
if
(
likely
(
rc
==
0
))
{
{
...
@@ -1181,7 +1276,7 @@ int ha_ibmdb2i::rnd_pos(uchar * buf, uchar *pos)
...
@@ -1181,7 +1276,7 @@ int ha_ibmdb2i::rnd_pos(uchar * buf, uchar *pos)
{
{
rrnAssocHandle
=
activeHandle
;
rrnAssocHandle
=
activeHandle
;
const
char
*
readBuf
=
activeReadBuf
->
getRowN
(
0
);
const
char
*
readBuf
=
activeReadBuf
->
getRowN
(
0
);
rc
=
mungeDB2row
(
buf
,
readBuf
,
readBuf
+
active
Format
->
readRowNullOffset
,
false
);
rc
=
mungeDB2row
(
buf
,
readBuf
,
readBuf
+
active
ReadBuf
->
getRowNullOffset
()
,
false
);
releaseRowNeeded
=
TRUE
;
releaseRowNeeded
=
TRUE
;
}
}
}
}
...
@@ -1450,7 +1545,9 @@ int ha_ibmdb2i::getNextIdVal(ulonglong *value)
...
@@ -1450,7 +1545,9 @@ int ha_ibmdb2i::getNextIdVal(ulonglong *value)
char
queryBuffer
[
MAX_DB2_COLNAME_LENGTH
+
MAX_DB2_QUALIFIEDNAME_LENGTH
+
64
];
char
queryBuffer
[
MAX_DB2_COLNAME_LENGTH
+
MAX_DB2_QUALIFIEDNAME_LENGTH
+
64
];
strcpy
(
queryBuffer
,
" SELECT CAST(MAX( "
);
strcpy
(
queryBuffer
,
" SELECT CAST(MAX( "
);
convertMySQLNameToDB2Name
(
table
->
found_next_number_field
->
field_name
,
strend
(
queryBuffer
),
MAX_DB2_COLNAME_LENGTH
+
1
);
convertMySQLNameToDB2Name
(
table
->
found_next_number_field
->
field_name
,
strend
(
queryBuffer
),
MAX_DB2_COLNAME_LENGTH
+
1
);
strcat
(
queryBuffer
,
") AS BIGINT) FROM "
);
strcat
(
queryBuffer
,
") AS BIGINT) FROM "
);
db2Table
->
getDB2QualifiedName
(
strend
(
queryBuffer
));
db2Table
->
getDB2QualifiedName
(
strend
(
queryBuffer
));
DBUG_ASSERT
(
strlen
(
queryBuffer
)
<
sizeof
(
queryBuffer
));
DBUG_ASSERT
(
strlen
(
queryBuffer
)
<
sizeof
(
queryBuffer
));
...
@@ -1621,7 +1718,9 @@ int ha_ibmdb2i::reset_auto_increment(ulonglong value)
...
@@ -1621,7 +1718,9 @@ int ha_ibmdb2i::reset_auto_increment(ulonglong value)
query
.
append
(
fileName
);
query
.
append
(
fileName
);
query
.
append
(
STRING_WITH_LEN
(
" ALTER COLUMN "
));
query
.
append
(
STRING_WITH_LEN
(
" ALTER COLUMN "
));
char
colName
[
MAX_DB2_COLNAME_LENGTH
+
1
];
char
colName
[
MAX_DB2_COLNAME_LENGTH
+
1
];
convertMySQLNameToDB2Name
(
table
->
found_next_number_field
->
field_name
,
colName
,
sizeof
(
colName
));
convertMySQLNameToDB2Name
(
table
->
found_next_number_field
->
field_name
,
colName
,
sizeof
(
colName
));
query
.
append
(
colName
);
query
.
append
(
colName
);
char
restart_value
[
22
];
char
restart_value
[
22
];
...
@@ -1637,10 +1736,10 @@ int ha_ibmdb2i::reset_auto_increment(ulonglong value)
...
@@ -1637,10 +1736,10 @@ int ha_ibmdb2i::reset_auto_increment(ulonglong value)
rc
=
db2i_ileBridge
::
getBridgeForThread
()
->
execSQL
(
sqlStream
.
getPtrToData
(),
rc
=
db2i_ileBridge
::
getBridgeForThread
()
->
execSQL
(
sqlStream
.
getPtrToData
(),
sqlStream
.
getStatementCount
(),
sqlStream
.
getStatementCount
(),
getCommitLevel
(),
QMY_NONE
,
//getCommitLevel(),
FALSE
,
FALSE
,
FALSE
,
FALSE
,
FALSE
,
TRUE
,
//FALSE,
dataHandle
);
dataHandle
);
if
(
rc
==
0
)
if
(
rc
==
0
)
db2Table
->
updateStartId
(
value
);
db2Table
->
updateStartId
(
value
);
...
@@ -1657,7 +1756,8 @@ int ha_ibmdb2i::reset_auto_increment(ulonglong value)
...
@@ -1657,7 +1756,8 @@ int ha_ibmdb2i::reset_auto_increment(ulonglong value)
bool
ha_ibmdb2i
::
get_error_message
(
int
error
,
String
*
buf
)
bool
ha_ibmdb2i
::
get_error_message
(
int
error
,
String
*
buf
)
{
{
DBUG_ENTER
(
"ha_ibmdb2i::get_error_message"
);
DBUG_ENTER
(
"ha_ibmdb2i::get_error_message"
);
if
(
error
>=
DB2I_FIRST_ERR
&&
error
<=
DB2I_LAST_ERR
)
if
((
error
>=
DB2I_FIRST_ERR
&&
error
<=
DB2I_LAST_ERR
)
||
(
error
>=
QMY_ERR_MIN
&&
error
<=
QMY_ERR_MAX
))
{
{
db2i_ileBridge
*
bridge
=
db2i_ileBridge
::
getBridgeForThread
(
ha_thd
());
db2i_ileBridge
*
bridge
=
db2i_ileBridge
::
getBridgeForThread
(
ha_thd
());
char
*
errMsg
=
bridge
->
getErrorStorage
();
char
*
errMsg
=
bridge
->
getErrorStorage
();
...
@@ -1774,6 +1874,8 @@ int ha_ibmdb2i::external_lock(THD *thd, int lock_type)
...
@@ -1774,6 +1874,8 @@ int ha_ibmdb2i::external_lock(THD *thd, int lock_type)
}
}
// Cache this away so we don't have to access it on each row operation
cachedZeroDateOption
=
(
enum_ZeroDate
)
THDVAR
(
thd
,
compat_opt_allow_zero_date_vals
);
DBUG_RETURN
(
rc
);
DBUG_RETURN
(
rc
);
}
}
...
@@ -1834,9 +1936,16 @@ int ha_ibmdb2i::delete_table(const char *name)
...
@@ -1834,9 +1936,16 @@ int ha_ibmdb2i::delete_table(const char *name)
if
(
rc
==
0
)
if
(
rc
==
0
)
{
{
db2i_table
::
deleteAssocFiles
(
name
);
db2i_table
::
deleteAssocFiles
(
name
);
FILE_HANDLE
savedHandle
=
bridge
->
findAndRemovePreservedHandle
(
name
);
}
if
(
savedHandle
)
FILE_HANDLE
savedHandle
=
bridge
->
findAndRemovePreservedHandle
(
name
,
&
share
);
while
(
savedHandle
)
{
bridge
->
deallocateFile
(
savedHandle
,
TRUE
);
bridge
->
deallocateFile
(
savedHandle
,
TRUE
);
DBUG_ASSERT
(
share
);
if
(
free_share
(
share
))
share
=
NULL
;
savedHandle
=
bridge
->
findAndRemovePreservedHandle
(
name
,
&
share
);
}
}
my_errno
=
rc
;
my_errno
=
rc
;
...
@@ -2012,7 +2121,8 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
...
@@ -2012,7 +2121,8 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
if
(
osVersion
.
v
<
6
)
if
(
osVersion
.
v
<
6
)
{
{
if
(
strlen
(
libName
)
>
MAX_DB2_V5R4_LIBNAME_LENGTH
)
if
(
strlen
(
libName
)
>
MAX_DB2_V5R4_LIBNAME_LENGTH
+
(
isUpperOrQuote
(
system_charset_info
,
libName
)
?
2
:
0
))
{
{
getErrTxt
(
DB2I_ERR_TOO_LONG_SCHEMA
,
libName
,
MAX_DB2_V5R4_LIBNAME_LENGTH
);
getErrTxt
(
DB2I_ERR_TOO_LONG_SCHEMA
,
libName
,
MAX_DB2_V5R4_LIBNAME_LENGTH
);
DBUG_RETURN
(
DB2I_ERR_TOO_LONG_SCHEMA
);
DBUG_RETURN
(
DB2I_ERR_TOO_LONG_SCHEMA
);
...
@@ -2043,8 +2153,11 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
...
@@ -2043,8 +2153,11 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
query
.
append
(
STRING_WITH_LEN
(
" ("
));
query
.
append
(
STRING_WITH_LEN
(
" ("
));
THD
*
thd
=
ha_thd
();
THD
*
thd
=
ha_thd
();
enum_TimeFormat
timeFormat
=
(
THDVAR
(
thd
,
create_time_columns_as_TOD
)
?
TIME_OF_DAY
:
DURATION
);
enum_TimeFormat
timeFormat
=
(
enum_TimeFormat
)(
THDVAR
(
thd
,
compat_opt_time_as_duration
));
enum_BlobMapping
blobMapping
=
(
enum_BlobMapping
)(
THDVAR
(
thd
,
map_blob_to_varchar
));
enum_YearFormat
yearFormat
=
(
enum_YearFormat
)(
THDVAR
(
thd
,
compat_opt_year_as_int
));
enum_BlobMapping
blobMapping
=
(
enum_BlobMapping
)(
THDVAR
(
thd
,
compat_opt_blob_cols
));
enum_ZeroDate
zeroDate
=
(
enum_ZeroDate
)(
THDVAR
(
thd
,
compat_opt_allow_zero_date_vals
));
bool
propagateDefaults
=
THDVAR
(
thd
,
propagate_default_col_vals
);
Field
**
field
;
Field
**
field
;
for
(
field
=
table_arg
->
field
;
*
field
;
field
++
)
for
(
field
=
table_arg
->
field
;
*
field
;
field
++
)
...
@@ -2061,7 +2174,13 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
...
@@ -2061,7 +2174,13 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
query
.
append
(
colName
);
query
.
append
(
colName
);
query
.
append
(
' '
);
query
.
append
(
' '
);
if
(
rc
=
getFieldTypeMapping
(
*
field
,
query
,
timeFormat
,
blobMapping
))
if
(
rc
=
getFieldTypeMapping
(
*
field
,
query
,
timeFormat
,
blobMapping
,
zeroDate
,
propagateDefaults
,
yearFormat
))
DBUG_RETURN
(
rc
);
DBUG_RETURN
(
rc
);
if
(
(
*
field
)
->
flags
&
NOT_NULL_FLAG
)
if
(
(
*
field
)
->
flags
&
NOT_NULL_FLAG
)
...
@@ -2106,42 +2225,34 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
...
@@ -2106,42 +2225,34 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
}
}
}
}
String
primaryKeyQuery
;
bool
primaryHasStringField
=
false
;
primaryKeyQuery
.
length
(
0
);
if
(
table_arg
->
s
->
primary_key
!=
MAX_KEY
&&
!
isTemporary
)
if
(
table_arg
->
s
->
primary_key
!=
MAX_KEY
&&
!
isTemporary
)
{
{
KEY
&
curKey
=
table_arg
->
key_info
[
table_arg
->
s
->
primary_key
];
KEY
&
curKey
=
table_arg
->
key_info
[
table_arg
->
s
->
primary_key
];
primaryKeyQuery
.
append
(
STRING_WITH_LEN
(
"
PRIMARY KEY( "
));
query
.
append
(
STRING_WITH_LEN
(
",
PRIMARY KEY( "
));
for
(
int
j
=
0
;
j
<
curKey
.
key_parts
;
++
j
)
for
(
int
j
=
0
;
j
<
curKey
.
key_parts
;
++
j
)
{
{
if
(
j
!=
0
)
if
(
j
!=
0
)
{
{
primaryKeyQ
uery
.
append
(
STRING_WITH_LEN
(
" , "
)
);
q
uery
.
append
(
STRING_WITH_LEN
(
" , "
)
);
}
}
Field
*
field
=
curKey
.
key_part
[
j
].
field
;
Field
*
field
=
curKey
.
key_part
[
j
].
field
;
convertMySQLNameToDB2Name
(
field
->
field_name
,
colName
,
sizeof
(
colName
));
convertMySQLNameToDB2Name
(
field
->
field_name
,
colName
,
sizeof
(
colName
));
primaryKeyQuery
.
append
(
colName
);
query
.
append
(
colName
);
rc
=
updateAssociatedSortSequence
(
field
,
enum_field_types
type
=
field
->
real_type
();
if
(
type
==
MYSQL_TYPE_VARCHAR
||
type
==
MYSQL_TYPE_BLOB
||
type
==
MYSQL_TYPE_STRING
)
{
rc
=
updateAssociatedSortSequence
(
field
->
charset
(),
&
fileSortSequenceType
,
&
fileSortSequenceType
,
fileSortSequence
,
fileSortSequence
,
fileSortSequenceLibrary
);
fileSortSequenceLibrary
);
if
(
rc
)
DBUG_RETURN
(
rc
);
if
(
rc
)
DBUG_RETURN
(
rc
);
primaryHasStringField
=
true
;
}
}
primaryKeyQuery
.
append
(
STRING_WITH_LEN
(
" ) "
));
}
bool
needAlterForPrimaryKey
=
FALSE
;
if
((
fileSortSequence
[
0
]
!=
'*'
)
&&
(
fileSortSequence
[
0
]
!=
'Q'
))
// An ICU sort sequence
{
needAlterForPrimaryKey
=
TRUE
;
}
else
{
if
(
primaryKeyQuery
.
length
()
>
0
)
{
query
.
append
(
STRING_WITH_LEN
(
" , "
));
query
.
append
(
primaryKeyQuery
);
}
}
query
.
append
(
STRING_WITH_LEN
(
" ) "
));
}
}
rc
=
buildDB2ConstraintString
(
thd
->
lex
,
rc
=
buildDB2ConstraintString
(
thd
->
lex
,
...
@@ -2162,20 +2273,6 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
...
@@ -2162,20 +2273,6 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
SqlStatementStream
sqlStream
(
query
.
length
());
SqlStatementStream
sqlStream
(
query
.
length
());
sqlStream
.
addStatement
(
query
,
fileSortSequence
,
fileSortSequenceLibrary
);
sqlStream
.
addStatement
(
query
,
fileSortSequence
,
fileSortSequenceLibrary
);
if
(
needAlterForPrimaryKey
==
TRUE
&&
!
isTemporary
)
{
rc
=
buildCreateIndexStatement
(
sqlStream
,
table_arg
->
key_info
[
table_arg
->
s
->
primary_key
],
true
,
libName
,
fileName
);
if
(
rc
)
DBUG_RETURN
(
rc
);
}
uint
i
=
0
;
for
(
uint
i
=
0
;
i
<
table_arg
->
s
->
keys
;
++
i
)
for
(
uint
i
=
0
;
i
<
table_arg
->
s
->
keys
;
++
i
)
{
{
if
(
i
!=
table_arg
->
s
->
primary_key
||
isTemporary
)
if
(
i
!=
table_arg
->
s
->
primary_key
||
isTemporary
)
...
@@ -2193,8 +2290,8 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
...
@@ -2193,8 +2290,8 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
initBridge
();
initBridge
();
if
(
THDVAR
(
thd
,
discovery_mode
)
==
1
)
//
if (THDVAR(thd, discovery_mode) == 1)
bridge
()
->
expectErrors
(
QMY_ERR_TABLE_EXISTS
);
//
bridge()->expectErrors(QMY_ERR_TABLE_EXISTS);
rc
=
bridge
()
->
execSQL
(
sqlStream
.
getPtrToData
(),
rc
=
bridge
()
->
execSQL
(
sqlStream
.
getPtrToData
(),
sqlStream
.
getStatementCount
(),
sqlStream
.
getStatementCount
(),
...
@@ -2209,7 +2306,7 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
...
@@ -2209,7 +2306,7 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
my_error
(
ER_BLOB_USED_AS_KEY
,
MYF
(
0
),
"*unknown*"
);
my_error
(
ER_BLOB_USED_AS_KEY
,
MYF
(
0
),
"*unknown*"
);
rc
=
ER_BLOB_USED_AS_KEY
;
rc
=
ER_BLOB_USED_AS_KEY
;
}
}
else
if
(
unlikely
(
rc
==
QMY_ERR_TABLE_EXISTS
)
&&
/*
else if (unlikely(rc == QMY_ERR_TABLE_EXISTS) &&
THDVAR(thd, discovery_mode) == 1)
THDVAR(thd, discovery_mode) == 1)
{
{
db2i_table* temp = new db2i_table(table_arg->s, name);
db2i_table* temp = new db2i_table(table_arg->s, name);
...
@@ -2221,6 +2318,7 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
...
@@ -2221,6 +2318,7 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
DBUG_RETURN(rc);
DBUG_RETURN(rc);
}
}
*/
if
(
!
rc
&&
!
isTemporary
)
if
(
!
rc
&&
!
isTemporary
)
{
{
...
@@ -2483,9 +2581,9 @@ void ha_ibmdb2i::start_bulk_insert(ha_rows rows)
...
@@ -2483,9 +2581,9 @@ void ha_ibmdb2i::start_bulk_insert(ha_rows rows)
if
(
activeHandle
==
0
)
if
(
activeHandle
==
0
)
{
{
last_start_bulk_insert_rc
=
useDataFile
(
QMY_UPDATABLE
);
last_start_bulk_insert_rc
=
useDataFile
();
if
(
last_start_bulk_insert_rc
==
0
)
if
(
last_start_bulk_insert_rc
==
0
)
prepWriteBuffer
(
rows
);
last_start_bulk_insert_rc
=
prepWriteBuffer
(
rows
,
db2Table
->
dataFile
()
);
}
}
if
(
last_start_bulk_insert_rc
==
0
)
if
(
last_start_bulk_insert_rc
==
0
)
...
@@ -2519,12 +2617,18 @@ int ha_ibmdb2i::end_bulk_insert()
...
@@ -2519,12 +2617,18 @@ int ha_ibmdb2i::end_bulk_insert()
}
}
int
ha_ibmdb2i
::
prepReadBuffer
(
ha_rows
rowsToRead
)
int
ha_ibmdb2i
::
prepReadBuffer
(
ha_rows
rowsToRead
,
const
db2i_file
*
file
,
char
intent
)
{
{
DBUG_ENTER
(
"ha_ibmdb2i::prepReadBuffer"
);
DBUG_ENTER
(
"ha_ibmdb2i::prepReadBuffer"
);
DBUG_ASSERT
(
(
accessIntent
==
QMY_READ_ONLY
||
accessIntent
==
QMY_UPDATABLE
)
&&
rowsToRead
>
0
);
DBUG_ASSERT
(
rowsToRead
>
0
);
int
rc
=
0
;
THD
*
thd
=
ha_thd
();
char
cmtLvl
=
getCommitLevel
(
thd
);
const
db2i_file
::
RowFormat
*
format
;
int
rc
=
file
->
obtainRowFormat
(
activeHandle
,
intent
,
cmtLvl
,
&
format
);
if
(
unlikely
(
rc
))
DBUG_RETURN
(
rc
);
if
(
lobFieldsRequested
())
if
(
lobFieldsRequested
())
{
{
...
@@ -2534,10 +2638,8 @@ int ha_ibmdb2i::prepReadBuffer(ha_rows rowsToRead)
...
@@ -2534,10 +2638,8 @@ int ha_ibmdb2i::prepReadBuffer(ha_rows rowsToRead)
rowsToRead
=
min
(
stats
.
records
+
1
,
min
(
rowsToRead
,
DEFAULT_MAX_ROWS_TO_BUFFER
));
rowsToRead
=
min
(
stats
.
records
+
1
,
min
(
rowsToRead
,
DEFAULT_MAX_ROWS_TO_BUFFER
));
THD
*
thd
=
ha_thd
();
uint
bufSize
=
min
((
format
->
readRowLen
*
rowsToRead
),
THDVAR
(
thd
,
max_read_buffer_size
));
multiRowReadBuf
.
allocBuf
(
format
->
readRowLen
,
format
->
readRowNullOffset
,
bufSize
);
uint
bufSize
=
min
((
activeFormat
->
readRowLen
*
rowsToRead
),
THDVAR
(
thd
,
max_read_buffer_size
));
multiRowReadBuf
.
allocBuf
(
activeFormat
->
readRowLen
,
bufSize
);
activeReadBuf
=
&
multiRowReadBuf
;
activeReadBuf
=
&
multiRowReadBuf
;
if
(
db2Table
->
hasBlobs
())
if
(
db2Table
->
hasBlobs
())
...
@@ -2547,28 +2649,42 @@ int ha_ibmdb2i::prepReadBuffer(ha_rows rowsToRead)
...
@@ -2547,28 +2649,42 @@ int ha_ibmdb2i::prepReadBuffer(ha_rows rowsToRead)
rc
=
prepareReadBufferForLobs
();
rc
=
prepareReadBufferForLobs
();
if
(
rc
)
DBUG_RETURN
(
rc
);
if
(
rc
)
DBUG_RETURN
(
rc
);
}
}
activeReadBuf
->
update
(
accessIntent
,
&
releaseRowNeeded
,
getCommitLevel
(
thd
));
// if (accessIntent == QMY_UPDATABLE &&
// thd_tx_isolation(thd) == ISO_REPEATABLE_READ &&
// !THDVAR(thd, transaction_unsafe))
// activeReadBuf->update(QMY_READ_ONLY, &releaseRowNeeded, QMY_REPEATABLE_READ);
// else
activeReadBuf
->
update
(
intent
,
&
releaseRowNeeded
,
cmtLvl
);
DBUG_RETURN
(
rc
);
DBUG_RETURN
(
rc
);
}
}
void
ha_ibmdb2i
::
prepWriteBuffer
(
ha_rows
rowsToWrit
e
)
int
ha_ibmdb2i
::
prepWriteBuffer
(
ha_rows
rowsToWrite
,
const
db2i_file
*
fil
e
)
{
{
DBUG_ENTER
(
"ha_ibmdb2i::prepWriteBuffer"
);
DBUG_ENTER
(
"ha_ibmdb2i::prepWriteBuffer"
);
DBUG_ASSERT
(
accessIntent
==
QMY_UPDATABLE
&&
rowsToWrite
>
0
);
DBUG_ASSERT
(
accessIntent
==
QMY_UPDATABLE
&&
rowsToWrite
>
0
);
const
db2i_file
::
RowFormat
*
format
;
int
rc
=
file
->
obtainRowFormat
(
activeHandle
,
QMY_UPDATABLE
,
getCommitLevel
(
ha_thd
()),
&
format
);
if
(
unlikely
(
rc
))
DBUG_RETURN
(
rc
);
rowsToWrite
=
min
(
rowsToWrite
,
DEFAULT_MAX_ROWS_TO_BUFFER
);
rowsToWrite
=
min
(
rowsToWrite
,
DEFAULT_MAX_ROWS_TO_BUFFER
);
uint
bufSize
=
min
((
activeF
ormat
->
writeRowLen
*
rowsToWrite
),
THDVAR
(
ha_thd
(),
max_write_buffer_size
));
uint
bufSize
=
min
((
f
ormat
->
writeRowLen
*
rowsToWrite
),
THDVAR
(
ha_thd
(),
max_write_buffer_size
));
multiRowWriteBuf
.
allocBuf
(
activeFormat
->
writeRowLen
,
bufSize
);
multiRowWriteBuf
.
allocBuf
(
format
->
writeRowLen
,
format
->
writeRowNullOffset
,
bufSize
);
activeWriteBuf
=
&
multiRowWriteBuf
;
activeWriteBuf
=
&
multiRowWriteBuf
;
if
(
!
blobWriteBuffers
&&
db2Table
->
hasBlobs
())
if
(
!
blobWriteBuffers
&&
db2Table
->
hasBlobs
())
{
{
blobWriteBuffers
=
new
ValidatedPointer
<
char
>
[
db2Table
->
getBlobCount
()];
blobWriteBuffers
=
new
ValidatedPointer
<
char
>
[
db2Table
->
getBlobCount
()];
}
}
DBUG_
VOID_RETURN
;
DBUG_
RETURN
(
rc
)
;
}
}
...
@@ -2621,7 +2737,7 @@ int ha_ibmdb2i::flushWrite(FILE_HANDLE fileHandle, uchar* buf )
...
@@ -2621,7 +2737,7 @@ int ha_ibmdb2i::flushWrite(FILE_HANDLE fileHandle, uchar* buf )
readAllColumns
=
true
;
readAllColumns
=
true
;
mungeDB2row
(
buf
,
mungeDB2row
(
buf
,
badRow
,
badRow
,
badRow
+
active
Format
->
writeRowNullOffset
,
badRow
+
active
WriteBuf
->
getRowNullOffset
()
,
true
);
true
);
readAllColumns
=
savedReadAllColumns
;
readAllColumns
=
savedReadAllColumns
;
...
@@ -2770,7 +2886,7 @@ int ha_ibmdb2i::prepareReadBufferForLobs()
...
@@ -2770,7 +2886,7 @@ int ha_ibmdb2i::prepareReadBufferForLobs()
activeReadBuf
->
setRowsToProcess
((
activeLobFields
?
1
:
activeReadBuf
->
getRowCapacity
()));
activeReadBuf
->
setRowsToProcess
((
activeLobFields
?
1
:
activeReadBuf
->
getRowCapacity
()));
int
rc
=
bridge
()
->
objectOverride
(
activeHandle
,
int
rc
=
bridge
()
->
objectOverride
(
activeHandle
,
activeReadBuf
->
ptr
(),
activeReadBuf
->
ptr
(),
active
Format
->
readRowLen
);
active
ReadBuf
->
getRowLength
()
);
DBUG_RETURN
(
rc
);
DBUG_RETURN
(
rc
);
}
}
...
@@ -2898,7 +3014,10 @@ int32 ha_ibmdb2i::buildCreateIndexStatement(SqlStatementStream& sqlStream,
...
@@ -2898,7 +3014,10 @@ int32 ha_ibmdb2i::buildCreateIndexStatement(SqlStatementStream& sqlStream,
Field
*
field
=
key
.
key_part
[
j
].
field
;
Field
*
field
=
key
.
key_part
[
j
].
field
;
convertMySQLNameToDB2Name
(
field
->
field_name
,
colName
,
sizeof
(
colName
));
convertMySQLNameToDB2Name
(
field
->
field_name
,
colName
,
sizeof
(
colName
));
fieldDefinition
.
append
(
colName
);
fieldDefinition
.
append
(
colName
);
rc
=
updateAssociatedSortSequence
(
field
,
&
fileSortSequenceType
,
fileSortSequence
,
fileSortSequenceLibrary
);
rc
=
updateAssociatedSortSequence
(
field
->
charset
(),
&
fileSortSequenceType
,
fileSortSequence
,
fileSortSequenceLibrary
);
if
(
rc
)
DBUG_RETURN
(
rc
);
if
(
rc
)
DBUG_RETURN
(
rc
);
}
}
fieldDefinition
.
append
(
STRING_WITH_LEN
(
" ) "
));
fieldDefinition
.
append
(
STRING_WITH_LEN
(
" ) "
));
...
@@ -3098,7 +3217,7 @@ double ha_ibmdb2i::read_time(uint index, uint ranges, ha_rows rows)
...
@@ -3098,7 +3217,7 @@ double ha_ibmdb2i::read_time(uint index, uint ranges, ha_rows rows)
DBUG_RETURN
(
cost
);
DBUG_RETURN
(
cost
);
}
}
int
ha_ibmdb2i
::
useIndexFile
(
char
intent
,
int
idx
)
int
ha_ibmdb2i
::
useIndexFile
(
int
idx
)
{
{
DBUG_ENTER
(
"ha_ibmdb2i::useIndexFile"
);
DBUG_ENTER
(
"ha_ibmdb2i::useIndexFile"
);
...
@@ -3110,19 +3229,11 @@ int ha_ibmdb2i::useIndexFile(char intent, int idx)
...
@@ -3110,19 +3229,11 @@ int ha_ibmdb2i::useIndexFile(char intent, int idx)
if
(
!
indexHandles
[
idx
])
if
(
!
indexHandles
[
idx
])
rc
=
db2Table
->
indexFile
(
idx
)
->
allocateNewInstance
(
&
indexHandles
[
idx
],
curConnection
);
rc
=
db2Table
->
indexFile
(
idx
)
->
allocateNewInstance
(
&
indexHandles
[
idx
],
curConnection
);
if
(
rc
==
0
)
{
rc
=
db2Table
->
indexFile
(
idx
)
->
useFile
(
indexHandles
[
idx
],
intent
,
getCommitLevel
(),
&
activeFormat
);
if
(
rc
==
0
)
if
(
rc
==
0
)
{
{
activeHandle
=
indexHandles
[
idx
];
activeHandle
=
indexHandles
[
idx
];
bumpInUseCounter
(
1
);
bumpInUseCounter
(
1
);
}
}
}
DBUG_RETURN
(
rc
);
DBUG_RETURN
(
rc
);
}
}
...
@@ -3141,11 +3252,15 @@ static struct st_mysql_sys_var* ibmdb2i_system_variables[] = {
...
@@ -3141,11 +3252,15 @@ static struct st_mysql_sys_var* ibmdb2i_system_variables[] = {
MYSQL_SYSVAR
(
max_read_buffer_size
),
MYSQL_SYSVAR
(
max_read_buffer_size
),
MYSQL_SYSVAR
(
max_write_buffer_size
),
MYSQL_SYSVAR
(
max_write_buffer_size
),
MYSQL_SYSVAR
(
async_enabled
),
MYSQL_SYSVAR
(
async_enabled
),
MYSQL_SYSVAR
(
create_time_columns_as_TOD
),
MYSQL_SYSVAR
(
assume_exclusive_use
),
MYSQL_SYSVAR
(
assume_exclusive_use
),
MYSQL_SYSVAR
(
map_blob_to_varchar
),
MYSQL_SYSVAR
(
compat_opt_blob_cols
),
MYSQL_SYSVAR
(
compat_opt_time_as_duration
),
MYSQL_SYSVAR
(
compat_opt_allow_zero_date_vals
),
MYSQL_SYSVAR
(
compat_opt_year_as_int
),
MYSQL_SYSVAR
(
propagate_default_col_vals
),
MYSQL_SYSVAR
(
create_index_option
),
MYSQL_SYSVAR
(
create_index_option
),
MYSQL_SYSVAR
(
discovery_mode
),
// MYSQL_SYSVAR(discovery_mode),
MYSQL_SYSVAR
(
system_trace_level
),
NULL
NULL
};
};
...
@@ -3160,7 +3275,7 @@ mysql_declare_plugin(ibmdb2i)
...
@@ -3160,7 +3275,7 @@ mysql_declare_plugin(ibmdb2i)
"IBMDB2I"
,
"IBMDB2I"
,
"The IBM development team in Rochester, Minnesota"
,
"The IBM development team in Rochester, Minnesota"
,
"IBM DB2 for i Storage Engine"
,
"IBM DB2 for i Storage Engine"
,
PLUGIN_LICENSE_
PROPRIETARY
,
PLUGIN_LICENSE_
GPL
,
ibmdb2i_init_func
,
/* Plugin Init */
ibmdb2i_init_func
,
/* Plugin Init */
ibmdb2i_done_func
,
/* Plugin Deinit */
ibmdb2i_done_func
,
/* Plugin Deinit */
0x0100
/* 1.0 */
,
0x0100
/* 1.0 */
,
...
...
storage/ibmdb2i/ha_ibmdb2i.h
View file @
c61fab93
...
@@ -65,7 +65,7 @@ OF SUCH DAMAGE.
...
@@ -65,7 +65,7 @@ OF SUCH DAMAGE.
It is used to describe the underlying table definition, and it caches
It is used to describe the underlying table definition, and it caches
table statistics.
table statistics.
*/
*/
typedef
struct
st_ibmdb2i_share
{
struct
IBMDB2I_SHARE
{
char
*
table_name
;
char
*
table_name
;
uint
table_name_length
,
use_count
;
uint
table_name_length
,
use_count
;
pthread_mutex_t
mutex
;
pthread_mutex_t
mutex
;
...
@@ -110,7 +110,7 @@ typedef struct st_ibmdb2i_share {
...
@@ -110,7 +110,7 @@ typedef struct st_ibmdb2i_share {
ulong
data_file_length
;
ulong
data_file_length
;
}
cachedStats
;
}
cachedStats
;
}
IBMDB2I_SHARE
;
};
class
ha_ibmdb2i
:
public
handler
class
ha_ibmdb2i
:
public
handler
{
{
...
@@ -143,16 +143,15 @@ class ha_ibmdb2i: public handler
...
@@ -143,16 +143,15 @@ class ha_ibmdb2i: public handler
// Array of file handles belonging to the underlying LFs
// Array of file handles belonging to the underlying LFs
FILE_HANDLE
*
indexHandles
;
FILE_HANDLE
*
indexHandles
;
// Pointer to a definition of the layout of the row buffer for the file
// described by activeHandle
const
db2i_file
::
RowFormat
*
activeFormat
;
// Flag to indicate whether a call needs to be made to unlock a row when
// Flag to indicate whether a call needs to be made to unlock a row when
// a read operation has ended. DB2 will handle row unlocking as we move
// a read operation has ended. DB2 will handle row unlocking as we move
// through rows, but if an operation ends before we reach the end of a file,
// through rows, but if an operation ends before we reach the end of a file,
// DB2 needs to know to unlock the last row read.
// DB2 needs to know to unlock the last row read.
bool
releaseRowNeeded
;
bool
releaseRowNeeded
;
// Pointer to a definition of the layout of the row buffer for the file
// described by activeHandle
const
db2i_file
::
RowFormat
*
activeFormat
;
IORowBuffer
keyBuf
;
IORowBuffer
keyBuf
;
uint32
keyLen
;
uint32
keyLen
;
...
@@ -190,6 +189,7 @@ class ha_ibmdb2i: public handler
...
@@ -190,6 +189,7 @@ class ha_ibmdb2i: public handler
// The access intent indicated by the last external_locks() call.
// The access intent indicated by the last external_locks() call.
// May be either QMY_READ or QMY_UPDATABLE
// May be either QMY_READ or QMY_UPDATABLE
char
accessIntent
;
char
accessIntent
;
char
readAccessIntent
;
ha_rows
*
indexReadSizeEstimates
;
ha_rows
*
indexReadSizeEstimates
;
...
@@ -361,6 +361,20 @@ class ha_ibmdb2i: public handler
...
@@ -361,6 +361,20 @@ class ha_ibmdb2i: public handler
AS_VARCHAR
AS_VARCHAR
};
};
enum
enum_ZeroDate
{
NO_SUBSTITUTE
,
SUBSTITUTE_0001_01_01
};
enum
enum_YearFormat
{
CHAR4
,
SMALLINT
};
enum_ZeroDate
cachedZeroDateOption
;
IBMDB2I_SHARE
*
get_share
(
const
char
*
table_name
,
TABLE
*
table
);
IBMDB2I_SHARE
*
get_share
(
const
char
*
table_name
,
TABLE
*
table
);
int
free_share
(
IBMDB2I_SHARE
*
share
);
int
free_share
(
IBMDB2I_SHARE
*
share
);
int32
mungeDB2row
(
uchar
*
record
,
const
char
*
dataPtr
,
const
char
*
nullMapPtr
,
bool
skipLOBs
);
int32
mungeDB2row
(
uchar
*
record
,
const
char
*
dataPtr
,
const
char
*
nullMapPtr
,
bool
skipLOBs
);
...
@@ -396,10 +410,9 @@ class ha_ibmdb2i: public handler
...
@@ -396,10 +410,9 @@ class ha_ibmdb2i: public handler
}
}
int
useDataFile
(
char
intent
)
int
useDataFile
()
{
{
DBUG_ENTER
(
"ha_ibmdb2i::useDataFile"
);
DBUG_ENTER
(
"ha_ibmdb2i::useDataFile"
);
DBUG_PRINT
(
"ha_ibmdb2i::useDataFile"
,
(
"Intent: %d"
,
intent
));
int
rc
=
0
;
int
rc
=
0
;
if
(
!
dataHandle
)
if
(
!
dataHandle
)
...
@@ -409,20 +422,11 @@ class ha_ibmdb2i: public handler
...
@@ -409,20 +422,11 @@ class ha_ibmdb2i: public handler
DBUG_ASSERT
(
activeHandle
==
0
);
DBUG_ASSERT
(
activeHandle
==
0
);
if
(
likely
(
rc
==
0
))
{
rc
=
db2Table
->
dataFile
()
->
useFile
(
dataHandle
,
intent
,
getCommitLevel
(),
&
activeFormat
);
if
(
likely
(
rc
==
0
))
if
(
likely
(
rc
==
0
))
{
{
activeHandle
=
dataHandle
;
activeHandle
=
dataHandle
;
bumpInUseCounter
(
1
);
bumpInUseCounter
(
1
);
}
}
}
DBUG_RETURN
(
rc
);
DBUG_RETURN
(
rc
);
}
}
...
@@ -448,7 +452,7 @@ class ha_ibmdb2i: public handler
...
@@ -448,7 +452,7 @@ class ha_ibmdb2i: public handler
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
int
useIndexFile
(
char
intent
,
int
idx
);
int
useIndexFile
(
int
idx
);
void
releaseIndexFile
(
int
idx
)
void
releaseIndexFile
(
int
idx
)
{
{
...
@@ -526,7 +530,10 @@ class ha_ibmdb2i: public handler
...
@@ -526,7 +530,10 @@ class ha_ibmdb2i: public handler
int
getFieldTypeMapping
(
Field
*
field
,
int
getFieldTypeMapping
(
Field
*
field
,
String
&
mapping
,
String
&
mapping
,
enum_TimeFormat
timeFormate
,
enum_TimeFormat
timeFormate
,
enum_BlobMapping
blobMapping
);
enum_BlobMapping
blobMapping
,
enum_ZeroDate
zeroDateHandling
,
bool
propagateDefaults
,
enum_YearFormat
yearFormat
);
int
getKeyFromName
(
const
char
*
name
,
size_t
len
);
int
getKeyFromName
(
const
char
*
name
,
size_t
len
);
...
@@ -564,6 +571,9 @@ class ha_ibmdb2i: public handler
...
@@ -564,6 +571,9 @@ class ha_ibmdb2i: public handler
{
{
DBUG_ASSERT
(
activeReadBuf
->
rowCount
()
==
1
);
DBUG_ASSERT
(
activeReadBuf
->
rowCount
()
==
1
);
row
=
activeReadBuf
->
readNextRow
(
orientation
,
currentRRN
);
row
=
activeReadBuf
->
readNextRow
(
orientation
,
currentRRN
);
if
(
unlikely
(
!
row
))
rc
=
activeReadBuf
->
lastrc
();
}
}
}
}
}
}
...
@@ -571,7 +581,7 @@ class ha_ibmdb2i: public handler
...
@@ -571,7 +581,7 @@ class ha_ibmdb2i: public handler
if
(
likely
(
rc
==
0
))
if
(
likely
(
rc
==
0
))
{
{
rrnAssocHandle
=
activeHandle
;
rrnAssocHandle
=
activeHandle
;
rc
=
mungeDB2row
(
destination
,
row
,
row
+
active
Format
->
readRowNullOffset
,
false
);
rc
=
mungeDB2row
(
destination
,
row
,
row
+
active
ReadBuf
->
getRowNullOffset
()
,
false
);
}
}
return
rc
;
return
rc
;
}
}
...
@@ -631,7 +641,7 @@ class ha_ibmdb2i: public handler
...
@@ -631,7 +641,7 @@ class ha_ibmdb2i: public handler
}
}
}
}
int
rc
=
file
->
useFile
(
handle
,
intent
,
getCommitLevel
(),
&
activeFormat
);
int
rc
=
file
->
obtainRowFormat
(
handle
,
intent
,
getCommitLevel
(),
&
activeFormat
);
if
(
likely
(
rc
==
0
))
if
(
likely
(
rc
==
0
))
{
{
activeHandle
=
handle
;
activeHandle
=
handle
;
...
@@ -641,12 +651,25 @@ class ha_ibmdb2i: public handler
...
@@ -641,12 +651,25 @@ class ha_ibmdb2i: public handler
DBUG_RETURN
(
rc
);
DBUG_RETURN
(
rc
);
}
}
int
prepReadBuffer
(
ha_rows
rowsToRead
);
const
db2i_file
*
getFileForActiveHandle
()
const
void
prepWriteBuffer
(
ha_rows
rowsToWrite
);
{
if
(
activeHandle
==
dataHandle
)
return
db2Table
->
dataFile
();
else
for
(
uint
i
=
0
;
i
<
table_share
->
keys
;
++
i
)
if
(
indexHandles
[
i
]
==
activeHandle
)
return
db2Table
->
indexFile
(
i
);
DBUG_ASSERT
(
0
);
return
NULL
;
}
int
prepReadBuffer
(
ha_rows
rowsToRead
,
const
db2i_file
*
file
,
char
intent
);
int
prepWriteBuffer
(
ha_rows
rowsToWrite
,
const
db2i_file
*
file
);
void
invalidateCachedStats
()
void
invalidateCachedStats
()
{
{
share
->
cachedStats
.
invalidate
(
rowCount
|
deletedRowCount
|
objLength
|
meanRowLen
|
ioCount
);
share
->
cachedStats
.
invalidate
(
rowCount
|
deletedRowCount
|
objLength
|
meanRowLen
|
ioCount
);
}
}
void
warnIfInvalidData
()
void
warnIfInvalidData
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment