/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/test/ql-update-table-test.cc
Line | Count | Source (jump to first uncovered line) |
1 | | //-------------------------------------------------------------------------------------------------- |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | //-------------------------------------------------------------------------------------------------- |
15 | | |
16 | | #include "yb/common/jsonb.h" |
17 | | #include "yb/common/ql_value.h" |
18 | | #include "yb/common/table_properties_constants.h" |
19 | | |
20 | | #include "yb/gutil/strings/substitute.h" |
21 | | |
22 | | #include "yb/yql/cql/ql/test/ql-test-base.h" |
23 | | |
24 | | using std::string; |
25 | | using strings::Substitute; |
26 | | |
27 | | namespace yb { |
28 | | namespace ql { |
29 | | |
30 | | class TestQLUpdateTable : public QLTestBase { |
31 | | public: |
32 | 0 | TestQLUpdateTable() : QLTestBase() { |
33 | 0 | } |
34 | | |
35 | 0 | std::string GetUpdateStmt(int64_t ttl_msec) { |
36 | 0 | return strings::Substitute( |
37 | 0 | "UPDATE test_table USING TTL $0 SET v1 = 1 WHERE h1 = 0 AND h2 = 'zero' AND r1 = 1 " |
38 | 0 | "AND r2 = 'r2';", ttl_msec); |
39 | 0 | } |
40 | | }; |
41 | | |
42 | 0 | TEST_F(TestQLUpdateTable, TestQLUpdateToJson) { |
43 | | // Init the simulated cluster. |
44 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
45 | | |
46 | | // Get a processor. |
47 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
48 | 0 | std::shared_ptr<QLRowBlock> row_block; |
49 | |
|
50 | 0 | auto to_json_str = [](const QLValue& value) -> string { |
51 | 0 | common::Jsonb jsonb(value.jsonb_value()); |
52 | 0 | string str; |
53 | 0 | CHECK_OK(jsonb.ToJsonString(&str)); |
54 | 0 | return str; |
55 | 0 | }; |
56 | | |
57 | | // Create table with JSONB. |
58 | 0 | CHECK_VALID_STMT("CREATE TABLE test_json (h int PRIMARY KEY, j jsonb)"); |
59 | |
|
60 | 0 | CHECK_VALID_STMT("INSERT INTO test_json (h, j) values (1, '{\"a\":123}')"); |
61 | 0 | CHECK_VALID_STMT("UPDATE test_json SET j->'a' = '{}', j->'a'->'b' = '6' where h = 1"); |
62 | 0 | CHECK_VALID_STMT("SELECT * FROM test_json"); |
63 | 0 | row_block = processor->row_block(); |
64 | 0 | CHECK_EQ(row_block->row_count(), 1); |
65 | 0 | EXPECT_EQ(1, row_block->row(0).column(0).int32_value()); |
66 | 0 | EXPECT_EQ("{\"a\":{\"b\":6}}", to_json_str(row_block->row(0).column(1))); |
67 | 0 | } |
68 | | |
69 | 0 | TEST_F(TestQLUpdateTable, TestQLUpdateTableSimple) { |
70 | | // Init the simulated cluster. |
71 | 0 | ASSERT_NO_FATALS(CreateSimulatedCluster()); |
72 | | |
73 | | // Get a processor. |
74 | 0 | TestQLProcessor *processor = GetQLProcessor(); |
75 | | |
76 | | // ----------------------------------------------------------------------------------------------- |
77 | | // Create the table. |
78 | 0 | const char *create_stmt = |
79 | 0 | "CREATE TABLE test_table(h1 int, h2 varchar, " |
80 | 0 | "r1 int, r2 varchar, " |
81 | 0 | "v1 int, v2 varchar, " |
82 | 0 | "primary key((h1, h2), r1, r2));"; |
83 | 0 | CHECK_VALID_STMT(create_stmt); |
84 | |
|
85 | 0 | CHECK_VALID_STMT(GetUpdateStmt(yb::common::kCassandraMaxTtlSeconds)); |
86 | 0 | CHECK_VALID_STMT(GetUpdateStmt(yb::common::kCassandraMinTtlSeconds)); |
87 | 0 | CHECK_INVALID_STMT(GetUpdateStmt(yb::common::kCassandraMaxTtlSeconds + 1)); |
88 | 0 | CHECK_INVALID_STMT(GetUpdateStmt(yb::common::kCassandraMinTtlSeconds - 1)); |
89 | | |
90 | | // ----------------------------------------------------------------------------------------------- |
91 | | // Unknown table. |
92 | 0 | CHECK_INVALID_STMT("UPDATE test_table_unknown SET v1 = 77 WHERE h1 = 0 AND h2 = 'zero';"); |
93 | | |
94 | | // Missing hash key. |
95 | 0 | CHECK_INVALID_STMT("UPDATE test_table SET v1 = 77 WHERE h1 = 0;"); |
96 | | |
97 | | // Wrong operator on hash key. |
98 | 0 | CHECK_INVALID_STMT("UPDATE test_table SET v1 = 77 WHERE h1 > 0 AND h2 = 'zero';"); |
99 | | |
100 | | // ----------------------------------------------------------------------------------------------- |
101 | | // Insert 100 rows into the table. |
102 | 0 | static const int kNumRows = 100; |
103 | 0 | for (int idx = 0; idx < kNumRows; idx++) { |
104 | | // INSERT: Valid statement with column list. |
105 | 0 | string stmt = Substitute("INSERT INTO test_table(h1, h2, r1, r2, v1, v2) " |
106 | 0 | "VALUES($0, 'h$1', $2, 'r$3', $4, 'v$5');", |
107 | 0 | idx, idx, idx+100, idx+100, idx+1000, idx+1000); |
108 | 0 | CHECK_VALID_STMT(stmt); |
109 | 0 | } |
110 | | |
111 | | // Testing UPDATE one row. |
112 | 0 | string select_stmt; |
113 | 0 | std::shared_ptr<QLRowBlock> row_block = processor->row_block(); |
114 | 0 | for (int idx = 0; idx < kNumRows; idx++) { |
115 | | // SELECT an entry to make sure it's there. |
116 | 0 | select_stmt = Substitute("SELECT * FROM test_table" |
117 | 0 | " WHERE h1 = $0 AND h2 = 'h$1' AND r1 = $2 AND r2 = 'r$3';", |
118 | 0 | idx, idx, idx+100, idx+100); |
119 | 0 | CHECK_VALID_STMT(select_stmt); |
120 | 0 | row_block = processor->row_block(); |
121 | 0 | CHECK_EQ(row_block->row_count(), 1); |
122 | | |
123 | | // UPDATE the entry. |
124 | 0 | CHECK_VALID_STMT(Substitute("UPDATE test_table SET v1 = $0, v2 = 'v$0'" |
125 | 0 | " WHERE h1 = $1 AND h2 = 'h$1' AND r1 = $2 AND r2 = 'r$2';", |
126 | 0 | idx + 2000, idx, idx+100)); |
127 | | |
128 | | // SELECT the same entry to make sure it's no longer there. |
129 | 0 | CHECK_VALID_STMT(select_stmt); |
130 | 0 | row_block = processor->row_block(); |
131 | 0 | CHECK_EQ(row_block->row_count(), 1); |
132 | 0 | const QLRow& row = row_block->row(0); |
133 | 0 | CHECK_EQ(row.column(0).int32_value(), idx); |
134 | 0 | CHECK_EQ(row.column(1).string_value(), Substitute("h$0", idx)); |
135 | 0 | CHECK_EQ(row.column(2).int32_value(), idx + 100); |
136 | 0 | CHECK_EQ(row.column(3).string_value(), Substitute("r$0", idx + 100)); |
137 | 0 | CHECK_EQ(row.column(4).int32_value(), idx + 2000); |
138 | 0 | CHECK_EQ(row.column(5).string_value(), Substitute("v$0", idx + 2000)); |
139 | 0 | } |
140 | 0 | } |
141 | | |
142 | | } // namespace ql |
143 | | } // namespace yb |