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 "sql_resultset.h"
24 #include "plugin_log.h"
25 
Field_value()26 Field_value::Field_value()
27 : is_unsigned(false), has_ptr(false)
28 {}
29 
Field_value(const Field_value & other)30 Field_value::Field_value(const Field_value& other):
31     value(other.value),
32     v_string_length(other.v_string_length),
33     is_unsigned(other.is_unsigned),
34     has_ptr(other.has_ptr)
35 {
36   if (other.has_ptr)
37   {
38     copy_string(other.value.v_string, other.v_string_length);
39   }
40 }
41 
operator =(const Field_value & other)42 Field_value& Field_value::operator = (const Field_value& other)
43 {
44   if (&other != this)
45   {
46     this->~Field_value();
47 
48     value = other.value;
49     v_string_length = other.v_string_length;
50     is_unsigned = other.is_unsigned;
51     has_ptr = other.has_ptr;
52 
53     if (other.has_ptr)
54     {
55       copy_string(other.value.v_string, other.v_string_length);
56     }
57   }
58 
59   return *this;
60 }
61 
Field_value(const longlong & num,bool unsign)62 Field_value::Field_value(const longlong &num, bool unsign)
63 {
64   value.v_long = num;
65   is_unsigned = unsign;
66   has_ptr = false;
67 }
68 
Field_value(const double num)69 Field_value::Field_value(const double num)
70 {
71   value.v_double = num;
72   has_ptr = false;
73 }
74 
Field_value(const decimal_t & decimal)75 Field_value::Field_value(const decimal_t &decimal)
76 {
77   value.v_decimal = decimal;
78   has_ptr = false;
79 }
80 
81 
Field_value(const MYSQL_TIME & time)82 Field_value::Field_value(const MYSQL_TIME &time)
83 {
84   value.v_time = time;
85   has_ptr = false;
86 }
87 
copy_string(const char * str,size_t length)88 void Field_value::copy_string(const char *str, size_t length)
89 {
90   value.v_string = (char*)malloc(length + 1);
91   if (value.v_string)
92   {
93     value.v_string[length] = '\0';
94     memcpy(value.v_string, str, length);
95     v_string_length = length;
96     has_ptr = true;
97   }
98   else
99   {
100     log_message(MY_ERROR_LEVEL, "Error copying from empty string "); /* purecov: inspected */
101   }
102 }
103 
Field_value(const char * str,size_t length)104 Field_value::Field_value(const char *str, size_t length)
105 {
106   copy_string(str, length);
107 }
108 
109 
~Field_value()110 Field_value::~Field_value()
111 {
112   if (has_ptr && value.v_string)
113   {
114     free(value.v_string);
115   }
116 }
117 
118 /** resultset class **/
119 
clear()120 void Sql_resultset::clear()
121 {
122   while(!result_value.empty())
123   {
124     std::vector<Field_value*> fld_val= result_value.back();
125     result_value.pop_back();
126     while(!fld_val.empty())
127     {
128       Field_value *fld= fld_val.back();
129       fld_val.pop_back();
130       delete fld;
131     }
132   }
133   result_value.clear();
134   result_meta.clear();
135 
136   current_row= 0;
137   num_cols= 0;
138   num_rows= 0;
139   num_metarow= 0;
140   m_resultcs= NULL;
141   m_server_status= 0;
142   m_warn_count= 0;
143   m_affected_rows= 0;
144   m_last_insert_id= 0;
145   m_sql_errno= 0;
146   m_killed= false;
147 }
148 
149 
new_row()150 void Sql_resultset::new_row()
151 {
152   result_value.push_back(std::vector< Field_value* >());
153 }
154 
155 
new_field(Field_value * val)156 void Sql_resultset::new_field(Field_value *val)
157 {
158   result_value[num_rows].push_back(val);
159 }
160 
161 
next()162 bool Sql_resultset::next()
163 {
164   if (current_row < (int)num_rows - 1)
165   {
166     current_row++;
167     return true;
168   }
169 
170   return false;
171 }
172