Server IP : 172.67.216.182 / Your IP : 162.158.106.173 Web Server : Apache System : Linux krdc-ubuntu-s-2vcpu-4gb-amd-blr1-01.localdomain 5.15.0-142-generic #152-Ubuntu SMP Mon May 19 10:54:31 UTC 2025 x86_64 User : www ( 1000) PHP Version : 7.4.33 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /www/server/mysql/src/rapid/unittest/gunit/xplugin/ |
Upload File : |
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is also distributed with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have included with MySQL. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <gtest/gtest.h> #include <mysql/service_my_snprintf.h> #include <limits> #include <string> #include <set> #include "ngs_common/protocol_protobuf.h" #include "ngs/protocol/row_builder.h" #include "ngs_common/xdatetime.h" #include "ngs_common/xdecimal.h" #include "decimal.h" #include "mysqlx_row.h" #include "ngs/protocol/buffer.h" #include "ngs/protocol/output_buffer.h" #include "protobuf_message.h" namespace xpl { namespace test { typedef ngs::Output_buffer Output_buffer; typedef ngs::Row_builder Row_builder; typedef ngs::Page_pool Page_pool; const ngs::Pool_config default_pool_config = { 0, 0, BUFFER_PAGE_SIZE }; static std::vector<ngs::shared_ptr<ngs::Page> > page_del; static void add_pages(Output_buffer *ob, const size_t no_of_pages, const size_t page_size) { for (size_t i = 0; i < no_of_pages; i++) { page_del.push_back(ngs::shared_ptr<ngs::Page>(new ngs::Page(static_cast<uint32_t>(page_size)))); ngs::Resource<ngs::Page> page(page_del.back().get()); ob->push_back(page); } } TEST(row_builder, row_start) { Row_builder rb; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_null_field(); rb.add_null_field(); rb.start_row(obuffer.get()); rb.end_row(); ASSERT_EQ(0u, rb.get_num_fields()); ASSERT_FALSE(NULL == obuffer); } TEST(row_builder, row_msg_size) { Row_builder rb; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); add_pages(obuffer.get(),2, 8); rb.start_row(obuffer.get()); rb.add_null_field(); rb.end_row(); int32_t size; obuffer->int32_at(0, size); ASSERT_EQ(3, size); // 1 byte for msg tag + 1 byte for field header + 1 byte for field value (NULL) rb.start_row(obuffer.get()); rb.add_null_field(); rb.add_null_field(); rb.end_row(); obuffer->int32_at(7, size); // offset of the size is 7 (3 bytes for prev msg + 4 for its size) ASSERT_EQ(5, size); // 1 byte for msg tag + 2*(1 byte for field header + 1 byte for field value (NULL)) } TEST(row_builder, row_abort) { Row_builder rb; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_null_field(); rb.add_null_field(); rb.abort_row(); ASSERT_EQ(0u, rb.get_num_fields()); rb.end_row(); } TEST(row_builder, fields_qty) { Row_builder rb; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); ASSERT_EQ(0u, rb.get_num_fields()); rb.add_null_field(); rb.add_null_field(); ASSERT_EQ(2u, rb.get_num_fields()); rb.add_longlong_field(0, true); rb.add_float_field(0.0f); rb.add_float_field(0.0f); ASSERT_EQ(5u, rb.get_num_fields()); rb.end_row(); ASSERT_EQ(0u, rb.get_num_fields()); } TEST(row_builder, null_field) { Row_builder rb; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_null_field(); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row (message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); ASSERT_EQ(0u, row->mutable_field(0)->length()); } TEST(row_builder, unsigned64_field) { Row_builder rb; std::string* buffer; int idx = 0; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_longlong_field(0, true); rb.add_longlong_field(500, true); rb.add_longlong_field(10000000, true); rb.add_longlong_field(0x7fffffffffffffffLL, true); rb.add_longlong_field(1, true); rb.add_longlong_field(0xffffffffffffffffLL, true); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); ASSERT_EQ(0u, mysqlx::Row_decoder::u64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(500u, mysqlx::Row_decoder::u64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(10000000u, mysqlx::Row_decoder::u64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(0x7fffffffffffffffULL, mysqlx::Row_decoder::u64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(1u, mysqlx::Row_decoder::u64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(0xffffffffffffffffULL, mysqlx::Row_decoder::u64_from_buffer(*buffer)); } TEST(row_builder, signed64_field) { Row_builder rb; std::string* buffer; int idx = 0; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_longlong_field(0, false); rb.add_longlong_field(-500, false); rb.add_longlong_field(-10000000, false); rb.add_longlong_field(0x7fffffffffffffffLL, false); rb.add_longlong_field(-1, false); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); ASSERT_EQ(0, mysqlx::Row_decoder::s64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(-500, mysqlx::Row_decoder::s64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(-10000000, mysqlx::Row_decoder::s64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(0x7fffffffffffffffLL, mysqlx::Row_decoder::s64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(-1, mysqlx::Row_decoder::s64_from_buffer(*buffer)); } TEST(row_builder, float_field) { Row_builder rb; std::string* buffer; int idx = 0; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_float_field(0.0f); rb.add_float_field(0.0001f); rb.add_float_field(-10000000.1f); rb.add_float_field(9999.91992f); rb.add_float_field(std::numeric_limits<float>::min()); rb.add_float_field(std::numeric_limits<float>::max()); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); ASSERT_FLOAT_EQ(0.0f, mysqlx::Row_decoder::float_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_FLOAT_EQ(0.0001f, mysqlx::Row_decoder::float_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_FLOAT_EQ(-10000000.1f, mysqlx::Row_decoder::float_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_FLOAT_EQ(9999.91992f, mysqlx::Row_decoder::float_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_FLOAT_EQ(std::numeric_limits<float>::min(), mysqlx::Row_decoder::float_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_FLOAT_EQ(std::numeric_limits<float>::max(), mysqlx::Row_decoder::float_from_buffer(*buffer)); } TEST(row_builder, double_field) { Row_builder rb; std::string* buffer; int idx = 0; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_double_field(0.0); rb.add_double_field(0.0001); rb.add_double_field(-10000000.1); rb.add_double_field(9999.91992); rb.add_double_field(std::numeric_limits<double>::min()); rb.add_double_field(std::numeric_limits<double>::max()); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); ASSERT_DOUBLE_EQ(0.0, mysqlx::Row_decoder::double_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_DOUBLE_EQ(0.0001, mysqlx::Row_decoder::double_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_DOUBLE_EQ(-10000000.1, mysqlx::Row_decoder::double_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_DOUBLE_EQ(9999.91992, mysqlx::Row_decoder::double_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_DOUBLE_EQ(std::numeric_limits<double>::min(), mysqlx::Row_decoder::double_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), mysqlx::Row_decoder::double_from_buffer(*buffer)); } TEST(row_builder, string_field) { Row_builder rb; std::string* buffer; int idx = 0; size_t len; const char* const STR1 = "ABBABABBBAAA-09-0900--==0,\0\0\0\0\0"; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_string_field("", 0, NULL); rb.add_string_field(STR1, strlen(STR1), NULL); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); ASSERT_STREQ("", mysqlx::Row_decoder::string_from_buffer(*buffer, len)); ASSERT_EQ(len, 0u); buffer = row->mutable_field(idx++); const char* res = mysqlx::Row_decoder::string_from_buffer(*buffer, len); for (size_t i = 0; i < len; i++) { ASSERT_EQ(STR1[i], res[i]); } ASSERT_EQ(len, strlen(STR1)); } TEST(row_builder, date_field) { Row_builder rb; std::string* buffer; int idx = 0; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); MYSQL_TIME time; time.year = 2006; time.month = 3; time.day = 24; rb.start_row(obuffer.get()); rb.add_date_field(&time); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); mysqlx::DateTime xtime = mysqlx::Row_decoder::datetime_from_buffer(*buffer); ASSERT_EQ(time.year, xtime.year()); ASSERT_EQ(time.month, xtime.month()); ASSERT_EQ(time.day, xtime.day()); } TEST(row_builder, time_field) { Row_builder rb; std::string* buffer; int idx = 0; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); MYSQL_TIME time; time.neg = false; time.hour = 12; time.minute = 0; time.second = 0; time.second_part = 999999; MYSQL_TIME time2; time2.neg = false; time2.hour = 0; time2.minute = 0; time2.second = 0; time2.second_part = 0; MYSQL_TIME time3; time3.neg = true; time3.hour = 811; time3.minute = 0; time3.second = 0; time3.second_part = 0; rb.start_row(obuffer.get()); rb.add_time_field(&time,0); rb.add_time_field(&time2, 0); rb.add_time_field(&time3, 0); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); mysqlx::Time xtime = mysqlx::Row_decoder::time_from_buffer(*buffer); ASSERT_TRUE(false == xtime.negate()); ASSERT_EQ(time.hour, xtime.hour()); ASSERT_EQ(time.minute, xtime.minutes()); ASSERT_EQ(time.second, xtime.seconds()); ASSERT_EQ(time.second_part, xtime.useconds()); buffer = row->mutable_field(idx++); xtime = mysqlx::Row_decoder::time_from_buffer(*buffer); ASSERT_TRUE(false == xtime.negate()); ASSERT_EQ(time2.hour, xtime.hour()); ASSERT_EQ(time2.minute, xtime.minutes()); ASSERT_EQ(time2.second, xtime.seconds()); ASSERT_EQ(time2.second_part, xtime.useconds()); buffer = row->mutable_field(idx++); xtime = mysqlx::Row_decoder::time_from_buffer(*buffer); ASSERT_TRUE(true == xtime.negate()); ASSERT_EQ(time3.hour, xtime.hour()); ASSERT_EQ(time3.minute, xtime.minutes()); ASSERT_EQ(time3.second, xtime.seconds()); ASSERT_EQ(time3.second_part, xtime.useconds()); } TEST(row_builder, datetime_field) { Row_builder rb; std::string* buffer; int idx = 0; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); MYSQL_TIME time; time.year = 2016; time.month = 12; time.day = 24; time.hour = 13; time.minute = 55; time.second = 55; time.second_part = 999999; time.time_type = MYSQL_TIMESTAMP_DATETIME; MYSQL_TIME time2; time2.year = 2000; time2.month = 1; time2.day = 1; time2.hour = 0; time2.minute = 0; time2.second = 0; time2.second_part = 0; time2.time_type = MYSQL_TIMESTAMP_DATETIME; rb.start_row(obuffer.get()); rb.add_datetime_field(&time, 0); rb.add_datetime_field(&time2, 0); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); mysqlx::DateTime xtime = mysqlx::Row_decoder::datetime_from_buffer(*buffer); ASSERT_EQ(time.year, xtime.year()); ASSERT_EQ(time.month, xtime.month()); ASSERT_EQ(time.day, xtime.day()); ASSERT_EQ(time.hour, xtime.hour()); ASSERT_EQ(time.minute, xtime.minutes()); ASSERT_EQ(time.second, xtime.seconds()); ASSERT_EQ(time.second_part, xtime.useconds()); buffer = row->mutable_field(idx++); xtime = mysqlx::Row_decoder::datetime_from_buffer(*buffer); ASSERT_EQ(time2.year, xtime.year()); ASSERT_EQ(time2.month, xtime.month()); ASSERT_EQ(time2.day, xtime.day()); ASSERT_EQ(time2.hour, xtime.hour()); ASSERT_EQ(time2.minute, xtime.minutes()); ASSERT_EQ(time2.second, xtime.seconds()); ASSERT_EQ(time2.second_part, xtime.useconds()); } TEST(row_builder, decimal_field) { Row_builder rb; std::string* buffer; int idx = 0; mysqlx::Decimal xdecimal; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); decimal_digit_t arr1[] = { 1, 0 }; decimal_t dec1 = {1, 1, 2, 1, arr1}; rb.add_decimal_field(&dec1); decimal_digit_t arr2[] = { 1, 0 }; decimal_t dec2 = { 1, 1, 2, 0, arr2 }; rb.add_decimal_field(&dec2); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); xdecimal = mysqlx::Row_decoder::decimal_from_buffer(*buffer); ASSERT_EQ("-1.0", xdecimal.str()); buffer = row->mutable_field(idx++); xdecimal = mysqlx::Row_decoder::decimal_from_buffer(*buffer); ASSERT_EQ("1.0", xdecimal.str()); } TEST(row_builder, set_field) { Row_builder rb; std::string* buffer; int idx = 0; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_set_field("A,B,C,D", strlen("A,B,C,D"), NULL); rb.add_set_field("", strlen(""), NULL); //empty SET case rb.add_set_field("A", strlen("A"), NULL); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); ASSERT_EQ(mysqlx::Row_decoder::set_from_buffer_as_str(*buffer), "A,B,C,D"); std::set<std::string> elems; mysqlx::Row_decoder::set_from_buffer(*buffer, elems); ASSERT_EQ(1u, elems.count("A")); ASSERT_EQ(1u, elems.count("B")); ASSERT_EQ(1u, elems.count("C")); ASSERT_EQ(1u, elems.count("D")); ASSERT_EQ(4u, elems.size()); buffer = row->mutable_field(idx++); mysqlx::Row_decoder::set_from_buffer(*buffer, elems); ASSERT_EQ(true, elems.empty()); ASSERT_EQ("", mysqlx::Row_decoder::set_from_buffer_as_str(*buffer)); buffer = row->mutable_field(idx++); mysqlx::Row_decoder::set_from_buffer(*buffer, elems); ASSERT_EQ(1u, elems.size()); ASSERT_EQ(1u, elems.count("A")); ASSERT_EQ("A", mysqlx::Row_decoder::set_from_buffer_as_str(*buffer)); } TEST(row_builder, bit_field) { Row_builder rb; std::string* buffer; int idx = 0; ngs::unique_ptr<Page_pool> page_pool(new Page_pool(default_pool_config)); ngs::unique_ptr<Output_buffer> obuffer(new Output_buffer(*page_pool)); rb.start_row(obuffer.get()); rb.add_bit_field("\x00", 1, NULL); rb.add_bit_field("\x01", 1, NULL); rb.add_bit_field("\xff\x00", 2, NULL); rb.add_bit_field("\x00\x00\x00\x00\x00\x00\x00\x00", 8, NULL); rb.add_bit_field("\xff\xff\xff\xff\xff\xff\xff\xff", 8, NULL); rb.end_row(); ngs::unique_ptr<Mysqlx::Resultset::Row> row(message_from_buffer<Mysqlx::Resultset::Row>(obuffer.get())); buffer = row->mutable_field(idx++); ASSERT_EQ(0x0u, mysqlx::Row_decoder::u64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(0x1u, mysqlx::Row_decoder::u64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(0xff00u, mysqlx::Row_decoder::u64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(0x0000000000000000ULL, mysqlx::Row_decoder::u64_from_buffer(*buffer)); buffer = row->mutable_field(idx++); ASSERT_EQ(0xffffffffffffffffULL, mysqlx::Row_decoder::u64_from_buffer(*buffer)); } } // namespace test } // namespace xpl