1 /* Copyright (c) 2015, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software Foundation,
21    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 #include "compatibility_module.h"
24 
Compatibility_module()25 Compatibility_module::Compatibility_module()
26   : local_version(NULL)
27 {}
28 
Compatibility_module(Member_version & local_version)29 Compatibility_module::Compatibility_module(Member_version &local_version)
30 {
31   this->local_version= new Member_version(local_version.get_version());
32 }
33 
34 Member_version&
get_local_version()35 Compatibility_module::get_local_version()
36 {
37   return *this->local_version;
38 }
39 
40 void
set_local_version(Member_version & local_version)41 Compatibility_module::set_local_version(Member_version &local_version)
42 {
43   delete this->local_version;
44   this->local_version= new Member_version(local_version.get_version());
45 }
46 
47 void
add_incompatibility(Member_version & from,Member_version & to)48 Compatibility_module::add_incompatibility(Member_version &from,
49                                           Member_version &to)
50 {
51   this->incompatibilities.
52       insert(std::make_pair(from.get_version(),
53                             std::make_pair(to.get_version(),
54                                            to.get_version())));
55 }
56 
57 void
add_incompatibility(Member_version & from,Member_version & to_min,Member_version & to_max)58 Compatibility_module::add_incompatibility(Member_version &from,
59                                           Member_version &to_min,
60                                           Member_version &to_max)
61 {
62   assert(to_min.get_version() <= to_max.get_version());
63   this->incompatibilities.
64       insert(std::make_pair(from.get_version(),
65                             std::make_pair(to_min.get_version(),
66                                            to_max.get_version())));
67 }
68 
69 Compatibility_type
check_local_incompatibility(Member_version & to,bool is_lowest_version)70 Compatibility_module::check_local_incompatibility(Member_version &to, bool is_lowest_version)
71 {
72   return check_incompatibility(get_local_version(), to, is_lowest_version);
73 }
74 
75 bool
check_version_range_incompatibility(Member_version & from,unsigned int to_min,unsigned int to_max)76 Compatibility_module::check_version_range_incompatibility(Member_version &from,
77                                                           unsigned int to_min,
78                                                           unsigned int to_max)
79 {
80   unsigned int to_max_major_version= to_max >> 16;
81   unsigned int to_min_major_version= to_min >> 16;
82   // if it is outside the range of the major version
83   if (from.get_major_version() > to_max_major_version ||
84       from.get_major_version() < to_min_major_version)
85     return false;
86 
87   unsigned int to_max_minor_version= (to_max >> 8) & 0xff;
88   unsigned int to_min_minor_version= (to_min >> 8) & 0xff;
89   // if it is outside the range of the minor version
90   if (from.get_minor_version() > to_max_minor_version ||
91       from.get_minor_version() < to_min_minor_version)
92     return false; /* purecov: inspected */
93 
94   unsigned int to_max_patch_version= to_max & 0xff;
95   unsigned int to_min_patch_version= to_min & 0xff;
96   // if it is outside the range of the patch version
97   if (from.get_patch_version() > to_max_patch_version ||
98       from.get_patch_version() < to_min_patch_version)
99     return false;
100 
101   return true;
102 }
103 
104 Compatibility_type
check_incompatibility(Member_version & from,Member_version & to,bool do_version_check)105 Compatibility_module::check_incompatibility(Member_version &from,
106                                             Member_version &to,
107                                             bool do_version_check)
108 {
109   //Check if they are the same...
110   if (from == to)
111     return COMPATIBLE;
112 
113   //Find if the values are present in the statically defined table...
114   std::pair <std::multimap<unsigned int,
115                            std::pair<unsigned int, unsigned int> >::iterator,
116              std::multimap<unsigned int,
117                            std::pair<unsigned int, unsigned int> >::iterator> search_its;
118 
119   search_its = this->incompatibilities.equal_range(from.get_version());
120 
121   for (std::multimap<unsigned int,
122                      std::pair<unsigned int, unsigned int> >::iterator it=
123                          search_its.first;
124        it != search_its.second;
125        ++it)
126   {
127     if (check_version_range_incompatibility(to,
128                                             it->second.first,
129                                             it->second.second))
130     {
131       return INCOMPATIBLE;
132     }
133   }
134 
135   //It was not deemed incompatible by the table rules:
136 
137   /*
138     Version compatibility might only be against the lowest group version
139   */
140   if(do_version_check)
141   {
142     /*
143       If they belong to the same major version
144     */
145     if (from.get_major_version() == to.get_major_version())
146       return COMPATIBLE;
147   }
148   else
149   {
150     return COMPATIBLE;
151   }
152 
153   //If it has a higher major version then change to read mode
154   if (from.get_major_version() > to.get_major_version())
155     return READ_COMPATIBLE;
156 
157   /*
158     It is a lower version, so it is incompatible lower, meaning
159     that by default it is not compatible, but user may ignore
160     this decision.
161   */
162   return INCOMPATIBLE_LOWER_VERSION;
163 }
164 
~Compatibility_module()165 Compatibility_module::~Compatibility_module()
166 {
167   delete this->local_version;
168 }
169 
170