YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/yql/pggate/test/pggate_test_delete.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/ybc-internal.h"
17
18
#include "yb/util/status_log.h"
19
20
#include "yb/yql/pggate/test/pggate_test.h"
21
#include "yb/yql/pggate/ybc_pggate.h"
22
23
namespace yb {
24
namespace pggate {
25
26
class PggateTestDelete : public PggateTest {
27
};
28
29
0
TEST_F(PggateTestDelete, TestDelete) {
30
0
  CHECK_OK(Init("TestDelete"));
31
32
0
  const char *tabname = "basic_table";
33
0
  const YBCPgOid tab_oid = 3;
34
0
  YBCPgStatement pg_stmt;
35
36
  // Create table in the connected database.
37
0
  int col_count = 0;
38
0
  CHECK_YBC_STATUS(YBCPgNewCreateTable(kDefaultDatabase, kDefaultSchema, tabname,
39
0
                                       kDefaultDatabaseOid, tab_oid,
40
0
                                       false /* is_shared_table */, true /* if_not_exist */,
41
0
                                       false /* add_primary_key */, true /* colocated */,
42
0
                                       kInvalidOid /* tablegroup_id */,
43
0
                                       kInvalidOid /* tablespace_id */,
44
0
                                       kInvalidOid /* matview_pg_table_id */,
45
0
                                       &pg_stmt));
46
0
  CHECK_YBC_STATUS(YBCTestCreateTableAddColumn(pg_stmt, "hash_key", ++col_count,
47
0
                                             DataType::INT64, true, true));
48
0
  CHECK_YBC_STATUS(YBCTestCreateTableAddColumn(pg_stmt, "id", ++col_count,
49
0
                                             DataType::INT32, false, true));
50
0
  CHECK_YBC_STATUS(YBCTestCreateTableAddColumn(pg_stmt, "dependent_count", ++col_count,
51
0
                                             DataType::INT16, false, false));
52
0
  CHECK_YBC_STATUS(YBCTestCreateTableAddColumn(pg_stmt, "project_count", ++col_count,
53
0
                                             DataType::INT32, false, false));
54
0
  CHECK_YBC_STATUS(YBCTestCreateTableAddColumn(pg_stmt, "salary", ++col_count,
55
0
                                             DataType::FLOAT, false, false));
56
0
  CHECK_YBC_STATUS(YBCTestCreateTableAddColumn(pg_stmt, "job", ++col_count,
57
0
                                             DataType::STRING, false, false));
58
0
  CHECK_YBC_STATUS(YBCPgExecCreateTable(pg_stmt));
59
60
0
  pg_stmt = nullptr;
61
62
  // INSERT ----------------------------------------------------------------------------------------
63
  // Allocate new insert.
64
0
  CHECK_YBC_STATUS(YBCPgNewInsert(kDefaultDatabaseOid, tab_oid,
65
0
                                  false /* is_single_row_txn */, &pg_stmt));
66
67
  // Allocate constant expressions.
68
  // TODO(neil) We can also allocate expression with bind.
69
0
  int seed = 1;
70
0
  YBCPgExpr expr_hash;
71
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt8(pg_stmt, seed, false, &expr_hash));
72
73
0
  YBCPgExpr expr_id;
74
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt4(pg_stmt, seed, false, &expr_id));
75
0
  YBCPgExpr expr_depcnt;
76
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt2(pg_stmt, seed, false, &expr_depcnt));
77
0
  YBCPgExpr expr_projcnt;
78
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt4(pg_stmt, 100 + seed, false, &expr_projcnt));
79
0
  YBCPgExpr expr_salary;
80
0
  CHECK_YBC_STATUS(YBCTestNewConstantFloat4(pg_stmt, seed + 1.0*seed/10.0, false, &expr_salary));
81
0
  YBCPgExpr expr_job;
82
0
  string job = strings::Substitute("Job_title_$0", seed);
83
0
  CHECK_YBC_STATUS(YBCTestNewConstantText(pg_stmt, job.c_str(), false, &expr_job));
84
85
  // Set column value to be inserted.
86
0
  int attr_num = 0;
87
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_hash));
88
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_id));
89
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_depcnt));
90
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_projcnt));
91
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_salary));
92
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_job));
93
0
  CHECK_EQ(attr_num, col_count);
94
95
0
  const int insert_row_count = 7;
96
0
  for (int i = 0; i < insert_row_count; i++) {
97
    // Insert the row with the original seed.
98
0
    BeginTransaction();
99
0
    CHECK_YBC_STATUS(YBCPgExecInsert(pg_stmt));
100
0
    CommitTransaction();
101
102
    // Update the constant expresions to insert the next row.
103
    // TODO(neil) When we support binds, we can also call UpdateBind here.
104
0
    seed++;
105
0
    CHECK_YBC_STATUS(YBCPgUpdateConstInt8(expr_hash, seed, false));
106
0
    CHECK_YBC_STATUS(YBCPgUpdateConstInt4(expr_id, seed, false));
107
0
    CHECK_YBC_STATUS(YBCPgUpdateConstInt2(expr_depcnt, seed, false));
108
0
    CHECK_YBC_STATUS(YBCPgUpdateConstInt4(expr_projcnt, 100 + seed, false));
109
0
    CHECK_YBC_STATUS(YBCPgUpdateConstFloat4(expr_salary, seed + 1.0*seed/10.0, false));
110
0
    job = strings::Substitute("Job_title_$0", seed);
111
0
    CHECK_YBC_STATUS(YBCPgUpdateConstChar(expr_job, job.c_str(), job.size(), false));
112
0
  }
