MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbRecAttr.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 
19 #include <ndb_global.h>
20 #include <NdbOut.hpp>
21 #include <NdbRecAttr.hpp>
22 #include <NdbBlob.hpp>
23 #include "NdbDictionaryImpl.hpp"
24 #include <NdbTCP.h>
25 
26 NdbRecAttr::NdbRecAttr(Ndb*)
27 {
28  theStorageX = 0;
29  init();
30 }
31 
33 {
34  release();
35 }
36 
37 int
38 NdbRecAttr::setup(const class NdbDictionary::Column* col, char* aValue)
39 {
40  return setup(&(col->m_impl), aValue);
41 }
42 
43 int
44 NdbRecAttr::setup(const NdbColumnImpl* anAttrInfo, char* aValue)
45 {
46  Uint32 tAttrSize = anAttrInfo->m_attrSize;
47  Uint32 tArraySize = anAttrInfo->m_arraySize;
48  Uint32 tAttrByteSize = tAttrSize * tArraySize;
49 
50  m_column = anAttrInfo;
51 
52  theAttrId = anAttrInfo->m_attrId;
53  m_size_in_bytes = tAttrByteSize;
54 
55  return setup(tAttrByteSize, aValue);
56 }
57 
58 int
59 NdbRecAttr::setup(Uint32 byteSize, char* aValue)
60 {
61  theValue = aValue;
62  m_getVarValue = NULL; // set in getVarValue() only
63 
64  if (theStorageX)
65  delete[] theStorageX;
66  theStorageX = NULL; // "safety first"
67 
68  // check alignment to signal data
69  // a future version could check alignment per data type as well
70 
71  if (aValue != NULL && (UintPtr(aValue)&3) == 0 && (byteSize&3) == 0) {
72  theRef = aValue;
73  return 0;
74  }
75 
76  if (byteSize <= 32) {
77  theStorage[0] = 0;
78  theStorage[1] = 0;
79  theStorage[2] = 0;
80  theStorage[3] = 0;
81  theRef = theStorage;
82  return 0;
83  }
84  Uint32 tSize = (byteSize + 7) >> 3;
85  Uint64* tRef = new Uint64[tSize];
86  if (tRef != NULL) {
87  for (Uint32 i = 0; i < tSize; i++) {
88  tRef[i] = 0;
89  }
90  theStorageX = tRef;
91  theRef = tRef;
92  return 0;
93  }
94  errno= ENOMEM;
95  return -1;
96 }
97 
98 
99 void
100 NdbRecAttr::copyout()
101 {
102  char* tRef = (char*)theRef;
103  char* tValue = theValue;
104  if (tRef != tValue && tRef != NULL && tValue != NULL) {
105  Uint32 n = m_size_in_bytes;
106  while (n-- > 0) {
107  *tValue++ = *tRef++;
108  }
109  }
110 }
111 
112 NdbRecAttr *
114  NdbRecAttr * ret = new NdbRecAttr(0);
115  if (ret == NULL)
116  {
117  errno = ENOMEM;
118  return NULL;
119  }
120  ret->theAttrId = theAttrId;
121  ret->m_size_in_bytes = m_size_in_bytes;
122  ret->m_column = m_column;
123 
124  Uint32 n = m_size_in_bytes;
125  if(n <= 32){
126  ret->theRef = (char*)&ret->theStorage[0];
127  ret->theStorageX = 0;
128  ret->theValue = 0;
129  } else {
130  ret->theStorageX = new Uint64[((n + 7) >> 3)];
131  if (ret->theStorageX == NULL)
132  {
133  delete ret;
134  errno = ENOMEM;
135  return NULL;
136  }
137  ret->theRef = (char*)ret->theStorageX;
138  ret->theValue = 0;
139  }
140  memcpy(ret->theRef, theRef, n);
141  return ret;
142 }
143 
144 bool
145 NdbRecAttr::receive_data(const Uint32 * data32, Uint32 sz)
146 {
147  const unsigned char* data = (const unsigned char*)data32;
148  if(sz)
149  {
150  if (unlikely(m_getVarValue != NULL)) {
151  // ONLY for blob V2 implementation
152  assert(m_column->getType() == NdbDictionary::Column::Longvarchar ||
154  assert(sz >= 2);
155  Uint32 len = data[0] + (data[1] << 8);
156  assert(len == sz - 2);
157  assert(len < (1 << 16));
158  *m_getVarValue = len;
159  data += 2;
160  sz -= 2;
161  }
162  if(!copyoutRequired())
163  memcpy(theRef, data, sz);
164  else
165  memcpy(theValue, data, sz);
166  m_size_in_bytes= sz;
167  return true;
168  }
169  else
170  {
171  return setNULL();
172  }
173  return false;
174 }
175 
176 static const NdbRecordPrintFormat default_print_format;
177 
178 NdbOut&
179 ndbrecattr_print_formatted(NdbOut& out, const NdbRecAttr &r,
180  const NdbRecordPrintFormat &f)
181 {
182  return NdbDictionary::printFormattedValue(out,
183  f,
184  r.getColumn(),
185  r.isNULL()==0 ? r.aRef() : 0);
186 }
187 
188 NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
189 {
190  return ndbrecattr_print_formatted(out, r, default_print_format);
191 }
192 
193 Int64
195 {
196  Int64 val;
197  memcpy(&val,theRef,8);
198  return val;
199 }
200 
201 Uint64
203 {
204  Uint64 val;
205  memcpy(&val,theRef,8);
206  return val;
207 }
208 
209 float
211 {
212  float val;
213  memcpy(&val,theRef,sizeof(val));
214  return val;
215 }
216 
217 double
219 {
220  double val;
221  memcpy(&val,theRef,sizeof(val));
222  return val;
223 }
224 
225 Int32
227 {
228  return sint3korr((unsigned char *)theRef);
229 }
230 
231 Uint32
233 {
234  return uint3korr((unsigned char*)theRef);
235 }