/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/test/ql-datatype-test.cc
Line | Count | Source (jump to first uncovered line) |
1 | | //-------------------------------------------------------------------------------------------------- |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | //-------------------------------------------------------------------------------------------------- |
15 | | |
16 | | #include "yb/common/ql_value.h" |
17 | | |
18 | | #include "yb/gutil/strings/substitute.h" |
19 | | |
20 | | #include "yb/util/decimal.h" |
21 | | #include "yb/util/result.h" |
22 | | #include "yb/util/status_log.h" |
23 | | |
24 | | #include "yb/yql/cql/ql/test/ql-test-base.h" |
25 | | |
26 | | using std::string; |
27 | | using std::unique_ptr; |
28 | | using std::shared_ptr; |
29 | | using strings::Substitute; |
30 | | |
31 | | namespace yb { |
32 | | namespace ql { |
33 | | |
34 | | class TestQLQuery : public QLTestBase { |
35 | | public: |
36 | 0 | TestQLQuery() : QLTestBase() { |
37 | 0 | } |
38 | | }; |
39 | | |
40 | 0 | TEST_F(TestQLQuery, TestQLQuerySimple) { |
41 | | // Init the simulated cluster. |
42 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
43 | | |
44 | | // Get a processor. |
45 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
46 | | |
47 | | // Create the table. |
48 | 0 | const char *create_stmt = "CREATE TABLE test_table" |
49 | 0 | "(h0 tinyint, h1 smallint, h2 int, h3 bigint, h4 varchar, h5 varint," |
50 | 0 | " r0 tinyint, r1 smallint, r2 int, r3 bigint, r4 varchar, r5 varint," |
51 | 0 | " v0 tinyint, v1 smallint, v2 int, v3 bigint, v4 varchar," |
52 | 0 | " v5 float, v6 double precision, v7 boolean, v8 varint," |
53 | 0 | " primary key((h0, h1, h2, h3, h4, h5), r0, r1, r2, r3, r4, r5));"; |
54 | 0 | CHECK_VALID_STMT(create_stmt); |
55 | | |
56 | | // Test NOTFOUND. Select from empty table for all types. |
57 | 0 | CHECK_VALID_STMT("SELECT * FROM test_table"); |
58 | 0 | CHECK_VALID_STMT("SELECT * FROM test_table" |
59 | 0 | " WHERE h0 = 0 AND h1 = 0 AND h2 = 0 AND h3 = 0 AND h4 = 'zero' AND h5 = 0;"); |
60 | 0 | std::shared_ptr<QLRowBlock> empty_row_block = processor->row_block(); |
61 | 0 | CHECK_EQ(empty_row_block->row_count(), 0); |
62 | | |
63 | | // Insert 10 rows into the table. |
64 | 0 | string stmt; |
65 | 0 | static const int kNumRows = 10; |
66 | 0 | for (int idx = 0; idx < kNumRows; idx++) { |
67 | 0 | const char *bool_value = idx % 2 == 0 ? "true" : "false"; |
68 | | |
69 | | // INSERT: Valid statement with column list. |
70 | 0 | stmt = Substitute( |
71 | 0 | "INSERT INTO test_table" |
72 | 0 | "(h0, h1, h2, h3, h4, h5," |
73 | 0 | " r0, r1, r2, r3, r4, r5," |
74 | 0 | " v0, v1, v2, v3, v4, v5, v6, v7, v8)" |
75 | 0 | " VALUES($0, $0, $0, $0, 'h$0', $0," |
76 | 0 | " $1, $1, $1, $1, 'r$1', $1," |
77 | 0 | " $0, $2, $2, $2, 'v$2', $2, $2, $3, $2);", |
78 | 0 | idx, idx+100, idx+200, bool_value); |
79 | 0 | LOG(INFO) << "Executing " << stmt; |
80 | 0 | CHECK_VALID_STMT(stmt); |
81 | 0 | } |
82 | 0 | LOG(INFO) << kNumRows << " rows inserted"; |
83 | | |
84 | | // Test simple query and result. |
85 | 0 | CHECK_VALID_STMT("SELECT * FROM test_table " |
86 | 0 | " WHERE h0 = 7 AND h1 = 7 AND h2 = 7 AND h3 = 7 AND h4 = 'h7' AND h5 = 7;"); |
87 | |
|
88 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
89 | 0 | CHECK_EQ(row_block->row_count(), 1); |
90 | 0 | const QLRow& row = row_block->row(0); |
91 | 0 | CHECK_EQ(row.column(0).int8_value(), 7); |
92 | 0 | CHECK_EQ(row.column(1).int16_value(), 7); |
93 | 0 | CHECK_EQ(row.column(2).int32_value(), 7); |
94 | 0 | CHECK_EQ(row.column(3).int64_value(), 7); |
95 | 0 | CHECK_EQ(row.column(4).string_value(), "h7"); |
96 | 0 | CHECK_EQ(row.column(5).varint_value(), util::VarInt(7)); |
97 | 0 | CHECK_EQ(row.column(6).int8_value(), 107); |
98 | 0 | CHECK_EQ(row.column(7).int16_value(), 107); |
99 | 0 | CHECK_EQ(row.column(8).int32_value(), 107); |
100 | 0 | CHECK_EQ(row.column(9).int64_value(), 107); |
101 | 0 | CHECK_EQ(row.column(10).string_value(), "r107"); |
102 | 0 | CHECK_EQ(row.column(11).varint_value(), util::VarInt(107)); |
103 | 0 | CHECK_EQ(row.column(12).int8_value(), 7); |
104 | 0 | CHECK_EQ(row.column(13).int16_value(), 207); |
105 | 0 | CHECK_EQ(row.column(14).int32_value(), 207); |
106 | 0 | CHECK_EQ(row.column(15).int64_value(), 207); |
107 | 0 | CHECK_EQ(row.column(16).string_value(), "v207"); |
108 | 0 | int ival = row.column(17).float_value(); |
109 | 0 | CHECK(ival >= 206 && ival <= 207); |
110 | 0 | ival = row.column(18).double_value();; |
111 | 0 | CHECK(ival >= 206 && ival <= 207); |
112 | 0 | CHECK_EQ(row.column(19).bool_value(), false); |
113 | 0 | CHECK_EQ(row.column(20).varint_value(), util::VarInt(207)); |
114 | 0 | } |
115 | | |
116 | 0 | #define CHECK_EXPECTED_ROW_DECIMAL(processor, name, balance, rate) \ |
117 | 0 | do { \ |
118 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); \ |
119 | 0 | CHECK_EQ(row_block->row_count(), 1); \ |
120 | 0 | CHECK_EQ(row_block->row(0).column(0).string_value(), name); \ |
121 | 0 | util::Decimal expected_decimal(balance), ret_decimal; \ |
122 | 0 | auto s = ret_decimal.DecodeFromComparable(row_block->row(0).column(1).decimal_value()); \ |
123 | 0 | CHECK(s.ok()); \ |
124 | 0 | CHECK_EQ(ret_decimal, expected_decimal); \ |
125 | 0 | CHECK_EQ(row_block->row(0).column(2).double_value(), rate); \ |
126 | 0 | } while(0) |
127 | | |
128 | 0 | #define CHECK_EXPECTED_ROW_VARINT(processor, name, balance, rate) \ |
129 | 0 | do { \ |
130 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); \ |
131 | 0 | CHECK_EQ(row_block->row_count(), 1); \ |
132 | 0 | CHECK_EQ(row_block->row(0).column(0).string_value(), name); \ |
133 | 0 | util::VarInt expected_varint = CHECK_RESULT(util::VarInt::CreateFromString(balance)); \ |
134 | 0 | util::VarInt ret_varint; \ |
135 | 0 | ret_varint = row_block->row(0).column(1).varint_value(); \ |
136 | 0 | CHECK_EQ(ret_varint, expected_varint); \ |
137 | 0 | CHECK_EQ(row_block->row(0).column(2).double_value(), rate); \ |
138 | 0 | } while(0) |
139 | | |
140 | 0 | TEST_F(TestQLQuery, TestQLDecimalType) { |
141 | | // Init the simulated cluster. |
142 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
143 | | |
144 | | // Get a processor. |
145 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
146 | | |
147 | | // Create the table. |
148 | 0 | const char *create_stmt = |
149 | 0 | "CREATE TABLE accounts(name varchar, balance decimal, rate double, primary key(name))"; |
150 | 0 | CHECK_VALID_STMT(create_stmt); |
151 | |
|
152 | 0 | string balance = "123456789123456789123456789123456789123456789123456390482039482309482309481.99"; |
153 | 0 | double rate = .01; |
154 | 0 | string stmt = Substitute("INSERT INTO accounts(name, balance, rate) VALUES('neil', $0, $1)", |
155 | 0 | balance, rate); |
156 | 0 | LOG(INFO) << "Executing " << stmt; |
157 | 0 | CHECK_VALID_STMT(stmt); |
158 | 0 | CHECK_VALID_STMT("SELECT name, balance, rate FROM accounts WHERE name='neil'"); |
159 | 0 | CHECK_EXPECTED_ROW_DECIMAL(processor, "neil", balance, rate); |
160 | 0 | } |
161 | | |
162 | 0 | TEST_F(TestQLQuery, TestQLVarIntType) { |
163 | | // Init the simulated cluster. |
164 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
165 | | |
166 | | // Get a processor. |
167 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
168 | | |
169 | | // Create the table. |
170 | 0 | const char *create_stmt = |
171 | 0 | "CREATE TABLE accounts(name varchar, balance varint, rate double, primary key(name))"; |
172 | 0 | CHECK_VALID_STMT(create_stmt); |
173 | |
|
174 | 0 | string balance = "123456789123456789123456789123456789123456789123456390482039482309482309481"; |
175 | 0 | double rate = .01; |
176 | 0 | string stmt = Substitute("INSERT INTO accounts(name, balance, rate) VALUES('sagnik', $0, $1)", |
177 | 0 | balance, rate); |
178 | 0 | LOG(INFO) << "Executing " << stmt; |
179 | 0 | CHECK_VALID_STMT(stmt); |
180 | 0 | CHECK_VALID_STMT("SELECT name, balance, rate FROM accounts WHERE name='sagnik'"); |
181 | 0 | CHECK_EXPECTED_ROW_VARINT(processor, "sagnik", balance, rate); |
182 | 0 | } |
183 | | |
184 | 0 | TEST_F(TestQLQuery, TestQLDecimalTypeInKey) { |
185 | | // Init the simulated cluster. |
186 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
187 | | |
188 | | // Get a processor. |
189 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
190 | | |
191 | | // Create the table. |
192 | 0 | auto create_stmt = "CREATE TABLE accounts(name varchar, balance decimal, rate double, " |
193 | 0 | "primary key(name, balance))"; |
194 | 0 | CHECK_VALID_STMT(create_stmt); |
195 | |
|
196 | 0 | vector<string> names = { "hector", "kannan", "karthik", "neil" }; |
197 | 0 | vector<string> balances = { |
198 | 0 | "1.0", |
199 | 0 | "100.01", |
200 | 0 | "100.02", |
201 | 0 | "123456789123456789123456789123456789123456789123456390482039482309482309481.99" |
202 | 0 | }; |
203 | 0 | vector<double> rates = { .0001, .022, 0001, .0001 }; |
204 | |
|
205 | 0 | for (size_t i = 0; i < names.size(); i++) { |
206 | 0 | auto insert_stmt = Substitute("INSERT INTO accounts(name, balance, rate) VALUES('$0', $1, $2)", |
207 | 0 | names[i], balances[i], rates[i]); |
208 | 0 | LOG(INFO) << "Executing: " << insert_stmt; |
209 | 0 | CHECK_VALID_STMT(insert_stmt); |
210 | 0 | auto select_stmt1 = |
211 | 0 | Substitute("SELECT name, balance, rate FROM accounts WHERE name = '$0' AND balance = $1", |
212 | 0 | names[i], balances[i]); |
213 | 0 | LOG(INFO) << "Executing: " << select_stmt1; |
214 | 0 | CHECK_VALID_STMT(select_stmt1); |
215 | 0 | CHECK_EXPECTED_ROW_DECIMAL(processor, names[i], balances[i], rates[i]); |
216 | |
|
217 | 0 | auto select_stmt2 = |
218 | 0 | Substitute("SELECT name, balance, rate FROM accounts WHERE name = '$0' AND balance > 0.001", |
219 | 0 | names[i]); |
220 | 0 | LOG(INFO) << "Executing: " << select_stmt2; |
221 | 0 | CHECK_VALID_STMT(select_stmt2); |
222 | 0 | CHECK_EXPECTED_ROW_DECIMAL(processor, names[i], balances[i], rates[i]); |
223 | |
|
224 | 0 | auto select_stmt3 = |
225 | 0 | Substitute("SELECT name, balance, rate FROM accounts WHERE name = '$0' AND balance < $1", |
226 | 0 | names[i], |
227 | 0 | "123456789123456789123456789123456789123456789123456390482039482309482309482.99"); |
228 | 0 | LOG(INFO) << "Executing : " << select_stmt3; |
229 | 0 | CHECK_VALID_STMT(select_stmt3); |
230 | 0 | CHECK_EXPECTED_ROW_DECIMAL(processor, names[i], balances[i], rates[i]); |
231 | 0 | } |
232 | 0 | } |
233 | | |
234 | 0 | TEST_F(TestQLQuery, TestQLVarIntTypeInKey) { |
235 | | // Init the simulated cluster. |
236 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
237 | | |
238 | | // Get a processor. |
239 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
240 | | |
241 | | // Create the table. |
242 | 0 | auto create_stmt = "CREATE TABLE accounts(name varchar, balance varint, rate double, " |
243 | 0 | "primary key(name, balance))"; |
244 | 0 | CHECK_VALID_STMT(create_stmt); |
245 | |
|
246 | 0 | vector<string> names = { "hector", "kannan", "karthik", "sagnik" }; |
247 | 0 | vector<string> balances = { |
248 | 0 | "-6555627", |
249 | 0 | "0", |
250 | 0 | "234", |
251 | 0 | "123456789123456789123456789123456789123456789123456390482039482309482309481" |
252 | 0 | }; |
253 | 0 | vector<double> rates = { .0001, .022, 0001, .0001 }; |
254 | |
|
255 | 0 | for (size_t i = 0; i < names.size(); i++) { |
256 | 0 | auto insert_stmt = Substitute("INSERT INTO accounts(name, balance, rate) VALUES('$0', $1, $2)", |
257 | 0 | names[i], balances[i], rates[i]); |
258 | 0 | LOG(INFO) << "Executing: " << insert_stmt; |
259 | 0 | CHECK_VALID_STMT(insert_stmt); |
260 | 0 | auto select_stmt1 = |
261 | 0 | Substitute("SELECT name, balance, rate FROM accounts WHERE name = '$0' AND balance = $1", |
262 | 0 | names[i], balances[i]); |
263 | 0 | LOG(INFO) << "Executing: " << select_stmt1; |
264 | 0 | CHECK_VALID_STMT(select_stmt1); |
265 | 0 | CHECK_EXPECTED_ROW_VARINT(processor, names[i], balances[i], rates[i]); |
266 | |
|
267 | 0 | auto select_stmt2 = |
268 | 0 | Substitute("SELECT name, balance, rate FROM accounts WHERE name = '$0' AND balance > $1", |
269 | 0 | names[i], |
270 | 0 | "-99988989898988989898989876454542344567754322121356576877980000765313347"); |
271 | 0 | LOG(INFO) << "Executing: " << select_stmt2; |
272 | 0 | CHECK_VALID_STMT(select_stmt2); |
273 | 0 | CHECK_EXPECTED_ROW_VARINT(processor, names[i], balances[i], rates[i]); |
274 | |
|
275 | 0 | auto select_stmt3 = |
276 | 0 | Substitute("SELECT name, balance, rate FROM accounts WHERE name = '$0' AND balance < $1", |
277 | 0 | names[i], |
278 | 0 | "123456789123456789123456789123456789123456789123456390482039482309482309482"); |
279 | 0 | LOG(INFO) << "Executing : " << select_stmt3; |
280 | 0 | CHECK_VALID_STMT(select_stmt3); |
281 | 0 | CHECK_EXPECTED_ROW_VARINT(processor, names[i], balances[i], rates[i]); |
282 | 0 | } |
283 | 0 | } |
284 | | |
285 | | } // namespace ql |
286 | | } // namespace yb |