1 /*
2    Copyright (c) 2009, 2021, Oracle and/or its affiliates.
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, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #include "Ndbinfo.hpp"
26 #include "SimulatedBlock.hpp"
27 #include <kernel/AttributeHeader.hpp>
28 #include <signaldata/TransIdAI.hpp>
29 
30 #define JAM_FILE_ID 326
31 
32 
Row(Signal * signal,DbinfoScanReq & req)33 Ndbinfo::Row::Row(Signal* signal, DbinfoScanReq& req) :
34   col_counter(0),
35   m_req(req)
36 {
37   // Use the "temporary" part of signal->theData as row buffer
38   start = signal->getDataPtrSend() + DbinfoScanReq::SignalLength;
39   const Uint32 data_sz = sizeof(signal->theData)/sizeof(signal->theData[0]);
40   end = signal->getDataPtrSend() + data_sz;
41   assert(start < end);
42 
43   curr = start;
44 }
45 
46 bool
check_buffer_space(AttributeHeader & ah) const47 Ndbinfo::Row::check_buffer_space(AttributeHeader& ah) const
48 {
49   const Uint32 needed =  ah.getHeaderSize() + ah.getDataSize();
50   const Uint32 avail = (Uint32)(end - curr);
51 
52   if(needed > avail)
53   {
54     ndbout_c("Warning, too small row buffer for attribute: %d, "
55              "needed: %d, avail: %d", ah.getAttributeId(), needed, avail);
56     assert(false);
57     return false; // Not enough room in row buffer
58   }
59   return true;
60 }
61 
62 void
check_attribute_type(AttributeHeader & ah,ColumnType type) const63 Ndbinfo::Row::check_attribute_type(AttributeHeader& ah, ColumnType type) const
64 {
65 #ifdef VM_TRACE
66   const Table& tab = getTable(m_req.tableId);
67   const Uint32 colid = ah.getAttributeId();
68   assert(colid < (Uint32)tab.m.ncols);
69   assert(tab.col[colid].coltype == type);
70 #endif
71 }
72 
73 void
write_string(const char * str)74 Ndbinfo::Row::write_string(const char* str)
75 {
76   const size_t clen = strlen(str) + 1;
77   // Create AttributeHeader
78   AttributeHeader ah(col_counter++, (Uint32)clen);
79   check_attribute_type(ah, Ndbinfo::String);
80   if (!check_buffer_space(ah))
81     return;
82 
83   // Write AttributeHeader to buffer
84   ah.insertHeader(curr);
85   curr += ah.getHeaderSize();
86 
87   // Write data to buffer
88   memcpy(curr, str, clen);
89   curr += ah.getDataSize();
90 
91   assert(curr <= end);
92   return;
93 }
94 
95 void
write_uint32(Uint32 value)96 Ndbinfo::Row::write_uint32(Uint32 value)
97 {
98   // Create AttributeHeader
99   AttributeHeader ah(col_counter++, sizeof(Uint32));
100   check_attribute_type(ah, Ndbinfo::Number);
101   if (!check_buffer_space(ah))
102     return;
103 
104   // Write AttributeHeader to buffer
105   ah.insertHeader(curr);
106   curr += ah.getHeaderSize();
107 
108   // Write data to buffer
109   memcpy(curr, &value, sizeof(Uint32));
110   curr += ah.getDataSize();
111 
112   assert(curr <= end);
113   return;
114 }
115 
116 void
write_uint64(Uint64 value)117 Ndbinfo::Row::write_uint64(Uint64 value)
118 {
119   // Create AttributeHeader
120   AttributeHeader ah(col_counter++, sizeof(Uint64));
121   check_attribute_type(ah, Ndbinfo::Number64);
122   if (!check_buffer_space(ah))
123     return;
124 
125   // Write AttributeHeader to buffer
126   ah.insertHeader(curr);
127   curr += ah.getHeaderSize();
128 
129   // Write data to buffer
130   memcpy(curr, &value, sizeof(Uint64));
131   curr += ah.getDataSize();
132 
133   assert(curr <= end);
134   return;
135 }
136 
137 
138