summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorRamil Kalimullin <ramil@mysql.com>2010-11-18 13:40:57 +0300
committerRamil Kalimullin <ramil@mysql.com>2010-11-18 13:40:57 +0300
commit7a4708cfd7ee7cd51d637e48366bed0791d77c4f (patch)
treef67f4a6e2fd2e3828a0321bbd2b1c6ffc5f0d220 /storage
parent594a599247489df21747526c523f436c41511dfe (diff)
parentaaa370f5d7fa08b4b6c7fb56bd54f84829626e07 (diff)
downloadmariadb-git-7a4708cfd7ee7cd51d637e48366bed0791d77c4f.tar.gz
Auto-merge from mysql-5.1-bugteam.
Diffstat (limited to 'storage')
-rw-r--r--storage/ibmdb2i/CMakeLists.txt25
-rw-r--r--storage/ibmdb2i/Makefile.am54
-rw-r--r--storage/ibmdb2i/db2i_blobCollection.cc107
-rw-r--r--storage/ibmdb2i/db2i_blobCollection.h151
-rw-r--r--storage/ibmdb2i/db2i_charsetSupport.cc826
-rw-r--r--storage/ibmdb2i/db2i_charsetSupport.h65
-rw-r--r--storage/ibmdb2i/db2i_collationSupport.cc355
-rw-r--r--storage/ibmdb2i/db2i_collationSupport.h48
-rw-r--r--storage/ibmdb2i/db2i_constraints.cc672
-rw-r--r--storage/ibmdb2i/db2i_conversion.cc1459
-rw-r--r--storage/ibmdb2i/db2i_errors.cc297
-rw-r--r--storage/ibmdb2i/db2i_errors.h93
-rw-r--r--storage/ibmdb2i/db2i_file.cc556
-rw-r--r--storage/ibmdb2i/db2i_file.h445
-rw-r--r--storage/ibmdb2i/db2i_global.h138
-rw-r--r--storage/ibmdb2i/db2i_iconv.h51
-rw-r--r--storage/ibmdb2i/db2i_ileBridge.cc1342
-rw-r--r--storage/ibmdb2i/db2i_ileBridge.h499
-rw-r--r--storage/ibmdb2i/db2i_ioBuffers.cc332
-rw-r--r--storage/ibmdb2i/db2i_ioBuffers.h416
-rw-r--r--storage/ibmdb2i/db2i_misc.h129
-rw-r--r--storage/ibmdb2i/db2i_myconv.cc1498
-rw-r--r--storage/ibmdb2i/db2i_myconv.h3201
-rw-r--r--storage/ibmdb2i/db2i_rir.cc686
-rw-r--r--storage/ibmdb2i/db2i_safeString.h98
-rw-r--r--storage/ibmdb2i/db2i_sqlStatementStream.cc86
-rw-r--r--storage/ibmdb2i/db2i_sqlStatementStream.h151
-rw-r--r--storage/ibmdb2i/db2i_validatedPointer.h162
-rw-r--r--storage/ibmdb2i/ha_ibmdb2i.cc3359
-rw-r--r--storage/ibmdb2i/ha_ibmdb2i.h822
-rw-r--r--storage/ibmdb2i/plug.in12
-rw-r--r--storage/myisam/ft_nlq_search.c2
-rw-r--r--storage/myisam/mi_create.c4
-rw-r--r--storage/myisammrg/myrg_open.c2
34 files changed, 3 insertions, 18140 deletions
diff --git a/storage/ibmdb2i/CMakeLists.txt b/storage/ibmdb2i/CMakeLists.txt
deleted file mode 100644
index 11cc4300569..00000000000
--- a/storage/ibmdb2i/CMakeLists.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2006 MySQL AB
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
- ${CMAKE_SOURCE_DIR}/regex
- ${CMAKE_SOURCE_DIR}/extra/yassl/include)
-ADD_LIBRARY(ibmdb2i ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc
- db2i_blobCollection.cc db2i_file.cc db2i_charsetSupport.cc
- db2i_collationSupport.cc db2i_errors.cc db2i_constraints.cc
- db2i_rir.cc db2i_sqlStatementStream.cc db2i_ioBuffers.cc db2i_myconv.cc)
diff --git a/storage/ibmdb2i/Makefile.am b/storage/ibmdb2i/Makefile.am
deleted file mode 100644
index b9602e392e0..00000000000
--- a/storage/ibmdb2i/Makefile.am
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Copyright (c) 2007, 2008, IBM Corporation.
-# All rights reserved.
-#
-#
-
-#called from the top level Makefile
-
-MYSQLDATAdir = $(localstatedir)
-MYSQLSHAREdir = $(pkgdatadir)
-MYSQLBASEdir= $(prefix)
-MYSQLLIBdir= $(pkglibdir)
-pkgplugindir = $(pkglibdir)/plugin
-INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
- -I$(top_srcdir)/regex \
- -I$(top_srcdir)/sql \
- -I$(srcdir) \
- -I$ /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0f.xpf/cur/cmvc/base.pgm/my.xpf/apis \
- -I$ /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0.xpf/bld/cmvc/base.pgm/lg.xpf \
- -I$ /afs/rchland.ibm.com/lande/shadow/dev2000/osxpf/v5r4m0.xpf/bld/cmvc/base.pgm/tq.xpf
-WRAPLIBS=
-
-LDADD =
-
-DEFS = @DEFS@
-
-noinst_HEADERS = ha_ibmdb2i.h db2i_collationSupport.h db2i_file.h \
- db2i_ioBuffers.h db2i_blobCollection.h \
- db2i_global.h db2i_misc.h db2i_charsetSupport.h db2i_errors.h \
- db2i_iconv.h db2i_myconv.h db2i_safeString.h db2i_sqlStatementStream.h \
- db2i_ileBridge.h db2i_validatedPointer.h
-
-EXTRA_LTLIBRARIES = ha_ibmdb2i.la
-pkgplugin_LTLIBRARIES = @plugin_ibmdb2i_shared_target@
-ha_ibmdb2i_la_LIBADD = -liconv
-ha_ibmdb2i_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
-ha_ibmdb2i_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_ibmdb2i_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_ibmdb2i_la_SOURCES = ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc \
- db2i_blobCollection.cc db2i_file.cc db2i_charsetSupport.cc \
- db2i_collationSupport.cc db2i_errors.cc db2i_constraints.cc \
- db2i_rir.cc db2i_sqlStatementStream.cc db2i_ioBuffers.cc \
- db2i_myconv.cc
-
-EXTRA_LIBRARIES = libibmdb2i.a
-noinst_LIBRARIES = @plugin_ibmdb2i_static_target@
-libibmdb2i_a_CXXFLAGS = $(AM_CXXFLAGS)
-libibmdb2i_a_CFLAGS = $(AM_CFLAGS)
-libibmdb2i_a_SOURCES= $(ha_ibmdb2i_la_SOURCES)
-
-
-EXTRA_DIST = CMakeLists.txt plug.in
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/storage/ibmdb2i/db2i_blobCollection.cc b/storage/ibmdb2i/db2i_blobCollection.cc
deleted file mode 100644
index 17101c9c0a4..00000000000
--- a/storage/ibmdb2i/db2i_blobCollection.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#include "db2i_blobCollection.h"
-
-/**
- Return the size to use when allocating space for blob reads.
-
- @param fieldIndex The field to allocate for
- @param[out] shouldProtect Indicates whether storage protection should be
- applied to the space, because the size returned is
- smaller than the maximum possible size.
-*/
-
-uint32
-BlobCollection::getSizeToAllocate(int fieldIndex, bool& shouldProtect)
-{
- Field* field = table->getMySQLTable()->field[fieldIndex];
- uint fieldLength = field->max_display_length();
-
- if (fieldLength <= MAX_FULL_ALLOCATE_BLOB_LENGTH)
- {
- shouldProtect = false;
- return fieldLength;
- }
-
- shouldProtect = true;
-
- uint curMaxSize = table->getBlobFieldActualSize(fieldIndex);
-
- uint defaultAllocSize = min(defaultAllocation, fieldLength);
-
- return max(defaultAllocSize, curMaxSize);
-
-}
-
-void
-BlobCollection::generateBuffer(int fieldIndex)
-{
- DBUG_ASSERT(table->db2Field(fieldIndex).isBlob());
-
- bool protect;
- buffers[table->getBlobIdFromField(fieldIndex)].Malloc(getSizeToAllocate(fieldIndex, protect), protect);
-
- return;
-}
-
-/**
- Realloc the read buffer associated with a blob field.
-
- This is used when the previous allocation for a blob field is found to be
- too small (this is discovered when QMY_READ trips over the protected boundary
- page).
-
- @param fieldIndex The field to be reallocated
- @param size The size of buffer to allocate for this field.
-*/
-
-ValidatedPointer<char>&
-BlobCollection::reallocBuffer(int fieldIndex, size_t size)
-{
- ProtectedBuffer& buf = buffers[table->getBlobIdFromField(fieldIndex)];
- if (size <= buf.allocLen())
- return buf.ptr();
-
- table->updateBlobFieldActualSize(fieldIndex, size);
-
- DBUG_PRINT("BlobCollection::reallocBuffer",("PERF: reallocing %d to %d: ", fieldIndex, size));
-
- bool protect;
- buf.Free();
- buf.Malloc(getSizeToAllocate(fieldIndex, protect), protect);
- return buf.ptr();
-}
diff --git a/storage/ibmdb2i/db2i_blobCollection.h b/storage/ibmdb2i/db2i_blobCollection.h
deleted file mode 100644
index 6a60394555f..00000000000
--- a/storage/ibmdb2i/db2i_blobCollection.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#ifndef DB2I_BLOBCOLLECTION_H
-#define DB2I_BLOBCOLLECTION_H
-
-#include "db2i_global.h"
-#include "db2i_file.h"
-
-/**
- @class ProtectedBuffer
- @brief Implements memory management for (optionally) protected buffers.
-
- Buffers created with the protection option will have a guard page set on the
- page following requested allocation size. The side effect is that the actual
- allocation is up to 2*4096-1 bytes larger than the size requested by the
- using code.
-*/
-
-class ProtectedBuffer
-{
-public:
- ProtectedBuffer() : protectBuf(false)
- {;}
-
- void Malloc(size_t size, bool protect = false)
- {
- protectBuf = protect;
- bufptr.alloc(size + (protectBuf ? 0x1fff : 0x0));
- if ((void*)bufptr != NULL)
- {
- len = size;
- if (protectBuf)
- 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
- }
- }
-
- void Free()
- {
- if ((void*)bufptr != NULL)
- {
- if (protectBuf)
- mprotect(protectedPage(), 0x1000, PROT_READ | PROT_WRITE);
- bufptr.dealloc();
- }
- }
-
- ~ProtectedBuffer()
- {
- Free();
- }
-
- ValidatedPointer<char>& ptr() {return bufptr;}
- bool isProtected() const {return protectBuf;}
- size_t allocLen() const {return len;}
-private:
- void* protectedPage()
- {
- return (void*)(((address64_t)(void*)bufptr + len + 0x1000) & ~0xfff);
- }
-
- ValidatedPointer<char> bufptr;
- size_t len;
- bool protectBuf;
-
-};
-
-
-/**
- @class BlobCollection
- @brief Manages memory allocation for reading blobs associated with a table.
-
- Allocations are done on-demand and are protected with a guard page if less
- than the max possible size is allocated.
-*/
-class BlobCollection
-{
- public:
- BlobCollection(db2i_table* db2Table, uint32 defaultAllocSize) :
- defaultAllocation(defaultAllocSize), table(db2Table)
- {
- buffers = new ProtectedBuffer[table->getBlobCount()];
- }
-
- ~BlobCollection()
- {
- delete[] buffers;
- }
-
- ValidatedPointer<char>& getBufferPtr(int fieldIndex)
- {
- int blobIndex = table->getBlobIdFromField(fieldIndex);
- if ((char*)buffers[blobIndex].ptr() == NULL)
- generateBuffer(fieldIndex);
-
- return buffers[blobIndex].ptr();
- }
-
- ValidatedPointer<char>& reallocBuffer(int fieldIndex, size_t size);
-
-
- private:
-
- uint32 getSizeToAllocate(int fieldIndex, bool& shouldProtect);
- void generateBuffer(int fieldIndex);
-
- db2i_table* table; // The table being read
- ProtectedBuffer* buffers; // The buffers
- uint32 defaultAllocation;
- /* The default size to use when first allocating a buffer */
-};
-
-#endif
diff --git a/storage/ibmdb2i/db2i_charsetSupport.cc b/storage/ibmdb2i/db2i_charsetSupport.cc
deleted file mode 100644
index 83bf1b9448b..00000000000
--- a/storage/ibmdb2i/db2i_charsetSupport.cc
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-
-#include "db2i_charsetSupport.h"
-#include "as400_types.h"
-#include "as400_protos.h"
-#include "db2i_ileBridge.h"
-#include "qlgusr.h"
-#include "db2i_errors.h"
-
-
-/*
- The following arrays define a mapping between IANA-style text descriptors and
- IBM i CCSID text descriptors. The mapping is a 1-to-1 correlation between
- corresponding array slots.
-*/
-#define MAX_IANASTRING 23
-static const char ianaStringType[MAX_IANASTRING][10] =
-{
- {"ascii"},
- {"Big5"}, //big5
- {"cp1250"},
- {"cp1251"},
- {"cp1256"},
- {"cp850"},
- {"cp852"},
- {"cp866"},
- {"IBM943"}, //cp932
- {"EUC-KR"}, //euckr
- {"IBM1381"}, //gb2312
- {"IBM1386"}, //gbk
- {"greek"},
- {"hebrew"},
- {"latin1"},
- {"latin2"},
- {"latin5"},
- {"macce"},
- {"tis620"},
- {"Shift_JIS"}, //sjis
- {"ucs2"},
- {"EUC-JP"}, //ujis
- {"utf8"}
-};
-static const char ccsidType[MAX_IANASTRING][6] =
-{
- {"367"}, //ascii
- {"950"}, //big5
- {"1250"}, //cp1250
- {"1251"}, //cp1251
- {"1256"}, //cp1256
- {"850"}, //cp850
- {"852"}, //cp852
- {"866"}, //cp866
- {"943"}, //cp932
- {"970"}, //euckr
- {"1381"}, //gb2312
- {"1386"}, //gbk
- {"813"}, //greek
- {"916"}, //hebrew
- {"923"}, //latin1
- {"912"}, //latin2
- {"920"}, //latin5
- {"1282"}, //macce
- {"874"}, //tis620
- {"943"}, //sjis
- {"13488"},//ucs2
- {"5050"}, //ujis
- {"1208"} //utf8
-};
-
-static _ILEpointer *QlgCvtTextDescToDesc_sym;
-
-/* We keep a cache of the mapping for text descriptions obtained via
- QlgTextDescToDesc. The following structures implement this cache. */
-static HASH textDescMapHash;
-static MEM_ROOT textDescMapMemroot;
-static pthread_mutex_t textDescMapHashMutex;
-struct TextDescMap
-{
- struct HashKey
- {
- int32 inType;
- int32 outType;
- char inDesc[Qlg_MaxDescSize];
- } hashKey;
- char outDesc[Qlg_MaxDescSize];
-};
-
-/* We keep a cache of the mapping for open iconv descriptors. The following
- structures implement this cache. */
-static HASH iconvMapHash;
-static MEM_ROOT iconvMapMemroot;
-static pthread_mutex_t iconvMapHashMutex;
-struct IconvMap
-{
- struct HashKey
- {
- uint32 direction; // These are uint32s to avoid garbage data in the key from compiler padding
- uint32 db2CCSID;
- const CHARSET_INFO* myCharset;
- } hashKey;
- iconv_t iconvDesc;
-};
-
-
-/**
- Initialize the static structures used by this module.
-
- This must only be called once per plugin instantiation.
-
- @return 0 if successful. Failure otherwise
-*/
-int32 initCharsetSupport()
-{
- DBUG_ENTER("initCharsetSupport");
-
- int actmark = _ILELOAD("QSYS/QLGUSR", ILELOAD_LIBOBJ);
- if ( actmark == -1 )
- {
- DBUG_PRINT("initCharsetSupport", ("conversion srvpgm activation failed"));
- DBUG_RETURN(1);
- }
-
- QlgCvtTextDescToDesc_sym = (ILEpointer*)malloc_aligned(sizeof(ILEpointer));
- if (_ILESYM(QlgCvtTextDescToDesc_sym, actmark, "QlgCvtTextDescToDesc") == -1)
- {
- DBUG_PRINT("initCharsetSupport",
- ("resolve of QlgCvtTextDescToDesc failed"));
- DBUG_RETURN(errno);
- }
-
- VOID(pthread_mutex_init(&textDescMapHashMutex,MY_MUTEX_INIT_FAST));
- hash_init(&textDescMapHash, &my_charset_bin, 10, offsetof(TextDescMap, hashKey), sizeof(TextDescMap::hashKey), 0, 0, HASH_UNIQUE);
-
- VOID(pthread_mutex_init(&iconvMapHashMutex,MY_MUTEX_INIT_FAST));
- hash_init(&iconvMapHash, &my_charset_bin, 10, offsetof(IconvMap, hashKey), sizeof(IconvMap::hashKey), 0, 0, HASH_UNIQUE);
-
- init_alloc_root(&textDescMapMemroot, 2048, 0);
- init_alloc_root(&iconvMapMemroot, 256, 0);
-
- initMyconv();
-
- DBUG_RETURN(0);
-}
-
-/**
- Cleanup the static structures used by this module.
-
- This must only be called once per plugin instantiation and only if
- initCharsetSupport() was successful.
-*/
-void doneCharsetSupport()
-{
- cleanupMyconv();
-
- free_root(&textDescMapMemroot, 0);
- free_root(&iconvMapMemroot, 0);
-
- pthread_mutex_destroy(&textDescMapHashMutex);
- hash_free(&textDescMapHash);
- pthread_mutex_destroy(&iconvMapHashMutex);
- hash_free(&iconvMapHash);
- free_aligned(QlgCvtTextDescToDesc_sym);
-}
-
-
-/**
- Convert a text description from one type to another.
-
- This function is just a wrapper for the IBM i QlgTextDescToDesc function plus
- some overrides for conversions that the API does not handle correctly and
- support for caching the computed conversion.
-
- @param inType The type of descriptor pointed to by "in".
- @param outType The type of descriptor requested for "out".
- @param in The descriptor to be convereted.
- @param[out] out The equivalent descriptor
- @param hashKey The hash key to be used for caching the conversion result.
-
- @return 0 if successful. Failure otherwise
-*/
-static int32 getNewTextDesc(const int32 inType,
- const int32 outType,
- const char* in,
- char* out,
- const TextDescMap::HashKey* hashKey)
-{
- DBUG_ENTER("db2i_charsetSupport::getNewTextDesc");
- const arg_type_t signature[] = { ARG_INT32, ARG_INT32, ARG_MEMPTR, ARG_INT32, ARG_MEMPTR, ARG_INT32, ARG_INT32, ARG_END };
- struct ArgList
- {
- ILEarglist_base base;
- int32 CRDIInType;
- int32 CRDIOutType;
- ILEpointer CRDIDesc;
- int32 CRDIDescSize;
- ILEpointer CRDODesc;
- int32 CRDODescSize;
- int32 CTDCCSID;
- } *arguments;
-
- if ((inType == Qlg_TypeIANA) && (outType == Qlg_TypeAix41))
- {
- // Override non-standard charsets
- if (unlikely(strcmp("IBM1381", in) == 0))
- {
- strcpy(out, "IBM-1381");
- DBUG_RETURN(0);
- }
- }
- else if ((inType == Qlg_TypeAS400CCSID) && (outType == Qlg_TypeAix41))
- {
- // Override non-standard charsets
- if (strcmp("1148", in) == 0)
- {
- strcpy(out, "IBM-1148");
- DBUG_RETURN(0);
- }
- else if (unlikely(strcmp("1153", in) == 0))
- {
- strcpy(out, "IBM-1153");
- DBUG_RETURN(0);
- }
- }
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- arguments->CRDIInType = inType;
- arguments->CRDIOutType = outType;
- arguments->CRDIDesc.s.addr = (address64_t) in;
- arguments->CRDIDescSize = Qlg_MaxDescSize;
- arguments->CRDODesc.s.addr = (address64_t) out;
- arguments->CRDODescSize = Qlg_MaxDescSize;
- arguments->CTDCCSID = 819;
- _ILECALL(QlgCvtTextDescToDesc_sym,
- &arguments->base,
- signature,
- RESULT_INT32);
- if (unlikely(arguments->base.result.s_int32.r_int32 < 0))
- {
- if (arguments->base.result.s_int32.r_int32 == Qlg_InDescriptorNotFound)
- {
- DBUG_RETURN(DB2I_ERR_UNSUPP_CHARSET);
- }
- else
- {
- getErrTxt(DB2I_ERR_ILECALL,"QlgCvtTextDescToDesc",arguments->base.result.s_int32.r_int32);
- DBUG_RETURN(DB2I_ERR_ILECALL);
- }
- }
-
- // Store the conversion information into a cache entry
- TextDescMap* mapping = (TextDescMap*)alloc_root(&textDescMapMemroot, sizeof(TextDescMap));
- if (unlikely(!mapping))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- memcpy(&(mapping->hashKey), hashKey, sizeof(hashKey));
- strcpy(mapping->outDesc, out);
- pthread_mutex_lock(&textDescMapHashMutex);
- my_hash_insert(&textDescMapHash, (const uchar*)mapping);
- pthread_mutex_unlock(&textDescMapHashMutex);
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Convert a text description from one type to another.
-
- This function takes a text description in one representation and converts
- it into another representation. Although the OS provides some facilities for
- doing this, the support is not complete, nor does MySQL always use standard
- identifiers. Therefore, there are a lot of hardcoded overrides required.
- There is probably some room for optimization here, but this should not be
- called frequently under most circumstances.
-
- @param inType The type of descriptor pointed to by "in".
- @param outType The type of descriptor requested for "out".
- @param in The descriptor to be convereted.
- @param[out] out The equivalent descriptor
-
- @return 0 if successful. Failure otherwise
-*/
-static int32 convertTextDesc(const int32 inType, const int32 outType, const char* inDesc, char* outDesc)
-{
- DBUG_ENTER("db2i_charsetSupport::convertTextDesc");
- const char* inDescOverride;
-
- if (inType == Qlg_TypeIANA)
- {
- // Override non-standard charsets
- if (strcmp("big5", inDesc) == 0)
- inDescOverride = "Big5";
- else if (strcmp("cp932", inDesc) == 0)
- inDescOverride = "IBM943";
- else if (strcmp("euckr", inDesc) == 0)
- inDescOverride = "EUC-KR";
- else if (strcmp("gb2312", inDesc) == 0)
- inDescOverride = "IBM1381";
- else if (strcmp("gbk", inDesc) == 0)
- inDescOverride = "IBM1386";
- else if (strcmp("sjis", inDesc) == 0)
- inDescOverride = "Shift_JIS";
- else if (strcmp("ujis", inDesc) == 0)
- inDescOverride = "EUC-JP";
- else
- inDescOverride = inDesc;
-
- // Hardcode non-standard charsets
- if (outType == Qlg_TypeAix41)
- {
- if (strcmp("Big5", inDescOverride) == 0)
- {
- strcpy(outDesc,"big5");
- DBUG_RETURN(0);
- }
- else if (strcmp("IBM1386", inDescOverride) == 0)
- {
- strcpy(outDesc,"GBK");
- DBUG_RETURN(0);
- }
- else if (strcmp("Shift_JIS", inDescOverride) == 0 ||
- strcmp("IBM943", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-943");
- DBUG_RETURN(0);
- }
- else if (strcmp("tis620", inDescOverride) == 0)
- {
- strcpy(outDesc,"TIS-620");
- DBUG_RETURN(0);
- }
- else if (strcmp("ucs2", inDescOverride) == 0)
- {
- strcpy(outDesc,"UCS-2");
- DBUG_RETURN(0);
- }
- else if (strcmp("cp1250", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-1250");
- DBUG_RETURN(0);
- }
- else if (strcmp("cp1251", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-1251");
- DBUG_RETURN(0);
- }
- else if (strcmp("cp1256", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-1256");
- DBUG_RETURN(0);
- }
- else if (strcmp("macce", inDescOverride) == 0)
- {
- strcpy(outDesc,"IBM-1282");
- DBUG_RETURN(0);
- }
- }
- else if (outType == Qlg_TypeAS400CCSID)
- {
- // See if we can fast path the convert
- for (int loopCnt = 0; loopCnt < MAX_IANASTRING; ++loopCnt)
- {
- if (strcmp((char*)ianaStringType[loopCnt],inDescOverride) == 0)
- {
- strcpy(outDesc,ccsidType[loopCnt]);
- DBUG_RETURN(0);
- }
- }
- }
- }
- else
- inDescOverride = inDesc;
-
- // We call getNewTextDesc for all other conversions and cache the result.
- TextDescMap *mapping;
- TextDescMap::HashKey hashKey;
- hashKey.inType= inType;
- hashKey.outType= outType;
- uint32 len = strlen(inDescOverride);
- memcpy(hashKey.inDesc, inDescOverride, len);
- memset(hashKey.inDesc+len, 0, sizeof(hashKey.inDesc) - len);
-
- if (!(mapping=(TextDescMap *) hash_search(&textDescMapHash,
- (const uchar*)&hashKey,
- sizeof(hashKey))))
- {
- DBUG_RETURN(getNewTextDesc(inType, outType, inDescOverride, outDesc, &hashKey));
- }
- else
- {
- strcpy(outDesc, mapping->outDesc);
- }
- DBUG_RETURN(0);
-}
-
-
-/**
- Convert an IANA character set name into a DB2 for i CCSID value.
-
- @param parmIANADesc An IANA character set name
- @param[out] db2Ccsid The equivalent CCSID value
-
- @return 0 if successful. Failure otherwise
-*/
-int32 convertIANAToDb2Ccsid(const char* parmIANADesc, uint16* db2Ccsid)
-{
- int32 rc;
- uint16 aixCcsid;
- char aixCcsidString[Qlg_MaxDescSize];
- int aixEncodingScheme;
- int db2EncodingScheme;
- rc = convertTextDesc(Qlg_TypeIANA, Qlg_TypeAS400CCSID, parmIANADesc, aixCcsidString);
- if (unlikely(rc))
- {
- if (rc == DB2I_ERR_UNSUPP_CHARSET)
- getErrTxt(DB2I_ERR_UNSUPP_CHARSET, parmIANADesc);
-
- return rc;
- }
- aixCcsid = atoi(aixCcsidString);
- rc = getEncodingScheme(aixCcsid, aixEncodingScheme);
- if (rc != 0)
- return rc;
- switch(aixEncodingScheme) { // Select on encoding scheme
- case 0x1100: // EDCDIC SBCS
- case 0x2100: // ASCII SBCS
- case 0x4100: // AIX SBCS
- case 0x4105: // MS Windows
- case 0x5100: // ISO 7 bit ASCII
- db2EncodingScheme = 0x1100;
- break;
- case 0x1200: // EDCDIC DBCS
- case 0x2200: // ASCII DBCS
- db2EncodingScheme = 0x1200;
- break;
- case 0x1301: // EDCDIC Mixed
- case 0x2300: // ASCII Mixed
- case 0x4403: // EUC (ISO 2022)
- db2EncodingScheme = 0x1301;
- break;
- case 0x7200: // UCS2
- db2EncodingScheme = 0x7200;
- break;
- case 0x7807: // UTF-8
- db2EncodingScheme = 0x7807;
- break;
- case 0x7500: // UTF-32
- db2EncodingScheme = 0x7500;
- break;
- default: // Unknown
- {
- getErrTxt(DB2I_ERR_UNKNOWN_ENCODING,aixEncodingScheme);
- return DB2I_ERR_UNKNOWN_ENCODING;
- }
- break;
- }
- if (aixEncodingScheme == db2EncodingScheme)
- {
- *db2Ccsid = aixCcsid;
- }
- else
- {
- rc = getAssociatedCCSID(aixCcsid, db2EncodingScheme, db2Ccsid); // EDCDIC SBCS
- if (rc != 0)
- return rc;
- }
-
- return 0;
-}
-
-
-/**
- Obtain the encoding scheme of a CCSID.
-
- @param inCcsid An IBM i CCSID
- @param[out] outEncodingScheme The associated encoding scheme
-
- @return 0 if successful. Failure otherwise
-*/
-int32 getEncodingScheme(const uint16 inCcsid, int32& outEncodingScheme)
-{
- DBUG_ENTER("db2i_charsetSupport::getEncodingScheme");
-
- static bool ptrInited = FALSE;
- static char ptrSpace[sizeof(ILEpointer) + 15];
- static ILEpointer* ptrToPtr = (ILEpointer*)roundToQuadWordBdy(ptrSpace);
- int rc;
-
- if (!ptrInited)
- {
- rc = _RSLOBJ2(ptrToPtr, RSLOBJ_TS_PGM, "QTQGESP", "QSYS");
-
- if (rc)
- {
- getErrTxt(DB2I_ERR_RESOLVE_OBJ,"QTQGESP","QSYS","*PGM",errno);
- DBUG_RETURN(DB2I_ERR_RESOLVE_OBJ);
- }
- ptrInited = TRUE;
- }
-
- DBUG_ASSERT(inCcsid != 0);
-
- int GESPCCSID = inCcsid;
- int GESPLen = 32;
- int GESPNbrVal = 0;
- int32 GESPES;
- int GESPCSCPL[32];
- int GESPFB[3];
- void* ILEArgv[7];
- ILEArgv[0] = &GESPCCSID;
- ILEArgv[1] = &GESPLen;
- ILEArgv[2] = &GESPNbrVal;
- ILEArgv[3] = &GESPES;
- ILEArgv[4] = &GESPCSCPL;
- ILEArgv[5] = &GESPFB;
- ILEArgv[6] = NULL;
-
- rc = _PGMCALL(ptrToPtr, (void**)&ILEArgv, 0);
-
- if (rc)
- {
- getErrTxt(DB2I_ERR_PGMCALL,"QTQGESP","QSYS",rc);
- DBUG_RETURN(DB2I_ERR_PGMCALL);
- }
- if (GESPFB[0] != 0 ||
- GESPFB[1] != 0 ||
- GESPFB[2] != 0)
- {
- getErrTxt(DB2I_ERR_QTQGESP,GESPFB[0],GESPFB[1],GESPFB[2]);
- DBUG_RETURN(DB2I_ERR_QTQGESP);
- }
- outEncodingScheme = GESPES;
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Get the best fit equivalent CCSID. (Wrapper for QTQGRDC API)
-
- @param inCcsid An IBM i CCSID
- @param inEncodingScheme The encoding scheme
- @param[out] outCcsid The equivalent CCSID
-
- @return 0 if successful. Failure otherwise
-*/
-int32 getAssociatedCCSID(const uint16 inCcsid, const int inEncodingScheme, uint16* outCcsid)
-{
- DBUG_ENTER("db2i_charsetSupport::getAssociatedCCSID");
- static bool ptrInited = FALSE;
- static char ptrSpace[sizeof(ILEpointer) + 15];
- static ILEpointer* ptrToPtr = (ILEpointer*)roundToQuadWordBdy(ptrSpace);
- int rc;
-
- // Override non-standard charsets
- if ((inCcsid == 923) && (inEncodingScheme == 0x1100))
- {
- *outCcsid = 1148;
- DBUG_RETURN(0);
- }
- else if ((inCcsid == 1250) && (inEncodingScheme == 0x1100))
- {
- *outCcsid = 1153;
- DBUG_RETURN(0);
- }
-
- if (!ptrInited)
- {
- rc = _RSLOBJ2(ptrToPtr, RSLOBJ_TS_PGM, "QTQGRDC", "QSYS");
-
- if (rc)
- {
- getErrTxt(DB2I_ERR_RESOLVE_OBJ,"QTQGRDC","QSYS","*PGM",errno);
- DBUG_RETURN(DB2I_ERR_RESOLVE_OBJ);
- }
- ptrInited = TRUE;
- }
-
- int GRDCCCSID = inCcsid;
- int GRDCES = inEncodingScheme;
- int GRDCSel = 0;
- int GRDCAssCCSID;
- int GRDCFB[3];
- void* ILEArgv[7];
- ILEArgv[0] = &GRDCCCSID;
- ILEArgv[1] = &GRDCES;
- ILEArgv[2] = &GRDCSel;
- ILEArgv[3] = &GRDCAssCCSID;
- ILEArgv[4] = &GRDCFB;
- ILEArgv[5] = NULL;
-
- rc = _PGMCALL(ptrToPtr, (void**)&ILEArgv, 0);
-
- if (rc)
- {
- getErrTxt(DB2I_ERR_PGMCALL,"QTQGRDC","QSYS",rc);
- DBUG_RETURN(DB2I_ERR_PGMCALL);
- }
- if (GRDCFB[0] != 0 ||
- GRDCFB[1] != 0 ||
- GRDCFB[2] != 0)
- {
- getErrTxt(DB2I_ERR_QTQGRDC,GRDCFB[0],GRDCFB[1],GRDCFB[2]);
- DBUG_RETURN(DB2I_ERR_QTQGRDC);
- }
-
- *outCcsid = GRDCAssCCSID;
-
- DBUG_RETURN(0);
-}
-
-/**
- Open an iconv conversion between a MySQL charset and the respective IBM i CCSID
-
- @param direction The direction of the conversion
- @param mysqlCSName Name of the MySQL character set
- @param db2CCSID The IBM i CCSID
- @param hashKey The key to use for inserting the opened conversion into the cache
- @param[out] newConversion The iconv descriptor
-
- @return 0 if successful. Failure otherwise
-*/
-static int32 openNewConversion(enum_conversionDirection direction,
- const char* mysqlCSName,
- uint16 db2CCSID,
- IconvMap::HashKey* hashKey,
- iconv_t& newConversion)
-{
- DBUG_ENTER("db2i_charsetSupport::openNewConversion");
-
- char mysqlAix41Desc[Qlg_MaxDescSize];
- char db2Aix41Desc[Qlg_MaxDescSize];
- char db2CcsidString[6] = "";
- int32 rc;
-
- /*
- First we have to convert the MySQL IANA-like name and the DB2 CCSID into
- there equivalent iconv descriptions.
- */
- rc = convertTextDesc(Qlg_TypeIANA, Qlg_TypeAix41, mysqlCSName, mysqlAix41Desc);
- if (unlikely(rc))
- {
- if (rc == DB2I_ERR_UNSUPP_CHARSET)
- getErrTxt(DB2I_ERR_UNSUPP_CHARSET, mysqlCSName);
-
- DBUG_RETURN(rc);
- }
- CHARSET_INFO *cs= &my_charset_bin;
- (uint)(cs->cset->long10_to_str)(cs,db2CcsidString,sizeof(db2CcsidString), 10, db2CCSID);
- rc = convertTextDesc(Qlg_TypeAS400CCSID, Qlg_TypeAix41, db2CcsidString, db2Aix41Desc);
- if (unlikely(rc))
- {
- if (rc == DB2I_ERR_UNSUPP_CHARSET)
- getErrTxt(DB2I_ERR_UNSUPP_CHARSET, mysqlCSName);
-
- DBUG_RETURN(rc);
- }
-
- /* Call iconv to open the conversion. */
- if (direction == toDB2)
- {
- newConversion = iconv_open(db2Aix41Desc, mysqlAix41Desc);
- }
- else
- {
- newConversion = iconv_open(mysqlAix41Desc, db2Aix41Desc);
- }
-
- if (unlikely(newConversion == (iconv_t) -1))
- {
- getErrTxt(DB2I_ERR_UNSUPP_CHARSET, mysqlCSName);
- DBUG_RETURN(DB2I_ERR_UNSUPP_CHARSET);
- }
-
- /* Insert the new conversion into the cache. */
- IconvMap* mapping = (IconvMap*)alloc_root(&iconvMapMemroot, sizeof(IconvMap));
- if (!mapping)
- {
- my_error(ER_OUTOFMEMORY, MYF(0), sizeof(IconvMap));
- DBUG_RETURN( HA_ERR_OUT_OF_MEM);
- }
- memcpy(&(mapping->hashKey), hashKey, sizeof(mapping->hashKey));
- mapping->iconvDesc = newConversion;
- pthread_mutex_lock(&iconvMapHashMutex);
- my_hash_insert(&iconvMapHash, (const uchar*)mapping);
- pthread_mutex_unlock(&iconvMapHashMutex);
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Open an iconv conversion between a MySQL charset and the respective IBM i CCSID
-
- @param direction The direction of the conversion
- @param cs The MySQL character set
- @param db2CCSID The IBM i CCSID
- @param[out] newConversion The iconv descriptor
-
- @return 0 if successful. Failure otherwise
-*/
-int32 getConversion(enum_conversionDirection direction, const CHARSET_INFO* cs, uint16 db2CCSID, iconv_t& conversion)
-{
- DBUG_ENTER("db2i_charsetSupport::getConversion");
-
- int32 rc;
-
- /* Build the hash key */
- IconvMap::HashKey hashKey;
- hashKey.direction= direction;
- hashKey.myCharset= cs;
- hashKey.db2CCSID= db2CCSID;
-
- /* Look for the conversion in the cache and add it if it is not there. */
- IconvMap *mapping;
- if (!(mapping= (IconvMap *) hash_search(&iconvMapHash,
- (const uchar*)&hashKey,
- sizeof(hashKey))))
- {
- DBUG_PRINT("getConversion", ("Hash miss for direction=%d, cs=%s, ccsid=%d", direction, cs->name, db2CCSID));
- rc= openNewConversion(direction, cs->csname, db2CCSID, &hashKey, conversion);
- if (rc)
- DBUG_RETURN(rc);
- }
- else
- {
- conversion= mapping->iconvDesc;
- }
-
- DBUG_RETURN(0);
-}
-
-/**
- Fast-path conversion from ASCII to EBCDIC for use in converting
- identifiers to be sent to the QMY APIs.
-
- @param input ASCII data
- @param[out] ouput EBCDIC data
- @param ilen Size of input buffer and output buffer
-*/
-int convToEbcdic(const char* input, char* output, size_t ilen)
-{
- static bool inited = FALSE;
- static iconv_t ic;
-
- if (ilen == 0)
- return 0;
-
- if (!inited)
- {
- ic = iconv_open( "IBM-037", "ISO8859-1" );
- inited = TRUE;
- }
- size_t substitutedChars;
- size_t olen = ilen;
- if (iconv( ic, (char**)&input, &ilen, &output, &olen, &substitutedChars ) == -1)
- return errno;
-
- return 0;
-}
-
-
-/**
- Fast-path conversion from EBCDIC to ASCII for use in converting
- data received from the QMY APIs.
-
- @param input EBCDIC data
- @param[out] ouput ASCII data
- @param ilen Size of input buffer and output buffer
-*/
-int convFromEbcdic(const char* input, char* output, size_t ilen)
-{
- static bool inited = FALSE;
- static iconv_t ic;
-
- if (ilen == 0)
- return 0;
-
- if (!inited)
- {
- ic = iconv_open("ISO8859-1", "IBM-037");
- inited = TRUE;
- }
-
- size_t substitutedChars;
- size_t olen = ilen;
- if (iconv( ic, (char**)&input, &ilen, &output, &olen, &substitutedChars) == -1)
- return errno;
-
- return 0;
-}
diff --git a/storage/ibmdb2i/db2i_charsetSupport.h b/storage/ibmdb2i/db2i_charsetSupport.h
deleted file mode 100644
index 77051e1e0db..00000000000
--- a/storage/ibmdb2i/db2i_charsetSupport.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#ifndef DB2I_CHARSETSUPPORT_H
-#define DB2I_CHARSETSUPPORT_H
-
-#include "db2i_global.h"
-#include "mysql_priv.h"
-#include <mysql/plugin.h>
-#include "db2i_iconv.h"
-
-/**
- @enum enum_conversionDirection
-
- Conversion directions for getConversion()
-*/
-enum enum_conversionDirection
-{
- toMySQL,
- toDB2
-};
-
-int initCharsetSupport();
-void doneCharsetSupport();
-int32 convertIANAToDb2Ccsid(const char* parmIANADesc, uint16* db2Ccsid);
-int32 getEncodingScheme(const uint16 inCcsid, int32& outEncodingScheme);
-int32 getAssociatedCCSID(const uint16 inCcsid, const int inEncodingScheme, uint16* outCcsid);
-int convToEbcdic(const char* input, char* output, size_t ilen);
-int convFromEbcdic(const char* input, char* output, size_t ilen);
-int32 getConversion(enum_conversionDirection direction, const CHARSET_INFO* cs, uint16 db2CCSID, iconv_t& conversion);
-
-#endif
diff --git a/storage/ibmdb2i/db2i_collationSupport.cc b/storage/ibmdb2i/db2i_collationSupport.cc
deleted file mode 100644
index 65a17fd2452..00000000000
--- a/storage/ibmdb2i/db2i_collationSupport.cc
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#include "db2i_collationSupport.h"
-#include "db2i_errors.h"
-
-
-/*
- The following arrays define a mapping between MySQL collation names and
- corresponding IBM i sort sequences. The mapping is a 1-to-1 correlation
- between corresponding array slots but is incomplete without case-sensitivity
- markers dynamically added to the mySqlSortSequence names.
-*/
-#define MAX_COLLATION 87
-static const char* mySQLCollation[MAX_COLLATION] =
-{
- {"ascii_general"},
- {"ascii"},
- {"big5_chinese"},
- {"big5"},
- {"cp1250_croatian"},
- {"cp1250_general"},
- {"cp1250_polish"},
- {"cp1250"},
- {"cp1251_bulgarian"},
- {"cp1251_general"},
- {"cp1251"},
- {"cp1256_general"},
- {"cp1256"},
- {"cp850_general"},
- {"cp850"},
- {"cp852_general"},
- {"cp852"},
- {"cp932_japanese"},
- {"cp932"},
- {"euckr_korean"},
- {"euckr"},
- {"gb2312_chinese"},
- {"gb2312"},
- {"gbk_chinese"},
- {"gbk"},
- {"greek_general"},
- {"greek"},
- {"hebrew_general"},
- {"hebrew"},
- {"latin1_danish"},
- {"latin1_general"},
- {"latin1_german1"},
- {"latin1_spanish"},
- {"latin1_swedish"},
- {"latin1"},
- {"latin2_croatian"},
- {"latin2_general"},
- {"latin2_hungarian"},
- {"latin2"},
- {"latin5_turkish"},
- {"latin5"},
- {"macce_general"},
- {"macce"},
- {"sjis_japanese"},
- {"sjis"},
- {"tis620_thai"},
- {"tis620"},
- {"ucs2_czech"},
- {"ucs2_danish"},
- {"ucs2_esperanto"},
- {"ucs2_estonian"},
- {"ucs2_general"},
- {"ucs2_hungarian"},
- {"ucs2_icelandic"},
- {"ucs2_latvian"},
- {"ucs2_lithuanian"},
- {"ucs2_persian"},
- {"ucs2_polish"},
- {"ucs2_romanian"},
- {"ucs2_slovak"},
- {"ucs2_slovenian"},
- {"ucs2_spanish"},
- {"ucs2_swedish"},
- {"ucs2_turkish"},
- {"ucs2_unicode"},
- {"ucs2"},
- {"ujis_japanese"},
- {"ujis"},
- {"utf8_czech"},
- {"utf8_danish"},
- {"utf8_esperanto"},
- {"utf8_estonian"},
- {"utf8_general"},
- {"utf8_hungarian"},
- {"utf8_icelandic"},
- {"utf8_latvian"},
- {"utf8_lithuanian"},
- {"utf8_persian"},
- {"utf8_polish"},
- {"utf8_romanian"},
- {"utf8_slovak"},
- {"utf8_slovenian"},
- {"utf8_spanish"},
- {"utf8_swedish"},
- {"utf8_turkish"},
- {"utf8_unicode"},
- {"utf8"}
-};
-
-
-static const char* mySqlSortSequence[MAX_COLLATION] =
-{
- {"QALA101F4"},
- {"QBLA101F4"},
- {"QACHT04B0"},
- {"QBCHT04B0"},
- {"QALA20481"},
- {"QCLA20481"},
- {"QDLA20481"},
- {"QELA20481"},
- {"QACYR0401"},
- {"QBCYR0401"},
- {"QCCYR0401"},
- {"QAARA01A4"},
- {"QBARA01A4"},
- {"QCLA101F4"},
- {"QDLA101F4"},
- {"QALA20366"},
- {"QBLA20366"},
- {"QAJPN04B0"},
- {"QBJPN04B0"},
- {"QAKOR04B0"},
- {"QBKOR04B0"},
- {"QACHS04B0"},
- {"QBCHS04B0"},
- {"QCCHS04B0"},
- {"QDCHS04B0"},
- {"QAELL036B"},
- {"QBELL036B"},
- {"QAHEB01A8"},
- {"QBHEB01A8"},
- {"QALA1047C"},
- {"QBLA1047C"},
- {"QCLA1047C"},
- {"QDLA1047C"},
- {"QELA1047C"},
- {"QFLA1047C"},
- {"QCLA20366"},
- {"QELA20366"},
- {"QFLA20366"},
- {"QGLA20366"},
- {"QATRK0402"},
- {"QBTRK0402"},
- {"QHLA20366"},
- {"QILA20366"},
- {"QCJPN04B0"},
- {"QDJPN04B0"},
- {"QATHA0346"},
- {"QBTHA0346"},
- {"ACS_CZ"},
- {"ADA_DK"},
- {"AEO"},
- {"AET"},
- {"QAUCS04B0"},
- {"AHU"},
- {"AIS"},
- {"ALV"},
- {"ALT"},
- {"AFA"},
- {"APL"},
- {"ARO"},
- {"ASK"},
- {"ASL"},
- {"AES"},
- {"ASW"},
- {"ATR"},
- {"AEN"},
- {"*HEX"},
- {"QEJPN04B0"},
- {"QFJPN04B0"},
- {"ACS_CZ"},
- {"ADA_DK"},
- {"AEO"},
- {"AET"},
- {"QAUCS04B0"},
- {"AHU"},
- {"AIS"},
- {"ALV"},
- {"ALT"},
- {"AFA"},
- {"APL"},
- {"ARO"},
- {"ASK"},
- {"ASL"},
- {"AES"},
- {"ASW"},
- {"ATR"},
- {"AEN"},
- {"*HEX"}
-};
-
-
-/**
- Get the IBM i sort sequence that corresponds to the given MySQL collation.
-
- @param fieldCharSet The collated character set
- @param[out] rtnSortSequence The corresponding sort sequence
-
- @return 0 if successful. Failure otherwise
-*/
-static int32 getAssociatedSortSequence(const CHARSET_INFO *fieldCharSet, const char** rtnSortSequence)
-{
- DBUG_ENTER("ha_ibmdb2i::getAssociatedSortSequence");
-
- if (strcmp(fieldCharSet->csname,"binary") != 0)
- {
- int collationSearchLen = strlen(fieldCharSet->name);
- if (fieldCharSet->state & MY_CS_BINSORT)
- collationSearchLen -= 4;
- else
- collationSearchLen -= 3;
-
- uint16 loopCnt = 0;
- for (loopCnt; loopCnt < MAX_COLLATION; ++loopCnt)
- {
- if ((strlen(mySQLCollation[loopCnt]) == collationSearchLen) &&
- (strncmp((char*)mySQLCollation[loopCnt], fieldCharSet->name, collationSearchLen) == 0))
- break;
- }
- if (loopCnt == MAX_COLLATION) // Did not find associated sort sequence
- {
- getErrTxt(DB2I_ERR_SRTSEQ);
- DBUG_RETURN(DB2I_ERR_SRTSEQ);
- }
- *rtnSortSequence = mySqlSortSequence[loopCnt];
- }
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Update sort sequence information for a key.
-
- 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
- and (with the exception of the charset parm) preserve the values for the
- parms across invocations, until a particular key has been evaluated. Once
- the last field in the key has been evaluated, the fileSortSequence and
- fileSortSequenceLibrary parms will contain the correct information for
- creating the corresponding DB2 key.
-
- @param charset The character set under consideration
- @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
- that corresponds
-
- @return 0 if successful. Failure otherwise
-*/
-int32 updateAssociatedSortSequence(const CHARSET_INFO* charset,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary)
-{
- DBUG_ENTER("ha_ibmdb2i::updateAssociatedSortSequence");
- DBUG_ASSERT(charset);
- if (strcmp(charset->csname,"binary") != 0)
- {
- char newSortSequence[11] = "";
- char newSortSequenceType = ' ';
- const char* foundSortSequence;
- int rc = getAssociatedSortSequence(charset, &foundSortSequence);
- if (rc) DBUG_RETURN (rc);
- switch(foundSortSequence[0])
- {
- case '*': // Binary
- strcat(newSortSequence,foundSortSequence);
- newSortSequenceType = 'B';
- break;
- case 'Q': // Non-ICU sort sequence
- strcat(newSortSequence,foundSortSequence);
- if ((charset->state & MY_CS_BINSORT) != 0)
- {
- strcat(newSortSequence,"U");
- }
- else if ((charset->state & MY_CS_CSSORT) != 0)
- {
- strcat(newSortSequence,"U");
- }
- else
- {
- strcat(newSortSequence,"S");
- }
- newSortSequenceType = 'N';
- break;
- default: // ICU sort sequence
- {
- if ((charset->state & MY_CS_CSSORT) == 0)
- {
- if (osVersion.v >= 6)
- strcat(newSortSequence,"I34"); // ICU 3.4
- else
- strcat(newSortSequence,"I26"); // ICU 2.6.1
- }
- strcat(newSortSequence,foundSortSequence);
- newSortSequenceType = 'I';
- }
- break;
- }
- if (*fileSortSequenceType == ' ') // If no sort sequence has been set yet
- {
- // Set associated sort sequence
- strcpy(fileSortSequence,newSortSequence);
- strcpy(fileSortSequenceLibrary,"QSYS");
- *fileSortSequenceType = newSortSequenceType;
- }
- else if (strcmp(fileSortSequence,newSortSequence) != 0)
- {
- // Only one sort sequence/collation is supported for each DB2 index.
- getErrTxt(DB2I_ERR_MIXED_COLLATIONS);
- DBUG_RETURN(DB2I_ERR_MIXED_COLLATIONS);
- }
- }
-
- DBUG_RETURN(0);
-}
diff --git a/storage/ibmdb2i/db2i_collationSupport.h b/storage/ibmdb2i/db2i_collationSupport.h
deleted file mode 100644
index b2ce09de1ea..00000000000
--- a/storage/ibmdb2i/db2i_collationSupport.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#ifndef DB2I_COLLATIONSUPPORT_H
-#define DB2I_COLLATIONSUPPORT_H
-
-#include "db2i_global.h"
-#include "mysql_priv.h"
-
-int32 updateAssociatedSortSequence(const CHARSET_INFO* charset,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary);
-
-#endif
diff --git a/storage/ibmdb2i/db2i_constraints.cc b/storage/ibmdb2i/db2i_constraints.cc
deleted file mode 100644
index 1fde0dd3d14..00000000000
--- a/storage/ibmdb2i/db2i_constraints.cc
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-
-#include "ha_ibmdb2i.h"
-#include "db2i_safeString.h"
-
-// This function is called when building the CREATE TABLE information for
-// foreign key constraints. It converts a constraint, table, schema, or
-// field name from EBCDIC to ASCII. If the DB2 name is quoted, it removes
-// those quotes. It then adds the appropriate quotes for a MySQL identifier.
-
-static void convNameForCreateInfo(THD *thd, SafeString& info, char* fromName, int len)
-{
- int quote;
- char cquote; // Quote character
- char convName[MAX_DB2_FILENAME_LENGTH]; // Converted name
-
- memset(convName, 0, sizeof(convName));
- convFromEbcdic(fromName, convName, len);
- quote = get_quote_char_for_identifier(thd, convName, len);
- cquote = (char) quote;
- if (quote != EOF)
- info.strcat(cquote);
- if (convName[0] == '"') // If DB2 name was quoted, remove quotes
- {
- if (strstr(convName, "\"\""))
- stripExtraQuotes(convName+1, len-1);
- info.strncat((char*)(convName+1), len-2);
- }
- else // DB2 name was not quoted
- info.strncat(convName, len);
- if (quote != EOF)
- info.strcat(cquote);
-}
-
-/**
- Evaluate the parse tree to build foreign key constraint clauses
-
- @parm lex The parse tree
- @parm appendHere The DB2 string to receive the constraint clauses
- @parm path The path to the table under consideration
- @parm fields Pointer to the table's list of field pointers
- @parm[in, out] fileSortSequenceType The sort sequence type associated with the table
- @parm[in, out] fileSortSequence The sort sequence associated with the table
- @parm[in, out] fileSortSequenceLibrary The sort sequence library associated with the table
-
- @return 0 if successful; HA_ERR_CANNOT_ADD_FOREIGN otherwise
-*/
-int ha_ibmdb2i::buildDB2ConstraintString(LEX* lex,
- String& appendHere,
- const char* path,
- Field** fields,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary)
-{
- List_iterator<Key> keyIter(lex->alter_info.key_list);
- char colName[MAX_DB2_COLNAME_LENGTH+1];
-
- Key* curKey;
-
- while (curKey = keyIter++)
- {
- if (curKey->type == Key::FOREIGN_KEY)
- {
- appendHere.append(STRING_WITH_LEN(", "));
-
- Foreign_key* fk = (Foreign_key*)curKey;
-
- char db2LibName[MAX_DB2_SCHEMANAME_LENGTH+1];
- if (fk->name)
- {
- char db2FKName[MAX_DB2_FILENAME_LENGTH+1];
- appendHere.append(STRING_WITH_LEN("CONSTRAINT "));
- if (fk->ref_table->db.str)
- {
- convertMySQLNameToDB2Name(fk->ref_table->db.str, db2LibName, sizeof(db2LibName));
- }
- else
- {
- db2i_table::getDB2LibNameFromPath(path, db2LibName);
- }
- if (lower_case_table_names == 1)
- my_casedn_str(files_charset_info, db2LibName);
- appendHere.append(db2LibName);
-
- appendHere.append('.');
-
- convertMySQLNameToDB2Name(fk->name, db2FKName, sizeof(db2FKName));
- appendHere.append(db2FKName);
- }
-
- appendHere.append(STRING_WITH_LEN(" FOREIGN KEY ("));
-
- bool firstTime = true;
-
- List_iterator<Key_part_spec> column(fk->columns);
- Key_part_spec* curColumn;
-
- while (curColumn = column++)
- {
- if (!firstTime)
- {
- appendHere.append(',');
- }
- firstTime = false;
-
- convertMySQLNameToDB2Name(curColumn->field_name, colName, sizeof(colName));
- appendHere.append(colName);
-
- // DB2 requires that the sort sequence on the child table match the parent table's
- // sort sequence. We ensure that happens by updating the sort sequence according
- // to the constrained fields.
- Field** field = fields;
- do
- {
- if (strcmp((*field)->field_name, curColumn->field_name) == 0)
- {
- int rc = updateAssociatedSortSequence((*field)->charset(),
- fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
-
- if (unlikely(rc)) return rc;
- }
- } while (*(++field));
- }
-
- firstTime = true;
-
- appendHere.append(STRING_WITH_LEN(") REFERENCES "));
-
- if (fk->ref_table->db.str)
- {
- convertMySQLNameToDB2Name(fk->ref_table->db.str, db2LibName, sizeof(db2LibName));
- }
- else
- {
- db2i_table::getDB2LibNameFromPath(path, db2LibName);
- }
- if (lower_case_table_names == 1)
- my_casedn_str(files_charset_info, db2LibName);
- appendHere.append(db2LibName);
- appendHere.append('.');
-
- char db2FileName[MAX_DB2_FILENAME_LENGTH+1];
- convertMySQLNameToDB2Name(fk->ref_table->table.str, db2FileName, sizeof(db2FileName));
- if (lower_case_table_names)
- my_casedn_str(files_charset_info, db2FileName);
- appendHere.append(db2FileName);
-
-
- if (!fk->ref_columns.is_empty())
- {
- List_iterator<Key_part_spec> ref(fk->ref_columns);
- Key_part_spec* curRef;
- appendHere.append(STRING_WITH_LEN(" ("));
-
-
- while (curRef = ref++)
- {
- if (!firstTime)
- {
- appendHere.append(',');
- }
- firstTime = false;
-
- convertMySQLNameToDB2Name(curRef->field_name, colName, sizeof(colName));
- appendHere.append(colName);
- }
-
- appendHere.append(STRING_WITH_LEN(") "));
- }
-
- if (fk->delete_opt != Foreign_key::FK_OPTION_UNDEF)
- {
- appendHere.append(STRING_WITH_LEN("ON DELETE "));
- switch (fk->delete_opt)
- {
- case Foreign_key::FK_OPTION_RESTRICT:
- appendHere.append(STRING_WITH_LEN("RESTRICT ")); break;
- case Foreign_key::FK_OPTION_CASCADE:
- appendHere.append(STRING_WITH_LEN("CASCADE ")); break;
- case Foreign_key::FK_OPTION_SET_NULL:
- appendHere.append(STRING_WITH_LEN("SET NULL ")); break;
- case Foreign_key::FK_OPTION_NO_ACTION:
- appendHere.append(STRING_WITH_LEN("NO ACTION ")); break;
- case Foreign_key::FK_OPTION_DEFAULT:
- appendHere.append(STRING_WITH_LEN("SET DEFAULT ")); break;
- default:
- return HA_ERR_CANNOT_ADD_FOREIGN; break;
- }
- }
-
- if (fk->update_opt != Foreign_key::FK_OPTION_UNDEF)
- {
- appendHere.append(STRING_WITH_LEN("ON UPDATE "));
- switch (fk->update_opt)
- {
- case Foreign_key::FK_OPTION_RESTRICT:
- appendHere.append(STRING_WITH_LEN("RESTRICT ")); break;
- case Foreign_key::FK_OPTION_NO_ACTION:
- appendHere.append(STRING_WITH_LEN("NO ACTION ")); break;
- default:
- return HA_ERR_CANNOT_ADD_FOREIGN; break;
- }
- }
-
- }
-
- }
-
- return 0;
-}
-
-
-/***********************************************************************
-Get the foreign key information in the form of a character string so
-that it can be inserted into a CREATE TABLE statement. This is used by
-the SHOW CREATE TABLE statement. The string will later be freed by the
-free_foreign_key_create_info() method.
-************************************************************************/
-
-char* ha_ibmdb2i::get_foreign_key_create_info(void)
-{
- DBUG_ENTER("ha_ibmdb2i::get_foreign_key_create_info");
- int rc = 0;
- char* infoBuffer = NULL; // Pointer to string returned to MySQL
- uint32 constraintSpaceLength;// Length of space passed to DB2
- ValidatedPointer<char> constraintSpace; // Space pointer passed to DB2
- uint32 neededLen; // Length returned from DB2
- uint32 cstCnt; // Number of foreign key constraints from DB2
- uint32 fld; //
- constraint_hdr* cstHdr; // Pointer to constraint header structure
- FK_constraint* FKCstDef; // Pointer to constraint definition structure
- cst_name* fieldName; // Pointer to field name structure
- char* tempPtr; // Temp pointer for traversing constraint space
- char convName[128];
-
- /* Allocate space to retrieve the DB2 constraint information. */
-
- if (!(share = get_share(table_share->path.str, table)))
- DBUG_RETURN(NULL);
-
- constraintSpaceLength = 5000; // Try allocating 5000 bytes and see if enough.
-
- initBridge();
-
- constraintSpace.alloc(constraintSpaceLength);
- rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE)
- ->constraints(db2Table->dataFile()->getMasterDefnHandle(),
- constraintSpace,
- constraintSpaceLength,
- &neededLen,
- &cstCnt);
-
- if (unlikely(rc == QMY_ERR_NEED_MORE_SPACE))
- {
- constraintSpaceLength = neededLen; // Get length of space that's needed
- constraintSpace.realloc(constraintSpaceLength);
- rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE)
- ->constraints(db2Table->dataFile()->getMasterDefnHandle(),
- constraintSpace,
- constraintSpaceLength,
- &neededLen,
- &cstCnt);
- }
-
- /* If constraint information was returned by DB2, build a text string */
- /* to return to MySQL. */
-
- if ((rc == 0) && (cstCnt > 0))
- {
- THD* thd = ha_thd();
- infoBuffer = (char*) my_malloc(MAX_FOREIGN_LEN + 1, MYF(MY_WME));
- if (infoBuffer == NULL)
- {
- free_share(share);
- DBUG_RETURN(NULL);
- }
-
- SafeString info(infoBuffer, MAX_FOREIGN_LEN + 1);
-
- /* Loop through the DB2 constraints and build a text string for each foreign */
- /* key constraint that is found. */
-
- tempPtr = constraintSpace;
- cstHdr = (constraint_hdr_t*)(void*)constraintSpace; // Address first constraint definition
- for (int i = 0; i < cstCnt && !info.overflowed(); ++i)
- {
- if (cstHdr->CstType[0] == QMY_CST_FK) // If this is a foreign key constraint
- {
- tempPtr = (char*)(tempPtr + cstHdr->CstDefOff);
- FKCstDef = (FK_constraint_t*)tempPtr;
-
- /* Process the constraint name. */
-
- info.strncat(STRING_WITH_LEN(",\n CONSTRAINT "));
- convNameForCreateInfo(thd, info,
- FKCstDef->CstName.Name, FKCstDef->CstName.Len);
-
- /* Process the names of the foreign keys. */
-
- info.strncat(STRING_WITH_LEN(" FOREIGN KEY ("));
- tempPtr = (char*)(tempPtr + FKCstDef->KeyColOff);
- fieldName= (cst_name_t*)tempPtr;
- for (fld = 0; fld < FKCstDef->KeyCnt; ++fld)
- {
- convNameForCreateInfo(thd, info, fieldName->Name, fieldName->Len);
- if ((fld + 1) < FKCstDef->KeyCnt)
- {
- info.strncat(STRING_WITH_LEN(", "));
- fieldName = fieldName + 1;
- }
- }
-
- /* Process the schema-name and name of the referenced table. */
-
- info.strncat(STRING_WITH_LEN(") REFERENCES "));
- convNameForCreateInfo(thd, info,
- FKCstDef->RefSchema.Name, FKCstDef->RefSchema.Len);
- info.strcat('.');
- convNameForCreateInfo(thd, info,
- FKCstDef->RefTable.Name, FKCstDef->RefTable.Len);
- info.strncat(STRING_WITH_LEN(" ("));
-
- /* Process the names of the referenced keys. */
-
- tempPtr = (char*)FKCstDef;
- tempPtr = (char*)(tempPtr + FKCstDef->RefColOff);
- fieldName= (cst_name_t*)tempPtr;
- for (fld = 0; fld < FKCstDef->RefCnt; ++fld)
- {
- convNameForCreateInfo(thd, info, fieldName->Name, fieldName->Len);
- if ((fld + 1) < FKCstDef->RefCnt)
- {
- info.strncat(STRING_WITH_LEN(", "));
- fieldName = fieldName + 1;
- }
- }
-
- /* Process the ON UPDATE and ON DELETE rules. */
-
- info.strncat(STRING_WITH_LEN(") ON UPDATE "));
- switch(FKCstDef->UpdMethod)
- {
- case QMY_NOACTION: info.strncat(STRING_WITH_LEN("NO ACTION")); break;
- case QMY_RESTRICT: info.strncat(STRING_WITH_LEN("RESTRICT")); break;
- default: break;
- }
- info.strncat(STRING_WITH_LEN(" ON DELETE "));
- switch(FKCstDef->DltMethod)
- {
- case QMY_CASCADE: info.strncat(STRING_WITH_LEN("CASCADE")); break;
- case QMY_SETDFT: info.strncat(STRING_WITH_LEN("SET DEFAULT")); break;
- case QMY_SETNULL: info.strncat(STRING_WITH_LEN("SET NULL")); break;
- case QMY_NOACTION: info.strncat(STRING_WITH_LEN("NO ACTION")); break;
- case QMY_RESTRICT: info.strncat(STRING_WITH_LEN("RESTRICT")); break;
- default: break;
- }
- }
-
- /* Address the next constraint, if any. */
-
- if ((i+1) < cstCnt)
- {
- tempPtr = (char*)cstHdr + cstHdr->CstLen;
- cstHdr = (constraint_hdr_t*)(tempPtr);
- }
- }
- }
-
- /* Cleanup and return */
- free_share(share);
-
- DBUG_RETURN(infoBuffer);
-}
-
-/***********************************************************************
-Free the foreign key create info (for a table) that was acquired by the
-get_foreign_key_create_info() method.
-***********************************************************************/
-
-void ha_ibmdb2i::free_foreign_key_create_info(char* info)
-{
- DBUG_ENTER("ha_ibmdb2i::free_foreign_key_create_info");
-
- if (info)
- {
- my_free(info, MYF(0));
- }
- DBUG_VOID_RETURN;
-}
-
-/***********************************************************************
-This method returns to MySQL a list, with one entry in the list describing
-each foreign key constraint.
-***********************************************************************/
-
-int ha_ibmdb2i::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
-{
- DBUG_ENTER("ha_ibmdb2i::get_foreign_key_list");
- int rc = 0;
- uint32 constraintSpaceLength; // Length of space passed to DB2
- ValidatedPointer<char> constraintSpace; // Space pointer passed to DB2
- uint16 rtnCode; // Return code from DB2
- uint32 neededLen; // Bytes needed to contain DB2 constraint info
- uint32 cstCnt; // Number of constraints returned by DB2
- uint32 fld;
- constraint_hdr* cstHdr; // Pointer to a cst header structure
- FK_constraint* FKCstDef; // Pointer to definition of foreign key constraint
- cst_name* fieldName; // Pointer to field name structure
- const char *method;
- ulong methodLen;
- char* tempPtr; // Temp pointer for traversing constraint space
- char convName[128];
-
- if (!(share = get_share(table_share->path.str, table)))
- DBUG_RETURN(0);
-
- // Allocate space to retrieve the DB2 constraint information.
- constraintSpaceLength = 5000; // Try allocating 5000 bytes and see if enough.
-
- constraintSpace.alloc(constraintSpaceLength);
- rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE)
- ->constraints(db2Table->dataFile()->getMasterDefnHandle(),
- constraintSpace,
- constraintSpaceLength,
- &neededLen,
- &cstCnt);
-
- if (unlikely(rc == QMY_ERR_NEED_MORE_SPACE))
- {
- constraintSpaceLength = neededLen; // Get length of space that's needed
- constraintSpace.realloc(constraintSpaceLength);
- rc = bridge()->expectErrors(QMY_ERR_NEED_MORE_SPACE)
- ->constraints(db2Table->dataFile()->getMasterDefnHandle(),
- constraintSpace,
- constraintSpaceLength,
- &neededLen,
- &cstCnt);
- }
-
- /* If constraint information was returned by DB2, build a text string */
- /* to return to MySQL. */
- if ((rc == 0) && (cstCnt > 0))
- {
- tempPtr = constraintSpace;
- cstHdr = (constraint_hdr_t*)(void*)constraintSpace; // Address first constraint definition
- for (int i = 0; i < cstCnt; ++i)
- {
- if (cstHdr->CstType[0] == QMY_CST_FK) // If this is a foreign key constraint
- {
- FOREIGN_KEY_INFO f_key_info;
- LEX_STRING *name= 0;
- tempPtr = (char*)(tempPtr + cstHdr->CstDefOff);
- FKCstDef = (FK_constraint_t*)tempPtr;
-
- /* Process the constraint name. */
-
- convFromEbcdic(FKCstDef->CstName.Name, convName,FKCstDef->CstName.Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- f_key_info.forein_id = thd_make_lex_string(thd, 0,
- convName + 1, (uint) (FKCstDef->CstName.Len - 2), 1);
- else // Not quoted
- f_key_info.forein_id = thd_make_lex_string(thd, 0,
- convName, (uint) FKCstDef->CstName.Len, 1);
-
- /* Process the names of the foreign keys. */
-
-
- tempPtr = (char*)(tempPtr + FKCstDef->KeyColOff);
- fieldName = (cst_name_t*)tempPtr;
- for (fld = 0; fld < FKCstDef->KeyCnt; ++fld)
- {
- convFromEbcdic(fieldName->Name, convName, fieldName->Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- name = thd_make_lex_string(thd, name,
- convName + 1, (uint) (fieldName->Len - 2), 1);
- else
- name = thd_make_lex_string(thd, name, convName, (uint) fieldName->Len, 1);
- f_key_info.foreign_fields.push_back(name);
- if ((fld + 1) < FKCstDef->KeyCnt)
- fieldName = fieldName + 1;
- }
-
- /* Process the schema and name of the referenced table. */
-
- convFromEbcdic(FKCstDef->RefSchema.Name, convName, FKCstDef->RefSchema.Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- f_key_info.referenced_db = thd_make_lex_string(thd, 0,
- convName + 1, (uint) (FKCstDef->RefSchema.Len -2), 1);
- else
- f_key_info.referenced_db = thd_make_lex_string(thd, 0,
- convName, (uint) FKCstDef->RefSchema.Len, 1);
- convFromEbcdic(FKCstDef->RefTable.Name, convName, FKCstDef->RefTable.Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- f_key_info.referenced_table = thd_make_lex_string(thd, 0,
- convName +1, (uint) (FKCstDef->RefTable.Len -2), 1);
- else
- f_key_info.referenced_table = thd_make_lex_string(thd, 0,
- convName, (uint) FKCstDef->RefTable.Len, 1);
-
- /* Process the names of the referenced keys. */
-
- tempPtr = (char*)FKCstDef;
- tempPtr = (char*)(tempPtr + FKCstDef->RefColOff);
- fieldName= (cst_name_t*)tempPtr;
- for (fld = 0; fld < FKCstDef->RefCnt; ++fld)
- {
- convFromEbcdic(fieldName->Name, convName, fieldName->Len);
- if (convName[0] == '"') // If quoted, exclude quotes.
- name = thd_make_lex_string(thd, name,
- convName + 1, (uint) (fieldName->Len -2), 1);
- else
- name = thd_make_lex_string(thd, name, convName, (uint) fieldName->Len, 1);
- f_key_info.referenced_fields.push_back(name);
- if ((fld + 1) < FKCstDef->RefCnt)
- fieldName = fieldName + 1;
- }
-
- /* Process the ON UPDATE and ON DELETE rules. */
-
- switch(FKCstDef->UpdMethod)
- {
- case QMY_NOACTION:
- {
- method = "NO ACTION";
- methodLen=9;
- }
- break;
- case QMY_RESTRICT:
- {
- method = "RESTRICT";
- methodLen = 8;
- }
- break;
- default: break;
- }
- f_key_info.update_method = thd_make_lex_string(
- thd, f_key_info.update_method, method, methodLen, 1);
- switch(FKCstDef->DltMethod)
- {
- case QMY_CASCADE:
- {
- method = "CASCADE";
- methodLen = 7;
- }
- break;
- case QMY_SETDFT:
- {
- method = "SET DEFAULT";
- methodLen = 11;
- }
- break;
- case QMY_SETNULL:
- {
- method = "SET NULL";
- methodLen = 8;
- }
- break;
- case QMY_NOACTION:
- {
- method = "NO ACTION";
- methodLen = 9;
- }
- break;
- case QMY_RESTRICT:
- {
- method = "RESTRICT";
- methodLen = 8;
- }
- break;
- default: break;
- }
- f_key_info.delete_method = thd_make_lex_string(
- thd, f_key_info.delete_method, method, methodLen, 1);
- f_key_info.referenced_key_name= thd_make_lex_string(thd, 0, (char *)"", 1, 1);
- FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *)
- thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO));
- f_key_list->push_back(pf_key_info);
- }
-
- /* Address the next constraint, if any. */
-
- if ((i+1) < cstCnt)
- {
- tempPtr = (char*)cstHdr + cstHdr->CstLen;
- cstHdr = (constraint_hdr_t*)(tempPtr);
- }
- }
- }
-
- /* Cleanup and return. */
-
- free_share(share);
- DBUG_RETURN(0);
-}
-
-/***********************************************************************
-Checks if the table is referenced by a foreign key.
-Returns: 0 if not referenced (or error occurs),
- > 0 if is referenced
-***********************************************************************/
-
-uint ha_ibmdb2i::referenced_by_foreign_key(void)
-{
- DBUG_ENTER("ha_ibmdb2i::referenced_by_foreign_key");
-
- int rc = 0;
- FILE_HANDLE queryFile = 0;
- uint32 resultRowLen;
- uint32 count = 0;
-
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- String query(128);
- query.append(STRING_WITH_LEN(" SELECT COUNT(*) FROM SYSIBM.SQLFOREIGNKEYS WHERE PKTABLE_SCHEM = '"));
- query.append(libName+1, strlen(libName)-2); // parent library name
- query.append(STRING_WITH_LEN("' AND PKTABLE_NAME = '"));
- query.append(fileName+1, strlen(fileName)-2); // parent file name
- query.append(STRING_WITH_LEN("'"));
-
- SqlStatementStream sqlStream(query);
-
- rc = bridge()->prepOpen(sqlStream.getPtrToData(),
- &queryFile,
- &resultRowLen);
- if (rc == 0)
- {
- IOReadBuffer rowBuffer(1, resultRowLen);
- rc = bridge()->read(queryFile, rowBuffer.ptr(), QMY_READ_ONLY, QMY_NONE, QMY_FIRST);
- if (!rc) count = *((uint32*)rowBuffer.getRowN(0));
- bridge()->deallocateFile(queryFile);
- }
- DBUG_RETURN(count);
-}
diff --git a/storage/ibmdb2i/db2i_conversion.cc b/storage/ibmdb2i/db2i_conversion.cc
deleted file mode 100644
index 9a85eb01c9b..00000000000
--- a/storage/ibmdb2i/db2i_conversion.cc
+++ /dev/null
@@ -1,1459 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-
-#include "db2i_ileBridge.h"
-#include "mysql_priv.h"
-#include "db2i_charsetSupport.h"
-#include "ctype.h"
-#include "ha_ibmdb2i.h"
-#include "db2i_errors.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.
-
- @param[out] bcdString The BCD string to be modified
- @param pos The position within the string to be updated.
- @param val The value to be assigned into the string at pos.
-*/
-static inline void bcdAssign(char* bcdString, uint pos, uint val)
-{
- bcdString[pos/2] |= val << ((pos % 2) ? 0 : 4);
-}
-
-/**
- Read a BCD digit from a BCD string.
-
- @param[out] bcdString The BCD string to be read
- @param pos The position within the string to be read.
-
- @return bcdGet The value of the BCD digit at pos.
-*/
-static inline uint bcdGet(const char* bcdString, uint pos)
-{
- return (bcdString[pos/2] >> ((pos % 2) ? 0 : 4)) & 0xf;
-}
-
-/**
- In-place convert a number in ASCII represenation to EBCDIC representation.
-
- @param string The string of ASCII characters
- @param len The length of string
-*/
-static inline void convertNumericToEbcdicFast(char* string, int len)
-{
- for (int i = 0; i < len; ++i, ++string)
- {
- switch(*string)
- {
- case '-':
- *string = 0x60; break;
- case ':':
- *string = 0x7A; break;
- case '.':
- *string = 0x4B; break;
- default:
- DBUG_ASSERT(isdigit(*string));
- *string += 0xF0 - '0';
- break;
- }
- }
-}
-
-
-/**
- atoi()-like function for a 4-character EBCDIC string.
-
- @param string The EBCDIC string
- @return a4toi_ebcdic The decimal value of the EBCDIC string
-*/
-static inline uint16 a4toi_ebcdic(const uchar* string)
-{
- return ((string[0]-0xF0) * 1000 +
- (string[1]-0xF0) * 100 +
- (string[2]-0xF0) * 10 +
- (string[3]-0xF0));
-};
-
-
-/**
- atoi()-like function for a 4-character EBCDIC string.
-
- @param string The EBCDIC string
- @return a4toi_ebcdic The decimal value of the EBCDIC string
-*/
-static inline uint8 a2toi_ebcdic(const uchar* string)
-{
- return ((string[0]-0xF0) * 10 +
- (string[1]-0xF0));
-};
-
-/**
- Perform character conversion for textual field data.
-*/
-int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction,
- uint16 fieldID,
- const char* input,
- char* output,
- size_t ilen,
- size_t olen,
- size_t* outDataLen,
- bool tacitErrors,
- size_t* substChars)
-{
- DBUG_PRINT("ha_ibmdb2i::convertFieldChars",("Direction: %d; length = %d", direction, ilen));
-
- if (unlikely(ilen == 0))
- {
- if (outDataLen) *outDataLen = 0;
- return (0);
- }
-
- iconv_t& conversion = db2Table->getConversionDefinition(direction, fieldID);
-
- if (unlikely(conversion == (iconv_t)(-1)))
- {
- return (DB2I_ERR_UNSUPP_CHARSET);
- }
-
- size_t initOLen= olen;
- size_t substitutedChars = 0;
- int rc = iconv(conversion, (char**)&input, &ilen, &output, &olen, &substitutedChars );
- if (outDataLen) *outDataLen = initOLen - olen;
- if (substChars) *substChars = substitutedChars;
- if (unlikely(rc < 0))
- {
- int er = errno;
- if (er == EILSEQ)
- {
- if (!tacitErrors) getErrTxt(DB2I_ERR_ILL_CHAR, table->field[fieldID]->field_name);
- return (DB2I_ERR_ILL_CHAR);
- }
- else
- {
- if (!tacitErrors) getErrTxt(DB2I_ERR_ICONV,er);
- return (DB2I_ERR_ICONV);
- }
- }
- if (unlikely(substitutedChars) && (!tacitErrors))
- {
- warning(ha_thd(), DB2I_ERR_SUB_CHARS, table->field[fieldID]->field_name);
- }
-
- 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.
-
- The result will be appended to mapping as a DB2 SQL phrase.
-
- @param field The MySQL field to be evaluated
- @param[out] mapping The receiver for the DB2 SQL syntax
- @param timeFormat The format to be used for mapping the TIME type
-*/
-int ha_ibmdb2i::getFieldTypeMapping(Field* field,
- String& mapping,
- enum_TimeFormat timeFormat,
- enum_BlobMapping blobMapping,
- enum_ZeroDate zeroDateHandling,
- bool propagateDefaults,
- enum_YearFormat yearFormat)
-{
- char stringBuildBuffer[257];
- uint32 fieldLength;
- bool defaultNeedsQuotes = false;
- uint16 db2Ccsid = 0;
-
- CHARSET_INFO* fieldCharSet = field->charset();
- switch (field->type())
- {
- case MYSQL_TYPE_NEWDECIMAL:
- {
- uint precision= ((Field_new_decimal*)field)->precision;
- uint scale= field->decimals();
-
- if (precision <= MAX_DEC_PRECISION)
- {
- sprintf(stringBuildBuffer,"DECIMAL(%d, %d)",precision,scale);
- }
- else
- {
- if (scale > precision - MAX_DEC_PRECISION)
- {
- scale = scale - (precision - MAX_DEC_PRECISION);
- precision = MAX_DEC_PRECISION;
- sprintf(stringBuildBuffer,"DECIMAL(%d, %d)",precision,scale);
- }
- else
- {
- return HA_ERR_UNSUPPORTED;
- }
- warning(ha_thd(), DB2I_ERR_PRECISION);
- }
-
- mapping.append(stringBuildBuffer);
- }
- break;
- case MYSQL_TYPE_TINY:
- mapping.append(STRING_WITH_LEN("SMALLINT"));
- break;
- case MYSQL_TYPE_SHORT:
- if (((Field_num*)field)->unsigned_flag)
- mapping.append(STRING_WITH_LEN("INT"));
- else
- mapping.append(STRING_WITH_LEN("SMALLINT"));
- break;
- case MYSQL_TYPE_LONG:
- if (((Field_num*)field)->unsigned_flag)
- mapping.append(STRING_WITH_LEN("BIGINT"));
- else
- mapping.append(STRING_WITH_LEN("INT"));
- break;
- case MYSQL_TYPE_FLOAT:
- mapping.append(STRING_WITH_LEN("REAL"));
- break;
- case MYSQL_TYPE_DOUBLE:
- mapping.append(STRING_WITH_LEN("DOUBLE"));
- break;
- case MYSQL_TYPE_LONGLONG:
- if (((Field_num*)field)->unsigned_flag)
- mapping.append(STRING_WITH_LEN("DECIMAL(20,0)"));
- else
- mapping.append(STRING_WITH_LEN("BIGINT"));
- break;
- case MYSQL_TYPE_INT24:
- mapping.append(STRING_WITH_LEN("INTEGER"));
- break;
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_NEWDATE:
- mapping.append(STRING_WITH_LEN("DATE"));
- defaultNeedsQuotes = true;
- break;
- case MYSQL_TYPE_TIME:
- if (timeFormat == TIME_OF_DAY)
- {
- mapping.append(STRING_WITH_LEN("TIME"));
- defaultNeedsQuotes = true;
- }
- else
- mapping.append(STRING_WITH_LEN("INTEGER"));
- break;
- case MYSQL_TYPE_DATETIME:
- 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;
- case MYSQL_TYPE_YEAR:
- if (yearFormat == CHAR4)
- {
- mapping.append(STRING_WITH_LEN("CHAR(4) CCSID 1208"));
- defaultNeedsQuotes = true;
- }
- else
- {
- mapping.append(STRING_WITH_LEN("SMALLINT"));
- defaultNeedsQuotes = false;
- }
- break;
- case MYSQL_TYPE_BIT:
- sprintf(stringBuildBuffer, "BINARY(%d)", (field->max_display_length() / 8) + 1);
- mapping.append(stringBuildBuffer);
- break;
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_VARCHAR:
- case MYSQL_TYPE_STRING:
- {
- if (field->real_type() == MYSQL_TYPE_ENUM ||
- field->real_type() == MYSQL_TYPE_SET)
- {
- mapping.append(STRING_WITH_LEN("BIGINT"));
- }
- else
- {
- defaultNeedsQuotes = true;
-
- fieldLength = field->max_display_length(); // Get field byte length
-
- if (fieldCharSet == &my_charset_bin)
- {
- if (field->type() == MYSQL_TYPE_STRING)
- {
- sprintf(stringBuildBuffer, "BINARY(%d)", max(fieldLength, 1));
- }
- else
- {
- if (fieldLength <= MAX_VARCHAR_LENGTH)
- {
- sprintf(stringBuildBuffer, "VARBINARY(%d)", max(fieldLength, 1));
- }
- else if (blobMapping == AS_VARCHAR &&
- (field->flags & PART_KEY_FLAG))
- {
- sprintf(stringBuildBuffer, "LONG VARBINARY ");
- }
- else
- {
- fieldLength = min(MAX_BLOB_LENGTH, fieldLength);
- sprintf(stringBuildBuffer, "BLOB(%d)", max(fieldLength, 1));
- }
- }
- mapping.append(stringBuildBuffer);
- }
- else
- {
- if (field->type() == MYSQL_TYPE_STRING)
- {
- if (fieldLength > MAX_CHAR_LENGTH)
- return 1;
- if (fieldCharSet->mbmaxlen > 1)
- {
- if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2
- {
- sprintf(stringBuildBuffer, "GRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 13488;
- }
- else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 &&
- strcmp(fieldCharSet->name, "utf8_general_ci") != 0)
- {
- sprintf(stringBuildBuffer, "CHAR(%d)", max(fieldLength, 1)); // Number of bytes
- db2Ccsid = 1208;
- }
- else
- {
- sprintf(stringBuildBuffer, "GRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 1200;
- }
- }
- else
- {
- sprintf(stringBuildBuffer, "CHAR(%d)", max(fieldLength, 1));
- }
- mapping.append(stringBuildBuffer);
- }
- else
- {
- if (fieldLength <= MAX_VARCHAR_LENGTH)
- {
- if (fieldCharSet->mbmaxlen > 1)
- {
- if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2
- {
- sprintf(stringBuildBuffer, "VARGRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 13488;
- }
- else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 &&
- strcmp(fieldCharSet->name, "utf8_general_ci") != 0)
- {
- sprintf(stringBuildBuffer, "VARCHAR(%d)", max(fieldLength, 1)); // Number of bytes
- db2Ccsid = 1208;
- }
- else
- {
- sprintf(stringBuildBuffer, "VARGRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 1200;
- }
- }
- else
- {
- sprintf(stringBuildBuffer, "VARCHAR(%d)", max(fieldLength, 1));
- }
- }
- else if (blobMapping == AS_VARCHAR &&
- (field->flags & PART_KEY_FLAG))
- {
- if (fieldCharSet->mbmaxlen > 1)
- {
- if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2
- {
- sprintf(stringBuildBuffer, "LONG VARGRAPHIC ");
- db2Ccsid = 13488;
- }
- else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 &&
- strcmp(fieldCharSet->name, "utf8_general_ci") != 0)
- {
- sprintf(stringBuildBuffer, "LONG VARCHAR ");
- db2Ccsid = 1208;
- }
- else
- {
- sprintf(stringBuildBuffer, "LONG VARGRAPHIC ");
- db2Ccsid = 1200;
- }
- }
- else
- {
- sprintf(stringBuildBuffer, "LONG VARCHAR ");
- }
- }
- else
- {
- fieldLength = min(MAX_BLOB_LENGTH, fieldLength);
-
- if (fieldCharSet->mbmaxlen > 1)
- {
- if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2
- {
- sprintf(stringBuildBuffer, "DBCLOB(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 13488;
- }
- else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 &&
- strcmp(fieldCharSet->name, "utf8_general_ci") != 0)
- {
- sprintf(stringBuildBuffer, "CLOB(%d)", max(fieldLength, 1)); // Number of bytes
- db2Ccsid = 1208;
- }
- else
- {
- sprintf(stringBuildBuffer, "DBCLOB(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters
- db2Ccsid = 1200;
- }
- }
- else
- {
- sprintf(stringBuildBuffer, "CLOB(%d)", max(fieldLength, 1)); // Number of characters
- }
- }
-
- mapping.append(stringBuildBuffer);
- }
- if (db2Ccsid == 0) // If not overriding CCSID
- {
- int32 rtnCode = convertIANAToDb2Ccsid(fieldCharSet->csname, &db2Ccsid);
- if (rtnCode)
- return rtnCode;
- }
-
- if (db2Ccsid != 1208 &&
- db2Ccsid != 13488)
- {
- // Check whether there is a character conversion available.
- iconv_t temp;
- int32 rc = getConversion(toDB2, fieldCharSet, db2Ccsid, temp);
- if (unlikely(rc))
- return rc;
- }
-
- sprintf(stringBuildBuffer, " CCSID %d ", db2Ccsid);
- mapping.append(stringBuildBuffer);
- }
- }
- }
- break;
-
- }
-
- if (propagateDefaults)
- get_field_default_value(field,
- mapping,
- defaultNeedsQuotes,
- db2Ccsid,
- (zeroDateHandling==SUBSTITUTE_0001_01_01));
-
- return 0;
-}
-
-
-/**
- Convert MySQL field data into the equivalent DB2 format
-
- @param field The MySQL field to be converted
- @param db2Field The corresponding DB2 field definition
- @param db2Buf The buffer to receive the converted data
- @param data NULL if field points to the correct data; otherwise,
- the data to be converted (for use with keys)
-*/
-int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char* db2Buf, const uchar* data)
-{
- enum_field_types fieldType = field->type();
- switch (fieldType)
- {
- case MYSQL_TYPE_NEWDECIMAL:
- {
- uint precision= ((Field_new_decimal*)field)->precision;
- uint scale= field->decimals();
- uint db2Precision = min(precision, MAX_DEC_PRECISION);
- uint truncationAmount = precision - db2Precision;
-
- if (scale >= truncationAmount)
- {
- String tempString(precision+2);
-
- if (data == NULL)
- {
- field->val_str((String*)&tempString, (String*)(NULL));
- }
- else
- {
- field->val_str(&tempString, data);
- }
- const char* temp = tempString.ptr();
- char packed[32];
- memset(&packed, 0, sizeof(packed));
-
- int bcdPos = db2Precision - (db2Precision % 2 ? 1 : 0);
- bcdAssign(packed, bcdPos+1, (temp[0] == '-' ? 0xD : 0xF));
-
- int strPos=tempString.length() - 1 - truncationAmount;
-
- for (;strPos >= 0 && bcdPos >= 0; strPos--)
- {
- if (my_isdigit(&my_charset_latin1, temp[strPos]))
- {
- bcdAssign(packed, bcdPos, temp[strPos]-'0');
- --bcdPos;
- }
- }
- memcpy(db2Buf, &packed, (db2Precision/2)+1);
- }
-
- }
- break;
- case MYSQL_TYPE_TINY:
- {
- int16 temp = (data == NULL ? field->val_int() : field->val_int(data));
- memcpy(db2Buf , &temp, sizeof(temp));
- }
- break;
- case MYSQL_TYPE_SHORT:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- memset(db2Buf, 0, 2);
- memcpy(db2Buf+2, (data == NULL ? field->ptr : data), 2);
- }
- else
- {
- memcpy(db2Buf, (data == NULL ? field->ptr : data), 2);
- }
- }
- break;
- case MYSQL_TYPE_LONG:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- memset(db2Buf, 0, 4);
- memcpy(db2Buf+4, (data == NULL ? field->ptr : data), 4);
- }
- else
- {
- memcpy(db2Buf, (data == NULL ? field->ptr : data), 4);
- }
- }
- break;
- case MYSQL_TYPE_FLOAT:
- {
- memcpy(db2Buf, (data == NULL ? field->ptr : data), 4);
- }
- break;
- case MYSQL_TYPE_DOUBLE:
- {
- memcpy(db2Buf, (data == NULL ? field->ptr : data), 8);
- }
- break;
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_DATETIME:
- {
- String tempString(27);
- if (data == NULL)
- {
- field->val_str(&tempString, &tempString);
- }
- else
- {
- field->val_str(&tempString, data);
- }
- memset(db2Buf, '0', 26);
- memcpy(db2Buf, tempString.ptr(), tempString.length());
- if (strncmp(db2Buf,ZERO_DATETIME_VALUE,strlen(ZERO_DATETIME_VALUE)) == 0)
- {
- 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);
- }
- }
- (db2Buf)[10] = '-';
- (db2Buf)[13] = (db2Buf)[16] = (db2Buf)[19] = '.';
-
- convertNumericToEbcdicFast(db2Buf, 26);
- }
- break;
- case MYSQL_TYPE_LONGLONG:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- char temp[23];
- String tempString(temp, sizeof(temp), &my_charset_latin1);
-
- if (data == NULL)
- {
- field->val_str((String*)&tempString, (String*)(NULL));
- }
- else
- {
- field->val_str(&tempString, data);
- }
- char packed[11];
- memset(packed, 0, sizeof(packed));
- bcdAssign(packed, 21, (temp[0] == '-' ? 0xD : 0xF));
- int strPos=tempString.length()-1;
- int bcdPos=20;
-
- for (;strPos >= 0; strPos--)
- {
- if (my_isdigit(&my_charset_latin1, temp[strPos]))
- {
- bcdAssign(packed, bcdPos, temp[strPos]-'0');
- --bcdPos;
- }
- }
- memcpy(db2Buf, &packed, 11);
- }
- else
- {
- *(uint64*)db2Buf = *(uint64*)(data == NULL ? field->ptr : data);
- }
- }
- break;
- case MYSQL_TYPE_INT24:
- {
- int32 temp= (data == NULL ? field->val_int() : field->val_int(data));
- memcpy(db2Buf , &temp, sizeof(temp));
- }
- break;
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_NEWDATE:
- {
- String tempString(11);
- if (data == NULL)
- {
- field->val_str(&tempString, (String*)NULL);
- }
- else
- {
- field->val_str(&tempString, data);
- }
- memcpy(db2Buf, tempString.ptr(), 10);
- 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,field->field_name);
- return(DB2I_ERR_INVALID_COL_VALUE);
- }
- }
-
- convertNumericToEbcdicFast(db2Buf,10);
- }
- break;
- case MYSQL_TYPE_TIME:
- {
- if (db2Field.getType() == QMY_TIME)
- {
- String tempString(10);
- if (data == NULL)
- {
- field->val_str(&tempString, (String*)NULL);
- }
- else
- {
- field->val_str(&tempString, data);
- }
- memcpy(db2Buf, tempString.ptr(), 8);
- (db2Buf)[2]=(db2Buf)[5] = '.';
-
- convertNumericToEbcdicFast(db2Buf, 8);
- }
- else
- {
- int32 temp = sint3korr(data == NULL ? field->ptr : data);
- memcpy(db2Buf, &temp, sizeof(temp));
- }
- }
- break;
- case MYSQL_TYPE_YEAR:
- {
- String tempString(5);
- if (db2Field.getType() == QMY_CHAR)
- {
- if (data == NULL)
- {
- field->val_str(&tempString, (String*)NULL);
- }
- else
- {
- field->val_str(&tempString, data);
- }
- memcpy(db2Buf, tempString.ptr(), 4);
- }
- else
- {
- uint8 temp = *(uint8*)(data == NULL ? field->ptr : data);
- *(uint16*)(db2Buf) = (temp ? temp + 1900 : 0);
- }
- }
- break;
- case MYSQL_TYPE_BIT:
- {
- int bytesToCopy = db2Field.getByteLengthInRecord();
-
- if (data == NULL)
- {
- uint64 temp = field->val_int();
- memcpy(db2Buf,
- ((char*)&temp) + (sizeof(temp) - bytesToCopy),
- bytesToCopy);
- }
- else
- {
- memcpy(db2Buf,
- data,
- bytesToCopy);
- }
- }
- break;
- case MYSQL_TYPE_VARCHAR:
- case MYSQL_TYPE_STRING:
- case MYSQL_TYPE_BLOB:
- {
- if (field->real_type() == MYSQL_TYPE_ENUM ||
- field->real_type() == MYSQL_TYPE_SET)
- {
- int64 temp= (data == NULL ? field->val_int() : field->val_int(data));
- *(int64*)db2Buf = temp;
- }
- else
- {
- const uchar* dataToStore;
- uint32 bytesToStore;
- uint32 bytesToPad = 0;
- CHARSET_INFO* fieldCharSet = field->charset();
- uint32 maxDisplayLength = field->max_display_length();
- switch (fieldType)
- {
- case MYSQL_TYPE_STRING:
- {
- bytesToStore = maxDisplayLength;
- if (data == NULL)
- dataToStore = field->ptr;
- else
- dataToStore = data;
- }
- break;
- case MYSQL_TYPE_VARCHAR:
- {
-
- if (data == NULL)
- {
- bytesToStore = field->data_length();
- dataToStore = field->ptr + ((Field_varstring*)field)->length_bytes;
- }
- else
- {
- // Key lens are stored little-endian
- bytesToStore = *(uint8*)data + ((*(uint8*)(data+1)) << 8);
- dataToStore = data + 2;
- }
- bytesToPad = maxDisplayLength - bytesToStore;
- }
- break;
- case MYSQL_TYPE_BLOB:
- {
- if (data == NULL)
- {
- bytesToStore = ((Field_blob*)field)->get_length();
- bytesToPad = maxDisplayLength - bytesToStore;
- ((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;
- }
-
- int32 rc;
- uint16 db2FieldType = db2Field.getType();
- switch(db2FieldType)
- {
- case QMY_CHAR:
- if (maxDisplayLength == 0)
- bytesToPad = 1;
- case QMY_VARCHAR:
- if (db2FieldType == QMY_VARCHAR)
- {
- db2Buf += sizeof(uint16);
- bytesToPad = 0;
- }
-
- if (bytesToStore > db2Field.getDataLengthInRecord())
- {
- bytesToStore = db2Field.getDataLengthInRecord();
- field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
- }
-
- if (fieldCharSet == &my_charset_bin) // If binary
- {
- if (bytesToStore)
- memcpy(db2Buf, dataToStore, bytesToStore);
- if (bytesToPad)
- memset(db2Buf + bytesToStore, 0x00, bytesToPad);
- }
- else if (db2Field.getCCSID() == 1208) // utf8
- {
- if (bytesToStore)
- memcpy(db2Buf, dataToStore, bytesToStore);
- if (bytesToPad)
- memset(db2Buf + bytesToStore, ' ', bytesToPad);
- }
- else // single-byte ASCII to EBCDIC
- {
- DBUG_ASSERT(fieldCharSet->mbmaxlen == 1);
- if (bytesToStore)
- {
- rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore, db2Buf, bytesToStore, bytesToStore, NULL);
- if (rc)
- return rc;
- }
- if (bytesToPad)
- memset(db2Buf + bytesToStore, 0x40, bytesToPad);
- }
-
- if (db2FieldType == QMY_VARCHAR)
- *(uint16*)(db2Buf - sizeof(uint16)) = bytesToStore;
- break;
- case QMY_VARGRAPHIC:
- db2Buf += sizeof(uint16);
- bytesToPad = 0;
- case QMY_GRAPHIC:
- if (maxDisplayLength == 0 && db2FieldType == QMY_GRAPHIC)
- bytesToPad = 2;
-
- if (db2Field.getCCSID() == 13488)
- {
- if (bytesToStore)
- memcpy(db2Buf, dataToStore, bytesToStore);
- if (bytesToPad)
- memset16((db2Buf + bytesToStore), 0x0020, bytesToPad/2);
- }
- else
- {
- size_t db2BytesToStore;
- size_t maxDb2BytesToStore;
-
- if (maxDisplayLength == 0 && db2FieldType == QMY_GRAPHIC)
- maxDb2BytesToStore = 2;
- else
- maxDb2BytesToStore = min(((bytesToStore * 2) / fieldCharSet->mbminlen),
- ((maxDisplayLength * 2) / fieldCharSet->mbmaxlen));
-
- if (bytesToStore == 0)
- db2BytesToStore = 0;
- else
- {
- rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore, db2Buf, bytesToStore, maxDb2BytesToStore, &db2BytesToStore);
- if (rc)
- return rc;
- bytesToStore = db2BytesToStore;
- }
- if (db2BytesToStore < maxDb2BytesToStore) // If need to pad
- memset16((db2Buf + db2BytesToStore), 0x0020, (maxDb2BytesToStore - db2BytesToStore)/2);
- }
-
- if (db2FieldType == QMY_VARGRAPHIC)
- *(uint16*)(db2Buf-sizeof(uint16)) = bytesToStore/2;
- break;
- case QMY_BLOBCLOB:
- case QMY_DBCLOB:
- {
- DBUG_ASSERT(data == NULL);
- DB2LobField* lobField = (DB2LobField*)(db2Buf + db2Field.calcBlobPad());
-
- if ((fieldCharSet == &my_charset_bin) || // binary or
- (db2Field.getCCSID()==13488) ||
- (db2Field.getCCSID()==1208)) // binary UTF8
- {
- }
- else
- {
- char* temp;
- int32 rc;
- size_t db2BytesToStore;
- if (fieldCharSet->mbmaxlen == 1) // single-byte ASCII to EBCDIC
- {
- temp = getCharacterConversionBuffer(field->field_index, bytesToStore);
- rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore,temp,bytesToStore, bytesToStore, NULL);
- if (rc)
- return (rc);
- }
- else // Else Far East, special UTF8 or non-special UTF8/UCS2
- {
- size_t maxDb2BytesToStore;
- maxDb2BytesToStore = min(((bytesToStore * 2) / fieldCharSet->mbminlen),
- ((maxDisplayLength * 2) / fieldCharSet->mbmaxlen));
- temp = getCharacterConversionBuffer(field->field_index, maxDb2BytesToStore);
- rc = convertFieldChars(toDB2, field->field_index, (char*)dataToStore,temp,bytesToStore, maxDb2BytesToStore, &db2BytesToStore);
- if (rc)
- return (rc);
- bytesToStore = db2BytesToStore;
- }
- dataToStore = (uchar*)temp;
- }
-
- uint16 blobID = db2Table->getBlobIdFromField(field->field_index);
- if (blobWriteBuffers[blobID] != (char*)dataToStore)
- blobWriteBuffers[blobID].reassign((char*)dataToStore);
- if ((void*)blobWriteBuffers[blobID])
- lobField->dataHandle = (ILEMemHandle)blobWriteBuffers[blobID];
- else
- lobField->dataHandle = 0;
- lobField->length = bytesToStore / (db2FieldType == QMY_DBCLOB ? 2 : 1);
- }
- break;
- }
- }
- }
- break;
- default:
- DBUG_ASSERT(0);
- break;
- }
-
- return (ha_thd()->is_error());
-}
-
-
-/**
- Convert DB2 field data into the equivalent MySQL format
-
- @param db2Field The DB2 field definition
- @param field The MySQL field to receive the converted data
- @param buf The DB2 data to be converted
-*/
-int32 ha_ibmdb2i::convertDB2toMySQL(const DB2Field& db2Field, Field* field, const char* buf)
-{
- int32 storeRC = 0; // Result of the field->store() operation
-
- const char* bufPtr = buf + db2Field.getBufferOffset();
-
- switch (field->type())
- {
- case MYSQL_TYPE_NEWDECIMAL:
- {
- uint precision= ((Field_new_decimal*)field)->precision;
- uint scale= field->decimals();
- uint db2Precision = min(precision, MAX_DEC_PRECISION);
- uint decimalPlace = precision-scale+1;
- char temp[80];
-
- if (precision <= MAX_DEC_PRECISION ||
- scale > precision - MAX_DEC_PRECISION)
- {
- uint numNibbles = db2Precision + (db2Precision % 2 ? 0 : 1);
-
- temp[0] = (bcdGet(bufPtr, numNibbles) == 0xD ? '-' : ' ');
- int strPos=1;
- int bcdPos=(db2Precision % 2 ? 0 : 1);
-
- for (;bcdPos < numNibbles; bcdPos++, strPos++)
- {
- if (strPos == decimalPlace)
- {
- temp[strPos] = '.';
- strPos++;
- }
-
- temp[strPos] = bcdGet(bufPtr, bcdPos) + '0';
- }
-
- temp[strPos] = 0;
-
- storeRC = field->store(temp, strPos, &my_charset_latin1);
- }
- }
- break;
- case MYSQL_TYPE_TINY:
- {
- storeRC = field->store(*(int16*)bufPtr, ((Field_num*)field)->unsigned_flag);
- }
- break;
- case MYSQL_TYPE_SHORT:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- storeRC = field->store(*(int32*)bufPtr, TRUE);
- }
- else
- {
- storeRC = field->store(*(int16*)bufPtr, FALSE);
- }
- }
- break;
- case MYSQL_TYPE_LONG:
- {
- if (((Field_num*)field)->unsigned_flag)
- {
- storeRC = field->store(*(int64*)bufPtr, TRUE);
- }
- else
- {
- storeRC = field->store(*(int32*)bufPtr, FALSE);
- }
- }
- break;
- case MYSQL_TYPE_FLOAT:
- {
- storeRC = field->store(*(float*)bufPtr);
- }
- break;
- case MYSQL_TYPE_DOUBLE:
- {
- storeRC = field->store(*(double*)bufPtr);
- }
- break;
- case MYSQL_TYPE_LONGLONG:
- {
- char temp[23];
- if (((Field_num*)field)->unsigned_flag)
- {
- temp[0] = (bcdGet(bufPtr, 21) == 0xD ? '-' : ' ');
- int strPos=1;
- int bcdPos=0;
-
- for (;bcdPos <= 20; bcdPos++, strPos++)
- {
- temp[strPos] = bcdGet(bufPtr, bcdPos) + '0';
- }
-
- temp[strPos] = 0;
-
- storeRC = field->store(temp, strPos, &my_charset_latin1);
- }
- else
- {
- storeRC = field->store(*(int64*)bufPtr, FALSE);
- }
- }
- break;
- case MYSQL_TYPE_INT24:
- {
- storeRC = field->store(*(int32*)bufPtr, ((Field_num*)field)->unsigned_flag);
- }
- break;
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_NEWDATE:
- {
- longlong value= a4toi_ebcdic((uchar*)bufPtr) * 10000 +
- a2toi_ebcdic((uchar*)bufPtr+5) * 100 +
- a2toi_ebcdic((uchar*)bufPtr+8);
-
- if (cachedZeroDateOption == SUBSTITUTE_0001_01_01 &&
- value == (10000 + 100 + 1))
- value = 0;
-
- storeRC = field->store(value);
- }
- break;
- case MYSQL_TYPE_TIME:
- {
- if (db2Field.getType() == QMY_TIME)
- {
- longlong value= a2toi_ebcdic((uchar*)bufPtr) * 10000 +
- a2toi_ebcdic((uchar*)bufPtr+3) * 100 +
- a2toi_ebcdic((uchar*)bufPtr+6);
-
- storeRC = field->store(value);
- }
- else
- storeRC = field->store(*((int32*)bufPtr));
- }
- break;
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_DATETIME:
- {
- longlong value= (a4toi_ebcdic((uchar*)bufPtr) * 10000 +
- a2toi_ebcdic((uchar*)bufPtr+5) * 100 +
- a2toi_ebcdic((uchar*)bufPtr+8)) * 1000000LL +
- (a2toi_ebcdic((uchar*)bufPtr+11) * 10000 +
- a2toi_ebcdic((uchar*)bufPtr+14) * 100 +
- a2toi_ebcdic((uchar*)bufPtr+17));
-
- if (cachedZeroDateOption == SUBSTITUTE_0001_01_01 &&
- value == (10000 + 100 + 1) * 1000000LL)
- value = 0;
-
- storeRC = field->store(value);
- }
- break;
- case MYSQL_TYPE_YEAR:
- {
- if (db2Field.getType() == QMY_CHAR)
- {
- storeRC = field->store(bufPtr, 4, &my_charset_bin);
- }
- else
- {
- storeRC = field->store(*((uint16*)bufPtr));
- }
- }
- break;
- case MYSQL_TYPE_BIT:
- {
- uint64 temp= 0;
- int bytesToCopy= db2Field.getByteLengthInRecord();
- memcpy(((char*)&temp) + (sizeof(temp) - bytesToCopy), bufPtr, bytesToCopy);
- storeRC = field->store(temp, TRUE);
- }
- break;
- case MYSQL_TYPE_VARCHAR:
- case MYSQL_TYPE_STRING:
- case MYSQL_TYPE_BLOB:
- {
- if (field->real_type() == MYSQL_TYPE_ENUM ||
- field->real_type() == MYSQL_TYPE_SET)
- {
- storeRC = field->store(*(int64*)bufPtr);
- }
- else
- {
-
- const char* dataToStore = NULL;
- uint32 bytesToStore = 0;
- CHARSET_INFO* fieldCharSet = field->charset();
- switch(db2Field.getType())
- {
- case QMY_CHAR:
- case QMY_GRAPHIC:
- {
- bytesToStore = db2Field.getByteLengthInRecord();
- if (bytesToStore == 0)
- bytesToStore = 1;
- dataToStore = bufPtr;
- }
- break;
- case QMY_VARCHAR:
- {
- bytesToStore = *(uint16*)bufPtr;
- dataToStore = bufPtr+sizeof(uint16);
- }
- break;
- case QMY_VARGRAPHIC:
- {
- /* For VARGRAPHIC, convert the number of double-byte characters
- to the number of bytes. */
- bytesToStore = (*(uint16*)bufPtr)*2;
- dataToStore = bufPtr+sizeof(uint16);
- }
- break;
- case QMY_DBCLOB:
- case QMY_BLOBCLOB:
- {
- DB2LobField* lobField = (DB2LobField* )(bufPtr + db2Field.calcBlobPad());
- bytesToStore = lobField->length * (db2Field.getType() == QMY_DBCLOB ? 2 : 1);
- dataToStore = (char*)blobReadBuffers->getBufferPtr(field->field_index);
- }
- break;
-
- }
-
- if ((fieldCharSet != &my_charset_bin) && // not binary &
- (db2Field.getCCSID() != 13488) && // not UCS2 &
- (db2Field.getCCSID() != 1208))
- {
- char* temp;
- size_t db2BytesToStore;
- int rc;
- if (fieldCharSet->mbmaxlen > 1)
- {
- size_t maxDb2BytesToStore = ((bytesToStore / 2) * fieldCharSet->mbmaxlen); // Worst case for number of bytes
- temp = getCharacterConversionBuffer(field->field_index, maxDb2BytesToStore);
- rc = convertFieldChars(toMySQL, field->field_index, dataToStore, temp, bytesToStore, maxDb2BytesToStore, &db2BytesToStore);
- bytesToStore = db2BytesToStore;
- }
- else // single-byte ASCII to EBCDIC
- {
- temp = getCharacterConversionBuffer(field->field_index, bytesToStore);
- rc = convertFieldChars(toMySQL, field->field_index, dataToStore, temp, bytesToStore, bytesToStore, NULL);
- }
- if (rc)
- return (rc);
- dataToStore = temp;
- }
-
- if ((field)->flags & BLOB_FLAG)
- ((Field_blob*)(field))->set_ptr(bytesToStore, (uchar*)dataToStore);
- else
- storeRC = field->store(dataToStore, bytesToStore, &my_charset_bin);
- }
- }
- break;
- default:
- DBUG_ASSERT(0);
- break;
-
- }
-
- if (storeRC)
- {
- invalidDataFound = true;
- }
-
- return 0;
-}
diff --git a/storage/ibmdb2i/db2i_errors.cc b/storage/ibmdb2i/db2i_errors.cc
deleted file mode 100644
index dd50e40e61b..00000000000
--- a/storage/ibmdb2i/db2i_errors.cc
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#include "db2i_errors.h"
-#include "db2i_ileBridge.h"
-#include "db2i_charsetSupport.h"
-#include "mysql_priv.h"
-#include "stdarg.h"
-
-#define MAX_MSGSTRING 109
-
-/*
- The following strings are associated with errors that can be produced
- within the storage engine proper.
-*/
-static const char* engineErrors[MAX_MSGSTRING] =
-{
- {""},
- {"Error opening codeset conversion from %.64s to %.64s (errno = %d)"},
- {"Invalid %-.10s name '%-.128s'"},
- {"Unsupported move from '%-.128s' to '%-.128s' on RENAME TABLE statement"},
- {"The %-.64s character set is not supported."},
- {"Auto_increment is not allowed for a partitioned table"},
- {"Character set conversion error due to unknown encoding scheme %d"},
- {""},
- {"Table '%-.128s' was not found by the storage engine"},
- {"Could not resolve to %-.128s in library %-.10s type %-.10s (errno = %d)"},
- {"Error on _PGMCALL for program %-.10s in library %-.10s (error = %d)"},
- {"Error on _ILECALL for API '%.128s' (error = %d)"},
- {"Error in iconv() function during character set conversion (errno = %d)"},
- {"Error from Get Encoding Scheme (QTQGESP) API: %d, %d, %d"},
- {"Error from Get Related Default CCSID (QTQGRDC) API: %d, %d, %d"},
- {"Data out of range for column '%.192s'"},
- {"Schema name '%.128s' exceeds maximum length of %d characters"},
- {"Multiple collations not supported in a single index or constraint"},
- {"Sort sequence was not found"},
- {"One or more characters in column %.128s were substituted during conversion"},
- {"A decimal column exceeded the maximum precision. Data may be truncated."},
- {"Some data returned by DB2 for table %s could not be converted for MySQL"},
- {""},
- {"Column %.128s contains characters that cannot be converted"},
- {"An invalid name was specified for ibmdb2i_rdb_name."},
- {"A duplicate key was encountered for index '%.128s'"},
- {"A table with the same name exists but has incompatible column definitions."},
- {"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."},
-};
-
-/*
- The following strings are associated with errors that can be returned
- by the operating system via the QMY_* APIs. Most are very uncommon and
- indicate a bug somewhere.
-*/
-static const char* systemErrors[MAX_MSGSTRING] =
-{
- {"Thread ID is too long"},
- {"Error creating a SPACE memory object"},
- {"Error creating a FILE memory object"},
- {"Error creating a SPACE synchronization token"},
- {"Error creating a FILE synchronization token"},
- {"See message %-.7s in joblog for job %-.6s/%-.10s/%-.10s."},
- {"Error unlocking a synchronization token when closing a connection"},
- {"Invalid action specified for an 'object lock' request"},
- {"Invalid action specified for a savepoint request"},
- {"Partial keys are not supported with an ICU sort sequence"},
- {"Error retrieving an ICU sort key"},
- {"Error converting single-byte sort sequence to UCS-2"},
- {"An unsupported collation was specified"},
- {"Validation failed for referenced table of foreign key constraint"},
- {"Error extracting table for constraint information"},
- {"Error extracting referenced table for constraint information"},
- {"Invalid action specified for a 'commitment control' request"},
- {"Invalid commitment control isolation level specified on 'open' request"},
- {"Invalid file handle"},
- {" "},
- {"Invalid option specified for returning data on 'read' request"},
- {"Invalid orientation specified for 'read' request"},
- {"Invalid option type specified for 'read' request"},
- {"Invalid isolation level for starting commitment control"},
- {"Error unlocking a synchronization token in module QMYALC"},
- {"Length of space for returned format is not long enough"},
- {"SQL XA transactions are currently unsupported by this interface"},
- {"The associated QSQSRVR job was killed or ended unexpectedly."},
- {"Error unlocking a synchronization token in module QMYSEI"},
- {"Error unlocking a synchronization token in module QMYSPO"},
- {"Error converting input CCSID from short form to long form"},
- {" "},
- {"Error getting associated CCSID for CCSID conversion"},
- {"Error converting a string from one CCSID to another"},
- {"Error unlocking a synchronization token"},
- {"Error destroying a synchronization token"},
- {"Error locking a synchronization token"},
- {"Error recreating a synchronization token"},
- {"A space handle was not specified for a constraint request"},
- {"An SQL cursor was specified for a delete request"},
- {" "},
- {"Error on delete request because current UFCB for connection is not open"},
- {"An SQL cursor was specified for an object initialization request"},
- {"An SQL cursor was specified for an object override request"},
- {"A space handle was not specified for an object override request"},
- {"An SQL cursor was specified for an information request"},
- {"An SQL cursor was specified for an object lock request"},
- {"An SQL cursor was specified for an optimize request"},
- {"A data handle was not specified for a read request"},
- {"A row number handle was not specified for a read request"},
- {"A key handle was not specified for a read request"},
- {"An SQL cursor was specified for an row estimation request"},
- {"A space handle was not specified for a row estimation request"},
- {"An SQL cursor was specified for a release record request"},
- {"A statement handle was not specified for an 'execute immediate' request"},
- {"A statement handle was not specified for a 'prepare open' request"},
- {"An SQL cursor was specified for an update request"},
- {"The UFCB was not open for read"},
- {"Error on update request because current UFCB for connection is not open"},
- {"A data handle was not specified for an update request"},
- {"An SQL cursor was specified for a write request"},
- {"A data handle was not specified for a write request"},
- {"An unknown function was specified on a process request"},
- {"A share definition was not specified for an 'allocate share' request"},
- {"A share handle was not specified for an 'allocate share' request"},
- {"A use count handle was not specified for an 'allocate share' request"},
- {"A 'records per key' handle was not specified for an information request"},
- {"Error resolving LOB addresss"},
- {"Length of a LOB space is too small"},
- {"An unknown function was specified for a server request"},
- {"Object authorization failed. See message %-.7s in joblog for job %-.6s/%-.10s/%-.10s. for more information."},
- {" "},
- {"Error locking mutex on server"},
- {"Error unlocking mutex on server"},
- {"Error checking for RDB name in RDB Directory"},
- {"Error creating mutex on server"},
- {"A table with that name already exists"},
- {" "},
- {"Error unlocking mutex"},
- {"Error connecting to server job"},
- {"Error connecting to server job"},
- {" "},
- {"Function check occurred while registering parameter spaces. See joblog."},
- {" "},
- {" "},
- {"End of block"},
- {"The file has changed and might not be compatible with the MySQL table definition"},
- {"Error giving pipe to server job"},
- {"There are open object locks when attempting to deallocate"},
- {"There is no open lock"},
- {" "},
- {" "},
- {"The maximum value for the auto_increment data type was exceeded"},
- {"Error occurred closing the pipe "},
- {"Error occurred taking a descriptor for the pipe"},
- {"Error writing to pipe "},
- {"Server was interrupted "},
- {"No pipe descriptor exists for reuse "},
- {"Error occurred during an SQL prepare statement "},
- {"Error occurred during an SQL open "},
- {" "},
- {" "},
- {" "},
- {" "},
- {" "},
- {" "},
- {"An unspecified error was returned from the system."},
- {" "}
-};
-
-/**
- This function builds the text string for an error code, and substitutes
- a variable number of replacement variables into the string.
-*/
-void getErrTxt(int errCode, ...)
-{
- va_list args;
- va_start(args,errCode);
- char* buffer = db2i_ileBridge::getBridgeForThread()->getErrorStorage();
- const char* msg;
-
- if (errCode >= QMY_ERR_MIN && errCode <= QMY_ERR_SQ_OPEN)
- msg = systemErrors[errCode - QMY_ERR_MIN];
- else
- {
- DBUG_ASSERT(errCode >= DB2I_FIRST_ERR && errCode <= DB2I_LAST_ERR);
- msg = engineErrors[errCode - DB2I_FIRST_ERR];
- }
-
- (void) my_vsnprintf (buffer, MYSQL_ERRMSG_SIZE, msg, args);
- va_end(args);
- fprintf(stderr,"ibmdb2i error %d: %s\n",errCode,buffer);
- DBUG_PRINT("error", ("ibmdb2i error %d: %s",errCode,buffer));
-}
-
-static inline void trimSpace(char* str)
-{
- char* end = strchr(str, ' ');
- if (end) *end = 0;
-}
-
-
-/**
- Generate the error text specific to an API error returned by a QMY_* API.
-
- @parm errCode The error value
- @parm errInfo The structure containing the message and job identifiers.
-*/
-void reportSystemAPIError(int errCode, const Qmy_Error_output *errInfo)
-{
- if (errCode >= QMY_ERR_MIN && errCode <= QMY_ERR_SQ_OPEN)
- {
- switch(errCode)
- {
- case QMY_ERR_MSGID:
- case QMY_ERR_NOT_AUTH:
- {
- DBUG_ASSERT(errInfo);
- char jMsg[8]; // Error message ID
- char jName[11]; // Job name
- char jUser[11]; // Job user
- char jNbr[7]; // Job number
- memset(jMsg, 0, sizeof(jMsg));
- memset(jName, 0, sizeof(jMsg));
- memset(jUser, 0, sizeof(jMsg));
- memset(jMsg, 0, sizeof(jMsg));
-
- convFromEbcdic(errInfo->MsgId,jMsg,sizeof(jMsg)-1);
- convFromEbcdic(errInfo->JobName,jName,sizeof(jName)-1);
- trimSpace(jName);
- convFromEbcdic(errInfo->JobUser,jUser,sizeof(jUser)-1);
- trimSpace(jUser);
- convFromEbcdic(errInfo->JobNbr,jNbr,sizeof(jNbr)-1);
- getErrTxt(errCode,jMsg,jNbr,jUser,jName);
- }
- break;
- case QMY_ERR_RTNFMT:
- {
- getErrTxt(QMY_ERR_LVLID_MISMATCH);
- }
- break;
- default:
- getErrTxt(errCode);
- break;
- }
- }
-}
-
-
-/**
- Generate a warning for the specified error.
-*/
-void warning(THD *thd, int errCode, ...)
-{
- va_list args;
- va_start(args,errCode);
- char buffer[MYSQL_ERRMSG_SIZE];
- const char* msg;
-
- DBUG_ASSERT(errCode >= DB2I_FIRST_ERR && errCode <= DB2I_LAST_ERR);
- msg = engineErrors[errCode - DB2I_FIRST_ERR];
-
- (void) my_vsnprintf (buffer, MYSQL_ERRMSG_SIZE, msg, args);
- va_end(args);
- DBUG_PRINT("warning", ("ibmdb2i warning %d: %s",errCode,buffer));
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, errCode, buffer);
-}
-
-
diff --git a/storage/ibmdb2i/db2i_errors.h b/storage/ibmdb2i/db2i_errors.h
deleted file mode 100644
index b6dd314ef50..00000000000
--- a/storage/ibmdb2i/db2i_errors.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#ifndef DB2I_ERRORS_H
-#define DB2I_ERRORS_H
-
-#include "qmyse.h"
-class THD;
-
-/**
- @enum DB2I_errors
-
- @brief These are the errors that can be returned by the storage engine proper
- and that are specific to the engine. Refer to db2i_errors.cc for text
- descriptions of the errors.
-*/
-
-enum DB2I_errors
-{
- DB2I_FIRST_ERR = 2500,
- DB2I_ERR_ICONV_OPEN,
- DB2I_ERR_INVALID_NAME,
- DB2I_ERR_RENAME_MOVE,
- DB2I_ERR_UNSUPP_CHARSET,
- DB2I_ERR_PART_AUTOINC,
- DB2I_ERR_UNKNOWN_ENCODING,
- DB2I_ERR_RESERVED,
- DB2I_ERR_TABLE_NOT_FOUND,
- DB2I_ERR_RESOLVE_OBJ,
- DB2I_ERR_PGMCALL,
- DB2I_ERR_ILECALL,
- DB2I_ERR_ICONV,
- DB2I_ERR_QTQGESP,
- DB2I_ERR_QTQGRDC,
- DB2I_ERR_INVALID_COL_VALUE,
- DB2I_ERR_TOO_LONG_SCHEMA,
- DB2I_ERR_MIXED_COLLATIONS,
- DB2I_ERR_SRTSEQ,
- DB2I_ERR_SUB_CHARS,
- DB2I_ERR_PRECISION,
- DB2I_ERR_INVALID_DATA,
- DB2I_ERR_RESERVED2,
- DB2I_ERR_ILL_CHAR,
- DB2I_ERR_BAD_RDB_NAME,
- DB2I_ERR_UNKNOWN_IDX,
- DB2I_ERR_DISCOVERY_MISMATCH,
- DB2I_ERR_WARN_CREATE_DISCOVER,
- DB2I_ERR_WARN_COL_ATTRS,
- DB2I_LAST_ERR = DB2I_ERR_WARN_COL_ATTRS
-};
-
-void getErrTxt(int errcode, ...);
-void reportSystemAPIError(int errCode, const Qmy_Error_output *errInfo);
-void warning(THD *thd, int errCode, ...);
-
-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
diff --git a/storage/ibmdb2i/db2i_file.cc b/storage/ibmdb2i/db2i_file.cc
deleted file mode 100644
index a16aa927527..00000000000
--- a/storage/ibmdb2i/db2i_file.cc
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-
-#include "db2i_file.h"
-#include "db2i_charsetSupport.h"
-#include "db2i_collationSupport.h"
-#include "db2i_misc.h"
-#include "db2i_errors.h"
-#include "my_dir.h"
-
-db2i_table::db2i_table(const TABLE_SHARE* myTable, const char* path) :
- mysqlTable(myTable),
- db2StartId(0),
- blobFieldCount(0),
- blobFields(NULL),
- blobFieldActualSizes(NULL),
- logicalFiles(NULL),
- physicalFile(NULL),
- db2TableNameSQLAscii(NULL),
- db2LibNameSQLAscii(NULL)
-{
- char asciiLibName[MAX_DB2_SCHEMANAME_LENGTH + 1];
- getDB2LibNameFromPath(path, asciiLibName, ASCII_NATIVE);
-
- char asciiFileName[MAX_DB2_FILENAME_LENGTH + 1];
- getDB2FileNameFromPath(path, asciiFileName, ASCII_NATIVE);
-
- size_t libNameLen = strlen(asciiLibName);
- size_t fileNameLen = strlen(asciiFileName);
-
- db2LibNameEbcdic=(char *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
- &db2LibNameEbcdic, libNameLen+1,
- &db2LibNameAscii, libNameLen+1,
- &db2LibNameSQLAscii, libNameLen*2 + 1,
- &db2TableNameEbcdic, fileNameLen+1,
- &db2TableNameAscii, fileNameLen+1,
- &db2TableNameSQLAscii, fileNameLen*2 + 1,
- NullS);
-
- if (likely(db2LibNameEbcdic))
- {
- memcpy(db2LibNameAscii, asciiLibName, libNameLen);
- convertNativeToSQLName(db2LibNameAscii, db2LibNameSQLAscii);
- convToEbcdic(db2LibNameAscii, db2LibNameEbcdic, libNameLen);
- memcpy(db2TableNameAscii, asciiFileName, fileNameLen);
- convertNativeToSQLName(db2TableNameAscii, db2TableNameSQLAscii);
- convToEbcdic(db2TableNameAscii, db2TableNameEbcdic, fileNameLen);
- }
-
- conversionDefinitions[toMySQL] = NULL;
- conversionDefinitions[toDB2] = NULL;
-
- isTemporaryTable = (strstr(mysqlTable->path.str, mysql_tmpdir) == mysqlTable->path.str);
-}
-
-
-int32 db2i_table::initDB2Objects(const char* path)
-{
- uint fileObjects = 1 + mysqlTable->keys;
- ValidatedPointer<ShrDef> fileDefnSpace(sizeof(ShrDef) * fileObjects);
-
- physicalFile = new db2i_file(this);
- physicalFile->fillILEDefn(&fileDefnSpace[0], true);
-
- logicalFileCount = mysqlTable->keys;
- if (logicalFileCount > 0)
- {
- logicalFiles = new db2i_file*[logicalFileCount];
- for (int k = 0; k < logicalFileCount; k++)
- {
- logicalFiles[k] = new db2i_file(this, k);
- logicalFiles[k]->fillILEDefn(&fileDefnSpace[k+1], false);
- }
- }
-
- ValidatedPointer<FILE_HANDLE> fileDefnHandles(sizeof(FILE_HANDLE) * fileObjects);
- size_t formatSpaceLen = sizeof(format_hdr_t) + mysqlTable->fields * sizeof(DB2Field);
- formatSpace.alloc(formatSpaceLen);
-
- int rc = db2i_ileBridge::getBridgeForThread()->
- expectErrors(QMY_ERR_RTNFMT)->
- allocateFileDefn(fileDefnSpace,
- fileDefnHandles,
- fileObjects,
- db2LibNameEbcdic,
- strlen(db2LibNameEbcdic),
- formatSpace,
- formatSpaceLen);
-
- 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;
- }
-
- convFromEbcdic(((format_hdr_t*)formatSpace)->FilLvlId, fileLevelID, sizeof(fileLevelID));
-
- if (!doFileIDsMatch(path))
- {
- getErrTxt(QMY_ERR_LVLID_MISMATCH);
- return QMY_ERR_LVLID_MISMATCH;
- }
-
- physicalFile->setMasterDefnHandle(fileDefnHandles[0]);
- for (int k = 0; k < mysqlTable->keys; k++)
- {
- logicalFiles[k]->setMasterDefnHandle(fileDefnHandles[k+1]);
- }
-
- db2StartId = (uint64)(((format_hdr_t*)formatSpace)->StartIdVal);
- db2Fields = (DB2Field*)((char*)(void*)formatSpace + ((format_hdr_t*)formatSpace)->ColDefOff);
-
- uint fields = mysqlTable->fields;
- for (int i = 0; i < fields; ++i)
- {
- if (db2Field(i).isBlob())
- {
- blobFieldCount++;
- }
- }
-
- if (blobFieldCount)
- {
- blobFieldActualSizes = (uint*)my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
- &blobFieldActualSizes, blobFieldCount * sizeof(uint),
- &blobFields, blobFieldCount * sizeof(uint16),
- NullS);
-
- int b = 0;
- for (int i = 0; i < fields; ++i)
- {
- if (db2Field(i).isBlob())
- {
- blobFields[b++] = i;
- }
- }
- }
-
- my_multi_malloc(MYF(MY_WME),
- &conversionDefinitions[toMySQL], fields * sizeof(iconv_t),
- &conversionDefinitions[toDB2], fields * sizeof(iconv_t),
- NullS);
- for (int i = 0; i < fields; ++i)
- {
- conversionDefinitions[toMySQL][i] = (iconv_t)(-1);
- conversionDefinitions[toDB2][i] = (iconv_t)(-1);
- }
-
- return 0;
-}
-
-int db2i_table::fastInitForCreate(const char* path)
-{
- ValidatedPointer<ShrDef> fileDefnSpace(sizeof(ShrDef));
-
- physicalFile = new db2i_file(this);
- physicalFile->fillILEDefn(fileDefnSpace, true);
-
- ValidatedPointer<FILE_HANDLE> fileDefnHandles(sizeof(FILE_HANDLE));
-
- size_t formatSpaceLen = sizeof(format_hdr_t) +
- mysqlTable->fields * sizeof(DB2Field);
- formatSpace.alloc(formatSpaceLen);
-
- int rc = db2i_ileBridge::getBridgeForThread()->allocateFileDefn(fileDefnSpace,
- fileDefnHandles,
- 1,
- db2LibNameEbcdic,
- strlen(db2LibNameEbcdic),
- formatSpace,
- formatSpaceLen);
-
- if (rc)
- return rc;
-
- convFromEbcdic(((format_hdr_t*)formatSpace)->FilLvlId, fileLevelID, sizeof(fileLevelID));
- doFileIDsMatch(path);
-
- return 0;
-}
-
-bool db2i_table::doFileIDsMatch(const char* path)
-{
- char name_buff[FN_REFLEN];
-
- fn_format(name_buff, path, "", FID_EXT, (MY_REPLACE_EXT | MY_UNPACK_FILENAME));
-
- File fd = my_open(name_buff, O_RDONLY, MYF(0));
-
- if (fd == -1)
- {
- if (errno == ENOENT)
- {
- fd = my_create(name_buff, 0, O_WRONLY, MYF(MY_WME));
-
- if (fd == -1)
- {
- // TODO: Report errno here
- return false;
- }
- my_write(fd, (uchar*)fileLevelID, sizeof(fileLevelID), MYF(MY_WME));
- my_close(fd, MYF(0));
- return true;
- }
- else
- {
- // TODO: Report errno here
- return false;
- }
- }
-
- char diskFID[sizeof(fileLevelID)];
-
- bool match = false;
-
- if (my_read(fd, (uchar*)diskFID, sizeof(diskFID), MYF(MY_WME)) == sizeof(diskFID) &&
- (memcmp(diskFID, fileLevelID, sizeof(diskFID)) == 0))
- match = true;
-
- my_close(fd, MYF(0));
-
- return match;
-}
-
-void db2i_table::deleteAssocFiles(const char* name)
-{
- char name_buff[FN_REFLEN];
- fn_format(name_buff, name, "", FID_EXT, (MY_REPLACE_EXT | MY_UNPACK_FILENAME));
- my_delete(name_buff, MYF(0));
-}
-
-void db2i_table::renameAssocFiles(const char* from, const char* to)
-{
- rename_file_ext(from, to, FID_EXT);
-}
-
-
-db2i_table::~db2i_table()
-{
- if (blobFieldActualSizes)
- my_free(blobFieldActualSizes, MYF(0));
-
- if (conversionDefinitions[toMySQL])
- my_free(conversionDefinitions[toMySQL], MYF(0));
-
- if (logicalFiles)
- {
- for (int k = 0; k < logicalFileCount; ++k)
- {
- delete logicalFiles[k];
- }
-
- delete[] logicalFiles;
- }
- delete physicalFile;
-
- my_free(db2LibNameEbcdic, 0);
-}
-
-void db2i_table::getDB2QualifiedName(char* to)
-{
- strcat(to, getDB2LibName(ASCII_SQL));
- strcat(to, ".");
- strcat(to, getDB2TableName(ASCII_SQL));
-}
-
-
-void db2i_table::getDB2QualifiedNameFromPath(const char* path, char* to)
-{
- getDB2LibNameFromPath(path, to);
- strcat(to, ".");
- getDB2FileNameFromPath(path, strend(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)
-{
- if (strchr(in, '#') == NULL)
- {
- smartFilenameToTableName(in, out, outlen);
- return;
- }
-
- char* temp = (char*)sql_alloc(outlen);
-
- const char* part1, *part2, *part3, *part4;
- part1 = in;
- part2 = strstr(part1, "#P#");
- if (part2);
- {
- part3 = part2 + 3;
- part4 = strchr(part3, '#');
- if (!part4)
- part4 = strend(in);
- }
-
- memcpy(temp, part1, min(outlen, part2 - part1));
- temp[min(outlen-1, part2-part1)] = 0;
-
- int32 accumLen = smartFilenameToTableName(temp, out, outlen);
-
- if (part2 && (accumLen + 4 < outlen))
- {
- strcat(out, "#P#");
- accumLen += 4;
-
- memset(temp, 0, min(outlen, part2-part1));
- memcpy(temp, part3, min(outlen, part4-part3));
- temp[min(outlen-1, part4-part3)] = 0;
-
- accumLen += smartFilenameToTableName(temp, strend(out), outlen-accumLen);
-
- if (part4 && (accumLen + (strend(in) - part4 + 1) < outlen))
- {
- strcat(out, part4);
- }
- }
-}
-
-void db2i_table::getDB2LibNameFromPath(const char* path, char* lib, NameFormatFlags format)
-{
- if (strstr(path, mysql_tmpdir) == path)
- {
- strcpy(lib, DB2I_TEMP_TABLE_SCHEMA);
- }
- else
- {
- const char* c = strend(path) - 1;
- while (c > path && *c != '\\' && *c != '/')
- --c;
-
- if (c != path)
- {
- const char* dbEnd = c;
- do {
- --c;
- } while (c >= path && *c != '\\' && *c != '/');
-
- if (c >= path)
- {
- const char* dbStart = c+1;
- char fileName[FN_REFLEN];
- memcpy(fileName, dbStart, dbEnd - dbStart);
- fileName[dbEnd-dbStart] = 0;
-
- char dbName[MAX_DB2_SCHEMANAME_LENGTH+1];
- filenameToTablename(fileName, dbName , sizeof(dbName));
-
- convertMySQLNameToDB2Name(dbName, lib, sizeof(dbName), true, (format==ASCII_SQL) );
- }
- else
- DBUG_ASSERT(0); // This should never happen!
- }
- }
-}
-
-void db2i_table::getDB2FileNameFromPath(const char* path, char* file, NameFormatFlags format)
-{
- const char* fileEnd = strend(path);
- const char* c = fileEnd;
- while (c > path && *c != '\\' && *c != '/')
- --c;
-
- if (c != path)
- {
- const char* fileStart = c+1;
- char fileName[FN_REFLEN];
- memcpy(fileName, fileStart, fileEnd - fileStart);
- fileName[fileEnd - fileStart] = 0;
- char db2Name[MAX_DB2_FILENAME_LENGTH+1];
- filenameToTablename(fileName, db2Name, sizeof(db2Name));
- convertMySQLNameToDB2Name(db2Name, file, sizeof(db2Name), true, (format==ASCII_SQL) );
- }
-}
-
-// Generates the DB2 index name when given the MySQL index and table names.
-int32 db2i_table::appendQualifiedIndexFileName(const char* indexName,
- const char* tableName,
- String& to,
- NameFormatFlags format,
- enum_DB2I_INDEX_TYPE type)
-{
- char generatedName[MAX_DB2_FILENAME_LENGTH+1];
- strncpy(generatedName, indexName, DB2I_INDEX_NAME_LENGTH_TO_PRESERVE);
- generatedName[DB2I_INDEX_NAME_LENGTH_TO_PRESERVE] = 0;
- char* endOfGeneratedName;
-
- if (type == typeDefault)
- {
- strcat(generatedName, DB2I_DEFAULT_INDEX_NAME_DELIMITER);
- endOfGeneratedName = strend(generatedName);
- }
- else if (type != typeNone)
- {
- strcat(generatedName, DB2I_ADDL_INDEX_NAME_DELIMITER);
- endOfGeneratedName = strend(generatedName);
- *(endOfGeneratedName-2) = char(type);
- }
-
- uint lenWithoutFile = endOfGeneratedName - generatedName;
-
- char strippedTableName[MAX_DB2_FILENAME_LENGTH+1];
- if (format == ASCII_SQL)
- {
- strcpy(strippedTableName, tableName);
- stripExtraQuotes(strippedTableName+1, sizeof(strippedTableName));
- tableName = strippedTableName;
- }
-
- if (strlen(tableName) > (MAX_DB2_FILENAME_LENGTH-lenWithoutFile))
- return -1;
-
- strncat(generatedName,
- tableName+1,
- min(strlen(tableName), (MAX_DB2_FILENAME_LENGTH-lenWithoutFile))-2 );
-
- char finalName[MAX_DB2_FILENAME_LENGTH+1];
- convertMySQLNameToDB2Name(generatedName, finalName, sizeof(finalName), true, (format==ASCII_SQL));
- to.append(finalName);
-
- return 0;
-}
-
-
-void db2i_table::findConversionDefinition(enum_conversionDirection direction, uint16 fieldID)
-{
- getConversion(direction,
- mysqlTable->field[fieldID]->charset(),
- db2Field(fieldID).getCCSID(),
- conversionDefinitions[direction][fieldID]);
-}
-
-
-db2i_file::db2i_file(db2i_table* table) : db2Table(table)
-{
- commonCtorInit();
-
- DBUG_ASSERT(table->getMySQLTable()->table_name.length <= MAX_DB2_FILENAME_LENGTH-2);
-
- db2FileName = (char*)table->getDB2TableName(db2i_table::EBCDIC_NATIVE);
-}
-
-db2i_file::db2i_file(db2i_table* table, int index) : db2Table(table)
-{
- commonCtorInit();
-
- if ((index == table->getMySQLTable()->primary_key) && !table->isTemporary())
- {
- db2FileName = (char*)table->getDB2TableName(db2i_table::EBCDIC_NATIVE);
- }
- else
- {
- // Generate the index name (in index___table form); quote and EBCDICize it.
- String qualifiedPath;
- qualifiedPath.length(0);
-
- const char* asciiFileName = table->getDB2TableName(db2i_table::ASCII_NATIVE);
-
- db2i_table::appendQualifiedIndexFileName(table->getMySQLTable()->key_info[index].name,
- asciiFileName,
- qualifiedPath,
- db2i_table::ASCII_NATIVE,
- typeDefault);
-
- db2FileName = (char*)my_malloc(qualifiedPath.length()+1, MYF(MY_WME | MY_ZEROFILL));
- convToEbcdic(qualifiedPath.ptr(), db2FileName, qualifiedPath.length());
- }
-}
-
-void db2i_file::commonCtorInit()
-{
- masterDefn = 0;
- memset(&formats, 0, maxRowFormats*sizeof(RowFormat));
-}
-
-
-void db2i_file::fillILEDefn(ShrDef* defn, bool readInArrivalSeq)
-{
- defn->ObjNamLen = strlen(db2FileName);
- DBUG_ASSERT(defn->ObjNamLen <= sizeof(defn->ObjNam));
- memcpy(defn->ObjNam, db2FileName, defn->ObjNamLen);
- defn->ArrSeq[0] = (readInArrivalSeq ? QMY_YES : QMY_NO);
-}
-
diff --git a/storage/ibmdb2i/db2i_file.h b/storage/ibmdb2i/db2i_file.h
deleted file mode 100644
index 7b63b18c315..00000000000
--- a/storage/ibmdb2i/db2i_file.h
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#ifndef DB2I_FILE_H
-#define DB2I_FILE_H
-
-#include "db2i_global.h"
-#include "db2i_ileBridge.h"
-#include "db2i_validatedPointer.h"
-#include "db2i_iconv.h"
-#include "db2i_charsetSupport.h"
-
-const char FID_EXT[] = ".FID";
-
-class db2i_file;
-
-#pragma pack(1)
-struct DB2LobField
-{
- char reserved1;
- uint32 length;
- char reserved2[4];
- uint32 ordinal;
- ILEMemHandle dataHandle;
- char reserved3[8];
-};
-#pragma pack(pop)
-
-class DB2Field
-{
- public:
- uint16 getType() const { return *(uint16*)(&definition.ColType); }
- uint16 getByteLengthInRecord() const { return definition.ColLen; }
- uint16 getDataLengthInRecord() const
- {
- return (getType() == QMY_VARCHAR || getType() == QMY_VARGRAPHIC ? definition.ColLen - 2 : definition.ColLen);
- }
- uint16 getCCSID() const { return *(uint16*)(&definition.ColCCSID); }
- bool isBlob() const
- {
- uint16 type = getType();
- return (type == QMY_BLOBCLOB || type == QMY_DBCLOB);
- }
- uint16 getBufferOffset() const { return definition.ColBufOff; }
- uint16 calcBlobPad() const
- {
- DBUG_ASSERT(isBlob());
- return getByteLengthInRecord() - sizeof (DB2LobField);
- }
- DB2LobField* asBlobField(char* buf) const
- {
- DBUG_ASSERT(isBlob());
- return (DB2LobField*)(buf + getBufferOffset() + calcBlobPad());
- }
- private:
- col_def_t definition;
-};
-
-
-/**
- @class db2i_table
-
- @details
- This class describes the logical SQL table provided by DB2.
- It stores "table-scoped" information such as the name of the
- DB2 schema, BLOB descriptions, and the corresponding MySQL table definition.
- Only one instance exists per SQL table.
-*/
-class db2i_table
-{
- public:
- enum NameFormatFlags
- {
- ASCII_SQL,
- ASCII_NATIVE,
- EBCDIC_NATIVE
- };
-
- db2i_table(const TABLE_SHARE* myTable, const char* path = NULL);
-
- ~db2i_table();
-
- int32 initDB2Objects(const char* path);
-
- const TABLE_SHARE* getMySQLTable() const
- {
- return mysqlTable;
- }
-
- uint64 getStartId() const
- {
- return db2StartId;
- }
-
- void updateStartId(uint64 newStartId)
- {
- db2StartId = newStartId;
- }
-
- bool hasBlobs() const
- {
- return (blobFieldCount > 0);
- }
-
- uint16 getBlobCount() const
- {
- return blobFieldCount;
- }
-
- uint getBlobFieldActualSize(uint fieldIndex) const
- {
- return blobFieldActualSizes[getBlobIdFromField(fieldIndex)];
- }
-
- void updateBlobFieldActualSize(uint fieldIndex, uint32 newSize)
- {
- // It's OK that this isn't threadsafe, since this is just an advisory
- // value. If a race condition causes the lesser of two values to be stored,
- // that's OK.
- uint16 blobID = getBlobIdFromField(fieldIndex);
- DBUG_ASSERT(blobID < blobFieldCount);
-
- if (blobFieldActualSizes[blobID] < newSize)
- {
- blobFieldActualSizes[blobID] = newSize;
- }
- }
-
-
-
- const char* getDB2LibName(NameFormatFlags format = EBCDIC_NATIVE)
- {
- switch (format)
- {
- case EBCDIC_NATIVE:
- return db2LibNameEbcdic; break;
- case ASCII_NATIVE:
- return db2LibNameAscii; break;
- case ASCII_SQL:
- return db2LibNameSQLAscii; break;
- default:
- DBUG_ASSERT(0);
- }
- return NULL;
- }
-
- const char* getDB2TableName(NameFormatFlags format = EBCDIC_NATIVE) const
- {
- switch (format)
- {
- case EBCDIC_NATIVE:
- return db2TableNameEbcdic; break;
- case ASCII_NATIVE:
- return db2TableNameAscii; break;
- case ASCII_SQL:
- return db2TableNameAscii; break;
- break;
- default:
- DBUG_ASSERT(0);
- }
- return NULL;
- }
-
- DB2Field& db2Field(int fieldID) const { return db2Fields[fieldID]; }
- DB2Field& db2Field(const Field* field) const { return db2Field(field->field_index); }
-
- void processFormatSpace();
-
- void* getFormatSpace(size_t& spaceNeeded)
- {
- DBUG_ASSERT(formatSpace == NULL);
- spaceNeeded = sizeof(format_hdr_t) + mysqlTable->fields * sizeof(DB2Field);
- formatSpace.alloc(spaceNeeded);
- return (void*)formatSpace;
- }
-
- bool isTemporary() const
- {
- return isTemporaryTable;
- }
-
- void getDB2QualifiedName(char* to);
- static void getDB2LibNameFromPath(const char* path, char* lib, NameFormatFlags format=ASCII_SQL);
- static void getDB2FileNameFromPath(const char* path, char* file, NameFormatFlags format=ASCII_SQL);
- static void getDB2QualifiedNameFromPath(const char* path, char* to);
- static int32 appendQualifiedIndexFileName(const char* indexName,
- const char* tableName,
- String& to,
- NameFormatFlags format=ASCII_SQL,
- enum_DB2I_INDEX_TYPE type=typeDefault);
-
- uint16 getBlobIdFromField(uint16 fieldID) const
- {
- for (int i = 0; i < blobFieldCount; ++i)
- {
- if (blobFields[i] == fieldID)
- return i;
- }
- DBUG_ASSERT(0);
- return 0;
- }
-
- iconv_t& getConversionDefinition(enum_conversionDirection direction,
- uint16 fieldID)
- {
- if (conversionDefinitions[direction][fieldID] == (iconv_t)(-1))
- findConversionDefinition(direction, fieldID);
-
- return conversionDefinitions[direction][fieldID];
- }
-
- const db2i_file* dataFile() const
- {
- return physicalFile;
- }
-
- const db2i_file* indexFile(uint idx) const
- {
- return logicalFiles[idx];
- }
-
- const char* getFileLevelID() const
- {
- return fileLevelID;
- }
-
- static void deleteAssocFiles(const char* name);
- static void renameAssocFiles(const char* from, const char* to);
-
- int fastInitForCreate(const char* path);
- int initDiscoveredTable(const char* path);
-
- uint16* blobFields;
-
-private:
-
- void findConversionDefinition(enum_conversionDirection direction, uint16 fieldID);
- 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,
- char* output)
- {
-
- output[0] = input[0];
-
- uint o = 1;
- uint i = 1;
- do
- {
- output[o++] = input[i];
- if (input[i] == '"' && input[i+1])
- output[o++] = '"';
- } while (input[++i]);
-
- output[o] = 0; // This isn't the most user-friendly way to handle overflows,
- // but at least its safe.
- }
-
- bool doFileIDsMatch(const char* path);
-
- ValidatedPointer<format_hdr_t> formatSpace;
- DB2Field* db2Fields;
- uint64 db2StartId; // Starting value for identity column
- uint16 blobFieldCount; // Count of LOB fields in the DB2 table
- uint* blobFieldActualSizes; // Array of LOB field lengths (actual vs. allocated).
- // This is updated as LOBs are read and will contain
- // the length of the longest known LOB in that field.
- iconv_t* conversionDefinitions[2];
-
- const TABLE_SHARE* mysqlTable;
- uint16 logicalFileCount;
- char* db2LibNameEbcdic; // Quoted and in EBCDIC
- char* db2LibNameAscii;
- char* db2TableNameEbcdic;
- char* db2TableNameAscii;
- char* db2TableNameSQLAscii;
- char* db2LibNameSQLAscii;
-
- db2i_file* physicalFile;
- db2i_file** logicalFiles;
-
- bool isTemporaryTable;
- char fileLevelID[13];
-};
-
-/**
- @class db2i_file
-
- @details This class describes a file object underlaying a particular SQL
- table. Both "physical files" (data) and "logical files" (indices) are
- described by this class. Only one instance of the class exists per DB2 file
- object. The single instance is responsible for de/allocating the multiple
- handles used by the handlers.
-*/
-class db2i_file
-{
-
-public:
- struct RowFormat
- {
- uint16 readRowLen;
- uint16 readRowNullOffset;
- uint16 writeRowLen;
- uint16 writeRowNullOffset;
- char inited;
- };
-
-public:
-
- // Construct an instance for a physical file.
- db2i_file(db2i_table* table);
-
- // Construct an instance for a logical file.
- db2i_file(db2i_table* table, int index);
-
- ~db2i_file()
- {
- if (masterDefn)
- db2i_ileBridge::getBridgeForThread()->deallocateFile(masterDefn);
-
- if (db2FileName != (char*)db2Table->getDB2TableName(db2i_table::EBCDIC_NATIVE))
- my_free(db2FileName, MYF(0));
- }
-
- // This is roughly equivalent to an "open". It tells ILE to allocate a descriptor
- // for the file. The associated handle is returned to the caller.
- int allocateNewInstance(FILE_HANDLE* newHandle, ILEMemHandle inuseSpace) const
- {
- int rc;
-
- rc = db2i_ileBridge::getBridgeForThread()->allocateFileInstance(masterDefn,
- inuseSpace,
- newHandle);
-
- if (rc) *newHandle = 0;
-
- return rc;
- }
-
- // This obtains the row layout associated with a particular access intent for
- // an open instance of the file.
- int obtainRowFormat(FILE_HANDLE instanceHandle,
- char intent,
- char commitLevel,
- const RowFormat** activeFormat) const
- {
- DBUG_ENTER("db2i_file::obtainRowFormat");
- RowFormat* rowFormat;
-
- if (intent == QMY_UPDATABLE)
- rowFormat = &(formats[readWrite]);
- else if (intent == QMY_READ_ONLY)
- rowFormat = &(formats[readOnly]);
-
- if (unlikely(!rowFormat->inited))
- {
- int rc = db2i_ileBridge::getBridgeForThread()->
- initFileForIO(instanceHandle,
- intent,
- commitLevel,
- &(rowFormat->writeRowLen),
- &(rowFormat->writeRowNullOffset),
- &(rowFormat->readRowLen),
- &(rowFormat->readRowNullOffset));
- if (rc) DBUG_RETURN(rc);
- rowFormat->inited = 1;
- }
-
- *activeFormat = rowFormat;
- DBUG_RETURN(0);
- }
-
- const char* getDB2FileName() const
- {
- return db2FileName;
- }
-
- void fillILEDefn(ShrDef* defn, bool readInArrivalSeq);
-
- void setMasterDefnHandle(FILE_HANDLE handle)
- {
- masterDefn = handle;
- }
-
- FILE_HANDLE getMasterDefnHandle() const
- {
- return masterDefn;
- }
-
-private:
- enum RowFormats
- {
- readOnly = 0,
- readWrite,
- maxRowFormats
- };
-
- mutable RowFormat formats[maxRowFormats];
-
- void commonCtorInit();
-
- char* db2FileName; // Quoted and in EBCDIC
-
- db2i_table* db2Table; // The logical SQL table contained by this file.
-
- bool db2CanSort;
-
- FILE_HANDLE masterDefn;
-};
-
-
-#endif
diff --git a/storage/ibmdb2i/db2i_global.h b/storage/ibmdb2i/db2i_global.h
deleted file mode 100644
index d201fbd8124..00000000000
--- a/storage/ibmdb2i/db2i_global.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#ifndef DB2I_GLOBAL_H
-#define DB2I_GLOBAL_H
-
-#define MYSQL_SERVER 1
-
-#include "my_global.h"
-#include "my_sys.h"
-
-const uint MAX_DB2_KEY_PARTS=120;
-const int MAX_DB2_V5R4_LIBNAME_LENGTH = 10;
-const int MAX_DB2_V6R1_LIBNAME_LENGTH = 30;
-const int MAX_DB2_SCHEMANAME_LENGTH=258;
-const int MAX_DB2_FILENAME_LENGTH=258;
-const int MAX_DB2_COLNAME_LENGTH=128;
-const int MAX_DB2_SAVEPOINTNAME_LENGTH=128;
-const int MAX_DB2_QUALIFIEDNAME_LENGTH=MAX_DB2_V6R1_LIBNAME_LENGTH + 1 + MAX_DB2_FILENAME_LENGTH;
-const uint32 MAX_CHAR_LENGTH = 32765;
-const uint32 MAX_VARCHAR_LENGTH = 32739;
-const uint32 MAX_DEC_PRECISION = 63;
-const uint32 MAX_BLOB_LENGTH = 2147483646;
-const uint32 MAX_BINARY_LENGTH = MAX_CHAR_LENGTH;
-const uint32 MAX_VARBINARY_LENGTH = MAX_VARCHAR_LENGTH;
-const uint32 MAX_FULL_ALLOCATE_BLOB_LENGTH = 65536;
-const uint32 MAX_FOREIGN_LEN = 64000;
-const char* DB2I_TEMP_TABLE_SCHEMA = "QTEMP";
-const char DB2I_ADDL_INDEX_NAME_DELIMITER[5] = {'_','_','_','_','_'};
-const char DB2I_DEFAULT_INDEX_NAME_DELIMITER[3] = {'_','_','_'};
-const int DB2I_INDEX_NAME_LENGTH_TO_PRESERVE = 110;
-
-enum enum_DB2I_INDEX_TYPE
-{
- typeNone = 0,
- typeDefault = 'D',
- typeHex = 'H',
- typeAscii = 'A'
-};
-
-void* roundToQuadWordBdy(void* ptr)
-{
- return (void*)(((uint64)(ptr)+0xf) & ~0xf);
-}
-
-typedef uint64_t ILEMemHandle;
-
-struct OSVersion
-{
- uint8 v;
- uint8 r;
-};
-extern OSVersion osVersion;
-
-
-/**
- Allocate 16-byte aligned space using the MySQL heap allocator
-
- @details Many of the spaces used by the QMY_* APIS are required to be
- aligned on 16 byte boundaries. The standard system malloc will do this
- alignment by default. However, in order to use the heap debug and tracking
- features of the mysql allocator, we chose to implement an aligning wrapper
- around my_malloc. Essentially, we overallocate the storage space, find the
- first aligned address in the space, store a pointer to the true malloc
- allocation in the bytes immediately preceding the aligned address, and return
- the aligned address to the caller.
-
- @parm size The size of heap storage needed
-
- @return A 16-byte aligned pointer to the storage requested.
-*/
-void* malloc_aligned(size_t size)
-{
- char* p;
- char* base;
- base = (char*)my_malloc(size + sizeof(void*) + 15, MYF(MY_WME));
- if (likely(base))
- {
- p = (char*)roundToQuadWordBdy(base + sizeof(void*));
- char** p2 = (char**)(p - sizeof(void*));
- *p2 = base;
- }
- else
- p = NULL;
-
- return p;
-}
-
-/**
- Free a 16-byte aligned space alloced by malloc_aligned
-
- @details We know that a pointer to the true malloced storage immediately
- precedes the aligned address, so we pull that out and call my_free().
-
- @parm p A 16-byte aligned pointer generated by malloc_aligned
-*/
-void free_aligned(void* p)
-{
- if (likely(p))
- {
- my_free(*(char**)((char*)p-sizeof(void*)), MYF(0));
- }
-}
-
-#endif
diff --git a/storage/ibmdb2i/db2i_iconv.h b/storage/ibmdb2i/db2i_iconv.h
deleted file mode 100644
index 9fc6e4ed636..00000000000
--- a/storage/ibmdb2i/db2i_iconv.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-/**
- @file
-
- @brief Used to redefine iconv symbols to the optimized "myconv" ones
-*/
-
-#ifndef DB2I_ICONV_H
-#define DB2I_ICONV_H
-
-#include "db2i_myconv.h"
-#define iconv_open(A, B) myconv_open(A, B, CONVERTER_DMAP)
-#define iconv_close myconv_close
-#define iconv myconv_dmap
-#define iconv_t myconv_t
-
-#endif
diff --git a/storage/ibmdb2i/db2i_ileBridge.cc b/storage/ibmdb2i/db2i_ileBridge.cc
deleted file mode 100644
index 68ae2c2bb72..00000000000
--- a/storage/ibmdb2i/db2i_ileBridge.cc
+++ /dev/null
@@ -1,1342 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-
-#include "db2i_ileBridge.h"
-#include "my_dbug.h"
-#include "db2i_global.h"
-#include "db2i_charsetSupport.h"
-#include "db2i_errors.h"
-
-
-// static class member data
-ILEpointer* db2i_ileBridge::functionSymbols;
-db2i_ileBridge* db2i_ileBridge::globalBridge;
-#ifndef DBUG_OFF
-uint32 db2i_ileBridge::registeredPtrs;
-#endif
-
-pthread_key(IleParms*, THR_ILEPARMS);
-
-static void ileParmsDtor(void* parmsToFree)
-{
- if (parmsToFree)
- {
- free_aligned(parmsToFree);
- DBUG_PRINT("db2i_ileBridge", ("Freeing space for parms"));
- }
-}
-
-
-/**
- Convert a timestamp in ILE time format into a unix time_t
-*/
-static inline time_t convertILEtime(const ILE_time_t& input)
-{
- tm temp;
-
- temp.tm_sec = input.Second;
- temp.tm_min = input.Minute;
- temp.tm_hour = input.Hour;
- temp.tm_mday = input.Day;
- temp.tm_mon = input.Month-1;
- temp.tm_year = input.Year - 1900;
- temp.tm_isdst = -1;
-
- return mktime(&temp);
-}
-
-/**
- Allocate and intialize a new bridge structure
-*/
-db2i_ileBridge* db2i_ileBridge::createNewBridge(CONNECTION_HANDLE connID)
-{
- DBUG_PRINT("db2i_ileBridge::createNewBridge",("Building new bridge..."));
- db2i_ileBridge* newBridge = (db2i_ileBridge*)my_malloc(sizeof(db2i_ileBridge), MYF(MY_WME));
-
- if (unlikely(newBridge == NULL))
- return NULL;
-
- newBridge->stmtTxActive = false;
- newBridge->connErrText = NULL;
- newBridge->pendingLockedHandles.head = NULL;
- newBridge->cachedConnectionID = connID;
-
- return newBridge;
-}
-
-
-void db2i_ileBridge::destroyBridge(db2i_ileBridge* bridge)
-{
- bridge->freeErrorStorage();
- my_free(bridge, MYF(0));
-}
-
-
-void db2i_ileBridge::destroyBridgeForThread(const THD* thd)
-{
- void* thdData = *thd_ha_data(thd, ibmdb2i_hton);
- if (thdData != NULL)
- {
- destroyBridge((db2i_ileBridge*)thdData);
- }
-}
-
-
-void db2i_ileBridge::registerPtr(const void* ptr, ILEMemHandle* receiver)
-{
- static const arg_type_t ileSignature[] = { ARG_MEMPTR, ARG_END };
-
- if (unlikely(ptr == NULL))
- {
- *receiver = 0;
- return;
- }
-
- struct ArgList
- {
- ILEarglist_base base;
- ILEpointer ptr;
- } *arguments;
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- arguments->ptr.s.addr = (address64_t)(ptr);
-
- _ILECALL(&functionSymbols[funcRegisterSpace],
- &arguments->base,
- ileSignature,
- RESULT_INT64);
-
-#ifndef DBUG_OFF
- uint32 truncHandle = arguments->base.result.r_uint64;
- DBUG_PRINT("db2i_ileBridge::registerPtr",("Register 0x%p with handle %d", ptr, truncHandle));
- getBridgeForThread()->registeredPtrs++;
-#endif
-
- *receiver = arguments->base.result.r_uint64;
- return;
-}
-
-void db2i_ileBridge::unregisterPtr(ILEMemHandle handle)
-{
- static const arg_type_t ileSignature[] = { ARG_UINT64, ARG_END };
-
- if (unlikely(handle == NULL))
- return;
-
- struct ArgList
- {
- ILEarglist_base base;
- uint64 handle;
- } *arguments;
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- arguments->handle = (uint64)(handle);
-
- _ILECALL(&functionSymbols[funcUnregisterSpace],
- &arguments->base,
- ileSignature,
- RESULT_VOID);
-
-#ifndef DBUG_OFF
- DBUG_PRINT("db2i_ileBridge::unregisterPtr",("Unregister handle %d", (uint32)handle));
- getBridgeForThread()->registeredPtrs--;
-#endif
-}
-
-
-
-/**
- Initialize the bridge component
-
- @details Resolves srvpgm and function names of the APIs. If this fails,
- the approrpiate operating system support (PTFs) is probably not installed.
-
- WARNING:
- Must be called before any other functions in this class are used!!!!
- Can only be called by a single thread!
-*/
-int db2i_ileBridge::setup()
-{
- static const char funcNames[db2i_ileBridge::funcListEnd][32] =
- {
- {"QmyRegisterParameterSpaces"},
- {"QmyRegisterSpace"},
- {"QmyUnregisterSpace"},
- {"QmyProcessRequest"}
- };
-
- DBUG_ENTER("db2i_ileBridge::setup");
-
- int actmark = _ILELOAD("QSYS/QMYSE", ILELOAD_LIBOBJ);
- if ( actmark == -1 )
- {
- DBUG_PRINT("db2i_ileBridge::setup", ("srvpgm activation failed"));
- DBUG_RETURN(1);
- }
-
- functionSymbols = (ILEpointer*)malloc_aligned(sizeof(ILEpointer) * db2i_ileBridge::funcListEnd);
-
- for (int i = 0; i < db2i_ileBridge::funcListEnd; i++)
- {
- if (_ILESYM(&functionSymbols[i], actmark, funcNames[i]) == -1)
- {
- DBUG_PRINT("db2i_ileBridge::setup",
- ("resolve of %s failed", funcNames[i]));
- DBUG_RETURN(errno);
- }
- }
-
- pthread_key_create(&THR_ILEPARMS, &ileParmsDtor);
-
-#ifndef DBUG_OFF
- registeredPtrs = 0;
-#endif
-
- globalBridge = createNewBridge(0);
-
- DBUG_RETURN(0);
-}
-
-/**
- Cleanup any resources before shutting down plug-in
-*/
-void db2i_ileBridge::takedown()
-{
- if (globalBridge)
- destroyBridge(globalBridge);
- free_aligned(functionSymbols);
-}
-
-/**
- Call off to QmyProcessRequest to perform the API that the caller prepared
-*/
-inline int32 db2i_ileBridge::doIt()
-{
- static const arg_type_t ileSignature[] = {ARG_END};
-
- struct ArgList
- {
- ILEarglist_base base;
- } *arguments;
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- _ILECALL(&functionSymbols[funcProcessRequest],
- &arguments->base,
- ileSignature,
- RESULT_INT32);
-
- return translateErrorCode(arguments->base.result.s_int32.r_int32);
-}
-
-/**
- Call off to QmyProcessRequest to perform the API that the caller prepared and
- log any errors that may occur.
-*/
-inline int32 db2i_ileBridge::doItWithLog()
-{
- int32 rc = doIt();
-
- if (unlikely(rc))
- {
- // Only report errors that we weren't expecting
- if (rc != tacitErrors[0] &&
- rc != tacitErrors[1] &&
- rc != QMY_ERR_END_OF_BLOCK)
- reportSystemAPIError(rc, (Qmy_Error_output_t*)parms()->outParms);
- }
- memset(tacitErrors, 0, sizeof(tacitErrors));
-
- return rc;
-}
-
-
-/**
- Interface to QMY_ALLOCATE_SHARE API
-
- See QMY_ALLOCATE_SHARE documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::allocateFileDefn(ILEMemHandle definitionSpace,
- ILEMemHandle handleSpace,
- uint16 fileCount,
- const char* schemaName,
- uint16 schemaNameLength,
- ILEMemHandle formatSpace,
- uint32 formatSpaceLen)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
-
- IleParms* parmBlock = parms();
- Qmy_MAOS0100 *input = (Qmy_MAOS0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_ALLOCATE_SHARE;
- input->ShrDefSpcHnd = definitionSpace;
- input->ShrHndSpcHnd = handleSpace;
- input->ShrDefCnt = fileCount;
- input->FmtSpcHnd = formatSpace;
- input->FmtSpcLen = formatSpaceLen;
-
- if (schemaNameLength > sizeof(input->SchNam))
- {
- // This should never happen!
- DBUG_ASSERT(0);
- return HA_ERR_GENERIC;
- }
-
- memcpy(input->SchNam, schemaName, schemaNameLength);
- input->SchNamLen = schemaNameLength;
-
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_ALLOCATE_INSTANCE API
-
- See QMY_ALLOCATE_INSTANCE documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::allocateFileInstance(FILE_HANDLE defnHandle,
- ILEMemHandle inuseSpace,
- FILE_HANDLE* instance)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
-
- IleParms* parmBlock = parms();
- Qmy_MAOI0100 *input = (Qmy_MAOI0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_ALLOCATE_INSTANCE;
- input->ShrHnd = defnHandle;
- input->CnnHnd = cachedConnectionID;
- input->UseSpcHnd = inuseSpace;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MAOI0100_output* output = (Qmy_MAOI0100_output*)parmBlock->outParms;
- DBUG_ASSERT(instance);
- *instance = output->ObjHnd;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_DEALLOCATE_OBJECT API
-
- See QMY_DEALLOCATE_OBJECT documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::deallocateFile(FILE_HANDLE rfileHandle,
- bool postDropTable)
-{
- IleParms* parmBlock = parms();
- Qmy_MDLC0100 *input = (Qmy_MDLC0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DEALLOCATE_OBJECT;
- input->ObjHnd = rfileHandle;
- input->ObjDrp[0] = (postDropTable ? QMY_YES : QMY_NO);
-
- DBUG_PRINT("db2i_ileBridge::deallocateFile", ("Deallocating %d", (uint32)rfileHandle));
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_OBJECT_INITIALIZATION API
-
- See QMY_OBJECT_INITIALIZATION documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::initFileForIO(FILE_HANDLE rfileHandle,
- char accessIntent,
- char commitLevel,
- uint16* inRecSize,
- uint16* inRecNullOffset,
- uint16* outRecSize,
- uint16* outRecNullOffset)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MOIX0100 *input = (Qmy_MOIX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_OBJECT_INITIALIZATION;
- input->CmtLvl[0] = commitLevel;
- input->Intent[0] = accessIntent;
- input->ObjHnd = rfileHandle;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MOIX0100_output* output = (Qmy_MOIX0100_output*)parmBlock->outParms;
- *inRecSize = output->InNxtRowOff;
- *inRecNullOffset = output->InNullMapOff;
- *outRecSize = output->OutNxtRowOff;
- *outRecNullOffset = output->OutNullMapOff;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_READ_ROWS API for reading a row with a specific RRN.
-
- See QMY_READ_ROWS documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::readByRRN(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- uint32 inRRN,
- char accessIntent,
- char commitLevel)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MRDX0100 *input = (Qmy_MRDX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_READ_ROWS;
- input->CmtLvl[0] = commitLevel;
- input->ObjHnd = rfileHandle;
- input->Intent[0] = accessIntent;
- input->OutSpcHnd = (uint64)buf;
- input->RelRowNbr = inRRN;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- if (rc == QMY_ERR_END_OF_BLOCK)
- {
- rc = 0;
- DBUG_PRINT("db2i_ileBridge::readByRRN", ("End of block signalled"));
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_WRITE_ROWS API.
-
- See QMY_WRITE_ROWS documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::writeRows(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- char commitLevel,
- int64* outIdVal,
- bool* outIdGen,
- uint32* dupKeyRRN,
- char** dupKeyName,
- uint32* dupKeyNameLen,
- uint32* outIdIncrement)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MWRT0100 *input = (Qmy_MWRT0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_WRITE_ROWS;
- input->CmtLvl[0] = commitLevel;
-
- input->ObjHnd = rfileHandle;
- input->InSpcHnd = (uint64_t) buf;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- Qmy_MWRT0100_output_t* output = (Qmy_MWRT0100_output_t*)parmBlock->outParms;
- if (likely(rc == 0 || rc == HA_ERR_FOUND_DUPP_KEY))
- {
- DBUG_ASSERT(dupKeyRRN && dupKeyName && dupKeyNameLen && outIdGen && outIdIncrement && outIdVal);
- *dupKeyRRN = output->DupRRN;
- *dupKeyName = (char*)parmBlock->outParms + output->DupObjNamOff;
- *dupKeyNameLen = output->DupObjNamLen;
- *outIdGen = (output->NewIdGen[0] == QMY_YES ? TRUE : FALSE);
- if (*outIdGen == TRUE)
- {
- *outIdIncrement = output->IdIncrement;
- *outIdVal = output->NewIdVal;
- }
- }
-
- return rc;
-
-}
-
-/**
- Interface to QMY_EXECUTE_IMMEDIATE API.
-
- See QMY_EXECUTE_IMMEDIATE documentation for more information about
- parameters and return codes.
-*/
-uint32 db2i_ileBridge::execSQL(const char* statement,
- uint32 statementCount,
- uint8 commitLevel,
- bool autoCreateSchema,
- bool dropSchema,
- bool noCommit,
- FILE_HANDLE fileHandle)
-
-{
- IleParms* parmBlock = parms();
- Qmy_MSEI0100 *input = (Qmy_MSEI0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_EXECUTE_IMMEDIATE;
-
- registerPtr(statement, &input->StmtsSpcHnd);
-
- input->NbrStmts = statementCount;
- *(uint16*)(&input->StmtCCSID) = 850;
- input->AutoCrtSchema[0] = (autoCreateSchema == TRUE ? QMY_YES : QMY_NO);
- input->DropSchema[0] = (dropSchema == TRUE ? QMY_YES : QMY_NO);
- input->CmtLvl[0] = commitLevel;
- if ((commitLevel == QMY_NONE && statementCount == 1) || noCommit)
- {
- input->CmtBefore[0] = QMY_NO;
- input->CmtAfter[0] = QMY_NO;
- }
- else
- {
- input->CmtBefore[0] = QMY_YES;
- input->CmtAfter[0] = QMY_YES;
- }
- input->CnnHnd = current_thd->thread_id;
- input->ObjHnd = fileHandle;
-
- int32 rc = doItWithLog();
-
- unregisterPtr(input->StmtsSpcHnd);
-
- return rc;
-}
-
-/**
- Interface to QMY_PREPARE_OPEN_CURSOR API.
-
- See QMY_PREPARE_OPEN_CURSOR documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::prepOpen(const char* statement,
- FILE_HANDLE* rfileHandle,
- uint32* recLength)
-{
- IleParms* parmBlock = parms();
- Qmy_MSPO0100 *input = (Qmy_MSPO0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_PREPARE_OPEN_CURSOR;
-
- registerPtr(statement, &input->StmtsSpcHnd );
- *(uint16*)(&input->StmtCCSID) = 850;
- input->CnnHnd = current_thd->thread_id;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MSPO0100_output* output = (Qmy_MSPO0100_output*)parmBlock->outParms;
- *rfileHandle = output->ObjHnd;
- *recLength = max(output->InNxtRowOff, output->OutNxtRowOff);
- }
-
-
- unregisterPtr(input->StmtsSpcHnd);
-
- return rc;
-}
-
-
-/**
- Interface to QMY_DELETE_ROW API.
-
- See QMY_DELETE_ROW documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::deleteRow(FILE_HANDLE rfileHandle,
- uint32 rrn)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MDLT0100 *input = (Qmy_MDLT0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DELETE_ROW;
- input->ObjHnd = rfileHandle;
- input->RelRowNbr = rrn;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_UPDATE_ROW API.
-
- See QMY_UPDATE_ROW documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::updateRow(FILE_HANDLE rfileHandle,
- uint32 rrn,
- ILEMemHandle buf,
- uint32* dupKeyRRN,
- char** dupKeyName,
- uint32* dupKeyNameLen)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MUPD0100 *input = (Qmy_MUPD0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_UPDATE_ROW;
- input->ObjHnd = rfileHandle;
- input->InSpcHnd = (uint64)buf;
- input->RelRowNbr = rrn;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- if (rc == HA_ERR_FOUND_DUPP_KEY)
- {
- Qmy_MUPD0100_output* output = (Qmy_MUPD0100_output*)parmBlock->outParms;
- DBUG_ASSERT(dupKeyRRN && dupKeyName && dupKeyNameLen);
- *dupKeyRRN = output->DupRRN;
- *dupKeyName = (char*)parmBlock->outParms + output->DupObjNamOff;
- *dupKeyNameLen = output->DupObjNamLen;
- }
-
- return rc;
-}
-
-/**
- Interface to QMY_DESCRIBE_RANGE API.
-
- See QMY_DESCRIBE_RANGE documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::recordsInRange(FILE_HANDLE defnHandle,
- ILEMemHandle inSpc,
- uint32 inKeyCnt,
- uint32 inLiteralCnt,
- uint32 inBoundsOff,
- uint32 inLitDefOff,
- uint32 inLiteralsOff,
- uint32 inCutoff,
- uint32 inSpcLen,
- uint16 inEndByte,
- uint64* outRecCnt,
- uint16* outRtnCode)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
-
- IleParms* parmBlock = parms();
- Qmy_MDRG0100 *input = (Qmy_MDRG0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DESCRIBE_RANGE;
- input->ShrHnd = defnHandle;
- input->SpcHnd = (uint64)inSpc;
- input->KeyCnt = inKeyCnt;
- input->LiteralCnt = inLiteralCnt;
- input->BoundsOff = inBoundsOff;
- input->LitDefOff = inLitDefOff;
- input->LiteralsOff = inLiteralsOff;
- input->Cutoff = inCutoff;
- input->SpcLen = inSpcLen;
- input->EndByte = inEndByte;
- input->CnnHnd = cachedConnectionID;
-
- int rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MDRG0100_output* output = (Qmy_MDRG0100_output*)parmBlock->outParms;
- DBUG_ASSERT(outRecCnt && outRtnCode);
- *outRecCnt = output->RecCnt;
- *outRtnCode = output->RtnCode;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_RELEASE_ROW API.
-
- See QMY_RELEASE_ROW documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::rrlslck(FILE_HANDLE rfileHandle, char accessIntent)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
-
- IleParms* parmBlock = parms();
- Qmy_MRRX0100 *input = (Qmy_MRRX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_RELEASE_ROW;
-
- input->ObjHnd = rfileHandle;
- input->CnnHnd = cachedConnectionID;
- input->Intent[0] = accessIntent;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-/**
- Interface to QMY_LOCK_OBJECT API.
-
- See QMY_LOCK_OBJECT documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::lockObj(FILE_HANDLE defnHandle,
- uint64 lockVal,
- char lockAction,
- char lockType,
- char lockTimeout)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MOLX0100 *input = (Qmy_MOLX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_LOCK_OBJECT;
- input->ShrHnd = defnHandle;
- input->LckTimeoutVal = lockVal;
- input->Action[0] = lockAction;
- input->LckTyp[0] = lockType;
- input->LckTimeout[0] = lockTimeout;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-/**
- Interface to QMY_DESCRIBE_CONSTRAINTS API.
-
- See QMY_DESCRIBE_CONSTRAINTS documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::constraints(FILE_HANDLE defnHandle,
- ILEMemHandle inSpc,
- uint32 inSpcLen,
- uint32* outLen,
- uint32* outCnt)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MDCT0100 *input = (Qmy_MDCT0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DESCRIBE_CONSTRAINTS;
- input->ShrHnd = defnHandle;
- input->CstSpcHnd = (uint64)inSpc;
- input->CstSpcLen = inSpcLen;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MDCT0100_output* output = (Qmy_MDCT0100_output*)parmBlock->outParms;
- DBUG_ASSERT(outLen && outCnt);
- *outLen = output->NeededLen;
- *outCnt = output->CstCnt;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_REORGANIZE_TABLE API.
-
- See QMY_REORGANIZE_TABLE documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::optimizeTable(FILE_HANDLE defnHandle)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MRGX0100 *input = (Qmy_MRGX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_REORGANIZE_TABLE;
- input->ShrHnd = defnHandle;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_PROCESS_COMMITMENT_CONTROL API.
-
- See QMY_PROCESS_COMMITMENT_CONTROL documentation for more information about
- parameters and return codes.
-*/
-int32 db2i_ileBridge::commitmentControl(uint8 function)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MCCX0100 *input = (Qmy_MCCX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_PROCESS_COMMITMENT_CONTROL;
- input->Function[0] = function;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_PROCESS_SAVEPOINT API.
-
- See QMY_PROCESS_SAVEPOINT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::savepoint(uint8 function,
- const char* savepointName)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- DBUG_PRINT("db2i_ileBridge::savepoint",("%d %s", (uint32)function, savepointName));
-
- IleParms* parmBlock = parms();
- Qmy_MSPX0100 *input = (Qmy_MSPX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- char* savPtNam = (char*)(input+1);
-
- input->Format = QMY_PROCESS_SAVEPOINT;
-
- if (strlen(savepointName) > MAX_DB2_SAVEPOINTNAME_LENGTH)
- {
- DBUG_ASSERT(0);
- return HA_ERR_GENERIC;
- }
- strcpy(savPtNam, savepointName);
-
- input->Function[0] = function;
- input->SavPtNamOff = savPtNam - (char*)(input);
- input->SavPtNamLen = strlen(savepointName);
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-static ILEMemHandle traceSpcHandle;
-/**
- Do initialization for the QMY_* APIs.
-
- @parm aspName The name of the relational database to use for all
- connections.
-
- @return 0 if successful; error otherwise
-*/
-int32 db2i_ileBridge::initILE(const char* aspName,
- uint16* traceCtlPtr)
-{
- // 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
- // we get a complaint about leaked memory on server shutdown.
- int32 rc;
- char inParms[db2i_ileBridge_MAX_INPARM_SIZE];
- char outParms[db2i_ileBridge_MAX_OUTPARM_SIZE];
- if (rc = registerParmSpace(inParms, outParms))
- {
- reportSystemAPIError(rc, NULL);
- return rc;
- }
-
- registerPtr(traceCtlPtr, &traceSpcHandle);
-
- struct ParmBlock
- {
- Qmy_MINI0100 parms;
- } *parmBlock = (ParmBlock*)inParms;
-
- memset(inParms, 0, sizeof(ParmBlock));
-
- parmBlock->parms.Format = QMY_INITIALIZATION;
-
- char paddedName[18];
- if (strlen(aspName) > sizeof(paddedName))
- {
- getErrTxt(DB2I_ERR_BAD_RDB_NAME);
- return DB2I_ERR_BAD_RDB_NAME;
- }
-
- memset(paddedName, ' ', sizeof(paddedName));
- memcpy(paddedName, aspName, strlen(aspName));
- convToEbcdic(paddedName, parmBlock->parms.RDBName, strlen(paddedName));
-
- parmBlock->parms.RDBNamLen = strlen(paddedName);
- parmBlock->parms.TrcSpcHnd = traceSpcHandle;
-
- rc = doIt();
-
- if (rc)
- {
- reportSystemAPIError(rc, (Qmy_Error_output_t*)outParms);
- }
-
- return rc;
-}
-
-/**
- Signal to the QMY_ APIs to perform any cleanup they need to do.
-*/
-int32 db2i_ileBridge::exitILE()
-{
- IleParms* parmBlock = parms();
- Qmy_MCLN0100 *input = (Qmy_MCLN0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_CLEANUP;
-
- int32 rc = doIt();
-
- if (rc)
- {
- reportSystemAPIError(rc, (Qmy_Error_output_t*)parmBlock->outParms);
- }
-
- unregisterPtr(traceSpcHandle);
-
- DBUG_PRINT("db2i_ileBridge::exitILE", ("Registered ptrs remaining: %d", registeredPtrs));
-#ifndef DBUG_OFF
- if (registeredPtrs != 0)
- printf("Oh no! IBMDB2I left some pointers registered. Count was %d.\n", registeredPtrs);
-#endif
-
- // This is needed to prevent SAFE_MALLOC from complaining at process termination.
- my_pthread_setspecific_ptr(THR_ILEPARMS, NULL);
- free_aligned(parmBlock);
-
- return rc;
-
-}
-
-
-/**
- Designate the specified addresses as parameter passing buffers.
-
- @parm in Input to the API will go here; format is defined by the individual API
- @parm out Output from the API will be; format is defined by the individual API
-
- @return 0 if success; error otherwise
-*/
-int db2i_ileBridge::registerParmSpace(char* in, char* out)
-{
- static const arg_type_t ileSignature[] = { ARG_MEMPTR, ARG_MEMPTR, ARG_END };
-
- struct ArgList
- {
- ILEarglist_base base;
- ILEpointer input;
- ILEpointer output;
- } *arguments;
-
- char argBuf[sizeof(ArgList)+15];
- arguments = (ArgList*)roundToQuadWordBdy(argBuf);
-
- arguments->input.s.addr = (address64_t)(in);
- arguments->output.s.addr = (address64_t)(out);
-
- _ILECALL(&functionSymbols[funcRegisterParameterSpaces],
- &arguments->base,
- ileSignature,
- RESULT_INT32);
-
- return arguments->base.result.s_int32.r_int32;
-}
-
-
-/**
- Interface to QMY_OBJECT_OVERRIDE API.
-
- See QMY_OBJECT_OVERRIDE documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::objectOverride(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- uint32 recordWidth)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MOOX0100 *input = (Qmy_MOOX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_OBJECT_OVERRIDE;
- input->ObjHnd = rfileHandle;
- input->OutSpcHnd = (uint64)buf;
- input->NxtRowOff = recordWidth;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-/**
- Interface to QMY_DESCRIBE_OBJECT API for obtaining table stats.
-
- See QMY_DESCRIBE_OBJECT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::retrieveTableInfo(FILE_HANDLE defnHandle,
- uint16 dataRequested,
- ha_statistics& stats,
- ILEMemHandle inSpc)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MDSO0100 *input = (Qmy_MDSO0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DESCRIBE_OBJECT;
- input->ShrHnd = defnHandle;
- input->CnnHnd = cachedConnectionID;
-
- if (dataRequested & objLength)
- input->RtnObjLen[0] = QMY_YES;
- if (dataRequested & rowCount)
- input->RtnRowCnt[0] = QMY_YES;
- if (dataRequested & deletedRowCount)
- input->RtnDltRowCnt[0] = QMY_YES;
- if (dataRequested & rowsPerKey)
- {
- input->RowKeyHnd = (uint64)inSpc;
- input->RtnRowKey[0] = QMY_YES;
- }
- if (dataRequested & meanRowLen)
- input->RtnMeanRowLen[0] = QMY_YES;
- if (dataRequested & lastModTime)
- input->RtnModTim[0] = QMY_YES;
- if (dataRequested & createTime)
- input->RtnCrtTim[0] = QMY_YES;
- if (dataRequested & ioCount)
- input->RtnEstIoCnt[0] = QMY_YES;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MDSO0100_output* output = (Qmy_MDSO0100_output*)parmBlock->outParms;
- if (dataRequested & objLength)
- stats.data_file_length = output->ObjLen;
- if (dataRequested & rowCount)
- stats.records= output->RowCnt;
- if (dataRequested & deletedRowCount)
- stats.deleted = output->DltRowCnt;
- if (dataRequested & meanRowLen)
- stats.mean_rec_length = output->MeanRowLen;
- if (dataRequested & lastModTime)
- stats.update_time = convertILEtime(output->ModTim);
- if (dataRequested & createTime)
- stats.create_time = convertILEtime(output->CrtTim);
- if (dataRequested & ioCount)
- stats.data_file_length = output->EstIoCnt;
- }
-
- return rc;
-}
-
-/**
- Interface to QMY_DESCRIBE_OBJECT API for finding index size.
-
- See QMY_DESCRIBE_OBJECT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::retrieveIndexInfo(FILE_HANDLE defnHandle,
- uint64* outPageCnt)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MDSO0100 *input = (Qmy_MDSO0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_DESCRIBE_OBJECT;
- input->ShrHnd = defnHandle;
- input->CnnHnd = cachedConnectionID;
- input->RtnPageCnt[0] = QMY_YES;
-
- int32 rc = doItWithLog();
-
- if (likely(rc == 0))
- {
- Qmy_MDSO0100_output* output = (Qmy_MDSO0100_output*)parmBlock->outParms;
- *outPageCnt = output->PageCnt;
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_CLOSE_CONNECTION API
-
- See QMY_CLOSE_CONNECTION documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::closeConnection(CONNECTION_HANDLE conn)
-{
- IleParms* parmBlock = parms();
- Qmy_MCCN0100 *input = (Qmy_MCCN0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_CLOSE_CONNECTION;
- input->CnnHnd = conn;
-
- int32 rc = doItWithLog();
-
- return rc;
-}
-
-
-/**
- Interface to QMY_INTERRUPT API
-
- See QMY_INTERRUPT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::readInterrupt(FILE_HANDLE fileHandle)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MINT0100 *input = (Qmy_MINT0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_INTERRUPT;
- input->CnnHnd = cachedConnectionID;
- input->ObjHnd = fileHandle;
-
- int32 rc = doItWithLog();
-
- if (rc == QMY_ERR_END_OF_BLOCK)
- {
- rc = 0;
- DBUG_PRINT("db2i_ileBridge::readInterrupt", ("End of block signalled"));
- }
-
- return rc;
-}
-
-/**
- Interface to QMY_READ_ROWS API
-
- See QMY_READ_ROWS documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::read(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- char accessIntent,
- char commitLevel,
- char orientation,
- bool asyncRead,
- ILEMemHandle rrn,
- ILEMemHandle key,
- uint32 keylen,
- uint16 keyParts,
- int pipeFD)
-{
- DBUG_ASSERT(cachedStateIsCoherent());
- IleParms* parmBlock = parms();
- Qmy_MRDX0100 *input = (Qmy_MRDX0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_READ_ROWS;
- input->CmtLvl[0] = commitLevel;
-
- input->ObjHnd = rfileHandle;
- input->Intent[0] = accessIntent;
- input->OutSpcHnd = (uint64)buf;
- input->OutRRNSpcHnd = (uint64)rrn;
- input->RtnData[0] = QMY_RETURN_DATA;
-
- if (key)
- {
- input->KeySpcHnd = (uint64)key;
- input->KeyColsLen = keylen;
- input->KeyColsNbr = keyParts;
- }
-
- input->Async[0] = (asyncRead ? QMY_YES : QMY_NO);
- input->PipeDesc = pipeFD;
- input->Orientation[0] = orientation;
- input->CnnHnd = cachedConnectionID;
-
- int32 rc = doItWithLog();
-
- // QMY_ERR_END_OF_BLOCK is informational only, so we ignore it.
- if (rc == QMY_ERR_END_OF_BLOCK)
- {
- rc = 0;
- DBUG_PRINT("db2i_ileBridge::read", ("End of block signalled"));
- }
-
- return rc;
-}
-
-
-/**
- Interface to QMY_QUIESCE_OBJECT API
-
- See QMY_QUIESCE_OBJECT documentation for more information about parameters and
- return codes.
-*/
-int32 db2i_ileBridge::quiesceFileInstance(FILE_HANDLE rfileHandle)
-{
- IleParms* parmBlock = parms();
- Qmy_MQSC0100 *input = (Qmy_MQSC0100*)&(parmBlock->inParms);
- memset(input, 0, sizeof(*input));
-
- input->Format = QMY_QUIESCE_OBJECT;
- input->ObjHnd = rfileHandle;
-
- int32 rc = doItWithLog();
-
-#ifndef DBUG_OFF
- if (unlikely(rc))
- {
- DBUG_ASSERT(0);
- }
-#endif
-
- return rc;
-}
-
-void db2i_ileBridge::PreservedHandleList::add(const char* newname, FILE_HANDLE newhandle, IBMDB2I_SHARE* share)
-{
- NameHandlePair *newPair = (NameHandlePair*)my_malloc(sizeof(NameHandlePair), MYF(MY_WME));
-
- newPair->next = head;
- head = newPair;
-
- strcpy(newPair->name, newname);
- newPair->handle = newhandle;
- newPair->share = share;
- DBUG_PRINT("db2i_ileBridge", ("Added handle %d for %s", uint32(newhandle), newname));
-}
-
-
-FILE_HANDLE db2i_ileBridge::PreservedHandleList::findAndRemove(const char* fileName, IBMDB2I_SHARE** share)
-{
- NameHandlePair* current = head;
- NameHandlePair* prev = NULL;
-
- while (current)
- {
- NameHandlePair* next = current->next;
- if (strcmp(fileName, current->name) == 0)
- {
- FILE_HANDLE tmp = current->handle;
- *share = current->share;
- if (prev)
- prev->next = next;
- if (current == head)
- head = next;
- my_free(current, MYF(0));
- DBUG_PRINT("db2i_ileBridge", ("Found handle %d for %s", uint32(tmp), fileName));
- return tmp;
- }
- prev = current;
- current = next;
- }
-
- return 0;
-}
-
-
-IleParms* db2i_ileBridge::initParmsForThread()
-{
-
- IleParms* p = (IleParms*)malloc_aligned(sizeof(IleParms));
- DBUG_ASSERT((uint64)(&(p->outParms))% 16 == 0); // Guarantee that outParms are aligned correctly
-
- if (likely(p))
- {
- int32 rc = registerParmSpace((p->inParms), (p->outParms));
- if (likely(rc == 0))
- {
- my_pthread_setspecific_ptr(THR_ILEPARMS, p);
- DBUG_PRINT("db2i_ileBridge", ("Inited space for parms"));
- return p;
- }
- else
- reportSystemAPIError(rc, NULL);
- }
-
- return NULL;
-}
-
diff --git a/storage/ibmdb2i/db2i_ileBridge.h b/storage/ibmdb2i/db2i_ileBridge.h
deleted file mode 100644
index 10b9820d983..00000000000
--- a/storage/ibmdb2i/db2i_ileBridge.h
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#ifndef DB2I_ILEBRIDGE_H
-#define DB2I_ILEBRIDGE_H
-
-#include "db2i_global.h"
-#include "mysql_priv.h"
-#include "as400_types.h"
-#include "as400_protos.h"
-#include "qmyse.h"
-#include "db2i_errors.h"
-
-typedef uint64_t FILE_HANDLE;
-typedef my_thread_id CONNECTION_HANDLE;
-const char SAVEPOINT_NAME[] = {0xD4,0xE2,0xD7,0xC9,0xD5,0xE3,0xC5,0xD9,0xD5,0x0};
-const uint32 TACIT_ERRORS_SIZE=2;
-
-enum db2i_InfoRequestSpec
-{
- objLength = 1,
- rowCount = 2,
- deletedRowCount = 4,
- rowsPerKey = 8,
- meanRowLen = 16,
- lastModTime = 32,
- createTime = 64,
- ioCount = 128
-};
-
-extern handlerton *ibmdb2i_hton;
-struct IBMDB2I_SHARE;
-
-const uint32 db2i_ileBridge_MAX_INPARM_SIZE = 512;
-const uint32 db2i_ileBridge_MAX_OUTPARM_SIZE = 512;
-
-extern pthread_key(IleParms*, THR_ILEPARMS);
-struct IleParms
-{
- char inParms[db2i_ileBridge_MAX_INPARM_SIZE];
- char outParms[db2i_ileBridge_MAX_OUTPARM_SIZE];
-};
-
-/**
- @class db2i_ileBridge
-
- Implements a connection-based interface to the QMY_* APIs
-
- @details Each client connection that touches an IBMDB2I table has a "bridge"
- associated with it. This bridge is constructed on first use and provides a
- more C-like interface to the APIs. As well, it is reponsible for tracking
- connection scoped information such as statement transaction state and error
- message text. The bridge is destroyed when the connection ends.
-*/
-class db2i_ileBridge
-{
- enum ileFuncs
- {
- funcRegisterParameterSpaces,
- funcRegisterSpace,
- funcUnregisterSpace,
- funcProcessRequest,
- funcListEnd
- };
-
- static db2i_ileBridge* globalBridge;
-public:
-
-
- static int setup();
- static void takedown();
-
- /**
- Obtain a pointer to the bridge for the current connection.
-
- If a MySQL client connection is on the stack, we get the associated brideg.
- Otherwise, we use the globalBridge.
- */
- static db2i_ileBridge* getBridgeForThread()
- {
- THD* thd = current_thd;
- if (likely(thd))
- return getBridgeForThread(thd);
-
- return globalBridge;
- }
-
- /**
- Obtain a pointer to the bridge for the specified connection.
-
- If a bridge exists already, we return it immediately. Otherwise, prepare
- a new bridge for the connection.
- */
- static db2i_ileBridge* getBridgeForThread(const THD* thd)
- {
- void* thdData = *thd_ha_data(thd, ibmdb2i_hton);
- if (likely(thdData != NULL))
- return (db2i_ileBridge*)(thdData);
-
- db2i_ileBridge* newBridge = createNewBridge(thd->thread_id);
- *thd_ha_data(thd, ibmdb2i_hton) = (void*)newBridge;
- return newBridge;
- }
-
- static void destroyBridgeForThread(const THD* thd);
- static void registerPtr(const void* ptr, ILEMemHandle* receiver);
- static void unregisterPtr(ILEMemHandle handle);
- int32 allocateFileDefn(ILEMemHandle definitionSpace,
- ILEMemHandle handleSpace,
- uint16 fileCount,
- const char* schemaName,
- uint16 schemaNameLength,
- ILEMemHandle formatSpace,
- uint32 formatSpaceLen);
- int32 allocateFileInstance(FILE_HANDLE defnHandle,
- ILEMemHandle inuseSpace,
- FILE_HANDLE* instance);
- int32 deallocateFile(FILE_HANDLE fileHandle,
- bool postDropTable=FALSE);
- int32 read(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- char accessIntent,
- char commitLevel,
- char orientation,
- bool asyncRead = FALSE,
- ILEMemHandle rrn = 0,
- ILEMemHandle key = 0,
- uint32 keylen = 0,
- uint16 keyParts = 0,
- int pipeFD = -1);
- int32 readByRRN(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- uint32 inRRN,
- char accessIntent,
- char commitLevel);
- int32 writeRows(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- char commitLevel,
- int64* outIdVal,
- bool* outIdGen,
- uint32* dupKeyRRN,
- char** dupKeyName,
- uint32* dupKeyNameLen,
- uint32* outIdIncrement);
- uint32 execSQL(const char* statement,
- uint32 statementCount,
- uint8 commitLevel,
- bool autoCreateSchema = FALSE,
- bool dropSchema = FALSE,
- bool noCommit = FALSE,
- FILE_HANDLE fileHandle = 0);
- int32 prepOpen(const char* statement,
- FILE_HANDLE* rfileHandle,
- uint32* recLength);
- int32 deleteRow(FILE_HANDLE rfileHandle,
- uint32 rrn);
- int32 updateRow(FILE_HANDLE rfileHandle,
- uint32 rrn,
- ILEMemHandle buf,
- uint32* dupKeyRRN,
- char** dupKeyName,
- uint32* dupKeyNameLen);
- int32 commitmentControl(uint8 function);
- int32 savepoint(uint8 function,
- const char* savepointName);
- int32 recordsInRange(FILE_HANDLE rfileHandle,
- ILEMemHandle inSpc,
- uint32 inKeyCnt,
- uint32 inLiteralCnt,
- uint32 inBoundsOff,
- uint32 inLitDefOff,
- uint32 inLiteralsOff,
- uint32 inCutoff,
- uint32 inSpcLen,
- uint16 inEndByte,
- uint64* outRecCnt,
- uint16* outRtnCode);
- int32 rrlslck(FILE_HANDLE rfileHandle,
- char accessIntent);
- int32 lockObj(FILE_HANDLE rfileHandle,
- uint64 inTimeoutVal,
- char inAction,
- char inLockType,
- char inTimeout);
- int32 constraints(FILE_HANDLE rfileHandle,
- ILEMemHandle inSpc,
- uint32 inSpcLen,
- uint32* outLen,
- uint32* outCnt);
- int32 optimizeTable(FILE_HANDLE rfileHandle);
- static int32 initILE(const char* aspName,
- uint16* traceCtlPtr);
- int32 initFileForIO(FILE_HANDLE rfileHandle,
- char accessIntent,
- char commitLevel,
- uint16* inRecSize,
- uint16* inRecNullOffset,
- uint16* outRecSize,
- uint16* outRecNullOffset);
- int32 readInterrupt(FILE_HANDLE fileHandle);
- static int32 exitILE();
-
- int32 objectOverride(FILE_HANDLE rfileHandle,
- ILEMemHandle buf,
- uint32 recordWidth = 0);
-
- int32 retrieveTableInfo(FILE_HANDLE rfileHandle,
- uint16 dataRequested,
- ha_statistics& stats,
- ILEMemHandle inSpc = NULL);
-
- int32 retrieveIndexInfo(FILE_HANDLE rfileHandle,
- uint64* outPageCnt);
-
- int32 closeConnection(CONNECTION_HANDLE conn);
- int32 quiesceFileInstance(FILE_HANDLE rfileHandle);
-
- /**
- Mark the beginning of a "statement transaction"
-
- @detail MySQL "statement transactions" (see sql/handler.cc) are implemented
- as DB2 savepoints having a predefined name.
-
- @return 0 if successful; error otherwise
- */
- uint32 beginStmtTx()
- {
- DBUG_ENTER("db2i_ileBridge::beginStmtTx");
- if (stmtTxActive)
- DBUG_RETURN(0);
-
- stmtTxActive = true;
-
- DBUG_RETURN(savepoint(QMY_SET_SAVEPOINT, SAVEPOINT_NAME));
- }
-
- /**
- Commit a "statement transaction"
-
- @return 0 if successful; error otherwise
- */
- uint32 commitStmtTx()
- {
- DBUG_ENTER("db2i_ileBridge::commitStmtTx");
- DBUG_ASSERT(stmtTxActive);
- stmtTxActive = false;
- DBUG_RETURN(savepoint(QMY_RELEASE_SAVEPOINT, SAVEPOINT_NAME));
- }
-
- /**
- Roll back a "statement transaction"
-
- @return 0 if successful; error otherwise
- */
- uint32 rollbackStmtTx()
- {
- DBUG_ENTER("db2i_ileBridge::rollbackStmtTx");
- DBUG_ASSERT(stmtTxActive);
- stmtTxActive = false;
- DBUG_RETURN(savepoint(QMY_ROLLBACK_SAVEPOINT, SAVEPOINT_NAME));
- }
-
-
- /**
- Provide storage for generating error messages.
-
- This storage must persist until the error message is retrieved from the
- handler instance. It is for this reason that we associate it with the bridge.
-
- @return Pointer to heap storage of MYSQL_ERRMSG_SIZE bytes
- */
- char* getErrorStorage()
- {
- if (!connErrText)
- {
- connErrText = (char*)my_malloc(MYSQL_ERRMSG_SIZE, MYF(MY_WME));
- if (connErrText) connErrText[0] = 0;
- }
-
- return connErrText;
- }
-
- /**
- Free storage for generating error messages.
- */
- void freeErrorStorage()
- {
- if (likely(connErrText))
- {
- my_free(connErrText, MYF(0));
- connErrText = NULL;
- }
- }
-
-
- /**
- Store a file handle for later retrieval.
-
- If deallocateFile encounters a lock when trying to perform its operation,
- the file remains allocated but must be deallocated later. This function
- provides a way for the connection to "remember" that this deallocation is
- still needed.
-
- @param newname The name of the file to be added
- @param newhandle The handle associated with newname
-
- */
- void preserveHandle(const char* newname, FILE_HANDLE newhandle, IBMDB2I_SHARE* share)
- {
- pendingLockedHandles.add(newname, newhandle, share);
- }
-
- /**
- Retrieve a file handle stored by preserveHandle().
-
- @param name The name of the file to be retrieved.
-
- @return The handle associated with name
- */
- FILE_HANDLE findAndRemovePreservedHandle(const char* name, IBMDB2I_SHARE** share)
- {
- FILE_HANDLE hdl = pendingLockedHandles.findAndRemove(name, share);
- return hdl;
- }
-
- /**
- Indicate which error messages should be suppressed on the next API call
-
- These functions are useful for ensuring that the provided error numbers
- are returned if a failure occurs but do not cause a spurious error message
- to be returned.
-
- @return A pointer to this instance
- */
- db2i_ileBridge* expectErrors(int32 er1)
- {
- tacitErrors[0]=er1;
- return this;
- }
-
- db2i_ileBridge* expectErrors(int32 er1, int32 er2)
- {
- tacitErrors[0]=er1;
- tacitErrors[1]=er2;
- return this;
- }
-
- /**
- Obtain the IBM i system message that accompanied the last API failure.
-
- @return A pointer to the 7 character message ID.
- */
- static const char* getErrorMsgID()
- {
- return ((Qmy_Error_output_t*)parms()->outParms)->MsgId;
- }
-
- /**
- Convert an API error code into the equivalent MySQL error code (if any)
-
- @param rc The QMYSE API error code
-
- @return If an equivalent exists, the MySQL error code; else rc
- */
- static int32 translateErrorCode(int32 rc)
- {
- if (likely(rc == 0))
- return 0;
-
- switch (rc)
- {
- case QMY_ERR_KEY_NOT_FOUND:
- return HA_ERR_KEY_NOT_FOUND;
- case QMY_ERR_DUP_KEY:
- return HA_ERR_FOUND_DUPP_KEY;
- case QMY_ERR_END_OF_FILE:
- return HA_ERR_END_OF_FILE;
- case QMY_ERR_LOCK_TIMEOUT:
- return HA_ERR_LOCK_WAIT_TIMEOUT;
- case QMY_ERR_CST_VIOLATION:
- return HA_ERR_NO_REFERENCED_ROW;
- case QMY_ERR_TABLE_NOT_FOUND:
- return HA_ERR_NO_SUCH_TABLE;
- case QMY_ERR_NON_UNIQUE_KEY:
- 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;
- }
-
-private:
-
- static db2i_ileBridge* createNewBridge(CONNECTION_HANDLE connID);
- static void destroyBridge(db2i_ileBridge* bridge);
- static int registerParmSpace(char* in, char* out);
- static int32 doIt();
- int32 doItWithLog();
-
- static _ILEpointer *functionSymbols; ///< Array of ILE function pointers
- CONNECTION_HANDLE cachedConnectionID; ///< The associated connection
- bool stmtTxActive; ///< Inside statement transaction
- char *connErrText; ///< Storage for error message
- int32 tacitErrors[TACIT_ERRORS_SIZE]; ///< List of errors to be suppressed
-
- static IleParms* initParmsForThread();
-
- /**
- Get space for passing parameters to the QMY_* APIs
-
- @details A fixed-length parameter passing space is associated with each
- pthread. This space is allocated and registered by initParmsForThread()
- the first time a pthread works with a bridge. The space is cached away
- and remains available until the pthread ends. It became necessary to
- disassociate the parameter space from the bridge in order to support
- future enhancements to MySQL that sever the one-to-one relationship between
- pthreads and user connections. The QMY_* APIs scope a registered parameter
- space to the thread that executes the register operation.
- */
- static IleParms* parms()
- {
- IleParms* p = my_pthread_getspecific_ptr(IleParms*, THR_ILEPARMS);
- if (likely(p))
- return p;
-
- return initParmsForThread();
- }
-
- class PreservedHandleList
- {
- friend db2i_ileBridge* db2i_ileBridge::createNewBridge(CONNECTION_HANDLE);
- public:
- void add(const char* newname, FILE_HANDLE newhandle, IBMDB2I_SHARE* share);
- FILE_HANDLE findAndRemove(const char* fileName, IBMDB2I_SHARE** share);
-
- private:
- struct NameHandlePair
- {
- char name[FN_REFLEN];
- FILE_HANDLE handle;
- IBMDB2I_SHARE* share;
- NameHandlePair* next;
- }* head;
- } pendingLockedHandles;
-
-
-#ifndef DBUG_OFF
- bool cachedStateIsCoherent()
- {
- return (current_thd->thread_id == cachedConnectionID);
- }
-
- friend void db2i_ileBridge::unregisterPtr(ILEMemHandle);
- friend void db2i_ileBridge::registerPtr(const void*, ILEMemHandle*);
- static uint32 registeredPtrs;
-#endif
-};
-
-
-
-#endif
diff --git a/storage/ibmdb2i/db2i_ioBuffers.cc b/storage/ibmdb2i/db2i_ioBuffers.cc
deleted file mode 100644
index 9525a6e34b5..00000000000
--- a/storage/ibmdb2i/db2i_ioBuffers.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#include "db2i_ioBuffers.h"
-
-/**
- Request another block of rows
-
- Request the next set of rows from DB2. This must only be called after
- newReadRequest().
-
- @param orientation The direction to use when reading through the table.
-*/
-void IOAsyncReadBuffer::loadNewRows(char orientation)
-{
- rewind();
- maxRows() = rowsToBlock;
-
- DBUG_PRINT("db2i_ioBuffers::loadNewRows", ("Requesting %d rows, async = %d", rowsToBlock, readIsAsync));
-
- rc = getBridge()->expectErrors(QMY_ERR_END_OF_BLOCK, QMY_ERR_LOB_SPACE_TOO_SMALL)
- ->read(file,
- ptr(),
- accessIntent,
- commitLevel,
- orientation,
- readIsAsync,
- rrnList,
- 0,
- 0,
- 0);
-
- DBUG_PRINT("db2i_ioBuffers::loadNewRows", ("recordsRead: %d, rc: %d", (uint32)rowCount(), rc));
-
-
- *releaseRowNeeded = true;
-
- if (rc == QMY_ERR_END_OF_BLOCK)
- {
- // This is really just an informational error, so we ignore it.
- rc = 0;
- DBUG_PRINT("db2i_ioBuffers::loadNewRows", ("End of block signalled"));
- }
- else if (rc == QMY_ERR_END_OF_FILE)
- {
- // If we reach EOF or end-of-key, DB2 guarantees that no rows will be locked.
- rc = HA_ERR_END_OF_FILE;
- *releaseRowNeeded = false;
- }
- else if (rc == QMY_ERR_KEY_NOT_FOUND)
- {
- rc = HA_ERR_KEY_NOT_FOUND;
- *releaseRowNeeded = false;
- }
-
- if (rc) closePipe();
-}
-
-
-/**
- Empty the message pipe to prepare for another read.
-*/
-void IOAsyncReadBuffer::drainPipe()
-{
- DBUG_ASSERT(pipeState == PendingFullBufferMsg);
- PipeRpy_t msg[32];
- int bytes;
- PipeRpy_t* lastMsg;
- while ((bytes = read(msgPipe, msg, sizeof(msg))) > 0)
- {
- DBUG_PRINT("db2i_ioBuffers::drainPipe",("Pipe returned %d bytes", bytes));
- lastMsg = &msg[bytes / (sizeof(msg[0]))-1];
- if (lastMsg->CumRowCnt == maxRows() ||
- lastMsg->RtnCod != 0)
- {
- pipeState = ConsumedFullBufferMsg;
- break;
- }
-
- }
- DBUG_PRINT("db2i_ioBuffers::drainPipe",("rc = %d, rows = %d, max = %d", lastMsg->RtnCod, lastMsg->CumRowCnt, (uint32)maxRows()));
-}
-
-
-/**
- Poll the message pipe for async read messages
-
- Only valid in async
-
- @param orientation The direction to use when reading through the table.
-*/
-void IOAsyncReadBuffer::pollNextRow(char orientation)
-{
- DBUG_ASSERT(readIsAsync);
-
- // Handle the case in which the buffer is full.
- if (rowCount() == maxRows())
- {
- // If we haven't read to the end, exit here.
- if (readCursor < rowCount())
- return;
-
- if (pipeState == PendingFullBufferMsg)
- drainPipe();
- if (pipeState == ConsumedFullBufferMsg)
- loadNewRows(orientation);
- }
-
- if (!rc)
- {
- PipeRpy_t* lastMsg = NULL;
- while (true)
- {
- PipeRpy_t msg[32];
- int bytes = read(msgPipe, msg, sizeof(msg));
- DBUG_PRINT("db2i_ioBuffers::pollNextRow",("Pipe returned %d bytes", bytes));
-
- if (unlikely(bytes < 0))
- {
- DBUG_PRINT("db2i_ioBuffers::pollNextRow", ("Error"));
- rc = errno;
- break;
- }
- else if (bytes == 0)
- break;
-
- DBUG_ASSERT(bytes % sizeof(msg[0]) == 0);
- lastMsg = &msg[bytes / (sizeof(msg[0]))-1];
-
- if (lastMsg->RtnCod || (lastMsg->CumRowCnt == usedRows()))
- {
- rc = lastMsg->RtnCod;
- break;
- }
- }
-
- *releaseRowNeeded = true;
-
- if (rc == QMY_ERR_END_OF_BLOCK)
- rc = 0;
- else if (rc == QMY_ERR_END_OF_FILE)
- {
- // If we reach EOF or end-of-key, DB2 guarantees that no rows will be locked.
- rc = HA_ERR_END_OF_FILE;
- *releaseRowNeeded = false;
- }
- else if (rc == QMY_ERR_KEY_NOT_FOUND)
- {
- rc = HA_ERR_KEY_NOT_FOUND;
- *releaseRowNeeded = false;
- }
-
- if (lastMsg)
- DBUG_PRINT("db2i_ioBuffers::pollNextRow", ("Good data: rc=%d; rows=%d; usedRows=%d", lastMsg->RtnCod, lastMsg->CumRowCnt, (uint32)usedRows()));
- if (lastMsg && likely(!rc))
- {
- if (lastMsg->CumRowCnt < maxRows())
- pipeState = PendingFullBufferMsg;
- else
- pipeState = ConsumedFullBufferMsg;
-
- DBUG_ASSERT(lastMsg->CumRowCnt <= usedRows());
-
- }
- DBUG_ASSERT(rowCount() <= getRowCapacity());
- }
- DBUG_PRINT("db2i_ioBuffers::pollNextRow", ("filledRows: %d, rc: %d", rowCount(), rc));
- if (rc) closePipe();
-}
-
-
-/**
- Prepare for the destruction of the row buffer storage.
-*/
-void IOAsyncReadBuffer::prepForFree()
-{
- interruptRead();
- rewind();
- IORowBuffer::prepForFree();
-}
-
-
-/**
- Initialize the newly allocated storage.
-
- @param sizeChanged Indicates whether the storage capacity is being changed.
-*/
-void IOAsyncReadBuffer::initAfterAllocate(bool sizeChanged)
-{
- rewind();
-
- if (sizeChanged || ((void*)rrnList == NULL))
- rrnList.realloc(getRowCapacity() * sizeof(uint32));
-}
-
-
-/**
- Send an initial read request
-
- @param infile The file (table/index) being read from
- @param orientation The orientation to use for this read request
- @param rowsToBuffer The number of rows to request each time
- @param useAsync Whether reads should be performed asynchronously.
- @param key The key to use (if any)
- @param keyLength The length of key (if any)
- @param keyParts The number of columns in the key (if any)
-
-*/
-void IOAsyncReadBuffer::newReadRequest(FILE_HANDLE infile,
- char orientation,
- uint32 rowsToBuffer,
- bool useAsync,
- ILEMemHandle key,
- int keyLength,
- int keyParts)
-{
- DBUG_ENTER("db2i_ioBuffers::newReadRequest");
- DBUG_ASSERT(rowsToBuffer <= getRowCapacity());
-#ifndef DBUG_OFF
- if (readCursor < rowCount())
- DBUG_PRINT("PERF:",("Wasting %d buffered rows!\n", rowCount() - readCursor));
-#endif
-
- int fildes[2];
- int ileDescriptor = QMY_REUSE;
-
- interruptRead();
-
- if (likely(useAsync))
- {
- if (rowsToBuffer == 1)
- {
- // Async provides little or no benefit for single row reads, so we turn it off
- DBUG_PRINT("db2i_ioBuffers::newReadRequest", ("Disabling async"));
- useAsync = false;
- }
- else
- {
- rc = pipe(fildes);
- if (rc) DBUG_VOID_RETURN;
-
- // Translate the pipe write descriptor into the equivalent ILE descriptor
- rc = fstatx(fildes[1], (struct stat*)&ileDescriptor, sizeof(ileDescriptor), STX_XPFFD_PASE);
- if (rc)
- {
- close(fildes[0]);
- close(fildes[1]);
- DBUG_VOID_RETURN;
- }
- pipeState = Untouched;
- msgPipe = fildes[0];
-
- DBUG_PRINT("db2i_ioBuffers::newReadRequest", ("Opened pipe %d", fildes[0]));
- }
- }
-
- file = infile;
- readIsAsync = useAsync;
- rowsToBlock = rowsToBuffer;
-
- rewind();
- maxRows() = 1;
- rc = getBridge()->expectErrors(QMY_ERR_END_OF_BLOCK, QMY_ERR_LOB_SPACE_TOO_SMALL)
- ->read(file,
- ptr(),
- accessIntent,
- commitLevel,
- orientation,
- useAsync,
- rrnList,
- key,
- keyLength,
- keyParts,
- ileDescriptor);
-
- // Having shared the pipe with ILE, we relinquish our claim on the write end
- // of the pipe.
- if (useAsync)
- close(fildes[1]);
-
- // If we reach EOF or end-of-key, DB2 guarantees that no rows will be locked.
- if (rc == QMY_ERR_END_OF_FILE)
- {
- rc = HA_ERR_END_OF_FILE;
- *releaseRowNeeded = false;
- }
- else if (rc == QMY_ERR_KEY_NOT_FOUND)
- {
- if (rowCount())
- rc = HA_ERR_END_OF_FILE;
- else
- rc = HA_ERR_KEY_NOT_FOUND;
- *releaseRowNeeded = false;
- }
- else
- *releaseRowNeeded = true;
-
- DBUG_VOID_RETURN;
-}
diff --git a/storage/ibmdb2i/db2i_ioBuffers.h b/storage/ibmdb2i/db2i_ioBuffers.h
deleted file mode 100644
index 350d854f055..00000000000
--- a/storage/ibmdb2i/db2i_ioBuffers.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-/**
- @file db2i_ioBuffers.h
-
- @brief Buffer classes used for interacting with QMYSE read/write buffers.
-
-*/
-
-
-#include "db2i_validatedPointer.h"
-#include "mysql_priv.h"
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <as400_types.h>
-
-// Needed for compilers which do not include fstatx in standard headers.
-extern "C" int fstatx(int, struct stat *, int, int);
-
-/**
- Basic row buffer
-
- Provides the basic structure and methods needed for communicating
- with QMYSE I/O APIs.
-
- @details All QMYSE I/O apis use a buffer that is structured as two integer
- row counts (max and used) and storage for some number of rows. The row counts
- are both input and output for the API, and their usage depends on the
- particular API invoked. This class encapsulates that buffer definition.
-*/
-class IORowBuffer
-{
- public:
- IORowBuffer() : allocSize(0), rowLength(0) {;}
- ~IORowBuffer() { freeBuf(); }
- ValidatedPointer<char>& ptr() { return data; }
-
- /**
- Sets up the buffer to hold the size indicated.
-
- @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
- */
- void allocBuf(uint32 rowLen, uint16 nullMapOffset, uint32 size)
- {
- nullOffset = nullMapOffset;
- uint32 newSize = size + sizeof(BufferHdr_t);
- // If the internal structure of the row is changing, we need to
- // remember this and notify the subclasses via initAfterAllocate();
- bool formatChanged = ((size/rowLen) != rowCapacity);
-
- if (newSize > allocSize)
- {
- this->freeBuf();
- data.alloc(newSize);
- if (likely((void*)data))
- allocSize = newSize;
- }
-
- if (likely((void*)data))
- {
- DBUG_ASSERT((uint64)(void*)data % 16 == 0);
- rowLength = rowLen;
- rowCapacity = size / rowLength;
- initAfterAllocate(formatChanged);
- }
- else
- {
- allocSize = 0;
- rowCapacity = 0;
- }
-
- DBUG_PRINT("db2i_ioBuffers::allocBuf",("rowCapacity = %d", rowCapacity));
- }
-
- void zeroBuf()
- {
- memset(data, 0, allocSize);
- }
-
- void freeBuf()
- {
- if (likely(allocSize))
- {
- prepForFree();
- DBUG_PRINT("IORowBuffer::freeBuf",("Freeing 0x%p", (char*)data));
- data.dealloc();
- }
- }
-
- char* getRowN(uint32 n)
- {
- if (unlikely(n >= getRowCapacity()))
- return NULL;
- return (char*)data + sizeof(BufferHdr_t) + (rowLength * n);
- };
-
- uint32 getRowCapacity() const {return rowCapacity;}
- uint32 getRowNullOffset() const {return nullOffset;}
- uint32 getRowLength() const {return rowLength;}
-
- protected:
- /**
- Called prior to freeing buffer storage so that subclasses can do
- any required cleanup
- */
- virtual void prepForFree()
- {
- allocSize = 0;
- rowCapacity = 0;
- }
-
- /**
- Called after buffer storage so that subclasses can do any required setup.
- */
- virtual void initAfterAllocate(bool sizeChanged) { return;}
-
- ValidatedPointer<char> data;
- uint32 allocSize;
- uint32 rowCapacity;
- uint32 rowLength;
- uint16 nullOffset;
- uint32& usedRows() const { return ((BufferHdr_t*)(char*)data)->UsedRowCnt; }
- uint32& maxRows() const {return ((BufferHdr_t*)(char*)data)->MaxRowCnt; }
-};
-
-
-/**
- Write buffer
-
- Implements methods for inserting data into a row buffer for use with the
- QMY_WRITE and QMY_UPDATE APIs.
-
- @details The max row count defines how many rows are in the buffer. The used
- row count is updated by QMYSE to indicate how many rows have been
- successfully written.
-*/
-class IOWriteBuffer : public IORowBuffer
-{
- public:
- bool endOfBuffer() const {return (maxRows() == getRowCapacity());}
-
- char* addRow()
- {
- return getRowN(maxRows()++);
- }
-
- void resetAfterWrite()
- {
- maxRows() = 0;
- }
-
- void deleteRow()
- {
- --maxRows();
- }
-
- uint32 rowCount() const {return maxRows();}
-
- uint32 rowsWritten() const {return usedRows()-1;}
-
- private:
- void initAfterAllocate(bool sizeChanged) {maxRows() = 0; usedRows() = 0;}
-};
-
-
-/**
- Read buffer
-
- Implements methods for reading data from and managing a row buffer for use
- with the QMY_READ APIs. This is primarily for use with metainformation queries.
-*/
-class IOReadBuffer : public IORowBuffer
-{
- public:
-
- IOReadBuffer() {;}
- IOReadBuffer(uint32 rows, uint32 rowLength)
- {
- allocBuf(rows, 0, rows * rowLength);
- maxRows() = rows;
- }
-
- uint32 rowCount() {return usedRows();}
- void setRowsToProcess(uint32 rows) { maxRows() = rows; }
-};
-
-
-/**
- Read buffer
-
- Implements methods for reading data from and managing a row buffer for use
- with the QMY_READ APIs.
-
- @details This class supports both sync and async read modes. The max row
- count defines the number of rows that are requested to be read. The used row
- count defines how many rows have been read. Sync mode is reasonably
- straightforward, but async mode has a complex system of communicating with
- QMYSE that is optimized for low latency. In async mode, the used row count is
- updated continuously by QMYSE as rows are read. At the same time, messages are
- sent to the associated pipe indicating that a row has been read. As long as
- the internal read cursor lags behind the used row count, the pipe is never
- consulted. But if the internal read cursor "catches up to" the used row count,
- then we block on the pipe until we find a message indicating that a new row
- has been read or that an error has occurred.
-*/
-class IOAsyncReadBuffer : public IOReadBuffer
-{
- public:
- IOAsyncReadBuffer() :
- file(0), readIsAsync(false), msgPipe(QMY_REUSE), bridge(NULL)
- {
- }
-
- ~IOAsyncReadBuffer()
- {
- interruptRead();
- rrnList.dealloc();
- }
-
-
- /**
- Signal read operation complete
-
- Indicates that the storage engine requires no more data from the table.
- Must be called between calls to newReadRequest().
- */
- void endRead()
- {
-#ifndef DBUG_OFF
- if (readCursor < rowCount())
- DBUG_PRINT("PERF:",("Wasting %d buffered rows!\n", rowCount() - readCursor));
-#endif
- interruptRead();
-
- file = 0;
- bridge = NULL;
- }
-
- /**
- Update data that may change on each read operation
- */
- void update(char newAccessIntent,
- bool* newReleaseRowNeeded,
- char commitLvl)
- {
- accessIntent = newAccessIntent;
- releaseRowNeeded = newReleaseRowNeeded;
- commitLevel = commitLvl;
- }
-
- /**
- Read the next row in the table.
-
- Return a pointer to the next row in the table, where "next" is defined
- by the orientation.
-
- @param orientaton
- @param[out] rrn The relative record number of the row returned. Not reliable
- if NULL is returned by this function.
-
- @return Pointer to the row. Null if no more rows are available or an error
- occurred.
- */
- char* readNextRow(char orientation, uint32& rrn)
- {
- DBUG_PRINT("db2i_ioBuffers::readNextRow", ("readCursor: %d, filledRows: %d, rc: %d", readCursor, rowCount(), rc));
-
- while (readCursor >= rowCount() && !rc)
- {
- if (!readIsAsync)
- loadNewRows(orientation);
- else
- pollNextRow(orientation);
- }
-
- if (readCursor >= rowCount())
- return NULL;
-
- rrn = rrnList[readCursor];
- return getRowN(readCursor++);
- }
-
- /**
- Retrieve the return code generated by the last operation.
-
- @return The return code, translated to the appropriate HA_ERR_*
- value if possible.
- */
- int32 lastrc()
- {
- return db2i_ileBridge::translateErrorCode(rc);
- }
-
- void rewind()
- {
- readCursor = 0;
- rc = 0;
- usedRows() = 0;
- }
-
- bool reachedEOD() { return EOD; }
-
- void newReadRequest(FILE_HANDLE infile,
- char orientation,
- uint32 rowsToBuffer,
- bool useAsync,
- ILEMemHandle key,
- int keyLength,
- int keyParts);
-
- private:
-
- /**
- End any running async read operation.
- */
- void interruptRead()
- {
- closePipe();
- if (file && readIsAsync && (rc == 0) && (rowCount() < getRowCapacity()))
- {
- DBUG_PRINT("IOReadBuffer::interruptRead", ("PERF: Interrupting %d", (uint32)file));
- getBridge()->readInterrupt(file);
- }
- }
-
- void closePipe()
- {
- if (msgPipe != QMY_REUSE)
- {
- DBUG_PRINT("db2i_ioBuffers::closePipe", ("Closing pipe %d", msgPipe));
- close(msgPipe);
- msgPipe = QMY_REUSE;
- }
- }
-
- /**
- Get a pointer to the active ILE bridge.
-
- Getting the bridge pointer is (relatively) expensive, so we cache
- it off for each operation.
- */
- db2i_ileBridge* getBridge()
- {
- if (unlikely(bridge == NULL))
- {
- bridge = db2i_ileBridge::getBridgeForThread();
- }
- return bridge;
- }
-
- void drainPipe();
- void pollNextRow(char orientation);
- void prepForFree();
- void initAfterAllocate(bool sizeChanged);
- void loadNewRows(char orientation);
-
-
- uint32 readCursor; // Read position within buffer
- int32 rc; // Last return code received
- ValidatedPointer<uint32> rrnList; // Receiver for list of rrns
- char accessIntent; // The access intent for this read
- char commitLevel; // What isolation level should be used
- char EOD; // Whether end-of-data was hit
- char readIsAsync; // Are reads to be done asynchronously?
- bool* releaseRowNeeded;
- /* Does the caller need to release the current row when finished reading */
- FILE_HANDLE file; // The file to be read
- int msgPipe;
- /* The read descriptor of the pipe used to pass messages during async reads */
- db2i_ileBridge* bridge; // Cached pointer to bridge
- uint32 rowsToBlock; // Number of rows to request
- enum
- {
- ConsumedFullBufferMsg,
- PendingFullBufferMsg,
- Untouched
- } pipeState;
- /* The state of the async read message pipe */
-};
-
diff --git a/storage/ibmdb2i/db2i_misc.h b/storage/ibmdb2i/db2i_misc.h
deleted file mode 100644
index f0b527aaad0..00000000000
--- a/storage/ibmdb2i/db2i_misc.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-#ifndef DB2I_MISC_H
-#define DB2I_MISC_H
-
-/**
- Undelimit quote-delimited DB2 names in-place
-*/
-void stripExtraQuotes(char* name, uint maxLen)
-{
- char* oldName = (char*)sql_strdup(name);
- uint i = 0;
- uint j = 0;
- do
- {
- name[j] = oldName[i];
- if (oldName[i] == '"' && oldName[i+1] == '"')
- ++i;
- } while (++j < maxLen && oldName[++i]);
-
- if (j == maxLen)
- --j;
- name[j] = 0;
-}
-
-/**
- Convert a MySQL identifier name into a DB2 compatible format
-
- @parm input The MySQL name
- @parm output The DB2 name
- @parm outlen The amount of space allocated for output
- @parm delimit Should delimiting quotes be placed around the converted name?
- @parm delimitQuotes Should quotes in the MySQL be delimited with additional quotes?
-
- @return FALSE if output was too small and name was truncated; TRUE otherwise
-*/
-bool convertMySQLNameToDB2Name(const char* input,
- char* output,
- size_t outlen,
- bool delimit = true,
- bool delimitQuotes = true)
-{
- uint o = 0;
- if (delimit)
- output[o++] = '"';
-
- uint i = 0;
- do
- {
- output[o] = input[i];
- if (delimitQuotes && input[i] == '"')
- output[++o] = '"';
- } while (++o < outlen-2 && input[++i]);
-
- if (delimit)
- output[o++] = '"';
- output[min(o, outlen-1)] = 0; // This isn't the most user-friendly way to handle overflows,
- // but at least its safe.
- return (o <= outlen-1);
-}
-
-bool isOrdinaryIdentifier(const char* s)
-{
- while (*s)
- {
- if (my_isupper(system_charset_info, *s) ||
- my_isdigit(system_charset_info, *s) ||
- (*s == '_') ||
- (*s == '@') ||
- (*s == '$') ||
- (*s == '#') ||
- (*s == '"'))
- ++s;
- else
- return false;
- }
- return true;
-}
-
-/**
- Fill memory with a 16-bit word.
-
- @param p Pointer to space to fill.
- @param v Value to fill
- @param l Length of space (in 16-bit words)
-*/
-void memset16(void* p, uint16 v, size_t l)
-{
- uint16* p2=(uint16*)p;
- while (l--)
- {
- *(p2++) = v;
- }
-}
-
-#endif
diff --git a/storage/ibmdb2i/db2i_myconv.cc b/storage/ibmdb2i/db2i_myconv.cc
deleted file mode 100644
index 7be6e1236cd..00000000000
--- a/storage/ibmdb2i/db2i_myconv.cc
+++ /dev/null
@@ -1,1498 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-/**
- @file
-
- @brief A direct map optimization of iconv and related functions
- This was show to significantly reduce character conversion cost
- for short strings when compared to calling iconv system code.
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <wchar.h>
-#include <errno.h>
-#include <iconv.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <string.h>
-#include <as400_protos.h>
-
-#include "db2i_myconv.h"
-#include "db2i_global.h"
-
-int32_t myconvDebug=0;
-
-static char szGetTimeString[20];
-static char * GetTimeString(time_t now)
-{
- struct tm * tm;
-
- now = time(&now);
- tm = (struct tm *) localtime(&now);
- sprintf(szGetTimeString, "%04d/%02d/%02d %02d:%02d:%02d",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-
- return szGetTimeString;
-}
-
-static MEM_ROOT dmapMemRoot;
-
-void initMyconv()
-{
- init_alloc_root(&dmapMemRoot, 0x200, 0);
-}
-
-void cleanupMyconv()
-{
- free_root(&dmapMemRoot,0);
-}
-
-
-#ifdef DEBUG
-/* type: */
-#define STDOUT_WITH_TIME -1 /* to stdout with time */
-#define STDERR_WITH_TIME -2 /* to stderr with time */
-#define STDOUT_WO_TIME 1 /* : to stdout */
-#define STDERR_WO_TIME 2 /* : to stderr */
-
-
-static void MyPrintf(long type,
- char * fmt, ...)
-{
- char StdoutFN[256];
- va_list ap;
- char * p;
- time_t now;
- FILE * fd=stderr;
-
- if (type < 0)
- {
- now = time(&now);
- fprintf(fd, "%s ", GetTimeString(now));
- }
- va_start(ap, fmt);
- vfprintf(fd, fmt, ap);
- va_end(ap);
-}
-#endif
-
-
-
-
-#define MAX_CONVERTER 128
-
-mycstoccsid(const char* pname)
-{
- if (strcmp(pname, "UTF-16")==0)
- return 1200;
- else if (strcmp(pname, "big5")==0)
- return 950;
- else
- return cstoccsid(pname);
-}
-#define cstoccsid mycstoccsid
-
-static struct __myconv_rec myconv_rec [MAX_CONVERTER];
-static struct __dmap_rec dmap_rec [MAX_CONVERTER];
-
-static int dmap_open(const char * to,
- const char * from,
- const int32_t idx)
-{
- if (myconvIsSBCS(from) && myconvIsSBCS(to)) {
- dmap_rec[idx].codingSchema = DMAP_S2S;
- if ((dmap_rec[idx].dmapS2S = (uchar *) alloc_root(&dmapMemRoot, 0x100)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_S2S, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapS2S, 0x00, 0x100);
- myconv_rec[idx].allocatedSize=0x100;
-
- {
- char dmapSrc[0x100];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft=0x100;
- size_t outBytesLeft=0x100;
- size_t len;
- char * inBuf=dmapSrc;
- char * outBuf=(char *) dmap_rec[idx].dmapS2S;
-
- if ((cd = iconv_open(to, from)) == (iconv_t) -1) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- inBytesLeft = 0x100;
- for (i = 0; i < inBytesLeft; ++i)
- dmapSrc[i]=i;
-
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d: iconv() returns %d, errno = %d in %s at %d\n",
- to, from, idx, DMAP_S2S, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "inBytesLeft = %d, inBuf - dmapSrc = %d\n", inBytesLeft, inBuf-dmapSrc);
- MyPrintf(STDERR_WITH_TIME,
- "outBytesLeft = %d, outBuf - dmapS2S = %d\n", outBytesLeft, outBuf-(char *) dmap_rec[idx].dmapS2S);
- }
- if ((inBytesLeft == 86 || inBytesLeft == 64 || inBytesLeft == 1) &&
- memcmp(from, "IBM-1256", 9) == 0 &&
- memcmp(to, "IBM-420", 8) == 0) {
- /* Known problem for IBM-1256_IBM-420 */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
- } else if ((inBytesLeft == 173 || inBytesLeft == 172 ||
- inBytesLeft == 74 || inBytesLeft == 73 ||
- inBytesLeft == 52 || inBytesLeft == 50 ||
- inBytesLeft == 31 || inBytesLeft == 20 ||
- inBytesLeft == 6) &&
- memcmp(to, "IBM-1256", 9) == 0 &&
- memcmp(from, "IBM-420", 8) == 0) {
- /* Known problem for IBM-420_IBM-1256 */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
- } else if ((128 >= inBytesLeft) &&
- memcmp(to, "IBM-037", 8) == 0 &&
- memcmp(from, "IBM-367", 8) == 0) {
- /* Known problem for IBM-367_IBM-037 */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
- } else if (((1 <= inBytesLeft && inBytesLeft <= 4) || (97 <= inBytesLeft && inBytesLeft <= 128)) &&
- memcmp(to, "IBM-838", 8) == 0 &&
- memcmp(from, "TIS-620", 8) == 0) {
- /* Known problem for TIS-620_IBM-838 */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
- }
- iconv_close(cd);
- return -1;
-#else
- /* Tolerant to undefined conversions for any converter */
- --inBytesLeft;
- ++inBuf;
- *outBuf=0x00;
- ++outBuf;
- --outBytesLeft;
- continue;
-#endif
- }
- } while (inBytesLeft > 0);
-
- if (myconvIsISO(to))
- myconv_rec[idx].subS=0x1A;
- else if (myconvIsASCII(to))
- myconv_rec[idx].subS=0x7F;
- else if (myconvIsEBCDIC(to))
- myconv_rec[idx].subS=0x3F;
-
- if (myconvIsISO(from))
- myconv_rec[idx].srcSubS=0x1A;
- else if (myconvIsASCII(from))
- myconv_rec[idx].srcSubS=0x7F;
- else if (myconvIsEBCDIC(from))
- myconv_rec[idx].srcSubS=0x3F;
-
- iconv_close(cd);
- }
- } else if (((myconvIsSBCS(from) && myconvIsUnicode2(to)) && (dmap_rec[idx].codingSchema = DMAP_S2U)) ||
- ((myconvIsSBCS(from) && myconvIsUTF8(to)) && (dmap_rec[idx].codingSchema = DMAP_S28))) {
- int i;
-
- /* single byte mapping */
- if ((dmap_rec[idx].dmapD12U = (UniChar *) alloc_root(&dmapMemRoot, 0x100 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_S2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapD12U, 0x00, 0x100 * 2);
- myconv_rec[idx].allocatedSize=0x100 * 2;
-
-
- {
- char dmapSrc[2];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
- char SS=0x1A;
-#ifdef support_surrogate
- if ((cd = iconv_open("UTF-16", from)) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open("UCS-2", from)) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x100; ++i) {
- dmapSrc[0]=i;
- inBuf=dmapSrc;
- inBytesLeft=1;
- outBuf=(char *) &(dmap_rec[idx].dmapD12U[i]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if ((errno == EILSEQ || errno == EINVAL) &&
- inBytesLeft == 1 &&
- outBytesLeft == 2) {
- continue;
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(cd,%02x,%d,%02x%02x,%d), errno = %d in %s at %d\n",
- to, from, idx, dmapSrc[0], 1,
- (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1], 2,
- errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "inBytesLeft=%d, outBytesLeft=%d, %02x%02x\n",
- inBytesLeft, outBytesLeft,
- (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1]);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- dmap_rec[idx].dmapD12U[i]=0x0000;
- }
- if (dmap_rec[idx].dmapE02U[i] == 0x001A && /* pick the first one */
- myconv_rec[idx].srcSubS == 0x00) {
- myconv_rec[idx].srcSubS=i;
- }
- }
- iconv_close(cd);
- }
- myconv_rec[idx].subS=0x1A;
- myconv_rec[idx].subD=0xFFFD;
-
-
- } else if (((myconvIsUCS2(from) && myconvIsSBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_U2S)) ||
- ((myconvIsUTF16(from) && myconvIsSBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_T2S)) ||
- ((myconvIsUTF8(from) && myconvIsSBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_82S))) {
- /* UTF-16 -> SBCS, the direct map a bit of waste of space,
- * binary search may be reasonable alternative
- */
- if ((dmap_rec[idx].dmapU2S = (uchar *) alloc_root(&dmapMemRoot, 0x10000 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2S, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapU2S, 0x00, 0x10000);
- myconv_rec[idx].allocatedSize=(0x10000 * 2);
-
- {
- iconv_t cd;
- int32_t i;
-
-#ifdef support_surrogate
- if ((cd = iconv_open(to, "UTF-16")) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open(to, "UCS-2")) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x100; ++i) {
- UniChar dmapSrc[0x100];
- int32_t j;
- for (j = 0; j < 0x100; ++j) {
- dmapSrc[j]=i * 0x100 + j;
- }
- char * inBuf=(char *) dmapSrc;
- char * outBuf=(char *) &(dmap_rec[idx].dmapU2S[i*0x100]);
- size_t inBytesLeft=sizeof(dmapSrc);
- size_t outBytesLeft=0x100;
- size_t len;
-
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (inBytesLeft == 0 && outBytesLeft == 0) { /* a number of substitution returns */
- continue;
- }
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- from, to, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "iconv() retuns %d, errno=%d, InBytesLeft=%d, OutBytesLeft=%d\n",
- len, errno, inBytesLeft, outBytesLeft, __FILE__,__LINE__);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- }
- iconv_close(cd);
-
- myconv_rec[idx].subS = dmap_rec[idx].dmapU2S[0x1A];
- myconv_rec[idx].subD = dmap_rec[idx].dmapU2S[0xFFFD];
- myconv_rec[idx].srcSubS = 0x1A;
- myconv_rec[idx].srcSubD = 0xFFFD;
- }
-
-
-
- } else if (((myconvIsDBCS(from) && myconvIsUnicode2(to)) && (dmap_rec[idx].codingSchema = DMAP_D2U)) ||
- ((myconvIsDBCS(from) && myconvIsUTF8(to)) && (dmap_rec[idx].codingSchema = DMAP_D28))) {
- int i;
- /* single byte mapping */
- if ((dmap_rec[idx].dmapD12U = (UniChar *) alloc_root(&dmapMemRoot, 0x100 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_D2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapD12U, 0x00, 0x100 * 2);
-
- /* double byte mapping, assume 7 bit ASCII is not use as the first byte of DBCS. */
- if ((dmap_rec[idx].dmapD22U = (UniChar *) alloc_root(&dmapMemRoot, 0x8000 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_D2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapD22U, 0x00, 0x8000 * 2);
-
- myconv_rec[idx].allocatedSize=(0x100 + 0x8000) * 2;
-
-
- {
- char dmapSrc[2];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
- char SS=0x1A;
-
-#ifdef support_surrogate
- if ((cd = iconv_open("UTF-16", from)) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open("UCS-2", from)) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x100; ++i) {
- dmapSrc[0]=i;
- inBuf=dmapSrc;
- inBytesLeft=1;
- outBuf=(char *) (&dmap_rec[idx].dmapD12U[i]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if ((errno == EILSEQ || errno == EINVAL) &&
- inBytesLeft == 1 &&
- outBytesLeft == 2) {
- continue;
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(cd,%02x,%d,%02x%02x,%d), errno = %d in %s at %d\n",
- to, from, idx, dmapSrc[0], 1,
- (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1], 2,
- errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "inBytesLeft=%d, outBytesLeft=%d, %02x%02x\n",
- inBytesLeft, outBytesLeft,
- (&dmap_rec[idx].dmapD12U[i])[0],(&dmap_rec[idx].dmapD12U[i])[1]);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- dmap_rec[idx].dmapD12U[i]=0x0000;
- }
- if (dmap_rec[idx].dmapD12U[i] == 0x001A && /* pick the first one */
- myconv_rec[idx].srcSubS == 0x00) {
- myconv_rec[idx].srcSubS=i;
- }
- }
-
-
- for (i = 0x80; i < 0x100; ++i) {
- int j;
- if (dmap_rec[idx].dmapD12U[i] != 0x0000)
- continue;
- for (j = 0x01; j < 0x100; ++j) {
- dmapSrc[0]=i;
- dmapSrc[1]=j;
- int offset = i-0x80;
- offset<<=8;
- offset+=j;
-
- inBuf=dmapSrc;
- inBytesLeft=2;
- outBuf=(char *) &(dmap_rec[idx].dmapD22U[offset]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (inBytesLeft == 2 && outBytesLeft == 2 && (errno == EILSEQ || errno == EINVAL)) {
- ; /* invalid DBCS character, dmapDD2U[offset] remains 0x0000 */
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(cd,%p,2,%p,2), errno = %d in %s at %d\n",
- to, from, idx,
- dmapSrc, &(dmap_rec[idx].dmapD22U[offset]),
- errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME,
- "iconv(cd,0x%02x%02x,2,0x%04x,2) returns %d, inBytesLeft=%d, outBytesLeft=%d\n",
- dmapSrc[0], dmapSrc[1],
- dmap_rec[idx].dmapD22U[offset],
- len, inBytesLeft, outBytesLeft);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- } else {
-#ifdef TRACE_DMAP
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc=%d, errno=%d in %s at %d\n",
- to, from, idx, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "%04X: src=%04X%04X, inBuf=0x%02X%02X, inBytesLeft=%d, outBuf=%02X%02X%02X, outBytesLeft=%d\n",
- i, dmapSrc[0], dmapSrc[1], inBuf[0], inBuf[1],
- inBytesLeft, outBuf[-2], outBuf[-1], outBuf[0], outBytesLeft);
- MyPrintf(STDERR_WITH_TIME,
- "&dmapSrc=%p, inBuf=%p, %p, outBuf=%p\n",
- dmapSrc, inBuf, dmap_rec[idx].dmapU2M3 + (i - 0x80) * 2, outBuf);
- }
-#endif
- }
- }
- if (dmap_rec[idx].dmapD12U[i] == 0xFFFD) { /* pick the last one */
- myconv_rec[idx].srcSubD=i* 0x100 + j;
- }
- }
- iconv_close(cd);
- }
-
- myconv_rec[idx].subS=0x1A;
- myconv_rec[idx].subD=0xFFFD;
- myconv_rec[idx].srcSubD=0xFCFC;
-
-
- } else if (((myconvIsUCS2(from) && myconvIsDBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_U2D)) ||
- ((myconvIsUTF16(from) && myconvIsDBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_T2D)) ||
- ((myconvIsUTF8(from) && myconvIsDBCS(to)) && (dmap_rec[idx].codingSchema = DMAP_82D))) {
- /* UTF-16 -> DBCS single/double byte */
- /* A single table will cover all characters, assuming no second byte is 0x00. */
- if ((dmap_rec[idx].dmapU2D = (uchar *) alloc_root(&dmapMemRoot, 0x10000 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2D, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- memset(dmap_rec[idx].dmapU2D, 0x00, 0x10000 * 2);
- myconv_rec[idx].allocatedSize=(0x10000 * 2);
-
- {
- UniChar dmapSrc[1];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
-
-#ifdef support_surrogate
- if ((cd = iconv_open(to, "UTF-16")) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open(to, "UCS-2")) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- /* easy implementation, convert 1 Unicode character at one time. */
- /* If the open performance is an issue, convert a chunk such as 128 chracters. */
- /* if the converted length is not the same as the original, convert one by one. */
- (dmap_rec[idx].dmapU2D)[0x0000]=0x00;
- for (i = 1; i < 0x10000; ++i) {
- dmapSrc[0]=i;
- inBuf=(char *) dmapSrc;
- inBytesLeft=2;
- outBuf=(char *) &((dmap_rec[idx].dmapU2D)[2*i]);
- outBytesLeft=2;
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (len == 1 && inBytesLeft == 0 && outBytesLeft == 1 && (dmap_rec[idx].dmapU2D)[2*i] == 0x1A) {
- /* UCS-2_TIS-620:0x0080 => 0x1A, converted to SBCS replacement character */
- (dmap_rec[idx].dmapU2D)[2*i+1]=0x00;
- break;
- } else if (len == 1 && inBytesLeft == 0 && outBytesLeft == 0) {
- break;
- }
- if (errno == EILSEQ || errno == EINVAL) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME,
- "iconv(cd,%04x,2,%02x%02x,2) returns inBytesLeft=%d, outBytesLeft=%d\n",
- dmapSrc[0],
- (dmap_rec[idx].dmapU2D)[2*i], (dmap_rec[idx].dmapU2D)[2*i+1],
- inBytesLeft, outBytesLeft);
- if (outBuf - (char *) dmap_rec[idx].dmapU2M2 > 1)
- MyPrintf(STDERR_WO_TIME, "outBuf[-2..2]=%02X%02X%02X%02X%02X\n", outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "outBuf[0..2]=%02X%02X%02X\n", outBuf[0],outBuf[1],outBuf[2]);
- }
-#endif
- inBuf+=2;
- inBytesLeft-=2;
- memcpy(outBuf, (char *) &(myconv_rec[idx].subD), 2);
- outBuf+=2;
- outBytesLeft-=2;
- } else {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "[%d] dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- i, to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME,
- "iconv(cd,%04x,2,%02x%02x,2) returns %d inBytesLeft=%d, outBytesLeft=%d\n",
- dmapSrc[0],
- (dmap_rec[idx].dmapU2D)[2*i],
- (dmap_rec[idx].dmapU2D)[2*i+1],
- len, inBytesLeft,outBytesLeft);
- if (i == 1) {
- MyPrintf(STDERR_WO_TIME,
- " inBuf [-1..2]=%02x%02x%02x%02x\n",
- inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- MyPrintf(STDERR_WO_TIME,
- " outBuf [-1..2]=%02x%02x%02x%02x\n",
- outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- } else {
- MyPrintf(STDERR_WO_TIME,
- " inBuf [-2..2]=%02x%02x%02x%02x%02x\n",
- inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- MyPrintf(STDERR_WO_TIME,
- " outBuf [-2..2]=%02x%02x%02x%02x%02x\n",
- outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- if (len == 0 && inBytesLeft == 0 && outBytesLeft == 1) { /* converted to SBCS */
- (dmap_rec[idx].dmapU2D)[2*i+1]=0x00;
- break;
- }
- }
- } while (inBytesLeft > 0);
- }
- iconv_close(cd);
- myconv_rec[idx].subS = dmap_rec[idx].dmapU2D[2*0x1A];
- myconv_rec[idx].subD = dmap_rec[idx].dmapU2D[2*0xFFFD] * 0x100
- + dmap_rec[idx].dmapU2D[2*0xFFFD+1];
- myconv_rec[idx].srcSubS = 0x1A;
- myconv_rec[idx].srcSubD = 0xFFFD;
- }
-
-
- } else if (((myconvIsEUC(from) && myconvIsUnicode2(to)) && (dmap_rec[idx].codingSchema = DMAP_E2U)) ||
- ((myconvIsEUC(from) && myconvIsUTF8(to)) && (dmap_rec[idx].codingSchema = DMAP_E28))) {
- int i;
- /* S0: 0x00 - 0x7F */
- if ((dmap_rec[idx].dmapE02U = (UniChar *) alloc_root(&dmapMemRoot, 0x100 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapE02U, 0x00, 0x100 * 2);
-
- /* S1: 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapE12U = (UniChar *) alloc_root(&dmapMemRoot, 0x60 * 0x60 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapE12U, 0x00, 0x60 * 0x60 * 2);
-
- /* SS2: 0x8E + 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapE22U = (UniChar *) alloc_root(&dmapMemRoot, 0x60 * 0x61 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapE22U, 0x00, 0x60 * 0x61 * 2);
-
- /* SS3: 0x8F + 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapE32U = (UniChar *) alloc_root(&dmapMemRoot, 0x60 * 0x61 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_E2U, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapE32U, 0x00, 0x60 * 0x61 * 2);
-
- myconv_rec[idx].allocatedSize=(0x100 + 0x60 * 0x60 + 0x60 * 0x61* 2) * 2;
-
-
- {
- char dmapSrc[0x60 * 0x60 * 3];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
- char SS=0x8E;
-
-#ifdef support_surrogate
- if ((cd = iconv_open("UTF-16", from)) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open("UCS-2", from)) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x100; ++i) {
- dmapSrc[0]=i;
- inBuf=dmapSrc;
- inBytesLeft=1;
- outBuf=(char *) (&dmap_rec[idx].dmapE02U[i]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
- }
-#endif
- dmap_rec[idx].dmapE02U[i]=0x0000;
- }
- if (dmap_rec[idx].dmapE02U[i] == 0x001A && /* pick the first one */
- myconv_rec[idx].srcSubS == 0x00) {
- myconv_rec[idx].srcSubS=i;
- }
- }
-
-
- inBuf=dmapSrc;
- for (i = 0; i < 0x60; ++i) {
- int j;
- for (j = 0; j < 0x60; ++j) {
- *inBuf=i+0xA0;
- ++inBuf;
- *inBuf=j+0xA0;
- ++inBuf;
- }
- }
- inBuf=dmapSrc;
- inBytesLeft=0x60 * 0x60 * 2;
- outBuf=(char *) dmap_rec[idx].dmapE12U;
- outBytesLeft=0x60 * 0x60 * 2;
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (errno == EILSEQ) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME, "inBytesLeft=%d, outBytesLeft=%d\n", inBytesLeft, outBytesLeft);
- if (inBuf - dmapSrc > 1 && inBuf - dmapSrc <= sizeof(dmapSrc) - 2)
- MyPrintf(STDERR_WO_TIME, "inBuf[-2..2]=%02X%02X%02X%02X%02X\n", inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "inBuf[0..2]=%02X%02X%02X\n", inBuf[0],inBuf[1],inBuf[2]);
- if (outBuf - (char *) dmap_rec[idx].dmapE12U > 1)
- MyPrintf(STDERR_WO_TIME, "outBuf[-2..2]=%02X%02X%02X%02X%02X\n", outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "outBuf[0..2]=%02X%02X%02X\n", outBuf[0],outBuf[1],outBuf[2]);
- }
-#endif
- inBuf+=2;
- inBytesLeft-=2;
- outBuf[0]=0x00;
- outBuf[1]=0x00;
- outBuf+=2;
- outBytesLeft-=2;
- } else {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- iconv_close(cd);
- return -1;
- }
- }
- } while (inBytesLeft > 0);
-
- /* SS2: 0x8E + 1 or 2 bytes */
- /* SS3: 0x8E + 1 or 2 bytes */
- while (SS != 0x00) {
- int32_t numSuccess=0;
- for (i = 0; i < 0x60; ++i) {
- inBuf=dmapSrc;
- inBuf[0]=SS;
- inBuf[1]=i+0xA0;
- inBytesLeft=2;
- if (SS == 0x8E)
- outBuf=(char *) &(dmap_rec[idx].dmapE22U[i]);
- else
- outBuf=(char *) &(dmap_rec[idx].dmapE32U[i]);
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (SS == 0x8E)
- dmap_rec[idx].dmapE22U[i]=0x0000;
- else
- dmap_rec[idx].dmapE32U[i]=0x0000;
- } else {
- ++numSuccess;
- }
- }
- if (numSuccess == 0) { /* SS2 is 2 bytes */
- inBuf=dmapSrc;
- for (i = 0; i < 0x60; ++i) {
- int j;
- for (j = 0; j < 0x60; ++j) {
- *inBuf=SS;
- ++inBuf;
- *inBuf=i+0xA0;
- ++inBuf;
- *inBuf=j+0xA0;
- ++inBuf;
- }
- }
- inBuf=dmapSrc;
- inBytesLeft=0x60 * 0x60 * 3;
- if (SS == 0x8E)
- outBuf=(char *) &(dmap_rec[idx].dmapE22U[0x60]);
- else
- outBuf=(char *) &(dmap_rec[idx].dmapE32U[0x60]);
- outBytesLeft=0x60 * 0x60 * 2;
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "%02X:dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- SS, to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME, "inBytesLeft=%d, outBytesLeft=%d\n", inBytesLeft, outBytesLeft);
- if (inBuf - dmapSrc > 1 && inBuf - dmapSrc <= sizeof(dmapSrc) - 2)
- MyPrintf(STDERR_WO_TIME, "inBuf[-2..2]=%02X%02X%02X%02X%02X\n", inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "inBuf[0..2]=%02X%02X%02X\n", inBuf[0],inBuf[1],inBuf[2]);
- }
-#endif
- if (errno == EILSEQ || errno == EINVAL) {
- inBuf+=3;
- inBytesLeft-=3;
- outBuf[0]=0x00;
- outBuf[1]=0x00;
- outBuf+=2;
- outBytesLeft-=2;
- } else {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "%02X:dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- SS, to, from, idx, errno, __FILE__,__LINE__);
-#endif
- iconv_close(cd);
- return -1;
- }
- }
- } while (inBytesLeft > 0);
- }
- if (SS == 0x8E)
- SS=0x8F;
- else
- SS = 0x00;
- }
- iconv_close(cd);
-
- myconv_rec[idx].subS=0x1A;
- myconv_rec[idx].subD=0xFFFD;
- for (i = 0; i < 0x80; ++i) {
- if (dmap_rec[idx].dmapE02U[i] == 0x001A) {
- myconv_rec[idx].srcSubS=i; /* pick the first one */
- break;
- }
- }
-
- for (i = 0; i < 0x60 * 0x60; ++i) {
- if (dmap_rec[idx].dmapE12U[i] == 0xFFFD) {
- uchar byte1=i / 0x60;
- uchar byte2=i % 0x60;
- myconv_rec[idx].srcSubD=(byte1 + 0xA0) * 0x100 + (byte2 + 0xA0); /* pick the last one */
- }
- }
-
- }
-
- } else if (((myconvIsUCS2(from) && myconvIsEUC(to)) && (dmap_rec[idx].codingSchema = DMAP_U2E)) ||
- ((myconvIsUTF16(from) && myconvIsEUC(to)) && (dmap_rec[idx].codingSchema = DMAP_T2E)) ||
- ((myconvIsUTF8(from) && myconvIsEUC(to)) && (dmap_rec[idx].codingSchema = DMAP_82E))) {
- /* S0: 0x00 - 0xFF */
- if ((dmap_rec[idx].dmapU2S = (uchar *) alloc_root(&dmapMemRoot, 0x100)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2E, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapU2S, 0x00, 0x100);
-
- /* U0080 - UFFFF -> S1: 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapU2M2 = (uchar *) alloc_root(&dmapMemRoot, 0xFF80 * 2)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2E, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapU2M2, 0x00, 0xFF80 * 2);
-
- /* U0080 - UFFFF -> SS2: 0x8E + 0xA0 - 0xFF, 0xA0 - 0xFF
- * SS3: 0x8F + 0xA0 - 0xFF, 0xA0 - 0xFF */
- if ((dmap_rec[idx].dmapU2M3 = (uchar *) alloc_root(&dmapMemRoot, 0xFF80 * 3)) == NULL) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d), CS=%d failed with malloc(), errno = %d in %s at %d\n",
- to, from, idx, DMAP_U2E, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
- memset(dmap_rec[idx].dmapU2M3, 0x00, 0xFF80 * 3);
- myconv_rec[idx].allocatedSize=(0x100 + 0xFF80 * 2 + 0xFF80 * 3);
-
- {
- UniChar dmapSrc[0x80];
- iconv_t cd;
- int32_t i;
- size_t inBytesLeft;
- size_t outBytesLeft;
- size_t len;
- char * inBuf;
- char * outBuf;
-
-#ifdef support_surrogate
- if ((cd = iconv_open(to, "UTF-16")) == (iconv_t) -1) {
-#else
- if ((cd = iconv_open(to, "UCS-2")) == (iconv_t) -1) {
-#endif
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed with iconv_open(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- return -1;
- }
-
- for (i = 0; i < 0x80; ++i)
- dmapSrc[i]=i;
- inBuf=(char *) dmapSrc;
- inBytesLeft=0x80 * 2;
- outBuf=(char *) dmap_rec[idx].dmapU2S;
- outBytesLeft=0x80;
- do {
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
-#endif
- iconv_close(cd);
- return -1;
- }
- } while (inBytesLeft > 0);
-
- myconv_rec[idx].srcSubS = 0x1A;
- myconv_rec[idx].srcSubD = 0xFFFD;
- myconv_rec[idx].subS = dmap_rec[idx].dmapU2S[0x1A];
-
- outBuf=(char *) &(myconv_rec[idx].subD);
- dmapSrc[0]=0xFFFD;
- inBuf=(char *) dmapSrc;
- inBytesLeft=2;
- outBytesLeft=2;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc=%d, errno=%d in %s at %d\n",
- to, from, idx, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME, "iconv(0x1A,1,%p,1) returns outBuf=%p, outBytesLeft=%d\n",
- dmapSrc, outBuf, outBytesLeft);
- }
-#endif
- if (outBytesLeft == 0) {
- /* UCS-2_IBM-eucKR returns error.
- myconv(iconv) rc=1, error=0, InBytesLeft=0, OutBytesLeft=18
- myconv(iconvRev) rc=-1, error=116, InBytesLeft=2, OutBytesLeft=20
- iconv: 0xFFFD => 0xAFFE => 0x rc=1,-1 sub=0,0
- */
- ;
- } else {
- iconv_close(cd);
- return -1;
- }
- }
-
- for (i = 0x80; i < 0xFFFF; ++i) {
- uchar eucBuf[3];
- dmapSrc[0]=i;
- inBuf=(char *) dmapSrc;
- inBytesLeft=2;
- outBuf=(char *) eucBuf;
- outBytesLeft=sizeof(eucBuf);
- errno=0;
- if ((len = iconv(cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft)) != (size_t) 0) {
- if (len == 1 && errno == 0 && inBytesLeft == 0 && outBytesLeft == 1) { /* substitution occurred. */ continue;
- }
-
- if (errno == EILSEQ) {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), errno = %d in %s at %d\n",
- to, from, idx, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WO_TIME, "inBytesLeft=%d, outBytesLeft=%d\n", inBytesLeft, outBytesLeft);
- if (inBuf - (char *) dmapSrc > 1 && inBuf - (char *) dmapSrc <= sizeof(dmapSrc) - 2)
- MyPrintf(STDERR_WO_TIME, "inBuf[-2..2]=%02X%02X%02X%02X%02X\n", inBuf[-2],inBuf[-1],inBuf[0],inBuf[1],inBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "inBuf[0..2]=%02X%02X%02X\n", inBuf[0],inBuf[1],inBuf[2]);
- if (outBuf - (char *) dmap_rec[idx].dmapU2M2 > 1)
- MyPrintf(STDERR_WO_TIME, "outBuf[-2..2]=%02X%02X%02X%02X%02X\n", outBuf[-2],outBuf[-1],outBuf[0],outBuf[1],outBuf[2]);
- else
- MyPrintf(STDERR_WO_TIME, "outBuf[0..2]=%02X%02X%02X\n", outBuf[0],outBuf[1],outBuf[2]);
- }
-#endif
- inBuf+=2;
- inBytesLeft-=2;
- memcpy(outBuf, (char *) &(myconv_rec[idx].subD), 2);
- outBuf+=2;
- outBytesLeft-=2;
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc = %d, errno = %d in %s at %d\n",
- to, from, idx, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "%04X: src=%04X%04X, inBuf=0x%02X%02X, inBytesLeft=%d, outBuf[-2..0]=%02X%02X%02X, outBytesLeft=%d\n",
- i, dmapSrc[0], dmapSrc[1], inBuf[0], inBuf[1],
- inBytesLeft, outBuf[-2], outBuf[-1], outBuf[0], outBytesLeft);
- MyPrintf(STDERR_WITH_TIME,
- "&dmapSrc=%p, inBuf=%p, dmapU2M2 + %d = %p, outBuf=%p\n",
- dmapSrc, inBuf, (i - 0x80) * 2, dmap_rec[idx].dmapU2M2 + (i - 0x80) * 2, outBuf);
- }
-#endif
- iconv_close(cd);
- return -1;
- }
- }
- if (sizeof(eucBuf) - outBytesLeft == 1) {
- if (i < 0x100) {
- (dmap_rec[idx].dmapU2S)[i]=eucBuf[0];
- } else {
- dmap_rec[idx].dmapU2M2[(i - 0x80) * 2] = eucBuf[0];
- dmap_rec[idx].dmapU2M2[(i - 0x80) * 2 + 1] = 0x00;
- }
- } else if (sizeof(eucBuf) - outBytesLeft == 2) { /* 2 bytes */
- dmap_rec[idx].dmapU2M2[(i - 0x80) * 2] = eucBuf[0];
- dmap_rec[idx].dmapU2M2[(i - 0x80) * 2 + 1] = eucBuf[1];
- } else if (sizeof(eucBuf) - outBytesLeft == 3) { /* 3 byte SS2/SS3 */
- dmap_rec[idx].dmapU2M3[(i - 0x80) * 3] = eucBuf[0];
- dmap_rec[idx].dmapU2M3[(i - 0x80) * 3 + 1] = eucBuf[1];
- dmap_rec[idx].dmapU2M3[(i - 0x80) * 3 + 2] = eucBuf[2];
- } else {
-#ifdef DEBUG
- if (myconvDebug) {
- MyPrintf(STDERR_WITH_TIME,
- "dmap_open(%s,%s,%d) failed to initialize with iconv(), rc=%d, errno=%d in %s at %d\n",
- to, from, idx, len, errno, __FILE__,__LINE__);
- MyPrintf(STDERR_WITH_TIME,
- "%04X: src=%04X%04X, inBuf=0x%02X%02X, inBytesLeft=%d, outBuf=%02X%02X%02X, outBytesLeft=%d\n",
- i, dmapSrc[0], dmapSrc[1], inBuf[0], inBuf[1],
- inBytesLeft, outBuf[-2], outBuf[-1], outBuf[0], outBytesLeft);
- MyPrintf(STDERR_WITH_TIME,
- "&dmapSrc=%p, inBuf=%p, %p, outBuf=%p\n",
- dmapSrc, inBuf, dmap_rec[idx].dmapU2M3 + (i - 0x80) * 2, outBuf);
- }
-#endif
- return -1;
- }
-
- }
- iconv_close(cd);
- }
-
- } else if (myconvIsUTF16(from) && myconvIsUTF8(to)) {
- dmap_rec[idx].codingSchema = DMAP_T28;
-
- } else if (myconvIsUCS2(from) && myconvIsUTF8(to)) {
- dmap_rec[idx].codingSchema = DMAP_U28;
-
- } else if (myconvIsUTF8(from) && myconvIsUnicode2(to)) {
- dmap_rec[idx].codingSchema = DMAP_82U;
-
- } else if (myconvIsUnicode2(from) && myconvIsUnicode2(to)) {
- dmap_rec[idx].codingSchema = DMAP_U2U;
-
- } else {
-
- return -1;
- }
- myconv_rec[idx].cnv_dmap=&(dmap_rec[idx]);
- return 0;
-}
-
-
-
-static int bins_open(const char * to,
- const char * from,
- const int32_t idx)
-{
- return -1;
-}
-
-
-
-static int32_t dmap_close(const int32_t idx)
-{
- if (dmap_rec[idx].codingSchema == DMAP_S2S) {
- if (dmap_rec[idx].dmapS2S != NULL) {
- dmap_rec[idx].dmapS2S=NULL;
- }
- } else if (dmap_rec[idx].codingSchema = DMAP_E2U) {
- if (dmap_rec[idx].dmapE02U != NULL) {
- dmap_rec[idx].dmapE02U=NULL;
- }
- if (dmap_rec[idx].dmapE12U != NULL) {
- dmap_rec[idx].dmapE12U=NULL;
- }
- if (dmap_rec[idx].dmapE22U != NULL) {
- dmap_rec[idx].dmapE22U=NULL;
- }
- if (dmap_rec[idx].dmapE32U != NULL) {
- dmap_rec[idx].dmapE32U=NULL;
- }
- }
-
- return 0;
-}
-
-
-static int32_t bins_close(const int32_t idx)
-{
- return 0;
-}
-
-
-myconv_t myconv_open(const char * toCode,
- const char * fromCode,
- int32_t converter)
-{
- int32 i;
- for (i = 0; i < MAX_CONVERTER; ++i) {
- if (myconv_rec[i].converterType == 0)
- break;
- }
- if (i >= MAX_CONVERTER)
- return ((myconv_t) -1);
-
- myconv_rec[i].converterType = converter;
- myconv_rec[i].index=i;
- myconv_rec[i].fromCcsid=cstoccsid(fromCode);
- if (myconv_rec[i].fromCcsid == 0 && memcmp(fromCode, "big5",5) == 0)
- myconv_rec[i].fromCcsid=950;
- myconv_rec[i].toCcsid=cstoccsid(toCode);
- if (myconv_rec[i].toCcsid == 0 && memcmp(toCode, "big5",5) == 0)
- myconv_rec[i].toCcsid=950;
- strncpy(myconv_rec[i].from, fromCode, sizeof(myconv_rec[i].from)-1);
- strncpy(myconv_rec[i].to, toCode, sizeof(myconv_rec[i].to)-1);
-
- if (converter == CONVERTER_ICONV) {
- if ((myconv_rec[i].cnv_iconv=iconv_open(toCode, fromCode)) == (iconv_t) -1) {
- return ((myconv_t) -1);
- }
- myconv_rec[i].allocatedSize = -1;
- myconv_rec[i].srcSubS=myconvGetSubS(fromCode);
- myconv_rec[i].srcSubD=myconvGetSubD(fromCode);
- myconv_rec[i].subS=myconvGetSubS(toCode);
- myconv_rec[i].subD=myconvGetSubD(toCode);
- return &(myconv_rec[i]);
- } else if (converter == CONVERTER_DMAP &&
- dmap_open(toCode, fromCode, i) != -1) {
- return &(myconv_rec[i]);
- }
- return ((myconv_t) -1);
-}
-
-
-
-int32_t myconv_close(myconv_t cd)
-{
- int32_t ret=0;
-
- if (cd->converterType == CONVERTER_ICONV) {
- ret=iconv_close(cd->cnv_iconv);
- } else if (cd->converterType == CONVERTER_DMAP) {
- ret=dmap_close(cd->index);
- }
- memset(&(myconv_rec[cd->index]), 0x00, sizeof(myconv_rec[cd->index]));
- return ret;
-}
-
-
-
-
-/* reference: http://www-306.ibm.com/software/globalization/other/es.jsp */
-/* systemCL would be expensive, and myconvIsXXXXX is called frequently.
- need to cache entries */
-#define MAX_CCSID 256
-static int ccsidList [MAX_CCSID];
-static int esList [MAX_CCSID];
-int32 getEncodingScheme(const uint16 inCcsid, int32& outEncodingScheme);
-EXTERN int myconvGetES(CCSID ccsid)
-{
- /* call QtqValidateCCSID in ILE to get encoding schema */
- /* return QtqValidateCCSID(ccsid); */
- int i;
- for (i = 0; i < MAX_CCSID; ++i) {
- if (ccsidList[i] == ccsid)
- return esList[i];
- if (ccsidList[i] == 0x00)
- break;
- }
-
- if (i >= MAX_CCSID) {
- i=MAX_CCSID-1;
- }
-
- {
- ccsidList[i]=ccsid;
- getEncodingScheme(ccsid, esList[i]);
-#ifdef DEBUG_PASE
- if (myconvDebug) {
- fprintf(stderr, "CCSID=%d, ES=0x%04X\n", ccsid, esList[i]);
- }
-#endif
- return esList[i];
- }
- return 0;
-}
-
-
-EXTERN int myconvIsEBCDIC(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x1100 ||
- es == 0x1200 ||
- es == 0x6100 ||
- es == 0x6200 ||
- es == 0x1301 ) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsISO(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x4100 ||
- es == 0x4105 ||
- es == 0x4155 ||
- es == 0x5100 ||
- es == 0x5150 ||
- es == 0x5200 ||
- es == 0x5404 ||
- es == 0x5409 ||
- es == 0x540A ||
- es == 0x5700) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsASCII(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x2100 ||
- es == 0x3100 ||
- es == 0x8100 ||
- es == 0x2200 ||
- es == 0x3200 ||
- es == 0x9200 ||
- es == 0x2300 ||
- es == 0x2305 ||
- es == 0x3300 ||
- es == 0x2900 ||
- es == 0x2A00) {
- return TRUE;
- } else if (memcmp(pName, "big5", 5) == 0) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-
-EXTERN int myconvIsUCS2(const char * pName)
-{
- if (cstoccsid(pName) == 13488) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsUTF16(const char * pName)
-{
- if (cstoccsid(pName) == 1200) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsUnicode2(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x7200 ||
- es == 0x720B ||
- es == 0x720F) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsUTF8(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x7807) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsUnicode(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x7200 ||
- es == 0x720B ||
- es == 0x720F ||
- es == 0x7807) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsEUC(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x4403) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsDBCS(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x1200 ||
- es == 0x2200 ||
- es == 0x2300 ||
- es == 0x2305 ||
- es == 0x2A00 ||
- es == 0x3200 ||
- es == 0x3300 ||
- es == 0x5200 ||
- es == 0x6200 ||
- es == 0x9200) {
- return TRUE;
- } else if (memcmp(pName, "big5", 5) == 0) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-EXTERN int myconvIsSBCS(const char * pName)
-{
- int es = myconvGetES(cstoccsid(pName));
- if (es == 0x1100 ||
- es == 0x2100 ||
- es == 0x3100 ||
- es == 0x4100 ||
- es == 0x4105 ||
- es == 0x5100 ||
- es == 0x5150 ||
- es == 0x6100 ||
- es == 0x8100) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-
-EXTERN char myconvGetSubS(const char * code)
-{
- if (myconvIsEBCDIC(code)) {
- return 0x3F;
- } else if (myconvIsASCII(code)) {
- return 0x1A;
- } else if (myconvIsISO(code)) {
- return 0x1A;
- } else if (myconvIsEUC(code)) {
- return 0x1A;
- } else if (myconvIsUCS2(code)) {
- return 0x00;
- } else if (myconvIsUTF8(code)) {
- return 0x1A;
- }
- return 0x00;
-}
-
-
-EXTERN UniChar myconvGetSubD(const char * code)
-{
- if (myconvIsEBCDIC(code)) {
- return 0xFDFD;
- } else if (myconvIsASCII(code)) {
- return 0xFCFC;
- } else if (myconvIsISO(code)) {
- return 0x00;
- } else if (myconvIsEUC(code)) {
- return 0x00;
- } else if (myconvIsUCS2(code)) {
- return 0xFFFD;
- } else if (myconvIsUTF8(code)) {
- return 0x00;
- }
- return 0x00;
-}
-
diff --git a/storage/ibmdb2i/db2i_myconv.h b/storage/ibmdb2i/db2i_myconv.h
deleted file mode 100644
index 98032748148..00000000000
--- a/storage/ibmdb2i/db2i_myconv.h
+++ /dev/null
@@ -1,3201 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-/**
- @file
-
- @brief A direct map optimization of iconv and related functions
- This was show to significantly reduce character conversion cost
- for short strings when compared to calling iconv system code.
-*/
-
-#ifndef DB2I_MYCONV_H
-#define DB2I_MYCONV_H
-
-
-#include <sys/time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <wchar.h>
-#include <errno.h>
-#include <iconv.h>
-#include <ctype.h>
-#include <time.h>
-#include <stdarg.h>
-#include <string.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifdef __cplusplus
-#define INTERN inline
-#define EXTERN extern "C"
-#else
-#define INTERN static
-#define EXTERN extern
-#endif
-
-
-/* ANSI integer data types */
-#if defined(__OS400_TGTVRM__)
-/* for DTAMDL(*P128), datamodel(P128): int/long/pointer=4/4/16 */
-/* LLP64:4/4/8 is used for teraspace ?? */
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef int int32_t;
-typedef unsigned int uint32_t;
-typedef long long int64_t;
-typedef unsigned long long uint64_t;
-#elif defined(PASE)
-/* PASE uses IPL32: int/long/pointer=4/4/4 + long long */
-#elif defined(__64BIT__)
-/* AIX 64 bit uses LP64: int/long/pointer=4/8/8 */
-#endif
-
-#define CONVERTER_ICONV 1
-#define CONVERTER_DMAP 2
-
-#define DMAP_S2S 10
-#define DMAP_S2U 20
-#define DMAP_D2U 30
-#define DMAP_E2U 40
-#define DMAP_U2S 120
-#define DMAP_T2S 125
-#define DMAP_U2D 130
-#define DMAP_T2D 135
-#define DMAP_U2E 140
-#define DMAP_T2E 145
-#define DMAP_S28 220
-#define DMAP_D28 230
-#define DMAP_E28 240
-#define DMAP_82S 310
-#define DMAP_82D 320
-#define DMAP_82E 330
-#define DMAP_U28 410
-#define DMAP_82U 420
-#define DMAP_T28 425
-#define DMAP_U2U 510
-
-
-typedef struct __dmap_rec *dmap_t;
-
-struct __dmap_rec
-{
- uint32_t codingSchema;
- unsigned char * dmapS2S; /* SBCS -> SBCS */
- /* The following conversion needs be followed by conversion from UCS-2/UTF-16 to UTF-8 */
- UniChar * dmapD12U; /* DBCS(non-EUC) -> UCS-2/UTF-16 */
- UniChar * dmapD22U; /* DBCS(non-EUC) -> UCS-2/UTF-16 */
- UniChar * dmapE02U; /* EUC/SS0 -> UCS-2/UTF-16 */
- UniChar * dmapE12U; /* EUC/SS1 -> UCS-2/UTF-16 */
- UniChar * dmapE22U; /* EUC/0x8E + SS2 -> UCS-2/UTF-16 */
- UniChar * dmapE32U; /* EUC/0x8F + SS3 -> UCS-2/UTF-16 */
- uchar * dmapU2D; /* UCS-2 -> DBCS */
- uchar * dmapU2S; /* UCS-2 -> EUC SS0 */
- uchar * dmapU2M2; /* UCS-2 -> EUC SS1 */
- uchar * dmapU2M3; /* UCS-2 -> EUC SS2/SS3 */
- /* All of these pointers/tables are not used at the same time.
- * You may be able save some space if you consolidate them.
- */
- uchar * dmapS28; /* SBCS -> UTF-8 */
- uchar * dmapD28; /* DBCS -> UTF-8 */
-};
-
-typedef struct __myconv_rec *myconv_t;
-struct __myconv_rec
-{
- uint32_t converterType;
- uint32_t index; /* for close */
- union {
- iconv_t cnv_iconv;
- dmap_t cnv_dmap;
- };
- int32_t allocatedSize;
- int32_t fromCcsid;
- int32_t toCcsid;
- UniChar subD; /* DBCS substitution char */
- char subS; /* SBCS substitution char */
- UniChar srcSubD; /* DBCS substitution char of src codepage */
- char srcSubS; /* SBCS substitution char of src codepage */
- char from [41+1]; /* codepage name is up to 41 bytes */
- char to [41+1]; /* codepage name is up to 41 bytes */
-#ifdef __64BIT__
- char reserved[10]; /* align 128 */
-#else
- char reserved[14]; /* align 128 */
-#endif
-};
-
-
-EXTERN int32_t myconvDebug;
-
-
-
-EXTERN int myconvGetES(CCSID);
-EXTERN int myconvIsEBCDIC(const char *);
-EXTERN int myconvIsASCII(const char *);
-EXTERN int myconvIsUnicode(const char *); /* UTF-8, UTF-16, or UCS-2 */
-EXTERN int myconvIsUnicode2(const char *); /* 2 byte Unicode */
-EXTERN int myconvIsUCS2(const char *);
-EXTERN int myconvIsUTF16(const char *);
-EXTERN int myconvIsUTF8(const char *);
-EXTERN int myconvIsEUC(const char *);
-EXTERN int myconvIsISO(const char *);
-EXTERN int myconvIsSBCS(const char *);
-EXTERN int myconvIsDBCS(const char *);
-EXTERN char myconvGetSubS(const char *);
-EXTERN UniChar myconvGetSubD(const char *);
-
-
-EXTERN myconv_t myconv_open(const char*, const char*, int32_t);
-EXTERN int myconv_close(myconv_t);
-
-INTERN size_t myconv_iconv(myconv_t cd ,
- char** inBuf,
- size_t* inBytesLeft,
- char** outBuf,
- size_t* outBytesLeft,
- size_t* numSub)
-{
- return iconv(cd->cnv_iconv, inBuf, inBytesLeft, outBuf, outBytesLeft);
-}
-
-INTERN size_t myconv_dmap(myconv_t cd,
- char** inBuf,
- size_t* inBytesLeft,
- char** outBuf,
- size_t* outBytesLeft,
- size_t* numSub)
-{
- if (cd->cnv_dmap->codingSchema == DMAP_S2S) {
- register unsigned char * dmapS2S=cd->cnv_dmap->dmapS2S;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- } else {
- *pOut=dmapS2S[*pIn];
- if (*pOut == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(*inBytesLeft-inLen);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (*pOut == subS) {
- if ((*pOut=dmapS2S[*pIn]) == subS) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- }
- }
- ++pIn;
- --inLen;
- ++pOut;
- }
- *outBytesLeft-=(*inBytesLeft-inLen);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_E2U) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapE02U=(uchar *) (cd->cnv_dmap->dmapE02U);
- register uchar * dmapE12U=(uchar *) (cd->cnv_dmap->dmapE12U);
- register uchar * dmapE22U=(uchar *) (cd->cnv_dmap->dmapE22U);
- register uchar * dmapE32U=(uchar *) (cd->cnv_dmap->dmapE32U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- if (*pIn == 0x8E) { /* SS2 */
- if (inLen < 2) {
- if (cd->fromCcsid == 33722 || /* IBM-eucJP */
- cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE22U[offset] == 0x00 &&
- dmapE22U[offset+1] == 0x00) { /* 2 bytes */
- if (inLen < 3) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60 + 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE22U[offset] == 0x00 &&
- dmapE22U[offset+1] == 0x00) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- *pOut=dmapE22U[offset];
- ++pOut;
- *pOut=dmapE22U[offset+1];
- ++pOut;
- if (dmapE22U[offset] == 0xFF &&
- dmapE22U[offset+1] == 0xFD) {
- if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=3;
- } else { /* 1 bytes */
- *pOut=dmapE22U[offset];
- ++pOut;
- *pOut=dmapE22U[offset+1];
- ++pOut;
- ++pIn;
- inLen-=2;
- }
- } else if (*pIn == 0x8F) { /* SS3 */
- if (inLen < 2) {
- if (cd->fromCcsid == 33722) /* IBM-eucJP */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 970 || /* IBM-eucKR */
- cd->fromCcsid == 964 || /* IBM-eucTW */
- cd->fromCcsid == 1383 || /* IBM-eucCN */
- (cd->fromCcsid == 33722 && 3 <= inLen)) /* IBM-eucJP */
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE32U[offset] == 0x00 &&
- dmapE32U[offset+1] == 0x00) { /* 0x8F + 2 bytes */
- if (inLen < 3) {
- if (cd->fromCcsid == 33722)
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60 + 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE32U[offset] == 0x00 &&
- dmapE32U[offset+1] == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- *pOut=dmapE32U[offset];
- ++pOut;
- *pOut=dmapE32U[offset+1];
- ++pOut;
- if (dmapE32U[offset] == 0xFF &&
- dmapE32U[offset+1] == 0xFD) {
- if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=3;
- } else { /* 0x8F + 1 bytes */
- *pOut=dmapE32U[offset];
- ++pOut;
- *pOut=dmapE32U[offset+1];
- ++pOut;
- ++pIn;
- inLen-=2;
- }
-
- } else {
- offset=*pIn;
- offset<<=1;
- if (dmapE02U[offset] == 0x00 &&
- dmapE02U[offset+1] == 0x00) { /* SS1 */
- if (inLen < 2) {
- if ((cd->fromCcsid == 33722 && (*pIn == 0xA0 || (0xA9 <= *pIn && *pIn <= 0xAF) || *pIn == 0xFF)) ||
- (cd->fromCcsid == 970 && (*pIn == 0xA0 || *pIn == 0xAD || *pIn == 0xAE || *pIn == 0xAF || *pIn == 0xFF)) ||
- (cd->fromCcsid == 964 && (*pIn == 0xA0 || (0xAA <= *pIn && *pIn <= 0xC1) || *pIn == 0xC3 || *pIn == 0xFE || *pIn == 0xFF)) ||
- (cd->fromCcsid == 1383 && (*pIn == 0xA0 || *pIn == 0xFF)))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE12U[offset] == 0x00 &&
- dmapE12U[offset+1] == 0x00) { /* undefined mapping */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- *pOut=dmapE12U[offset];
- ++pOut;
- *pOut=dmapE12U[offset+1];
- ++pOut;
- if (dmapE12U[offset] == 0xFF &&
- dmapE12U[offset+1] == 0xFD) {
- if (pIn[-1] * 0x100 + pIn[0] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=2;
- } else {
- *pOut=dmapE02U[offset];
- ++pOut;
- *pOut=dmapE02U[offset+1];
- ++pOut;
- if (dmapE02U[offset] == 0x00 &&
- dmapE02U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- ++pIn;
- --inLen;
- }
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_E28) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapE02U=(uchar *) (cd->cnv_dmap->dmapE02U);
- register uchar * dmapE12U=(uchar *) (cd->cnv_dmap->dmapE12U);
- register uchar * dmapE22U=(uchar *) (cd->cnv_dmap->dmapE22U);
- register uchar * dmapE32U=(uchar *) (cd->cnv_dmap->dmapE32U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- register UniChar in; /* copy part of U28 */
- register UniChar ucs2;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- if (*pIn == 0x8E) { /* SS2 */
- if (inLen < 2) {
- if (cd->fromCcsid == 33722 || /* IBM-eucJP */
- cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE22U[offset] == 0x00 &&
- dmapE22U[offset+1] == 0x00) { /* 2 bytes */
- if (inLen < 3) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60 + 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE22U[offset] == 0x00 &&
- dmapE22U[offset+1] == 0x00) {
- if (cd->fromCcsid == 964) /* IBM-eucTW */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- in=dmapE22U[offset];
- in<<=8;
- in+=dmapE22U[offset+1];
- if (dmapE22U[offset] == 0xFF &&
- dmapE22U[offset+1] == 0xFD) {
- if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=3;
- } else { /* 1 bytes */
- in=dmapE22U[offset];
- in<<=8;
- in+=dmapE22U[offset+1];
- ++pIn;
- inLen-=2;
- }
- } else if (*pIn == 0x8F) { /* SS3 */
- if (inLen < 2) {
- if (cd->fromCcsid == 33722) /* IBM-eucJP */
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- ++pIn;
- if (*pIn < 0xA0) {
- if (cd->fromCcsid == 970 || /* IBM-eucKR */
- cd->fromCcsid == 964 || /* IBM-eucTW */
- cd->fromCcsid == 1383 || /* IBM-eucCN */
- (cd->fromCcsid == 33722 && 3 <= inLen)) /* IBM-eucJP */
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE32U[offset] == 0x00 &&
- dmapE32U[offset+1] == 0x00) { /* 0x8F + 2 bytes */
- if (inLen < 3) {
- if (cd->fromCcsid == 33722)
- errno=EINVAL; /* 22 */
- else
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60 + 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE32U[offset] == 0x00 &&
- dmapE32U[offset+1] == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- return -1;
- }
- in=dmapE32U[offset];
- in<<=8;
- in+=dmapE32U[offset+1];
- if (dmapE32U[offset] == 0xFF &&
- dmapE32U[offset+1] == 0xFD) {
- if (pIn[-2] * 0x100 + pIn[-1] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=3;
- } else { /* 0x8F + 1 bytes */
- in=dmapE32U[offset];
- in<<=8;
- in+=dmapE32U[offset+1];
- ++pIn;
- inLen-=2;
- }
-
- } else {
- offset=*pIn;
- offset<<=1;
- if (dmapE02U[offset] == 0x00 &&
- dmapE02U[offset+1] == 0x00) { /* SS1 */
- if (inLen < 2) {
- if ((cd->fromCcsid == 33722 && (*pIn == 0xA0 || (0xA9 <= *pIn && *pIn <= 0xAF) || *pIn == 0xFF)) ||
- (cd->fromCcsid == 970 && (*pIn == 0xA0 || *pIn == 0xAD || *pIn == 0xAE || *pIn == 0xAF || *pIn == 0xFF)) ||
- (cd->fromCcsid == 964 && (*pIn == 0xA0 || (0xAA <= *pIn && *pIn <= 0xC1) || *pIn == 0xC3 || *pIn == 0xFE || *pIn == 0xFF)) ||
- (cd->fromCcsid == 1383 && (*pIn == 0xA0 || *pIn == 0xFF)))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- offset=(*pIn - 0xA0) * 0x60;
- ++pIn;
- if (*pIn < 0xA0) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- offset+=(*pIn - 0xA0);
- offset<<=1;
- if (dmapE12U[offset] == 0x00 &&
- dmapE12U[offset+1] == 0x00) { /* undefined mapping */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- in=dmapE12U[offset];
- in<<=8;
- in+=dmapE12U[offset+1];
- if (dmapE12U[offset] == 0xFF &&
- dmapE12U[offset+1] == 0xFD) {
- if (pIn[-1] * 0x100 + pIn[0] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=2;
- } else {
- in=dmapE02U[offset];
- in<<=8;
- in+=dmapE02U[offset+1];
- if (dmapE02U[offset] == 0x00 &&
- dmapE02U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- ++pIn;
- --inLen;
- }
- }
- ucs2=in;
- if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=ucs2; /* dmapD12U[offset+1]; */
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else if ((in & 0xFC00) == 0xD800) {
- *pOut=0xEF;
- ++pOut;
- *pOut=0xBF;
- ++pOut;
- *pOut=0xBD;
- ++pOut;
- } else {
- register uchar byte;
- register uchar work;
- byte=(ucs2>>8); /* dmapD12U[offset]; */
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=(ucs2>>8); /* dmapD12U[offset]; */
- byte<<=2;
- work=ucs2; /* dmapD12U[offset+1]; */
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=ucs2; /* dmapD12U[offset+1]; */
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- /* end of U28 */
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_U2E) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register uchar * dmapU2M2=cd->cnv_dmap->dmapU2M2 - 0x80 * 2;
- register uchar * dmapU2M3=cd->cnv_dmap->dmapU2M3 - 0x80 * 3;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- register size_t rc=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if (in < 0x100 && dmapU2S[in] != 0x0000) {
- if ((*pOut=dmapU2S[in]) == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- ++pOut;
- } else {
- in<<=1;
- if (dmapU2M2[in] == 0x00) { /* not found in dmapU2M2 */
- in*=1.5;
- if (dmapU2M3[in] == 0x00) { /* not found in dmapU2M3*/
- *pOut=pSubD[0];
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- ++rc;
- } else {
- *pOut=dmapU2M3[in];
- ++pOut;
- *pOut=dmapU2M3[1+in];
- ++pOut;
- *pOut=dmapU2M3[2+in];
- ++pOut;
- }
- } else {
- *pOut=dmapU2M2[in];
- ++pOut;
- if (dmapU2M2[1+in] == 0x00) {
- if (*pOut == subS) {
- in>>=1;
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2M2[1+in];
- ++pOut;
- if (memcmp(pOut-2, pSubD, 2) == 0) {
- in>>=1;
- if (in != cd->srcSubD) {
- ++numS;
- ++rc;
- }
- }
- }
- }
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return rc; /* compatibility to iconv() */
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_T2E) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register uchar * dmapU2M2=cd->cnv_dmap->dmapU2M2 - 0x80 * 2;
- register uchar * dmapU2M3=cd->cnv_dmap->dmapU2M3 - 0x80 * 3;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- register size_t rc=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen-1;
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return 0;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if (0xD800 <= in && in <= 0xDBFF) { /* first byte of surrogate */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- ++numS;
- *numSub+=numS;
- return -1;
-
- } else if (0xDC00 <= in && in <= 0xDFFF) { /* second byte of surrogate */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return -1;
-
- } else if (in < 0x100 && dmapU2S[in] != 0x0000) {
- if ((*pOut=dmapU2S[in]) == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- ++pOut;
- } else {
- in<<=1;
- if (dmapU2M2[in] == 0x00) { /* not found in dmapU2M2 */
- in*=1.5;
- if (dmapU2M3[in] == 0x00) { /* not found in dmapU2M3*/
- *pOut=pSubD[0];
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- ++rc;
- } else {
- *pOut=dmapU2M3[in];
- ++pOut;
- *pOut=dmapU2M3[1+in];
- ++pOut;
- *pOut=dmapU2M3[2+in];
- ++pOut;
- }
- } else {
- *pOut=dmapU2M2[in];
- ++pOut;
- if (dmapU2M2[1+in] == 0x00) {
- if (*pOut == subS) {
- in>>=1;
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2M2[1+in];
- ++pOut;
- if (memcmp(pOut-2, pSubD, 2) == 0) {
- in>>=1;
- if (in != cd->srcSubD) {
- ++numS;
- ++rc;
- }
- }
- }
- }
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_82E) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register uchar * dmapU2M2=cd->cnv_dmap->dmapU2M2 - 0x80 * 2;
- register uchar * dmapU2M3=cd->cnv_dmap->dmapU2M3 - 0x80 * 3;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- register size_t rc=0;
- while (0 < inLen) {
- register uint32_t in;
- uint32_t in2;
- if (pLastOutBuf < pOut)
- break;
- /* convert from UTF-8 to UCS-2 */
- if (*pIn == 0x00) {
- in=0x0000;
- ++pIn;
- --inLen;
- } else { /* 82U: */
- register uchar byte1=*pIn;
- if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */
- /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/
- in=byte1;
- ++pIn;
- --inLen;
- } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */
- if (inLen < 2) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- /* 2 bytes sequence:
- 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */
- register uchar byte2;
- ++pIn;
- byte2=*pIn;
- if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */
- register uchar work=byte1;
- work<<=6;
- byte2&=0x3F; /* 0b00111111; */
- byte2|=work;
-
- byte1&=0x1F; /* 0b00011111; */
- byte1>>=2;
- in=byte1;
- in<<=8;
- in+=byte2;
- inLen-=2;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */
- /* 3 bytes sequence:
- 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */
- register uchar byte2;
- register uchar byte3;
- if (inLen < 3) {
- if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- if ((byte2 & 0xC0) != 0x80 ||
- (byte3 & 0xC0) != 0x80 ||
- (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- *numSub+=numS;
- return -1;
- }
- {
- register uchar work=byte2;
- work<<=6;
- byte3&=0x3F; /* 0b00111111; */
- byte3|=work;
-
- byte2&=0x3F; /* 0b00111111; */
- byte2>>=2;
-
- byte1<<=4;
- in=byte1 | byte2;;
- in<<=8;
- in+=byte3;
- inLen-=3;
- ++pIn;
- }
- } else if ((0xF0 <= byte1 && byte1 <= 0xF4)) { /* (bytes1 & 11111000) == 0x1110000 */
- /* 4 bytes sequence
- 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx
- where uuuuu = wwww + 1 */
- register uchar byte2;
- register uchar byte3;
- register uchar byte4;
- if (inLen < 4) {
- if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) ||
- (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) ||
- (cd->toCcsid == 13488) )
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- ++pIn;
- byte4=*pIn;
- if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */
- (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */
- (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */
- register uchar work=byte2;
- if (byte1 == 0xF0 && byte2 < 0x90) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- /* iconv() returns 0 for 0xF4908080 and convert to 0x00
- } else if (byte1 == 0xF4 && byte2 > 0x8F) {
- errno=EINVAL;
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- */
- }
-
- work&=0x30; /* 0b00110000; */
- work>>=4;
- byte1&=0x07; /* 0b00000111; */
- byte1<<=2;
- byte1+=work; /* uuuuu */
- --byte1; /* wwww */
-
- work=byte1 & 0x0F;
- work>>=2;
- work+=0xD8; /* 0b11011011; */
- in=work;
- in<<=8;
-
- byte1<<=6;
- byte2<<=2;
- byte2&=0x3C; /* 0b00111100; */
- work=byte3;
- work>>=4;
- work&=0x03; /* 0b00000011; */
- work|=byte1;
- work|=byte2;
- in+=work;
-
- work=byte3;
- work>>=2;
- work&=0x03; /* 0b00000011; */
- work|=0xDC; /* 0b110111xx; */
- in2=work;
- in2<<=8;
-
- byte3<<=6;
- byte4&=0x3F; /* 0b00111111; */
- byte4|=byte3;
- in2+=byte4;
- inLen-=4;
- ++pIn;
-#ifdef match_with_GBK
- if ((0xD800 == in && in2 < 0xDC80) ||
- (0xD840 == in && in2 < 0xDC80) ||
- (0xD880 == in && in2 < 0xDC80) ||
- (0xD8C0 == in && in2 < 0xDC80) ||
- (0xD900 == in && in2 < 0xDC80) ||
- (0xD940 == in && in2 < 0xDC80) ||
- (0xD980 == in && in2 < 0xDC80) ||
- (0xD9C0 == in && in2 < 0xDC80) ||
- (0xDA00 == in && in2 < 0xDC80) ||
- (0xDA40 == in && in2 < 0xDC80) ||
- (0xDA80 == in && in2 < 0xDC80) ||
- (0xDAC0 == in && in2 < 0xDC80) ||
- (0xDB00 == in && in2 < 0xDC80) ||
- (0xDB40 == in && in2 < 0xDC80) ||
- (0xDB80 == in && in2 < 0xDC80) ||
- (0xDBC0 == in && in2 < 0xDC80)) {
-#else
- if ((0xD800 <= in && in <= 0xDBFF) &&
- (0xDC00 <= in2 && in2 <= 0xDFFF)) {
-#endif
- *pOut=subS;
- ++pOut;
- ++numS;
- continue;
- }
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
- } else if (0xF5 <= byte1 && byte1 <= 0xFF) { /* minic iconv() behavior */
- if (inLen < 4 ||
- (inLen >= 4 && byte1 == 0xF8 && pIn[1] < 0x90) ||
- pIn[1] < 0x80 || 0xBF < pIn[1] ||
- pIn[2] < 0x80 || 0xBF < pIn[2] ||
- pIn[3] < 0x80 || 0xBF < pIn[3] ) {
- if (inLen == 1)
- errno=EINVAL; /* 22 */
- else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else if (inLen >= 4 && (byte1 == 0xF8 || (pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
-
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- } else if ((pIn[1] == 0x80 || pIn[1] == 0x90 || pIn[1] == 0xA0 || pIn[1] == 0xB0) &&
- pIn[2] < 0x82) {
- *pOut=subS; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- continue;
- } else {
- *pOut=pSubD[0]; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- continue;
- /* iconv() returns 0 with strange 1 byte converted values */
- }
-
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- /* end of UTF-8 to UCS-2 */
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if (in < 0x100 && dmapU2S[in] != 0x0000) {
- if ((*pOut=dmapU2S[in]) == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- ++pOut;
- } else {
- in<<=1;
- if (dmapU2M2[in] == 0x00) { /* not found in dmapU2M2 */
- in*=1.5;
- if (dmapU2M3[in] == 0x00) { /* not found in dmapU2M3*/
- *pOut=pSubD[0];
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- ++rc;
- } else {
- *pOut=dmapU2M3[in];
- ++pOut;
- *pOut=dmapU2M3[1+in];
- ++pOut;
- *pOut=dmapU2M3[2+in];
- ++pOut;
- }
- } else {
- *pOut=dmapU2M2[in];
- ++pOut;
- if (dmapU2M2[1+in] == 0x00) {
- if (*pOut == subS) {
- in>>=1;
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2M2[1+in];
- ++pOut;
- if (memcmp(pOut-2, pSubD, 2) == 0) {
- in>>=1;
- if (in != cd->srcSubD) {
- ++numS;
- ++rc;
- }
- }
- }
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_S2U) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- offset=*pIn;
- offset<<=1;
- *pOut=dmapD12U[offset];
- ++pOut;
- *pOut=dmapD12U[offset+1];
- ++pOut;
- if (dmapD12U[offset] == 0x00) {
- if (dmapD12U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- } else if (dmapD12U[offset+1] == 0x00) {
- pOut-=2;
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- ++pIn;
- --inLen;
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_S28) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- register UniChar in; /* copy part of U28 */
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- offset=*pIn;
- offset<<=1;
- in=dmapD12U[offset];
- in<<=8;
- in+=dmapD12U[offset+1];
- if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- if (in == 0x000) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=dmapD12U[offset+1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else if ((in & 0xFC00) == 0xD800) { /* There should not be no surrogate character in SBCS. */
- *pOut=0xEF;
- ++pOut;
- *pOut=0xBF;
- ++pOut;
- *pOut=0xBD;
- ++pOut;
- } else {
- register uchar byte;
- register uchar work;
- byte=dmapD12U[offset];
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=dmapD12U[offset];
- byte<<=2;
- work=dmapD12U[offset+1];
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=dmapD12U[offset+1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- /* end of U28 */
- if (dmapD12U[offset] == 0x00) {
- if (dmapD12U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- }
- ++pIn;
- --inLen;
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_U2S) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
-
- *inBytesLeft=inLen;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- } else {
- if ((*pOut=dmapU2S[in]) == 0x00) {
- *pOut=subS;
- ++numS;
- errno=EINVAL; /* 22 */
- } else if (*pOut == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- }
- ++pOut;
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return numS;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_T2S) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
-
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return 0;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
-
- } else if (0xD800 <= in && in <= 0xDFFF) { /* 0xD800-0xDFFF, surrogate first and second values */
- if (0xDC00 <= in ) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
-
- } else if (inLen < 4) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- return -1;
-
- } else {
- register uint32_t in2;
- in2=pIn[2];
- in2<<=8;
- in2+=pIn[3];
- if (0xDC00 <= in2 && in2 <= 0xDFFF) { /* second surrogate character =0xDC00 - 0xDFFF*/
- *pOut=subS;
- ++numS;
- pIn+=4;
- } else {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- }
- } else {
- if ((*pOut=dmapU2S[in]) == 0x00) {
- *pOut=subS;
- ++numS;
- errno=EINVAL; /* 22 */
- } else if (*pOut == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- }
- ++pOut;
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_82S) {
- register uchar * dmapU2S=cd->cnv_dmap->dmapU2S;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- uint32_t in2; /* The second surrogate value */
- if (pLastOutBuf < pOut)
- break;
- /* convert from UTF-8 to UCS-2 */
- if (*pIn == 0x00) {
- in=0x0000;
- ++pIn;
- --inLen;
- } else { /* 82U: */
- register uchar byte1=*pIn;
- if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */
- /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/
- in=byte1;
- ++pIn;
- --inLen;
- } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */
- if (inLen < 2) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- /* 2 bytes sequence:
- 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */
- register uchar byte2;
- ++pIn;
- byte2=*pIn;
- if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */
- register uchar work=byte1;
- work<<=6;
- byte2&=0x3F; /* 0b00111111; */
- byte2|=work;
-
- byte1&=0x1F; /* 0b00011111; */
- byte1>>=2;
- in=byte1;
- in<<=8;
- in+=byte2;
- inLen-=2;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */
- /* 3 bytes sequence:
- 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */
- register uchar byte2;
- register uchar byte3;
- if (inLen < 3) {
- if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- if ((byte2 & 0xC0) != 0x80 ||
- (byte3 & 0xC0) != 0x80 ||
- (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- *numSub+=numS;
- return -1;
- }
- {
- register uchar work=byte2;
- work<<=6;
- byte3&=0x3F; /* 0b00111111; */
- byte3|=work;
-
- byte2&=0x3F; /* 0b00111111; */
- byte2>>=2;
-
- byte1<<=4;
- in=byte1 | byte2;;
- in<<=8;
- in+=byte3;
- inLen-=3;
- ++pIn;
- }
- } else if ((0xF0 <= byte1 && byte1 <= 0xF4) || /* (bytes1 & 11111000) == 0x1110000 */
- ((byte1&=0xF7) && 0xF0 <= byte1 && byte1 <= 0xF4)) { /* minic iconv() behavior */
- /* 4 bytes sequence
- 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx
- where uuuuu = wwww + 1 */
- register uchar byte2;
- register uchar byte3;
- register uchar byte4;
- if (inLen < 4) {
- if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) ||
- (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) ||
- (cd->toCcsid == 13488) )
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- ++pIn;
- byte4=*pIn;
- if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */
- (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */
- (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */
- register uchar work=byte2;
- if (byte1 == 0xF0 && byte2 < 0x90) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- /* iconv() returns 0 for 0xF4908080 and convert to 0x00
- } else if (byte1 == 0xF4 && byte2 > 0x8F) {
- errno=EINVAL;
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- */
- }
-
- work&=0x30; /* 0b00110000; */
- work>>=4;
- byte1&=0x07; /* 0b00000111; */
- byte1<<=2;
- byte1+=work; /* uuuuu */
- --byte1; /* wwww */
-
- work=byte1 & 0x0F;
- work>>=2;
- work+=0xD8; /* 0b11011011; */
- in=work;
- in<<=8;
-
- byte1<<=6;
- byte2<<=2;
- byte2&=0x3C; /* 0b00111100; */
- work=byte3;
- work>>=4;
- work&=0x03; /* 0b00000011; */
- work|=byte1;
- work|=byte2;
- in+=work;
-
- work=byte3;
- work>>=2;
- work&=0x03; /* 0b00000011; */
- work|=0xDC; /* 0b110111xx; */
- in2=work;
- in2<<=8;
-
- byte3<<=6;
- byte4&=0x3F; /* 0b00111111; */
- byte4|=byte3;
- in2+=byte4;
- inLen-=4;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xF0) { /* minic iconv() behavior */
- if (inLen < 4 ||
- pIn[1] < 0x80 || 0xBF < pIn[1] ||
- pIn[2] < 0x80 || 0xBF < pIn[2] ||
- pIn[3] < 0x80 || 0xBF < pIn[3] ) {
- if (inLen == 1)
- errno=EINVAL; /* 22 */
- else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else if (inLen >= 4 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
-
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- } else {
- *pOut=subS; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- /* UTF-8_IBM-850 0xF0908080 : converted value does not match, iconv=0x00, dmap=0x7F
- UTF-8_IBM-850 0xF0908081 : converted value does not match, iconv=0x01, dmap=0x7F
- UTF-8_IBM-850 0xF0908082 : converted value does not match, iconv=0x02, dmap=0x7F
- UTF-8_IBM-850 0xF0908083 : converted value does not match, iconv=0x03, dmap=0x7F
- ....
- UTF-8_IBM-850 0xF09081BE : converted value does not match, iconv=0x7E, dmap=0x7F
- UTF-8_IBM-850 0xF09081BF : converted value does not match, iconv=0x1C, dmap=0x7F
- UTF-8_IBM-850 0xF09082A0 : converted value does not match, iconv=0xFF, dmap=0x7F
- UTF-8_IBM-850 0xF09082A1 : converted value does not match, iconv=0xAD, dmap=0x7F
- ....
- */
- continue;
- /* iconv() returns 0 with strange 1 byte converted values */
- }
-
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- /* end of UTF-8 to UCS-2 */
- if (in == 0x0000) {
- *pOut=0x00;
- } else {
- if ((*pOut=dmapU2S[in]) == 0x00) {
- *pOut=subS;
- ++numS;
- errno=EINVAL; /* 22 */
- } else if (*pOut == subS) {
- if (in != cd->srcSubS) {
- ++numS;
- }
- }
- }
- ++pOut;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_D2U) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U);
- register uchar * dmapD22U=(uchar *) (cd->cnv_dmap->dmapD22U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- offset=*pIn;
- offset<<=1;
- if (dmapD12U[offset] == 0x00 &&
- dmapD12U[offset+1] == 0x00) { /* DBCS */
- if (inLen < 2) {
- if (*pIn == 0x80 || *pIn == 0xFF ||
- (cd->fromCcsid == 943 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0xA0 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xEF || *pIn == 0xFD || *pIn == 0xFE)) ||
- (cd->fromCcsid == 932 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0x87 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xED || *pIn == 0xEE || *pIn == 0xEF)) ||
- (cd->fromCcsid == 1381 && ((0x85 <= *pIn && *pIn <= 0x8B) || (0xAA <= *pIn && *pIn <= 0xAF) || (0xF8 <= *pIn && *pIn <= 0xFE))))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- offset-=0x100;
- ++pIn;
- offset<<=8;
- offset+=(*pIn * 2);
- if (dmapD22U[offset] == 0x00 &&
- dmapD22U[offset+1] == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- *pOut=dmapD22U[offset];
- ++pOut;
- *pOut=dmapD22U[offset+1];
- ++pOut;
- if (dmapD22U[offset] == 0xFF &&
- dmapD22U[offset+1] == 0xFD) {
- if (pIn[-1] * 0x100 + pIn[0] != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=2;
- } else { /* SBCS */
- *pOut=dmapD12U[offset];
- ++pOut;
- *pOut=dmapD12U[offset+1];
- ++pOut;
- if (dmapD12U[offset] == 0x00 &&
- dmapD12U[offset+1] == 0x1A) {
- if (*pIn != cd->srcSubS)
- ++numS;
- }
- ++pIn;
- --inLen;
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_D28) {
- /* use uchar * instead of UniChar to avoid memcpy */
- register uchar * dmapD12U=(uchar *) (cd->cnv_dmap->dmapD12U);
- register uchar * dmapD22U=(uchar *) (cd->cnv_dmap->dmapD22U);
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register int offset;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- register UniChar in; /* copy part of U28 */
- register UniChar ucs2;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else {
- offset=*pIn;
- offset<<=1;
- if (dmapD12U[offset] == 0x00 &&
- dmapD12U[offset+1] == 0x00) { /* DBCS */
- if (inLen < 2) {
- if (*pIn == 0x80 || *pIn == 0xFF ||
- (cd->fromCcsid == 943 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0xA0 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xEF || *pIn == 0xFD || *pIn == 0xFE)) ||
- (cd->fromCcsid == 932 && (*pIn == 0x85 || *pIn == 0x86 || *pIn == 0x87 || *pIn == 0xEB || *pIn == 0xEC || *pIn == 0xED || *pIn == 0xEE || *pIn == 0xEF)) ||
- (cd->fromCcsid == 1381 && ((0x85 <= *pIn && *pIn <= 0x8B) || (0xAA <= *pIn && *pIn <= 0xAF) || (0xF8 <= *pIn && *pIn <= 0xFE))))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- offset-=0x100;
- ++pIn;
- offset<<=8;
- offset+=(*pIn * 2);
- if (dmapD22U[offset] == 0x00 &&
- dmapD22U[offset+1] == 0x00) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- return -1;
- }
- in=dmapD22U[offset];
- in<<=8;
- in+=dmapD22U[offset+1];
- ucs2=in;
- if (dmapD22U[offset] == 0xFF &&
- dmapD22U[offset+1] == 0xFD) {
- if (in != cd->srcSubD)
- ++numS;
- }
- ++pIn;
- inLen-=2;
- } else { /* SBCS */
- in=dmapD12U[offset];
- in<<=8;
- in+=dmapD12U[offset+1];
- ucs2=in;
- if (dmapD12U[offset] == 0x00 &&
- dmapD12U[offset+1] == 0x1A) {
- if (in != cd->srcSubS)
- ++numS;
- }
- ++pIn;
- --inLen;
- }
- if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=ucs2; /* dmapD12U[offset+1]; */
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else if ((in & 0xFC00) == 0xD800) { /* There should not be no surrogate character in SBCS. */
- *pOut=0xEF;
- ++pOut;
- *pOut=0xBF;
- ++pOut;
- *pOut=0xBD;
- ++pOut;
- } else {
- register uchar byte;
- register uchar work;
- byte=(ucs2>>8); /* dmapD12U[offset]; */
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=(ucs2>>8); /* dmapD12U[offset]; */
- byte<<=2;
- work=ucs2; /* dmapD12U[offset+1]; */
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=ucs2; /* dmapD12U[offset+1]; */
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- /* end of U28 */
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_U2D) {
- register uchar * dmapU2D=cd->cnv_dmap->dmapU2D;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
-
- *inBytesLeft=inLen;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else {
- in<<=1;
- *pOut=dmapU2D[in];
- ++pOut;
- if (dmapU2D[in+1] == 0x00) { /* SBCS */
- if (*pOut == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2D[in+1];
- ++pOut;
- if (dmapU2D[in] == pSubD[0] &&
- dmapU2D[in+1] == pSubD[1]) {
- in>>=1;
- if (in != cd->srcSubD)
- ++numS;
- }
- }
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return numS; /* to minic iconv() behavior */
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_T2D) {
- register uchar * dmapU2D=cd->cnv_dmap->dmapU2D;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return 0;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if (0xD800 <= in && in <= 0xDBFF) { /* first byte of surrogate */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- ++numS;
- *numSub+=numS;
- return -1;
-
- } else if (0xDC00 <= in && in <= 0xDFFF) { /* second byte of surrogate */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- ++numS;
- *numSub+=numS;
- return -1;
-
- } else {
- in<<=1;
- *pOut=dmapU2D[in];
- ++pOut;
- if (dmapU2D[in+1] == 0x00) { /* SBCS */
- if (*pOut == subS) {
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2D[in+1];
- ++pOut;
- if (dmapU2D[in] == pSubD[0] &&
- dmapU2D[in+1] == pSubD[1]) {
- in>>=1;
- if (in != cd->srcSubD)
- ++numS;
- }
- }
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0; /* to minic iconv() behavior */
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_82D) {
- register uchar * dmapU2D=cd->cnv_dmap->dmapU2D;
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register char subS=cd->subS;
- register char * pSubD=(char *) &(cd->subD);
- register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- uint32_t in2;
- if (pLastOutBuf < pOut)
- break;
- /* convert from UTF-8 to UCS-2 */
- if (*pIn == 0x00) {
- in=0x0000;
- ++pIn;
- --inLen;
- } else { /* 82U: */
- register uchar byte1=*pIn;
- if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */
- /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/
- in=byte1;
- ++pIn;
- --inLen;
- } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */
- if (inLen < 2) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- /* 2 bytes sequence:
- 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */
- register uchar byte2;
- ++pIn;
- byte2=*pIn;
- if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */
- register uchar work=byte1;
- work<<=6;
- byte2&=0x3F; /* 0b00111111; */
- byte2|=work;
-
- byte1&=0x1F; /* 0b00011111; */
- byte1>>=2;
- in=byte1;
- in<<=8;
- in+=byte2;
- inLen-=2;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */
- /* 3 bytes sequence:
- 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */
- register uchar byte2;
- register uchar byte3;
- if (inLen < 3) {
- if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- if ((byte2 & 0xC0) != 0x80 ||
- (byte3 & 0xC0) != 0x80 ||
- (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- *numSub+=numS;
- return -1;
- }
- {
- register uchar work=byte2;
- work<<=6;
- byte3&=0x3F; /* 0b00111111; */
- byte3|=work;
-
- byte2&=0x3F; /* 0b00111111; */
- byte2>>=2;
-
- byte1<<=4;
- in=byte1 | byte2;;
- in<<=8;
- in+=byte3;
- inLen-=3;
- ++pIn;
- }
- } else if ((0xF0 <= byte1 && byte1 <= 0xF4)) { /* (bytes1 & 11111000) == 0x1110000 */
- /* 4 bytes sequence
- 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx
- where uuuuu = wwww + 1 */
- register uchar byte2;
- register uchar byte3;
- register uchar byte4;
- if (inLen < 4) {
- if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) ||
- (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) ||
- (cd->toCcsid == 13488) )
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- ++pIn;
- byte4=*pIn;
- if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */
- (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */
- (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */
- register uchar work=byte2;
- if (byte1 == 0xF0 && byte2 < 0x90) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- /* iconv() returns 0 for 0xF4908080 and convert to 0x00
- } else if (byte1 == 0xF4 && byte2 > 0x8F) {
- errno=EINVAL;
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- */
- }
-
- work&=0x30; /* 0b00110000; */
- work>>=4;
- byte1&=0x07; /* 0b00000111; */
- byte1<<=2;
- byte1+=work; /* uuuuu */
- --byte1; /* wwww */
-
- work=byte1 & 0x0F;
- work>>=2;
- work+=0xD8; /* 0b11011011; */
- in=work;
- in<<=8;
-
- byte1<<=6;
- byte2<<=2;
- byte2&=0x3C; /* 0b00111100; */
- work=byte3;
- work>>=4;
- work&=0x03; /* 0b00000011; */
- work|=byte1;
- work|=byte2;
- in+=work;
-
- work=byte3;
- work>>=2;
- work&=0x03; /* 0b00000011; */
- work|=0xDC; /* 0b110111xx; */
- in2=work;
- in2<<=8;
-
- byte3<<=6;
- byte4&=0x3F; /* 0b00111111; */
- byte4|=byte3;
- in2+=byte4;
- inLen-=4;
- ++pIn;
-#ifdef match_with_GBK
- if ((0xD800 == in && in2 < 0xDC80) ||
- (0xD840 == in && in2 < 0xDC80) ||
- (0xD880 == in && in2 < 0xDC80) ||
- (0xD8C0 == in && in2 < 0xDC80) ||
- (0xD900 == in && in2 < 0xDC80) ||
- (0xD940 == in && in2 < 0xDC80) ||
- (0xD980 == in && in2 < 0xDC80) ||
- (0xD9C0 == in && in2 < 0xDC80) ||
- (0xDA00 == in && in2 < 0xDC80) ||
- (0xDA40 == in && in2 < 0xDC80) ||
- (0xDA80 == in && in2 < 0xDC80) ||
- (0xDAC0 == in && in2 < 0xDC80) ||
- (0xDB00 == in && in2 < 0xDC80) ||
- (0xDB40 == in && in2 < 0xDC80) ||
- (0xDB80 == in && in2 < 0xDC80) ||
- (0xDBC0 == in && in2 < 0xDC80)) {
-#else
- if ((0xD800 <= in && in <= 0xDBFF) &&
- (0xDC00 <= in2 && in2 <= 0xDFFF)) {
-#endif
- *pOut=subS;
- ++pOut;
- ++numS;
- continue;
- }
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
- } else if (0xF5 <= byte1 && byte1 <= 0xFF) { /* minic iconv() behavior */
- if (inLen < 4 ||
- (inLen >= 4 && byte1 == 0xF8 && pIn[1] < 0x90) ||
- pIn[1] < 0x80 || 0xBF < pIn[1] ||
- pIn[2] < 0x80 || 0xBF < pIn[2] ||
- pIn[3] < 0x80 || 0xBF < pIn[3] ) {
- if (inLen == 1)
- errno=EINVAL; /* 22 */
- else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else if (inLen >= 4 && (byte1 == 0xF8 || (pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
-
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- } else if ((pIn[1] == 0x80 || pIn[1] == 0x90 || pIn[1] == 0xA0 || pIn[1] == 0xB0) &&
- pIn[2] < 0x82) {
- *pOut=subS; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- continue;
- } else {
- *pOut=pSubD[0]; /* Though returns replacement character, which iconv() does not return. */
- ++pOut;
- *pOut=pSubD[1];
- ++pOut;
- ++numS;
- pIn+=4;
- inLen-=4;
- continue;
- /* iconv() returns 0 with strange 1 byte converted values */
- }
-
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- /* end of UTF-8 to UCS-2 */
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else {
- in<<=1;
- *pOut=dmapU2D[in];
- ++pOut;
- if (dmapU2D[in+1] == 0x00) { /* SBCS */
- if (dmapU2D[in] == subS) {
- in>>=1;
- if (in != cd->srcSubS)
- ++numS;
- }
- } else {
- *pOut=dmapU2D[in+1];
- ++pOut;
- if (dmapU2D[in] == pSubD[0] &&
- dmapU2D[in+1] == pSubD[1]) {
- in>>=1;
- if (in != cd->srcSubD)
- ++numS;
- }
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_82U) {
- /* See http://unicode.org/versions/corrigendum1.html */
- /* convert from UTF-8 to UTF-16 can cover all conversion from UTF-8 to UCS-2 */
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- register size_t numS=0;
- while (0 < inLen) {
- if (pLastOutBuf < pOut)
- break;
- if (*pIn == 0x00) {
- *pOut=0x00;
- ++pOut;
- *pOut=0x00;
- ++pOut;
- ++pIn;
- --inLen;
- } else { /* 82U: */
- register uchar byte1=*pIn;
- if ((byte1 & 0x80) == 0x00) { /* if (byte1 & 0b10000000 == 0b00000000) { */
- /* 1 bytes sequence: 0xxxxxxx => 00000000 0xxxxxxx*/
- *pOut=0x00;
- ++pOut;
- *pOut=byte1;
- ++pOut;
- ++pIn;
- --inLen;
- } else if ((byte1 & 0xE0) == 0xC0) { /* (byte1 & 0b11100000 == 0b11000000) { */
- if (inLen < 2) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- if (byte1 == 0xC0 || byte1 == 0xC1) { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- /* 2 bytes sequence:
- 110yyyyy 10xxxxxx => 00000yyy yyxxxxxx */
- register uchar byte2;
- ++pIn;
- byte2=*pIn;
- if ((byte2 & 0xC0) == 0x80) { /* byte2 & 0b11000000 == 0b10000000) { */
- register uchar work=byte1;
- work<<=6;
- byte2&=0x3F; /* 0b00111111; */
- byte2|=work;
-
- byte1&=0x1F; /* 0b00011111; */
- byte1>>=2;
- *pOut=byte1;
- ++pOut;
- *pOut=byte2;
- ++pOut;
- inLen-=2;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-1;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xE0) { /* byte1 & 0b11110000 == 0b11100000 */
- /* 3 bytes sequence:
- 1110zzzz 10yyyyyy 10xxxxxx => zzzzyyyy yyxxxxxx */
- register uchar byte2;
- register uchar byte3;
- if (inLen < 3) {
- if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- if ((byte2 & 0xC0) != 0x80 ||
- (byte3 & 0xC0) != 0x80 ||
- (byte1 == 0xE0 && byte2 < 0xA0)) { /* invalid sequence, only 0xA0-0xBF allowed after 0xE0 */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-2;
- *numSub+=numS;
- return -1;
- }
- {
- register uchar work=byte2;
- work<<=6;
- byte3&=0x3F; /* 0b00111111; */
- byte3|=work;
-
- byte2&=0x3F; /* 0b00111111; */
- byte2>>=2;
-
- byte1<<=4;
- *pOut=byte1 | byte2;;
- ++pOut;
- *pOut=byte3;
- ++pOut;
- inLen-=3;
- ++pIn;
- }
- } else if ((0xF0 <= byte1 && byte1 <= 0xF4) || /* (bytes1 & 11111000) == 0x1110000 */
- ((byte1&=0xF7) && 0xF0 <= byte1 && byte1 <= 0xF4)) { /* minic iconv() behavior */
- /* 4 bytes sequence
- 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx => 110110ww wwzzzzyy 110111yy yyxxxxxx
- where uuuuu = wwww + 1 */
- register uchar byte2;
- register uchar byte3;
- register uchar byte4;
- if (inLen < 4 || cd->toCcsid == 13488) {
- if ((inLen >= 2 && (pIn[1] & 0xC0) != 0x80) ||
- (inLen >= 3 && (pIn[2] & 0xC0) != 0x80) ||
- (cd->toCcsid == 13488) )
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- ++pIn;
- byte2=*pIn;
- ++pIn;
- byte3=*pIn;
- ++pIn;
- byte4=*pIn;
- if ((byte2 & 0xC0) == 0x80 && /* byte2 & 0b11000000 == 0b10000000 */
- (byte3 & 0xC0) == 0x80 && /* byte3 & 0b11000000 == 0b10000000 */
- (byte4 & 0xC0) == 0x80) { /* byte4 & 0b11000000 == 0b10000000 */
- register uchar work=byte2;
- if (byte1 == 0xF0 && byte2 < 0x90) {
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- } else if (byte1 == 0xF4 && byte2 > 0x8F) {
- errno=EINVAL; /* 22 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
-
- work&=0x30; /* 0b00110000; */
- work>>=4;
- byte1&=0x07; /* 0b00000111; */
- byte1<<=2;
- byte1+=work; /* uuuuu */
- --byte1; /* wwww */
-
- work=byte1 & 0x0F;
- work>>=2;
- work+=0xD8; /* 0b11011011; */
- *pOut=work;
- ++pOut;
-
- byte1<<=6;
- byte2<<=2;
- byte2&=0x3C; /* 0b00111100; */
- work=byte3;
- work>>=4;
- work&=0x03; /* 0b00000011; */
- work|=byte1;
- work|=byte2;
- *pOut=work;
- ++pOut;
-
- work=byte3;
- work>>=2;
- work&=0x03; /* 0b00000011; */
- work|=0xDC; /* 0b110111xx; */
- *pOut=work;
- ++pOut;
-
- byte3<<=6;
- byte4&=0x3F; /* 0b00111111; */
- byte4|=byte3;
- *pOut=byte4;
- ++pOut;
- inLen-=4;
- ++pIn;
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn-3;
- *numSub+=numS;
- return -1;
- }
- } else if ((byte1 & 0xF0) == 0xF0) {
- if (cd->toCcsid == 13488) {
- errno=EILSEQ; /* 116 */
- } else {
- if (inLen == 1)
- errno=EINVAL; /* 22 */
- else if (inLen == 2 && (pIn[1] & 0xC0) != 0x80)
- errno=EILSEQ; /* 116 */
- else if (inLen == 3 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else if (inLen >= 4 && ((pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80 || (pIn[3] & 0xC0) != 0x80))
- errno=EILSEQ; /* 116 */
- else
- errno=EINVAL; /* 22 */
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
-
- } else { /* invalid sequence */
- errno=EILSEQ; /* 116 */
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return -1;
- }
- }
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- *numSub+=numS;
- return 0;
- } else if (cd->cnv_dmap->codingSchema == DMAP_U28) {
- /* See http://unicode.org/versions/corrigendum1.html */
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- // register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=pIn[1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else {
- register uchar byte;
- register uchar work;
- byte=pIn[0];
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=pIn[0];
- byte<<=2;
- work=pIn[1];
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=pIn[1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- // *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_T28) { /* UTF-16_UTF-8 */
- /* See http://unicode.org/versions/corrigendum1.html */
- register int inLen=*inBytesLeft;
- register char * pOut=*outBuf;
- register char * pIn=*inBuf;
- register char * pLastOutBuf = *outBuf + *outBytesLeft - 1;
- // register size_t numS=0;
- while (0 < inLen) {
- register uint32_t in;
- if (inLen == 1) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=0;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return 0;
- }
- if (pLastOutBuf < pOut)
- break;
- in=pIn[0];
- in<<=8;
- in+=pIn[1];
- if (in == 0x0000) {
- *pOut=0x00;
- ++pOut;
- } else if ((in & 0xFF80) == 0x0000) { /* U28: in & 0b1111111110000000 == 0x0000 */
- *pOut=in;
- ++pOut;
- } else if ((in & 0xF800) == 0x0000) { /* in & 0b1111100000000000 == 0x0000 */
- register uchar byte;
- in>>=6;
- in&=0x001F; /* 0b0000000000011111 */
- in|=0x00C0; /* 0b0000000011000000 */
- *pOut=in;
- ++pOut;
- byte=pIn[1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- } else if ((in & 0xFC00) == 0xD800) { /* in & 0b1111110000000000 == 0b1101100000000000, first surrogate character */
- if (0xDC00 <= in ) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
-
- } else if (inLen < 4) {
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- return -1;
-
- } else if ((pIn[2] & 0xFC) != 0xDC) { /* pIn[2] & 0b11111100 == 0b11011100, second surrogate character */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-2;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn+2;
- return -1;
-
- } else {
- register uchar byte;
- register uchar work;
- in>>=6;
- in&=0x000F; /* 0b0000000000001111 */
- byte=in; /* wwww */
- ++byte; /* uuuuu */
- work=byte; /* save uuuuu */
- byte>>=2;
- byte|=0xF0; /* 0b11110000; */
- *pOut=byte;
- ++pOut;
-
- byte=work;
- byte&=0x03; /* 0b00000011; */
- byte<<=4;
- byte|=0x80; /* 0b10000000; */
- work=pIn[1];
- work&=0x3C; /* 0b00111100; */
- work>>=2;
- byte|=work;
- *pOut=byte;
- ++pOut;
-
- byte=pIn[1];
- byte&=0x03; /* 0b00000011; */
- byte<<=4;
- byte|=0x80; /* 0b10000000; */
- work=pIn[2];
- work&=0x03; /* 0b00000011; */
- work<<=2;
- byte|=work;
- work=pIn[3];
- work>>=6;
- byte|=work;
- *pOut=byte;
- ++pOut;
-
- byte=pIn[3];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- pIn+=2;
- inLen-=2;
- }
- } else if ((in & 0xFC00) == 0xDC00) { /* in & 0b11111100 == 0b11011100, second surrogate character */
- errno=EINVAL; /* 22 */
- *inBytesLeft=inLen-1;
- *outBytesLeft-=(pOut-*outBuf);
- *outBuf=pOut;
- *inBuf=pIn;
- return -1;
-
- } else {
- register uchar byte;
- register uchar work;
- byte=pIn[0];
- byte>>=4;
- byte|=0xE0; /* 0b11100000; */
- *pOut=byte;
- ++pOut;
-
- byte=pIn[0];
- byte<<=2;
- work=pIn[1];
- work>>=6;
- byte|=work;
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
-
- byte=pIn[1];
- byte&=0x3F; /* 0b00111111; */
- byte|=0x80; /* 0b10000000; */
- *pOut=byte;
- ++pOut;
- }
- pIn+=2;
- inLen-=2;
- }
- *outBytesLeft-=(pOut-*outBuf);
- *inBytesLeft=inLen;
- *outBuf=pOut;
- *inBuf=pIn;
- // *numSub+=numS;
- return 0;
-
- } else if (cd->cnv_dmap->codingSchema == DMAP_U2U) { /* UTF-16_UCS-2 */
- register int inLen=*inBytesLeft;
- register int outLen=*outBytesLeft;
- if (inLen <= outLen) {
- memcpy(*outBuf, *inBuf, inLen);
- (*outBytesLeft)-=inLen;
- (*inBuf)+=inLen;
- (*outBuf)+=inLen;
- *inBytesLeft=0;
- return 0;
- }
- memcpy(*outBuf, *inBuf, outLen);
- (*outBytesLeft)=0;
- (*inBuf)+=outLen;
- (*outBuf)+=outLen;
- *inBytesLeft-=outLen;
- return (*inBytesLeft);
-
- } else {
- return -1;
- }
- return 0;
-}
-
-
-#ifdef DEBUG
-inline size_t myconv(myconv_t cd ,
- char** inBuf,
- size_t* inBytesLeft,
- char** outBuf,
- size_t* outBytesLeft,
- size_t* numSub)
-{
- if (cd->converterType == CONVERTER_ICONV) {
- return myconv_iconv(cd,inBuf,inBytesLeft,outBuf,outBytesLeft,numSub);
- } else if (cd->converterType == CONVERTER_DMAP) {
- return myconv_dmap(cd,inBuf,inBytesLeft,outBuf,outBytesLeft,numSub);
- }
- return -1;
-}
-
-inline char * converterName(int32_t type)
-{
- if (type == CONVERTER_ICONV)
- return "iconv";
- else if (type == CONVERTER_DMAP)
- return "dmap";
-
- return "?????";
-}
-#else
-#define myconv(a,b,c,d,e,f) \
-(((a)->converterType == CONVERTER_ICONV)? myconv_iconv((a),(b),(c),(d),(e),(f)): (((a)->converterType == CONVERTER_DMAP)? myconv_dmap((a),(b),(c),(d),(e),(f)): -1))
-
-
-#define converterName(a) \
-(((a) == CONVERTER_ICONV)? "iconv": ((a) == CONVERTER_DMAP)? "dmap": "?????")
-#endif
-
-void initMyconv();
-void cleanupMyconv();
-
-#endif
diff --git a/storage/ibmdb2i/db2i_rir.cc b/storage/ibmdb2i/db2i_rir.cc
deleted file mode 100644
index 091c4d98383..00000000000
--- a/storage/ibmdb2i/db2i_rir.cc
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#include "ha_ibmdb2i.h"
-
-/* Helper function for records_in_range.
- Input: Bitmap of used key parts.
- Output: Number of used key parts. */
-
-static inline int getKeyCntFromMap(key_part_map keypart_map)
-{
- int cnt = 0;
- while (keypart_map)
- {
- keypart_map = keypart_map >> 1;
- cnt++;
- }
- return (cnt);
-}
-
-/**
- @brief
- Given a starting key and an ending key, estimate the number of rows that
- will exist between the two keys.
-
- INPUT
- inx Index to use
- min_key Min key. Is NULL if no min range
- max_key Max key. Is NULL if no max range
-
- NOTES
- min_key.flag can have one of the following values:
- HA_READ_KEY_EXACT Include the key in the range
- HA_READ_AFTER_KEY Don't include key in range
-
- max_key.flag can have one of the following values:
- HA_READ_BEFORE_KEY Don't include key in range
- HA_READ_AFTER_KEY Include all 'end_key' values in the range
-
- RETURN
- HA_POS_ERROR Error or the storage engine cannot estimate the number of rows
- 1 There are no matching keys in the given range
- n > 0 There are approximately n rows in the range
-*/
-ha_rows ha_ibmdb2i::records_in_range(uint inx,
- key_range *min_key,
- key_range *max_key)
-{
- DBUG_ENTER("ha_ibmdb2i::records_in_range");
- int rc = 0; // Return code
- ha_rows rows = 0; // Row count returned to caller of this method
- uint32 spcLen; // Length of space passed to DB2
- uint32 keyCnt; // Number of fields in the key composite
- uint32 literalCnt = 0; // Number of literals
- uint32 boundsOff; // Offset from beginning of space to range bounds
- uint32 litDefOff; // Offset from beginning of space to literal definitions
- uint32 literalsOff; // Offset from beginning of space to literal values
- uint32 cutoff = 0; // Early exit cutoff (currently not used)
- uint64 recCnt; // Row count from DB2
- uint16 rtnCode; // Return code from DB2
- Bounds* boundsPtr; // Pointer to a pair of range bounds
- Bound* boundPtr; // Pointer to a single (high or low) range bound
- LitDef* litDefPtr; // Pointer to a literal definition
- char* literalsPtr; // Pointer to the start of all literal values
- char* literalPtr; // Pointer to the start of this literal value
- char* tempPtr; // Temporary pointer
- char* tempMinPtr; // Temporary pointer into min_key
- int minKeyCnt = 0; // Number of fields in the min_key composite
- int maxKeyCnt = 0; // Number of fields in the max_key composite
- size_t tempLen = 0; // Temporary length
- uint16 DB2FieldWidth = 0; // DB2 field width
- uint32 workFieldLen = 0; // Length of workarea needed for CCSID conversions
- bool overrideInclusion; // Indicator for inclusion/exclusion
- char* endOfLiteralPtr; // Pointer to the end of this literal
- char* endOfMinPtr; // Pointer to end of min_key
- uint16 endByte = 0; // End byte of char or graphic literal (padding not included)
- bool reuseLiteral; // Indicator that hi and lo bounds use same literal
- char* minPtr = NULL; // Work pointer for traversing min_key
- char* maxPtr = NULL; // Work pointer for traversing max_key
- /*
- Handle the special case of 'x < null' anywhere in the key range. There are
- no values less than null, but return 1 so that MySQL does not assume
- the empty set for the query.
- */
- if (min_key != NULL && max_key != NULL &&
- min_key->flag == HA_READ_AFTER_KEY && max_key->flag == HA_READ_BEFORE_KEY &&
- min_key->length == max_key->length &&
- (memcmp((uchar*)min_key->key,(uchar*)max_key->key,min_key->length)==0))
- {
- DBUG_PRINT("ha_ibmdb2i::records_in_range",("Estimate 1 row for key %d; special case: < null", inx));
- DBUG_RETURN((ha_rows) 1 );
- }
- /*
- Determine the number of fields in the key composite.
- */
-
- if (min_key)
- {
- minKeyCnt = getKeyCntFromMap(min_key->keypart_map);
- minPtr = (char*)min_key->key;
- }
- if (max_key)
- {
- maxKeyCnt = getKeyCntFromMap(max_key->keypart_map);
- maxPtr = (char*)max_key->key;
- }
- 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
- space must be large enough to store the following:
- - one pair of bounds (high and low) per field in the key composite
- - one literal definition per literal value
- - the literal values
- - work area for literal CCSID conversions
- Since we don't know yet how many of these structures are needed,
- allocate enough space for the maximum that we will possibly need.
- The workarea for the literal conversion must be big enough to hold the
- largest of the DB2 key fields.
- */
- KEY& curKey = table->key_info[inx];
-
- for (int i = 0; i < keyCnt; i++)
- {
- DB2FieldWidth =
- db2Table->db2Field(curKey.key_part[i].field->field_index).getByteLengthInRecord();
- if (DB2FieldWidth > workFieldLen)
- workFieldLen = DB2FieldWidth; // Get length of largest DB2 field
- tempLen = tempLen + DB2FieldWidth; // Tally the DB2 field lengths
- }
- spcLen = (sizeof(Bounds)*keyCnt) + (sizeof(LitDef)*keyCnt*2) + (tempLen*2) + workFieldLen;
-
- ValidatedPointer<char> spcPtr(spcLen); // Pointer to space passed to DB2
- memset(spcPtr, 0, spcLen); // Clear the allocated space
- /*
- Set addressability to the various sections of the DB2 interface space.
- */
- boundsOff = 0; // Range bounds are at the start of the space
- litDefOff = sizeof(Bounds) * keyCnt; // Literal defs follow all the range bounds
- literalsOff = litDefOff + (sizeof(LitDef) * keyCnt * 2); // Literal values are last
- boundsPtr = (Bounds_t*)(void*)spcPtr; // Address first bounds structure
- tempPtr = (char*)((char*)spcPtr + litDefOff);
- litDefPtr = (LitDef_t*)tempPtr; // Address first literal definition
- tempPtr = (char*)((char*)spcPtr + literalsOff);
- literalsPtr = (char*)tempPtr; // Address start of literal values
- literalPtr = literalsPtr; // Address first literal value
- /*
- For each key part, build the low (min) and high (max) DB2 range bounds.
- If literals are specified in the MySQL range, build DB2 literal
- definitions and store the literal values for access by DB2.
-
- If no value is specified for a key part, assume infinity. Negative
- infinity will cause processing to start at the first index entry.
- Positive infinity will cause processing to end at the last index entry.
- When infinity is specified in a bound, inclusion/exclusion and position
- are ignored, and there is no literal definition or literal value for
- the bound.
-
- If the keypart value is null, the null indicator is set in the range
- bound and the other fields in the bound are ignored. When the bound is
- null, only index entries with the null value will be included in the
- estimate. If one bound is null, both bounds must be null. When the bound
- is not null, the data offset and length must be set, and the literal
- value stored for access by DB2.
- */
- for (int partsInUse = 0; partsInUse < keyCnt; ++partsInUse)
- {
- Field *field= curKey.key_part[partsInUse].field;
- overrideInclusion = false;
- reuseLiteral = false;
- endOfLiteralPtr = NULL;
- /*
- Build the low bound for the key range.
- */
- if ((partsInUse + 1) > minKeyCnt) // if no min_key info for this part
- boundsPtr->LoBound.Infinity[0] = QMY_NEG_INFINITY; // select...where 3 between x and y
- else
- {
- if ((curKey.key_part[partsInUse].null_bit) && (char*)minPtr[0])
- { // min_key is null
- if (max_key == NULL ||
- ((partsInUse + 1) > maxKeyCnt)) // select...where x='ab' and y=null and z != 'c'
- boundsPtr->LoBound.Infinity[0] = QMY_NEG_INFINITY; // select...where x not null or
- // select...where x > null
- else // max_key is not null
- {
- if (min_key->flag == HA_READ_KEY_EXACT)
- boundsPtr->LoBound.IsNull[0] = QMY_YES; // select...where x is null
- else
- {
- if ((char*)maxPtr[0])
- boundsPtr->LoBound.IsNull[0] = QMY_YES; // select...where a = null and b < 5 (max-before)
- // select...where a='a' and b is null and c !='a' (max-after)
- else
- boundsPtr->LoBound.Infinity[0] = QMY_NEG_INFINITY; // select...where x < y
- }
- } // end min_key is null
- }
- else // min_key is not null
- {
- if (literalCnt) litDefPtr = litDefPtr + 1;
- literalCnt = literalCnt + 1;
- boundsPtr->LoBound.Position = literalCnt;
- /*
- Determine inclusion or exclusion.
- */
- if (min_key->flag == HA_READ_KEY_EXACT || //select...where a like 'this%'
-
- /* An example for the following conditions is 'select...where a = 5 and b > null'. */
-
- (max_key &&
- (memcmp((uchar*)minPtr,(uchar*)maxPtr,
- curKey.key_part[partsInUse].store_length)==0)))
-
- {
- if ((min_key->flag != HA_READ_KEY_EXACT) ||
- (max_key &&
- (memcmp((uchar*)minPtr,(uchar*)maxPtr,
- curKey.key_part[partsInUse].store_length)==0)))
- overrideInclusion = true; // Need inclusion for both min and max
- }
- else
- boundsPtr->LoBound.Embodiment[0] = QMY_EXCLUSION;
- litDefPtr->FieldNbr = field->field_index + 1;
- DB2Field& db2Field = db2Table->db2Field(field->field_index);
- litDefPtr->DataType = db2Field.getType();
- /*
- Convert the literal to DB2 format
- */
- if ((field->type() != MYSQL_TYPE_BIT) && // Don't do conversion on BIT data
- (field->charset() != &my_charset_bin) && // Don't do conversion on BINARY data
- (litDefPtr->DataType == QMY_CHAR ||
- litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_GRAPHIC ||
- litDefPtr->DataType == QMY_VARGRAPHIC))
- {
- // Most of the code is required by the considerable wrangling needed
- // to prepare partial keys for use by DB2
- // 1. UTF8 (CCSID 1208) data can be copied across unmodified if it is
- // utf8_bin. Otherwise, we need to convert the min and max
- // characters into the min and max characters employed
- // by the DB2 sort sequence. This is complicated by the fact that
- // the character widths are not always equal.
- // 2. Likewise, UCS2 (CCSID 13488) data can be copied across unmodified
- // if it is ucs2_bin or ucs2_general_ci. Otherwise, we need to
- // convert the min and max characters into the min and max characters
- // employed by the DB2 sort sequence.
- // 3. All other data will use standard iconv conversions. If an
- // unconvertible character is encountered, we assume it is the min
- // char and fill the remainder of the DB2 key with 0s. This may not
- // always be accurate, but it is probably sufficient for range
- // estimations.
- const char* keyData = minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0);
- char* db2Data = literalPtr;
- uint16 outLen = db2Field.getByteLengthInRecord();
- uint16 inLen;
- if (litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_VARGRAPHIC)
- {
- inLen = *(uint8*)keyData + ((*(uint8*)(keyData+1)) << 8);
- keyData += 2;
- outLen -= sizeof(uint16);
- db2Data += sizeof(uint16);
- }
- else
- {
- inLen = field->max_display_length();
- }
-
- size_t convertedBytes = 0;
- if (db2Field.getCCSID() == 1208)
- {
- DBUG_ASSERT(inLen <= outLen);
- if (strcmp(field->charset()->name, "utf8_bin"))
- {
- const char* end = keyData+inLen;
- const char* curKey = keyData;
- char* curDB2 = db2Data;
- uint32 min = field->charset()->min_sort_char;
- while ((curKey < end) && (curDB2 < db2Data+outLen-3))
- {
- my_wc_t temp;
- int len = field->charset()->cset->mb_wc(field->charset(),
- &temp,
- (const uchar*)curKey,
- (const uchar*)end);
- if (temp != min)
- {
- DBUG_ASSERT(len <= 3);
- switch (len)
- {
- case 3: *(curDB2+2) = *(curKey+2);
- case 2: *(curDB2+1) = *(curKey+1);
- case 1: *(curDB2) = *(curKey);
- }
- curDB2 += len;
- }
- else
- {
- *(curDB2++) = 0xEF;
- *(curDB2++) = 0xBF;
- *(curDB2++) = 0xBF;
- }
- curKey += len;
- }
- convertedBytes = curDB2 - db2Data;
- }
- else
- {
- memcpy(db2Data, keyData, inLen);
- convertedBytes = inLen;
- }
- rc = 0;
- }
- else if (db2Field.getCCSID() == 13488)
- {
- DBUG_ASSERT(inLen <= outLen);
- if (strcmp(field->charset()->name, "ucs2_bin") &&
- strcmp(field->charset()->name, "ucs2_general_ci"))
- {
- const char* end = keyData+inLen;
- const uint16* curKey = (uint16*)keyData;
- uint16* curDB2 = (uint16*)db2Data;
- uint16 min = field->charset()->min_sort_char;
- while (curKey < (uint16*)end)
- {
- if (*curKey != min)
- *curDB2 = *curKey;
- else
- *curDB2 = 0xFFFF;
- ++curKey;
- ++curDB2;
- }
- }
- else
- {
- memcpy(db2Data, keyData, inLen);
- }
- convertedBytes = inLen;
- rc = 0;
- }
- else
- {
- rc = convertFieldChars(toDB2,
- field->field_index,
- keyData,
- db2Data,
- inLen,
- outLen,
- &convertedBytes,
- true);
-
- if (rc == DB2I_ERR_ILL_CHAR)
- {
- // If an illegal character is encountered, we fill the remainder
- // of the key with 0x00. This was implemented as a corollary to
- // Bug#45012, though it should probably remain even after that
- // bug is fixed.
- memset(db2Data+convertedBytes, 0x00, outLen-convertedBytes);
- convertedBytes = outLen;
- rc = 0;
- }
- }
-
- if (!rc &&
- (litDefPtr->DataType == QMY_VARGRAPHIC ||
- litDefPtr->DataType == QMY_VARCHAR))
- {
- *(uint16*)(db2Data-sizeof(uint16)) =
- convertedBytes / (litDefPtr->DataType == QMY_VARGRAPHIC ? 2 : 1);
- }
-
- }
- else // Non-character fields
- {
- rc = convertMySQLtoDB2(field,
- db2Field,
- literalPtr,
- (uchar*)minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0));
- }
-
- if (rc != 0) break;
- litDefPtr->Offset = (uint32_t)(literalPtr - literalsPtr);
- litDefPtr->Length = db2Field.getByteLengthInRecord();
- literalPtr = literalPtr + litDefPtr->Length; // Bump pointer for next literal
- }
- /* If there is a max_key value for this field, and if the max_key value is
- the same as the min_key value, then the low bound literal can be reused
- for the high bound literal. This eliminates the overhead of copying and
- converting the same value twice. */
- if (max_key && ((partsInUse + 1) <= maxKeyCnt) &&
- (memcmp((uchar*)minPtr,(uchar*)maxPtr,
- curKey.key_part[partsInUse].store_length)==0 || endOfLiteralPtr))
- reuseLiteral = true;
- minPtr += curKey.key_part[partsInUse].store_length;
- }
- /*
- Build the high bound for the key range.
- */
- if (max_key == NULL || ((partsInUse + 1) > maxKeyCnt))
- boundsPtr->HiBound.Infinity[0] = QMY_POS_INFINITY;
- else
- {
- if ((curKey.key_part[partsInUse].null_bit) && (char*)maxPtr[0])
- {
- if (min_key == NULL)
- boundsPtr->HiBound.Infinity[0] = QMY_POS_INFINITY;
- else
- boundsPtr->HiBound.IsNull[0] = QMY_YES; // select...where x is 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 (literalCnt)
- litDefPtr = litDefPtr + 1;
- literalCnt = literalCnt + 1;
- litDefPtr->FieldNbr = field->field_index + 1;
- DB2Field& db2Field = db2Table->db2Field(field->field_index);
- litDefPtr->DataType = db2Field.getType();
- /*
- Convert the literal to DB2 format
- */
- if ((field->type() != MYSQL_TYPE_BIT) && // Don't do conversion on BIT data
- (field->charset() != &my_charset_bin) && // Don't do conversion on BINARY data
- (litDefPtr->DataType == QMY_CHAR ||
- litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_GRAPHIC ||
- litDefPtr->DataType == QMY_VARGRAPHIC))
- {
- // We need to handle char fields in a special way in order to account
- // for partial keys. Refer to the note above for a description of the
- // basic design.
- char* keyData = maxPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0);
- char* db2Data = literalPtr;
- uint16 outLen = db2Field.getByteLengthInRecord();
- uint16 inLen;
- if (litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_VARGRAPHIC)
- {
- inLen = *(uint8*)keyData + ((*(uint8*)(keyData+1)) << 8);
- keyData += 2;
- outLen -= sizeof(uint16);
- db2Data += sizeof(uint16);
- }
- else
- {
- inLen = field->max_display_length();
- }
-
- size_t convertedBytes;
- if (db2Field.getCCSID() == 1208)
- {
- if (strcmp(field->charset()->name, "utf8_bin"))
- {
- const char* end = keyData+inLen;
- const char* curKey = keyData;
- char* curDB2 = db2Data;
- uint32 max = field->charset()->max_sort_char;
- while (curKey < end && (curDB2 < db2Data+outLen-3))
- {
- my_wc_t temp;
- int len = field->charset()->cset->mb_wc(field->charset(), &temp, (const uchar*)curKey, (const uchar*)end);
- if (temp != max)
- {
- DBUG_ASSERT(len <= 3);
- switch (len)
- {
- case 3: *(curDB2+2) = *(curKey+2);
- case 2: *(curDB2+1) = *(curKey+1);
- case 1: *(curDB2) = *(curKey);
- }
- curDB2 += len;
- }
- else
- {
- *(curDB2++) = 0xE4;
- *(curDB2++) = 0xB6;
- *(curDB2++) = 0xBF;
- }
- curKey += len;
- }
- convertedBytes = curDB2 - db2Data;
- }
- else
- {
- DBUG_ASSERT(inLen <= outLen);
- memcpy(db2Data, keyData, inLen);
- convertedBytes = inLen;
- }
- rc = 0;
- }
- else if (db2Field.getCCSID() == 13488)
- {
- if (strcmp(field->charset()->name, "ucs2_bin") &&
- strcmp(field->charset()->name, "ucs2_general_ci"))
- {
- char* end = keyData+inLen;
- uint16* curKey = (uint16*)keyData;
- uint16* curDB2 = (uint16*)db2Data;
- uint16 max = field->charset()->max_sort_char;
- while (curKey < (uint16*)end)
- {
- if (*curKey != max)
- *curDB2 = *curKey;
- else
- *curDB2 = 0x4DBF;
- ++curKey;
- ++curDB2;
- }
- }
- else
- {
- memcpy(db2Data, keyData, outLen);
- }
- rc = 0;
- }
- else
- {
- size_t substituteChars = 0;
- rc = convertFieldChars(toDB2,
- field->field_index,
- keyData,
- db2Data,
- inLen,
- outLen,
- &convertedBytes,
- true,
- &substituteChars);
-
- if (rc == DB2I_ERR_ILL_CHAR)
- {
- // If an illegal character is encountered, we fill the remainder
- // of the key with 0xFF. This was implemented to work around
- // Bug#45012, though it should probably remain even after that
- // bug is fixed.
- memset(db2Data+convertedBytes, 0xFF, outLen-convertedBytes);
- rc = 0;
- }
- else if ((substituteChars &&
- (litDefPtr->DataType == QMY_VARCHAR ||
- litDefPtr->DataType == QMY_CHAR)) ||
- strcmp(field->charset()->name, "cp1251_bulgarian_ci") == 0)
- {
- // When iconv translates the max_sort_char with a substitute
- // character, we have no way to know whether this affects
- // the sort order of the key. Therefore, to be safe, when
- // we know that substitute characters have been used in a
- // single-byte string, we traverse the translated key
- // in reverse, replacing substitue characters with 0xFF, which
- // always sorts with the greatest weight in DB2 sort sequences.
- // cp1251_bulgarian_ci is also handled this way because the
- // max_sort_char is a control character which does not sort
- // equivalently in DB2.
- DBUG_ASSERT(inLen == outLen);
- char* tmpKey = keyData + inLen - 1;
- char* tmpDB2 = db2Data + outLen - 1;
- while (*tmpKey == field->charset()->max_sort_char &&
- *tmpDB2 != 0xFF)
- {
- *tmpDB2 = 0xFF;
- --tmpKey;
- --tmpDB2;
- }
- }
- }
-
- if (!rc &&
- (litDefPtr->DataType == QMY_VARGRAPHIC ||
- litDefPtr->DataType == QMY_VARCHAR))
- {
- *(uint16*)(db2Data-sizeof(uint16)) =
- outLen / (litDefPtr->DataType == QMY_VARGRAPHIC ? 2 : 1);
- }
- }
- else
- {
- rc = convertMySQLtoDB2(field,
- db2Field,
- literalPtr,
- (uchar*)maxPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0));
- }
- if (rc != 0) break;
- litDefPtr->Offset = (uint32_t)(literalPtr - literalsPtr);
- litDefPtr->Length = db2Field.getByteLengthInRecord();
- literalPtr = literalPtr + litDefPtr->Length; // Bump pointer for next literal
- }
- boundsPtr->HiBound.Position = literalCnt;
- if (max_key->flag == HA_READ_BEFORE_KEY && !overrideInclusion)
- boundsPtr->HiBound.Embodiment[0] = QMY_EXCLUSION;
- }
- maxPtr += curKey.key_part[partsInUse].store_length;
- }
- /*
- Bump to the next field in the key composite.
- */
-
- if ((partsInUse+1) < keyCnt)
- boundsPtr = boundsPtr + 1;
- }
-
- /*
- Call DB2 to estimate the number of rows in the key range.
- */
- if (rc == 0)
- {
- rc = db2i_ileBridge::getBridgeForThread()->recordsInRange((indexHandles[inx] ? indexHandles[inx] : db2Table->indexFile(inx)->getMasterDefnHandle()),
- spcPtr,
- keyCnt,
- literalCnt,
- boundsOff,
- litDefOff,
- literalsOff,
- cutoff,
- (uint32_t)(literalPtr - (char*)spcPtr),
- endByte,
- &recCnt,
- &rtnCode);
- }
- /*
- Set the row count and return.
- Beware that if this method returns a zero row count, MySQL assumes the
- result set for the query is zero; never return a zero row count.
- */
- if ((rc == 0) && (rtnCode == QMY_SUCCESS || rtnCode == QMY_EARLY_EXIT))
- {
- rows = recCnt ? (ha_rows)recCnt : 1;
- }
-
- rows = (rows > 0 ? rows : HA_POS_ERROR);
-
- setIndexReadEstimate(inx, rows);
-
- DBUG_PRINT("ha_ibmdb2i::recordsInRange",("Estimate %d rows for key %d", uint32(rows), inx));
-
- DBUG_RETURN(rows);
-}
diff --git a/storage/ibmdb2i/db2i_safeString.h b/storage/ibmdb2i/db2i_safeString.h
deleted file mode 100644
index e353316c8fc..00000000000
--- a/storage/ibmdb2i/db2i_safeString.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-
-#ifndef DB2I_SAFESTRING_H
-#define DB2I_SAFESTRING_H
-
-
-#include <my_global.h>
-#include <string.h>
-
-/**
- @class SafeString
-
- This class was designed to provide safe, but lightweight, concatenation
- operations C strings inside pre-allocated buffers.
-*/
-class SafeString
-{
-public:
- SafeString(char* buffer, size_t size) :
- allocSize(size), curPos(0), buf(buffer)
- {
- DBUG_ASSERT(size > 0);
- buf[allocSize - 1] = 0xFF; // Set an overflow indicator
- }
-
- char* ptr() { return buf; }
- operator char*() { return buf; }
-
- SafeString& strcat(const char* str)
- {
- return this->strncat(str, strlen(str));
- }
-
- SafeString& strcat(char one)
- {
- if (curPos < allocSize - 2)
- {
- buf[curPos++] = one;
- }
- buf[curPos] = 0;
-
- return *this;
- }
-
- SafeString& strncat(const char* str, size_t len)
- {
- uint64 amountToCopy = min((allocSize-1) - curPos, len);
- memcpy(buf + curPos, str, amountToCopy);
- curPos += amountToCopy;
- buf[curPos] = 0;
- return *this;
- }
-
- bool overflowed() const { return (buf[allocSize - 1] == 0);}
-
-private:
- char* buf;
- uint64 curPos;
- size_t allocSize;
-};
-
-
-#endif
diff --git a/storage/ibmdb2i/db2i_sqlStatementStream.cc b/storage/ibmdb2i/db2i_sqlStatementStream.cc
deleted file mode 100644
index 92a8b03fd00..00000000000
--- a/storage/ibmdb2i/db2i_sqlStatementStream.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#include "db2i_sqlStatementStream.h"
-#include "as400_types.h"
-
-/**
- Add a statement to the statement stream, allocating additional memory as needed.
-
- @parm stmt The statement text
- @parm length The length of the statement text
- @parm fileSortSequence The DB2 sort sequence identifier, in EBCDIC
- @parm fileSortSequenceLibrary The DB2 sort sequence library, in EBCDIC
-
- @return Reference to this object
-*/
-SqlStatementStream& SqlStatementStream::addStatementInternal(const char* stmt,
- uint32 length,
- const char* fileSortSequence,
- const char* fileSortSequenceLibrary)
-{
- uint32 storageNeeded = length + sizeof(StmtHdr_t);
- storageNeeded = (storageNeeded + 3) & ~3; // We have to be 4-byte aligned.
- if (storageNeeded > storageRemaining())
- {
- // We overallocate new storage to reduce number of times reallocation is
- // needed.
- int newSize = curSize + 2 * storageNeeded;
- DBUG_PRINT("SqlStatementStream::addStatementInternal",
- ("PERF: Had to realloc! Old size=%d. New size=%d", curSize, newSize));
- char* old_space = block;
- char* new_space = (char*)getNewSpace(newSize);
- memcpy(new_space, old_space, curSize);
- ptr = new_space + (ptr - old_space);
- curSize = newSize;
- }
-
- DBUG_ASSERT((address64_t)ptr % 4 == 0);
-
- memcpy(((StmtHdr_t*)ptr)->SrtSeqNam,
- fileSortSequence,
- sizeof(((StmtHdr_t*)ptr)->SrtSeqNam));
- memcpy(((StmtHdr_t*)ptr)->SrtSeqSch,
- fileSortSequenceLibrary,
- sizeof(((StmtHdr_t*)ptr)->SrtSeqSch));
- ((StmtHdr_t*)ptr)->Length = length;
- memcpy(ptr + sizeof(StmtHdr_t), stmt, length);
-
- ptr += storageNeeded;
- ++statements;
-
- return *this;
-}
diff --git a/storage/ibmdb2i/db2i_sqlStatementStream.h b/storage/ibmdb2i/db2i_sqlStatementStream.h
deleted file mode 100644
index 11db41a6c5d..00000000000
--- a/storage/ibmdb2i/db2i_sqlStatementStream.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-#ifndef DB2I_SQLSTATEMENTSTREAM_H
-#define DB2I_SQLSTATEMENTSTREAM_H
-
-#include "db2i_charsetSupport.h"
-#include "qmyse.h"
-
-/**
- @class SqlStatementStream
-
- This class handles building the stream of SQL statements expected by the
- QMY_EXECUTE_IMMEDIATE and QMY_PREPARE_OPEN_CURSOR APIs.
- Memory allocation is handled internally.
-*/
-class SqlStatementStream
-{
- public:
- /**
- ctor to be used when multiple strings may be appended.
- */
- SqlStatementStream(uint32 firstStringSize) : statements(0)
- {
- curSize = firstStringSize + sizeof(StmtHdr_t);
- curSize = (curSize + 3) & ~3;
- ptr = (char*) getNewSpace(curSize);
- if (ptr == NULL)
- curSize = 0;
- }
-
- /**
- ctor to be used when only a single statement will be executed.
- */
- SqlStatementStream(const String& statement) : statements(0), block(NULL), curSize(0), ptr(0)
- {
- addStatement(statement);
- }
-
- /**
- ctor to be used when only a single statement will be executed.
- */
- SqlStatementStream(const char* statement) : statements(0), block(NULL), curSize(0), ptr(0)
- {
- addStatement(statement);
- }
-
- /**
- Append an SQL statement, specifiying the DB2 sort sequence under which
- the statement should be executed. This is important for CREATE TABLE
- and CREATE INDEX statements.
- */
- SqlStatementStream& addStatement(const String& append, const char* fileSortSequence, const char* fileSortSequenceLibrary)
- {
- char sortSeqEbcdic[10];
- char sortSeqLibEbcdic[10];
-
- DBUG_ASSERT(strlen(fileSortSequence) <= 10 &&
- strlen(fileSortSequenceLibrary) <= 10);
- memset(sortSeqEbcdic, 0x40, 10);
- memset(sortSeqLibEbcdic, 0x40, 10);
- convToEbcdic(fileSortSequence, sortSeqEbcdic, strlen(fileSortSequence));
- convToEbcdic(fileSortSequenceLibrary, sortSeqLibEbcdic, strlen(fileSortSequenceLibrary));
-
- return addStatementInternal(append.ptr(), append.length(), sortSeqEbcdic, sortSeqLibEbcdic);
- }
-
- /**
- Append an SQL statement using default (*HEX) sort sequence.
- */
- SqlStatementStream& addStatement(const String& append)
- {
- const char splatHEX[] = {0x5C, 0xC8, 0xC5, 0xE7, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; // *HEX
- const char blanks[] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; //
-
- return addStatementInternal(append.ptr(), append.length(), splatHEX, blanks);
- }
-
- /**
- Append an SQL statement using default (*HEX) sort sequence.
- */
- SqlStatementStream& addStatement(const char* stmt)
- {
- const char splatHEX[] = {0x5C, 0xC8, 0xC5, 0xE7, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; // *HEX
- const char blanks[] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; //
-
- return addStatementInternal(stmt, strlen(stmt), splatHEX, blanks);
- }
-
- char* getPtrToData() const { return block; }
- uint32 getStatementCount() const { return statements; }
- private:
- SqlStatementStream& addStatementInternal(const char* stmt,
- uint32 length,
- const char* fileSortSequence,
- const char* fileSortSequenceLibrary);
-
- uint32 storageRemaining() const
- {
- return (block == NULL ? 0 : curSize - (ptr - block));
- }
-
- char* getNewSpace(size_t size)
- {
- allocBase = (char*)sql_alloc(size + 15);
- block = (char*)roundToQuadWordBdy(allocBase);
- return block;
- }
-
- uint32 curSize; // The size of the usable memory.
- char* allocBase; // The allocated memory (with padding for aligment)
- char* block; // The usable memory chunck (aligned for ILE)
- char* ptr; // The current position within block.
- uint32 statements; // The number of statements that have been appended.
-};
-
-#endif
-
diff --git a/storage/ibmdb2i/db2i_validatedPointer.h b/storage/ibmdb2i/db2i_validatedPointer.h
deleted file mode 100644
index c4e31d1f11b..00000000000
--- a/storage/ibmdb2i/db2i_validatedPointer.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-#ifndef DB2I_VALIDATEDPOINTER_H
-#define DB2I_VALIDATEDPOINTER_H
-
-#include "db2i_ileBridge.h"
-
-/**
- @class ValidatedPointer
- @brief Encapsulates a pointer registered for usage by the QMYSE APIs
-
- @details As a performance optimization, to prevent pointer validation each
- time a particular pointer is thunked across to ILE, QMYSE allows us to
- "register" a pointer such that it is validated once and then subsequently
- referenced on QMYSE APIs by means of a handle value. This class should be
- used to manage memory allocation/registration/unregistration of these
- pointers. Using the alloc function guarantees that the resulting storage is
- 16-byte aligned, a requirement for many pointers passed to QMYSE.
-*/
-template <class T>
-class ValidatedPointer
-{
-public:
- ValidatedPointer<T>() : address(NULL), handle(NULL) {;}
-
- ValidatedPointer<T>(size_t size)
- {
- alloc(size);
- }
-
- ValidatedPointer<T>(T* ptr)
- {
- assign(ptr);
- }
-
- operator T*()
- {
- return address;
- };
-
- operator T*() const
- {
- return address;
- };
-
- operator void*()
- {
- return address;
- };
-
- operator ILEMemHandle()
- {
- return handle;
- }
-
- void alloc(size_t size)
- {
- address = (T*)malloc_aligned(size);
- if (address)
- db2i_ileBridge::registerPtr(address, &handle);
- mallocedHere = 1;
- }
-
- void assign(T* ptr)
- {
- address = ptr;
- db2i_ileBridge::registerPtr((void*)ptr, &handle);
- mallocedHere = 0;
- }
-
- void realloc(size_t size)
- {
- dealloc();
- alloc(size);
- }
-
- void reassign(T* ptr)
- {
- dealloc();
- assign(ptr);
- }
-
- void dealloc()
- {
- if (address)
- {
- db2i_ileBridge::unregisterPtr(handle);
-
- if (mallocedHere)
- free_aligned((void*)address);
- }
- address = NULL;
- handle = 0;
- }
-
- ~ValidatedPointer()
- {
- dealloc();
- }
-
-private:
- // Disable copy ctor and assignment operator, as these would break
- // the registration guarantees provided by the class.
- ValidatedPointer& operator= (const ValidatedPointer newVal);
- ValidatedPointer(ValidatedPointer& newCopy);
-
- ILEMemHandle handle;
- T* address;
- char mallocedHere;
-};
-
-
-/**
- @class ValidatedObject
- @brief This class allows users to instantiate and register a particular
- object in a single step.
-*/
-template<class T>
-class ValidatedObject : public ValidatedPointer<T>
-{
- public:
- ValidatedObject<T>() : ValidatedPointer<T>(&value) {;}
-
- T& operator= (const T newVal) { value = newVal; return value; }
-
- private:
- T value;
-};
-#endif
diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc
deleted file mode 100644
index 39096be7848..00000000000
--- a/storage/ibmdb2i/ha_ibmdb2i.cc
+++ /dev/null
@@ -1,3359 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-
-/**
- @file ha_ibmdb2i.cc
-
- @brief
- The ha_ibmdb2i storage engine provides an interface from MySQL to IBM DB2 for i.
-
-*/
-
-#ifdef USE_PRAGMA_IMPLEMENTATION
-#pragma implementation // gcc: Class implementation
-#endif
-
-#include "ha_ibmdb2i.h"
-#include "mysql_priv.h"
-#include <mysql/plugin.h>
-#include "db2i_ileBridge.h"
-#include "db2i_charsetSupport.h"
-#include <sys/utsname.h>
-#include "db2i_safeString.h"
-
-static const char __NOT_NULL_VALUE_EBCDIC = 0xF0; // '0'
-static const char __NULL_VALUE_EBCDIC = 0xF1; // '1'
-static const char __DEFAULT_VALUE_EBCDIC = 0xC4; // 'D'
-static const char BlankASPName[19] = " ";
-static const int DEFAULT_MAX_ROWS_TO_BUFFER = 4096;
-
-static const char SAVEPOINT_PREFIX[] = {0xD4, 0xE8, 0xE2, 0xD7}; // MYSP (in EBCDIC)
-
-OSVersion osVersion;
-
-
-// ================================================================
-// ================================================================
-// System variables
-static char* ibmdb2i_rdb_name;
-static MYSQL_SYSVAR_STR(rdb_name, ibmdb2i_rdb_name,
- PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY,
- "The name of the RDB to use",
- NULL,
- NULL,
- BlankASPName);
-
-static MYSQL_THDVAR_BOOL(transaction_unsafe,
- 0,
- "Disable support for commitment control",
- NULL,
- NULL,
- FALSE);
-
-static MYSQL_THDVAR_UINT(lob_alloc_size,
- 0,
- "Baseline allocation for lob read buffer",
- NULL,
- NULL,
- 2*1024*1024,
- 64*1024,
- 128*1024*1024,
- 1);
-
-static MYSQL_THDVAR_UINT(max_read_buffer_size,
- 0,
- "Maximum size of buffers used for read-ahead.",
- NULL,
- NULL,
- 1*1024*1024,
- 32*1024,
- 16*1024*1024,
- 1);
-
-static MYSQL_THDVAR_UINT(max_write_buffer_size,
- 0,
- "Maximum size of buffers used for bulk writes.",
- NULL,
- NULL,
- 8*1024*1024,
- 32*1024,
- 64*1024*1024,
- 1);
-
-static MYSQL_THDVAR_BOOL(compat_opt_time_as_duration,
- 0,
- "Control how new TIME columns should be defined in DB2. 0=time-of-day (default), 1=duration.",
- NULL,
- NULL,
- 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(compat_opt_blob_cols,
- 0,
- "Control how new TEXT and BLOB columns should be defined in DB2. 0=CLOB/BLOB (default), 1=VARCHAR/VARBINARY",
- NULL,
- NULL,
- 0,
- 0,
- 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 MYSQL_SYSVAR_BOOL(assume_exclusive_use, ibmdb2i_assume_exclusive_use,
- 0,
- "Can MySQL assume that this process is the only one modifying the DB2 tables. ",
- NULL,
- NULL,
- FALSE);
-
-static MYSQL_THDVAR_BOOL(async_enabled,
- 0,
- "Should reads be done asynchronously when possible",
- NULL,
- NULL,
- TRUE);
-
-static MYSQL_THDVAR_UINT(create_index_option,
- 0,
- "Control whether additional indexes are created. 0=No (default), 1=Create additional *HEX-based index",
- NULL,
- NULL,
- 0,
- 0,
- 1,
- 1);
-
-/* static MYSQL_THDVAR_UINT(discovery_mode,
- 0,
- "Unsupported",
- NULL,
- NULL,
- 0,
- 0,
- 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);
-
-
-inline uint8 ha_ibmdb2i::getCommitLevel(THD* thd)
-{
- if (!THDVAR(thd, transaction_unsafe))
- {
- switch (thd_tx_isolation(thd))
- {
- case ISO_READ_UNCOMMITTED:
- return (accessIntent == QMY_READ_ONLY ? QMY_READ_UNCOMMITTED : QMY_REPEATABLE_READ);
- case ISO_READ_COMMITTED:
- return (accessIntent == QMY_READ_ONLY ? QMY_READ_COMMITTED : QMY_REPEATABLE_READ);
- case ISO_REPEATABLE_READ:
- return QMY_REPEATABLE_READ;
- case ISO_SERIALIZABLE:
- return QMY_SERIALIZABLE;
- }
- }
-
- return QMY_NONE;
-}
-
-inline uint8 ha_ibmdb2i::getCommitLevel()
-{
- return getCommitLevel(ha_thd());
-}
-
-//=====================================================================
-
-static handler *ibmdb2i_create_handler(handlerton *hton,
- TABLE_SHARE *table,
- MEM_ROOT *mem_root);
-static void ibmdb2i_drop_database(handlerton *hton, char* path);
-static int ibmdb2i_savepoint_set(handlerton *hton, THD* thd, void *sv);
-static int ibmdb2i_savepoint_rollback(handlerton *hton, THD* thd, void *sv);
-static int ibmdb2i_savepoint_release(handlerton *hton, THD* thd, void *sv);
-static uint ibmdb2i_alter_table_flags(uint flags);
-
-handlerton *ibmdb2i_hton;
-static bool was_ILE_inited;
-
-/* Tracks the number of open tables */
-static HASH ibmdb2i_open_tables;
-
-/* Mutex used to synchronize initialization of the hash */
-static pthread_mutex_t ibmdb2i_mutex;
-
-
-/**
- Create hash key for tracking open tables.
-*/
-
-static uchar* ibmdb2i_get_key(IBMDB2I_SHARE *share,size_t *length,
- bool not_used __attribute__((unused)))
-{
- *length=share->table_name_length;
- return (uchar*) share->table_name;
-}
-
-
-int ibmdb2i_close_connection(handlerton* hton, THD *thd)
-{
- DBUG_PRINT("ha_ibmdb2i::close_connection", ("Closing %d", thd->thread_id));
- db2i_ileBridge::getBridgeForThread(thd)->closeConnection(thd->thread_id);
- db2i_ileBridge::destroyBridgeForThread(thd);
-
- return 0;
-}
-
-
-static int ibmdb2i_init_func(void *p)
-{
- DBUG_ENTER("ibmdb2i_init_func");
-
- utsname tempName;
- uname(&tempName);
- osVersion.v = atoi(tempName.version);
- osVersion.r = atoi(tempName.release);
-
- was_ILE_inited = false;
- ibmdb2i_hton= (handlerton *)p;
- VOID(pthread_mutex_init(&ibmdb2i_mutex,MY_MUTEX_INIT_FAST));
- (void) hash_init(&ibmdb2i_open_tables,table_alias_charset,32,0,0,
- (hash_get_key) ibmdb2i_get_key,0,0);
-
- ibmdb2i_hton->state= SHOW_OPTION_YES;
- ibmdb2i_hton->create= ibmdb2i_create_handler;
- ibmdb2i_hton->drop_database= ibmdb2i_drop_database;
- ibmdb2i_hton->commit= ha_ibmdb2i::doCommit;
- ibmdb2i_hton->rollback= ha_ibmdb2i::doRollback;
- ibmdb2i_hton->savepoint_offset= 0;
- ibmdb2i_hton->savepoint_set= ibmdb2i_savepoint_set;
- ibmdb2i_hton->savepoint_rollback= ibmdb2i_savepoint_rollback;
- ibmdb2i_hton->savepoint_release= ibmdb2i_savepoint_release;
- ibmdb2i_hton->alter_table_flags=ibmdb2i_alter_table_flags;
- ibmdb2i_hton->close_connection=ibmdb2i_close_connection;
-
- int rc;
-
- rc = initCharsetSupport();
-
- if (!rc)
- rc = db2i_ileBridge::setup();
-
- if (!rc)
- {
- int nameLen = strlen(ibmdb2i_rdb_name);
- for (int i = 0; i < nameLen; ++i)
- {
- ibmdb2i_rdb_name[i] = my_toupper(system_charset_info, (uchar)ibmdb2i_rdb_name[i]);
- }
-
- rc = db2i_ileBridge::initILE(ibmdb2i_rdb_name, (uint16*)(((char*)&ibmdb2i_system_trace)+2));
- if (rc == 0)
- {
- was_ILE_inited = true;
- }
- }
-
- DBUG_RETURN(rc);
-}
-
-
-static int ibmdb2i_done_func(void *p)
-{
- int error= 0;
- DBUG_ENTER("ibmdb2i_done_func");
-
- if (ibmdb2i_open_tables.records)
- error= 1;
-
- if (was_ILE_inited)
- db2i_ileBridge::exitILE();
-
- db2i_ileBridge::takedown();
-
- doneCharsetSupport();
-
- hash_free(&ibmdb2i_open_tables);
- pthread_mutex_destroy(&ibmdb2i_mutex);
-
- DBUG_RETURN(0);
-}
-
-
-IBMDB2I_SHARE *ha_ibmdb2i::get_share(const char *table_name, TABLE *table)
-{
- IBMDB2I_SHARE *share;
- uint length;
- char *tmp_name;
-
- pthread_mutex_lock(&ibmdb2i_mutex);
- length=(uint) strlen(table_name);
-
- if (!(share=(IBMDB2I_SHARE*) hash_search(&ibmdb2i_open_tables,
- (uchar*)table_name,
- length)))
- {
- if (!(share=(IBMDB2I_SHARE *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
- &share, sizeof(*share),
- &tmp_name, length+1,
- NullS)))
- {
- pthread_mutex_unlock(&ibmdb2i_mutex);
- return NULL;
- }
-
- share->use_count=0;
- share->table_name_length=length;
- share->table_name=tmp_name;
- strmov(share->table_name,table_name);
- if (my_hash_insert(&ibmdb2i_open_tables, (uchar*) share))
- goto error;
- thr_lock_init(&share->lock);
- pthread_mutexattr_t mutexattr = MY_MUTEX_INIT_FAST;
- pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&share->mutex, &mutexattr);
-
- share->db2Table = new db2i_table(table->s, table_name);
- int32 rc = share->db2Table->initDB2Objects(table_name);
-
- if (rc)
- {
- delete share->db2Table;
- hash_delete(&ibmdb2i_open_tables, (uchar*) share);
- thr_lock_delete(&share->lock);
- my_errno = rc;
- goto error;
- }
-
- memset(&share->cachedStats, 0, sizeof(share->cachedStats));
- }
- share->use_count++;
- pthread_mutex_unlock(&ibmdb2i_mutex);
-
- db2Table = share->db2Table;
-
- return share;
-
-error:
- pthread_mutex_destroy(&share->mutex);
- my_free((uchar*) share, MYF(0));
- pthread_mutex_unlock(&ibmdb2i_mutex);
-
- return NULL;
-}
-
-
-
-int ha_ibmdb2i::free_share(IBMDB2I_SHARE *share)
-{
- pthread_mutex_lock(&ibmdb2i_mutex);
- if (!--share->use_count)
- {
- delete share->db2Table;
- db2Table = NULL;
-
- hash_delete(&ibmdb2i_open_tables, (uchar*) share);
- thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->mutex);
- my_free(share, MYF(0));
- pthread_mutex_unlock(&ibmdb2i_mutex);
- return 1;
- }
- pthread_mutex_unlock(&ibmdb2i_mutex);
-
- return 0;
-}
-
-static handler* ibmdb2i_create_handler(handlerton *hton,
- TABLE_SHARE *table,
- MEM_ROOT *mem_root)
-{
- return new (mem_root) ha_ibmdb2i(hton, table);
-}
-
-static void ibmdb2i_drop_database(handlerton *hton, char* path)
-{
- DBUG_ENTER("ha_ibmdb2i::ibmdb2i_drop_database");
- int rc = 0;
- char queryBuffer[200];
- String query(queryBuffer, sizeof(queryBuffer), system_charset_info);
- query.length(0);
- query.append(STRING_WITH_LEN(" DROP SCHEMA \""));
- query.append(path+2, strchr(path+2, '/')-(path+2));
- query.append('"');
-
- SqlStatementStream sqlStream(query);
-
- rc = db2i_ileBridge::getBridgeForThread()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- QMY_NONE,
- FALSE,
- TRUE);
- DBUG_VOID_RETURN;
-}
-
-inline static void genSavepointName(const void* sv, char* out)
-{
- *(uint32*)out = *(uint32*)SAVEPOINT_PREFIX;
- DBUG_ASSERT(sizeof(SAVEPOINT_PREFIX) == 4);
- out += sizeof(SAVEPOINT_PREFIX);
-
- longlong2str((longlong)sv, out, 10);
- while (*out)
- {
- out += 0xF0;
- ++out;
- }
-}
-
-
-/*********************************************************************
-Sets a transaction savepoint. */
-static int ibmdb2i_savepoint_set(handlerton* hton, THD* thd, void* sv)
-{
- DBUG_ENTER("ibmdb2i_savepoint_set");
- int rc = 0;
- if (!THDVAR(thd ,transaction_unsafe))
- {
- char name[64];
- genSavepointName(sv, name);
- DBUG_PRINT("ibmdb2i_savepoint_set",("Setting %s", name));
- rc = ha_ibmdb2i::doSavepointSet(thd, name);
- }
- DBUG_RETURN(rc);
-}
-
-
-/*********************************************************************
-Rollback a savepoint. */
-static int ibmdb2i_savepoint_rollback(handlerton* hton, THD* thd, void* sv)
-{
- DBUG_ENTER("ibmdb2i_savepoint_rollback");
- int rc = 0;
- if (!THDVAR(thd,transaction_unsafe))
- {
- char name[64];
- genSavepointName(sv, name);
- DBUG_PRINT("ibmdb2i_savepoint_rollback",("Rolling back %s", name));
- rc = ha_ibmdb2i::doSavepointRollback(thd, name);
- }
- DBUG_RETURN(rc);
-}
-
-
-/*********************************************************************
-Release a savepoint. */
-static int ibmdb2i_savepoint_release(handlerton* hton, THD* thd, void* sv)
-{
- DBUG_ENTER("ibmdb2i_savepoint_release");
- int rc = 0;
- if (!THDVAR(thd,transaction_unsafe))
- {
- char name[64];
- genSavepointName(sv, name);
- DBUG_PRINT("ibmdb2i_savepoint_release",("Releasing %s", name));
- rc = ha_ibmdb2i::doSavepointRelease(thd, name);
- }
- DBUG_RETURN(rc);
-}
-
-/* Thse flags allow for the online add and drop of an index via the CREATE INDEX,
- DROP INDEX, and ALTER TABLE statements. These flags indicate that MySQL is not
- required to lock the table before calling the storage engine to add or drop the
- index(s). */
-static uint ibmdb2i_alter_table_flags(uint flags)
-{
- return (HA_ONLINE_ADD_INDEX | HA_ONLINE_DROP_INDEX |
- HA_ONLINE_ADD_UNIQUE_INDEX | HA_ONLINE_DROP_UNIQUE_INDEX |
- HA_ONLINE_ADD_PK_INDEX | HA_ONLINE_DROP_PK_INDEX);
-}
-
-ha_ibmdb2i::ha_ibmdb2i(handlerton *hton, TABLE_SHARE *table_arg)
- :share(NULL), handler(hton, table_arg),
- activeHandle(0), dataHandle(0),
- activeReadBuf(NULL), activeWriteBuf(NULL),
- blobReadBuffers(NULL), accessIntent(QMY_UPDATABLE), currentRRN(0),
- releaseRowNeeded(FALSE),
- indexReadSizeEstimates(NULL),
- outstanding_start_bulk_insert(false),
- last_rnd_init_rc(0),
- last_index_init_rc(0),
- last_start_bulk_insert_rc(0),
- autoIncLockAcquired(false),
- got_auto_inc_values(false),
- next_identity_value(0),
- indexHandles(0),
- returnDupKeysImmediately(false),
- onDupUpdate(false),
- blobWriteBuffers(NULL),
- forceSingleRowRead(false)
- {
- activeReferences = 0;
- ref_length = sizeof(currentRRN);
- if (table_share && table_share->keys > 0)
- {
- indexHandles = (FILE_HANDLE*)my_malloc(table_share->keys * sizeof(FILE_HANDLE), MYF(MY_WME | MY_ZEROFILL));
- }
- clear_alloc_root(&conversionBufferMemroot);
- }
-
-
-ha_ibmdb2i::~ha_ibmdb2i()
-{
- DBUG_ASSERT(activeReferences == 0 || outstanding_start_bulk_insert);
-
- if (indexHandles)
- my_free(indexHandles, MYF(0));
- if (indexReadSizeEstimates)
- my_free(indexReadSizeEstimates, MYF(0));
-
- cleanupBuffers();
-}
-
-
-static const char *ha_ibmdb2i_exts[] = {
- FID_EXT,
- NullS
-};
-
-const char **ha_ibmdb2i::bas_ext() const
-{
- return ha_ibmdb2i_exts;
-}
-
-
-int ha_ibmdb2i::open(const char *name, int mode, uint test_if_locked)
-{
- DBUG_ENTER("ha_ibmdb2i::open");
-
- initBridge();
-
- dataHandle = bridge()->findAndRemovePreservedHandle(name, &share);
-
- if (share)
- db2Table = share->db2Table;
-
- if (!share && (!(share = get_share(name, table))))
- DBUG_RETURN(my_errno);
- thr_lock_data_init(&share->lock,&lock,NULL);
-
- info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
-
-
- DBUG_RETURN(0);
-}
-
-
-
-
-int ha_ibmdb2i::close(void)
-{
- DBUG_ENTER("ha_ibmdb2i::close");
- int32 rc = 0;
- bool preserveShare = false;
-
- db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread();
-
- if (dataHandle)
- {
- if (bridge->expectErrors(QMY_ERR_PEND_LOCKS)->deallocateFile(dataHandle, FALSE) == QMY_ERR_PEND_LOCKS)
- {
- bridge->preserveHandle(share->table_name, dataHandle, share);
- preserveShare = true;
- }
- dataHandle = 0;
- }
-
- for (int idx = 0; idx < table_share->keys; ++idx)
- {
- if (indexHandles[idx] != 0)
- {
- bridge->deallocateFile(indexHandles[idx], FALSE);
- }
- }
-
- cleanupBuffers();
-
- if (!preserveShare)
- {
- if (free_share(share))
- share = NULL;
- }
-
- DBUG_RETURN(rc);
-}
-
-
-
-int ha_ibmdb2i::write_row(uchar * buf)
-{
-
- DBUG_ENTER("ha_ibmdb2i::write_row");
-
- if (last_start_bulk_insert_rc)
- DBUG_RETURN( last_start_bulk_insert_rc );
-
- ha_statistic_increment(&SSV::ha_write_count);
- int rc = 0;
-
- bool fileHandleNeedsRelease = false;
-
- if (!activeHandle)
- {
- rc = useDataFile();
- if (rc) DBUG_RETURN(rc);
- fileHandleNeedsRelease = true;
- }
-
- if (!outstanding_start_bulk_insert)
- rc = prepWriteBuffer(1, getFileForActiveHandle());
-
- if (!rc)
- {
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
-
- char* writeBuffer = activeWriteBuf->addRow();
- rc = prepareRowForWrite(writeBuffer,
- writeBuffer+activeWriteBuf->getRowNullOffset(),
- true);
- if (rc == 0)
- {
- // If we are doing block inserts, if the MI is supposed to generate an auto_increment
- // (i.e. identity column) value for this record, and if this is not the first record in
- // the block, then store the value (that the MI will generate for the identity column)
- // into the MySQL write buffer. We can predetermine the value because the file is locked.
-
- if ((autoIncLockAcquired) && (default_identity_value) && (got_auto_inc_values))
- {
- if (unlikely((next_identity_value - 1) ==
- maxValueForField(table->next_number_field)))
- {
- rc = QMY_ERR_MAXVALUE;
- }
- else
- {
- rc = table->next_number_field->store((longlong) next_identity_value, TRUE);
- next_identity_value = next_identity_value + incrementByValue;
- }
- }
- // If the buffer is full, or if we locked the file and this is the first or last row
- // of a blocked insert, then flush the buffer.
- if (!rc && (activeWriteBuf->endOfBuffer()) ||
- ((autoIncLockAcquired) &&
- ((!got_auto_inc_values))) ||
- (returnDupKeysImmediately))
- rc = flushWrite(activeHandle, buf);
- }
- else
- activeWriteBuf->deleteRow();
- }
-
- if (fileHandleNeedsRelease)
- releaseActiveHandle();
-
- DBUG_RETURN(rc);
-}
-
-/**
- @brief
- Helper function used by write_row and update_row to prepare the MySQL
- row for insertion into DB2.
-*/
-int ha_ibmdb2i::prepareRowForWrite(char* data, char* nulls, bool honorIdentCols)
-{
- int rc = 0;
-
- // set null map all to non nulls
- memset(nulls,__NOT_NULL_VALUE_EBCDIC, table->s->fields);
- default_identity_value = FALSE;
-
- ulong sql_mode = ha_thd()->variables.sql_mode;
-
- my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
- for (Field **field = table->field; *field && !rc; ++field)
- {
- int fieldIndex = (*field)->field_index;
- if ((*field)->Field::is_null())
- {
- nulls[fieldIndex] = __NULL_VALUE_EBCDIC;
- }
- if (honorIdentCols && ((*field)->flags & AUTO_INCREMENT_FLAG) &&
- *field == table->next_number_field)
-// && ((!autoIncLockAcquired) || (!got_auto_inc_values)))
- {
- if (sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)
- {
- if (!table->auto_increment_field_not_null)
- {
- nulls[fieldIndex] = __DEFAULT_VALUE_EBCDIC;
- default_identity_value = TRUE;
- }
- }
- else if ((*field)->val_int() == 0)
- {
- nulls[fieldIndex] = __DEFAULT_VALUE_EBCDIC;
- default_identity_value = TRUE;
- }
- }
-
- DB2Field& db2Field = db2Table->db2Field(fieldIndex);
- if (nulls[fieldIndex] == __NOT_NULL_VALUE_EBCDIC ||
- db2Field.isBlob())
- {
- rc = convertMySQLtoDB2(*field, db2Field, data + db2Field.getBufferOffset());
- }
- }
-
- if (!rc && db2Table->hasBlobs())
- rc = db2i_ileBridge::getBridgeForThread()->objectOverride(activeHandle,
- activeWriteBuf->ptr());
-
- dbug_tmp_restore_column_map(table->read_set, old_map);
-
- return rc;
-}
-
-
-
-int ha_ibmdb2i::update_row(const uchar * old_data, uchar * new_data)
-{
- DBUG_ENTER("ha_ibmdb2i::update_row");
- ha_statistic_increment(&SSV::ha_update_count);
- int rc;
-
- bool fileHandleNeedsRelease = false;
-
- if (!activeHandle)
- {
- rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle);
- if (rc) DBUG_RETURN(rc);
- fileHandleNeedsRelease = true;
- }
-
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
-
- char* writeBuf = activeWriteBuf->addRow();
- rc = prepareRowForWrite(writeBuf,
- writeBuf+activeWriteBuf->getRowNullOffset(),
- onDupUpdate);
-
- char* lastDupKeyNamePtr = NULL;
- uint32 lastDupKeyNameLen = 0;
-
- if (!rc)
- {
- rc = db2i_ileBridge::getBridgeForThread()->updateRow(activeHandle,
- currentRRN,
- activeWriteBuf->ptr(),
- &lastDupKeyRRN,
- &lastDupKeyNamePtr,
- &lastDupKeyNameLen);
- }
-
- if (lastDupKeyNameLen)
- {
- lastDupKeyID = getKeyFromName(lastDupKeyNamePtr, lastDupKeyNameLen);
- rrnAssocHandle = activeHandle;
- }
-
- if (fileHandleNeedsRelease)
- releaseActiveHandle();
-
- activeWriteBuf->resetAfterWrite();
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::delete_row(const uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::delete_row");
- ha_statistic_increment(&SSV::ha_delete_count);
-
- bool needReleaseFile = false;
- int rc = 0;
-
- if (!activeHandle) // In some circumstances, MySQL comes here after
- { // closing the active handle. We need to re-open.
- rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle);
- needReleaseFile = true;
- }
-
- if (likely(!rc))
- {
- rc = db2i_ileBridge::getBridgeForThread()->deleteRow(activeHandle,
- currentRRN);
- invalidateCachedStats();
- if (needReleaseFile)
- releaseActiveHandle();
- }
-
- DBUG_RETURN(rc);
-}
-
-
-
-int ha_ibmdb2i::index_init(uint idx, bool sorted)
-{
- DBUG_ENTER("ha_ibmdb2i::index_init");
-
- int& rc = last_index_init_rc;
- rc = 0;
-
- invalidDataFound=false;
- tweakReadSet();
-
- active_index=idx;
-
- rc = useIndexFile(idx);
-
- 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);
- }
-
- rrnAssocHandle= 0;
-
- DBUG_RETURN(rc);
-}
-
-
-
-int ha_ibmdb2i::index_read(uchar * buf, const uchar * key,
- uint key_len,
- enum ha_rkey_function find_flag)
-{
- DBUG_ENTER("ha_ibmdb2i::index_read");
-
- if (unlikely(last_index_init_rc)) DBUG_RETURN(last_index_init_rc);
-
- int rc;
-
- ha_rows estimatedRows = getIndexReadEstimate(active_index);
- rc = prepReadBuffer(estimatedRows, db2Table->indexFile(active_index), readAccessIntent);
- if (unlikely(rc)) DBUG_RETURN(rc);
-
- DBUG_ASSERT(activeReadBuf);
-
- keyBuf.allocBuf(activeReadBuf->getRowLength(),
- activeReadBuf->getRowNullOffset(),
- activeReadBuf->getRowLength());
- keyBuf.zeroBuf();
-
- char* db2KeyBufPtr = keyBuf.ptr();
- char* nullKeyMap = db2KeyBufPtr + activeReadBuf->getRowNullOffset();
-
- const uchar* keyBegin = key;
- int partsInUse;
-
- KEY& curKey = table->key_info[active_index];
-
- for (partsInUse = 0; partsInUse < curKey.key_parts, key - keyBegin < key_len; ++partsInUse)
- {
- Field* field = curKey.key_part[partsInUse].field;
- if ((curKey.key_part[partsInUse].null_bit) &&
- (char*)key[0])
- {
- if (field->flags & AUTO_INCREMENT_FLAG)
- {
- table->status = STATUS_NOT_FOUND;
- DBUG_RETURN(HA_ERR_END_OF_FILE);
- }
- else
- {
- nullKeyMap[partsInUse] = __NULL_VALUE_EBCDIC;
- }
- }
- else
- {
- nullKeyMap[partsInUse] = __NOT_NULL_VALUE_EBCDIC;
- convertMySQLtoDB2(field,
- db2Table->db2Field(field->field_index),
- db2KeyBufPtr,
- (uchar*)key+((curKey.key_part[partsInUse].null_bit)? 1 : 0) ); // + (curKey.key_parts+7) / 8);
- }
-
- db2KeyBufPtr += db2Table->db2Field(field->field_index).getByteLengthInRecord();
- key += curKey.key_part[partsInUse].store_length;
- }
-
- keyLen = db2KeyBufPtr - (char*)keyBuf.ptr();
-
- DBUG_PRINT("ha_ibmdb2i::index_read", ("find_flag: %d", find_flag));
-
- char readDirection = QMY_NEXT;
-
- switch (find_flag)
- {
- case HA_READ_AFTER_KEY:
- doInitialRead(QMY_AFTER_EQUAL, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- break;
- case HA_READ_BEFORE_KEY:
- doInitialRead(QMY_BEFORE_EQUAL, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- break;
- case HA_READ_KEY_OR_NEXT:
- doInitialRead(QMY_AFTER_OR_EQUAL, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- break;
- case HA_READ_KEY_OR_PREV:
- DBUG_ASSERT(0); // This function is unused
- doInitialRead(QMY_BEFORE_OR_EQUAL, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- break;
- case HA_READ_PREFIX_LAST_OR_PREV:
- doInitialRead(QMY_LAST_PREVIOUS, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- readDirection = QMY_PREVIOUS;
- break;
- case HA_READ_PREFIX_LAST:
- doInitialRead(QMY_PREFIX_LAST, estimatedRows,
- keyBuf.ptr(), keyLen, partsInUse);
- readDirection = QMY_PREVIOUS;
- break;
- case HA_READ_KEY_EXACT:
- doInitialRead(QMY_EQUAL, estimatedRows, keyBuf.ptr(), keyLen, partsInUse);
- break;
- default:
- DBUG_ASSERT(0);
- return HA_ERR_GENERIC;
- break;
- }
-
- ha_statistic_increment(&SSV::ha_read_key_count);
- rc = readFromBuffer(buf, readDirection);
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::index_next(uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::index_next");
- ha_statistic_increment(&SSV::ha_read_next_count);
-
- int rc = readFromBuffer(buf, QMY_NEXT);
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::index_next_same(uchar *buf, const uchar *key, uint keylen)
-{
- DBUG_ENTER("ha_ibmdb2i::index_next_same");
- ha_statistic_increment(&SSV::ha_read_next_count);
-
- int rc = readFromBuffer(buf, QMY_NEXT_EQUAL);
-
- if (rc == HA_ERR_KEY_NOT_FOUND)
- {
- rc = HA_ERR_END_OF_FILE;
- }
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-int ha_ibmdb2i::index_read_last(uchar * buf, const uchar * key, uint key_len)
-{
- DBUG_ENTER("ha_ibmdb2i::index_read_last");
- DBUG_RETURN(index_read(buf, key, key_len, HA_READ_PREFIX_LAST));
-}
-
-
-
-int ha_ibmdb2i::index_prev(uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::index_prev");
- ha_statistic_increment(&SSV::ha_read_prev_count);
-
- int rc = readFromBuffer(buf, QMY_PREVIOUS);
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::index_first(uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::index_first");
-
- if (unlikely(last_index_init_rc)) DBUG_RETURN(last_index_init_rc);
-
- int rc = prepReadBuffer(DEFAULT_MAX_ROWS_TO_BUFFER,
- db2Table->indexFile(active_index),
- readAccessIntent);
-
- if (rc == 0)
- {
- doInitialRead(QMY_FIRST, DEFAULT_MAX_ROWS_TO_BUFFER);
- ha_statistic_increment(&SSV::ha_read_first_count);
- rc = readFromBuffer(buf, QMY_NEXT);
- }
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::index_last(uchar * buf)
-{
- DBUG_ENTER("ha_ibmdb2i::index_last");
-
- if (unlikely(last_index_init_rc)) DBUG_RETURN(last_index_init_rc);
-
- int rc = prepReadBuffer(DEFAULT_MAX_ROWS_TO_BUFFER,
- db2Table->indexFile(active_index),
- readAccessIntent);
-
- if (rc == 0)
- {
- doInitialRead(QMY_LAST, DEFAULT_MAX_ROWS_TO_BUFFER);
- ha_statistic_increment(&SSV::ha_read_last_count);
- rc = readFromBuffer(buf, QMY_PREVIOUS);
- }
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::rnd_init(bool scan)
-{
- DBUG_ENTER("ha_ibmdb2i::rnd_init");
-
- int& rc = last_rnd_init_rc;
- rc = 0;
-
- tweakReadSet();
- invalidDataFound=false;
-
- uint32 rowsToBlockOnRead;
-
- if (!scan)
- {
- rowsToBlockOnRead = 1;
- }
- else
- {
- rowsToBlockOnRead = DEFAULT_MAX_ROWS_TO_BUFFER;
- }
-
- rc = useDataFile();
-
- 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;
-// }
-
- rc = prepReadBuffer(rowsToBlockOnRead, db2Table->dataFile(), readAccessIntent);
-
- if (!rc && accessIntent != QMY_READ_ONLY)
- rc = prepWriteBuffer(1, db2Table->dataFile());
-
- if (!rc && scan)
- doInitialRead(QMY_FIRST, rowsToBlockOnRead);
-
- if (rc)
- releaseDataFile();
- }
-
- rrnAssocHandle= 0;
-
- DBUG_RETURN(0); // MySQL sometimes does not check the return code, causing
- // an assert in ha_rnd_end later on if we return a non-zero
- // value here.
-}
-
-int ha_ibmdb2i::rnd_end()
-{
- DBUG_ENTER("ha_ibmdb2i::rnd_end");
-
- warnIfInvalidData();
- if (likely(activeReadBuf))
- activeReadBuf->endRead();
- if (last_rnd_init_rc == 0)
- releaseActiveHandle();
- last_rnd_init_rc = 0;
- DBUG_RETURN(0);
-}
-
-
-int32 ha_ibmdb2i::mungeDB2row(uchar* record, const char* dataPtr, const char* nullMapPtr, bool skipLOBs)
-{
- DBUG_ASSERT(dataPtr);
-
- my_bitmap_map *old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
- my_bitmap_map *old_read_map;
-
- if (unlikely(readAllColumns))
- old_read_map = tmp_use_all_columns(table, table->read_set);
-
- resetCharacterConversionBuffers();
-
- my_ptrdiff_t old_ptr= (my_ptrdiff_t) (record - table->record[0]);
- int fieldIndex = 0;
- for (Field **field = table->field; *field; ++field, ++fieldIndex)
- {
- if (unlikely(old_ptr))
- (*field)->move_field_offset(old_ptr);
- if (nullMapPtr[fieldIndex] == __NULL_VALUE_EBCDIC ||
- (!bitmap_is_set(table->read_set, fieldIndex)) ||
- (skipLOBs && db2Table->db2Field(fieldIndex).isBlob()))
- {
- (*field)->set_null();
- }
- else
- {
- (*field)->set_notnull();
- convertDB2toMySQL(db2Table->db2Field(fieldIndex), *field, dataPtr);
- }
- if (unlikely(old_ptr))
- (*field)->move_field_offset(-old_ptr);
-
- }
-
- if (unlikely(readAllColumns))
- tmp_restore_column_map(table->read_set, old_read_map);
- dbug_tmp_restore_column_map(table->write_set, old_write_map);
-
- return 0;
-}
-
-
-int ha_ibmdb2i::rnd_next(uchar *buf)
-{
- DBUG_ENTER("ha_ibmdb2i::rnd_next");
-
- if (unlikely(last_rnd_init_rc)) DBUG_RETURN(last_rnd_init_rc);
- ha_statistic_increment(&SSV::ha_read_rnd_next_count);
-
- int rc;
-
- rc = readFromBuffer(buf, QMY_NEXT);
-
- table->status= (rc ? STATUS_NOT_FOUND: 0);
- DBUG_RETURN(rc);
-}
-
-
-void ha_ibmdb2i::position(const uchar *record)
-{
- DBUG_ENTER("ha_ibmdb2i::position");
- my_store_ptr(ref, ref_length, currentRRN);
- DBUG_VOID_RETURN;
-}
-
-
-int ha_ibmdb2i::rnd_pos(uchar * buf, uchar *pos)
-{
- DBUG_ENTER("ha_ibmdb2i::rnd_pos");
- if (unlikely(last_rnd_init_rc)) DBUG_RETURN( last_rnd_init_rc);
- ha_statistic_increment(&SSV::ha_read_rnd_count);
-
- currentRRN = my_get_ptr(pos, ref_length);
-
- tweakReadSet();
-
- int rc = 0;
-
- if (rrnAssocHandle &&
- (activeHandle != rrnAssocHandle))
- {
- if (activeHandle) releaseActiveHandle();
- rc = useFileByHandle(QMY_UPDATABLE, rrnAssocHandle);
- }
-
- if (likely(rc == 0))
- {
- rc = prepReadBuffer(1, getFileForActiveHandle(), accessIntent);
-
- if (likely(rc == 0) && accessIntent == QMY_UPDATABLE)
- rc = prepWriteBuffer(1, getFileForActiveHandle());
-
- if (likely(rc == 0))
- {
- rc = db2i_ileBridge::getBridgeForThread()->readByRRN(activeHandle,
- activeReadBuf->ptr(),
- currentRRN,
- accessIntent,
- getCommitLevel());
-
- if (likely(rc == 0))
- {
- rrnAssocHandle = activeHandle;
- const char* readBuf = activeReadBuf->getRowN(0);
- rc = mungeDB2row(buf, readBuf, readBuf + activeReadBuf->getRowNullOffset(), false);
- releaseRowNeeded = TRUE;
- }
- }
- }
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::info(uint flag)
-{
- DBUG_ENTER("ha_ibmdb2i::info");
-
- uint16 infoRequested = 0;
- ValidatedPointer<char> rowKeySpcPtr; // Space pointer passed to DB2
- uint32 rowKeySpcLen; // Length of space passed to DB2
- THD* thd = ha_thd();
- int command = thd_sql_command(thd);
-
- if (flag & HA_STATUS_AUTO)
- stats.auto_increment_value = (ulonglong) 0;
-
- if (flag & HA_STATUS_ERRKEY)
- {
- errkey = lastDupKeyID;
- my_store_ptr(dup_ref, ref_length, lastDupKeyRRN);
- }
-
- if (flag & HA_STATUS_TIME)
- {
- if ((flag & HA_STATUS_NO_LOCK) &&
- ibmdb2i_assume_exclusive_use &&
- share &&
- (share->cachedStats.isInited(lastModTime)))
- stats.update_time = share->cachedStats.getUpdateTime();
- else
- infoRequested |= lastModTime;
- }
-
- if (flag & HA_STATUS_CONST)
- {
- stats.block_size=4096;
- infoRequested |= createTime;
-
- if (table->s->keys)
- {
- infoRequested |= rowsPerKey;
- rowKeySpcLen = (table->s->keys) * MAX_DB2_KEY_PARTS * sizeof(uint64);
- rowKeySpcPtr.alloc(rowKeySpcLen);
- memset(rowKeySpcPtr, 0, rowKeySpcLen); // Clear the allocated space
- }
- }
-
- if (flag & HA_STATUS_VARIABLE)
- {
- if ((flag & HA_STATUS_NO_LOCK) &&
- (command != SQLCOM_SHOW_TABLE_STATUS) &&
- ibmdb2i_assume_exclusive_use &&
- share &&
- (share->cachedStats.isInited(rowCount | deletedRowCount | meanRowLen | ioCount)) &&
- (share->cachedStats.getRowCount() >= 2))
- {
- stats.records = share->cachedStats.getRowCount();
- stats.deleted = share->cachedStats.getDelRowCount();
- stats.mean_rec_length = share->cachedStats.getMeanLength();
- stats.data_file_length = share->cachedStats.getAugmentedDataLength();
- }
- else
- {
- infoRequested |= rowCount | deletedRowCount | meanRowLen;
- if (command == SQLCOM_SHOW_TABLE_STATUS)
- infoRequested |= objLength;
- else
- infoRequested |= ioCount;
- }
- }
-
- int rc = 0;
-
- if (infoRequested)
- {
- DBUG_PRINT("ha_ibmdb2i::info",("Retrieving fresh stats %d", flag));
-
- initBridge(thd);
- rc = bridge()->retrieveTableInfo((dataHandle ? dataHandle : db2Table->dataFile()->getMasterDefnHandle()),
- infoRequested,
- stats,
- rowKeySpcPtr);
-
- if (!rc)
- {
- if ((flag & HA_STATUS_VARIABLE) &&
- (command != SQLCOM_SHOW_TABLE_STATUS))
- stats.data_file_length = stats.data_file_length * IO_SIZE;
-
- if ((ibmdb2i_assume_exclusive_use) &&
- (share) &&
- (command != SQLCOM_SHOW_TABLE_STATUS))
- {
- if (flag & HA_STATUS_VARIABLE)
- {
- share->cachedStats.cacheRowCount(stats.records);
- share->cachedStats.cacheDelRowCount(stats.deleted);
- share->cachedStats.cacheMeanLength(stats.mean_rec_length);
- share->cachedStats.cacheAugmentedDataLength(stats.data_file_length);
- }
-
- if (flag & HA_STATUS_TIME)
- {
- share->cachedStats.cacheUpdateTime(stats.update_time);
- }
- }
-
- if (flag & HA_STATUS_CONST)
- {
- ulong i; // Loop counter for indexes
- ulong j; // Loop counter for key parts
- RowKey* rowKeyPtr; // Pointer to 'number of unique rows' array for this index
-
- rowKeyPtr = (RowKey_t*)(void*)rowKeySpcPtr; // Address first array of DB2 row counts
- for (i = 0; i < table->s->keys; i++) // Do for each index, including primary
- {
- for (j = 0; j < table->key_info[i].key_parts; j++)
- {
- table->key_info[i].rec_per_key[j]= rowKeyPtr->RowKeyArray[j];
- }
- rowKeyPtr = rowKeyPtr + 1; // Address next array of DB2 row counts
- }
- }
- }
- else if (rc == HA_ERR_LOCK_WAIT_TIMEOUT && share)
- {
- // If we couldn't retrieve the info because the object was locked,
- // we'll do our best by returning the most recently cached data.
- if ((infoRequested & rowCount) &&
- share->cachedStats.isInited(rowCount))
- stats.records = share->cachedStats.getRowCount();
- if ((infoRequested & deletedRowCount) &&
- share->cachedStats.isInited(deletedRowCount))
- stats.deleted = share->cachedStats.getDelRowCount();
- if ((infoRequested & meanRowLen) &&
- share->cachedStats.isInited(meanRowLen))
- stats.mean_rec_length = share->cachedStats.getMeanLength();
- if ((infoRequested & lastModTime) &&
- share->cachedStats.isInited(lastModTime))
- stats.update_time = share->cachedStats.getUpdateTime();
-
- rc = 0;
- }
- }
-
- DBUG_RETURN(rc);
-}
-
-
-ha_rows ha_ibmdb2i::records()
-{
- DBUG_ENTER("ha_ibmdb2i::records");
- int rc;
- rc = bridge()->retrieveTableInfo((dataHandle ? dataHandle : db2Table->dataFile()->getMasterDefnHandle()),
- rowCount,
- stats);
-
- if (unlikely(rc))
- {
- if (rc == HA_ERR_LOCK_WAIT_TIMEOUT &&
- share &&
- (share->cachedStats.isInited(rowCount)))
- DBUG_RETURN(share->cachedStats.getRowCount());
- else
- DBUG_RETURN(HA_POS_ERROR);
- }
- else if (share)
- {
- share->cachedStats.cacheRowCount(stats.records);
- }
-
- DBUG_RETURN(stats.records);
-}
-
-
-int ha_ibmdb2i::extra(enum ha_extra_function operation)
-{
- DBUG_ENTER("ha_ibmdb2i::extra");
-
- switch(operation)
- {
- // Can these first five flags be replaced by attending to HA_EXTRA_WRITE_CACHE?
- case HA_EXTRA_NO_IGNORE_DUP_KEY:
- case HA_EXTRA_WRITE_CANNOT_REPLACE:
- {
- returnDupKeysImmediately = false;
- onDupUpdate = false;
- }
- break;
- case HA_EXTRA_INSERT_WITH_UPDATE:
- {
- returnDupKeysImmediately = true;
- onDupUpdate = true;
- }
- break;
- case HA_EXTRA_IGNORE_DUP_KEY:
- case HA_EXTRA_WRITE_CAN_REPLACE:
- returnDupKeysImmediately = true;
- break;
- case HA_EXTRA_FLUSH_CACHE:
- if (outstanding_start_bulk_insert)
- finishBulkInsert();
- break;
- }
-
-
- DBUG_RETURN(0);
-}
-
-/**
- @brief
- The DB2 storage engine will ignore a MySQL generated value and will generate
- a new value in SLIC. We arbitrarily set first_value to 1, and set the
- interval to infinity for better performance on multi-row inserts.
-*/
-void ha_ibmdb2i::get_auto_increment(ulonglong offset, ulonglong increment,
- ulonglong nb_desired_values,
- ulonglong *first_value,
- ulonglong *nb_reserved_values)
-{
- DBUG_ENTER("ha_ibmdb2i::get_auto_increment");
- *first_value= 1;
- *nb_reserved_values= ULONGLONG_MAX;
-}
-
-
-
-void ha_ibmdb2i::update_create_info(HA_CREATE_INFO *create_info)
-{
- DBUG_ENTER("ha_ibmdb2i::update_create_info");
-
- if ((!(create_info->used_fields & HA_CREATE_USED_AUTO)) &&
- (table->found_next_number_field != NULL))
- {
- initBridge();
-
- create_info->auto_increment_value= 1;
-
- ha_rows rowCount = records();
-
- if (rowCount == 0)
- {
- create_info->auto_increment_value = db2Table->getStartId();
- DBUG_VOID_RETURN;
- }
- else if (rowCount == HA_POS_ERROR)
- {
- DBUG_VOID_RETURN;
- }
-
- getNextIdVal(&create_info->auto_increment_value);
- }
- DBUG_VOID_RETURN;
-}
-
-
-int ha_ibmdb2i::getNextIdVal(ulonglong *value)
-{
- DBUG_ENTER("ha_ibmdb2i::getNextIdVal");
-
- char queryBuffer[MAX_DB2_COLNAME_LENGTH + MAX_DB2_QUALIFIEDNAME_LENGTH + 64];
- strcpy(queryBuffer, " SELECT CAST(MAX( ");
- convertMySQLNameToDB2Name(table->found_next_number_field->field_name,
- strend(queryBuffer),
- MAX_DB2_COLNAME_LENGTH+1);
- strcat(queryBuffer, ") AS BIGINT) FROM ");
- db2Table->getDB2QualifiedName(strend(queryBuffer));
- DBUG_ASSERT(strlen(queryBuffer) < sizeof(queryBuffer));
-
- SqlStatementStream sqlStream(queryBuffer);
- DBUG_PRINT("ha_ibmdb2i::getNextIdVal", ("Sent to DB2: %s",queryBuffer));
-
- int rc = 0;
- FILE_HANDLE fileHandle2;
- uint32 db2RowDataLen2;
- rc = bridge()->prepOpen(sqlStream.getPtrToData(),
- &fileHandle2,
- &db2RowDataLen2);
- if (likely(rc == 0))
- {
- IOReadBuffer rowBuffer(1, db2RowDataLen2);
- rc = bridge()->read(fileHandle2,
- rowBuffer.ptr(),
- QMY_READ_ONLY,
- QMY_NONE,
- QMY_FIRST);
-
- if (likely(rc == 0))
- {
- /* This check is here for the case where the table is not empty,
- but the auto_increment starting value has been changed since
- the last record was written. */
-
- longlong maxIdVal = *(longlong*)(rowBuffer.getRowN(0));
- if ((maxIdVal + 1) > db2Table->getStartId())
- *value = maxIdVal + 1;
- else
- *value = db2Table->getStartId();
- }
-
- bridge()->deallocateFile(fileHandle2);
- }
- DBUG_RETURN(rc);
-}
-
-
-/*
- Updates index cardinalities.
-*/
-int ha_ibmdb2i::analyze(THD* thd, HA_CHECK_OPT *check_opt)
-{
- DBUG_ENTER("ha_ibmdb2i::analyze");
- info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
- DBUG_RETURN(0);
-}
-
-int ha_ibmdb2i::optimize(THD* thd, HA_CHECK_OPT *check_opt)
-{
- DBUG_ENTER("ha_ibmdb2i::optimize");
-
- initBridge(thd);
-
- if (unlikely(records() == 0))
- DBUG_RETURN(0); // DB2 doesn't like to reorganize a table with no data.
-
- quiesceAllFileHandles();
-
- int32 rc = bridge()->optimizeTable(db2Table->dataFile()->getMasterDefnHandle());
- info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
-
- DBUG_RETURN(rc);
-}
-
-
-/**
- @brief
- Determines if an ALTER TABLE is allowed to switch the storage engine
- for this table. If the table has a foreign key or is referenced by a
- foreign key, then it cannot be switched.
-*/
-bool ha_ibmdb2i::can_switch_engines(void)
-/*=================================*/
-{
- DBUG_ENTER("ha_ibmdb2i::can_switch_engines");
-
- int rc = 0;
- FILE_HANDLE queryFile = 0;
- uint32 resultRowLen;
- uint count = 0;
- bool can_switch = FALSE; // 1 if changing storage engine is allowed
-
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- String query(256);
- query.append(STRING_WITH_LEN(" SELECT COUNT(*) FROM SYSIBM.SQLFOREIGNKEYS WHERE ((PKTABLE_SCHEM = '"));
- query.append(libName+1, strlen(libName)-2); // Remove quotes from parent schema name
- query.append(STRING_WITH_LEN("' AND PKTABLE_NAME = '"));
- query.append(fileName+1,strlen(fileName)-2); // Remove quotes from file name
- query.append(STRING_WITH_LEN("') OR (FKTABLE_SCHEM = '"));
- query.append(libName+1,strlen(libName)-2); // Remove quotes from child schema
- query.append(STRING_WITH_LEN("' AND FKTABLE_NAME = '"));
- query.append(fileName+1,strlen(fileName)-2); // Remove quotes from child name
- query.append(STRING_WITH_LEN("'))"));
-
- SqlStatementStream sqlStream(query);
-
- rc = bridge()->prepOpen(sqlStream.getPtrToData(),
- &queryFile,
- &resultRowLen);
- if (rc == 0)
- {
- IOReadBuffer rowBuffer(1, resultRowLen);
-
- rc = bridge()->read(queryFile,
- rowBuffer.ptr(),
- QMY_READ_ONLY,
- QMY_NONE,
- QMY_FIRST);
- if (!rc)
- {
- count = *(uint*)(rowBuffer.getRowN(0));
- if (count == 0)
- can_switch = TRUE;
- }
-
- bridge()->deallocateFile(queryFile);
- }
- DBUG_RETURN(can_switch);
-}
-
-
-
-bool ha_ibmdb2i::check_if_incompatible_data(HA_CREATE_INFO *info,
- uint table_changes)
-{
- DBUG_ENTER("ha_ibmdb2i::check_if_incompatible_data");
- uint i;
- /* Check that auto_increment value and field definitions were
- not changed. */
- if ((info->used_fields & HA_CREATE_USED_AUTO &&
- info->auto_increment_value != 0) ||
- table_changes != IS_EQUAL_YES)
- DBUG_RETURN(COMPATIBLE_DATA_NO);
- /* Check if any fields were renamed. */
- for (i= 0; i < table->s->fields; i++)
- {
- Field *field= table->field[i];
- if (field->flags & FIELD_IS_RENAMED)
- {
- DBUG_PRINT("info", ("Field has been renamed, copy table"));
- DBUG_RETURN(COMPATIBLE_DATA_NO);
- }
- }
- DBUG_RETURN(COMPATIBLE_DATA_YES);
-}
-
-int ha_ibmdb2i::reset_auto_increment(ulonglong value)
- {
- DBUG_ENTER("ha_ibmdb2i::reset_auto_increment");
-
- int rc = 0;
-
- quiesceAllFileHandles();
-
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- String query(512);
- query.append(STRING_WITH_LEN(" ALTER TABLE "));
- query.append(libName);
- query.append('.');
- query.append(fileName);
- query.append(STRING_WITH_LEN(" ALTER COLUMN "));
- char colName[MAX_DB2_COLNAME_LENGTH+1];
- convertMySQLNameToDB2Name(table->found_next_number_field->field_name,
- colName,
- sizeof(colName));
- query.append(colName);
-
- char restart_value[22];
- CHARSET_INFO *cs= &my_charset_bin;
- uint len = (uint)(cs->cset->longlong10_to_str)(cs,restart_value,sizeof(restart_value), 10, value);
- restart_value[len] = 0;
-
- query.append(STRING_WITH_LEN(" RESTART WITH "));
- query.append(restart_value);
-
- SqlStatementStream sqlStream(query);
- DBUG_PRINT("ha_ibmdb2i::reset_auto_increment", ("Sent to DB2: %s",query.c_ptr()));
-
- rc = db2i_ileBridge::getBridgeForThread()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- QMY_NONE, //getCommitLevel(),
- FALSE,
- FALSE,
- TRUE, //FALSE,
- dataHandle);
- if (rc == 0)
- db2Table->updateStartId(value);
-
- DBUG_RETURN(rc);
-}
-
-
-/**
- @brief
- This function receives an error code that was previously set by the handler.
- It returns to MySQL the error string associated with that error.
-*/
-bool ha_ibmdb2i::get_error_message(int error, String *buf)
-{
- DBUG_ENTER("ha_ibmdb2i::get_error_message");
- 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());
- char* errMsg = bridge->getErrorStorage();
- buf->copy(errMsg, strlen(errMsg),system_charset_info);
- bridge->freeErrorStorage();
- }
- DBUG_RETURN(FALSE);
-}
-
-
-int ha_ibmdb2i::delete_all_rows()
-{
- DBUG_ENTER("ha_ibmdb2i::delete_all_rows");
- int rc = 0;
- char queryBuffer[MAX_DB2_QUALIFIEDNAME_LENGTH + 64];
- strcpy(queryBuffer, " DELETE FROM ");
- db2Table->getDB2QualifiedName(strend(queryBuffer));
- DBUG_ASSERT(strlen(queryBuffer) < sizeof(queryBuffer));
-
- SqlStatementStream sqlStream(queryBuffer);
- DBUG_PRINT("ha_ibmdb2i::delete_all_rows", ("Sent to DB2: %s",queryBuffer));
- rc = bridge()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- getCommitLevel(),
- false,
- false,
- true,
- dataHandle);
-
- /* If this method was called on behalf of a TRUNCATE TABLE statement, and if */
- /* the table has an auto_increment field, then reset the starting value for */
- /* the auto_increment field to 1.
- */
- if (rc == 0 && thd_sql_command(ha_thd()) == SQLCOM_TRUNCATE &&
- table->found_next_number_field )
- rc = reset_auto_increment(1);
-
- invalidateCachedStats();
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::external_lock(THD *thd, int lock_type)
-{
- int rc = 0;
-
- DBUG_ENTER("ha_ibmdb2i::external_lock");
- DBUG_PRINT("ha_ibmdb2i::external_lock",("Lock type: %d", lock_type));
-
- if (lock_type == F_RDLCK)
- accessIntent = QMY_READ_ONLY;
- else if (lock_type == F_WRLCK)
- accessIntent = QMY_UPDATABLE;
-
- initBridge(thd);
- int command = thd_sql_command(thd);
-
- if (!THDVAR(thd,transaction_unsafe))
- {
- if (lock_type != F_UNLCK)
- {
- if (autoCommitIsOn(thd) == QMY_YES)
- {
- trans_register_ha(thd, FALSE, ibmdb2i_hton);
- }
- else
- {
- trans_register_ha(thd, TRUE, ibmdb2i_hton);
- if (likely(command != SQLCOM_CREATE_TABLE))
- {
- trans_register_ha(thd, FALSE, ibmdb2i_hton);
- bridge()->beginStmtTx();
- }
- }
- }
- }
-
- if (command == SQLCOM_LOCK_TABLES ||
- command == SQLCOM_ALTER_TABLE ||
- command == SQLCOM_UNLOCK_TABLES ||
- (accessIntent == QMY_UPDATABLE &&
- (command == SQLCOM_UPDATE ||
- command == SQLCOM_UPDATE_MULTI ||
- command == SQLCOM_DELETE ||
- command == SQLCOM_DELETE_MULTI ||
- command == SQLCOM_REPLACE ||
- command == SQLCOM_REPLACE_SELECT) &&
- getCommitLevel(thd) == QMY_NONE))
- {
- char action;
- char type;
- if (lock_type == F_UNLCK)
- {
- action = QMY_UNLOCK;
- type = accessIntent == QMY_READ_ONLY ? QMY_LSRD : QMY_LENR;
- }
- else
- {
- action = QMY_LOCK;
- type = lock_type == F_RDLCK ? QMY_LSRD : QMY_LENR;
- }
-
- DBUG_PRINT("ha_ibmdb2i::external_lock",("%socking table", action==QMY_LOCK ? "L" : "Unl"));
-
- if (!dataHandle)
- rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection);
-
- rc = bridge()->lockObj(dataHandle,
- 0,
- action,
- type,
- (command == SQLCOM_LOCK_TABLES ? QMY_NO : QMY_YES));
-
- }
-
- // 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);
-}
-
-
-THR_LOCK_DATA **ha_ibmdb2i::store_lock(THD *thd,
- THR_LOCK_DATA **to,
- enum thr_lock_type lock_type)
-{
- if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
- {
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
- lock_type <= TL_WRITE) && !(thd->in_lock_tables && thd_sql_command(thd) == SQLCOM_LOCK_TABLES))
- lock_type= TL_WRITE_ALLOW_WRITE;
- lock.type=lock_type;
- }
- *to++= &lock;
- return to;
-}
-
-
-int ha_ibmdb2i::delete_table(const char *name)
-{
- DBUG_ENTER("ha_ibmdb2i::delete_table");
- THD* thd = ha_thd();
- db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread(thd);
-
- char db2Name[MAX_DB2_QUALIFIEDNAME_LENGTH];
- db2i_table::getDB2QualifiedNameFromPath(name, db2Name);
-
- String query(128);
- query.append(STRING_WITH_LEN(" DROP TABLE "));
- query.append(db2Name);
-
- if (thd_sql_command(thd) == SQLCOM_DROP_TABLE &&
- thd->lex->drop_mode == DROP_RESTRICT)
- query.append(STRING_WITH_LEN(" RESTRICT "));
- DBUG_PRINT("ha_ibmdb2i::delete_table", ("Sent to DB2: %s",query.c_ptr()));
-
- SqlStatementStream sqlStream(query);
-
- db2i_table::getDB2LibNameFromPath(name, db2Name);
- bool isTemporary = (strcmp(db2Name, DB2I_TEMP_TABLE_SCHEMA) == 0 ? TRUE : FALSE);
-
- int rc = bridge->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- (isTemporary ? QMY_NONE : getCommitLevel(thd)),
- FALSE,
- FALSE,
- isTemporary);
-
- if (rc == HA_ERR_NO_SUCH_TABLE)
- {
- warning(thd, DB2I_ERR_TABLE_NOT_FOUND, name);
- rc = 0;
- }
-
- if (rc == 0)
- {
- db2i_table::deleteAssocFiles(name);
- }
-
- FILE_HANDLE savedHandle = bridge->findAndRemovePreservedHandle(name, &share);
- while (savedHandle)
- {
- bridge->deallocateFile(savedHandle, TRUE);
- DBUG_ASSERT(share);
- if (free_share(share))
- share = NULL;
- savedHandle = bridge->findAndRemovePreservedHandle(name, &share);
- }
-
- my_errno = rc;
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::rename_table(const char * from, const char * to)
-{
- DBUG_ENTER("ha_ibmdb2i::rename_table ");
-
- char db2FromFileName[MAX_DB2_FILENAME_LENGTH + 1];
- char db2ToFileName[MAX_DB2_FILENAME_LENGTH+1];
- char db2FromLibName[MAX_DB2_SCHEMANAME_LENGTH+1];
- char db2ToLibName[MAX_DB2_SCHEMANAME_LENGTH+1];
-
- db2i_table::getDB2LibNameFromPath(from, db2FromLibName);
- db2i_table::getDB2LibNameFromPath(to, db2ToLibName);
-
- if (strcmp(db2FromLibName, db2ToLibName) != 0 )
- {
- getErrTxt(DB2I_ERR_RENAME_MOVE,from,to);
- DBUG_RETURN(DB2I_ERR_RENAME_MOVE);
- }
-
- db2i_table::getDB2FileNameFromPath(from, db2FromFileName, db2i_table::ASCII_NATIVE);
- db2i_table::getDB2FileNameFromPath(to, db2ToFileName);
-
- char escapedFromFileName[2 * MAX_DB2_FILENAME_LENGTH + 1];
-
- uint o = 0;
- uint i = 1;
- do
- {
- escapedFromFileName[o++] = db2FromFileName[i];
- if (db2FromFileName[i] == '+')
- escapedFromFileName[o++] = '+';
- } while (db2FromFileName[++i]);
- escapedFromFileName[o-1] = 0;
-
-
- int rc = 0;
-
- char queryBuffer[sizeof(db2FromLibName) + 2 * sizeof(db2FromFileName) + 256];
- SafeString selectQuery(queryBuffer, sizeof(queryBuffer));
- selectQuery.strncat(STRING_WITH_LEN("SELECT CAST(INDEX_NAME AS VARCHAR(128) CCSID 1208) FROM QSYS2.SYSINDEXES WHERE INDEX_NAME LIKE '%+_+_+_%"));
- selectQuery.strcat(escapedFromFileName);
- selectQuery.strncat(STRING_WITH_LEN("' ESCAPE '+' AND TABLE_NAME='"));
- selectQuery.strncat(db2FromFileName+1, strlen(db2FromFileName)-2);
- selectQuery.strncat(STRING_WITH_LEN("' AND TABLE_SCHEMA='"));
- selectQuery.strncat(db2FromLibName+1, strlen(db2FromLibName)-2);
- selectQuery.strcat('\'');
- DBUG_ASSERT(!selectQuery.overflowed());
-
- SqlStatementStream indexQuery(selectQuery.ptr());
-
- FILE_HANDLE queryFile = 0;
- uint32 resultRowLen;
-
- initBridge();
- rc = bridge()->prepOpen(indexQuery.getPtrToData(),
- &queryFile,
- &resultRowLen);
-
- if (unlikely(rc))
- DBUG_RETURN(rc);
-
- IOReadBuffer rowBuffer(1, resultRowLen);
-
- int tableNameLen = strlen(db2FromFileName) - 2;
-
- SqlStatementStream renameQuery(64);
- String query;
- while (rc == 0)
- {
- query.length(0);
-
- rc = bridge()->read(queryFile,
- rowBuffer.ptr(),
- QMY_READ_ONLY,
- QMY_NONE,
- QMY_NEXT);
-
- if (!rc)
- {
- const char* rowData = rowBuffer.getRowN(0);
- char indexFileName[MAX_DB2_FILENAME_LENGTH];
- memset(indexFileName, 0, sizeof(indexFileName));
-
- uint16 fileNameLen = *(uint16*)(rowData);
- strncpy(indexFileName, rowData + sizeof(uint16), fileNameLen);
-
- int bytesToRetain = fileNameLen - tableNameLen;
- if (bytesToRetain <= 0)
- /* We can't handle index names in which the MySQL index name and
- the table name together are longer than the max index name. */
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*");
- DBUG_RETURN(DB2I_ERR_INVALID_NAME);
- }
- char indexName[MAX_DB2_FILENAME_LENGTH];
- memset(indexName, 0, sizeof(indexName));
-
- strncpy(indexName,
- indexFileName,
- bytesToRetain);
-
- char db2IndexName[MAX_DB2_FILENAME_LENGTH+1];
-
- convertMySQLNameToDB2Name(indexFileName, db2IndexName, sizeof(db2IndexName));
-
- query.append(STRING_WITH_LEN("RENAME INDEX "));
- query.append(db2FromLibName);
- query.append('.');
- query.append(db2IndexName);
- query.append(STRING_WITH_LEN(" TO "));
- if (db2i_table::appendQualifiedIndexFileName(indexName, db2ToFileName, query, db2i_table::ASCII_SQL, typeNone) == -1)
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*");
- DBUG_RETURN(DB2I_ERR_INVALID_NAME );
- }
- renameQuery.addStatement(query);
- DBUG_PRINT("ha_ibmdb2i::rename_table", ("Sent to DB2: %s",query.c_ptr_safe()));
- }
- }
-
-
- if (queryFile)
- bridge()->deallocateFile(queryFile);
-
- if (rc != HA_ERR_END_OF_FILE)
- DBUG_RETURN(rc);
-
- char db2Name[MAX_DB2_QUALIFIEDNAME_LENGTH];
-
- /* Rename the table */
- query.length(0);
- query.append(STRING_WITH_LEN(" RENAME TABLE "));
- db2i_table::getDB2QualifiedNameFromPath(from, db2Name);
- query.append(db2Name);
- query.append(STRING_WITH_LEN(" TO "));
- query.append(db2ToFileName);
- DBUG_PRINT("ha_ibmdb2i::rename_table", ("Sent to DB2: %s",query.c_ptr_safe()));
- renameQuery.addStatement(query);
- rc = bridge()->execSQL(renameQuery.getPtrToData(),
- renameQuery.getStatementCount(),
- getCommitLevel());
-
- if (!rc)
- db2i_table::renameAssocFiles(from, to);
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
- HA_CREATE_INFO *create_info)
-{
- DBUG_ENTER("ha_ibmdb2i::create");
-
- int rc;
- char fileSortSequence[11] = "*HEX";
- char fileSortSequenceLibrary[11] = "";
- char fileSortSequenceType = ' ';
- char libName[MAX_DB2_SCHEMANAME_LENGTH+1];
- char fileName[MAX_DB2_FILENAME_LENGTH+1];
- char colName[MAX_DB2_COLNAME_LENGTH+1];
- bool isTemporary;
- ulong auto_inc_value;
-
- db2i_table::getDB2LibNameFromPath(name, libName);
- db2i_table::getDB2FileNameFromPath(name, fileName);
-
- if (osVersion.v < 6)
- {
- if (strlen(libName) >
- MAX_DB2_V5R4_LIBNAME_LENGTH + (isOrdinaryIdentifier(libName) ? 2 : 0))
- {
- getErrTxt(DB2I_ERR_TOO_LONG_SCHEMA,libName, MAX_DB2_V5R4_LIBNAME_LENGTH);
- DBUG_RETURN(DB2I_ERR_TOO_LONG_SCHEMA);
- }
- }
- else if (strlen(libName) > MAX_DB2_V6R1_LIBNAME_LENGTH)
- {
- getErrTxt(DB2I_ERR_TOO_LONG_SCHEMA,libName, MAX_DB2_V6R1_LIBNAME_LENGTH);
- DBUG_RETURN(DB2I_ERR_TOO_LONG_SCHEMA);
- }
-
- String query(256);
-
- if (strcmp(libName, DB2I_TEMP_TABLE_SCHEMA))
- {
- query.append(STRING_WITH_LEN("CREATE TABLE "));
- query.append(libName);
- query.append('.');
- query.append(fileName);
- isTemporary = FALSE;
- }
- else
- {
- query.append(STRING_WITH_LEN("DECLARE GLOBAL TEMPORARY TABLE "));
- query.append(fileName);
- isTemporary = TRUE;
- }
- query.append(STRING_WITH_LEN(" ("));
-
- THD* thd = ha_thd();
- enum_TimeFormat timeFormat = (enum_TimeFormat)(THDVAR(thd, compat_opt_time_as_duration));
- 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;
- for (field= table_arg->field; *field; field++)
- {
- if ( field != table_arg->field ) // Not the first one
- query.append(STRING_WITH_LEN(" , "));
-
- if (!convertMySQLNameToDB2Name((*field)->field_name, colName, sizeof(colName)))
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"field",(*field)->field_name);
- DBUG_RETURN(DB2I_ERR_INVALID_NAME );
- }
-
- query.append(colName);
- query.append(' ');
-
- if (rc = getFieldTypeMapping(*field,
- query,
- timeFormat,
- blobMapping,
- zeroDate,
- propagateDefaults,
- yearFormat))
- DBUG_RETURN(rc);
-
- if ( (*field)->flags & NOT_NULL_FLAG )
- {
- query.append(STRING_WITH_LEN(" NOT NULL "));
- }
- if ( (*field)->flags & AUTO_INCREMENT_FLAG )
- {
-#ifdef WITH_PARTITION_STORAGE_ENGINE
- if (table_arg->part_info)
- {
- getErrTxt(DB2I_ERR_PART_AUTOINC);
- DBUG_RETURN(DB2I_ERR_PART_AUTOINC);
- }
-#endif
- query.append(STRING_WITH_LEN(" GENERATED BY DEFAULT AS IDENTITY ") );
- if (create_info->auto_increment_value != 0)
- {
- /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE TABLE ...AUTO_INCREMENT = x; Set the starting
- value for the auto_increment column. */
- char stringValue[22];
- CHARSET_INFO *cs= &my_charset_bin;
- uint len = (uint)(cs->cset->longlong10_to_str)(cs,stringValue,sizeof(stringValue), 10, create_info->auto_increment_value);
- stringValue[len] = 0;
- query.append(STRING_WITH_LEN(" (START WITH "));
- query.append(stringValue);
-
- uint64 maxValue=maxValueForField(*field);
-
- if (maxValue)
- {
- len = (uint)(cs->cset->longlong10_to_str)(cs,stringValue,sizeof(stringValue), 10, maxValue);
- stringValue[len] = 0;
- query.append(STRING_WITH_LEN(" MAXVALUE "));
- query.append(stringValue);
- }
-
- query.append(STRING_WITH_LEN(") "));
- }
-
- }
- }
-
- String fieldDefinition(128);
-
- if (table_arg->s->primary_key != MAX_KEY && !isTemporary)
- {
- query.append(STRING_WITH_LEN(", PRIMARY KEY "));
- rc = buildIndexFieldList(fieldDefinition,
- table_arg->key_info[table_arg->s->primary_key],
- true,
- &fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
- if (rc) DBUG_RETURN(rc);
- query.append(fieldDefinition);
- }
-
- rc = buildDB2ConstraintString(thd->lex,
- query,
- name,
- table_arg->field,
- &fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
- if (rc) DBUG_RETURN (rc);
-
- query.append(STRING_WITH_LEN(" ) "));
-
- if (isTemporary)
- query.append(STRING_WITH_LEN(" ON COMMIT PRESERVE ROWS "));
-
- if (create_info->alias)
- generateAndAppendRCDFMT(create_info->alias, query);
- else if (((TABLE_LIST*)(thd->lex->select_lex.table_list.first))->table_name)
- generateAndAppendRCDFMT((char*)((TABLE_LIST*)(thd->lex->select_lex.table_list.first))->table_name, query);
-
- DBUG_PRINT("ha_ibmdb2i::create", ("Sent to DB2: %s",query.c_ptr()));
- SqlStatementStream sqlStream(query.length());
- sqlStream.addStatement(query,fileSortSequence,fileSortSequenceLibrary);
-
- if (table_arg->s->primary_key != MAX_KEY &&
- !isTemporary &&
- (THDVAR(thd, create_index_option)==1) &&
- (fileSortSequenceType != 'B') &&
- (fileSortSequenceType != ' '))
- {
- rc = generateShadowIndex(sqlStream,
- table_arg->key_info[table_arg->s->primary_key],
- libName,
- fileName,
- fieldDefinition);
- if (rc) DBUG_RETURN(rc);
- }
- for (uint i = 0; i < table_arg->s->keys; ++i)
- {
- if (i != table_arg->s->primary_key || isTemporary)
- {
- rc = buildCreateIndexStatement(sqlStream,
- table_arg->key_info[i],
- false,
- libName,
- fileName);
- if (rc) DBUG_RETURN (rc);
- }
- }
-
- bool noCommit = isTemporary || ((!autoCommitIsOn(thd)) && (thd_sql_command(thd) == SQLCOM_ALTER_TABLE));
-
- initBridge();
-
-// if (THDVAR(thd, discovery_mode) == 1)
-// bridge()->expectErrors(QMY_ERR_TABLE_EXISTS);
-
- rc = bridge()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- (isTemporary ? QMY_NONE : getCommitLevel(thd)),
- TRUE,
- FALSE,
- noCommit );
-
- if (unlikely(rc == QMY_ERR_MSGID) &&
- memcmp(bridge()->getErrorMsgID(), DB2I_SQL0350, 7) == 0)
- {
- my_error(ER_BLOB_USED_AS_KEY, MYF(0), "*unknown*");
- rc = ER_BLOB_USED_AS_KEY;
- }
-/* else if (unlikely(rc == QMY_ERR_TABLE_EXISTS) &&
- THDVAR(thd, discovery_mode) == 1)
- {
- db2i_table* temp = new db2i_table(table_arg->s, name);
- int32 rc = temp->fastInitForCreate(name);
- delete temp;
-
- if (!rc)
- warning(thd, DB2I_ERR_WARN_CREATE_DISCOVER);
-
- DBUG_RETURN(rc);
- }
-*/
-
- if (!rc && !isTemporary)
- {
- db2i_table* temp = new db2i_table(table_arg->s, name);
- rc = temp->fastInitForCreate(name);
- delete temp;
- if (rc)
- delete_table(name);
- }
-
- DBUG_RETURN(rc);
-}
-
-
-/**
- @brief
- Add an index on-line to a table. This method is called on behalf of
- a CREATE INDEX or ALTER TABLE statement.
- It is implemented via a composed DDL statement passed to DB2.
-*/
-int ha_ibmdb2i::add_index(TABLE *table_arg,
- KEY *key_info,
- uint num_of_keys)
-{
- DBUG_ENTER("ha_ibmdb2i::add_index");
-
- int rc;
- SqlStatementStream sqlStream(256);
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- quiesceAllFileHandles();
-
- uint primaryKey = MAX_KEY;
- if (table_arg->s->primary_key >= MAX_KEY && !db2Table->isTemporary())
- {
- for (int i = 0; i < num_of_keys; ++i)
- {
- if (strcmp(key_info[i].name, "PRIMARY") == 0)
- {
- primaryKey = i;
- break;
- }
- else if (primaryKey == MAX_KEY &&
- key_info[i].flags & HA_NOSAME)
- {
- primaryKey = i;
- for (int j=0 ; j < key_info[i].key_parts ;j++)
- {
- uint fieldnr= key_info[i].key_part[j].fieldnr;
- if (table_arg->s->field[fieldnr]->null_ptr ||
- table_arg->s->field[fieldnr]->key_length() !=
- key_info[i].key_part[j].length)
- {
- primaryKey = MAX_KEY;
- break;
- }
- }
- }
- }
- }
-
-
- for (int i = 0; i < num_of_keys; ++i)
- {
- KEY& curKey= key_info[i];
- rc = buildCreateIndexStatement(sqlStream,
- curKey,
- (i == primaryKey),
- libName,
- fileName);
- if (rc) DBUG_RETURN (rc);
- }
-
- rc = bridge()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- getCommitLevel(),
- FALSE,
- FALSE,
- FALSE,
- dataHandle);
-
- /* Handle the case where a unique index is being created but an error occurs
- because the file contains duplicate key values. */
- if (rc == ER_DUP_ENTRY)
- print_keydup_error(MAX_KEY,ER(ER_DUP_ENTRY_WITH_KEY_NAME));
-
- DBUG_RETURN(rc);
-}
-
-/**
- @brief
- Drop an index on-line from a table. This method is called on behalf of
- a DROP INDEX or ALTER TABLE statement.
- It is implemented via a composed DDL statement passed to DB2.
-*/
-int ha_ibmdb2i::prepare_drop_index(TABLE *table_arg,
- uint *key_num, uint num_of_keys)
-{
- DBUG_ENTER("ha_ibmdb2i::prepare_drop_index");
- int rc;
- int i = 0;
- String query(64);
- SqlStatementStream sqlStream(64 * num_of_keys);
- SqlStatementStream shadowStream(64 * num_of_keys);
-
- quiesceAllFileHandles();
-
- const char* libName = db2Table->getDB2LibName(db2i_table::ASCII_SQL);
- const char* fileName = db2Table->getDB2TableName(db2i_table::ASCII_SQL);
-
- while (i < num_of_keys)
- {
- query.length(0);
- DBUG_PRINT("info", ("ha_ibmdb2i::prepare_drop_index %u", key_num[i]));
- KEY& curKey= table_arg->key_info[key_num[i]];
- if (key_num[i] == table->s->primary_key && !db2Table->isTemporary())
- {
- query.append(STRING_WITH_LEN("ALTER TABLE "));
- query.append(libName);
- query.append(STRING_WITH_LEN("."));
- query.append(fileName);
- query.append(STRING_WITH_LEN(" DROP PRIMARY KEY"));
- }
- else
- {
- query.append(STRING_WITH_LEN("DROP INDEX "));
- query.append(libName);
- query.append(STRING_WITH_LEN("."));
- db2i_table::appendQualifiedIndexFileName(curKey.name, fileName, query);
- }
- DBUG_PRINT("ha_ibmdb2i::prepare_drop_index", ("Sent to DB2: %s",query.c_ptr_safe()));
- sqlStream.addStatement(query);
-
- query.length(0);
- query.append(STRING_WITH_LEN("DROP INDEX "));
- query.append(libName);
- query.append(STRING_WITH_LEN("."));
- db2i_table::appendQualifiedIndexFileName(curKey.name, fileName, query, db2i_table::ASCII_SQL, typeHex);
-
- DBUG_PRINT("ha_ibmdb2i::prepare_drop_index", ("Sent to DB2: %s",query.c_ptr_safe()));
- shadowStream.addStatement(query);
-
- ++i;
- }
-
- rc = bridge()->execSQL(sqlStream.getPtrToData(),
- sqlStream.getStatementCount(),
- getCommitLevel(),
- FALSE,
- FALSE,
- FALSE,
- dataHandle);
-
- if (rc == 0)
- bridge()->execSQL(shadowStream.getPtrToData(),
- shadowStream.getStatementCount(),
- getCommitLevel());
-
- DBUG_RETURN(rc);
-}
-
-
-void
-ha_ibmdb2i::unlock_row()
-{
- DBUG_ENTER("ha_ibmdb2i::unlock_row");
- DBUG_VOID_RETURN;
-}
-
-int
-ha_ibmdb2i::index_end()
-{
- DBUG_ENTER("ha_ibmdb2i::index_end");
- warnIfInvalidData();
- last_index_init_rc = 0;
- if (likely(activeReadBuf))
- activeReadBuf->endRead();
- if (likely(!last_index_init_rc))
- releaseIndexFile(active_index);
- active_index= MAX_KEY;
- DBUG_RETURN (0);
-}
-
-int ha_ibmdb2i::doCommit(handlerton *hton, THD *thd, bool all)
-{
- if (!THDVAR(thd, transaction_unsafe))
- {
- if (all || autoCommitIsOn(thd))
- {
- DBUG_PRINT("ha_ibmdb2i::doCommit",("Committing all"));
- return (db2i_ileBridge::getBridgeForThread(thd)->commitmentControl(QMY_COMMIT));
- }
- else
- {
- DBUG_PRINT("ha_ibmdb2i::doCommit",("Committing stmt"));
- return (db2i_ileBridge::getBridgeForThread(thd)->commitStmtTx());
- }
- }
-
- return (0);
-}
-
-
-int ha_ibmdb2i::doRollback(handlerton *hton, THD *thd, bool all)
-{
- if (!THDVAR(thd,transaction_unsafe))
- {
- if (all || autoCommitIsOn(thd))
- {
- DBUG_PRINT("ha_ibmdb2i::doRollback",("Rolling back all"));
- return ( db2i_ileBridge::getBridgeForThread(thd)->commitmentControl(QMY_ROLLBACK));
- }
- else
- {
- DBUG_PRINT("ha_ibmdb2i::doRollback",("Rolling back stmt"));
- return (db2i_ileBridge::getBridgeForThread(thd)->rollbackStmtTx());
- }
- }
- return (0);
-}
-
-
-void ha_ibmdb2i::start_bulk_insert(ha_rows rows)
-{
- DBUG_ENTER("ha_ibmdb2i::start_bulk_insert");
- DBUG_PRINT("ha_ibmdb2i::start_bulk_insert",("Rows hinted %d", rows));
- int rc;
- THD* thd = ha_thd();
- int command = thd_sql_command(thd);
-
- if (db2Table->hasBlobs() ||
- (command == SQLCOM_REPLACE || command == SQLCOM_REPLACE_SELECT))
- rows = 1;
- else if (rows == 0)
- rows = DEFAULT_MAX_ROWS_TO_BUFFER; // Shoot the moon
-
- // If we're doing a multi-row insert, binlogging is active, and the table has an
- // auto_increment column, then we'll attempt to lock the file while we perform a 'fast path' blocked
- // insert. If we can't get the lock, then we'll do a row-by-row 'slow path' insert instead. The reason is
- // because the MI generates the auto_increment (identity value), and if we can't lock the file,
- // then we can't predetermine what that value will be for insertion into the MySQL write buffer.
-
- if ((rows > 1) && // Multi-row insert
- (thd->options & OPTION_BIN_LOG) && // Binlogging is on
- (table->found_next_number_field)) // Table has an auto_increment column
- {
- if (!dataHandle)
- rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection);
-
- rc = bridge()->lockObj(dataHandle, 1, QMY_LOCK, QMY_LEAR, QMY_YES);
- if (rc==0) // Got the lock
- {
- autoIncLockAcquired = TRUE;
- got_auto_inc_values = FALSE;
- }
- else // Didn't get the lock
- rows = 1; // No problem, but don't block inserts
- }
-
- if (activeHandle == 0)
- {
- last_start_bulk_insert_rc = useDataFile();
- if (last_start_bulk_insert_rc == 0)
- last_start_bulk_insert_rc = prepWriteBuffer(rows, db2Table->dataFile());
- }
-
- if (last_start_bulk_insert_rc == 0)
- outstanding_start_bulk_insert = true;
- else
- {
- if (autoIncLockAcquired == TRUE)
- {
- bridge()->lockObj(dataHandle, 0, QMY_UNLOCK, QMY_LEAR, QMY_YES);
- autoIncLockAcquired = FALSE;
- }
- }
-
- DBUG_VOID_RETURN;
-}
-
-
-int ha_ibmdb2i::end_bulk_insert()
-{
- DBUG_ENTER("ha_ibmdb2i::end_bulk_insert");
- int rc = 0;
-
- if (outstanding_start_bulk_insert)
- {
- rc = finishBulkInsert();
- }
-
- my_errno = rc;
-
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::prepReadBuffer(ha_rows rowsToRead, const db2i_file* file, char intent)
-{
- DBUG_ENTER("ha_ibmdb2i::prepReadBuffer");
- DBUG_ASSERT(rowsToRead > 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())
- {
- forceSingleRowRead = true;
- rowsToRead = 1;
- }
-
- rowsToRead = min(stats.records+1,min(rowsToRead, DEFAULT_MAX_ROWS_TO_BUFFER));
-
- uint bufSize = min((format->readRowLen * rowsToRead), THDVAR(thd, max_read_buffer_size));
- multiRowReadBuf.allocBuf(format->readRowLen, format->readRowNullOffset, bufSize);
- activeReadBuf = &multiRowReadBuf;
-
- if (db2Table->hasBlobs())
- {
- if (!blobReadBuffers)
- blobReadBuffers = new BlobCollection(db2Table, THDVAR(thd, lob_alloc_size));
- rc = prepareReadBufferForLobs();
- if (rc) DBUG_RETURN(rc);
- }
-
-// 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);
-}
-
-
-int ha_ibmdb2i::prepWriteBuffer(ha_rows rowsToWrite, const db2i_file* file)
-{
- DBUG_ENTER("ha_ibmdb2i::prepWriteBuffer");
- 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);
-
- uint bufSize = min((format->writeRowLen * rowsToWrite), THDVAR(ha_thd(), max_write_buffer_size));
- multiRowWriteBuf.allocBuf(format->writeRowLen, format->writeRowNullOffset, bufSize);
- activeWriteBuf = &multiRowWriteBuf;
-
- if (!blobWriteBuffers && db2Table->hasBlobs())
- {
- blobWriteBuffers = new ValidatedPointer<char>[db2Table->getBlobCount()];
- }
- DBUG_RETURN(rc);
-}
-
-
-int ha_ibmdb2i::flushWrite(FILE_HANDLE fileHandle, uchar* buf )
-{
- DBUG_ENTER("ha_ibmdb2i::flushWrite");
- int rc;
- int64 generatedIdValue = 0;
- bool IdValueWasGenerated = FALSE;
- char* lastDupKeyNamePtr = NULL;
- uint32 lastDupKeyNameLen = 0;
- int loopCnt = 0;
- bool retry_dup = FALSE;
-
- while (loopCnt == 0 || retry_dup == TRUE)
- {
- rc = bridge()->writeRows(fileHandle,
- activeWriteBuf->ptr(),
- getCommitLevel(),
- &generatedIdValue,
- &IdValueWasGenerated,
- &lastDupKeyRRN,
- &lastDupKeyNamePtr,
- &lastDupKeyNameLen,
- &incrementByValue);
- loopCnt++;
- retry_dup = FALSE;
- invalidateCachedStats();
- if (lastDupKeyNameLen)
- {
- rrnAssocHandle = fileHandle;
-
- int command = thd_sql_command(ha_thd());
-
- if (command == SQLCOM_REPLACE ||
- command == SQLCOM_REPLACE_SELECT)
- lastDupKeyID = 0;
- else
- {
- lastDupKeyID = getKeyFromName(lastDupKeyNamePtr, lastDupKeyNameLen);
-
- if (likely(lastDupKeyID != MAX_KEY))
- {
- uint16 failedRow = activeWriteBuf->rowsWritten()+1;
-
- if (buf && (failedRow != activeWriteBuf->rowCount()))
- {
- const char* badRow = activeWriteBuf->getRowN(failedRow-1);
- bool savedReadAllColumns = readAllColumns;
- readAllColumns = true;
- mungeDB2row(buf,
- badRow,
- badRow + activeWriteBuf->getRowNullOffset(),
- true);
- readAllColumns = savedReadAllColumns;
-
- if (table->found_next_number_field)
- {
- table->next_number_field->store(next_identity_value - (incrementByValue * (activeWriteBuf->rowCount() - (failedRow - 1))));
- }
- }
-
- if (default_identity_value && // Table has ID colm and generating a value
- (!autoIncLockAcquired || !got_auto_inc_values) &&
- // Writing first or only row in block
- loopCnt == 1 && // Didn't already retry
- lastDupKeyID == table->s->next_number_index) // Autoinc column is in failed index
- {
- if (alterStartWith() == 0) // Reset next Identity value to max+1
- retry_dup = TRUE; // Rtry the write operation
- }
- }
- else
- {
- char unknownIndex[MAX_DB2_FILENAME_LENGTH+1];
- convFromEbcdic(lastDupKeyNamePtr, unknownIndex, min(lastDupKeyNameLen, MAX_DB2_FILENAME_LENGTH));
- unknownIndex[min(lastDupKeyNameLen, MAX_DB2_FILENAME_LENGTH)] = 0;
- getErrTxt(DB2I_ERR_UNKNOWN_IDX, unknownIndex);
- }
- }
- }
- }
-
- if ((rc == 0 || rc == HA_ERR_FOUND_DUPP_KEY)
- && default_identity_value && IdValueWasGenerated &&
- (!autoIncLockAcquired || !got_auto_inc_values))
- {
- /* Save the generated identity value for the MySQL last_insert_id() function. */
- insert_id_for_cur_row = generatedIdValue;
-
- /* Store the value into MySQL's buf for row-based replication
- or for an 'on duplicate key update' clause. */
- table->next_number_field->store((longlong) generatedIdValue, TRUE);
- if (autoIncLockAcquired)
- {
- got_auto_inc_values = TRUE;
- next_identity_value = generatedIdValue + incrementByValue;
- }
- }
- else
- {
- if (!autoIncLockAcquired) // Don't overlay value for first row of a block
- insert_id_for_cur_row = 0;
- }
-
-
- activeWriteBuf->resetAfterWrite();
- DBUG_RETURN(rc);
-}
-
-int ha_ibmdb2i::alterStartWith()
-{
- DBUG_ENTER("ha_ibmdb2i::alterStartWith");
- int rc = 0;
- ulonglong nextIdVal;
- if (!dataHandle)
- rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection);
- if (!rc) {rc = bridge()->lockObj(dataHandle, 1, QMY_LOCK, QMY_LENR, QMY_YES);}
- if (!rc)
- {
- rc = getNextIdVal(&nextIdVal);
- if (!rc) {rc = reset_auto_increment(nextIdVal);}
- bridge()->lockObj(dataHandle, 0, QMY_UNLOCK, QMY_LENR, QMY_YES);
- }
- DBUG_RETURN(rc);
-}
-
-bool ha_ibmdb2i::lobFieldsRequested()
-{
- if (!db2Table->hasBlobs())
- {
- DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("No LOBs"));
- return (false);
- }
-
- if (readAllColumns)
- {
- DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("All cols requested"));
- return (true);
- }
-
- for (int i = 0; i < db2Table->getBlobCount(); ++i)
- {
- if (bitmap_is_set(table->read_set, db2Table->blobFields[i]))
- {
- DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("LOB requested"));
- return (true);
- }
- }
-
- DBUG_PRINT("ha_ibmdb2i::lobFieldsRequested",("No LOBs requested"));
- return (false);
-}
-
-
-int ha_ibmdb2i::prepareReadBufferForLobs()
-{
- DBUG_ENTER("ha_ibmdb2i::prepareReadBufferForLobs");
- DBUG_ASSERT(db2Table->hasBlobs());
-
- uint32 activeLobFields = 0;
- DB2LobField* lobField;
- uint16 blobCount = db2Table->getBlobCount();
-
- char* readBuf = activeReadBuf->getRowN(0);
-
- for (int i = 0; i < blobCount; ++i)
- {
- int fieldID = db2Table->blobFields[i];
- DB2Field& db2Field = db2Table->db2Field(fieldID);
- lobField = db2Field.asBlobField(readBuf);
- if (readAllColumns ||
- bitmap_is_set(table->read_set, fieldID))
- {
- lobField->dataHandle = (ILEMemHandle)blobReadBuffers->getBufferPtr(fieldID);
- activeLobFields++;
- }
- else
- {
- lobField->dataHandle = NULL;
- }
- }
-
- if (activeLobFields == 0)
- {
- for (int i = 0; i < blobCount; ++i)
- {
- DB2Field& db2Field = db2Table->db2Field(db2Table->blobFields[i]);
- uint16 offset = db2Field.getBufferOffset() + db2Field.calcBlobPad();
-
- for (int r = 1; r < activeReadBuf->getRowCapacity(); ++r)
- {
- lobField = (DB2LobField*)(activeReadBuf->getRowN(r) + offset);
- lobField->dataHandle = NULL;
- }
- }
- }
-
- activeReadBuf->setRowsToProcess((activeLobFields ? 1 : activeReadBuf->getRowCapacity()));
- int rc = bridge()->objectOverride(activeHandle,
- activeReadBuf->ptr(),
- activeReadBuf->getRowLength());
- DBUG_RETURN(rc);
-}
-
-
-uint32 ha_ibmdb2i::adjustLobBuffersForRead()
-{
- DBUG_ENTER("ha_ibmdb2i::adjustLobBuffersForRead");
-
- char* readBuf = activeReadBuf->getRowN(0);
-
- for (int i = 0; i < db2Table->getBlobCount(); ++i)
- {
- DB2Field& db2Field = db2Table->db2Field(db2Table->blobFields[i]);
- DB2LobField* lobField = db2Field.asBlobField(readBuf);
- if (readAllColumns ||
- bitmap_is_set(table->read_set, db2Table->blobFields[i]))
- {
- lobField->dataHandle = (ILEMemHandle)blobReadBuffers->reallocBuffer(db2Table->blobFields[i], lobField->length);
-
- if (lobField->dataHandle == NULL)
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- }
- else
- {
- lobField->dataHandle = 0;
- }
- }
-
- int32 rc = bridge()->objectOverride(activeHandle,
- activeReadBuf->ptr());
- DBUG_RETURN(rc);
-}
-
-
-
-int ha_ibmdb2i::reset()
-{
- DBUG_ENTER("ha_ibmdb2i::reset");
-
- if (outstanding_start_bulk_insert)
- {
- finishBulkInsert();
- }
-
- if (activeHandle != 0)
- {
- releaseActiveHandle();
- }
-
- cleanupBuffers();
-
- db2i_ileBridge::getBridgeForThread(ha_thd())->freeErrorStorage();
-
- last_rnd_init_rc = last_index_init_rc = last_start_bulk_insert_rc = 0;
-
- returnDupKeysImmediately = false;
- onDupUpdate = false;
- forceSingleRowRead = false;
-
-#ifndef DBUG_OFF
- cachedBridge=NULL;
-#endif
-
- DBUG_RETURN(0);
-}
-
-
-int32 ha_ibmdb2i::buildCreateIndexStatement(SqlStatementStream& sqlStream,
- KEY& key,
- bool isPrimary,
- const char* db2LibName,
- const char* db2FileName)
-{
- DBUG_ENTER("ha_ibmdb2i::buildCreateIndexStatement");
-
- char fileSortSequence[11] = "*HEX";
- char fileSortSequenceLibrary[11] = "";
- char fileSortSequenceType = ' ';
- String query(256);
- query.length(0);
- int rc = 0;
-
- if (isPrimary)
- {
- query.append(STRING_WITH_LEN("ALTER TABLE "));
- query.append(db2LibName);
- query.append('.');
- query.append(db2FileName);
- query.append(STRING_WITH_LEN(" ADD PRIMARY KEY "));
- }
- else
- {
- query.append(STRING_WITH_LEN("CREATE"));
-
- if (key.flags & HA_NOSAME)
- query.append(STRING_WITH_LEN(" UNIQUE WHERE NOT NULL"));
-
- query.append(STRING_WITH_LEN(" INDEX "));
-
- query.append(db2LibName);
- query.append('.');
- if (db2i_table::appendQualifiedIndexFileName(key.name, db2FileName, query))
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*");
- DBUG_RETURN(DB2I_ERR_INVALID_NAME );
- }
-
- query.append(STRING_WITH_LEN(" ON "));
-
- query.append(db2LibName);
- query.append('.');
- query.append(db2FileName);
- }
-
- String fieldDefinition(128);
- rc = buildIndexFieldList(fieldDefinition,
- key,
- isPrimary,
- &fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
-
- if (rc) DBUG_RETURN(rc);
-
- query.append(fieldDefinition);
-
- if ((THDVAR(ha_thd(), create_index_option)==1) &&
- (fileSortSequenceType != 'B') &&
- (fileSortSequenceType != ' '))
- {
- rc = generateShadowIndex(sqlStream,
- key,
- db2LibName,
- db2FileName,
- fieldDefinition);
- if (rc) DBUG_RETURN(rc);
- }
-
- DBUG_PRINT("ha_ibmdb2i::buildCreateIndexStatement", ("Sent to DB2: %s",query.c_ptr_safe()));
- sqlStream.addStatement(query,fileSortSequence,fileSortSequenceLibrary);
-
- DBUG_RETURN(0);
-}
-
-/**
- Generate the SQL syntax for the list of fields to be assigned to the
- specified key. The corresponding sort sequence is also calculated.
-
- @param[out] appendHere The string to receive the generated SQL
- @param key The key to evaluate
- @param isPrimary True if this is being generated on behalf of the primary key
- @param[out] fileSortSequenceType The type of the associated sort sequence
- @param[out] fileSortSequence The name of the associated sort sequence
- @param[out] fileSortSequenceLibrary The library of the associated sort sequence
-
- @return 0 if successful; error value otherwise
-*/
-int32 ha_ibmdb2i::buildIndexFieldList(String& appendHere,
- const KEY& key,
- bool isPrimary,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary)
-{
- DBUG_ENTER("ha_ibmdb2i::buildIndexFieldList");
- appendHere.append(STRING_WITH_LEN(" ( "));
- for (int j = 0; j < key.key_parts; ++j)
- {
- char colName[MAX_DB2_COLNAME_LENGTH+1];
- if (j != 0)
- {
- appendHere.append(STRING_WITH_LEN(" , "));
- }
-
- KEY_PART_INFO& kpi = key.key_part[j];
- Field* field = kpi.field;
-
- convertMySQLNameToDB2Name(field->field_name,
- colName,
- sizeof(colName));
- appendHere.append(colName);
-
- int32 rc;
- rc = updateAssociatedSortSequence(field->charset(),
- fileSortSequenceType,
- fileSortSequence,
- fileSortSequenceLibrary);
- if (rc) DBUG_RETURN (rc);
- }
-
- appendHere.append(STRING_WITH_LEN(" ) "));
-
- DBUG_RETURN(0);
-}
-
-
-/**
- Generate an SQL statement that defines a *HEX sorted index to implement
- the ibmdb2i_create_index.
-
- @param[out] stream The stream to append the generated statement to
- @param key The key to evaluate
- @param[out] libName The library containg the table
- @param[out] fileName The DB2-compatible name of the table
- @param[out] fieldDefinition The list of the fields in the index, in SQL syntax
-
- @return 0 if successful; error value otherwise
-*/
-int32 ha_ibmdb2i::generateShadowIndex(SqlStatementStream& stream,
- const KEY& key,
- const char* libName,
- const char* fileName,
- const String& fieldDefinition)
-{
- String shadowQuery(256);
- shadowQuery.length(0);
- shadowQuery.append(STRING_WITH_LEN("CREATE INDEX "));
- shadowQuery.append(libName);
- shadowQuery.append('.');
- if (db2i_table::appendQualifiedIndexFileName(key.name, fileName, shadowQuery, db2i_table::ASCII_SQL, typeHex))
- {
- getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*");
- return DB2I_ERR_INVALID_NAME;
- }
- shadowQuery.append(STRING_WITH_LEN(" ON "));
- shadowQuery.append(libName);
- shadowQuery.append('.');
- shadowQuery.append(fileName);
- shadowQuery.append(fieldDefinition);
- DBUG_PRINT("ha_ibmdb2i::generateShadowIndex", ("Sent to DB2: %s",shadowQuery.c_ptr_safe()));
- stream.addStatement(shadowQuery,"*HEX","QSYS");
- return 0;
-}
-
-
-void ha_ibmdb2i::doInitialRead(char orientation,
- uint32 rowsToBuffer,
- ILEMemHandle key,
- int keyLength,
- int keyParts)
-{
- DBUG_ENTER("ha_ibmdb2i::doInitialRead");
-
- if (forceSingleRowRead)
- rowsToBuffer = 1;
- else
- rowsToBuffer = min(rowsToBuffer, activeReadBuf->getRowCapacity());
-
- activeReadBuf->newReadRequest(activeHandle,
- orientation,
- rowsToBuffer,
- THDVAR(ha_thd(), async_enabled),
- key,
- keyLength,
- keyParts);
- DBUG_VOID_RETURN;
-}
-
-
-int ha_ibmdb2i::start_stmt(THD *thd, thr_lock_type lock_type)
-{
- DBUG_ENTER("ha_ibmdb2i::start_stmt");
- initBridge(thd);
- if (!THDVAR(thd, transaction_unsafe))
- {
- trans_register_ha(thd, FALSE, ibmdb2i_hton);
-
- if (!autoCommitIsOn(thd))
- {
- bridge()->beginStmtTx();
- }
- }
-
- DBUG_RETURN(0);
-}
-
-int32 ha_ibmdb2i::handleLOBReadOverflow()
-{
- DBUG_ENTER("ha_ibmdb2i::handleLOBReadOverflow");
- DBUG_ASSERT(db2Table->hasBlobs() && (activeReadBuf->getRowCapacity() == 1));
-
- int32 rc = adjustLobBuffersForRead();
-
- if (!rc)
- {
- activeReadBuf->rewind();
- rc = bridge()->expectErrors(QMY_ERR_END_OF_BLOCK)
- ->read(activeHandle,
- activeReadBuf->ptr(),
- accessIntent,
- getCommitLevel(),
- QMY_SAME);
- releaseRowNeeded = TRUE;
-
- }
- DBUG_RETURN(rc);
-}
-
-
-int32 ha_ibmdb2i::finishBulkInsert()
-{
- int32 rc = 0;
-
- if (activeWriteBuf->rowCount() && activeHandle)
- rc = flushWrite(activeHandle, table->record[0]);
-
- if (activeHandle)
- releaseActiveHandle();
-
- if (autoIncLockAcquired == TRUE)
- {
- // We could check the return code on the unlock, but beware not
- // to overlay the return code from the flushwrite or we will mask
- // duplicate key errors..
- bridge()->lockObj(dataHandle, 0, QMY_UNLOCK, QMY_LEAR, QMY_YES);
- autoIncLockAcquired = FALSE;
- }
- outstanding_start_bulk_insert = false;
- multiRowWriteBuf.freeBuf();
- last_start_bulk_insert_rc = 0;
-
- resetCharacterConversionBuffers();
-
- return rc;
-}
-
-int ha_ibmdb2i::getKeyFromName(const char* name, size_t len)
-{
- for (int i = 0; i < table_share->keys; ++i)
- {
- const char* indexName = db2Table->indexFile(i)->getDB2FileName();
- if ((strncmp(name, indexName, len) == 0) &&
- (strlen(indexName) == len))
- {
- return i;
- }
- }
- return MAX_KEY;
-}
-
-/*
-Determine the number of I/O's it takes to read through the table.
- */
-double ha_ibmdb2i::scan_time()
- {
- DBUG_ENTER("ha_ibmdb2i::scan_time");
- DBUG_RETURN(ulonglong2double((stats.data_file_length)/IO_SIZE));
- }
-
-
-/**
- Estimate the number of I/O's it takes to read a set of ranges through
- an index.
-
- @param index
- @param ranges
- @param rows
-
- @return The estimate number of I/Os
-*/
-
-double ha_ibmdb2i::read_time(uint index, uint ranges, ha_rows rows)
-{
- DBUG_ENTER("ha_ibmdb2i::read_time");
- int rc;
- uint64 idxPageCnt = 0;
- double cost;
-
- if (unlikely(rows == HA_POS_ERROR))
- DBUG_RETURN(double(rows) + ranges);
-
- rc = bridge()->retrieveIndexInfo(db2Table->indexFile(index)->getMasterDefnHandle(),
- &idxPageCnt);
- if (!rc)
- {
- if ((idxPageCnt == 1) || // Retrieving rows in requested order or
- (ranges == rows)) // 'Sweep' full records retrieval
- cost = idxPageCnt/4;
- else
- {
- uint64 totalRecords = stats.records + 1;
- double dataPageCount = stats.data_file_length/IO_SIZE;
-
- cost = (rows * dataPageCount / totalRecords) +
- min(idxPageCnt, (log_2(idxPageCnt) * ranges +
- rows * (log_2(idxPageCnt) + log_2(rows) - log_2(totalRecords))));
- }
- }
- else
- {
- cost = rows2double(ranges+rows); // Use default costing
- }
- DBUG_RETURN(cost);
-}
-
-int ha_ibmdb2i::useIndexFile(int idx)
-{
- DBUG_ENTER("ha_ibmdb2i::useIndexFile");
-
- if (activeHandle)
- releaseActiveHandle();
-
- int rc = 0;
-
- if (!indexHandles[idx])
- rc = db2Table->indexFile(idx)->allocateNewInstance(&indexHandles[idx], curConnection);
-
- if (rc == 0)
- {
- activeHandle = indexHandles[idx];
- bumpInUseCounter(1);
- }
-
- DBUG_RETURN(rc);
-}
-
-
-ulong ha_ibmdb2i::index_flags(uint inx, uint part, bool all_parts) const
-{
- return HA_READ_NEXT | HA_READ_PREV | HA_KEYREAD_ONLY | HA_READ_ORDER | HA_READ_RANGE;
-}
-
-
-static struct st_mysql_sys_var* ibmdb2i_system_variables[] = {
- MYSQL_SYSVAR(rdb_name),
- MYSQL_SYSVAR(transaction_unsafe),
- MYSQL_SYSVAR(lob_alloc_size),
- MYSQL_SYSVAR(max_read_buffer_size),
- MYSQL_SYSVAR(max_write_buffer_size),
- MYSQL_SYSVAR(async_enabled),
- MYSQL_SYSVAR(assume_exclusive_use),
- 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(discovery_mode),
- MYSQL_SYSVAR(system_trace_level),
- NULL
-};
-
-
-struct st_mysql_storage_engine ibmdb2i_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION };
-
-mysql_declare_plugin(ibmdb2i)
-{
- MYSQL_STORAGE_ENGINE_PLUGIN,
- &ibmdb2i_storage_engine,
- "IBMDB2I",
- "The IBM development team in Rochester, Minnesota",
- "IBM DB2 for i Storage Engine",
- PLUGIN_LICENSE_GPL,
- ibmdb2i_init_func, /* Plugin Init */
- ibmdb2i_done_func, /* Plugin Deinit */
- 0x0100 /* 1.0 */,
- NULL, /* status variables */
- ibmdb2i_system_variables, /* system variables */
- NULL /* config options */
-}
-mysql_declare_plugin_end;
diff --git a/storage/ibmdb2i/ha_ibmdb2i.h b/storage/ibmdb2i/ha_ibmdb2i.h
deleted file mode 100644
index b2a43232f2d..00000000000
--- a/storage/ibmdb2i/ha_ibmdb2i.h
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
-Licensed Materials - Property of IBM
-DB2 Storage Engine Enablement
-Copyright IBM Corporation 2007,2008
-All rights reserved
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- (a) Redistributions of source code must retain this list of conditions, the
- copyright notice in section {d} below, and the disclaimer following this
- list of conditions.
- (b) Redistributions in binary form must reproduce this list of conditions, the
- copyright notice in section (d) below, and the disclaimer following this
- list of conditions, in the documentation and/or other materials provided
- with the distribution.
- (c) The name of IBM may not be used to endorse or promote products derived from
- this software without specific prior written permission.
- (d) The text of the required copyright notice is:
- Licensed Materials - Property of IBM
- DB2 Storage Engine Enablement
- Copyright IBM Corporation 2007,2008
- All rights reserved
-
-THIS SOFTWARE IS PROVIDED BY IBM CORPORATION "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL IBM CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-/** @file ha_ibmdb2i.h
-
- @brief
-
- @note
-
- @see
-*/
-
-#ifdef USE_PRAGMA_INTERFACE
-#pragma interface /* gcc class implementation */
-#endif
-
-#include "as400_types.h"
-#include "as400_protos.h"
-#include "db2i_global.h"
-#include "db2i_ileBridge.h"
-#include "builtins.h"
-#include "db2i_misc.h"
-#include "db2i_file.h"
-#include "db2i_blobCollection.h"
-#include "db2i_collationSupport.h"
-#include "db2i_validatedPointer.h"
-#include "db2i_ioBuffers.h"
-#include "db2i_errors.h"
-#include "db2i_sqlStatementStream.h"
-
-/** @brief
- IBMDB2I_SHARE is a structure that will be shared among all open handlers.
- It is used to describe the underlying table definition, and it caches
- table statistics.
-*/
-struct IBMDB2I_SHARE {
- char *table_name;
- uint table_name_length,use_count;
- pthread_mutex_t mutex;
- THR_LOCK lock;
-
- db2i_table* db2Table;
-
- class CStats
- {
- public:
- void cacheUpdateTime(time_t time)
- {update_time = time; initFlag |= lastModTime;}
- time_t getUpdateTime() const
- {return update_time;}
- void cacheRowCount(ha_rows rows)
- {records = rows; initFlag |= rowCount;}
- ha_rows getRowCount() const
- {return records;}
- void cacheDelRowCount(ha_rows rows)
- {deleted = rows; initFlag |= deletedRowCount;}
- ha_rows getDelRowCount() const
- {return deleted;}
- void cacheMeanLength(ulong len)
- {mean_rec_length = len; initFlag |= meanRowLen;}
- ulong getMeanLength()
- {return mean_rec_length;}
- void cacheAugmentedDataLength(ulong len)
- {data_file_length = len; initFlag |= ioCount;}
- ulong getAugmentedDataLength()
- {return data_file_length;}
- bool isInited(uint flags)
- {return initFlag & flags;}
- void invalidate(uint flags)
- {initFlag &= ~flags;}
-
- private:
- uint initFlag;
- time_t update_time;
- ha_rows records;
- ha_rows deleted;
- ulong mean_rec_length;
- ulong data_file_length;
- } cachedStats;
-
-};
-
-class ha_ibmdb2i: public handler
-{
- THR_LOCK_DATA lock; ///< MySQL lock
- IBMDB2I_SHARE *share; ///< Shared lock info
-
- // The record we are positioned on, together with the handle used to get
- // i.
- uint32 currentRRN;
- uint32 rrnAssocHandle;
-
- // Dup key values needed by info()
- uint32 lastDupKeyRRN;
- uint32 lastDupKeyID;
-
- bool returnDupKeysImmediately;
-
- // Dup key value need by update()
- bool onDupUpdate;
-
-
- db2i_table* db2Table;
-
- // The file handle of the PF or LF being accessed by the current operation.
- FILE_HANDLE activeHandle;
-
- // The file handle of the underlying PF
- FILE_HANDLE dataHandle;
-
- // Array of file handles belonging to the underlying LFs
- FILE_HANDLE* indexHandles;
-
- // 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
- // 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.
- 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;
- uint32 keyLen;
-
- IOWriteBuffer multiRowWriteBuf;
- IOAsyncReadBuffer multiRowReadBuf;
-
- IOAsyncReadBuffer* activeReadBuf;
- IOWriteBuffer* activeWriteBuf;
-
- BlobCollection* blobReadBuffers; // Dynamically allocated per query and used
- // to manage the buffers used for reading LOBs
- ValidatedPointer<char>* blobWriteBuffers;
-
- // Return codes are not used/honored by rnd_init and start_bulk_insert
- // so we need a way to signal the failure "downstream" to subsequent
- // functions.
- int last_rnd_init_rc;
- int last_index_init_rc;
- int last_start_bulk_insert_rc;
-
- // end_bulk_insert may get called twice for a single start_bulk_insert
- // This is our way to do cleanup only once.
- bool outstanding_start_bulk_insert;
-
- // Auto_increment 'increment by' value needed by write_row()
- uint32 incrementByValue;
- bool default_identity_value;
-
- // Flags and values used during write operations for auto_increment processing
- bool autoIncLockAcquired;
- bool got_auto_inc_values;
- uint64 next_identity_value;
-
- // The access intent indicated by the last external_locks() call.
- // May be either QMY_READ or QMY_UPDATABLE
- char accessIntent;
- char readAccessIntent;
-
- ha_rows* indexReadSizeEstimates;
-
- MEM_ROOT conversionBufferMemroot;
-
- bool forceSingleRowRead;
-
- bool readAllColumns;
-
- bool invalidDataFound;
-
- db2i_ileBridge* cachedBridge;
-
- ValidatedObject<volatile uint32> curConnection;
- uint16 activeReferences;
-
-public:
-
- ha_ibmdb2i(handlerton *hton, TABLE_SHARE *table_arg);
- ~ha_ibmdb2i();
-
- const char *table_type() const { return "IBMDB2I"; }
- const char *index_type(uint inx) { return "RADIX"; }
- const key_map *keys_to_use_for_scanning() { return &key_map_full; }
- const char **bas_ext() const;
-
- ulonglong table_flags() const
- {
- return HA_NULL_IN_KEY | HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY |
- HA_PARTIAL_COLUMN_READ |
- HA_DUPLICATE_POS | HA_NO_PREFIX_CHAR_KEYS |
- HA_HAS_RECORDS | HA_BINLOG_ROW_CAPABLE | HA_REQUIRES_KEY_COLUMNS_FOR_DELETE |
- HA_CAN_INDEX_BLOBS;
- }
-
- ulong index_flags(uint inx, uint part, bool all_parts) const;
-
-// Note that we do not implement max_supported_record_length.
-// We'll let create fail accordingly if the row is
-// too long. This allows us to hide the fact that varchars > 32K are being
-// implemented as DB2 LOBs.
-
- uint max_supported_keys() const { return 4000; }
- uint max_supported_key_parts() const { return MAX_DB2_KEY_PARTS; }
- uint max_supported_key_length() const { return 32767; }
- uint max_supported_key_part_length() const { return 32767; }
- double read_time(uint index, uint ranges, ha_rows rows);
- double scan_time();
- int open(const char *name, int mode, uint test_if_locked);
- int close(void);
- int write_row(uchar * buf);
- int update_row(const uchar * old_data, uchar * new_data);
- int delete_row(const uchar * buf);
- int index_init(uint idx, bool sorted);
- int index_read(uchar * buf, const uchar * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_next(uchar * buf);
- int index_read_last(uchar * buf, const uchar * key, uint key_len);
- int index_next_same(uchar *buf, const uchar *key, uint keylen);
- int index_prev(uchar * buf);
- int index_first(uchar * buf);
- int index_last(uchar * buf);
- int rnd_init(bool scan);
- int rnd_end();
- int rnd_next(uchar *buf);
- int rnd_pos(uchar * buf, uchar *pos);
- void position(const uchar *record);
- int info(uint);
- ha_rows records();
- int extra(enum ha_extra_function operation);
- int external_lock(THD *thd, int lock_type);
- int delete_all_rows(void);
- ha_rows records_in_range(uint inx, key_range *min_key,
- key_range *max_key);
- int delete_table(const char *from);
- int rename_table(const char * from, const char * to);
- int create(const char *name, TABLE *form,
- HA_CREATE_INFO *create_info);
- int updateFrm(TABLE *table_def, File file);
- int openTableDef(TABLE *table_def);
- int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys);
- int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys);
- int final_drop_index(TABLE *table_arg) {return 0;}
- void get_auto_increment(ulonglong offset, ulonglong increment,
- ulonglong nb_desired_values,
- ulonglong *first_value,
- ulonglong *nb_reserved_values);
- int reset_auto_increment(ulonglong value);
- void restore_auto_increment(ulonglong prev_insert_id) {return;}
- void update_create_info(HA_CREATE_INFO *create_info);
- int getNextIdVal(ulonglong *value);
- int analyze(THD* thd,HA_CHECK_OPT* check_opt);
- int optimize(THD* thd, HA_CHECK_OPT* check_opt);
- bool can_switch_engines();
- void free_foreign_key_create_info(char* str);
- char* get_foreign_key_create_info();
- int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
- uint referenced_by_foreign_key();
- bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
- virtual bool get_error_message(int error, String *buf);
-
- THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
- enum thr_lock_type lock_type);
-
- bool low_byte_first() const { return 0; }
- void unlock_row();
- int index_end();
- int reset();
- static int doCommit(handlerton *hton, THD *thd, bool all);
- static int doRollback(handlerton *hton, THD *thd, bool all);
- void start_bulk_insert(ha_rows rows);
- int end_bulk_insert();
- int start_stmt(THD *thd, thr_lock_type lock_type);
-
- void initBridge(THD* thd = NULL)
- {
- if (thd == NULL) thd = ha_thd();
- DBUG_PRINT("ha_ibmdb2i::initBridge",("Initing bridge. Conn ID=%d", thd->thread_id));
- cachedBridge = db2i_ileBridge::getBridgeForThread(thd);
- }
-
- db2i_ileBridge* bridge() {DBUG_ASSERT(cachedBridge); return cachedBridge;}
-
- static uint8 autoCommitIsOn(THD* thd)
- { return (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ? QMY_NO : QMY_YES); }
-
- uint8 getCommitLevel();
- uint8 getCommitLevel(THD* thd);
-
- static int doSavepointSet(THD* thd, char* name)
- {
- return db2i_ileBridge::getBridgeForThread(thd)->savepoint(QMY_SET_SAVEPOINT,
- name);
- }
-
- static int doSavepointRollback(THD* thd, char* name)
- {
- return db2i_ileBridge::getBridgeForThread(thd)->savepoint(QMY_ROLLBACK_SAVEPOINT,
- name);
- }
-
- static int doSavepointRelease(THD* thd, char* name)
- {
- return db2i_ileBridge::getBridgeForThread(thd)->savepoint(QMY_RELEASE_SAVEPOINT,
- name);
- }
-
- // We can't guarantee that the rows we know about when this is called
- // will be the same number of rows that read returns (since DB2 activity
- // may insert additional rows). Therefore, we do as the Federated SE and
- // return the max possible.
- ha_rows estimate_rows_upper_bound()
- {
- return HA_POS_ERROR;
- }
-
-
-private:
-
- enum enum_TimeFormat
- {
- TIME_OF_DAY,
- DURATION
- };
-
- enum enum_BlobMapping
- {
- AS_BLOB,
- 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);
- int free_share(IBMDB2I_SHARE *share);
- int32 mungeDB2row(uchar* record, const char* dataPtr, const char* nullMapPtr, bool skipLOBs);
- int prepareRowForWrite(char* data, char* nulls, bool honorIdentCols);
- int prepareReadBufferForLobs();
- int32 prepareWriteBufferForLobs();
- uint32 adjustLobBuffersForRead();
- bool lobFieldsRequested();
- int convertFieldChars(enum_conversionDirection direction,
- uint16 fieldID,
- const char* input,
- char* output,
- size_t ilen,
- size_t olen,
- size_t* outDataLen,
- bool tacitErrors=FALSE,
- size_t* substChars=NULL);
-
- /**
- Fast integer log2 function
- */
- uint64 log_2(uint64 val)
- {
- uint64 exp = 0;
- while( (val >> exp) != 0)
- {
- exp++;
- }
- DBUG_ASSERT(exp-1 == (uint64)log2(val));
- return exp-1;
- }
-
- void bumpInUseCounter(uint16 amount)
- {
- activeReferences += amount;
- DBUG_PRINT("ha_ibmdb2i::bumpInUseCounter", ("activeReferences = %d", activeReferences));
- if (activeReferences)
- curConnection = (uint32)(ha_thd()->thread_id);
- else
- curConnection = 0;
- }
-
-
- int useDataFile()
- {
- DBUG_ENTER("ha_ibmdb2i::useDataFile");
-
- int rc = 0;
- if (!dataHandle)
- rc = db2Table->dataFile()->allocateNewInstance(&dataHandle, curConnection);
- else if (activeHandle == dataHandle)
- DBUG_RETURN(0);
-
- DBUG_ASSERT(activeHandle == 0);
-
- if (likely(rc == 0))
- {
- activeHandle = dataHandle;
- bumpInUseCounter(1);
- }
-
- DBUG_RETURN(rc);
- }
-
- void releaseAnyLockedRows()
- {
- if (releaseRowNeeded)
- {
- DBUG_PRINT("ha_ibmdb2i::releaseAnyLockedRows", ("Releasing rows"));
- db2i_ileBridge::getBridgeForThread()->rrlslck(activeHandle, accessIntent);
- releaseRowNeeded = FALSE;
- }
- }
-
-
- void releaseDataFile()
- {
- DBUG_ENTER("ha_ibmdb2i::releaseDataFile");
- releaseAnyLockedRows();
- bumpInUseCounter(-1);
- DBUG_ASSERT((volatile int)activeReferences >= 0);
- activeHandle = 0;
- DBUG_VOID_RETURN;
- }
-
- int useIndexFile(int idx);
-
- void releaseIndexFile(int idx)
- {
- DBUG_ENTER("ha_ibmdb2i::releaseIndexFile");
- releaseAnyLockedRows();
- bumpInUseCounter(-1);
- DBUG_ASSERT((volatile int)activeReferences >= 0);
- activeHandle = 0;
- DBUG_VOID_RETURN;
- }
-
- FILE_HANDLE allocateFileHandle(char* database, char* table, int* activityReference, bool hasBlobs);
-
- int updateBuffers(const db2i_file::RowFormat* format, uint rowsToRead, uint rowsToWrite);
-
- int flushWrite(FILE_HANDLE fileHandle, uchar* buf = NULL);
-
- int alterStartWith();
-
- int buildDB2ConstraintString(LEX* lex,
- String& appendHere,
- const char* database,
- Field** fields,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary);
-
- void releaseWriteBuffer();
-
- void setIndexReadEstimate(uint index, ha_rows rows)
- {
- if (!indexReadSizeEstimates)
- {
- indexReadSizeEstimates = (ha_rows*)my_malloc(sizeof(ha_rows) * table->s->keys, MYF(MY_WME | MY_ZEROFILL));
- }
- indexReadSizeEstimates[index] = rows;
- }
-
- ha_rows getIndexReadEstimate(uint index)
- {
- if (indexReadSizeEstimates)
- return max(indexReadSizeEstimates[index], 1);
-
- return 10000; // Assume index scan if no estimate exists.
- }
-
-
- void quiesceAllFileHandles()
- {
- db2i_ileBridge* bridge = db2i_ileBridge::getBridgeForThread();
- if (dataHandle)
- {
- bridge->quiesceFileInstance(dataHandle);
- }
-
- for (int idx = 0; idx < table_share->keys; ++idx)
- {
- if (indexHandles[idx] != 0)
- {
- bridge->quiesceFileInstance(indexHandles[idx]);
- }
- }
- }
-
- int32 buildCreateIndexStatement(SqlStatementStream& sqlStream,
- KEY& key,
- bool isPrimary,
- const char* db2LibName,
- const char* db2FileName);
-
- int32 buildIndexFieldList(String& appendHere,
- const KEY& key,
- bool isPrimary,
- char* fileSortSequenceType,
- char* fileSortSequence,
- char* fileSortSequenceLibrary);
-
- // Specify NULL for data when using the data pointed to by field
- int32 convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char* db2Buf, const uchar* data = NULL);
-
- int32 convertDB2toMySQL(const DB2Field& db2Field, Field* field, const char* buf);
- int getFieldTypeMapping(Field* field,
- String& mapping,
- enum_TimeFormat timeFormate,
- enum_BlobMapping blobMapping,
- enum_ZeroDate zeroDateHandling,
- bool propagateDefaults,
- enum_YearFormat yearFormat);
-
- int getKeyFromName(const char* name, size_t len);
-
- void releaseActiveHandle()
- {
- if (activeHandle == dataHandle)
- releaseDataFile();
- else
- releaseIndexFile(active_index);
- }
-
-
- int32 finishBulkInsert();
-
- void doInitialRead(char orientation,
- uint32 rowsToBuffer,
- ILEMemHandle key = 0,
- int keyLength = 0,
- int keyParts = 0);
-
-
- int32 readFromBuffer(uchar* destination, char orientation)
- {
- char* row;
- int32 rc = 0;
- row = activeReadBuf->readNextRow(orientation, currentRRN);
-
- if (unlikely(!row))
- {
- rc = activeReadBuf->lastrc();
- if (rc == QMY_ERR_LOB_SPACE_TOO_SMALL)
- {
- rc = handleLOBReadOverflow();
- if (rc == 0)
- {
- DBUG_ASSERT(activeReadBuf->rowCount() == 1);
- row = activeReadBuf->readNextRow(orientation, currentRRN);
-
- if (unlikely(!row))
- rc = activeReadBuf->lastrc();
- }
- }
- }
-
- if (likely(rc == 0))
- {
- rrnAssocHandle = activeHandle;
- rc = mungeDB2row(destination, row, row+activeReadBuf->getRowNullOffset(), false);
- }
- return rc;
- }
-
- int32 handleLOBReadOverflow();
-
- char* getCharacterConversionBuffer(int fieldId, int length)
- {
- if (unlikely(!alloc_root_inited(&conversionBufferMemroot)))
- init_alloc_root(&conversionBufferMemroot, 8192, 0);
-
- return (char*)alloc_root(&conversionBufferMemroot, length);;
- }
-
- void resetCharacterConversionBuffers()
- {
- if (alloc_root_inited(&conversionBufferMemroot))
- {
- free_root(&conversionBufferMemroot, MYF(MY_MARK_BLOCKS_FREE));
- }
- }
-
- void tweakReadSet()
- {
- THD* thd = ha_thd();
- int command = thd_sql_command(thd);
- if ((command == SQLCOM_UPDATE ||
- command == SQLCOM_UPDATE_MULTI) ||
- ((command == SQLCOM_DELETE ||
- command == SQLCOM_DELETE_MULTI) &&
- thd->options & OPTION_BIN_LOG))
- readAllColumns = TRUE;
- else
- readAllColumns = FALSE;
- }
-
- /**
-
- */
- int useFileByHandle(char intent,
- FILE_HANDLE handle)
- {
- DBUG_ENTER("ha_ibmdb2i::useFileByHandle");
-
- const db2i_file* file;
- if (handle == dataHandle)
- file = db2Table->dataFile();
- else
- {
- for (uint i = 0; i < table_share->keys; ++i)
- {
- if (indexHandles[i] == handle)
- {
- file = db2Table->indexFile(i);
- active_index = i;
- }
- }
- }
-
- int rc = file->obtainRowFormat(handle, intent, getCommitLevel(), &activeFormat);
- if (likely(rc == 0))
- {
- activeHandle = handle;
- bumpInUseCounter(1);
- }
-
- DBUG_RETURN(rc);
- }
-
- const db2i_file* getFileForActiveHandle() const
- {
- 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()
- {
- share->cachedStats.invalidate(rowCount | deletedRowCount | objLength |
- meanRowLen | ioCount);
- }
-
- void warnIfInvalidData()
- {
- if (unlikely(invalidDataFound))
- {
- warning(ha_thd(), DB2I_ERR_INVALID_DATA, table->alias);
- }
- }
-
- /**
- Calculate the maximum value that a particular field can hold.
-
- This is used to anticipate overflows in the auto_increment processing.
-
- @param field The Field to be analyzed
-
- @return The maximum value
- */
- static uint64 maxValueForField(const Field* field)
- {
- uint64 maxValue=0;
- switch (field->type())
- {
- case MYSQL_TYPE_TINY:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = (1 << 8) - 1;
- else
- maxValue = (1 << 7) - 1;
- break;
- case MYSQL_TYPE_SHORT:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = (1 << 16) - 1;
- else
- maxValue = (1 << 15) - 1;
- break;
- case MYSQL_TYPE_INT24:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = (1 << 24) - 1;
- else
- maxValue = (1 << 23) - 1;
- break;
- case MYSQL_TYPE_LONG:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = (1LL << 32) - 1;
- else
- maxValue = (1 << 31) - 1;
- break;
- case MYSQL_TYPE_LONGLONG:
- if (((const Field_num*)field)->unsigned_flag)
- maxValue = ~(0LL);
- else
- maxValue = 1 << 63 - 1;
- break;
- }
-
- return maxValue;
- }
-
- void cleanupBuffers()
- {
- if (blobReadBuffers)
- {
- delete blobReadBuffers;
- blobReadBuffers = NULL;
- }
- if (blobWriteBuffers)
- {
- delete[] blobWriteBuffers;
- blobWriteBuffers = NULL;
- }
- if (alloc_root_inited(&conversionBufferMemroot))
- {
- free_root(&conversionBufferMemroot, MYF(0));
- }
- }
-
-
-/**
- Generate a valid RCDFMT name based on the name of the table.
-
- The RCDFMT name is devised by munging the name of the table,
- uppercasing all ascii alpha-numeric characters and replacing all other
- characters with underscores until up to ten characters have been generated.
-
- @param tableName The name of the table, as given on the MySQL
- CREATE TABLE statement
- @param[out] query The string to receive the generated RCDFMT name
-*/
- static void generateAndAppendRCDFMT(const char* tableName, String& query)
- {
- char rcdfmt[11];
-
- // The RCDFMT name must begin with an alpha character.
- // We enforce this by skipping to the first alpha character in the table
- // name. If no alpha character exists, we use 'X' for the RCDFMT name;
-
- while (*tableName &&
- (!my_isascii(*tableName) ||
- !my_isalpha(system_charset_info, *tableName)))
- {
- tableName += my_mbcharlen(system_charset_info, *tableName);
- }
-
- if (unlikely(!(*tableName)))
- {
- rcdfmt[0]= 'X';
- rcdfmt[1]= 0;
- }
- else
- {
- int r= 0;
- while ((r < sizeof(rcdfmt)-1) && *tableName)
- {
- if (my_isascii(*tableName) &&
- my_isalnum(system_charset_info, *tableName))
- rcdfmt[r] = my_toupper(system_charset_info, *tableName);
- else
- rcdfmt[r] = '_';
-
- ++r;
- tableName += my_mbcharlen(system_charset_info, *tableName);
- }
- rcdfmt[r]= 0;
- }
- query.append(STRING_WITH_LEN(" RCDFMT "));
- query.append(rcdfmt);
- }
-
- int32 generateShadowIndex(SqlStatementStream& stream,
- const KEY& key,
- const char* libName,
- const char* fileName,
- const String& fieldDefinition);
-};
diff --git a/storage/ibmdb2i/plug.in b/storage/ibmdb2i/plug.in
deleted file mode 100644
index 0913d72aabf..00000000000
--- a/storage/ibmdb2i/plug.in
+++ /dev/null
@@ -1,12 +0,0 @@
-MYSQL_STORAGE_ENGINE([ibmdb2i], [], [IBM DB2 for i Storage Engine],
- [IBM DB2 for i Storage Engine], [max,max-no-ndb])
-MYSQL_PLUGIN_DYNAMIC([ibmdb2i], [ha_ibmdb2i.la])
-
-AC_CHECK_HEADER([qlgusr.h],
- # qlgusr.h is just one of the headers from the i5/OS PASE environment; the
- # EBCDIC headers are in /QIBM/include, and have to be converted to ASCII
- # before cpp gets to them
- [:],
- # Missing PASE environment, can't build this engine
- [mysql_plugin_ibmdb2i=no
- with_plugin_ibmdb2i=no])
diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c
index 5317da78ee4..e185514b9c1 100644
--- a/storage/myisam/ft_nlq_search.c
+++ b/storage/myisam/ft_nlq_search.c
@@ -63,7 +63,7 @@ static int FT_SUPERDOC_cmp(void* cmp_arg __attribute__((unused)),
static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
{
- int subkeys, r;
+ int UNINIT_VAR(subkeys), r;
uint keylen, doc_cnt;
FT_SUPERDOC sdoc, *sptr;
TREE_ELEMENT *selem;
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 0b4d781379c..42bd8e26a94 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -38,7 +38,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
MI_CREATE_INFO *ci,uint flags)
{
register uint i,j;
- File UNINIT_VAR(dfile),file;
+ File UNINIT_VAR(dfile), UNINIT_VAR(file);
int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
myf create_flag;
uint fields,length,max_key_length,packed,pointer,real_length_diff,
@@ -73,8 +73,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
{
DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION);
}
- LINT_INIT(dfile);
- LINT_INIT(file);
errpos=0;
options=0;
bzero((uchar*) &share,sizeof(share));
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index 18f8aa8d2c0..4bc3f7a4018 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -221,7 +221,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
int (*callback)(void*, const char*),
void *callback_param)
{
- MYRG_INFO *m_info;
+ MYRG_INFO *UNINIT_VAR(m_info);
int rc;
int errpos;
int save_errno;