113
114
0
  pg_stmt = nullptr;
115
116
  // DELETE ----------------------------------------------------------------------------------------
117
  // Allocate new delete.
118
0
  CHECK_YBC_STATUS(YBCPgNewDelete(kDefaultDatabaseOid, tab_oid,
119
0
                                  false /* is_single_row_txn */, &pg_stmt));
120
121
  // Allocate constant expressions.
122
  // TODO(neil) We can also allocate expression with bind.
123
0
  seed = 1;
124
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt8(pg_stmt, seed, false, &expr_hash));
125
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt4(pg_stmt, seed, false, &expr_id));
126
127
0
  attr_num = 0;
128
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_hash));
129
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_id));
130
131
  // DELETE all of odd rows.
132
0
  const int delete_row_count = (insert_row_count + 1)/ 2;
133
0
  for (int i = 0; i < delete_row_count; i++) {
134
    // Delete the row with the original seed.
135
0
    BeginTransaction();
136
0
    CHECK_YBC_STATUS(YBCPgExecDelete(pg_stmt));
137
0
    CommitTransaction();
138
139
    // Update the constant expresions to delete the next row.
140
    // TODO(neil) When we support binds, we can also call UpdateBind here.
141
0
    seed = seed + 2;
142
0
    CHECK_YBC_STATUS(YBCPgUpdateConstInt8(expr_hash, seed, false));
143
0
    CHECK_YBC_STATUS(YBCPgUpdateConstInt4(expr_id, seed, false));
144
0
  }
145
146
0
  pg_stmt = nullptr;
147
148
  // SELECT ----------------------------------------------------------------------------------------
149
0
  LOG(INFO) << "Test SELECTing from non-partitioned table";
150
0
  CHECK_YBC_STATUS(YBCPgNewSelect(kDefaultDatabaseOid, tab_oid,
151
0
                                  NULL /* prepare_params */, &pg_stmt));
152
153
  // Specify the selected expressions.
154
0
  YBCPgExpr colref;
155
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 1, DataType::INT64, &colref));
156
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
157
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 2, DataType::INT32, &colref));
158
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
159
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 3, DataType::INT16, &colref));
160
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
161
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 4, DataType::INT32, &colref));
162
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
163
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 5, DataType::FLOAT, &colref));
164
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
165
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 6, DataType::STRING, &colref));
166
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
167
168
  // Execute select statement.
169
0
  BeginTransaction();
170
0
  CHECK_YBC_STATUS(YBCPgExecSelect(pg_stmt, nullptr /* exec_params */));
171
172
  // Fetching rows and check their contents.
173
0
  uint64_t *values = static_cast<uint64_t*>(YBCPAlloc(col_count * sizeof(uint64_t)));
174
0
  bool *isnulls = static_cast<bool*>(YBCPAlloc(col_count * sizeof(bool)));
175
0
  int select_row_count = 0;
176
0
  for (int i = 0; i < insert_row_count; i++) {
177
0
    bool has_data = false;
178
0
    CHECK_YBC_STATUS(YBCPgDmlFetch(pg_stmt, col_count, values, isnulls, nullptr, &has_data));
179
0
    if (!has_data) {
180
0
      break;
181
0
    }
182
0
    select_row_count++;
183
184
    // Print result
185
0
    LOG(INFO) << "ROW " << i << ": "
186
0
              << "hash_key = " << values[0]
187
0
              << ", id = " << values[1]
188
0
              << ", dependent count = " << values[2]
189
0
              << ", project count = " << values[3]
190
0
              << ", salary = " << *reinterpret_cast<float*>(&values[4])
191
0
              << ", job = (" << values[5] << ")";
192
193
    // Check result.
194
0
    int col_index = 0;
195
0
    auto hash_id = values[col_index++];  // id : int32
196
0
    auto id = values[col_index++];  // id : int32
197
0
    CHECK_EQ(hash_id, id) << "Expect hash and range key share the same value";
198
0
    CHECK(id%2 == 0) << "Odd rows should have been deleted";
199
0
    CHECK_EQ(values[col_index++], id);  // dependent_count : int16
200
0
    CHECK_EQ(values[col_index++], 100 + id);  // project_count : int32
201
0
    CHECK_LE(*reinterpret_cast<float*>(&values[col_index]), id + 1.0*id/10.0 + 0.01); // salary
202
0
    CHECK_GE(*reinterpret_cast<float*>(&values[col_index++]), id + 1.0*id/10.0 - 0.01); // float
203
204
0
    string selected_job_name = reinterpret_cast<char*>(values[col_index++]);
205
0
    string expected_job_name = strings::Substitute("Job_title_$0", id);
206
0
    CHECK_EQ(selected_job_name, expected_job_name);
207
0
  }
208
0
  CHECK_EQ(select_row_count, insert_row_count - delete_row_count) << "Unexpected row count";
209
0
  CommitTransaction();
210
211
0
  pg_stmt = nullptr;
212
0
}
213
214
} // namespace pggate
215
} // namespace yb