Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
c15a866f
Commit
c15a866f
authored
Jun 10, 2004
by
pekka@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
merged ndb api blobs
parents
8742612a
699793ec
Changes
38
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
3549 additions
and
290 deletions
+3549
-290
ndb/include/kernel/ndb_limits.h
ndb/include/kernel/ndb_limits.h
+5
-0
ndb/include/kernel/signaldata/DictTabInfo.hpp
ndb/include/kernel/signaldata/DictTabInfo.hpp
+10
-1
ndb/include/ndbapi/Ndb.hpp
ndb/include/ndbapi/Ndb.hpp
+6
-0
ndb/include/ndbapi/NdbApi.hpp
ndb/include/ndbapi/NdbApi.hpp
+1
-0
ndb/include/ndbapi/NdbBlob.hpp
ndb/include/ndbapi/NdbBlob.hpp
+294
-0
ndb/include/ndbapi/NdbConnection.hpp
ndb/include/ndbapi/NdbConnection.hpp
+12
-2
ndb/include/ndbapi/NdbDictionary.hpp
ndb/include/ndbapi/NdbDictionary.hpp
+23
-7
ndb/include/ndbapi/NdbOperation.hpp
ndb/include/ndbapi/NdbOperation.hpp
+26
-1
ndb/include/ndbapi/NdbScanOperation.hpp
ndb/include/ndbapi/NdbScanOperation.hpp
+6
-0
ndb/include/util/NdbSqlUtil.hpp
ndb/include/util/NdbSqlUtil.hpp
+23
-1
ndb/src/common/util/NdbSqlUtil.cpp
ndb/src/common/util/NdbSqlUtil.cpp
+20
-0
ndb/src/kernel/blocks/dbdict/Dbdict.cpp
ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+1
-0
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+2
-2
ndb/src/ndbapi/Makefile_old
ndb/src/ndbapi/Makefile_old
+2
-1
ndb/src/ndbapi/NdbBlob.cpp
ndb/src/ndbapi/NdbBlob.cpp
+1334
-0
ndb/src/ndbapi/NdbConnection.cpp
ndb/src/ndbapi/NdbConnection.cpp
+130
-18
ndb/src/ndbapi/NdbDictionary.cpp
ndb/src/ndbapi/NdbDictionary.cpp
+3
-0
ndb/src/ndbapi/NdbDictionaryImpl.cpp
ndb/src/ndbapi/NdbDictionaryImpl.cpp
+81
-0
ndb/src/ndbapi/NdbDictionaryImpl.hpp
ndb/src/ndbapi/NdbDictionaryImpl.hpp
+13
-4
ndb/src/ndbapi/NdbIndexOperation.cpp
ndb/src/ndbapi/NdbIndexOperation.cpp
+11
-0
ndb/src/ndbapi/NdbOperation.cpp
ndb/src/ndbapi/NdbOperation.cpp
+33
-4
ndb/src/ndbapi/NdbOperationDefine.cpp
ndb/src/ndbapi/NdbOperationDefine.cpp
+28
-0
ndb/src/ndbapi/NdbOperationScan.cpp
ndb/src/ndbapi/NdbOperationScan.cpp
+29
-2
ndb/src/ndbapi/NdbOperationSearch.cpp
ndb/src/ndbapi/NdbOperationSearch.cpp
+32
-0
ndb/src/ndbapi/NdbScanOperation.cpp
ndb/src/ndbapi/NdbScanOperation.cpp
+22
-0
ndb/src/ndbapi/Ndberr.cpp
ndb/src/ndbapi/Ndberr.cpp
+16
-0
ndb/src/ndbapi/Ndbinit.cpp
ndb/src/ndbapi/Ndbinit.cpp
+3
-0
ndb/src/ndbapi/Ndblist.cpp
ndb/src/ndbapi/Ndblist.cpp
+30
-0
ndb/src/ndbapi/ndberror.c
ndb/src/ndbapi/ndberror.c
+8
-2
ndb/src/old_files/client/odbc/codegen/SimpleGram.ypp
ndb/src/old_files/client/odbc/codegen/SimpleGram.ypp
+23
-3
ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp
ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp
+2
-0
ndb/src/old_files/client/odbc/common/DataType.cpp
ndb/src/old_files/client/odbc/common/DataType.cpp
+6
-0
ndb/src/old_files/client/odbc/common/DataType.hpp
ndb/src/old_files/client/odbc/common/DataType.hpp
+1
-0
ndb/test/ndbapi/Makefile_old
ndb/test/ndbapi/Makefile_old
+2
-1
ndb/test/ndbapi/testBlobs.cpp
ndb/test/ndbapi/testBlobs.cpp
+0
-194
ndb/test/ndbapi/testBlobs/testBlobs.cpp
ndb/test/ndbapi/testBlobs/testBlobs.cpp
+1211
-0
ndb/test/src/NDBT_Table.cpp
ndb/test/src/NDBT_Table.cpp
+90
-45
ndb/tools/ndbsql.cpp
ndb/tools/ndbsql.cpp
+10
-2
No files found.
ndb/include/kernel/ndb_limits.h
View file @
c15a866f
...
...
@@ -91,4 +91,9 @@
#define MAX_TTREE_PREF_SIZE 4 // words in min/max prefix each
#define MAX_TTREE_NODE_SLACK 3 // diff between max and min occupancy
/*
* Blobs.
*/
#define NDB_BLOB_HEAD_SIZE 2 // sizeof(NdbBlob::Head) >> 2
#endif
ndb/include/kernel/signaldata/DictTabInfo.hpp
View file @
c15a866f
...
...
@@ -307,7 +307,9 @@ public:
ExtBinary
=
NdbSqlUtil
::
Type
::
Binary
,
ExtVarbinary
=
NdbSqlUtil
::
Type
::
Varbinary
,
ExtDatetime
=
NdbSqlUtil
::
Type
::
Datetime
,
ExtTimespec
=
NdbSqlUtil
::
Type
::
Timespec
ExtTimespec
=
NdbSqlUtil
::
Type
::
Timespec
,
ExtBlob
=
NdbSqlUtil
::
Type
::
Blob
,
ExtClob
=
NdbSqlUtil
::
Type
::
Clob
};
// Attribute data interpretation
...
...
@@ -430,6 +432,13 @@ public:
AttributeSize
=
DictTabInfo
::
an8Bit
;
AttributeArraySize
=
12
*
AttributeExtLength
;
return
true
;
case
DictTabInfo
:
:
ExtBlob
:
case
DictTabInfo
:
:
ExtClob
:
AttributeType
=
DictTabInfo
::
StringType
;
AttributeSize
=
DictTabInfo
::
an8Bit
;
// head + inline part [ attr precision ]
AttributeArraySize
=
(
NDB_BLOB_HEAD_SIZE
<<
2
)
+
AttributeExtPrecision
;
return
true
;
};
return
false
;
}
...
...
ndb/include/ndbapi/Ndb.hpp
View file @
c15a866f
...
...
@@ -879,6 +879,7 @@ class NdbScanReceiver;
class
Table
;
class
BaseString
;
class
NdbEventOperation
;
class
NdbBlob
;
typedef
void
(
*
NdbEventCallback
)(
NdbEventOperation
*
,
Ndb
*
,
void
*
);
...
...
@@ -964,6 +965,7 @@ class Ndb
friend
class
NdbIndexOperation
;
friend
class
NdbDictionaryImpl
;
friend
class
NdbDictInterface
;
friend
class
NdbBlob
;
public:
/**
...
...
@@ -1452,6 +1454,7 @@ private:
NdbIndexOperation
*
getIndexOperation
();
// Get an index operation from idle
class
NdbGlobalEventBufferHandle
*
getGlobalEventBufferHandle
();
NdbBlob
*
getNdbBlob
();
// Get a blob handle etc
void
releaseSignal
(
NdbApiSignal
*
anApiSignal
);
void
releaseSignalsInList
(
NdbApiSignal
**
pList
);
...
...
@@ -1463,6 +1466,7 @@ private:
void
releaseRecAttr
(
NdbRecAttr
*
aRecAttr
);
void
releaseOperation
(
NdbOperation
*
anOperation
);
void
releaseScanOperation
(
NdbScanOperation
*
aScanOperation
);
void
releaseNdbBlob
(
NdbBlob
*
aBlob
);
void
check_send_timeout
();
void
remove_sent_list
(
Uint32
);
...
...
@@ -1505,6 +1509,7 @@ private:
void
freeNdbSubroutine
();
// Free the first idle NdbSubroutine obj
void
freeNdbCall
();
// Free the first idle NdbCall obj
void
freeNdbScanRec
();
// Free the first idle NdbScanRec obj
void
freeNdbBlob
();
// Free the first etc
NdbConnection
*
getNdbCon
();
// Get a connection from idle list
...
...
@@ -1613,6 +1618,7 @@ private:
NdbSubroutine
*
theSubroutineList
;
// First subroutine descriptor in
NdbCall
*
theCallList
;
// First call descriptor in list
NdbScanReceiver
*
theScanList
;
NdbBlob
*
theNdbBlobIdleList
;
Uint32
theMyRef
;
// My block reference
Uint32
theNode
;
// The node number of our node
...
...
ndb/include/ndbapi/NdbApi.hpp
View file @
c15a866f
...
...
@@ -28,4 +28,5 @@
#include "NdbDictionary.hpp"
#include "NdbEventOperation.hpp"
#include "NdbPool.hpp"
#include "NdbBlob.hpp"
#endif
ndb/include/ndbapi/NdbBlob.hpp
0 → 100644
View file @
c15a866f
/* Copyright (C) 2003 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; either version 2 of the License, or
(at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef NdbBlob_H
#define NdbBlob_H
#include <ndb_types.h>
#include <AttrType.hpp>
#include <NdbDictionary.hpp>
#include <NdbConnection.hpp>
#include <NdbError.hpp>
class
Ndb
;
class
NdbConnection
;
class
NdbOperation
;
class
NdbRecAttr
;
class
NdbTableImpl
;
class
NdbColumnImpl
;
/**
* @class NdbBlob
* @brief Blob handle
*
* Blob data is stored in 2 places:
*
* - "header" and "inline bytes" stored in the blob attribute
* - "blob parts" stored in a separate table NDB$BLOB_<t>_<v>_<c>
*
* Inline and part sizes can be set via NdbDictionary::Column methods
* when the table is created.
*
* NdbBlob is a blob handle. To access blob data, the handle must be
* created using NdbOperation::getBlobHandle in operation prepare phase.
* The handle has following states:
*
* - prepared: before the operation is executed
* - active: after execute or next result but before transaction commit
* - closed: after transaction commit
* - invalid: after rollback or transaction close
*
* NdbBlob supports 2 styles of data access:
*
* - in prepare phase, NdbBlob methods getValue and setValue are used to
* prepare a read or write of a single blob value of known size
*
* - in active phase, NdbBlob methods readData and writeData are used to
* read or write blob data of undetermined size
*
* NdbBlob methods return -1 on error and 0 on success, and use output
* parameters when necessary.
*
* Notes:
* - table and its blob part tables are not created atomically
* - blob data operations take effect at next transaction execute
* - NdbBlob may need to do implicit executes on the transaction
* - read and write of complete parts is much more efficient
* - scan must use the "new" interface NdbScanOperation
* - scan with blobs applies hold-read-lock (at minimum)
* - to update a blob in a read op requires exclusive tuple lock
* - update op in scan must do its own getBlobHandle
* - delete creates implicit, not-accessible blob handles
* - NdbOperation::writeTuple does not support blobs
* - there is no support for an asynchronous interface
*
* Bugs / limitations:
* - scan must use exclusive locking for now
*
* Todo:
* - add scan method hold-read-lock-until-next + return-keyinfo
* - better check of keyinfo length when setting keys
* - better check of allowed blob op vs locking mode
*/
class
NdbBlob
{
public:
enum
State
{
Idle
=
0
,
Prepared
=
1
,
Active
=
2
,
Closed
=
3
,
Invalid
=
9
};
State
getState
();
/**
* Prepare to read blob value. The value is available after execute.
* Use isNull to check for NULL and getLength to get the real length
* and to check for truncation. Sets current read/write position to
* after the data read.
*/
int
getValue
(
void
*
data
,
Uint32
bytes
);
/**
* Prepare to insert or update blob value. An existing longer blob
* value will be truncated. The data buffer must remain valid until
* execute. Sets current read/write position to after the data. Set
* data to null pointer (0) to create a NULL value.
*/
int
setValue
(
const
void
*
data
,
Uint32
bytes
);
/**
* Check if blob is null.
*/
int
getNull
(
bool
&
isNull
);
/**
* Set blob to NULL.
*/
int
setNull
();
/**
* Get current length in bytes. Use isNull to distinguish between
* length 0 blob and NULL blob.
*/
int
getLength
(
Uint64
&
length
);
/**
* Truncate blob to given length. Has no effect if the length is
* larger than current length.
*/
int
truncate
(
Uint64
length
=
0
);
/**
* Get current read/write position.
*/
int
getPos
(
Uint64
&
pos
);
/**
* Set read/write position. Must be between 0 and current length.
* "Sparse blobs" are not supported.
*/
int
setPos
(
Uint64
pos
);
/**
* Read at current position and set new position to first byte after
* the data read. A read past blob end returns actual number of bytes
* read in the in/out bytes parameter.
*/
int
readData
(
void
*
data
,
Uint32
&
bytes
);
/**
* Read at given position. Does not use or update current position.
*/
int
readData
(
Uint64
pos
,
void
*
data
,
Uint32
&
bytes
);
/**
* Write at current position and set new position to first byte after
* the data written. A write past blob end extends the blob value.
*/
int
writeData
(
const
void
*
data
,
Uint32
bytes
);
/**
* Write at given position. Does not use or update current position.
*/
int
writeData
(
Uint64
pos
,
const
void
*
data
,
Uint32
bytes
);
/**
* Return the blob column.
*/
const
NdbDictionary
::
Column
*
getColumn
();
/**
* Get blob parts table name. Useful only to test programs.
*/
static
const
unsigned
BlobTableNameSize
=
40
;
static
int
getBlobTableName
(
char
*
btname
,
Ndb
*
anNdb
,
const
char
*
tableName
,
const
char
*
columnName
);
/**
* Return error object. The error may be blob specific (below) or may
* be copied from a failed implicit operation.
*/
const
NdbError
&
getNdbError
()
const
;
// "Invalid blob attributes or invalid blob parts table"
static
const
int
ErrTable
=
4263
;
// "Invalid usage of blob attribute"
static
const
int
ErrUsage
=
4264
;
// "Method is not valid in current blob state"
static
const
int
ErrState
=
4265
;
// "Invalid blob seek position"
static
const
int
ErrSeek
=
4266
;
// "Corrupted blob value"
static
const
int
ErrCorrupt
=
4267
;
// "Error in blob head update forced rollback of transaction"
static
const
int
ErrAbort
=
4268
;
// "Unknown blob error"
static
const
int
ErrUnknown
=
4269
;
private:
friend
class
Ndb
;
friend
class
NdbConnection
;
friend
class
NdbOperation
;
friend
class
NdbScanOperation
;
friend
class
NdbDictionaryImpl
;
// state
State
theState
;
void
setState
(
State
newState
);
// define blob table
static
void
getBlobTableName
(
char
*
btname
,
const
NdbTableImpl
*
t
,
const
NdbColumnImpl
*
c
);
static
void
getBlobTable
(
NdbTableImpl
&
bt
,
const
NdbTableImpl
*
t
,
const
NdbColumnImpl
*
c
);
// table name
char
theBlobTableName
[
BlobTableNameSize
];
// ndb api stuff
Ndb
*
theNdb
;
NdbConnection
*
theNdbCon
;
NdbOperation
*
theNdbOp
;
NdbTableImpl
*
theTable
;
NdbTableImpl
*
theAccessTable
;
const
NdbColumnImpl
*
theColumn
;
char
theFillChar
;
// sizes
Uint32
theInlineSize
;
Uint32
thePartSize
;
Uint32
theStripeSize
;
// getValue/setValue
bool
theGetFlag
;
char
*
theGetBuf
;
bool
theSetFlag
;
const
char
*
theSetBuf
;
Uint32
theGetSetBytes
;
// head
struct
Head
{
Uint64
length
;
};
// buffers
struct
Buf
{
char
*
data
;
unsigned
size
;
unsigned
maxsize
;
Buf
();
~
Buf
();
void
alloc
(
unsigned
n
);
};
Buf
theKeyBuf
;
Buf
theAccessKeyBuf
;
Buf
theHeadInlineBuf
;
Buf
thePartBuf
;
Head
*
theHead
;
char
*
theInlineData
;
NdbRecAttr
*
theHeadInlineRecAttr
;
bool
theHeadInlineUpdateFlag
;
bool
theNewPartFlag
;
// length and read/write position
int
theNullFlag
;
Uint64
theLength
;
Uint64
thePos
;
// errors
NdbError
theError
;
// for keeping in lists
NdbBlob
*
theNext
;
// initialization
NdbBlob
();
void
init
();
void
release
();
// classify operations
bool
isTableOp
();
bool
isIndexOp
();
bool
isKeyOp
();
bool
isReadOp
();
bool
isInsertOp
();
bool
isUpdateOp
();
bool
isDeleteOp
();
bool
isScanOp
();
// computations
Uint32
getPartNumber
(
Uint64
pos
);
Uint32
getPartCount
();
Uint32
getDistKey
(
Uint32
part
);
// getters and setters
int
getTableKeyValue
(
NdbOperation
*
anOp
);
int
setTableKeyValue
(
NdbOperation
*
anOp
);
int
setAccessKeyValue
(
NdbOperation
*
anOp
);
int
setPartKeyValue
(
NdbOperation
*
anOp
,
Uint32
part
);
int
getHeadInlineValue
(
NdbOperation
*
anOp
);
void
getHeadFromRecAttr
();
int
setHeadInlineValue
(
NdbOperation
*
anOp
);
// data operations
int
readDataPrivate
(
Uint64
pos
,
char
*
buf
,
Uint32
&
bytes
);
int
writeDataPrivate
(
Uint64
pos
,
const
char
*
buf
,
Uint32
bytes
);
int
readParts
(
char
*
buf
,
Uint32
part
,
Uint32
count
);
int
insertParts
(
const
char
*
buf
,
Uint32
part
,
Uint32
count
);
int
updateParts
(
const
char
*
buf
,
Uint32
part
,
Uint32
count
);
int
deleteParts
(
Uint32
part
,
Uint32
count
);
// blob handle maintenance
int
atPrepare
(
NdbConnection
*
aCon
,
NdbOperation
*
anOp
,
const
NdbColumnImpl
*
aColumn
);
int
preExecute
(
ExecType
anExecType
,
bool
&
batch
);
int
postExecute
(
ExecType
anExecType
);
int
preCommit
();
int
atNextResult
();
// errors
void
setErrorCode
(
int
anErrorCode
,
bool
invalidFlag
=
true
);
void
setErrorCode
(
NdbOperation
*
anOp
,
bool
invalidFlag
=
true
);
void
setErrorCode
(
NdbConnection
*
aCon
,
bool
invalidFlag
=
true
);
#ifdef VM_TRACE
friend
class
NdbOut
&
operator
<<
(
NdbOut
&
,
const
NdbBlob
&
);
#endif
};
#endif
ndb/include/ndbapi/NdbConnection.hpp
View file @
c15a866f
...
...
@@ -28,6 +28,7 @@ class NdbIndexOperation;
class
NdbApiSignal
;
class
Ndb
;
class
NdbScanReceiver
;
class
NdbBlob
;
/**
...
...
@@ -160,6 +161,7 @@ class NdbConnection
friend
class
NdbScanOperation
;
friend
class
NdbIndexOperation
;
friend
class
NdbScanReceiver
;
friend
class
NdbBlob
;
public:
...
...
@@ -536,6 +538,10 @@ private:
~
NdbConnection
();
void
init
();
// Initialize connection object for new transaction
int
executeNoBlobs
(
ExecType
execType
,
AbortOption
abortOption
=
AbortOnError
,
int
force
=
0
);
/**
* Set Connected node id
...
...
@@ -625,10 +631,12 @@ private:
void
setOperationErrorCodeAbort
(
int
anErrorCode
);
int
checkMagicNumber
();
// Verify correct object
NdbOperation
*
getNdbOperation
(
class
NdbTableImpl
*
aTable
);
NdbOperation
*
getNdbOperation
(
class
NdbTableImpl
*
aTable
,
NdbOperation
*
aNextOp
=
0
);
NdbScanOperation
*
getNdbScanOperation
(
class
NdbTableImpl
*
aTable
);
NdbIndexOperation
*
getNdbIndexOperation
(
class
NdbIndexImpl
*
anIndex
,
class
NdbTableImpl
*
aTable
);
class
NdbTableImpl
*
aTable
,
NdbOperation
*
aNextOp
=
0
);
void
handleExecuteCompletion
();
...
...
@@ -730,6 +738,8 @@ private:
// nextScanResult.
NdbOperation
*
theScanningOp
;
// The operation actually performing the scan
Uint32
theBuddyConPtr
;
// optim: any blobs
bool
theBlobFlag
;
static
void
sendTC_COMMIT_ACK
(
NdbApiSignal
*
,
Uint32
transId1
,
Uint32
transId2
,
...
...
ndb/include/ndbapi/NdbDictionary.hpp
View file @
c15a866f
...
...
@@ -182,7 +182,8 @@ public:
Varbinary
,
///< Max len
Datetime
,
///< Precision down to 1 sec (sizeof(Datetime) == 8 bytes )
Timespec
,
///< Precision down to 1 nsec(sizeof(Datetime) == 12 bytes )
Blob
///< Binary large object (see NdbBlob)
Blob
,
///< Binary large object (see NdbBlob)
Clob
///< Text blob
};
/**
...
...
@@ -297,11 +298,28 @@ public:
* Array length for column or max length for variable length arrays.
*/
int
getLength
()
const
;
/**
* For blob, set or get "inline size" i.e. number of initial bytes
* to store in table's blob attribute. This part is normally in
* main memory and can be indexed and interpreted.
*/
void
setInlineSize
(
int
size
)
{
setPrecision
(
size
);
}
int
getInlineSize
()
const
{
return
getPrecision
();
}
/**
* Get size of element
* For blob, set or get "part size" i.e. number of bytes to store in
* each tuple of the "blob table". Must be less than 64k.
*/
int
Column
::
getSize
()
const
;
void
setPartSize
(
int
size
)
{
setScale
(
size
);
}
int
getPartSize
()
const
{
return
getScale
();
}
/**
* For blob, set or get "stripe size" i.e. number of consecutive
* <em>parts</em> to store in each node group.
*/
void
setStripeSize
(
int
size
)
{
setLength
(
size
);
}
int
getStripeSize
()
const
{
return
getLength
();
}
/**
* Set distribution key
...
...
@@ -354,7 +372,6 @@ public:
#endif
private:
friend
class
NdbRecAttr
;
friend
class
NdbColumnImpl
;
class
NdbColumnImpl
&
m_impl
;
Column
(
NdbColumnImpl
&
);
...
...
@@ -1029,6 +1046,7 @@ public:
private:
friend
class
NdbDictionaryImpl
;
friend
class
UtilTransactions
;
friend
class
NdbBlob
;
class
NdbDictionaryImpl
&
m_impl
;
Dictionary
(
NdbDictionaryImpl
&
);
const
Table
*
getIndexTable
(
const
char
*
indexName
,
...
...
@@ -1036,6 +1054,4 @@ public:
};
};
class
NdbOut
&
operator
<<
(
class
NdbOut
&
ndbout
,
const
NdbDictionary
::
Column
::
Type
type
);
#endif
ndb/include/ndbapi/NdbOperation.hpp
View file @
c15a866f
...
...
@@ -28,6 +28,7 @@ class NdbRecAttr;
class
NdbOperation
;
class
NdbConnection
;
class
NdbColumnImpl
;
class
NdbBlob
;
/**
* @class NdbOperation
...
...
@@ -41,7 +42,8 @@ class NdbOperation
friend
class
NdbScanReceiver
;
friend
class
NdbScanFilter
;
friend
class
NdbScanFilterImpl
;
friend
class
NdbBlob
;
public:
/**
* @name Define Standard Operation Type
...
...
@@ -525,6 +527,17 @@ public:
virtual
int
setValue
(
Uint32
anAttrId
,
Int64
aValue
);
virtual
int
setValue
(
Uint32
anAttrId
,
float
aValue
);
virtual
int
setValue
(
Uint32
anAttrId
,
double
aValue
);
/**
* This method replaces getValue/setValue for blobs. It creates
* a blob handle NdbBlob. A second call with same argument returns
* the previously created handle. The handle is linked to the
* operation and is maintained automatically.
*
* See NdbBlob for details.
*/
virtual
NdbBlob
*
getBlobHandle
(
const
char
*
anAttrName
);
virtual
NdbBlob
*
getBlobHandle
(
Uint32
anAttrId
);
/** @} *********************************************************************/
/**
...
...
@@ -832,6 +845,11 @@ public:
*/
int
getNdbErrorLine
();
/**
* Get table name of this operation.
*/
const
char
*
getTableName
()
const
;
/** @} *********************************************************************/
/**
...
...
@@ -953,6 +971,7 @@ protected:
Uint32
len
);
NdbRecAttr
*
getValue
(
const
NdbColumnImpl
*
anAttrObject
,
char
*
aValue
=
0
);
int
setValue
(
const
NdbColumnImpl
*
anAttrObject
,
const
char
*
aValue
,
Uint32
len
);
NdbBlob
*
getBlobHandle
(
NdbConnection
*
aCon
,
const
NdbColumnImpl
*
anAttrObject
);
int
incValue
(
const
NdbColumnImpl
*
anAttrObject
,
Uint32
aValue
);
int
incValue
(
const
NdbColumnImpl
*
anAttrObject
,
Uint64
aValue
);
int
subValue
(
const
NdbColumnImpl
*
anAttrObject
,
Uint32
aValue
);
...
...
@@ -997,6 +1016,10 @@ protected:
NdbOperation
*
takeOverScanOp
(
OperationType
opType
,
NdbConnection
*
updateTrans
);
// get table or index key from prepared signals
int
getKeyFromTCREQ
(
Uint32
*
data
,
unsigned
size
);
int
getKeyFromKEYINFO20
(
Uint32
*
data
,
unsigned
size
);
/******************************************************************************
* These are the private variables that are defined in the operation objects.
*****************************************************************************/
...
...
@@ -1095,6 +1118,8 @@ protected:
// saveBoundATTRINFO() moves ATTRINFO here when setBound() is ready
NdbApiSignal
*
theBoundATTRINFO
;
Uint32
theTotalBoundAI_Len
;
// Blobs in this operation
NdbBlob
*
theBlobList
;
};
...
...
ndb/include/ndbapi/NdbScanOperation.hpp
View file @
c15a866f
...
...
@@ -33,6 +33,8 @@
#include <NdbOperation.hpp>
#include <NdbCursorOperation.hpp>
class
NdbBlob
;
/**
* @class NdbScanOperation
* @brief Class of scan operations for use in transactions.
...
...
@@ -82,6 +84,10 @@ public:
int
setValue
(
Uint32
anAttrId
,
float
aValue
);
int
setValue
(
Uint32
anAttrId
,
double
aValue
);
#endif
NdbBlob
*
getBlobHandle
(
const
char
*
anAttrName
);
NdbBlob
*
getBlobHandle
(
Uint32
anAttrId
);
private:
NdbScanOperation
(
Ndb
*
aNdb
);
...
...
ndb/include/util/NdbSqlUtil.hpp
View file @
c15a866f
...
...
@@ -19,6 +19,7 @@
#include <string.h>
#include <ndb_types.h>
#include <kernel/ndb_limits.h>
class
NdbSqlUtil
{
public:
...
...
@@ -77,7 +78,9 @@ public:
Binary
,
// Len
Varbinary
,
// Max len
Datetime
,
// Precision down to 1 sec (size 8 bytes)
Timespec
// Precision down to 1 nsec (size 12 bytes)
Timespec
,
// Precision down to 1 nsec (size 12 bytes)
Blob
,
// Blob
Clob
// Text blob
};
Enum
m_typeId
;
Cmp
*
m_cmp
;
// set to NULL if cmp not implemented
...
...
@@ -121,6 +124,8 @@ private:
static
Cmp
cmpVarbinary
;
static
Cmp
cmpDatetime
;
static
Cmp
cmpTimespec
;
static
Cmp
cmpBlob
;
static
Cmp
cmpClob
;
};
inline
int
...
...
@@ -350,6 +355,23 @@ NdbSqlUtil::cmp(Uint32 typeId, const Uint32* p1, const Uint32* p2, Uint32 full,
break
;
case
Type
:
:
Timespec
:
// XXX fix this
break
;
case
Type
:
:
Blob
:
// XXX fix
break
;
case
Type
:
:
Clob
:
{
// skip blob head, the rest is varchar
const
unsigned
skip
=
NDB_BLOB_HEAD_SIZE
;
if
(
size
>=
skip
+
1
)
{
union
{
const
Uint32
*
p
;
const
char
*
v
;
}
u1
,
u2
;
u1
.
p
=
p1
+
skip
;
u2
.
p
=
p2
+
skip
;
// length in first 2 bytes
int
k
=
strncmp
(
u1
.
v
+
2
,
u2
.
v
+
2
,
((
size
-
skip
)
<<
2
)
-
2
);
return
k
<
0
?
-
1
:
k
>
0
?
+
1
:
full
==
size
?
0
:
CmpUnknown
;
}
return
CmpUnknown
;
}
break
;
}
return
CmpError
;
}
...
...
ndb/src/common/util/NdbSqlUtil.cpp
View file @
c15a866f
...
...
@@ -155,6 +155,14 @@ NdbSqlUtil::m_typeList[] = {
{
Type
::
Timespec
,
NULL
// cmpTimespec
},
{
Type
::
Blob
,
NULL
// cmpDatetime
},
{
Type
::
Clob
,
cmpClob
}
};
...
...
@@ -284,6 +292,18 @@ NdbSqlUtil::cmpTimespec(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32
return
cmp
(
Type
::
Timespec
,
p1
,
p2
,
full
,
size
);
}
int
NdbSqlUtil
::
cmpBlob
(
const
Uint32
*
p1
,
const
Uint32
*
p2
,
Uint32
full
,
Uint32
size
)
{
return
cmp
(
Type
::
Blob
,
p1
,
p2
,
full
,
size
);
}
int
NdbSqlUtil
::
cmpClob
(
const
Uint32
*
p1
,
const
Uint32
*
p2
,
Uint32
full
,
Uint32
size
)
{
return
cmp
(
Type
::
Clob
,
p1
,
p2
,
full
,
size
);
}
#ifdef NDB_SQL_UTIL_TEST
#include <NdbTick.h>
...
...
ndb/src/kernel/blocks/dbdict/Dbdict.cpp
View file @
c15a866f
...
...
@@ -4739,6 +4739,7 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it,
/**
* Ignore incoming old-style type and recompute it.
*/
attrDesc
.
print
(
stdout
);
bool
translateOk
=
attrDesc
.
translateExtType
();
tabRequire
(
translateOk
,
CreateTableRef
::
Inconsistency
);
...
...
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
View file @
c15a866f
...
...
@@ -2736,8 +2736,8 @@ void Dbtc::execTCKEYREQ(Signal* signal)
case
ZUPDATE
:
jam
();
if
(
Tattrlength
==
0
)
{
TCKEY_abort
(
signal
,
5
);
return
;
//
TCKEY_abort(signal, 5);
//
return;
}
//if
/*---------------------------------------------------------------------*/
// The missing break is intentional since we also want to set the opLock
...
...
ndb/src/ndbapi/Makefile_old
View file @
c15a866f
...
...
@@ -58,7 +58,8 @@ SOURCES = \
NdbSchemaOp.cpp \
NdbUtil.cpp \
NdbReceiver.cpp \
NdbDictionary.cpp NdbDictionaryImpl.cpp DictCache.cpp
NdbDictionary.cpp NdbDictionaryImpl.cpp DictCache.cpp \
NdbBlob.cpp
include $(NDB_TOP)/Epilogue.mk
...
...
ndb/src/ndbapi/NdbBlob.cpp
0 → 100644
View file @
c15a866f
This diff is collapsed.
Click to expand it.
ndb/src/ndbapi/NdbConnection.cpp
View file @
c15a866f
...
...
@@ -35,6 +35,7 @@ Adjust: 971022 UABMNST First version.
#include "NdbApiSignal.hpp"
#include "TransporterFacade.hpp"
#include "API.hpp"
#include "NdbBlob.hpp"
#include <ndb_limits.h>
#include <signaldata/TcKeyConf.hpp>
...
...
@@ -89,7 +90,8 @@ NdbConnection::NdbConnection( Ndb* aNdb ) :
theCurrentScanRec
(
NULL
),
thePreviousScanRec
(
NULL
),
theScanningOp
(
NULL
),
theBuddyConPtr
(
0xFFFFFFFF
)
theBuddyConPtr
(
0xFFFFFFFF
),
theBlobFlag
(
false
)
{
theListState
=
NotInList
;
theError
.
code
=
0
;
...
...
@@ -152,6 +154,8 @@ NdbConnection::init()
m_theLastCursorOperation
=
NULL
;
m_firstExecutedCursorOp
=
0
;
theBuddyConPtr
=
0xFFFFFFFF
;
//
theBlobFlag
=
false
;
}
//NdbConnection::init()
/*****************************************************************************
...
...
@@ -250,6 +254,86 @@ int
NdbConnection
::
execute
(
ExecType
aTypeOfExec
,
AbortOption
abortOption
,
int
forceSend
)
{
if
(
!
theBlobFlag
)
return
executeNoBlobs
(
aTypeOfExec
,
abortOption
,
forceSend
);
// execute prepared ops in batches, as requested by blobs
ExecType
tExecType
;
NdbOperation
*
tPrepOp
;
do
{
tExecType
=
aTypeOfExec
;
tPrepOp
=
theFirstOpInList
;
while
(
tPrepOp
!=
NULL
)
{
bool
batch
=
false
;
NdbBlob
*
tBlob
=
tPrepOp
->
theBlobList
;
while
(
tBlob
!=
NULL
)
{
if
(
tBlob
->
preExecute
(
tExecType
,
batch
)
==
-
1
)
return
-
1
;
tBlob
=
tBlob
->
theNext
;
}
if
(
batch
)
{
// blob asked to execute all up to here now
tExecType
=
NoCommit
;
break
;
}
tPrepOp
=
tPrepOp
->
next
();
}
// save rest of prepared ops if batch
NdbOperation
*
tRestOp
;
NdbOperation
*
tLastOp
;
if
(
tPrepOp
!=
NULL
)
{
tRestOp
=
tPrepOp
->
next
();
tPrepOp
->
next
(
NULL
);
tLastOp
=
theLastOpInList
;
theLastOpInList
=
tPrepOp
;
}
if
(
tExecType
==
Commit
)
{
NdbOperation
*
tOp
=
theCompletedFirstOp
;
while
(
tOp
!=
NULL
)
{
NdbBlob
*
tBlob
=
tOp
->
theBlobList
;
while
(
tBlob
!=
NULL
)
{
if
(
tBlob
->
preCommit
()
==
-
1
)
return
-
1
;
tBlob
=
tBlob
->
theNext
;
}
tOp
=
tOp
->
next
();
}
}
if
(
executeNoBlobs
(
tExecType
,
abortOption
,
forceSend
)
==
-
1
)
return
-
1
;
{
NdbOperation
*
tOp
=
theCompletedFirstOp
;
while
(
tOp
!=
NULL
)
{
NdbBlob
*
tBlob
=
tOp
->
theBlobList
;
while
(
tBlob
!=
NULL
)
{
// may add new operations if batch
if
(
tBlob
->
postExecute
(
tExecType
)
==
-
1
)
return
-
1
;
tBlob
=
tBlob
->
theNext
;
}
tOp
=
tOp
->
next
();
}
}
// add saved prepared ops if batch
if
(
tPrepOp
!=
NULL
&&
tRestOp
!=
NULL
)
{
if
(
theFirstOpInList
==
NULL
)
theFirstOpInList
=
tRestOp
;
else
theLastOpInList
->
next
(
tRestOp
);
theLastOpInList
=
tLastOp
;
}
}
while
(
theFirstOpInList
!=
NULL
||
tExecType
!=
aTypeOfExec
);
return
0
;
}
int
NdbConnection
::
executeNoBlobs
(
ExecType
aTypeOfExec
,
AbortOption
abortOption
,
int
forceSend
)
{
//------------------------------------------------------------------------
// We will start by preparing all operations in the transaction defined
...
...
@@ -330,7 +414,6 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* Reset error.code on execute
*/
theError
.
code
=
0
;
NdbCursorOperation
*
tcOp
=
m_theFirstCursorOperation
;
if
(
tcOp
!=
0
){
// Execute any cursor operations
...
...
@@ -885,7 +968,7 @@ Remark: Get an operation from NdbOperation object idlelist and
object, synchronous.
*****************************************************************************/
NdbOperation
*
NdbConnection
::
getNdbOperation
(
NdbTableImpl
*
tab
)
NdbConnection
::
getNdbOperation
(
NdbTableImpl
*
tab
,
NdbOperation
*
aNextOp
)
{
NdbOperation
*
tOp
;
...
...
@@ -897,14 +980,28 @@ NdbConnection::getNdbOperation(NdbTableImpl * tab)
tOp
=
theNdb
->
getOperation
();
if
(
tOp
==
NULL
)
goto
getNdbOp_error1
;
if
(
theLastOpInList
!=
NULL
)
{
theLastOpInList
->
next
(
tOp
);
theLastOpInList
=
tOp
;
if
(
aNextOp
==
NULL
)
{
if
(
theLastOpInList
!=
NULL
)
{
theLastOpInList
->
next
(
tOp
);
theLastOpInList
=
tOp
;
}
else
{
theLastOpInList
=
tOp
;
theFirstOpInList
=
tOp
;
}
//if
tOp
->
next
(
NULL
);
}
else
{
theLastOpInList
=
tOp
;
theFirstOpInList
=
tOp
;
}
//if
tOp
->
next
(
NULL
);
// add before the given op
if
(
theFirstOpInList
==
aNextOp
)
{
theFirstOpInList
=
tOp
;
}
else
{
NdbOperation
*
aLoopOp
=
theFirstOpInList
;
while
(
aLoopOp
!=
NULL
&&
aLoopOp
->
next
()
!=
aNextOp
)
aLoopOp
=
aLoopOp
->
next
();
assert
(
aLoopOp
!=
NULL
);
aLoopOp
->
next
(
tOp
);
}
tOp
->
next
(
aNextOp
);
}
if
(
tOp
->
init
(
tab
,
this
)
!=
-
1
)
{
return
tOp
;
}
else
{
...
...
@@ -1068,21 +1165,36 @@ Remark: Get an operation from NdbIndexOperation object idlelist and get
*****************************************************************************/
NdbIndexOperation
*
NdbConnection
::
getNdbIndexOperation
(
NdbIndexImpl
*
anIndex
,
NdbTableImpl
*
aTable
)
NdbTableImpl
*
aTable
,
NdbOperation
*
aNextOp
)
{
NdbIndexOperation
*
tOp
;
tOp
=
theNdb
->
getIndexOperation
();
if
(
tOp
==
NULL
)
goto
getNdbOp_error1
;
if
(
theLastOpInList
!=
NULL
)
{
theLastOpInList
->
next
(
tOp
);
theLastOpInList
=
tOp
;
if
(
aNextOp
==
NULL
)
{
if
(
theLastOpInList
!=
NULL
)
{
theLastOpInList
->
next
(
tOp
);
theLastOpInList
=
tOp
;
}
else
{
theLastOpInList
=
tOp
;
theFirstOpInList
=
tOp
;
}
//if
tOp
->
next
(
NULL
);
}
else
{
theLastOpInList
=
tOp
;
theFirstOpInList
=
tOp
;
}
//if
tOp
->
next
(
NULL
);
// add before the given op
if
(
theFirstOpInList
==
aNextOp
)
{
theFirstOpInList
=
tOp
;
}
else
{
NdbOperation
*
aLoopOp
=
theFirstOpInList
;
while
(
aLoopOp
!=
NULL
&&
aLoopOp
->
next
()
!=
aNextOp
)
aLoopOp
=
aLoopOp
->
next
();
assert
(
aLoopOp
!=
NULL
);
aLoopOp
->
next
(
tOp
);
}
tOp
->
next
(
aNextOp
);
}
if
(
tOp
->
indxInit
(
anIndex
,
aTable
,
this
)
!=
-
1
)
{
return
tOp
;
}
else
{
...
...
ndb/src/ndbapi/NdbDictionary.cpp
View file @
c15a866f
...
...
@@ -273,6 +273,9 @@ NdbDictionary::Table::addColumn(const Column & c){
if
(
c
.
getPrimaryKey
()){
m_impl
.
m_noOfKeys
++
;
}
if
(
col
->
getBlobType
())
{
m_impl
.
m_noOfBlobs
++
;
}
m_impl
.
buildColumnHash
();
}
...
...
ndb/src/ndbapi/NdbDictionaryImpl.cpp
View file @
c15a866f
...
...
@@ -34,6 +34,7 @@
#include <AttributeList.hpp>
#include <NdbEventOperation.hpp>
#include "NdbEventOperationImpl.hpp"
#include "NdbBlob.hpp"
#define DEBUG_PRINT 0
#define INCOMPATIBLE_VERSION -2
...
...
@@ -178,7 +179,14 @@ NdbColumnImpl::equal(const NdbColumnImpl& col) const
case
NdbDictionary
:
:
Column
::
Double
:
case
NdbDictionary
:
:
Column
::
Datetime
:
case
NdbDictionary
:
:
Column
::
Timespec
:
break
;
case
NdbDictionary
:
:
Column
::
Blob
:
case
NdbDictionary
:
:
Column
::
Clob
:
if
(
m_precision
!=
col
.
m_precision
||
m_scale
!=
col
.
m_scale
||
m_length
!=
col
.
m_length
)
{
return
false
;
}
break
;
}
if
(
m_autoIncrement
!=
col
.
m_autoIncrement
){
...
...
@@ -223,6 +231,8 @@ NdbTableImpl::NdbTableImpl()
:
NdbDictionary
::
Table
(
*
this
),
m_facade
(
this
)
{
m_noOfKeys
=
0
;
m_sizeOfKeysInWords
=
0
;
m_noOfBlobs
=
0
;
m_index
=
0
;
init
();
}
...
...
@@ -257,6 +267,8 @@ NdbTableImpl::init(){
m_indexType
=
NdbDictionary
::
Index
::
Undefined
;
m_noOfKeys
=
0
;
m_sizeOfKeysInWords
=
0
;
m_noOfBlobs
=
0
;
}
bool
...
...
@@ -336,6 +348,8 @@ NdbTableImpl::assign(const NdbTableImpl& org)
m_index
=
org
.
m_index
;
m_noOfKeys
=
org
.
m_noOfKeys
;
m_sizeOfKeysInWords
=
org
.
m_sizeOfKeysInWords
;
m_noOfBlobs
=
org
.
m_noOfBlobs
;
m_version
=
org
.
m_version
;
m_status
=
org
.
m_status
;
...
...
@@ -1076,6 +1090,8 @@ columnTypeMapping[] = {
{
DictTabInfo
::
ExtVarbinary
,
NdbDictionary
::
Column
::
Varbinary
},
{
DictTabInfo
::
ExtDatetime
,
NdbDictionary
::
Column
::
Datetime
},
{
DictTabInfo
::
ExtTimespec
,
NdbDictionary
::
Column
::
Timespec
},
{
DictTabInfo
::
ExtBlob
,
NdbDictionary
::
Column
::
Blob
},
{
DictTabInfo
::
ExtClob
,
NdbDictionary
::
Column
::
Clob
},
{
-
1
,
-
1
}
};
...
...
@@ -1131,6 +1147,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
Uint32
keyInfoPos
=
0
;
Uint32
keyCount
=
0
;
Uint32
blobCount
;
for
(
Uint32
i
=
0
;
i
<
tableDesc
.
NoOfAttributes
;
i
++
)
{
DictTabInfo
::
Attribute
attrDesc
;
attrDesc
.
init
();
...
...
@@ -1187,6 +1204,8 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
}
else
{
col
->
m_keyInfoPos
=
0
;
}
if
(
col
->
getBlobType
())
blobCount
++
;
NdbColumnImpl
*
null
=
0
;
impl
->
m_columns
.
fill
(
attrDesc
.
AttributeId
,
null
);
...
...
@@ -1199,6 +1218,8 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
it
.
next
();
}
impl
->
m_noOfKeys
=
keyCount
;
impl
->
m_sizeOfKeysInWords
=
keyInfoPos
;
impl
->
m_noOfBlobs
=
blobCount
;
*
ret
=
impl
;
return
0
;
}
...
...
@@ -1206,6 +1227,43 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
/*****************************************************************
* Create table and alter table
*/
int
NdbDictionaryImpl
::
createTable
(
NdbTableImpl
&
t
)
{
if
(
m_receiver
.
createTable
(
m_ndb
,
t
)
!=
0
)
return
-
1
;
if
(
t
.
m_noOfBlobs
==
0
)
return
0
;
// update table def from DICT
NdbTableImpl
*
tp
=
getTable
(
t
.
m_externalName
.
c_str
());
if
(
tp
==
NULL
)
{
m_error
.
code
=
709
;
return
-
1
;
}
if
(
createBlobTables
(
*
tp
)
!=
0
)
{
int
save_code
=
m_error
.
code
;
(
void
)
dropTable
(
t
);
m_error
.
code
=
save_code
;
return
-
1
;
}
return
0
;
}
int
NdbDictionaryImpl
::
createBlobTables
(
NdbTableImpl
&
t
)
{
for
(
unsigned
i
=
0
;
i
<
t
.
m_columns
.
size
();
i
++
)
{
NdbColumnImpl
&
c
=
*
t
.
m_columns
[
i
];
if
(
!
c
.
getBlobType
())
continue
;
NdbTableImpl
bt
;
NdbBlob
::
getBlobTable
(
bt
,
&
t
,
&
c
);
if
(
createTable
(
bt
)
!=
0
)
return
-
1
;
}
return
0
;
}
int
NdbDictInterface
::
createTable
(
Ndb
&
ndb
,
NdbTableImpl
&
impl
)
...
...
@@ -1540,6 +1598,12 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
if
(
dropIndex
(
element
.
name
,
name
)
==
-
1
)
return
-
1
;
}
if
(
impl
.
m_noOfBlobs
!=
0
)
{
if
(
dropBlobTables
(
impl
)
!=
0
)
return
-
1
;
}
int
ret
=
m_receiver
.
dropTable
(
impl
);
if
(
ret
==
0
){
const
char
*
internalTableName
=
impl
.
m_internalName
.
c_str
();
...
...
@@ -1554,6 +1618,23 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
return
ret
;
}
int
NdbDictionaryImpl
::
dropBlobTables
(
NdbTableImpl
&
t
)
{
for
(
unsigned
i
=
0
;
i
<
t
.
m_columns
.
size
();
i
++
)
{
NdbColumnImpl
&
c
=
*
t
.
m_columns
[
i
];
if
(
!
c
.
getBlobType
())
continue
;
char
btname
[
NdbBlob
::
BlobTableNameSize
];
NdbBlob
::
getBlobTableName
(
btname
,
&
t
,
&
c
);
if
(
dropTable
(
btname
)
!=
0
)
{
if
(
m_error
.
code
!=
709
)
return
-
1
;
}
}
return
0
;
}
int
NdbDictInterface
::
dropTable
(
const
NdbTableImpl
&
impl
)
{
...
...
ndb/src/ndbapi/NdbDictionaryImpl.hpp
View file @
c15a866f
...
...
@@ -81,6 +81,7 @@ public:
Uint32
m_keyInfoPos
;
Uint32
m_extType
;
// used by restore (kernel type in versin v2x)
bool
getInterpretableType
()
const
;
bool
getBlobType
()
const
;
/**
* Equality/assign
...
...
@@ -141,6 +142,8 @@ public:
* Aggregates
*/
Uint32
m_noOfKeys
;
unsigned
short
m_sizeOfKeysInWords
;
unsigned
short
m_noOfBlobs
;
/**
* Equality/assign
...
...
@@ -353,13 +356,12 @@ public:
bool
setTransporter
(
class
Ndb
*
ndb
,
class
TransporterFacade
*
tf
);
bool
setTransporter
(
class
TransporterFacade
*
tf
);
int
createTable
(
NdbTableImpl
&
t
)
{
return
m_receiver
.
createTable
(
m_ndb
,
t
);
}
int
createTable
(
NdbTableImpl
&
t
);
int
createBlobTables
(
NdbTableImpl
&
);
int
alterTable
(
NdbTableImpl
&
t
);
int
dropTable
(
const
char
*
name
);
int
dropTable
(
NdbTableImpl
&
);
int
dropBlobTables
(
NdbTableImpl
&
);
int
invalidateObject
(
NdbTableImpl
&
);
int
removeCachedObject
(
NdbTableImpl
&
);
...
...
@@ -432,6 +434,13 @@ NdbColumnImpl::getInterpretableType() const {
m_type
==
NdbDictionary
::
Column
::
Bigunsigned
);
}
inline
bool
NdbColumnImpl
::
getBlobType
()
const
{
return
(
m_type
==
NdbDictionary
::
Column
::
Blob
||
m_type
==
NdbDictionary
::
Column
::
Clob
);
}
inline
NdbTableImpl
&
NdbTableImpl
::
getImpl
(
NdbDictionary
::
Table
&
t
){
...
...
ndb/src/ndbapi/NdbIndexOperation.cpp
View file @
c15a866f
...
...
@@ -372,6 +372,17 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
}
else
if
((
tOpType
==
ReadRequest
)
||
(
tOpType
==
DeleteRequest
)
||
(
tOpType
==
ReadExclusive
))
{
theStatus
=
GetValue
;
// create blob handles automatically
if
(
tOpType
==
DeleteRequest
&&
m_currentTable
->
m_noOfBlobs
!=
0
)
{
for
(
unsigned
i
=
0
;
i
<
m_currentTable
->
m_columns
.
size
();
i
++
)
{
NdbColumnImpl
*
c
=
m_currentTable
->
m_columns
[
i
];
assert
(
c
!=
0
);
if
(
c
->
getBlobType
())
{
if
(
getBlobHandle
(
theNdbCon
,
c
)
==
NULL
)
return
-
1
;
}
}
}
return
0
;
}
else
if
((
tOpType
==
InsertRequest
)
||
(
tOpType
==
WriteRequest
))
{
theStatus
=
SetValue
;
...
...
ndb/src/ndbapi/NdbOperation.cpp
View file @
c15a866f
...
...
@@ -31,7 +31,8 @@
#include "NdbApiSignal.hpp"
#include "NdbRecAttr.hpp"
#include "NdbUtil.hpp"
#include "ndbapi_limits.h"
#include "NdbBlob.hpp"
#include <signaldata/TcKeyReq.hpp>
#include "NdbDictionaryImpl.hpp"
...
...
@@ -103,7 +104,8 @@ NdbOperation::NdbOperation(Ndb* aNdb) :
theFirstSCAN_TABINFO_Recv
(
NULL
),
theLastSCAN_TABINFO_Recv
(
NULL
),
theSCAN_TABCONF_Recv
(
NULL
),
theBoundATTRINFO
(
NULL
)
theBoundATTRINFO
(
NULL
),
theBlobList
(
NULL
)
{
theReceiver
.
init
(
NdbReceiver
::
NDB_OPERATION
,
this
);
theError
.
code
=
0
;
...
...
@@ -163,7 +165,7 @@ NdbOperation::init(NdbTableImpl* tab, NdbConnection* myConnection){
m_currentTable
=
m_accessTable
=
tab
;
theNdbCon
=
myConnection
;
for
(
Uint32
i
=
0
;
i
<
NDB_MAX_NO_OF_ATTRIBUTES_IN_
KEY
;
i
++
)
for
(
Uint32
i
=
0
;
i
<
MAXNROFTUPLE
KEY
;
i
++
)
for
(
int
j
=
0
;
j
<
3
;
j
++
)
theTupleKeyDefined
[
i
][
j
]
=
false
;
...
...
@@ -197,6 +199,7 @@ NdbOperation::init(NdbTableImpl* tab, NdbConnection* myConnection){
theTotalNrOfKeyWordInSignal
=
8
;
theMagicNumber
=
0xABCDEF01
;
theBoundATTRINFO
=
NULL
;
theBlobList
=
NULL
;
tSignal
=
theNdb
->
getSignal
();
if
(
tSignal
==
NULL
)
...
...
@@ -236,6 +239,8 @@ NdbOperation::release()
NdbCall
*
tSaveCall
;
NdbSubroutine
*
tSubroutine
;
NdbSubroutine
*
tSaveSubroutine
;
NdbBlob
*
tBlob
;
NdbBlob
*
tSaveBlob
;
if
(
theTCREQ
!=
NULL
)
{
...
...
@@ -308,6 +313,14 @@ NdbOperation::release()
}
theBoundATTRINFO
=
NULL
;
}
tBlob
=
theBlobList
;
while
(
tBlob
!=
NULL
)
{
tSaveBlob
=
tBlob
;
tBlob
=
tBlob
->
theNext
;
theNdb
->
releaseNdbBlob
(
tSaveBlob
);
}
theBlobList
=
NULL
;
releaseScan
();
}
...
...
@@ -356,6 +369,18 @@ NdbOperation::setValue( Uint32 anAttrId,
return
setValue
(
m_currentTable
->
getColumn
(
anAttrId
),
aValuePassed
,
len
);
}
NdbBlob
*
NdbOperation
::
getBlobHandle
(
const
char
*
anAttrName
)
{
return
getBlobHandle
(
theNdbCon
,
m_currentTable
->
getColumn
(
anAttrName
));
}
NdbBlob
*
NdbOperation
::
getBlobHandle
(
Uint32
anAttrId
)
{
return
getBlobHandle
(
theNdbCon
,
m_currentTable
->
getColumn
(
anAttrId
));
}
int
NdbOperation
::
incValue
(
const
char
*
anAttrName
,
Uint32
aValue
)
{
...
...
@@ -428,4 +453,8 @@ NdbOperation::setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len
return
setBound
(
m_accessTable
->
getColumn
(
anAttrId
),
type
,
aValue
,
len
);
}
const
char
*
NdbOperation
::
getTableName
()
const
{
return
m_currentTable
->
m_externalName
.
c_str
();
}
ndb/src/ndbapi/NdbOperationDefine.cpp
View file @
c15a866f
...
...
@@ -34,6 +34,7 @@
#include "NdbUtil.hpp"
#include "NdbOut.hpp"
#include "NdbImpl.hpp"
#include "NdbBlob.hpp"
#include <Interpreter.hpp>
...
...
@@ -604,6 +605,33 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo,
return
0
;
}
//NdbOperation::setValue()
NdbBlob
*
NdbOperation
::
getBlobHandle
(
NdbConnection
*
aCon
,
const
NdbColumnImpl
*
tAttrInfo
)
{
NdbBlob
*
tBlob
=
theBlobList
;
NdbBlob
*
tLastBlob
=
NULL
;
while
(
tBlob
!=
NULL
)
{
if
(
tBlob
->
theColumn
==
tAttrInfo
)
return
tBlob
;
tLastBlob
=
tBlob
;
tBlob
=
tBlob
->
theNext
;
}
tBlob
=
theNdb
->
getNdbBlob
();
if
(
tBlob
==
NULL
)
return
NULL
;
if
(
tBlob
->
atPrepare
(
aCon
,
this
,
tAttrInfo
)
==
-
1
)
{
theNdb
->
releaseNdbBlob
(
tBlob
);
return
NULL
;
}
if
(
tLastBlob
==
NULL
)
theBlobList
=
tBlob
;
else
tLastBlob
->
theNext
=
tBlob
;
tBlob
->
theNext
=
NULL
;
theNdbCon
->
theBlobFlag
=
true
;
return
tBlob
;
}
/*
* Define bound on index column in range scan.
*/
...
...
ndb/src/ndbapi/NdbOperationScan.cpp
View file @
c15a866f
...
...
@@ -569,8 +569,35 @@ NdbOperation::takeOverScanOp(OperationType opType, NdbConnection* updateTrans)
}
}
// create blob handles automatically
if
(
opType
==
DeleteRequest
&&
m_currentTable
->
m_noOfBlobs
!=
0
)
{
for
(
unsigned
i
=
0
;
i
<
m_currentTable
->
m_columns
.
size
();
i
++
)
{
NdbColumnImpl
*
c
=
m_currentTable
->
m_columns
[
i
];
assert
(
c
!=
0
);
if
(
c
->
getBlobType
())
{
if
(
newOp
->
getBlobHandle
(
updateTrans
,
c
)
==
NULL
)
return
NULL
;
}
}
}
return
newOp
;
}
int
NdbOperation
::
getKeyFromKEYINFO20
(
Uint32
*
data
,
unsigned
size
)
{
const
NdbScanReceiver
*
tScanRec
=
theNdbCon
->
thePreviousScanRec
;
NdbApiSignal
*
tSignal
=
tScanRec
->
theFirstKEYINFO20_Recv
;
unsigned
pos
=
0
;
unsigned
n
=
0
;
while
(
pos
<
size
)
{
if
(
n
==
20
)
{
tSignal
=
tSignal
->
next
();
n
=
0
;
}
const
unsigned
h
=
KeyInfo20
::
HeaderLength
;
data
[
pos
++
]
=
tSignal
->
getDataPtrSend
()[
h
+
n
++
];
}
return
0
;
}
ndb/src/ndbapi/NdbOperationSearch.cpp
View file @
c15a866f
...
...
@@ -251,6 +251,17 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
}
else
if
((
tOpType
==
ReadRequest
)
||
(
tOpType
==
DeleteRequest
)
||
(
tOpType
==
ReadExclusive
))
{
theStatus
=
GetValue
;
// create blob handles automatically
if
(
tOpType
==
DeleteRequest
&&
m_currentTable
->
m_noOfBlobs
!=
0
)
{
for
(
unsigned
i
=
0
;
i
<
m_currentTable
->
m_columns
.
size
();
i
++
)
{
NdbColumnImpl
*
c
=
m_currentTable
->
m_columns
[
i
];
assert
(
c
!=
0
);
if
(
c
->
getBlobType
())
{
if
(
getBlobHandle
(
theNdbCon
,
c
)
==
NULL
)
return
-
1
;
}
}
}
return
0
;
}
else
if
((
tOpType
==
InsertRequest
)
||
(
tOpType
==
WriteRequest
))
{
theStatus
=
SetValue
;
...
...
@@ -497,3 +508,24 @@ NdbOperation::insertKEYINFO(const char* aValue,
return
0
;
}
int
NdbOperation
::
getKeyFromTCREQ
(
Uint32
*
data
,
unsigned
size
)
{
assert
(
m_accessTable
!=
0
&&
m_accessTable
->
m_sizeOfKeysInWords
!=
0
);
assert
(
m_accessTable
->
m_sizeOfKeysInWords
==
size
);
unsigned
pos
=
0
;
while
(
pos
<
8
&&
pos
<
size
)
{
data
[
pos
++
]
=
theKEYINFOptr
[
pos
];
}
NdbApiSignal
*
tSignal
=
theFirstKEYINFO
;
unsigned
n
=
0
;
while
(
pos
<
size
)
{
if
(
n
==
20
)
{
tSignal
=
tSignal
->
next
();
n
=
0
;
}
data
[
pos
++
]
=
tSignal
->
getDataPtrSend
()[
3
+
n
++
];
}
return
0
;
}
ndb/src/ndbapi/NdbScanOperation.cpp
View file @
c15a866f
...
...
@@ -34,6 +34,7 @@
#include "NdbApiSignal.hpp"
#include <NdbOut.hpp>
#include "NdbDictionaryImpl.hpp"
#include "NdbBlob.hpp"
NdbScanOperation
::
NdbScanOperation
(
Ndb
*
aNdb
)
:
NdbCursorOperation
(
aNdb
),
...
...
@@ -294,6 +295,18 @@ int NdbScanOperation::setValue(Uint32 anAttrId, double aValue)
return
0
;
}
NdbBlob
*
NdbScanOperation
::
getBlobHandle
(
const
char
*
anAttrName
)
{
return
NdbOperation
::
getBlobHandle
(
m_transConnection
,
m_currentTable
->
getColumn
(
anAttrName
));
}
NdbBlob
*
NdbScanOperation
::
getBlobHandle
(
Uint32
anAttrId
)
{
return
NdbOperation
::
getBlobHandle
(
m_transConnection
,
m_currentTable
->
getColumn
(
anAttrId
));
}
// Private methods
int
NdbScanOperation
::
executeCursor
(
int
ProcessorId
)
...
...
@@ -344,6 +357,15 @@ int NdbScanOperation::nextResult(bool fetchAllowed)
const
NdbError
err
=
theNdbCon
->
getNdbError
();
m_transConnection
->
setOperationErrorCode
(
err
.
code
);
}
if
(
result
==
0
)
{
// handle blobs
NdbBlob
*
tBlob
=
theBlobList
;
while
(
tBlob
!=
NULL
)
{
if
(
tBlob
->
atNextResult
()
==
-
1
)
return
-
1
;
tBlob
=
tBlob
->
theNext
;
}
}
return
result
;
}
...
...
ndb/src/ndbapi/Ndberr.cpp
View file @
c15a866f
...
...
@@ -18,8 +18,10 @@
#include <NdbError.hpp>
#include "NdbImpl.hpp"
#include "NdbDictionaryImpl.hpp"
#include <NdbSchemaCon.hpp>
#include <NdbOperation.hpp>
#include <NdbConnection.hpp>
#include <NdbBlob.hpp>
static
void
...
...
@@ -65,3 +67,17 @@ NdbOperation::getNdbError() const {
update
(
theError
);
return
theError
;
}
const
NdbError
&
NdbSchemaCon
::
getNdbError
()
const
{
update
(
theError
);
return
theError
;
}
const
NdbError
&
NdbBlob
::
getNdbError
()
const
{
update
(
theError
);
return
theError
;
}
ndb/src/ndbapi/Ndbinit.cpp
View file @
c15a866f
...
...
@@ -85,6 +85,7 @@ Ndb::Ndb( const char* aDataBase , const char* aDataBaseSchema) :
theSubroutineList
(
NULL
),
theCallList
(
NULL
),
theScanList
(
NULL
),
theNdbBlobIdleList
(
NULL
),
theNoOfDBnodes
(
0
),
theDBnodes
(
NULL
),
the_release_ind
(
NULL
),
...
...
@@ -235,6 +236,8 @@ Ndb::~Ndb()
freeNdbCall
();
while
(
theScanList
!=
NULL
)
freeNdbScanRec
();
while
(
theNdbBlobIdleList
!=
NULL
)
freeNdbBlob
();
releaseTransactionArrays
();
startTransactionNodeSelectionData
.
release
();
...
...
ndb/src/ndbapi/Ndblist.cpp
View file @
c15a866f
...
...
@@ -27,6 +27,7 @@
#include "NdbScanReceiver.hpp"
#include "NdbUtil.hpp"
#include "API.hpp"
#include "NdbBlob.hpp"
void
Ndb
::
checkFailedNode
()
...
...
@@ -435,6 +436,19 @@ Ndb::getSignal()
return
tSignal
;
}
NdbBlob
*
Ndb
::
getNdbBlob
()
{
NdbBlob
*
tBlob
=
theNdbBlobIdleList
;
if
(
tBlob
!=
NULL
)
{
theNdbBlobIdleList
=
tBlob
->
theNext
;
tBlob
->
init
();
}
else
{
tBlob
=
new
NdbBlob
;
}
return
tBlob
;
}
/***************************************************************************
void releaseNdbBranch(NdbBranch* aNdbBranch);
...
...
@@ -601,6 +615,14 @@ Ndb::releaseSignalsInList(NdbApiSignal** pList){
}
}
void
Ndb
::
releaseNdbBlob
(
NdbBlob
*
aBlob
)
{
aBlob
->
release
();
aBlob
->
theNext
=
theNdbBlobIdleList
;
theNdbBlobIdleList
=
aBlob
;
}
/***************************************************************************
void freeOperation();
...
...
@@ -745,6 +767,14 @@ Ndb::freeSignal()
cfreeSignals
++
;
}
void
Ndb
::
freeNdbBlob
()
{
NdbBlob
*
tBlob
=
theNdbBlobIdleList
;
theNdbBlobIdleList
=
tBlob
->
theNext
;
delete
tBlob
;
}
/****************************************************************************
int releaseConnectToNdb(NdbConnection* aConnectConnection);
...
...
ndb/src/ndbapi/ndberror.c
View file @
c15a866f
...
...
@@ -418,8 +418,14 @@ ErrorBundle ErrorCodes[] = {
{
4259
,
AE
,
"Invalid set of range scan bounds"
},
{
4260
,
UD
,
"NdbScanFilter: Operator is not defined in NdbScanFilter::Group"
},
{
4261
,
UD
,
"NdbScanFilter: Column is NULL"
},
{
4262
,
UD
,
"NdbScanFilter: Condition is out of bounds"
}
{
4262
,
UD
,
"NdbScanFilter: Condition is out of bounds"
},
{
4263
,
IE
,
"Invalid blob attributes or invalid blob parts table"
},
{
4264
,
AE
,
"Invalid usage of blob attribute"
},
{
4265
,
AE
,
"Method is not valid in current blob state"
},
{
4266
,
AE
,
"Invalid blob seek position"
},
{
4267
,
IE
,
"Corrupted blob value"
},
{
4268
,
IE
,
"Error in blob head update forced rollback of transaction"
},
{
4268
,
IE
,
"Unknown blob error"
}
};
static
...
...
ndb/src/old_files/client/odbc/codegen/SimpleGram.ypp
View file @
c15a866f
...
...
@@ -88,6 +88,7 @@ struct PhysAttr { int storage; int logging; };
struct PhysAttr* m_phys_attr;
NdbDictionary::Object::FragmentType m_storage_attr;
bool m_logging_attr;
SqlType::Type m_sql_type;
}
/* keywords */
...
...
@@ -100,6 +101,7 @@ struct PhysAttr { int storage; int logging; };
T_BLOB
T_BY
T_CHAR
T_CLOB
T_CONSTRAINT
T_CREATE
T_DATETIME
...
...
@@ -128,6 +130,7 @@ struct PhysAttr { int storage; int logging; };
T_LIMIT
T_LOGGING
T_LONGBLOB
T_LONGCLOB
T_MEDIUM
T_NOLOGGING
T_NOT
...
...
@@ -248,6 +251,7 @@ struct PhysAttr { int storage; int logging; };
%type <m_phys_attr> phys_attr2
%type <m_storage_attr> storage_attr
%type <m_logging_attr> logging_attr
%type <m_sql_type> blob_type
%%
...
...
@@ -606,10 +610,10 @@ data_type:
$$ = dataType;
}
|
blob_
keyword
blob_
type
{
Plan_root* root = simpleParser.root();
SqlType sqlType(
SqlType::Blob
, true);
SqlType sqlType(
$1
, true);
Plan_data_type* dataType = new Plan_data_type(root, sqlType);
root->saveNode(dataType);
$$ = dataType;
...
...
@@ -620,10 +624,26 @@ dummy_binary:
|
T_BINARY
;
blob_
keyword
:
blob_
type
:
T_BLOB
{
$$ = SqlType::Blob;
}
|
T_LONGBLOB
{
$$ = SqlType::Blob;
}
|
T_CLOB
{
$$ = SqlType::Clob;
}
|
T_LONGCLOB
{
$$ = SqlType::Clob;
}
;
create_column_rest:
/* empty */
...
...
ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp
View file @
c15a866f
...
...
@@ -149,6 +149,7 @@ static const SqlKeyword sqlKeyword[] = {
{ "BLOB", T_BLOB, StateType },
{ "BY", T_BY, -1 },
{ "CHAR", T_CHAR, StateType },
{ "CLOB", T_CLOB, StateType },
{ "CONSTRAINT", T_CONSTRAINT, -1 },
{ "CREATE", T_CREATE, -1 },
{ "DATETIME", T_DATETIME, StateType },
...
...
@@ -177,6 +178,7 @@ static const SqlKeyword sqlKeyword[] = {
{ "LIMIT", T_LIMIT, -1 },
{ "LOGGING", T_LOGGING, StatePhys },
{ "LONGBLOB", T_LONGBLOB, StateType },
{ "LONGCLOB", T_LONGCLOB, StateType },
{ "MEDIUM", T_MEDIUM, StatePhys },
{ "NOLOGGING", T_NOLOGGING, StatePhys },
{ "NOT", T_NOT, -1 },
...
...
ndb/src/old_files/client/odbc/common/DataType.cpp
View file @
c15a866f
...
...
@@ -78,6 +78,9 @@ SqlType::setType(Ctx& ctx, Type type, bool nullable)
case
Blob
:
setType
(
ctx
,
Varbinary
,
FAKE_BLOB_SIZE
,
nullable
);
// XXX BLOB hack
return
;
case
Clob
:
setType
(
ctx
,
Varchar
,
FAKE_BLOB_SIZE
,
nullable
);
// XXX BLOB hack
return
;
case
Null
:
case
Unbound
:
break
;
...
...
@@ -193,6 +196,9 @@ SqlType::setType(Ctx& ctx, const NdbDictionary::Column* ndbColumn)
case
NdbDictionary
:
:
Column
::
Blob
:
setType
(
ctx
,
Blob
,
nullable
);
return
;
case
NdbDictionary
:
:
Column
::
Clob
:
setType
(
ctx
,
Clob
,
nullable
);
return
;
default:
break
;
}
...
...
ndb/src/old_files/client/odbc/common/DataType.hpp
View file @
c15a866f
...
...
@@ -74,6 +74,7 @@ public:
Date
=
SQL_DATE
,
Datetime
=
SQL_TYPE_TIMESTAMP
,
Blob
=
SQL_BLOB
,
Clob
=
SQL_CLOB
,
Null
=
NullDataType
,
// not an ODBC SQL type
Unbound
=
UnboundDataType
// special for placeholders
};
...
...
ndb/test/ndbapi/Makefile_old
View file @
c15a866f
...
...
@@ -37,7 +37,8 @@ BIN_DIRS = \
indexTest \
test_event \
indexTest2 \
testGrep
testGrep \
testBlobs
ifeq ($(NDB_OS), SOLARIS)
ifeq ($(NDB_COMPILER), FORTE6)
...
...
ndb/test/ndbapi/testBlobs.cpp
deleted
100644 → 0
View file @
8742612a
/* Copyright (C) 2003 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; either version 2 of the License, or
(at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* testBlobs
*/
#include <ndb_global.h>
#include <NdbMain.h>
#include <NdbOut.hpp>
#include <NdbThread.h>
#include <NdbMutex.h>
#include <NdbCondition.h>
#include <NdbTest.hpp>
#include <NdbTick.h>
struct
Opt
{
bool
m_core
;
const
char
*
m_table
;
Opt
()
:
m_core
(
false
),
m_table
(
"TB1"
)
{
}
};
static
Opt
opt
;
static
void
printusage
()
{
Opt
d
;
ndbout
<<
"usage: testBlobs [options]"
<<
endl
<<
"-core dump core on error - default "
<<
d
.
m_core
<<
endl
;
}
static
Ndb
*
myNdb
=
0
;
static
NdbDictionary
::
Dictionary
*
myDic
=
0
;
static
NdbConnection
*
myCon
=
0
;
static
NdbOperation
*
myOp
=
0
;
static
NdbBlob
*
myBlob
=
0
;
static
void
fatal
(
const
char
*
fmt
,
...)
{
va_list
ap
;
char
buf
[
200
];
va_start
(
ap
,
fmt
);
vsnprintf
(
buf
,
sizeof
(
buf
),
fmt
,
ap
);
va_end
(
ap
);
ndbout
<<
"fatal: "
<<
buf
<<
endl
;
if
(
myNdb
!=
0
&&
myNdb
->
getNdbError
().
code
!=
0
)
ndbout
<<
"ndb - "
<<
myNdb
->
getNdbError
()
<<
endl
;
if
(
myDic
!=
0
&&
myDic
->
getNdbError
().
code
!=
0
)
ndbout
<<
"dic - "
<<
myDic
->
getNdbError
()
<<
endl
;
if
(
opt
.
m_core
)
abort
();
NDBT_ProgramExit
(
NDBT_FAILED
);
exit
(
1
);
}
static
void
dropBlobsTable
()
{
NdbDictionary
::
Table
tab
(
NDB_BLOB_TABLE_NAME
);
if
(
myDic
->
dropTable
(
tab
)
==
-
1
)
if
(
myDic
->
getNdbError
().
code
!=
709
)
fatal
(
"dropTable"
);
}
static
void
createBlobsTable
()
{
NdbDictionary
::
Table
tab
(
NDB_BLOB_TABLE_NAME
);
// col 0
NdbDictionary
::
Column
col0
(
"BLOBID"
);
col0
.
setPrimaryKey
(
true
);
col0
.
setType
(
NdbDictionary
::
Column
::
Bigunsigned
);
tab
.
addColumn
(
col0
);
// col 1
NdbDictionary
::
Column
col1
(
"DATA"
);
col1
.
setPrimaryKey
(
false
);
col1
.
setType
(
NdbDictionary
::
Column
::
Binary
);
col1
.
setLength
(
NDB_BLOB_PIECE_SIZE
);
tab
.
addColumn
(
col1
);
// create
if
(
myDic
->
createTable
(
tab
)
==
-
1
)
fatal
(
"createTable"
);
}
static
void
dropTable
()
{
NdbDictionary
::
Table
tab
(
opt
.
m_table
);
if
(
myDic
->
dropTable
(
tab
)
==
-
1
)
if
(
myDic
->
getNdbError
().
code
!=
709
)
fatal
(
"dropTable"
);
}
static
void
createTable
()
{
NdbDictionary
::
Table
tab
(
opt
.
m_table
);
// col 0
NdbDictionary
::
Column
col0
(
"A"
);
col0
.
setPrimaryKey
(
true
);
col0
.
setType
(
NdbDictionary
::
Column
::
Unsigned
);
tab
.
addColumn
(
col0
);
// col 1
NdbDictionary
::
Column
col1
(
"B"
);
col1
.
setPrimaryKey
(
false
);
col1
.
setType
(
NdbDictionary
::
Column
::
Blob
);
tab
.
addColumn
(
col1
);
// create
if
(
myDic
->
createTable
(
tab
)
==
-
1
)
fatal
(
"createTable"
);
}
static
void
insertData
(
Uint32
key
)
{
}
static
void
insertTuples
()
{
for
(
Uint32
key
=
0
;
key
<=
99
;
key
++
)
{
if
((
myCon
=
myNdb
->
startTransaction
())
==
0
)
fatal
(
"startTransaction"
);
if
((
myOp
=
myCon
->
getNdbOperation
(
opt
.
m_table
))
==
0
)
fatal
(
"getNdbOperation"
);
if
(
myOp
->
insertTuple
()
==
-
1
)
fatal
(
"insertTuple"
);
if
(
myOp
->
setValue
((
unsigned
)
0
,
key
)
==
-
1
)
fatal
(
"setValue %u"
,
(
unsigned
)
key
);
if
((
myBlob
=
myOp
->
setBlob
(
1
))
==
0
)
fatal
(
"setBlob"
);
if
(
myCon
->
execute
(
NoCommit
)
==
-
1
)
fatal
(
"execute NoCommit"
);
insertData
(
key
);
if
(
myCon
->
execute
(
Commit
)
==
-
1
)
fatal
(
"execute Commit"
);
myNdb
->
closeTransaction
(
myCon
);
myOp
=
0
;
myBlob
=
0
;
myCon
=
0
;
}
}
static
void
testMain
()
{
myNdb
=
new
Ndb
(
"TEST_DB"
);
if
(
myNdb
->
init
()
!=
0
)
fatal
(
"init"
);
if
(
myNdb
->
waitUntilReady
()
<
0
)
fatal
(
"waitUntilReady"
);
myDic
=
myNdb
->
getDictionary
();
dropBlobsTable
();
createBlobsTable
();
// until moved to Ndbcntr
dropTable
();
createTable
();
insertTuples
();
}
NDB_COMMAND
(
testOdbcDriver
,
"testBlobs"
,
"testBlobs"
,
"testBlobs"
,
65535
)
{
while
(
++
argv
,
--
argc
>
0
)
{
const
char
*
arg
=
argv
[
0
];
if
(
strcmp
(
arg
,
"-core"
)
==
0
)
{
opt
.
m_core
=
true
;
continue
;
}
}
testMain
();
return
NDBT_ProgramExit
(
NDBT_OK
);
}
// vim: set sw=4:
ndb/test/ndbapi/testBlobs/testBlobs.cpp
0 → 100644
View file @
c15a866f
This diff is collapsed.
Click to expand it.
ndb/test/src/NDBT_Table.cpp
View file @
c15a866f
...
...
@@ -14,35 +14,112 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include
<NDBT_Table.hpp>
#include
"NDBT_Table.hpp"
#include <NdbTimer.hpp>
#include <NDBT.hpp>
class
NdbOut
&
operator
<<
(
class
NdbOut
&
ndbout
,
const
NDBT_Attribute
&
attr
){
NdbDictionary
::
Column
::
Type
type
=
attr
.
getType
();
bool
key
=
attr
.
getPrimaryKey
();
bool
null
=
attr
.
getNullable
();
ndbout
<<
attr
.
getName
()
<<
" "
<<
type
;
ndbout
<<
attr
.
getName
()
<<
"
\t
"
;
char
tmp
[
100
];
if
(
attr
.
getLength
()
!=
1
)
snprintf
(
tmp
,
100
,
" [%d]"
,
attr
.
getLength
());
else
tmp
[
0
]
=
0
;
switch
(
type
){
case
NdbDictionary
:
:
Column
::
Tinyint
:
ndbout
<<
"Tinyint"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Tinyunsigned
:
ndbout
<<
"Tinyunsigned"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Smallint
:
ndbout
<<
"Smallint"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Smallunsigned
:
ndbout
<<
"Smallunsigned"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Mediumint
:
ndbout
<<
"Mediumint"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Mediumunsigned
:
ndbout
<<
"Mediumunsigned"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Int
:
ndbout
<<
"Int"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Unsigned
:
ndbout
<<
"Unsigned"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Bigint
:
ndbout
<<
"Bigint"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Bigunsigned
:
ndbout
<<
"Bigunsigned"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Float
:
ndbout
<<
"Float"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Double
:
ndbout
<<
"Double"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Decimal
:
ndbout
<<
"("
<<
attr
.
getScale
()
<<
", "
<<
attr
.
getPrecision
()
<<
")"
;
ndbout
<<
"Decimal("
<<
attr
.
getScale
()
<<
", "
<<
attr
.
getPrecision
()
<<
")"
<<
tmp
;
break
;
default:
case
NdbDictionary
:
:
Column
::
Char
:
ndbout
<<
"Char("
<<
attr
.
getLength
()
<<
")"
;
break
;
case
NdbDictionary
:
:
Column
::
Varchar
:
ndbout
<<
"Varchar("
<<
attr
.
getLength
()
<<
")"
;
break
;
case
NdbDictionary
:
:
Column
::
Binary
:
ndbout
<<
"Binary("
<<
attr
.
getLength
()
<<
")"
;
break
;
case
NdbDictionary
:
:
Column
::
Varbinary
:
ndbout
<<
"Varbinary("
<<
attr
.
getLength
()
<<
")"
;
break
;
case
NdbDictionary
:
:
Column
::
Datetime
:
ndbout
<<
"Datetime"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Timespec
:
ndbout
<<
"Timespec"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Blob
:
ndbout
<<
"Blob("
<<
attr
.
getInlineSize
()
<<
","
<<
attr
.
getPartSize
()
<<
","
<<
attr
.
getStripeSize
()
<<
")"
;
break
;
case
NdbDictionary
:
:
Column
::
Clob
:
ndbout
<<
"Clob("
<<
attr
.
getInlineSize
()
<<
","
<<
attr
.
getPartSize
()
<<
","
<<
attr
.
getStripeSize
()
<<
")"
;
break
;
case
NdbDictionary
:
:
Column
::
Undefined
:
ndbout
<<
"Undefined"
<<
tmp
;
break
;
default:
ndbout
<<
"Unknown("
<<
type
<<
")"
;
}
if
(
attr
.
getLength
()
!=
1
)
ndbout
<<
"["
<<
attr
.
getLength
()
<<
"]"
;
if
(
attr
.
getNullable
())
ndbout
<<
" NULL"
;
else
ndbout
<<
" NOT NULL
"
;
ndbout
<<
"
\t
"
;
if
(
null
){
ndbout
<<
"NULL"
;
}
else
{
ndbout
<<
"
NOT
NULL"
;
}
ndbout
<<
"
\t
"
;
if
(
attr
.
getPrimaryKey
()
)
ndbout
<<
"
PRIMARY KEY
"
;
if
(
key
)
ndbout
<<
"
\t
primary key
"
;
return
ndbout
;
}
...
...
@@ -60,9 +137,6 @@ operator <<(class NdbOut& ndbout, const NDBT_Table & tab)
ndbout
<<
"Temporary table: "
<<
(
tab
.
getStoredTable
()
?
"no"
:
"yes"
)
<<
endl
;
ndbout
<<
"Number of attributes: "
<<
tab
.
getNoOfColumns
()
<<
endl
;
ndbout
<<
"Number of primary keys: "
<<
tab
.
getNoOfPrimaryKeys
()
<<
endl
;
ndbout
<<
"Length of frm data: "
<<
tab
.
getFrmLength
()
<<
endl
;
//<< ((tab.getTupleKey() == TupleId) ? " tupleid" : "") <<endl;
ndbout
<<
"TableStatus: "
;
switch
(
tab
.
getObjectStatus
()){
...
...
@@ -87,32 +161,3 @@ operator <<(class NdbOut& ndbout, const NDBT_Table & tab)
return
ndbout
;
}
class
NdbOut
&
operator
<<
(
class
NdbOut
&
,
const
NdbDictionary
::
Index
&
idx
)
{
ndbout
<<
idx
.
getName
();
ndbout
<<
"("
;
for
(
unsigned
i
=
0
;
i
<
idx
.
getNoOfColumns
();
i
++
)
{
const
NdbDictionary
::
Column
*
col
=
idx
.
getColumn
(
i
);
ndbout
<<
col
->
getName
();
if
(
i
<
idx
.
getNoOfColumns
()
-
1
)
ndbout
<<
", "
;
}
ndbout
<<
")"
;
ndbout
<<
" - "
;
switch
(
idx
.
getType
())
{
case
NdbDictionary
:
:
Object
::
UniqueHashIndex
:
ndbout
<<
"UniqueHashIndex"
;
break
;
case
NdbDictionary
:
:
Object
::
OrderedIndex
:
ndbout
<<
"OrderedIndex"
;
break
;
default:
ndbout
<<
"Type "
<<
idx
.
getType
();
break
;
}
return
ndbout
;
}
ndb/tools/ndbsql.cpp
View file @
c15a866f
...
...
@@ -33,6 +33,12 @@
#include <ctype.h>
#include <wctype.h>
#ifndef SQL_BLOB
#define SQL_BLOB 30
#endif
#ifndef SQL_CLOB
#define SQL_CLOB 40
#endif
/**************************************************************************
* ------------------------------------------------------------------------
...
...
@@ -211,8 +217,10 @@ SQLINTEGER display_length(SQLSMALLINT coltype, SQLINTEGER collen,
switch
(
coltype
)
{
case
SQL_VARCHAR
:
case
SQL_CHAR
:
//case SQL_BLOB:
//case SQL_CLOB:
case
SQL_VARBINARY
:
case
SQL_BINARY
:
case
SQL_BLOB
:
case
SQL_CLOB
:
case
SQL_BIT
:
//case SQL_REF:
//case SQL_BIT_VARYING:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment