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
c08df487
Commit
c08df487
authored
Jun 10, 2004
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ndb api blobs
parent
c5393007
Changes
37
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
3396 additions
and
176 deletions
+3396
-176
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
+26
-2
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/client/odbc/codegen/SimpleGram.ypp
ndb/src/client/odbc/codegen/SimpleGram.ypp
+23
-3
ndb/src/client/odbc/codegen/SimpleScan.lpp
ndb/src/client/odbc/codegen/SimpleScan.lpp
+2
-0
ndb/src/client/odbc/common/DataType.cpp
ndb/src/client/odbc/common/DataType.cpp
+6
-0
ndb/src/client/odbc/common/DataType.hpp
ndb/src/client/odbc/common/DataType.hpp
+1
-0
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
ndb/src/ndbapi/Makefile
+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
+31
-2
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
+8
-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/test/ndbapi/Makefile
ndb/test/ndbapi/Makefile
+2
-1
ndb/test/ndbapi/testBlobs/testBlobs.cpp
ndb/test/ndbapi/testBlobs/testBlobs.cpp
+1147
-131
ndb/test/src/NDBT_Table.cpp
ndb/test/src/NDBT_Table.cpp
+8
-1
ndb/tools/ndbsql/ndbsql.cpp
ndb/tools/ndbsql/ndbsql.cpp
+10
-2
No files found.
ndb/include/kernel/ndb_limits.h
View file @
c08df487
...
...
@@ -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 @
c08df487
...
...
@@ -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 @
c08df487
...
...
@@ -882,6 +882,7 @@ class NdbScanReceiver;
class
Table
;
class
BaseString
;
class
NdbEventOperation
;
class
NdbBlob
;
typedef
void
(
*
NdbEventCallback
)(
NdbEventOperation
*
,
Ndb
*
,
void
*
);
...
...
@@ -969,6 +970,7 @@ class Ndb
friend
class
NdbIndexOperation
;
friend
class
NdbDictionaryImpl
;
friend
class
NdbDictInterface
;
friend
class
NdbBlob
;
public:
/**
...
...
@@ -1468,6 +1470,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
);
...
...
@@ -1479,6 +1482,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
);
...
...
@@ -1521,6 +1525,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
...
...
@@ -1628,6 +1633,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 @
c08df487
...
...
@@ -30,4 +30,5 @@
#include "NdbDictionary.hpp"
#include "NdbEventOperation.hpp"
#include "NdbPool.hpp"
#include "NdbBlob.hpp"
#endif
ndb/include/ndbapi/NdbBlob.hpp
0 → 100644
View file @
c08df487
/* 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 @
c08df487
...
...
@@ -29,6 +29,7 @@ class NdbIndexOperation;
class
NdbApiSignal
;
class
Ndb
;
class
NdbScanReceiver
;
class
NdbBlob
;
/**
...
...
@@ -132,6 +133,7 @@ class NdbConnection
friend
class
NdbScanOperation
;
friend
class
NdbIndexOperation
;
friend
class
NdbScanReceiver
;
friend
class
NdbBlob
;
public:
...
...
@@ -500,6 +502,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
...
...
@@ -580,10 +586,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
();
...
...
@@ -662,6 +670,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 @
c08df487
...
...
@@ -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,7 +298,29 @@ 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
();
}
/**
* 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.
*/
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
*
...
...
@@ -1023,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
,
...
...
ndb/include/ndbapi/NdbOperation.hpp
View file @
c08df487
...
...
@@ -29,6 +29,7 @@ class NdbRecAttr;
class
NdbOperation
;
class
NdbConnection
;
class
NdbColumnImpl
;
class
NdbBlob
;
/**
* @class NdbOperation
...
...
@@ -42,7 +43,8 @@ class NdbOperation
friend
class
NdbScanReceiver
;
friend
class
NdbScanFilter
;
friend
class
NdbScanFilterImpl
;
friend
class
NdbBlob
;
public:
/**
* @name Define Standard Operation Type
...
...
@@ -526,6 +528,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
);
/** @} *********************************************************************/
/**
...
...
@@ -833,6 +846,11 @@ public:
*/
int
getNdbErrorLine
();
/**
* Get table name of this operation.
*/
const
char
*
getTableName
()
const
;
/** @} *********************************************************************/
protected:
...
...
@@ -924,6 +942,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
);
...
...
@@ -968,6 +987,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.
*****************************************************************************/
...
...
@@ -1071,6 +1094,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 @
c08df487
...
...
@@ -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 @
c08df487
...
...
@@ -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/client/odbc/codegen/SimpleGram.ypp
View file @
c08df487
...
...
@@ -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/client/odbc/codegen/SimpleScan.lpp
View file @
c08df487
...
...
@@ -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/client/odbc/common/DataType.cpp
View file @
c08df487
...
...
@@ -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/client/odbc/common/DataType.hpp
View file @
c08df487
...
...
@@ -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/src/common/util/NdbSqlUtil.cpp
View file @
c08df487
...
...
@@ -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 @
c08df487
...
...
@@ -4725,6 +4725,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 @
c08df487
...
...
@@ -2722,8 +2722,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
View file @
c08df487
...
...
@@ -55,7 +55,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 @
c08df487
This diff is collapsed.
Click to expand it.
ndb/src/ndbapi/NdbConnection.cpp
View file @
c08df487
...
...
@@ -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 @
c08df487
...
...
@@ -268,6 +268,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 @
c08df487
...
...
@@ -35,6 +35,7 @@
#include <AttributeList.hpp>
#include <NdbEventOperation.hpp>
#include "NdbEventOperationImpl.hpp"
#include "NdbBlob.hpp"
#define DEBUG_PRINT 0
#define INCOMPATIBLE_VERSION -2
...
...
@@ -179,7 +180,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
){
...
...
@@ -224,6 +232,8 @@ NdbTableImpl::NdbTableImpl()
:
NdbDictionary
::
Table
(
*
this
),
m_facade
(
this
)
{
m_noOfKeys
=
0
;
m_sizeOfKeysInWords
=
0
;
m_noOfBlobs
=
0
;
m_index
=
0
;
init
();
}
...
...
@@ -258,6 +268,8 @@ NdbTableImpl::init(){
m_indexType
=
NdbDictionary
::
Index
::
Undefined
;
m_noOfKeys
=
0
;
m_sizeOfKeysInWords
=
0
;
m_noOfBlobs
=
0
;
}
bool
...
...
@@ -337,6 +349,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
;
...
...
@@ -1077,6 +1091,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 @
c08df487
...
...
@@ -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
...
...
@@ -352,13 +355,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
&
);
...
...
@@ -431,6 +433,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 @
c08df487
...
...
@@ -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 @
c08df487
...
...
@@ -31,6 +31,7 @@
#include "NdbApiSignal.hpp"
#include "NdbRecAttr.hpp"
#include "NdbUtil.hpp"
#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
;
...
...
@@ -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 @
c08df487
...
...
@@ -35,6 +35,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 @
c08df487
...
...
@@ -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 @
c08df487
...
...
@@ -252,6 +252,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
;
...
...
@@ -498,3 +509,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 @
c08df487
...
...
@@ -34,6 +34,7 @@
#include "NdbApiSignal.hpp"
#include <NdbOut.hpp>
#include "NdbDictionaryImpl.hpp"
#include "NdbBlob.hpp"
NdbScanOperation
::
NdbScanOperation
(
Ndb
*
aNdb
)
:
NdbCursorOperation
(
aNdb
),
...
...
@@ -292,6 +293,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
)
...
...
@@ -342,6 +355,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 @
c08df487
...
...
@@ -21,6 +21,7 @@
#include <NdbSchemaCon.hpp>
#include <NdbOperation.hpp>
#include <NdbConnection.hpp>
#include <NdbBlob.hpp>
static
void
...
...
@@ -73,3 +74,10 @@ NdbSchemaCon::getNdbError() const {
update
(
theError
);
return
theError
;
}
const
NdbError
&
NdbBlob
::
getNdbError
()
const
{
update
(
theError
);
return
theError
;
}
ndb/src/ndbapi/Ndbinit.cpp
View file @
c08df487
...
...
@@ -83,6 +83,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
),
...
...
@@ -231,6 +232,8 @@ Ndb::~Ndb()
freeNdbCall
();
while
(
theScanList
!=
NULL
)
freeNdbScanRec
();
while
(
theNdbBlobIdleList
!=
NULL
)
freeNdbBlob
();
releaseTransactionArrays
();
startTransactionNodeSelectionData
.
release
();
...
...
ndb/src/ndbapi/Ndblist.cpp
View file @
c08df487
...
...
@@ -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 @
c08df487
...
...
@@ -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/test/ndbapi/Makefile
View file @
c08df487
...
...
@@ -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/testBlobs.cpp
View file @
c08df487
This diff is collapsed.
Click to expand it.
ndb/test/src/NDBT_Table.cpp
View file @
c08df487
...
...
@@ -94,7 +94,14 @@ operator <<(class NdbOut& ndbout, const NDBT_Attribute & attr){
ndbout
<<
"Timespec"
<<
tmp
;
break
;
case
NdbDictionary
:
:
Column
::
Blob
:
ndbout
<<
"Blob"
<<
tmp
;
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
;
...
...
ndb/tools/ndbsql/ndbsql.cpp
View file @
c08df487
...
...
@@ -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