1 /*
2    Copyright (c) 2011, 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, 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 #ifndef NDB_SHARE_H
26 #define NDB_SHARE_H
27 
28 #include <my_global.h>
29 #include <my_alloc.h>        // MEM_ROOT
30 #include <thr_lock.h>        // THR_LOCK
31 #include <my_bitmap.h>       // MY_BITMAP
32 
33 #include <ndbapi/Ndb.hpp>    // Ndb::TupleIdRange
34 
35 enum NDB_SHARE_STATE {
36   NSS_INITIAL= 0,
37   NSS_DROPPED,
38   NSS_ALTERED
39 };
40 
41 
42 enum enum_conflict_fn_type
43 {
44   CFT_NDB_UNDEF = 0
45   ,CFT_NDB_MAX
46   ,CFT_NDB_OLD
47   ,CFT_NDB_MAX_DEL_WIN
48   ,CFT_NDB_EPOCH
49   ,CFT_NUMBER_OF_CFTS /* End marker */
50 };
51 
52 #ifdef HAVE_NDB_BINLOG
53 static const Uint32 MAX_CONFLICT_ARGS= 8;
54 
55 enum enum_conflict_fn_arg_type
56 {
57   CFAT_END
58   ,CFAT_COLUMN_NAME
59   ,CFAT_EXTRA_GCI_BITS
60 };
61 
62 struct st_conflict_fn_arg
63 {
64   enum_conflict_fn_arg_type type;
65   const char *ptr;
66   uint32 len;
67   union
68   {
69     uint32 fieldno;      // CFAT_COLUMN_NAME
70     uint32 extraGciBits; // CFAT_EXTRA_GCI_BITS
71   };
72 };
73 
74 struct st_conflict_fn_arg_def
75 {
76   enum enum_conflict_fn_arg_type arg_type;
77   bool optional;
78 };
79 
80 /* What type of operation was issued */
81 enum enum_conflicting_op_type
82 {                /* NdbApi          */
83   WRITE_ROW,     /* insert (!write) */
84   UPDATE_ROW,    /* update          */
85   DELETE_ROW     /* delete          */
86 };
87 
88 /*
89   prepare_detect_func
90 
91   Type of function used to prepare for conflict detection on
92   an NdbApi operation
93 */
94 typedef int (* prepare_detect_func) (struct NDB_CONFLICT_FN_SHARE* cfn_share,
95                                      enum_conflicting_op_type op_type,
96                                      const uchar* old_data,
97                                      const uchar* new_data,
98                                      const MY_BITMAP* write_set,
99                                      class NdbInterpretedCode* code);
100 
101 struct st_conflict_fn_def
102 {
103   const char *name;
104   enum_conflict_fn_type type;
105   const st_conflict_fn_arg_def* arg_defs;
106   prepare_detect_func prep_func;
107 };
108 
109 /* What sort of conflict was found */
110 enum enum_conflict_cause
111 {
112   ROW_ALREADY_EXISTS,
113   ROW_DOES_NOT_EXIST,
114   ROW_IN_CONFLICT
115 };
116 
117 /* NdbOperation custom data which points out handler and record. */
118 struct Ndb_exceptions_data {
119   struct NDB_SHARE* share;
120   const NdbRecord* key_rec;
121   const uchar* row;
122   enum_conflicting_op_type op_type;
123 };
124 
125 enum enum_conflict_fn_flags
126 {
127   CFF_NONE = 0,
128   CFF_REFRESH_ROWS = 1
129 };
130 
131 struct NDB_CONFLICT_FN_SHARE {
132   const st_conflict_fn_def* m_conflict_fn;
133 
134   /* info about original table */
135   uint8 m_pk_cols;
136   uint8 m_resolve_column;
137   uint8 m_resolve_size;
138   uint8 m_flags;
139   uint16 m_offset[16];
140   uint16 m_resolve_offset;
141 
142   const NdbDictionary::Table *m_ex_tab;
143   uint32 m_count;
144 };
145 #endif
146 
147 
148 /*
149   Stats that can be retrieved from ndb
150 */
151 struct Ndb_statistics {
152   Uint64 row_count;
153   Uint64 commit_count;
154   ulong row_size;
155   Uint64 fragment_memory;
156   Uint64 fragment_extent_space;
157   Uint64 fragment_extent_free_space;
158 };
159 
160 
161 struct NDB_SHARE {
162   NDB_SHARE_STATE state;
163   MEM_ROOT mem_root;
164   THR_LOCK lock;
165   pthread_mutex_t mutex;
166   char *key;
167   uint key_length;
168   char *new_key;
169   uint use_count;
170   uint commit_count_lock;
171   ulonglong commit_count;
172   char *db;
173   char *table_name;
174   Ndb::TupleIdRange tuple_id_range;
175   struct Ndb_statistics stat;
176   struct Ndb_index_stat* index_stat_list;
177   bool util_thread; // if opened by util thread
178   uint32 connect_count;
179   uint32 flags;
180 #ifdef HAVE_NDB_BINLOG
181   NDB_CONFLICT_FN_SHARE *m_cfn_share;
182 #endif
183   class Ndb_event_data *event_data; // Place holder before NdbEventOperation is created
184   class NdbEventOperation *op;
185   char *old_names; // for rename table
186   MY_BITMAP *subscriber_bitmap;
187   class NdbEventOperation *new_op;
188 };
189 
190 
191 inline
192 NDB_SHARE_STATE
get_ndb_share_state(NDB_SHARE * share)193 get_ndb_share_state(NDB_SHARE *share)
194 {
195   NDB_SHARE_STATE state;
196   pthread_mutex_lock(&share->mutex);
197   state= share->state;
198   pthread_mutex_unlock(&share->mutex);
199   return state;
200 }
201 
202 
203 inline
204 void
set_ndb_share_state(NDB_SHARE * share,NDB_SHARE_STATE state)205 set_ndb_share_state(NDB_SHARE *share, NDB_SHARE_STATE state)
206 {
207   pthread_mutex_lock(&share->mutex);
208   share->state= state;
209   pthread_mutex_unlock(&share->mutex);
210 }
211 
212 #endif
213