/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/test/ql-select-expr-test.cc
Line | Count | Source (jump to first uncovered line) |
1 | | //-------------------------------------------------------------------------------------------------- |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | //-------------------------------------------------------------------------------------------------- |
4 | | |
5 | | #include <cmath> |
6 | | #include <limits> |
7 | | |
8 | | #include "yb/common/jsonb.h" |
9 | | #include "yb/common/ql_type.h" |
10 | | #include "yb/common/ql_value.h" |
11 | | #include "yb/common/schema.h" |
12 | | |
13 | | #include "yb/util/decimal.h" |
14 | | #include "yb/util/result.h" |
15 | | #include "yb/util/status_log.h" |
16 | | |
17 | | #include "yb/yql/cql/ql/statement.h" |
18 | | #include "yb/yql/cql/ql/test/ql-test-base.h" |
19 | | #include "yb/yql/cql/ql/util/cql_message.h" |
20 | | #include "yb/yql/cql/ql/util/errcodes.h" |
21 | | |
22 | | DECLARE_bool(TEST_tserver_timeout); |
23 | | |
24 | | using std::string; |
25 | | using std::unique_ptr; |
26 | | using std::shared_ptr; |
27 | | using std::numeric_limits; |
28 | | |
29 | | using strings::Substitute; |
30 | | using yb::util::Decimal; |
31 | | using yb::util::DecimalFromComparable; |
32 | | using yb::util::VarInt; |
33 | | |
34 | | namespace yb { |
35 | | namespace ql { |
36 | | |
37 | | struct CQLQueryParameters : public CQLMessage::QueryParameters { |
38 | | typedef CQLMessage::QueryParameters::NameToIndexMap NameToIndexMap; |
39 | | |
40 | 0 | CQLQueryParameters() { |
41 | 0 | flags = CQLMessage::QueryParameters::kWithValuesFlag; |
42 | 0 | } |
43 | | |
44 | 0 | void Reset() { |
45 | 0 | values.clear(); |
46 | 0 | value_map.clear(); |
47 | 0 | } |
48 | | |
49 | 0 | void PushBackInt32(const string& name, int32_t val) { |
50 | 0 | QLValue qv; |
51 | 0 | qv.set_int32_value(val); |
52 | 0 | PushBack(name, qv, DataType::INT32); |
53 | 0 | } |
54 | | |
55 | 0 | void PushBack(const string& name, const QLValue& qv, DataType data_type) { |
56 | 0 | PushBack(name, qv, QLType::Create(data_type)); |
57 | 0 | } |
58 | | |
59 | 0 | void PushBack(const string& name, const QLValue& qv, const shared_ptr<QLType>& type) { |
60 | 0 | faststring buffer; |
61 | 0 | qv.Serialize(type, YQL_CLIENT_CQL, &buffer); |
62 | |
|
63 | 0 | CQLMessage::Value msg_value; |
64 | 0 | msg_value.name = name; |
65 | 0 | msg_value.value = buffer.ToString(); |
66 | 0 | value_map.insert(NameToIndexMap::value_type(name, values.size())); |
67 | 0 | values.push_back(msg_value); |
68 | 0 | } |
69 | | }; |
70 | | |
71 | | class QLTestSelectedExpr : public QLTestBase { |
72 | | public: |
73 | 0 | QLTestSelectedExpr() : QLTestBase() { |
74 | 0 | } |
75 | | |
76 | | void CheckSelectedRow(TestQLProcessor *processor, |
77 | | const string& query, |
78 | 0 | const string& expected_row) const { |
79 | 0 | CHECK_VALID_STMT(query); |
80 | 0 | shared_ptr<QLRowBlock> row_block = processor->row_block(); |
81 | 0 | EXPECT_EQ(row_block->row_count(), 1); |
82 | 0 | if (row_block->row_count() > 0) { |
83 | 0 | const QLRow& row = row_block->row(0); |
84 | 0 | LOG(INFO) << "Got row: " << row.ToString(); |
85 | 0 | EXPECT_EQ(row.ToString(), expected_row); |
86 | 0 | } |
87 | 0 | } |
88 | | }; |
89 | | |
90 | 0 | TEST_F(QLTestSelectedExpr, TestAggregateExpr) { |
91 | | // Init the simulated cluster. |
92 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
93 | | |
94 | | // Get a processor. |
95 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
96 | 0 | LOG(INFO) << "Test selecting numeric expressions."; |
97 | | |
98 | | // Create the table and insert some value. |
99 | 0 | const char *create_stmt = |
100 | 0 | "CREATE TABLE test_aggr_expr(h int, r int," |
101 | 0 | " v1 bigint, v2 int, v3 smallint, v4 tinyint," |
102 | 0 | " v5 float, v6 double, primary key(h, r));"; |
103 | 0 | CHECK_VALID_STMT(create_stmt); |
104 | | |
105 | | // Insert rows whose hash value is '1'. |
106 | 0 | CHECK_VALID_STMT("INSERT INTO test_aggr_expr(h, r, v1, v2, v3, v4, v5, v6)" |
107 | 0 | " VALUES(1, 777, 11, 12, 13, 14, 15, 16);"); |
108 | | |
109 | | // Insert the rest of the rows, one of which has hash value of '1'. |
110 | 0 | int64_t v1_total = 11; |
111 | 0 | int32_t v2_total = 12; |
112 | 0 | int16_t v3_total = 13; |
113 | 0 | int8_t v4_total = 14; |
114 | 0 | float v5_total = 15; |
115 | 0 | double v6_total = 16; |
116 | 0 | for (int i = 1; i < 20; i++) { |
117 | 0 | string stmt = strings::Substitute( |
118 | 0 | "INSERT INTO test_aggr_expr(h, r, v1, v2, v3, v4, v5, v6)" |
119 | 0 | " VALUES($0, $1, $2, $3, $4, $5, $6, $7);", |
120 | 0 | i, i + 1, i + 1000, i + 100, i + 10, i, i + 77.77, i + 999.99); |
121 | 0 | CHECK_VALID_STMT(stmt); |
122 | |
|
123 | 0 | v1_total += (i + 1000); |
124 | 0 | v2_total += (i + 100); |
125 | 0 | v3_total += (i + 10); |
126 | 0 | v4_total += i; |
127 | 0 | v5_total += (i + 77.77); |
128 | 0 | v6_total += (i + 999.99); |
129 | 0 | } |
130 | |
|
131 | 0 | std::shared_ptr<QLRowBlock> row_block; |
132 | | |
133 | | //------------------------------------------------------------------------------------------------ |
134 | | // Test COUNT() aggregate function. |
135 | 0 | { |
136 | | // Test COUNT() - Not existing data. |
137 | 0 | CHECK_VALID_STMT("SELECT count(*), count(h), count(r), count(v1) " |
138 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 1;"); |
139 | 0 | row_block = processor->row_block(); |
140 | 0 | CHECK_EQ(row_block->row_count(), 1); |
141 | 0 | const QLRow& sum_0_row = row_block->row(0); |
142 | 0 | CHECK_EQ(sum_0_row.column(0).int64_value(), 0); |
143 | 0 | CHECK_EQ(sum_0_row.column(1).int64_value(), 0); |
144 | 0 | CHECK_EQ(sum_0_row.column(2).int64_value(), 0); |
145 | 0 | CHECK_EQ(sum_0_row.column(3).int64_value(), 0); |
146 | | |
147 | | // Test COUNT() - Where condition provides full primary key. |
148 | 0 | CHECK_VALID_STMT("SELECT count(*), count(h), count(r), count(v1) " |
149 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 777;"); |
150 | 0 | row_block = processor->row_block(); |
151 | 0 | CHECK_EQ(row_block->row_count(), 1); |
152 | 0 | const QLRow& sum_1_row = row_block->row(0); |
153 | 0 | CHECK_EQ(sum_1_row.column(0).int64_value(), 1); |
154 | 0 | CHECK_EQ(sum_1_row.column(1).int64_value(), 1); |
155 | 0 | CHECK_EQ(sum_1_row.column(2).int64_value(), 1); |
156 | 0 | CHECK_EQ(sum_1_row.column(3).int64_value(), 1); |
157 | | |
158 | | // Test COUNT() - Where condition provides full hash key. |
159 | 0 | CHECK_VALID_STMT("SELECT count(*), count(h), count(r), count(v1) " |
160 | 0 | " FROM test_aggr_expr WHERE h = 1;"); |
161 | 0 | row_block = processor->row_block(); |
162 | 0 | CHECK_EQ(row_block->row_count(), 1); |
163 | 0 | const QLRow& sum_2_row = row_block->row(0); |
164 | 0 | CHECK_EQ(sum_2_row.column(0).int64_value(), 2); |
165 | 0 | CHECK_EQ(sum_2_row.column(1).int64_value(), 2); |
166 | 0 | CHECK_EQ(sum_2_row.column(2).int64_value(), 2); |
167 | 0 | CHECK_EQ(sum_2_row.column(3).int64_value(), 2); |
168 | | |
169 | | // Test COUNT() - All rows. |
170 | 0 | CHECK_VALID_STMT("SELECT count(*), count(h), count(r), count(v1) " |
171 | 0 | " FROM test_aggr_expr;"); |
172 | 0 | row_block = processor->row_block(); |
173 | 0 | CHECK_EQ(row_block->row_count(), 1); |
174 | 0 | const QLRow& sum_all_row = row_block->row(0); |
175 | 0 | CHECK_EQ(sum_all_row.column(0).int64_value(), 20); |
176 | 0 | CHECK_EQ(sum_all_row.column(1).int64_value(), 20); |
177 | 0 | CHECK_EQ(sum_all_row.column(2).int64_value(), 20); |
178 | 0 | CHECK_EQ(sum_all_row.column(3).int64_value(), 20); |
179 | 0 | } |
180 | | |
181 | | //------------------------------------------------------------------------------------------------ |
182 | | // Test SUM() aggregate function. |
183 | 0 | { |
184 | | // Test SUM() - Not existing data. |
185 | 0 | CHECK_VALID_STMT("SELECT sum(v1), sum(v2), sum(v3), sum(v4), sum(v5), sum(v6)" |
186 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 1;"); |
187 | 0 | row_block = processor->row_block(); |
188 | 0 | CHECK_EQ(row_block->row_count(), 1); |
189 | 0 | const QLRow& sum_0_row = row_block->row(0); |
190 | 0 | CHECK_EQ(sum_0_row.column(0).int64_value(), 0); |
191 | 0 | CHECK_EQ(sum_0_row.column(1).int32_value(), 0); |
192 | 0 | CHECK_EQ(sum_0_row.column(2).int16_value(), 0); |
193 | 0 | CHECK_EQ(sum_0_row.column(3).int8_value(), 0); |
194 | 0 | CHECK_EQ(sum_0_row.column(4).float_value(), 0); |
195 | 0 | CHECK_EQ(sum_0_row.column(5).double_value(), 0); |
196 | | |
197 | | // Test SUM() - Where condition provides full primary key. |
198 | 0 | CHECK_VALID_STMT("SELECT sum(v1), sum(v2), sum(v3), sum(v4), sum(v5), sum(v6)" |
199 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 777;"); |
200 | 0 | row_block = processor->row_block(); |
201 | 0 | CHECK_EQ(row_block->row_count(), 1); |
202 | 0 | const QLRow& sum_1_row = row_block->row(0); |
203 | 0 | CHECK_EQ(sum_1_row.column(0).int64_value(), 11); |
204 | 0 | CHECK_EQ(sum_1_row.column(1).int32_value(), 12); |
205 | 0 | CHECK_EQ(sum_1_row.column(2).int16_value(), 13); |
206 | 0 | CHECK_EQ(sum_1_row.column(3).int8_value(), 14); |
207 | 0 | CHECK_EQ(sum_1_row.column(4).float_value(), 15); |
208 | 0 | CHECK_EQ(sum_1_row.column(5).double_value(), 16); |
209 | | |
210 | | // Test SUM() - Where condition provides full hash key. |
211 | 0 | CHECK_VALID_STMT("SELECT sum(v1), sum(v2), sum(v3), sum(v4), sum(v5), sum(v6)" |
212 | 0 | " FROM test_aggr_expr WHERE h = 1;"); |
213 | 0 | row_block = processor->row_block(); |
214 | 0 | CHECK_EQ(row_block->row_count(), 1); |
215 | 0 | const QLRow& sum_2_row = row_block->row(0); |
216 | 0 | CHECK_EQ(sum_2_row.column(0).int64_value(), 1012); |
217 | 0 | CHECK_EQ(sum_2_row.column(1).int32_value(), 113); |
218 | 0 | CHECK_EQ(sum_2_row.column(2).int16_value(), 24); |
219 | 0 | CHECK_EQ(sum_2_row.column(3).int8_value(), 15); |
220 | | // Comparing floating point for 93.77 |
221 | 0 | CHECK_GT(sum_2_row.column(4).float_value(), 93.765); |
222 | 0 | CHECK_LT(sum_2_row.column(4).float_value(), 93.775); |
223 | | // Comparing floating point for 1016.99 |
224 | 0 | CHECK_GT(sum_2_row.column(5).double_value(), 1016.985); |
225 | 0 | CHECK_LT(sum_2_row.column(5).double_value(), 1016.995); |
226 | | |
227 | | // Test SUM() - All rows. |
228 | 0 | CHECK_VALID_STMT("SELECT sum(v1), sum(v2), sum(v3), sum(v4), sum(v5), sum(v6)" |
229 | 0 | " FROM test_aggr_expr;"); |
230 | 0 | row_block = processor->row_block(); |
231 | 0 | CHECK_EQ(row_block->row_count(), 1); |
232 | 0 | const QLRow& sum_all_row = row_block->row(0); |
233 | 0 | CHECK_EQ(sum_all_row.column(0).int64_value(), v1_total); |
234 | 0 | CHECK_EQ(sum_all_row.column(1).int32_value(), v2_total); |
235 | 0 | CHECK_EQ(sum_all_row.column(2).int16_value(), v3_total); |
236 | 0 | CHECK_EQ(sum_all_row.column(3).int8_value(), v4_total); |
237 | 0 | CHECK_GT(sum_all_row.column(4).float_value(), v5_total - 0.1); |
238 | 0 | CHECK_LT(sum_all_row.column(4).float_value(), v5_total + 0.1); |
239 | 0 | CHECK_GT(sum_all_row.column(5).double_value(), v6_total - 0.1); |
240 | 0 | CHECK_LT(sum_all_row.column(5).double_value(), v6_total + 0.1); |
241 | 0 | } |
242 | | |
243 | | //------------------------------------------------------------------------------------------------ |
244 | | // Test MAX() aggregate functions. |
245 | 0 | { |
246 | | // Test MAX() - Not exist. |
247 | 0 | CHECK_VALID_STMT("SELECT max(v1), max(v2), max(v3), max(v4), max(v5), max(v6)" |
248 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 1;"); |
249 | 0 | row_block = processor->row_block(); |
250 | 0 | CHECK_EQ(row_block->row_count(), 1); |
251 | 0 | const QLRow& sum_0_row = row_block->row(0); |
252 | 0 | CHECK(sum_0_row.column(0).IsNull()); |
253 | 0 | CHECK(sum_0_row.column(1).IsNull()); |
254 | 0 | CHECK(sum_0_row.column(2).IsNull()); |
255 | 0 | CHECK(sum_0_row.column(3).IsNull()); |
256 | 0 | CHECK(sum_0_row.column(4).IsNull()); |
257 | 0 | CHECK(sum_0_row.column(5).IsNull()); |
258 | | |
259 | | // Test MAX() - Where condition provides full primary key. |
260 | 0 | CHECK_VALID_STMT("SELECT max(v1), max(v2), max(v3), max(v4), max(v5), max(v6)" |
261 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 777;"); |
262 | 0 | row_block = processor->row_block(); |
263 | 0 | CHECK_EQ(row_block->row_count(), 1); |
264 | 0 | const QLRow& sum_1_row = row_block->row(0); |
265 | 0 | CHECK_EQ(sum_1_row.column(0).int64_value(), 11); |
266 | 0 | CHECK_EQ(sum_1_row.column(1).int32_value(), 12); |
267 | 0 | CHECK_EQ(sum_1_row.column(2).int16_value(), 13); |
268 | 0 | CHECK_EQ(sum_1_row.column(3).int8_value(), 14); |
269 | 0 | CHECK_EQ(sum_1_row.column(4).float_value(), 15); |
270 | 0 | CHECK_EQ(sum_1_row.column(5).double_value(), 16); |
271 | | |
272 | | // Test MAX() - Where condition provides full hash key. |
273 | 0 | CHECK_VALID_STMT("SELECT max(v1), max(v2), max(v3), max(v4), max(v5), max(v6)" |
274 | 0 | " FROM test_aggr_expr WHERE h = 1;"); |
275 | 0 | row_block = processor->row_block(); |
276 | 0 | CHECK_EQ(row_block->row_count(), 1); |
277 | 0 | const QLRow& sum_2_row = row_block->row(0); |
278 | 0 | CHECK_EQ(sum_2_row.column(0).int64_value(), 1001); |
279 | 0 | CHECK_EQ(sum_2_row.column(1).int32_value(), 101); |
280 | 0 | CHECK_EQ(sum_2_row.column(2).int16_value(), 13); |
281 | 0 | CHECK_EQ(sum_2_row.column(3).int8_value(), 14); |
282 | | // Comparing floating point for 78.77 |
283 | 0 | CHECK_GT(sum_2_row.column(4).float_value(), 78.765); |
284 | 0 | CHECK_LT(sum_2_row.column(4).float_value(), 78.775); |
285 | | // Comparing floating point for 1000.99 |
286 | 0 | CHECK_GT(sum_2_row.column(5).double_value(), 1000.985); |
287 | 0 | CHECK_LT(sum_2_row.column(5).double_value(), 1000.995); |
288 | | |
289 | | // Test MAX() - All rows. |
290 | 0 | CHECK_VALID_STMT("SELECT max(v1), max(v2), max(v3), max(v4), max(v5), max(v6)" |
291 | 0 | " FROM test_aggr_expr;"); |
292 | 0 | row_block = processor->row_block(); |
293 | 0 | CHECK_EQ(row_block->row_count(), 1); |
294 | 0 | const QLRow& sum_all_row = row_block->row(0); |
295 | 0 | CHECK_EQ(sum_all_row.column(0).int64_value(), 1019); |
296 | 0 | CHECK_EQ(sum_all_row.column(1).int32_value(), 119); |
297 | 0 | CHECK_EQ(sum_all_row.column(2).int16_value(), 29); |
298 | 0 | CHECK_EQ(sum_all_row.column(3).int8_value(), 19); |
299 | 0 | float v5_max = 96.77; |
300 | 0 | CHECK_GT(sum_all_row.column(4).float_value(), v5_max - 0.1); |
301 | 0 | CHECK_LT(sum_all_row.column(4).float_value(), v5_max + 0.1); |
302 | 0 | double v6_max = 1018.99; |
303 | 0 | CHECK_GT(sum_all_row.column(5).double_value(), v6_max - 0.1); |
304 | 0 | CHECK_LT(sum_all_row.column(5).double_value(), v6_max + 0.1); |
305 | 0 | } |
306 | | |
307 | | //------------------------------------------------------------------------------------------------ |
308 | | // Test MIN() aggregate functions. |
309 | 0 | { |
310 | | // Test MIN() - Not exist. |
311 | 0 | CHECK_VALID_STMT("SELECT min(v1), min(v2), min(v3), min(v4), min(v5), min(v6)" |
312 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 1;"); |
313 | 0 | row_block = processor->row_block(); |
314 | 0 | CHECK_EQ(row_block->row_count(), 1); |
315 | 0 | const QLRow& sum_0_row = row_block->row(0); |
316 | 0 | CHECK(sum_0_row.column(0).IsNull()); |
317 | 0 | CHECK(sum_0_row.column(1).IsNull()); |
318 | 0 | CHECK(sum_0_row.column(2).IsNull()); |
319 | 0 | CHECK(sum_0_row.column(3).IsNull()); |
320 | 0 | CHECK(sum_0_row.column(4).IsNull()); |
321 | 0 | CHECK(sum_0_row.column(5).IsNull()); |
322 | | |
323 | | // Test MIN() - Where condition provides full primary key. |
324 | 0 | CHECK_VALID_STMT("SELECT min(v1), min(v2), min(v3), min(v4), min(v5), min(v6)" |
325 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 777;"); |
326 | 0 | row_block = processor->row_block(); |
327 | 0 | CHECK_EQ(row_block->row_count(), 1); |
328 | 0 | const QLRow& sum_1_row = row_block->row(0); |
329 | 0 | CHECK_EQ(sum_1_row.column(0).int64_value(), 11); |
330 | 0 | CHECK_EQ(sum_1_row.column(1).int32_value(), 12); |
331 | 0 | CHECK_EQ(sum_1_row.column(2).int16_value(), 13); |
332 | 0 | CHECK_EQ(sum_1_row.column(3).int8_value(), 14); |
333 | 0 | CHECK_EQ(sum_1_row.column(4).float_value(), 15); |
334 | 0 | CHECK_EQ(sum_1_row.column(5).double_value(), 16); |
335 | | |
336 | | // Test MIN() - Where condition provides full hash key. |
337 | 0 | CHECK_VALID_STMT("SELECT min(v1), min(v2), min(v3), min(v4), min(v5), min(v6)" |
338 | 0 | " FROM test_aggr_expr WHERE h = 1;"); |
339 | 0 | row_block = processor->row_block(); |
340 | 0 | CHECK_EQ(row_block->row_count(), 1); |
341 | 0 | const QLRow& sum_2_row = row_block->row(0); |
342 | 0 | CHECK_EQ(sum_2_row.column(0).int64_value(), 11); |
343 | 0 | CHECK_EQ(sum_2_row.column(1).int32_value(), 12); |
344 | 0 | CHECK_EQ(sum_2_row.column(2).int16_value(), 11); |
345 | 0 | CHECK_EQ(sum_2_row.column(3).int8_value(), 1); |
346 | | // Comparing floating point for 15 |
347 | 0 | CHECK_GT(sum_2_row.column(4).float_value(), 14.9); |
348 | 0 | CHECK_LT(sum_2_row.column(4).float_value(), 15.1); |
349 | | // Comparing floating point for 16 |
350 | 0 | CHECK_GT(sum_2_row.column(5).double_value(), 15.9); |
351 | 0 | CHECK_LT(sum_2_row.column(5).double_value(), 16.1); |
352 | | |
353 | | // Test MIN() - All rows. |
354 | 0 | CHECK_VALID_STMT("SELECT min(v1), min(v2), min(v3), min(v4), min(v5), min(v6)" |
355 | 0 | " FROM test_aggr_expr;"); |
356 | 0 | row_block = processor->row_block(); |
357 | 0 | CHECK_EQ(row_block->row_count(), 1); |
358 | 0 | const QLRow& sum_all_row = row_block->row(0); |
359 | 0 | CHECK_EQ(sum_all_row.column(0).int64_value(), 11); |
360 | 0 | CHECK_EQ(sum_all_row.column(1).int32_value(), 12); |
361 | 0 | CHECK_EQ(sum_all_row.column(2).int16_value(), 11); |
362 | 0 | CHECK_EQ(sum_all_row.column(3).int8_value(), 1); |
363 | 0 | float v5_min = 15; |
364 | 0 | CHECK_GT(sum_all_row.column(4).float_value(), v5_min - 0.1); |
365 | 0 | CHECK_LT(sum_all_row.column(4).float_value(), v5_min + 0.1); |
366 | 0 | double v6_min = 16; |
367 | 0 | CHECK_GT(sum_all_row.column(5).double_value(), v6_min - 0.1); |
368 | 0 | CHECK_LT(sum_all_row.column(5).double_value(), v6_min + 0.1); |
369 | 0 | } |
370 | 0 | } |
371 | | |
372 | 0 | TEST_F(QLTestSelectedExpr, TestAggregateExprWithNull) { |
373 | | // Init the simulated cluster. |
374 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
375 | | |
376 | | // Get a processor. |
377 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
378 | 0 | LOG(INFO) << "Test selecting numeric expressions with NULL column 'v2'."; |
379 | | |
380 | | // Create the table and insert some value. |
381 | 0 | const char *create_stmt = |
382 | 0 | "CREATE TABLE test_aggr_expr(h int, r int," |
383 | 0 | " v1 bigint, v2 int, v3 smallint, v4 tinyint," |
384 | 0 | " v5 float, v6 double, v7 text, primary key(h, r));"; |
385 | 0 | CHECK_VALID_STMT(create_stmt); |
386 | | |
387 | | // Insert rows whose hash value is '1'. |
388 | | // v2 = NULL - for all, v1 = NULL - first only, v7 = NULL - except first & second, |
389 | | // v3,v4,v5,v6 = NULL second only. |
390 | 0 | CHECK_VALID_STMT("INSERT INTO test_aggr_expr(h, r, v3, v4, v5, v6, v7)" // v1, v2 = NULL |
391 | 0 | " VALUES(1, 777, 13, 14, 15, 16, 'aaa');"); |
392 | 0 | CHECK_VALID_STMT("INSERT INTO test_aggr_expr(h, r, v1, v7)" // v2, v3, v4, v5, v6 = NULL |
393 | 0 | " VALUES(1, 888, 11, 'bbb');"); |
394 | | |
395 | | // Insert the rest of the rows, one of which has hash value of '1'. |
396 | 0 | int64_t v1_total = 11; |
397 | 0 | int16_t v3_total = 13; |
398 | 0 | int8_t v4_total = 14; |
399 | 0 | float v5_total = 15; |
400 | 0 | double v6_total = 16; |
401 | 0 | for (int i = 1; i < 20; i++) { |
402 | 0 | string stmt = strings::Substitute( |
403 | 0 | "INSERT INTO test_aggr_expr(h, r, v1, v3, v4, v5, v6)" // v2, v7 = NULL |
404 | 0 | " VALUES($0, $1, $2, $3, $4, $5, $6);", |
405 | 0 | i, i + 1, i + 1000, i + 10, i, i + 77.77, i + 999.99); |
406 | 0 | CHECK_VALID_STMT(stmt); |
407 | |
|
408 | 0 | v1_total += (i + 1000); |
409 | 0 | v3_total += (i + 10); |
410 | 0 | v4_total += i; |
411 | 0 | v5_total += (i + 77.77); |
412 | 0 | v6_total += (i + 999.99); |
413 | 0 | } |
414 | |
|
415 | 0 | std::shared_ptr<QLRowBlock> row_block; |
416 | | |
417 | | //------------------------------------------------------------------------------------------------ |
418 | | // Test COUNT() aggregate function. |
419 | 0 | { |
420 | | // Test COUNT() - Not existing data. |
421 | 0 | CHECK_VALID_STMT("SELECT count(*), count(h), count(r), count(v1), count(v2), count(v7)" |
422 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 1;"); |
423 | 0 | row_block = processor->row_block(); |
424 | 0 | CHECK_EQ(row_block->row_count(), 1); |
425 | 0 | const QLRow& sum_0_row = row_block->row(0); |
426 | 0 | CHECK_EQ(sum_0_row.column(0).int64_value(), 0); |
427 | 0 | CHECK_EQ(sum_0_row.column(1).int64_value(), 0); |
428 | 0 | CHECK_EQ(sum_0_row.column(2).int64_value(), 0); |
429 | 0 | CHECK_EQ(sum_0_row.column(3).int64_value(), 0); |
430 | 0 | CHECK_EQ(sum_0_row.column(4).int64_value(), 0); |
431 | 0 | CHECK_EQ(sum_0_row.column(5).int64_value(), 0); |
432 | | |
433 | | // Test COUNT() - Where condition provides full primary key. |
434 | 0 | CHECK_VALID_STMT("SELECT count(*), count(h), count(r), count(v1), count(v2), count(v7)" |
435 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 777;"); |
436 | 0 | row_block = processor->row_block(); |
437 | 0 | CHECK_EQ(row_block->row_count(), 1); |
438 | 0 | const QLRow& sum_1_row = row_block->row(0); |
439 | 0 | CHECK_EQ(sum_1_row.column(0).int64_value(), 1); |
440 | 0 | CHECK_EQ(sum_1_row.column(1).int64_value(), 1); |
441 | 0 | CHECK_EQ(sum_1_row.column(2).int64_value(), 1); |
442 | 0 | CHECK_EQ(sum_1_row.column(3).int64_value(), 0); // NULL values are not counted. |
443 | 0 | CHECK_EQ(sum_1_row.column(4).int64_value(), 0); // NULL values are not counted. |
444 | 0 | CHECK_EQ(sum_1_row.column(5).int64_value(), 1); |
445 | | |
446 | | // Test COUNT() - Where condition provides full hash key. |
447 | 0 | CHECK_VALID_STMT("SELECT count(*), count(h), count(r), count(v1), count(v2), count(v7)" |
448 | 0 | " FROM test_aggr_expr WHERE h = 1;"); |
449 | 0 | row_block = processor->row_block(); |
450 | 0 | CHECK_EQ(row_block->row_count(), 1); |
451 | 0 | const QLRow& sum_2_row = row_block->row(0); |
452 | 0 | CHECK_EQ(sum_2_row.column(0).int64_value(), 3); |
453 | 0 | CHECK_EQ(sum_2_row.column(1).int64_value(), 3); |
454 | 0 | CHECK_EQ(sum_2_row.column(2).int64_value(), 3); |
455 | 0 | CHECK_EQ(sum_2_row.column(3).int64_value(), 2); |
456 | 0 | CHECK_EQ(sum_2_row.column(4).int64_value(), 0); // NULL values are not counted. |
457 | 0 | CHECK_EQ(sum_2_row.column(5).int64_value(), 2); |
458 | | |
459 | | // Test COUNT() - All rows. |
460 | 0 | CHECK_VALID_STMT("SELECT count(*), count(h), count(r), count(v1), count(v2), count(v7)" |
461 | 0 | " FROM test_aggr_expr;"); |
462 | 0 | row_block = processor->row_block(); |
463 | 0 | CHECK_EQ(row_block->row_count(), 1); |
464 | 0 | const QLRow& sum_all_row = row_block->row(0); |
465 | 0 | CHECK_EQ(sum_all_row.column(0).int64_value(), 21); |
466 | 0 | CHECK_EQ(sum_all_row.column(1).int64_value(), 21); |
467 | 0 | CHECK_EQ(sum_all_row.column(2).int64_value(), 21); |
468 | 0 | CHECK_EQ(sum_all_row.column(3).int64_value(), 20); |
469 | 0 | CHECK_EQ(sum_all_row.column(4).int64_value(), 0); // NULL values are not counted. |
470 | 0 | CHECK_EQ(sum_all_row.column(5).int64_value(), 2); |
471 | 0 | } |
472 | | |
473 | | //------------------------------------------------------------------------------------------------ |
474 | | // Test SUM() aggregate function. NOTE: SUM(v7) - is not applicable for TEXT type. |
475 | 0 | { |
476 | | // Test SUM() - Not existing data. |
477 | 0 | CHECK_VALID_STMT("SELECT sum(v1), sum(v2), sum(v3), sum(v4), sum(v5), sum(v6)" |
478 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 1;"); |
479 | 0 | row_block = processor->row_block(); |
480 | 0 | CHECK_EQ(row_block->row_count(), 1); |
481 | 0 | const QLRow& sum_0_row = row_block->row(0); |
482 | 0 | CHECK_EQ(sum_0_row.column(0).int64_value(), 0); |
483 | 0 | CHECK_EQ(sum_0_row.column(1).int32_value(), 0); |
484 | 0 | CHECK_EQ(sum_0_row.column(2).int16_value(), 0); |
485 | 0 | CHECK_EQ(sum_0_row.column(3).int8_value(), 0); |
486 | 0 | CHECK_EQ(sum_0_row.column(4).float_value(), 0); |
487 | 0 | CHECK_EQ(sum_0_row.column(5).double_value(), 0); |
488 | | |
489 | | // Test SUM() - Where condition provides full primary key. |
490 | 0 | CHECK_VALID_STMT("SELECT sum(v1), sum(v2), sum(v3), sum(v4), sum(v5), sum(v6)" |
491 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 777;"); |
492 | 0 | row_block = processor->row_block(); |
493 | 0 | CHECK_EQ(row_block->row_count(), 1); |
494 | 0 | const QLRow& sum_1_row = row_block->row(0); |
495 | 0 | CHECK_EQ(sum_1_row.column(0).int64_value(), 0); // Only one NULL value. |
496 | 0 | CHECK_EQ(sum_1_row.column(1).int32_value(), 0); // NULL values are not counted. |
497 | 0 | CHECK_EQ(sum_1_row.column(2).int16_value(), 13); |
498 | 0 | CHECK_EQ(sum_1_row.column(3).int8_value(), 14); |
499 | 0 | CHECK_EQ(sum_1_row.column(4).float_value(), 15); |
500 | 0 | CHECK_EQ(sum_1_row.column(5).double_value(), 16); |
501 | | |
502 | | // Test SUM() - Where condition provides full hash key. |
503 | 0 | CHECK_VALID_STMT("SELECT sum(v1), sum(v2), sum(v3), sum(v4), sum(v5), sum(v6)" |
504 | 0 | " FROM test_aggr_expr WHERE h = 1;"); |
505 | 0 | row_block = processor->row_block(); |
506 | 0 | CHECK_EQ(row_block->row_count(), 1); |
507 | 0 | const QLRow& sum_2_row = row_block->row(0); |
508 | 0 | CHECK_EQ(sum_2_row.column(0).int64_value(), 1012); |
509 | 0 | CHECK_EQ(sum_2_row.column(1).int32_value(), 0); // NULL values are not counted. |
510 | 0 | CHECK_EQ(sum_2_row.column(2).int16_value(), 24); |
511 | 0 | CHECK_EQ(sum_2_row.column(3).int8_value(), 15); |
512 | | // Comparing floating point for 93.77 |
513 | 0 | CHECK_GT(sum_2_row.column(4).float_value(), 93.765); |
514 | 0 | CHECK_LT(sum_2_row.column(4).float_value(), 93.775); |
515 | | // Comparing floating point for 1016.99 |
516 | 0 | CHECK_GT(sum_2_row.column(5).double_value(), 1016.985); |
517 | 0 | CHECK_LT(sum_2_row.column(5).double_value(), 1016.995); |
518 | | |
519 | | // Test SUM() - All rows. |
520 | 0 | CHECK_VALID_STMT("SELECT sum(v1), sum(v2), sum(v3), sum(v4), sum(v5), sum(v6)" |
521 | 0 | " FROM test_aggr_expr;"); |
522 | 0 | row_block = processor->row_block(); |
523 | 0 | CHECK_EQ(row_block->row_count(), 1); |
524 | 0 | const QLRow& sum_all_row = row_block->row(0); |
525 | 0 | CHECK_EQ(sum_all_row.column(0).int64_value(), v1_total); |
526 | 0 | CHECK_EQ(sum_all_row.column(1).int32_value(), 0); // NULL values are not counted. |
527 | 0 | CHECK_EQ(sum_all_row.column(2).int16_value(), v3_total); |
528 | 0 | CHECK_EQ(sum_all_row.column(3).int8_value(), v4_total); |
529 | 0 | CHECK_GT(sum_all_row.column(4).float_value(), v5_total - 0.1); |
530 | 0 | CHECK_LT(sum_all_row.column(4).float_value(), v5_total + 0.1); |
531 | 0 | CHECK_GT(sum_all_row.column(5).double_value(), v6_total - 0.1); |
532 | 0 | CHECK_LT(sum_all_row.column(5).double_value(), v6_total + 0.1); |
533 | 0 | } |
534 | | |
535 | | //------------------------------------------------------------------------------------------------ |
536 | | // Test MAX() aggregate functions. |
537 | 0 | { |
538 | | // Test MAX() - Not exist. |
539 | 0 | CHECK_VALID_STMT("SELECT max(v1), max(v2), max(v3), max(v4), max(v5), max(v6), max(v7)" |
540 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 1;"); |
541 | 0 | row_block = processor->row_block(); |
542 | 0 | CHECK_EQ(row_block->row_count(), 1); |
543 | 0 | const QLRow& sum_0_row = row_block->row(0); |
544 | 0 | CHECK(sum_0_row.column(0).IsNull()); |
545 | 0 | CHECK(sum_0_row.column(1).IsNull()); |
546 | 0 | CHECK(sum_0_row.column(2).IsNull()); |
547 | 0 | CHECK(sum_0_row.column(3).IsNull()); |
548 | 0 | CHECK(sum_0_row.column(4).IsNull()); |
549 | 0 | CHECK(sum_0_row.column(5).IsNull()); |
550 | 0 | CHECK(sum_0_row.column(6).IsNull()); |
551 | | |
552 | | // Test MAX() - Where condition provides full primary key. |
553 | 0 | CHECK_VALID_STMT("SELECT max(v1), max(v2), max(v3), max(v4), max(v5), max(v6), max(v7)" |
554 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 777;"); |
555 | 0 | row_block = processor->row_block(); |
556 | 0 | CHECK_EQ(row_block->row_count(), 1); |
557 | 0 | const QLRow& sum_1_row = row_block->row(0); |
558 | 0 | CHECK(sum_1_row.column(0).IsNull()); // NULL value. |
559 | 0 | CHECK(sum_1_row.column(1).IsNull()); // NULL values. |
560 | 0 | CHECK_EQ(sum_1_row.column(2).int16_value(), 13); |
561 | 0 | CHECK_EQ(sum_1_row.column(3).int8_value(), 14); |
562 | 0 | CHECK_EQ(sum_1_row.column(4).float_value(), 15); |
563 | 0 | CHECK_EQ(sum_1_row.column(5).double_value(), 16); |
564 | 0 | CHECK_EQ(sum_1_row.column(6).string_value(), "aaa"); |
565 | | |
566 | | // Test MAX() - Where condition provides full hash key. |
567 | 0 | CHECK_VALID_STMT("SELECT max(v1), max(v2), max(v3), max(v4), max(v5), max(v6), max(v7)" |
568 | 0 | " FROM test_aggr_expr WHERE h = 1;"); |
569 | 0 | row_block = processor->row_block(); |
570 | 0 | CHECK_EQ(row_block->row_count(), 1); |
571 | 0 | const QLRow& sum_2_row = row_block->row(0); |
572 | 0 | CHECK_EQ(sum_2_row.column(0).int64_value(), 1001); |
573 | 0 | CHECK(sum_2_row.column(1).IsNull()); // NULL values. |
574 | 0 | CHECK_EQ(sum_2_row.column(2).int16_value(), 13); |
575 | 0 | CHECK_EQ(sum_2_row.column(3).int8_value(), 14); |
576 | | // Comparing floating point for 78.77 |
577 | 0 | CHECK_GT(sum_2_row.column(4).float_value(), 78.765); |
578 | 0 | CHECK_LT(sum_2_row.column(4).float_value(), 78.775); |
579 | | // Comparing floating point for 1000.99 |
580 | 0 | CHECK_GT(sum_2_row.column(5).double_value(), 1000.985); |
581 | 0 | CHECK_LT(sum_2_row.column(5).double_value(), 1000.995); |
582 | 0 | CHECK_EQ(sum_2_row.column(6).string_value(), "bbb"); |
583 | | |
584 | | // Test MAX() - All rows. |
585 | 0 | CHECK_VALID_STMT("SELECT max(v1), max(v2), max(v3), max(v4), max(v5), max(v6), max(v7)" |
586 | 0 | " FROM test_aggr_expr;"); |
587 | 0 | row_block = processor->row_block(); |
588 | 0 | CHECK_EQ(row_block->row_count(), 1); |
589 | 0 | const QLRow& sum_all_row = row_block->row(0); |
590 | 0 | CHECK_EQ(sum_all_row.column(0).int64_value(), 1019); |
591 | 0 | CHECK(sum_all_row.column(1).IsNull()); // NULL values. |
592 | 0 | CHECK_EQ(sum_all_row.column(2).int16_value(), 29); |
593 | 0 | CHECK_EQ(sum_all_row.column(3).int8_value(), 19); |
594 | 0 | float v5_max = 96.77; |
595 | 0 | CHECK_GT(sum_all_row.column(4).float_value(), v5_max - 0.1); |
596 | 0 | CHECK_LT(sum_all_row.column(4).float_value(), v5_max + 0.1); |
597 | 0 | double v6_max = 1018.99; |
598 | 0 | CHECK_GT(sum_all_row.column(5).double_value(), v6_max - 0.1); |
599 | 0 | CHECK_LT(sum_all_row.column(5).double_value(), v6_max + 0.1); |
600 | 0 | CHECK_EQ(sum_all_row.column(6).string_value(), "bbb"); |
601 | 0 | } |
602 | | |
603 | | //------------------------------------------------------------------------------------------------ |
604 | | // Test MIN() aggregate functions. |
605 | 0 | { |
606 | | // Test MIN() - Not exist. |
607 | 0 | CHECK_VALID_STMT("SELECT min(v1), min(v2), min(v3), min(v4), min(v5), min(v6), min(v7)" |
608 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 1;"); |
609 | 0 | row_block = processor->row_block(); |
610 | 0 | CHECK_EQ(row_block->row_count(), 1); |
611 | 0 | const QLRow& sum_0_row = row_block->row(0); |
612 | 0 | CHECK(sum_0_row.column(0).IsNull()); |
613 | 0 | CHECK(sum_0_row.column(1).IsNull()); |
614 | 0 | CHECK(sum_0_row.column(2).IsNull()); |
615 | 0 | CHECK(sum_0_row.column(3).IsNull()); |
616 | 0 | CHECK(sum_0_row.column(4).IsNull()); |
617 | 0 | CHECK(sum_0_row.column(5).IsNull()); |
618 | 0 | CHECK(sum_0_row.column(6).IsNull()); |
619 | | |
620 | | // Test MIN() - Where condition provides full primary key. |
621 | 0 | CHECK_VALID_STMT("SELECT min(v1), min(v2), min(v3), min(v4), min(v5), min(v6), min(v7)" |
622 | 0 | " FROM test_aggr_expr WHERE h = 1 AND r = 777;"); |
623 | 0 | row_block = processor->row_block(); |
624 | 0 | CHECK_EQ(row_block->row_count(), 1); |
625 | 0 | const QLRow& sum_1_row = row_block->row(0); |
626 | 0 | CHECK(sum_1_row.column(0).IsNull()); // NULL value. |
627 | 0 | CHECK(sum_1_row.column(1).IsNull()); // NULL values. |
628 | 0 | CHECK_EQ(sum_1_row.column(2).int16_value(), 13); |
629 | 0 | CHECK_EQ(sum_1_row.column(3).int8_value(), 14); |
630 | 0 | CHECK_EQ(sum_1_row.column(4).float_value(), 15); |
631 | 0 | CHECK_EQ(sum_1_row.column(5).double_value(), 16); |
632 | 0 | CHECK_EQ(sum_1_row.column(6).string_value(), "aaa"); |
633 | | |
634 | | // Test MIN() - Where condition provides full hash key. |
635 | 0 | CHECK_VALID_STMT("SELECT min(v1), min(v2), min(v3), min(v4), min(v5), min(v6), min(v7)" |
636 | 0 | " FROM test_aggr_expr WHERE h = 1;"); |
637 | 0 | row_block = processor->row_block(); |
638 | 0 | CHECK_EQ(row_block->row_count(), 1); |
639 | 0 | const QLRow& sum_2_row = row_block->row(0); |
640 | 0 | CHECK_EQ(sum_2_row.column(0).int64_value(), 11); |
641 | 0 | CHECK(sum_2_row.column(1).IsNull()); // NULL values. |
642 | 0 | CHECK_EQ(sum_2_row.column(2).int16_value(), 11); |
643 | 0 | CHECK_EQ(sum_2_row.column(3).int8_value(), 1); |
644 | | // Comparing floating point for 15 |
645 | 0 | CHECK_GT(sum_2_row.column(4).float_value(), 14.9); |
646 | 0 | CHECK_LT(sum_2_row.column(4).float_value(), 15.1); |
647 | | // Comparing floating point for 16 |
648 | 0 | CHECK_GT(sum_2_row.column(5).double_value(), 15.9); |
649 | 0 | CHECK_LT(sum_2_row.column(5).double_value(), 16.1); |
650 | 0 | CHECK_EQ(sum_2_row.column(6).string_value(), "aaa"); |
651 | | |
652 | | // Test MIN() - All rows. |
653 | 0 | CHECK_VALID_STMT("SELECT min(v1), min(v2), min(v3), min(v4), min(v5), min(v6), min(v7)" |
654 | 0 | " FROM test_aggr_expr;"); |
655 | 0 | row_block = processor->row_block(); |
656 | 0 | CHECK_EQ(row_block->row_count(), 1); |
657 | 0 | const QLRow& sum_all_row = row_block->row(0); |
658 | 0 | CHECK_EQ(sum_all_row.column(0).int64_value(), 11); |
659 | 0 | CHECK(sum_all_row.column(1).IsNull()); // NULL values. |
660 | 0 | CHECK_EQ(sum_all_row.column(2).int16_value(), 11); |
661 | 0 | CHECK_EQ(sum_all_row.column(3).int8_value(), 1); |
662 | 0 | float v5_min = 15; |
663 | 0 | CHECK_GT(sum_all_row.column(4).float_value(), v5_min - 0.1); |
664 | 0 | CHECK_LT(sum_all_row.column(4).float_value(), v5_min + 0.1); |
665 | 0 | double v6_min = 16; |
666 | 0 | CHECK_GT(sum_all_row.column(5).double_value(), v6_min - 0.1); |
667 | 0 | CHECK_LT(sum_all_row.column(5).double_value(), v6_min + 0.1); |
668 | 0 | CHECK_EQ(sum_all_row.column(6).string_value(), "aaa"); |
669 | 0 | } |
670 | 0 | } |
671 | | |
672 | 0 | TEST_F(QLTestSelectedExpr, TestQLSelectNumericExpr) { |
673 | | // Init the simulated cluster. |
674 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
675 | | |
676 | | // Get a processor. |
677 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
678 | 0 | LOG(INFO) << "Test selecting numeric expressions."; |
679 | | |
680 | | // Create the table and insert some value. |
681 | 0 | const char *create_stmt = |
682 | 0 | "CREATE TABLE test_numeric_expr(h1 int primary key," |
683 | 0 | " v1 bigint, v2 int, v3 smallint, v4 tinyint," |
684 | 0 | " v5 float, v6 double);"; |
685 | 0 | CHECK_VALID_STMT(create_stmt); |
686 | 0 | CHECK_VALID_STMT("INSERT INTO test_numeric_expr(h1, v1, v2, v3, v4, v5, v6)" |
687 | 0 | " VALUES(1, 11, 12, 13, 14, 15, 16);"); |
688 | | |
689 | | // Select TTL and WRITETIME. |
690 | | // - TTL and WRITETIME are not suppported for primary column. |
691 | 0 | CHECK_INVALID_STMT("SELECT TTL(h1) FROM test_numeric_expr WHERE h1 = 1;"); |
692 | 0 | CHECK_INVALID_STMT("SELECT WRITETIME(h1) FROM test_numeric_expr WHERE h1 = 1;"); |
693 | | |
694 | | // Test various select. |
695 | 0 | std::shared_ptr<QLRowBlock> row_block; |
696 | | |
697 | | // Select '*'. |
698 | 0 | CHECK_VALID_STMT("SELECT * FROM test_numeric_expr WHERE h1 = 1;"); |
699 | 0 | row_block = processor->row_block(); |
700 | 0 | CHECK_EQ(row_block->row_count(), 1); |
701 | 0 | const QLRow& star_row = row_block->row(0); |
702 | 0 | CHECK_EQ(star_row.column(0).int32_value(), 1); |
703 | 0 | CHECK_EQ(star_row.column(1).int64_value(), 11); |
704 | 0 | CHECK_EQ(star_row.column(2).int32_value(), 12); |
705 | 0 | CHECK_EQ(star_row.column(3).int16_value(), 13); |
706 | 0 | CHECK_EQ(star_row.column(4).int8_value(), 14); |
707 | 0 | CHECK_EQ(star_row.column(5).float_value(), 15); |
708 | 0 | CHECK_EQ(star_row.column(6).double_value(), 16); |
709 | | |
710 | | // Select expressions. |
711 | 0 | CHECK_VALID_STMT("SELECT h1, v1+1, v2+2, v3+3, v4+4, v5+5, v6+6 " |
712 | 0 | "FROM test_numeric_expr WHERE h1 = 1;"); |
713 | 0 | row_block = processor->row_block(); |
714 | 0 | CHECK_EQ(row_block->row_count(), 1); |
715 | 0 | const QLRow& expr_row = row_block->row(0); |
716 | 0 | CHECK_EQ(expr_row.column(0).int32_value(), 1); |
717 | 0 | CHECK_EQ(expr_row.column(1).int64_value(), 12); |
718 | 0 | CHECK_EQ(expr_row.column(2).int64_value(), 14); |
719 | 0 | CHECK_EQ(expr_row.column(3).int64_value(), 16); |
720 | 0 | CHECK_EQ(expr_row.column(4).int64_value(), 18); |
721 | 0 | CHECK_EQ(expr_row.column(5).double_value(), 20); |
722 | 0 | CHECK_EQ(expr_row.column(6).double_value(), 22); |
723 | | |
724 | | // Select with alias. |
725 | 0 | CHECK_VALID_STMT("SELECT v1+1 as one, TTL(v2) as two FROM test_numeric_expr WHERE h1 = 1;"); |
726 | 0 | row_block = processor->row_block(); |
727 | 0 | CHECK_EQ(row_block->row_count(), 1); |
728 | 0 | const QLRow& expr_alias_row = row_block->row(0); |
729 | 0 | CHECK_EQ(expr_alias_row.column(0).int64_value(), 12); |
730 | 0 | CHECK(expr_alias_row.column(1).IsNull()); |
731 | 0 | } |
732 | | |
733 | 0 | TEST_F(QLTestSelectedExpr, TestQLSelectToken) { |
734 | | // Init the simulated cluster. |
735 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
736 | | |
737 | | // Get a processor. |
738 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
739 | 0 | LOG(INFO) << "Test selecting numeric expressions."; |
740 | | |
741 | | // Create the table and insert some value. |
742 | 0 | const char *create_stmt = |
743 | 0 | "CREATE TABLE test_select_token(h1 int, h2 double, h3 text, " |
744 | 0 | " r int, v int, primary key ((h1, h2, h3), r));"; |
745 | |
|
746 | 0 | CHECK_VALID_STMT(create_stmt); |
747 | |
|
748 | 0 | CHECK_VALID_STMT("INSERT INTO test_select_token(h1, h2, h3, r, v) VALUES (1, 2.0, 'a', 1, 1)"); |
749 | 0 | CHECK_VALID_STMT("INSERT INTO test_select_token(h1, h2, h3, r, v) VALUES (11, 22.5, 'bc', 1, 1)"); |
750 | | |
751 | | // Test various selects. |
752 | 0 | std::shared_ptr<QLRowBlock> row_block; |
753 | | |
754 | | // Get the token for the first row. |
755 | 0 | CHECK_VALID_STMT("SELECT token(h1, h2, h3) FROM test_select_token " |
756 | 0 | "WHERE h1 = 1 AND h2 = 2.0 AND h3 = 'a';"); |
757 | 0 | row_block = processor->row_block(); |
758 | 0 | CHECK_EQ(row_block->row_count(), 1); |
759 | 0 | int64_t token1 = row_block->row(0).column(0).int64_value(); |
760 | | |
761 | | // Check the token value matches the row. |
762 | 0 | CHECK_VALID_STMT(Substitute("SELECT h1, h2, h3 FROM test_select_token " |
763 | 0 | "WHERE token(h1, h2, h3) = $0", token1)); |
764 | 0 | row_block = processor->row_block(); |
765 | 0 | CHECK_EQ(row_block->row_count(), 1); |
766 | 0 | const QLRow& row1 = row_block->row(0); |
767 | 0 | CHECK_EQ(row1.column(0).int32_value(), 1); |
768 | 0 | CHECK_EQ(row1.column(1).double_value(), 2.0); |
769 | 0 | CHECK_EQ(row1.column(2).string_value(), "a"); |
770 | | |
771 | | // Get the token for the second row (also test additional selected columns). |
772 | 0 | CHECK_VALID_STMT("SELECT v, token(h1, h2, h3), h3 FROM test_select_token " |
773 | 0 | "WHERE h1 = 11 AND h2 = 22.5 AND h3 = 'bc';"); |
774 | 0 | row_block = processor->row_block(); |
775 | 0 | CHECK_EQ(row_block->row_count(), 1); |
776 | | // Check the other selected columns return expected result. |
777 | 0 | CHECK_EQ(row_block->row(0).column(0).int32_value(), 1); |
778 | 0 | CHECK_EQ(row_block->row(0).column(2).string_value(), "bc"); |
779 | 0 | int64_t token2 = row_block->row(0).column(1).int64_value(); |
780 | | |
781 | | // Check the token value matches the row. |
782 | 0 | CHECK_VALID_STMT(Substitute("SELECT h1, h2, h3 FROM test_select_token " |
783 | 0 | "WHERE token(h1, h2, h3) = $0", token2)); |
784 | 0 | row_block = processor->row_block(); |
785 | 0 | CHECK_EQ(row_block->row_count(), 1); |
786 | 0 | const QLRow& row2 = row_block->row(0); |
787 | 0 | CHECK_EQ(row2.column(0).int32_value(), 11); |
788 | 0 | CHECK_EQ(row2.column(1).double_value(), 22.5); |
789 | 0 | CHECK_EQ(row2.column(2).string_value(), "bc"); |
790 | 0 | } |
791 | | |
792 | 0 | TEST_F(QLTestSelectedExpr, TestQLSelectToJson) { |
793 | | // Init the simulated cluster. |
794 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
795 | | |
796 | | // Get a processor. |
797 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
798 | 0 | std::shared_ptr<QLRowBlock> row_block; |
799 | 0 | LOG(INFO) << "Test selecting with ToJson() built-in."; |
800 | |
|
801 | 0 | auto to_json_str = [](const QLValue& value) -> string { |
802 | 0 | common::Jsonb jsonb(value.jsonb_value()); |
803 | 0 | string str; |
804 | 0 | CHECK_OK(jsonb.ToJsonString(&str)); |
805 | 0 | return str; |
806 | 0 | }; |
807 | | |
808 | | // Test various selects. |
809 | | |
810 | | // Create the user-defined-type, table with UDT & FROZEN and insert some value. |
811 | 0 | CHECK_VALID_STMT("CREATE TYPE udt(v1 int, v2 int)"); |
812 | 0 | CHECK_VALID_STMT("CREATE TABLE test_udt (h int PRIMARY KEY, s SET<int>, u udt, " |
813 | 0 | "f FROZEN<set<int>>, sf SET<FROZEN<set<int>>>, su SET<FROZEN<udt>>)"); |
814 | 0 | CHECK_VALID_STMT("INSERT INTO test_udt (h, s, u, f, sf, su) values (1, " |
815 | 0 | "{1,2}, {v1:3,v2:4}, {5,6}, {{7,8}}, {{v1:9,v2:0}})"); |
816 | | |
817 | | // Apply ToJson() to the key column. |
818 | 0 | CHECK_VALID_STMT("SELECT tojson(h) FROM test_udt"); |
819 | 0 | row_block = processor->row_block(); |
820 | 0 | CHECK_EQ(row_block->row_count(), 1); |
821 | 0 | EXPECT_EQ("1", to_json_str(row_block->row(0).column(0))); |
822 | | // Apply ToJson() to the SET. |
823 | 0 | CHECK_VALID_STMT("SELECT tojson(s) FROM test_udt"); |
824 | 0 | row_block = processor->row_block(); |
825 | 0 | CHECK_EQ(row_block->row_count(), 1); |
826 | 0 | EXPECT_EQ("[1,2]", to_json_str(row_block->row(0).column(0))); |
827 | | // Apply ToJson() to the UDT column. |
828 | 0 | CHECK_VALID_STMT("SELECT tojson(u) FROM test_udt"); |
829 | 0 | row_block = processor->row_block(); |
830 | 0 | CHECK_EQ(row_block->row_count(), 1); |
831 | 0 | EXPECT_EQ("{\"v1\":3,\"v2\":4}", to_json_str(row_block->row(0).column(0))); |
832 | | // Apply ToJson() to the FROZEN<SET> column. |
833 | 0 | CHECK_VALID_STMT("SELECT tojson(f) FROM test_udt"); |
834 | 0 | row_block = processor->row_block(); |
835 | 0 | CHECK_EQ(row_block->row_count(), 1); |
836 | 0 | EXPECT_EQ("[5,6]", to_json_str(row_block->row(0).column(0))); |
837 | | // Apply ToJson() to the SET<FROZEN<SET>> column. |
838 | 0 | CHECK_VALID_STMT("SELECT tojson(sf) FROM test_udt"); |
839 | 0 | row_block = processor->row_block(); |
840 | 0 | CHECK_EQ(row_block->row_count(), 1); |
841 | 0 | EXPECT_EQ("[[7,8]]", to_json_str(row_block->row(0).column(0))); |
842 | | // Apply ToJson() to the SET<FROZEN<UDT>> column. |
843 | 0 | CHECK_VALID_STMT("SELECT tojson(su) FROM test_udt"); |
844 | 0 | row_block = processor->row_block(); |
845 | 0 | CHECK_EQ(row_block->row_count(), 1); |
846 | 0 | EXPECT_EQ("[{\"v1\":9,\"v2\":0}]", to_json_str(row_block->row(0).column(0))); |
847 | |
|
848 | 0 | CHECK_VALID_STMT("CREATE TABLE test_udt2 (h int PRIMARY KEY, u frozen<udt>)"); |
849 | 0 | CHECK_VALID_STMT("INSERT INTO test_udt2 (h, u) values (1, {v1:33,v2:44})"); |
850 | | // Apply ToJson() to the FROZEN<UDT> column. |
851 | 0 | CHECK_VALID_STMT("SELECT tojson(u) FROM test_udt2"); |
852 | 0 | row_block = processor->row_block(); |
853 | 0 | CHECK_EQ(row_block->row_count(), 1); |
854 | 0 | EXPECT_EQ("{\"v1\":33,\"v2\":44}", to_json_str(row_block->row(0).column(0))); |
855 | |
|
856 | 0 | CHECK_VALID_STMT("CREATE TABLE test_udt3 (h int PRIMARY KEY, u list<frozen<udt>>)"); |
857 | 0 | CHECK_VALID_STMT("INSERT INTO test_udt3 (h, u) values (1, [{v1:44,v2:55}, {v1:66,v2:77}])"); |
858 | | // Apply ToJson() to the LIST<UDT> column. |
859 | 0 | CHECK_VALID_STMT("SELECT tojson(u) FROM test_udt3"); |
860 | 0 | row_block = processor->row_block(); |
861 | 0 | CHECK_EQ(row_block->row_count(), 1); |
862 | 0 | EXPECT_EQ("[{\"v1\":44,\"v2\":55},{\"v1\":66,\"v2\":77}]", |
863 | 0 | to_json_str(row_block->row(0).column(0))); |
864 | |
|
865 | 0 | CHECK_VALID_STMT("CREATE TABLE test_udt4 (h int PRIMARY KEY, " |
866 | 0 | "u map<frozen<udt>, frozen<udt>>)"); |
867 | 0 | CHECK_VALID_STMT("INSERT INTO test_udt4 (h, u) values " |
868 | 0 | "(1, {{v1:44,v2:55}:{v1:66,v2:77}, {v1:88,v2:99}:{v1:11,v2:22}})"); |
869 | | // Apply ToJson() to the MAP<FROZEN<UDT>:FROZEN<UDT>> column. |
870 | 0 | CHECK_VALID_STMT("SELECT tojson(u) FROM test_udt4"); |
871 | 0 | row_block = processor->row_block(); |
872 | 0 | CHECK_EQ(row_block->row_count(), 1); |
873 | 0 | EXPECT_EQ(("{\"{\\\"v1\\\":44,\\\"v2\\\":55}\":{\"v1\":66,\"v2\":77}," |
874 | 0 | "\"{\\\"v1\\\":88,\\\"v2\\\":99}\":{\"v1\":11,\"v2\":22}}"), |
875 | 0 | to_json_str(row_block->row(0).column(0))); |
876 | |
|
877 | 0 | CHECK_VALID_STMT("CREATE TABLE test_udt5 (h int PRIMARY KEY, " |
878 | 0 | "u map<frozen<list<frozen<udt>>>, frozen<set<frozen<udt>>>>)"); |
879 | 0 | CHECK_VALID_STMT("INSERT INTO test_udt5 (h, u) values " |
880 | 0 | "(1, {[{v1:44,v2:55}, {v1:66,v2:77}]:{{v1:88,v2:99},{v1:11,v2:22}}})"); |
881 | | // Apply ToJson() to the MAP<FROZEN<LIST<FROZEN<UDT>>>:FROZEN<SET<FROZEN<UDT>>>> column. |
882 | 0 | CHECK_VALID_STMT("SELECT tojson(u) FROM test_udt5"); |
883 | 0 | row_block = processor->row_block(); |
884 | 0 | CHECK_EQ(row_block->row_count(), 1); |
885 | 0 | EXPECT_EQ(("{\"[{\\\"v1\\\":44,\\\"v2\\\":55},{\\\"v1\\\":66,\\\"v2\\\":77}]\":" |
886 | 0 | "[{\"v1\":11,\"v2\":22},{\"v1\":88,\"v2\":99}]}"), |
887 | 0 | to_json_str(row_block->row(0).column(0))); |
888 | |
|
889 | 0 | CHECK_VALID_STMT("CREATE TABLE test_udt6 (h int PRIMARY KEY, " |
890 | 0 | "u map<frozen<map<frozen<udt>, text>>, frozen<set<frozen<udt>>>>)"); |
891 | 0 | CHECK_VALID_STMT("INSERT INTO test_udt6 (h, u) values " |
892 | 0 | "(1, {{{v1:11,v2:22}:'text'}:{{v1:55,v2:66},{v1:77,v2:88}}})"); |
893 | | // Apply ToJson() to the MAP<FROZEN<MAP<FROZEN<UDT>:TEXT>>:FROZEN<SET<FROZEN<UDT>>>> |
894 | | // column. |
895 | 0 | CHECK_VALID_STMT("SELECT tojson(u) FROM test_udt6"); |
896 | 0 | row_block = processor->row_block(); |
897 | 0 | CHECK_EQ(row_block->row_count(), 1); |
898 | 0 | EXPECT_EQ(("{\"{\\\"{\\\\\\\"v1\\\\\\\":11,\\\\\\\"v2\\\\\\\":22}\\\":\\\"text\\\"}\":" |
899 | 0 | "[{\"v1\":55,\"v2\":66},{\"v1\":77,\"v2\":88}]}"), |
900 | 0 | to_json_str(row_block->row(0).column(0))); |
901 | | |
902 | | // Test UDT with case-sensitive field names and names with spaces. |
903 | 0 | CHECK_VALID_STMT("CREATE TYPE udt7(v1 int, \"V2\" int, \"v 3\" int, \"V 4\" int)"); |
904 | 0 | CHECK_VALID_STMT("CREATE TABLE test_udt7 (h int PRIMARY KEY, u udt7)"); |
905 | 0 | CHECK_VALID_STMT("INSERT INTO test_udt7 (h, u) values " |
906 | 0 | "(1, {v1:11,\"V2\":22,\"v 3\":33,\"V 4\":44})"); |
907 | 0 | CHECK_VALID_STMT("SELECT tojson(u) FROM test_udt7"); |
908 | 0 | row_block = processor->row_block(); |
909 | 0 | CHECK_EQ(row_block->row_count(), 1); |
910 | | // Verify that the column names in upper case are double quoted (see the case in Cassandra). |
911 | 0 | EXPECT_EQ("{\"\\\"V 4\\\"\":44,\"\\\"V2\\\"\":22,\"v 3\":33,\"v1\":11}", |
912 | 0 | to_json_str(row_block->row(0).column(0))); |
913 | | |
914 | | // Feature Not Supported: UDT field types cannot refer to other user-defined types. |
915 | | // https://github.com/YugaByte/yugabyte-db/issues/1630 |
916 | 0 | CHECK_INVALID_STMT("CREATE TYPE udt8(i1 int, u1 udt)"); |
917 | | // CHECK_VALID_STMT("CREATE TABLE test_udt_in_udt (h int PRIMARY KEY, u udt8)"); |
918 | | // CHECK_VALID_STMT("INSERT INTO test_udt_in_udt (h, u) values (1, {i1:33,u1:{v1:44,v2:55}})"); |
919 | | // Apply ToJson() to the UDT<UDT> column. |
920 | | // CHECK_VALID_STMT("SELECT tojson(u) FROM test_udt_in_udt"); |
921 | | // row_block = processor->row_block(); |
922 | | // CHECK_EQ(row_block->row_count(), 1); |
923 | | // EXPECT_EQ("{\"i1\":33,\"u1\":{\"v1\":44,\"v2\":55}}", |
924 | | // to_json_str(row_block->row(0).column(0))); |
925 | 0 | } |
926 | | |
927 | 0 | TEST_F(QLTestSelectedExpr, TestCastDecimal) { |
928 | | // Init the simulated cluster. |
929 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
930 | | |
931 | | // Get a processor. |
932 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
933 | 0 | LOG(INFO) << "Test selecting with CAST."; |
934 | | |
935 | | // Test conversions FROM DECIMAL TO numeric types. |
936 | | |
937 | | // Create the table and insert some decimal value. |
938 | 0 | CHECK_VALID_STMT("CREATE TABLE num_decimal (pk int PRIMARY KEY, dc decimal)"); |
939 | | |
940 | | // Invalid values. |
941 | 0 | CHECK_INVALID_STMT("INSERT INTO num_decimal (pk, dc) values (1, NaN)"); |
942 | 0 | CHECK_INVALID_STMT("INSERT INTO num_decimal (pk, dc) values (1, 'NaN')"); |
943 | 0 | CHECK_INVALID_STMT("INSERT INTO num_decimal (pk, dc) values (1, Infinity)"); |
944 | 0 | CHECK_INVALID_STMT("INSERT INTO num_decimal (pk, dc) values (1, 'Infinity')"); |
945 | 0 | CHECK_INVALID_STMT("INSERT INTO num_decimal (pk, dc) values (1, 'a string')"); |
946 | |
|
947 | 0 | CHECK_VALID_STMT("INSERT INTO num_decimal (pk, dc) values (123, 456)"); |
948 | | // Test various selects. |
949 | 0 | { |
950 | 0 | CHECK_VALID_STMT("SELECT * FROM num_decimal"); |
951 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
952 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
953 | 0 | const QLRow& row = row_block->row(0); |
954 | 0 | ASSERT_EQ(row.column_count(), 2); |
955 | 0 | ASSERT_EQ(row.column(0).int32_value(), 123); |
956 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(1).decimal_value()), Decimal("456")); |
957 | 0 | } |
958 | 0 | { |
959 | 0 | CHECK_VALID_STMT("SELECT dc FROM num_decimal"); |
960 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
961 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
962 | 0 | const QLRow& row = row_block->row(0); |
963 | 0 | ASSERT_EQ(row.column_count(), 1); |
964 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), Decimal("456")); |
965 | 0 | } |
966 | 0 | { |
967 | 0 | CHECK_VALID_STMT("SELECT CAST(dc as int) FROM num_decimal"); |
968 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
969 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
970 | 0 | const QLRow& row = row_block->row(0); |
971 | 0 | ASSERT_EQ(row.column_count(), 1); |
972 | 0 | EXPECT_EQ(row.column(0).int32_value(), 456); |
973 | 0 | } |
974 | 0 | { |
975 | 0 | CHECK_VALID_STMT("SELECT CAST(dc as double) FROM num_decimal"); |
976 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
977 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
978 | 0 | const QLRow& row = row_block->row(0); |
979 | 0 | ASSERT_EQ(row.column_count(), 1); |
980 | 0 | EXPECT_EQ(row.column(0).double_value(), 456.); |
981 | 0 | } |
982 | 0 | { |
983 | 0 | CHECK_VALID_STMT("SELECT CAST(dc as float) FROM num_decimal"); |
984 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
985 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
986 | 0 | const QLRow& row = row_block->row(0); |
987 | 0 | ASSERT_EQ(row.column_count(), 1); |
988 | 0 | EXPECT_EQ(row.column(0).float_value(), 456.f); |
989 | 0 | } |
990 | 0 | { |
991 | 0 | CHECK_VALID_STMT("SELECT CAST(dc as text) FROM num_decimal"); |
992 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
993 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
994 | 0 | const QLRow& row = row_block->row(0); |
995 | 0 | ASSERT_EQ(row.column_count(), 1); |
996 | 0 | EXPECT_EQ(row.column(0).string_value(), "456"); |
997 | 0 | } |
998 | 0 | { |
999 | 0 | CHECK_VALID_STMT("SELECT CAST(dc as decimal) FROM num_decimal"); |
1000 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1001 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1002 | 0 | const QLRow& row = row_block->row(0); |
1003 | 0 | ASSERT_EQ(row.column_count(), 1); |
1004 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), Decimal("456")); |
1005 | 0 | } |
1006 | | |
1007 | | // Test value = MIN_BIGINT = -9,223,372,036,854,775,808 ~= -9.2E+18 |
1008 | | // (Using -9223372036854775807 instead of -9223372036854775808 due to a compiler |
1009 | | // bug: https://bugs.llvm.org/show_bug.cgi?id=21095) |
1010 | 0 | CHECK_VALID_STMT("INSERT INTO num_decimal (pk, dc) values (1, -9223372036854775807)"); |
1011 | 0 | { |
1012 | 0 | CHECK_VALID_STMT("SELECT dc FROM num_decimal where pk=1"); |
1013 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1014 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1015 | 0 | const QLRow& row = row_block->row(0); |
1016 | 0 | ASSERT_EQ(row.column_count(), 1); |
1017 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), |
1018 | 0 | Decimal("-9223372036854775807")); |
1019 | 0 | } |
1020 | 0 | { |
1021 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS bigint) FROM num_decimal where pk=1"); |
1022 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1023 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1024 | 0 | const QLRow& row = row_block->row(0); |
1025 | 0 | ASSERT_EQ(row.column_count(), 1); |
1026 | 0 | EXPECT_EQ(row.column(0).int64_value(), -9223372036854775807LL); |
1027 | 0 | } |
1028 | 0 | { |
1029 | | // INT32 overflow. |
1030 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS int) FROM num_decimal where pk=1"); |
1031 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1032 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1033 | 0 | const QLRow& row = row_block->row(0); |
1034 | 0 | ASSERT_EQ(row.column_count(), 1); |
1035 | 0 | EXPECT_EQ(row.column(0).int32_value(), static_cast<int32_t>(-9223372036854775807LL)); |
1036 | 0 | } |
1037 | 0 | { |
1038 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS decimal) FROM num_decimal where pk=1"); |
1039 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1040 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1041 | 0 | const QLRow& row = row_block->row(0); |
1042 | 0 | ASSERT_EQ(row.column_count(), 1); |
1043 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), |
1044 | 0 | Decimal("-9223372036854775807")); |
1045 | 0 | } |
1046 | | |
1047 | | // Test value 123.4E+18 > MAX_BIGINT = 9,223,372,036,854,775,807 ~= 9.2E+18 |
1048 | 0 | CHECK_VALID_STMT("INSERT INTO num_decimal (pk, dc) values (2, 123456789012345678901)"); |
1049 | 0 | { |
1050 | 0 | CHECK_VALID_STMT("SELECT dc FROM num_decimal where pk=2"); |
1051 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1052 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1053 | 0 | const QLRow& row = row_block->row(0); |
1054 | 0 | ASSERT_EQ(row.column_count(), 1); |
1055 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), |
1056 | 0 | Decimal("123456789012345678901")); |
1057 | 0 | } |
1058 | 0 | { |
1059 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS decimal) FROM num_decimal where pk=2"); |
1060 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1061 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1062 | 0 | const QLRow& row = row_block->row(0); |
1063 | 0 | ASSERT_EQ(row.column_count(), 1); |
1064 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), |
1065 | 0 | Decimal("123456789012345678901")); |
1066 | 0 | } |
1067 | | // INT64 overflow. |
1068 | 0 | CHECK_INVALID_STMT("SELECT CAST(dc AS bigint) FROM num_decimal where pk=2"); |
1069 | | // VARINT is not supported for CAST. |
1070 | 0 | CHECK_INVALID_STMT("SELECT CAST(dc AS varint) FROM num_decimal where pk=2"); |
1071 | | |
1072 | | // Test an extrim DECIMAL value. |
1073 | 0 | CHECK_VALID_STMT("INSERT INTO num_decimal (pk, dc) values " |
1074 | 0 | "(3, -123123123123456456456456.789789789789123123123123)"); |
1075 | 0 | { |
1076 | 0 | CHECK_VALID_STMT("SELECT dc FROM num_decimal where pk=3"); |
1077 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1078 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1079 | 0 | const QLRow& row = row_block->row(0); |
1080 | 0 | ASSERT_EQ(row.column_count(), 1); |
1081 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), |
1082 | 0 | Decimal("-123123123123456456456456.789789789789123123123123")); |
1083 | 0 | } |
1084 | 0 | { |
1085 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS decimal) FROM num_decimal where pk=3"); |
1086 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1087 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1088 | 0 | const QLRow& row = row_block->row(0); |
1089 | 0 | ASSERT_EQ(row.column_count(), 1); |
1090 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), |
1091 | 0 | Decimal("-123123123123456456456456.789789789789123123123123")); |
1092 | 0 | } |
1093 | | // INT64 overflow. |
1094 | 0 | CHECK_INVALID_STMT("SELECT CAST(dc AS bigint) FROM num_decimal where pk=3"); |
1095 | 0 | CHECK_INVALID_STMT("SELECT CAST(dc AS int) FROM num_decimal where pk=3"); |
1096 | | |
1097 | | // Test a value > MAX_DOUBLE=1.79769e+308. |
1098 | 0 | CHECK_VALID_STMT("INSERT INTO num_decimal (pk, dc) values (4, 5e+308)"); |
1099 | 0 | { |
1100 | 0 | CHECK_VALID_STMT("SELECT dc FROM num_decimal where pk=4"); |
1101 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1102 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1103 | 0 | const QLRow& row = row_block->row(0); |
1104 | 0 | ASSERT_EQ(row.column_count(), 1); |
1105 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), Decimal("5e+308")); |
1106 | 0 | } |
1107 | 0 | { |
1108 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS decimal) FROM num_decimal where pk=4"); |
1109 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1110 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1111 | 0 | const QLRow& row = row_block->row(0); |
1112 | 0 | ASSERT_EQ(row.column_count(), 1); |
1113 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), Decimal("5e+308")); |
1114 | 0 | } |
1115 | 0 | { |
1116 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS float) FROM num_decimal where pk=4"); |
1117 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1118 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1119 | 0 | const QLRow& row = row_block->row(0); |
1120 | 0 | ASSERT_EQ(row.column_count(), 1); |
1121 | | // FLOAT overflow = Infinity. |
1122 | 0 | EXPECT_EQ(row.column(0).float_value(), numeric_limits<float>::infinity()); |
1123 | 0 | } |
1124 | 0 | { |
1125 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS double) FROM num_decimal where pk=4"); |
1126 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1127 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1128 | 0 | const QLRow& row = row_block->row(0); |
1129 | 0 | ASSERT_EQ(row.column_count(), 1); |
1130 | | // DOUBLE overflow = Infinity. |
1131 | 0 | EXPECT_EQ(row.column(0).double_value(), numeric_limits<double>::infinity()); |
1132 | 0 | } |
1133 | | // Not supported. |
1134 | 0 | CHECK_INVALID_STMT("SELECT CAST(dc AS varint) FROM num_decimal where pk=4"); |
1135 | | |
1136 | | // Test a value > MAX_FLOAT=3.40282e+38. |
1137 | 0 | CHECK_VALID_STMT("INSERT INTO num_decimal (pk, dc) values (5, 5e+38)"); |
1138 | 0 | { |
1139 | 0 | CHECK_VALID_STMT("SELECT dc FROM num_decimal where pk=5"); |
1140 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1141 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1142 | 0 | const QLRow& row = row_block->row(0); |
1143 | 0 | ASSERT_EQ(row.column_count(), 1); |
1144 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), Decimal("5e+38")); |
1145 | 0 | } |
1146 | 0 | { |
1147 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS decimal) FROM num_decimal where pk=5"); |
1148 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1149 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1150 | 0 | const QLRow& row = row_block->row(0); |
1151 | 0 | ASSERT_EQ(row.column_count(), 1); |
1152 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), Decimal("5e+38")); |
1153 | 0 | } |
1154 | 0 | { |
1155 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS double) FROM num_decimal where pk=5"); |
1156 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1157 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1158 | 0 | const QLRow& row = row_block->row(0); |
1159 | 0 | ASSERT_EQ(row.column_count(), 1); |
1160 | 0 | EXPECT_EQ(row.column(0).double_value(), 5.e+38); |
1161 | 0 | } |
1162 | 0 | { |
1163 | 0 | CHECK_VALID_STMT("SELECT CAST(dc AS float) FROM num_decimal where pk=5"); |
1164 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1165 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1166 | 0 | const QLRow& row = row_block->row(0); |
1167 | 0 | ASSERT_EQ(row.column_count(), 1); |
1168 | | // FLOAT overflow = Infinity. |
1169 | 0 | EXPECT_EQ(row.column(0).float_value(), numeric_limits<float>::infinity()); |
1170 | 0 | } |
1171 | | // VARINT is not supported for CAST. |
1172 | 0 | CHECK_INVALID_STMT("SELECT CAST(dc AS varint) FROM num_decimal where pk=5"); |
1173 | | |
1174 | | // Test conversions FROM numeric types TO DECIMAL. |
1175 | | |
1176 | | // Create the table and insert some float value. |
1177 | 0 | CHECK_VALID_STMT("CREATE TABLE numbers (pk int PRIMARY KEY, flt float, dbl double, vari varint, " |
1178 | 0 | "i8 tinyint, i16 smallint, i32 int, i64 bigint)"); |
1179 | 0 | CHECK_VALID_STMT("INSERT INTO numbers (pk, flt) values (1, 456.7)"); |
1180 | | // Test various selects. |
1181 | 0 | { |
1182 | 0 | CHECK_VALID_STMT("SELECT flt FROM numbers"); |
1183 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1184 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1185 | 0 | const QLRow& row = row_block->row(0); |
1186 | 0 | ASSERT_EQ(row.column_count(), 1); |
1187 | 0 | EXPECT_EQ(row.column(0).float_value(), 456.7f); |
1188 | 0 | } |
1189 | 0 | { |
1190 | 0 | CHECK_VALID_STMT("SELECT CAST(flt as float) FROM numbers"); |
1191 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1192 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1193 | 0 | const QLRow& row = row_block->row(0); |
1194 | 0 | ASSERT_EQ(row.column_count(), 1); |
1195 | 0 | EXPECT_EQ(row.column(0).float_value(), 456.7f); |
1196 | 0 | } |
1197 | 0 | { |
1198 | 0 | CHECK_VALID_STMT("SELECT CAST(flt as decimal) FROM numbers"); |
1199 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1200 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1201 | 0 | const QLRow& row = row_block->row(0); |
1202 | 0 | ASSERT_EQ(row.column_count(), 1); |
1203 | 0 | double num = EXPECT_RESULT(DecimalFromComparable(row.column(0).decimal_value()).ToDouble()); |
1204 | 0 | EXPECT_LT(fabs(num - 456.7), 0.001); |
1205 | 0 | } |
1206 | | // Test -MAX_BIGINT=-9223372036854775807 |
1207 | 0 | CHECK_VALID_STMT("INSERT INTO numbers (pk, i64) values (2, -9223372036854775807)"); |
1208 | 0 | { |
1209 | 0 | CHECK_VALID_STMT("SELECT i64 FROM numbers where pk=2"); |
1210 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1211 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1212 | 0 | const QLRow& row = row_block->row(0); |
1213 | 0 | ASSERT_EQ(row.column_count(), 1); |
1214 | 0 | EXPECT_EQ(row.column(0).int64_value(), -9223372036854775807LL); |
1215 | 0 | } |
1216 | 0 | { |
1217 | 0 | CHECK_VALID_STMT("SELECT CAST(i64 as bigint) FROM numbers where pk=2"); |
1218 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1219 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1220 | 0 | const QLRow& row = row_block->row(0); |
1221 | 0 | ASSERT_EQ(row.column_count(), 1); |
1222 | 0 | EXPECT_EQ(row.column(0).int64_value(), -9223372036854775807LL); |
1223 | 0 | } |
1224 | 0 | { |
1225 | 0 | CHECK_VALID_STMT("SELECT CAST(i64 as decimal) FROM numbers where pk=2"); |
1226 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1227 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1228 | 0 | const QLRow& row = row_block->row(0); |
1229 | 0 | ASSERT_EQ(row.column_count(), 1); |
1230 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), |
1231 | 0 | Decimal("-9223372036854775807")); |
1232 | 0 | } |
1233 | | // Test VARINT: |
1234 | 0 | CHECK_VALID_STMT("INSERT INTO numbers (pk, vari) values (3, " |
1235 | 0 | "-123456789012345678901234567890123456789012345678901234567890)"); |
1236 | 0 | { |
1237 | 0 | CHECK_VALID_STMT("SELECT vari FROM numbers where pk=3"); |
1238 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1239 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1240 | 0 | const QLRow& row = row_block->row(0); |
1241 | 0 | ASSERT_EQ(row.column_count(), 1); |
1242 | 0 | EXPECT_EQ(row.column(0).varint_value(), CHECK_RESULT(VarInt::CreateFromString( |
1243 | 0 | "-123456789012345678901234567890123456789012345678901234567890"))); |
1244 | 0 | } |
1245 | 0 | { |
1246 | 0 | CHECK_VALID_STMT("SELECT CAST(vari as decimal) FROM numbers where pk=3"); |
1247 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1248 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1249 | 0 | const QLRow& row = row_block->row(0); |
1250 | 0 | ASSERT_EQ(row.column_count(), 1); |
1251 | 0 | EXPECT_EQ(DecimalFromComparable(row.column(0).decimal_value()), |
1252 | 0 | Decimal("-123456789012345678901234567890123456789012345678901234567890")); |
1253 | 0 | } |
1254 | | // VARINT is not supported for CAST. |
1255 | 0 | CHECK_INVALID_STMT("SELECT CAST(vari as varint) FROM numbers where pk=3"); |
1256 | | |
1257 | | // Test MAX_FLOAT=3.40282e+38 |
1258 | 0 | CHECK_VALID_STMT("INSERT INTO numbers (pk, flt) values (4, 3.40282e+38)"); |
1259 | | // Test various selects. |
1260 | 0 | { |
1261 | 0 | CHECK_VALID_STMT("SELECT flt FROM numbers where pk=4"); |
1262 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1263 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1264 | 0 | const QLRow& row = row_block->row(0); |
1265 | 0 | ASSERT_EQ(row.column_count(), 1); |
1266 | 0 | EXPECT_EQ(row.column(0).float_value(), 3.40282e+38f); |
1267 | 0 | } |
1268 | 0 | { |
1269 | 0 | CHECK_VALID_STMT("SELECT CAST(flt as float) FROM numbers where pk=4"); |
1270 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1271 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1272 | 0 | const QLRow& row = row_block->row(0); |
1273 | 0 | ASSERT_EQ(row.column_count(), 1); |
1274 | 0 | EXPECT_EQ(row.column(0).float_value(), 3.40282e+38f); |
1275 | 0 | } |
1276 | 0 | { |
1277 | 0 | CHECK_VALID_STMT("SELECT CAST(flt as decimal) FROM numbers where pk=4"); |
1278 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1279 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1280 | 0 | const QLRow& row = row_block->row(0); |
1281 | 0 | ASSERT_EQ(row.column_count(), 1); |
1282 | 0 | double num = EXPECT_RESULT(DecimalFromComparable(row.column(0).decimal_value()).ToDouble()); |
1283 | 0 | EXPECT_LT(fabs(num - 3.40282e+38), 1e+31); |
1284 | 0 | } |
1285 | | |
1286 | | // Test MAX_DOUBLE=1.79769e+308 |
1287 | 0 | CHECK_VALID_STMT("INSERT INTO numbers (pk, dbl) values (5, 1.79769e+308)"); |
1288 | | // Test various selects. |
1289 | 0 | { |
1290 | 0 | CHECK_VALID_STMT("SELECT dbl FROM numbers where pk=5"); |
1291 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1292 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1293 | 0 | const QLRow& row = row_block->row(0); |
1294 | 0 | ASSERT_EQ(row.column_count(), 1); |
1295 | 0 | EXPECT_EQ(row.column(0).double_value(), 1.79769e+308); |
1296 | 0 | } |
1297 | 0 | { |
1298 | 0 | CHECK_VALID_STMT("SELECT CAST(dbl as double) FROM numbers where pk=5"); |
1299 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1300 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1301 | 0 | const QLRow& row = row_block->row(0); |
1302 | 0 | ASSERT_EQ(row.column_count(), 1); |
1303 | 0 | EXPECT_EQ(row.column(0).double_value(), 1.79769e+308); |
1304 | 0 | } |
1305 | 0 | { |
1306 | 0 | CHECK_VALID_STMT("SELECT CAST(dbl as decimal) FROM numbers where pk=5"); |
1307 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1308 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1309 | 0 | const QLRow& row = row_block->row(0); |
1310 | 0 | ASSERT_EQ(row.column_count(), 1); |
1311 | 0 | double num = EXPECT_RESULT(DecimalFromComparable(row.column(0).decimal_value()).ToDouble()); |
1312 | 0 | EXPECT_EQ(num, 1.79769e+308); |
1313 | 0 | } |
1314 | 0 | { |
1315 | 0 | CHECK_VALID_STMT("SELECT CAST(dbl AS float) FROM numbers where pk=5"); |
1316 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1317 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1318 | 0 | const QLRow& row = row_block->row(0); |
1319 | 0 | ASSERT_EQ(row.column_count(), 1); |
1320 | | // FLOAT overflow = Infinity. |
1321 | 0 | EXPECT_EQ(row.column(0).float_value(), numeric_limits<float>::infinity()); |
1322 | 0 | } |
1323 | | // VARINT is not supported for CAST. |
1324 | 0 | CHECK_INVALID_STMT("SELECT CAST(dbl as varint) FROM numbers where pk=5"); |
1325 | 0 | } |
1326 | | |
1327 | 0 | TEST_F(QLTestSelectedExpr, TestCastTinyInt) { |
1328 | | // Init the simulated cluster. |
1329 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1330 | | |
1331 | | // Get a processor. |
1332 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
1333 | 0 | LOG(INFO) << "Test selecting with CAST."; |
1334 | | |
1335 | | // Try to convert FROM TINYINT TO a numeric type. |
1336 | | |
1337 | | // Create the table and insert some decimal value. |
1338 | 0 | CHECK_VALID_STMT("CREATE TABLE num_tinyint (pk int PRIMARY KEY, ti tinyint)"); |
1339 | 0 | CHECK_VALID_STMT("INSERT INTO num_tinyint (pk, ti) values (1, 123)"); |
1340 | | // Test various selects. |
1341 | 0 | { |
1342 | 0 | CHECK_VALID_STMT("SELECT * FROM num_tinyint"); |
1343 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1344 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1345 | 0 | const QLRow& row = row_block->row(0); |
1346 | 0 | ASSERT_EQ(row.column_count(), 2); |
1347 | 0 | ASSERT_EQ(row.column(0).int32_value(), 1); |
1348 | 0 | ASSERT_EQ(row.column(1).int8_value(), 123); |
1349 | 0 | } |
1350 | 0 | { |
1351 | 0 | CHECK_VALID_STMT("SELECT ti FROM num_tinyint"); |
1352 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1353 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1354 | 0 | const QLRow& row = row_block->row(0); |
1355 | 0 | ASSERT_EQ(row.column_count(), 1); |
1356 | 0 | ASSERT_EQ(row.column(0).int8_value(), 123); |
1357 | 0 | } |
1358 | 0 | { |
1359 | 0 | CHECK_VALID_STMT("SELECT CAST(ti as smallint) FROM num_tinyint"); |
1360 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1361 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1362 | 0 | const QLRow& row = row_block->row(0); |
1363 | 0 | ASSERT_EQ(row.column_count(), 1); |
1364 | 0 | ASSERT_EQ(row.column(0).int16_value(), 123); |
1365 | 0 | } |
1366 | 0 | { |
1367 | 0 | CHECK_VALID_STMT("SELECT CAST(ti as int) FROM num_tinyint"); |
1368 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1369 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1370 | 0 | const QLRow& row = row_block->row(0); |
1371 | 0 | ASSERT_EQ(row.column_count(), 1); |
1372 | 0 | ASSERT_EQ(row.column(0).int32_value(), 123); |
1373 | 0 | } |
1374 | 0 | { |
1375 | 0 | CHECK_VALID_STMT("SELECT CAST(ti as bigint) FROM num_tinyint"); |
1376 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1377 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1378 | 0 | const QLRow& row = row_block->row(0); |
1379 | 0 | ASSERT_EQ(row.column_count(), 1); |
1380 | 0 | ASSERT_EQ(row.column(0).int64_value(), 123); |
1381 | 0 | } |
1382 | 0 | { |
1383 | 0 | CHECK_VALID_STMT("SELECT CAST(ti as double) FROM num_tinyint"); |
1384 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1385 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1386 | 0 | const QLRow& row = row_block->row(0); |
1387 | 0 | ASSERT_EQ(row.column_count(), 1); |
1388 | 0 | ASSERT_EQ(row.column(0).double_value(), 123.); |
1389 | 0 | } |
1390 | 0 | { |
1391 | 0 | CHECK_VALID_STMT("SELECT CAST(ti as float) FROM num_tinyint"); |
1392 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1393 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1394 | 0 | const QLRow& row = row_block->row(0); |
1395 | 0 | ASSERT_EQ(row.column_count(), 1); |
1396 | 0 | ASSERT_EQ(row.column(0).float_value(), 123.f); |
1397 | 0 | } |
1398 | 0 | { |
1399 | 0 | CHECK_VALID_STMT("SELECT CAST(ti as text) FROM num_tinyint"); |
1400 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1401 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1402 | 0 | const QLRow& row = row_block->row(0); |
1403 | 0 | ASSERT_EQ(row.column_count(), 1); |
1404 | 0 | ASSERT_EQ(row.column(0).string_value(), "123"); |
1405 | 0 | } |
1406 | 0 | { |
1407 | 0 | CHECK_VALID_STMT("SELECT CAST(ti as decimal) FROM num_tinyint"); |
1408 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1409 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1410 | 0 | const QLRow& row = row_block->row(0); |
1411 | 0 | ASSERT_EQ(row.column_count(), 1); |
1412 | 0 | ASSERT_EQ(DecimalFromComparable(row.column(0).decimal_value()), Decimal("123")); |
1413 | 0 | } |
1414 | | // VARINT is not supported for CAST. |
1415 | 0 | CHECK_INVALID_STMT("SELECT CAST(ti AS varint) FROM num_tinyint"); |
1416 | | // TINYINT is not supported for CAST. |
1417 | 0 | CHECK_INVALID_STMT("SELECT CAST(ti as tinyint) FROM num_tinyint"); |
1418 | | |
1419 | | // Try value > MAX_TINYINT = 127 |
1420 | 0 | CHECK_INVALID_STMT("INSERT INTO num_tinyint (pk, ti) values (2, 256)"); |
1421 | | |
1422 | | // Try to convert FROM a numeric type TO TINYINT. |
1423 | | |
1424 | | // Create the table and insert some float value. |
1425 | 0 | CHECK_VALID_STMT("CREATE TABLE numbers (pk int PRIMARY KEY, flt float, dbl double, vari varint, " |
1426 | 0 | "i8 tinyint, i16 smallint, i32 int, i64 bigint)"); |
1427 | 0 | CHECK_VALID_STMT("INSERT INTO numbers (pk, flt, dbl, vari, i8, i16, i32, i64) values " |
1428 | 0 | "(1, 456.7, 123.456, 256, 123, 123, 123, 123)"); |
1429 | | // Test various selects. |
1430 | 0 | { |
1431 | 0 | CHECK_VALID_STMT("SELECT i8 FROM numbers"); |
1432 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1433 | 0 | ASSERT_EQ(row_block->row_count(), 1); |
1434 | 0 | const QLRow& row = row_block->row(0); |
1435 | 0 | ASSERT_EQ(row.column_count(), 1); |
1436 | 0 | ASSERT_EQ(row.column(0).int8_value(), 123); |
1437 | 0 | } |
1438 | | // TINYINT is not supported for CAST. |
1439 | 0 | CHECK_INVALID_STMT("SELECT CAST(i16 as tinyint) FROM numbers"); |
1440 | 0 | CHECK_INVALID_STMT("SELECT CAST(i32 as tinyint) FROM numbers"); |
1441 | 0 | CHECK_INVALID_STMT("SELECT CAST(i64 as tinyint) FROM numbers"); |
1442 | 0 | CHECK_INVALID_STMT("SELECT CAST(flt as tinyint) FROM numbers"); |
1443 | 0 | CHECK_INVALID_STMT("SELECT CAST(dbl as tinyint) FROM numbers"); |
1444 | 0 | CHECK_INVALID_STMT("SELECT CAST(vari as tinyint) FROM numbers"); |
1445 | 0 | } |
1446 | | |
1447 | 0 | TEST_F(QLTestSelectedExpr, TestTserverTimeout) { |
1448 | | // Init the simulated cluster. |
1449 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1450 | | // Get a processor. |
1451 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
1452 | 0 | const char *create_stmt = "CREATE TABLE test_table(h int, primary key(h));"; |
1453 | 0 | CHECK_VALID_STMT(create_stmt); |
1454 | | // Insert a row whose hash value is '1'. |
1455 | 0 | CHECK_VALID_STMT("INSERT INTO test_table(h) VALUES(1);"); |
1456 | | // Make sure a select statement works. |
1457 | 0 | CHECK_VALID_STMT("SELECT count(*) FROM test_table WHERE h = 1;"); |
1458 | | // Set a flag to simulate tserver timeout and now check that select produces an error. |
1459 | 0 | FLAGS_TEST_tserver_timeout = true; |
1460 | 0 | CHECK_INVALID_STMT("SELECT count(*) FROM test_table WHERE h = 1;"); |
1461 | 0 | } |
1462 | | |
1463 | 0 | TEST_F(QLTestSelectedExpr, ScanRangeTest) { |
1464 | | // Init the simulated cluster. |
1465 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1466 | | |
1467 | | // Get a processor. |
1468 | 0 | TestQLProcessor* processor = GetQLProcessor(); |
1469 | 0 | LOG(INFO) << "Running simple query test."; |
1470 | | // Create the table 1. |
1471 | 0 | const char* create_stmt = |
1472 | 0 | "CREATE TABLE test_range(h int, r1 int, r2 int, payload int, PRIMARY KEY ((h), r1, r2));"; |
1473 | 0 | CHECK_VALID_STMT(create_stmt); |
1474 | |
|
1475 | 0 | int h = 5; |
1476 | 0 | for (int r1 = 5; r1 < 8; r1++) { |
1477 | 0 | for (int r2 = 4; r2 < 9; r2++) { |
1478 | 0 | CHECK_VALID_STMT(strings::Substitute( |
1479 | 0 | "INSERT INTO test_range (h, r1, r2, payload) VALUES($0, $1, $2, $2);", h, r1, r2)); |
1480 | 0 | } |
1481 | 0 | } |
1482 | | |
1483 | | // Checking Row |
1484 | 0 | CHECK_VALID_STMT("SELECT * FROM test_range WHERE h = 5 AND r1 = 5 AND r2 >= 5 AND r2 <= 6;"); |
1485 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1486 | 0 | CHECK_EQ(row_block->row_count(), 2); |
1487 | 0 | { |
1488 | 0 | const QLRow& row = row_block->row(0); |
1489 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1490 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1491 | 0 | CHECK_EQ(row.column(2).int32_value(), 5); |
1492 | 0 | CHECK_EQ(row.column(3).int32_value(), 5); |
1493 | 0 | } |
1494 | 0 | { |
1495 | 0 | const QLRow& row = row_block->row(1); |
1496 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1497 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1498 | 0 | CHECK_EQ(row.column(2).int32_value(), 6); |
1499 | 0 | CHECK_EQ(row.column(3).int32_value(), 6); |
1500 | 0 | } |
1501 | 0 | } |
1502 | | |
1503 | 0 | TEST_F(QLTestSelectedExpr, ScanRangeTestReverse) { |
1504 | | // Init the simulated cluster. |
1505 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1506 | | |
1507 | | // Get a processor. |
1508 | 0 | TestQLProcessor* processor = GetQLProcessor(); |
1509 | 0 | LOG(INFO) << "Running simple query test."; |
1510 | | // Create the table 1. |
1511 | 0 | const char* create_stmt = |
1512 | 0 | "CREATE TABLE test_range(h int, r1 int, r2 int, payload int, PRIMARY KEY ((h), r1, r2));"; |
1513 | 0 | CHECK_VALID_STMT(create_stmt); |
1514 | |
|
1515 | 0 | int h = 5; |
1516 | 0 | for (int r1 = 5; r1 < 8; r1++) { |
1517 | 0 | for (int r2 = 4; r2 < 9; r2++) { |
1518 | 0 | CHECK_VALID_STMT(strings::Substitute( |
1519 | 0 | "INSERT INTO test_range (h, r1, r2, payload) VALUES($0, $1, $2, $2);", h, r1, r2)); |
1520 | 0 | } |
1521 | 0 | } |
1522 | | |
1523 | | // Checking Row |
1524 | 0 | CHECK_VALID_STMT( |
1525 | 0 | "SELECT * FROM test_range WHERE h = 5 AND r1 >= 5 AND r1 <= 6 AND r2 >= 5 AND r2 <= 6 ORDER " |
1526 | 0 | "BY r1 DESC;"); |
1527 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1528 | 0 | CHECK_EQ(row_block->row_count(), 4); |
1529 | 0 | { |
1530 | 0 | const QLRow& row = row_block->row(0); |
1531 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1532 | 0 | CHECK_EQ(row.column(1).int32_value(), 6); |
1533 | 0 | CHECK_EQ(row.column(2).int32_value(), 6); |
1534 | 0 | CHECK_EQ(row.column(3).int32_value(), 6); |
1535 | 0 | } |
1536 | 0 | { |
1537 | 0 | const QLRow& row = row_block->row(1); |
1538 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1539 | 0 | CHECK_EQ(row.column(1).int32_value(), 6); |
1540 | 0 | CHECK_EQ(row.column(2).int32_value(), 5); |
1541 | 0 | CHECK_EQ(row.column(3).int32_value(), 5); |
1542 | 0 | } |
1543 | 0 | { |
1544 | 0 | const QLRow& row = row_block->row(2); |
1545 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1546 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1547 | 0 | CHECK_EQ(row.column(2).int32_value(), 6); |
1548 | 0 | CHECK_EQ(row.column(3).int32_value(), 6); |
1549 | 0 | } |
1550 | 0 | { |
1551 | 0 | const QLRow& row = row_block->row(3); |
1552 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1553 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1554 | 0 | CHECK_EQ(row.column(2).int32_value(), 5); |
1555 | 0 | CHECK_EQ(row.column(3).int32_value(), 5); |
1556 | 0 | } |
1557 | 0 | } |
1558 | | |
1559 | 0 | TEST_F(QLTestSelectedExpr, ScanRangeTestIncDec) { |
1560 | | // Init the simulated cluster. |
1561 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1562 | | |
1563 | | // Get a processor. |
1564 | 0 | TestQLProcessor* processor = GetQLProcessor(); |
1565 | 0 | LOG(INFO) << "Running simple query test."; |
1566 | | // Create the table 1. |
1567 | 0 | const char* create_stmt = |
1568 | 0 | "CREATE TABLE test_range(h int, r1 int, r2 int, payload int, PRIMARY KEY ((h), r1, r2)) WITH " |
1569 | 0 | "CLUSTERING ORDER BY (r1 ASC, r2 DESC);"; |
1570 | 0 | CHECK_VALID_STMT(create_stmt); |
1571 | |
|
1572 | 0 | int h = 5; |
1573 | 0 | for (int r1 = 5; r1 < 8; r1++) { |
1574 | 0 | for (int r2 = 4; r2 < 9; r2++) { |
1575 | 0 | CHECK_VALID_STMT(strings::Substitute( |
1576 | 0 | "INSERT INTO test_range (h, r1, r2, payload) VALUES($0, $1, $2, $2);", h, r1, r2)); |
1577 | 0 | } |
1578 | 0 | } |
1579 | | |
1580 | | // Checking Row |
1581 | 0 | CHECK_VALID_STMT("SELECT * FROM test_range WHERE h = 5 AND r1 = 5 AND r2 >= 5 AND r2 <= 6;"); |
1582 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1583 | 0 | CHECK_EQ(row_block->row_count(), 2); |
1584 | 0 | { |
1585 | 0 | const QLRow& row = row_block->row(0); |
1586 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1587 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1588 | 0 | CHECK_EQ(row.column(2).int32_value(), 6); |
1589 | 0 | CHECK_EQ(row.column(3).int32_value(), 6); |
1590 | 0 | } |
1591 | 0 | { |
1592 | 0 | const QLRow& row = row_block->row(1); |
1593 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1594 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1595 | 0 | CHECK_EQ(row.column(2).int32_value(), 5); |
1596 | 0 | CHECK_EQ(row.column(3).int32_value(), 5); |
1597 | 0 | } |
1598 | 0 | } |
1599 | | |
1600 | 0 | TEST_F(QLTestSelectedExpr, ScanRangeTestIncDecReverse) { |
1601 | | // Init the simulated cluster. |
1602 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1603 | | |
1604 | | // Get a processor. |
1605 | 0 | TestQLProcessor* processor = GetQLProcessor(); |
1606 | 0 | LOG(INFO) << "Running simple query test."; |
1607 | | // Create the table 1. |
1608 | 0 | const char* create_stmt = |
1609 | 0 | "CREATE TABLE test_range(h int, r1 int, r2 int, payload int, PRIMARY KEY ((h), r1, r2)) WITH " |
1610 | 0 | "CLUSTERING ORDER BY (r1 ASC, r2 DESC);"; |
1611 | 0 | CHECK_VALID_STMT(create_stmt); |
1612 | |
|
1613 | 0 | int h = 5; |
1614 | 0 | for (int r1 = 5; r1 < 8; r1++) { |
1615 | 0 | for (int r2 = 4; r2 < 9; r2++) { |
1616 | 0 | CHECK_VALID_STMT(strings::Substitute( |
1617 | 0 | "INSERT INTO test_range (h, r1, r2, payload) VALUES($0, $1, $2, $2);", h, r1, r2)); |
1618 | 0 | } |
1619 | 0 | } |
1620 | | |
1621 | | // Checking Row |
1622 | 0 | CHECK_VALID_STMT( |
1623 | 0 | "SELECT * FROM test_range WHERE h = 5 AND r1 >= 5 AND r1 <= 6 AND r2 >= 5 AND r2 <= 6 ORDER " |
1624 | 0 | "BY r1 DESC;"); |
1625 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1626 | 0 | CHECK_EQ(row_block->row_count(), 4); |
1627 | 0 | { |
1628 | 0 | const QLRow& row = row_block->row(0); |
1629 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1630 | 0 | CHECK_EQ(row.column(1).int32_value(), 6); |
1631 | 0 | CHECK_EQ(row.column(2).int32_value(), 5); |
1632 | 0 | CHECK_EQ(row.column(3).int32_value(), 5); |
1633 | 0 | } |
1634 | 0 | { |
1635 | 0 | const QLRow& row = row_block->row(1); |
1636 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1637 | 0 | CHECK_EQ(row.column(1).int32_value(), 6); |
1638 | 0 | CHECK_EQ(row.column(2).int32_value(), 6); |
1639 | 0 | CHECK_EQ(row.column(3).int32_value(), 6); |
1640 | 0 | } |
1641 | 0 | { |
1642 | 0 | const QLRow& row = row_block->row(2); |
1643 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1644 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1645 | 0 | CHECK_EQ(row.column(2).int32_value(), 5); |
1646 | 0 | CHECK_EQ(row.column(3).int32_value(), 5); |
1647 | 0 | } |
1648 | 0 | { |
1649 | 0 | const QLRow& row = row_block->row(3); |
1650 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1651 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1652 | 0 | CHECK_EQ(row.column(2).int32_value(), 6); |
1653 | 0 | CHECK_EQ(row.column(3).int32_value(), 6); |
1654 | 0 | } |
1655 | 0 | } |
1656 | | |
1657 | 0 | TEST_F(QLTestSelectedExpr, ScanChoicesTest) { |
1658 | | // Init the simulated cluster. |
1659 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1660 | | |
1661 | | // Get a processor. |
1662 | 0 | TestQLProcessor* processor = GetQLProcessor(); |
1663 | 0 | LOG(INFO) << "Running simple query test."; |
1664 | | // Create the table 1. |
1665 | 0 | const char* create_stmt = |
1666 | 0 | "CREATE TABLE test_range(h int, r1 int, r2 int, payload int, PRIMARY KEY ((h), r1, r2));"; |
1667 | 0 | CHECK_VALID_STMT(create_stmt); |
1668 | |
|
1669 | 0 | int h = 5; |
1670 | 0 | for (int r1 = 5; r1 < 8; r1++) { |
1671 | 0 | for (int r2 = 4; r2 < 9; r2++) { |
1672 | 0 | CHECK_VALID_STMT(strings::Substitute( |
1673 | 0 | "INSERT INTO test_range (h, r1, r2, payload) VALUES($0, $1, $2, $2);", h, r1, r2)); |
1674 | 0 | } |
1675 | 0 | } |
1676 | | |
1677 | | // Checking Row |
1678 | 0 | CHECK_VALID_STMT("SELECT * FROM test_range WHERE h = 5 AND r1 in (5) and r2 in (5, 6)"); |
1679 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1680 | 0 | CHECK_EQ(row_block->row_count(), 2); |
1681 | 0 | { |
1682 | 0 | const QLRow& row = row_block->row(0); |
1683 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1684 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1685 | 0 | CHECK_EQ(row.column(2).int32_value(), 5); |
1686 | 0 | CHECK_EQ(row.column(3).int32_value(), 5); |
1687 | 0 | } |
1688 | 0 | { |
1689 | 0 | const QLRow& row = row_block->row(1); |
1690 | 0 | CHECK_EQ(row.column(0).int32_value(), 5); |
1691 | 0 | CHECK_EQ(row.column(1).int32_value(), 5); |
1692 | 0 | CHECK_EQ(row.column(2).int32_value(), 6); |
1693 | 0 | CHECK_EQ(row.column(3).int32_value(), 6); |
1694 | 0 | } |
1695 | 0 | } |
1696 | | |
1697 | 0 | TEST_F(QLTestSelectedExpr, ScanRangeTestIncDecAcrossHashCols) { |
1698 | | // Init the simulated cluster. |
1699 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1700 | | |
1701 | | // Get a processor. |
1702 | 0 | TestQLProcessor* processor = GetQLProcessor(); |
1703 | 0 | LOG(INFO) << "Running simple query test."; |
1704 | | // Create the table 1. |
1705 | 0 | const char* create_stmt = |
1706 | 0 | "CREATE TABLE test_range(h int, r1 int, r2 int, payload int, PRIMARY KEY ((h), r1, r2)) WITH " |
1707 | 0 | "CLUSTERING ORDER BY (r1 ASC, r2 DESC);"; |
1708 | 0 | CHECK_VALID_STMT(create_stmt); |
1709 | |
|
1710 | 0 | const int max_h = 48; |
1711 | 0 | for (int h = 0; h < max_h; h++) { |
1712 | 0 | for (int r1 = 0; r1 < 10; r1++) { |
1713 | 0 | for (int r2 = 0; r2 < 10; r2++) { |
1714 | 0 | CHECK_VALID_STMT(strings::Substitute( |
1715 | 0 | "INSERT INTO test_range (h, r1, r2, payload) VALUES($0, $1, $2, $2);", h, r1, r2)); |
1716 | 0 | } |
1717 | 0 | } |
1718 | 0 | } |
1719 | | |
1720 | | // Checking Row |
1721 | 0 | CHECK_VALID_STMT("SELECT h, r1, r2, payload FROM test_range WHERE r1 = 5 AND r2 > 4 AND r2 < 7;"); |
1722 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1723 | 0 | EXPECT_EQ(row_block->row_count(), 2 * max_h); |
1724 | 0 | vector<bool> seen(max_h, false); |
1725 | 0 | for (size_t h = 0; h < row_block->row_count(); h++) { |
1726 | 0 | const QLRow& row = row_block->row(h); |
1727 | 0 | LOG(INFO) << "got " << row.ToString(); |
1728 | 0 | seen[row.column(0).int32_value()] = true; |
1729 | 0 | EXPECT_EQ(row.column(1).int32_value(), 5); |
1730 | 0 | if (h % 2 == 0) { |
1731 | 0 | EXPECT_EQ(row.column(2).int32_value(), 6); |
1732 | 0 | EXPECT_EQ(row.column(3).int32_value(), 6); |
1733 | 0 | } else { |
1734 | 0 | EXPECT_EQ(row.column(2).int32_value(), 5); |
1735 | 0 | EXPECT_EQ(row.column(3).int32_value(), 5); |
1736 | 0 | } |
1737 | 0 | } |
1738 | 0 | CHECK_EQ(seen.size(), max_h); |
1739 | 0 | for (int h = 0; h < max_h; h++) { |
1740 | 0 | CHECK_EQ(seen[h], true); |
1741 | 0 | } |
1742 | 0 | } |
1743 | | |
1744 | 0 | TEST_F(QLTestSelectedExpr, ScanChoicesTestIncDecAcrossHashCols) { |
1745 | | // Init the simulated cluster. |
1746 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1747 | | |
1748 | | // Get a processor. |
1749 | 0 | TestQLProcessor* processor = GetQLProcessor(); |
1750 | 0 | LOG(INFO) << "Running simple query test."; |
1751 | | // Create the table 1. |
1752 | 0 | const char* create_stmt = |
1753 | 0 | "CREATE TABLE test_range(h int, r1 int, r2 int, payload int, PRIMARY KEY ((h), r1, r2)) WITH " |
1754 | 0 | "CLUSTERING ORDER BY (r1 ASC, r2 DESC);"; |
1755 | 0 | CHECK_VALID_STMT(create_stmt); |
1756 | |
|
1757 | 0 | const int max_h = 48; |
1758 | 0 | for (int h = 0; h < max_h; h++) { |
1759 | 0 | for (int r1 = 0; r1 < 10; r1++) { |
1760 | 0 | for (int r2 = 0; r2 < 10; r2++) { |
1761 | 0 | CHECK_VALID_STMT(strings::Substitute( |
1762 | 0 | "INSERT INTO test_range (h, r1, r2, payload) VALUES($0, $1, $2, $2);", h, r1, r2)); |
1763 | 0 | } |
1764 | 0 | } |
1765 | 0 | } |
1766 | | |
1767 | | // Checking Row |
1768 | 0 | CHECK_VALID_STMT("SELECT h, r1, r2, payload FROM test_range WHERE r1 in (5) AND r2 in (5, 6);"); |
1769 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
1770 | 0 | EXPECT_EQ(row_block->row_count(), 2 * max_h); |
1771 | 0 | vector<bool> seen(max_h, false); |
1772 | 0 | for (size_t h = 0; h < row_block->row_count(); h++) { |
1773 | 0 | const QLRow& row = row_block->row(h); |
1774 | 0 | LOG(INFO) << "got " << row.ToString(); |
1775 | 0 | seen[row.column(0).int32_value()] = true; |
1776 | 0 | EXPECT_EQ(row.column(1).int32_value(), 5); |
1777 | 0 | if (h % 2 == 0) { |
1778 | 0 | EXPECT_EQ(row.column(2).int32_value(), 6); |
1779 | 0 | EXPECT_EQ(row.column(3).int32_value(), 6); |
1780 | 0 | } else { |
1781 | 0 | EXPECT_EQ(row.column(2).int32_value(), 5); |
1782 | 0 | EXPECT_EQ(row.column(3).int32_value(), 5); |
1783 | 0 | } |
1784 | 0 | } |
1785 | 0 | CHECK_EQ(seen.size(), max_h); |
1786 | 0 | for (int h = 0; h < max_h; h++) { |
1787 | 0 | CHECK_EQ(seen[h], true); |
1788 | 0 | } |
1789 | 0 | } |
1790 | | |
1791 | 0 | TEST_F(QLTestSelectedExpr, TestPreparedStatementWithCollections) { |
1792 | | // Init the simulated cluster. |
1793 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
1794 | | |
1795 | | // Get a processor. |
1796 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
1797 | 0 | PreparedResult::UniPtr result; |
1798 | |
|
1799 | 0 | LOG(INFO) << "Create and setup test table."; |
1800 | 0 | CHECK_VALID_STMT("CREATE TABLE test_tbl (h INT, r INT, " |
1801 | 0 | "vm MAP<INT, TEXT>, vs set<INT>, vl list<TEXT>, PRIMARY KEY((h), r))"); |
1802 | | |
1803 | | //---------------------------------------------------------------------------------------------- |
1804 | | // Testing Map. |
1805 | | //---------------------------------------------------------------------------------------------- |
1806 | | // Test INSERT into MAP prepared statement. |
1807 | 0 | LOG(INFO) << "Prepare insert into MAP statement."; |
1808 | 0 | Statement insert_vm(processor->CurrentKeyspace(), |
1809 | 0 | "INSERT INTO test_tbl (h, r, vm) VALUES(?, ?, ?);"); |
1810 | 0 | EXPECT_OK(insert_vm.Prepare( |
1811 | 0 | &processor->ql_processor(), nullptr /* mem_tracker */, false /* internal */, &result)); |
1812 | 0 | auto vm_binds = result->bind_variable_schemas(); |
1813 | 0 | EXPECT_EQ(vm_binds.size(), 3); |
1814 | 0 | EXPECT_EQ(vm_binds[0].ToString(), "h[int32 NOT NULL NOT A PARTITION KEY]"); |
1815 | 0 | EXPECT_EQ(vm_binds[1].ToString(), "r[int32 NOT NULL NOT A PARTITION KEY]"); |
1816 | 0 | EXPECT_EQ(vm_binds[2].ToString(), "vm[map NOT NULL NOT A PARTITION KEY]"); |
1817 | 0 | EXPECT_EQ(vm_binds[2].type()->ToString(), "map<int, text>"); |
1818 | | |
1819 | | // Bind and execute the prepared statement with correct values. |
1820 | 0 | QLValue qvm; |
1821 | 0 | qvm.add_map_key()->set_int32_value(2); |
1822 | 0 | qvm.add_map_value()->set_string_value("b"); |
1823 | 0 | qvm.add_map_key()->set_int32_value(3); |
1824 | 0 | qvm.add_map_value()->set_string_value("c"); |
1825 | |
|
1826 | 0 | CQLQueryParameters params; |
1827 | 0 | params.PushBackInt32("h", 1); |
1828 | 0 | params.PushBackInt32("r", 1); |
1829 | 0 | params.PushBack("vm", qvm, QLType::CreateTypeMap(DataType::INT32, DataType::STRING)); |
1830 | |
|
1831 | 0 | EXPECT_OK(processor->Run(insert_vm, params)); |
1832 | | |
1833 | | // Bind and execute the prepared statement with NULL in value. |
1834 | 0 | QLValue qvm_null_val; |
1835 | 0 | qvm_null_val.add_map_key()->set_int32_value(1); |
1836 | 0 | qvm_null_val.add_map_value()->Clear(); // Set to null by clearing all existing values. |
1837 | |
|
1838 | 0 | params.Reset(); |
1839 | 0 | params.PushBackInt32("h", 2); |
1840 | 0 | params.PushBackInt32("r", 2); |
1841 | 0 | params.PushBack("vm", qvm_null_val, QLType::CreateTypeMap(DataType::INT32, DataType::STRING)); |
1842 | |
|
1843 | 0 | Status s = processor->Run(insert_vm, params); |
1844 | 0 | LOG(INFO) << "Expected error: " << s; |
1845 | 0 | EXPECT_TRUE(s.IsQLError()) << "Expected QLError, got: " << s; |
1846 | 0 | EXPECT_EQ(GetErrorCode(s), ErrorCode::INVALID_ARGUMENTS) |
1847 | 0 | << "Expected INVALID_ARGUMENT, got " << s; |
1848 | 0 | EXPECT_NE(s.message().ToBuffer().find("null is not supported inside collections"), |
1849 | 0 | string::npos) << s; |
1850 | | |
1851 | | // Bind and execute the prepared statement with NULL in key. |
1852 | 0 | QLValue qvm_null_key; |
1853 | 0 | qvm_null_key.add_map_key()->Clear(); // Set to null by clearing all existing values. |
1854 | 0 | qvm_null_key.add_map_value()->set_string_value("a"); |
1855 | |
|
1856 | 0 | params.Reset(); |
1857 | 0 | params.PushBackInt32("h", 9); |
1858 | 0 | params.PushBackInt32("r", 9); |
1859 | 0 | params.PushBack("vm", qvm_null_key, QLType::CreateTypeMap(DataType::INT32, DataType::STRING)); |
1860 | |
|
1861 | 0 | s = processor->Run(insert_vm, params); |
1862 | 0 | LOG(INFO) << "Expected error: " << s; |
1863 | 0 | EXPECT_TRUE(s.IsQLError()) << "Expected QLError, got: " << s; |
1864 | 0 | EXPECT_EQ(GetErrorCode(s), ErrorCode::INVALID_ARGUMENTS) |
1865 | 0 | << "Expected INVALID_ARGUMENT, got " << s; |
1866 | 0 | EXPECT_NE(s.message().ToBuffer().find("null is not supported inside collections"), |
1867 | 0 | string::npos) << s; |
1868 | | |
1869 | | //---------------------------------------------------------------------------------------------- |
1870 | | // Testing Set. |
1871 | | //---------------------------------------------------------------------------------------------- |
1872 | | // Test INSERT into SET prepared statement. |
1873 | 0 | LOG(INFO) << "Prepare insert into SET statement."; |
1874 | 0 | Statement insert_vs(processor->CurrentKeyspace(), |
1875 | 0 | "INSERT INTO test_tbl (h, r, vs) VALUES(?, ?, ?);"); |
1876 | 0 | EXPECT_OK(insert_vs.Prepare( |
1877 | 0 | &processor->ql_processor(), nullptr /* mem_tracker */, false /* internal */, &result)); |
1878 | 0 | auto vs_binds = result->bind_variable_schemas(); |
1879 | 0 | EXPECT_EQ(vs_binds.size(), 3); |
1880 | 0 | EXPECT_EQ(vs_binds[0].ToString(), "h[int32 NOT NULL NOT A PARTITION KEY]"); |
1881 | 0 | EXPECT_EQ(vs_binds[1].ToString(), "r[int32 NOT NULL NOT A PARTITION KEY]"); |
1882 | 0 | EXPECT_EQ(vs_binds[2].ToString(), "vs[set NOT NULL NOT A PARTITION KEY]"); |
1883 | 0 | EXPECT_EQ(vs_binds[2].type()->ToString(), "set<int>"); |
1884 | | |
1885 | | // Bind and execute the prepared statement with correct values. |
1886 | 0 | QLValue qvs; |
1887 | 0 | qvs.add_set_elem()->set_int32_value(4); |
1888 | 0 | qvs.add_set_elem()->set_int32_value(5); |
1889 | |
|
1890 | 0 | params.Reset(); |
1891 | 0 | params.PushBackInt32("h", 1); |
1892 | 0 | params.PushBackInt32("r", 1); |
1893 | 0 | params.PushBack("vs", qvs, QLType::CreateTypeSet(DataType::INT32)); |
1894 | |
|
1895 | 0 | EXPECT_OK(processor->Run(insert_vs, params)); |
1896 | | |
1897 | | // Bind and execute the prepared statement with NULL in SET element. |
1898 | 0 | QLValue qvs_null_elem; |
1899 | 0 | qvs_null_elem.add_set_elem()->Clear(); // Set to null by clearing all existing values. |
1900 | |
|
1901 | 0 | params.Reset(); |
1902 | 0 | params.PushBackInt32("h", 9); |
1903 | 0 | params.PushBackInt32("r", 9); |
1904 | 0 | params.PushBack("vs", qvs_null_elem, QLType::CreateTypeSet(DataType::INT32)); |
1905 | |
|
1906 | 0 | s = processor->Run(insert_vs, params); |
1907 | 0 | LOG(INFO) << "Expected error: " << s; |
1908 | 0 | EXPECT_TRUE(s.IsQLError()) << "Expected QLError, got: " << s; |
1909 | 0 | EXPECT_EQ(GetErrorCode(s), ErrorCode::INVALID_ARGUMENTS) |
1910 | 0 | << "Expected INVALID_ARGUMENT, got " << s; |
1911 | 0 | EXPECT_NE(s.message().ToBuffer().find("null is not supported inside collections"), |
1912 | 0 | string::npos) << s; |
1913 | | |
1914 | | //---------------------------------------------------------------------------------------------- |
1915 | | // Testing List. |
1916 | | //---------------------------------------------------------------------------------------------- |
1917 | | // Test INSERT into LIST prepared statement. |
1918 | 0 | LOG(INFO) << "Prepare insert into LIST statement."; |
1919 | 0 | Statement insert_vl(processor->CurrentKeyspace(), |
1920 | 0 | "INSERT INTO test_tbl (h, r, vl) VALUES(?, ?, ?);"); |
1921 | 0 | EXPECT_OK(insert_vl.Prepare( |
1922 | 0 | &processor->ql_processor(), nullptr /* mem_tracker */, false /* internal */, &result)); |
1923 | 0 | auto vl_binds = result->bind_variable_schemas(); |
1924 | 0 | EXPECT_EQ(vl_binds.size(), 3); |
1925 | 0 | EXPECT_EQ(vl_binds[0].ToString(), "h[int32 NOT NULL NOT A PARTITION KEY]"); |
1926 | 0 | EXPECT_EQ(vl_binds[1].ToString(), "r[int32 NOT NULL NOT A PARTITION KEY]"); |
1927 | 0 | EXPECT_EQ(vl_binds[2].ToString(), "vl[list NOT NULL NOT A PARTITION KEY]"); |
1928 | 0 | EXPECT_EQ(vl_binds[2].type()->ToString(), "list<text>"); |
1929 | | |
1930 | | // Bind and execute the prepared statement with correct values. |
1931 | 0 | QLValue qvl; |
1932 | 0 | qvl.add_list_elem()->set_string_value("x"); |
1933 | 0 | qvl.add_list_elem()->set_string_value("y"); |
1934 | |
|
1935 | 0 | params.Reset(); |
1936 | 0 | params.PushBackInt32("h", 1); |
1937 | 0 | params.PushBackInt32("r", 1); |
1938 | 0 | params.PushBack("vl", qvl, QLType::CreateTypeList(DataType::STRING)); |
1939 | |
|
1940 | 0 | EXPECT_OK(processor->Run(insert_vl, params)); |
1941 | | |
1942 | | // Bind and execute the prepared statement with NULL in LIST element. |
1943 | 0 | QLValue qvl_null_elem; |
1944 | 0 | qvl_null_elem.add_list_elem()->Clear(); // Set to null by clearing all existing values. |
1945 | |
|
1946 | 0 | params.Reset(); |
1947 | 0 | params.PushBackInt32("h", 3); |
1948 | 0 | params.PushBackInt32("r", 3); |
1949 | 0 | params.PushBack("vl", qvl_null_elem, QLType::CreateTypeList(DataType::STRING)); |
1950 | |
|
1951 | 0 | s = processor->Run(insert_vl, params); |
1952 | 0 | LOG(INFO) << "Expected error: " << s; |
1953 | 0 | EXPECT_TRUE(s.IsQLError()) << "Expected QLError, got: " << s; |
1954 | 0 | EXPECT_EQ(GetErrorCode(s), ErrorCode::INVALID_ARGUMENTS) |
1955 | 0 | << "Expected INVALID_ARGUMENT, got " << s; |
1956 | 0 | EXPECT_NE(s.message().ToBuffer().find("null is not supported inside collections"), |
1957 | 0 | string::npos) << s; |
1958 | | |
1959 | | //---------------------------------------------------------------------------------------------- |
1960 | | // Checking row. |
1961 | | //---------------------------------------------------------------------------------------------- |
1962 | 0 | CheckSelectedRow(processor, "SELECT * FROM test_tbl WHERE h = 1 AND r = 1", |
1963 | 0 | "{ int32:1, int32:1, map:{int32:2 -> string:\"b\", int32:3 -> string:\"c\"}, " |
1964 | 0 | "set:{int32:4, int32:5}, list:[string:\"x\", string:\"y\"] }"); |
1965 | 0 | LOG(INFO) << "Done."; |
1966 | 0 | } |
1967 | | |
1968 | | } // namespace ql |
1969 | | } // namespace yb |