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_select_inequality.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 PggateTestSelectInequality : public PggateTest {
27
};
28
29
0
TEST_F(PggateTestSelectInequality, TestSelectInequality) {
30
0
  CHECK_OK(Init("TestSelectInequality"));
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, "h", ++col_count,
47
0
                                               DataType::STRING, true, false));
48
0
  CHECK_YBC_STATUS(YBCTestCreateTableAddColumn(pg_stmt, "r1", ++col_count,
49
0
                                               DataType::INT64, false, true));
50
0
  CHECK_YBC_STATUS(YBCTestCreateTableAddColumn(pg_stmt, "val", ++col_count,
51
0
                                               DataType::STRING, false, false));
52
0
  CHECK_YBC_STATUS(YBCPgExecCreateTable(pg_stmt));
53
54
0
  pg_stmt = nullptr;
55
56
  // INSERT ----------------------------------------------------------------------------------------
57
  // Allocate new insert.
58
0
  CHECK_YBC_STATUS(YBCPgNewInsert(kDefaultDatabaseOid, tab_oid,
59
0
                                  false /* is_single_row_txn */, &pg_stmt));
60
61
0
  int h = 0, r = 0;
62
  // Allocate constant expressions.
63
  // TODO(neil) We can also allocate expression with bind.
64
0
  YBCPgExpr expr_id;
65
0
  string h_str = strings::Substitute("$0", h);
66
0
  CHECK_YBC_STATUS(YBCTestNewConstantText(pg_stmt, h_str.c_str(), false, &expr_id));
67
0
  YBCPgExpr expr_r1;
68
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt8(pg_stmt, r, false, &expr_r1));
69
0
  YBCPgExpr expr_val;
70
0
  string val = strings::Substitute("$0-$1", h, r);
71
0
  CHECK_YBC_STATUS(YBCTestNewConstantText(pg_stmt, val.c_str(), false, &expr_val));
72
73
  // Set column value to be inserted.
74
0
  int attr_num = 0;
75
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_id));
76
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_r1));
77
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, ++attr_num, expr_val));
78
0
  CHECK_EQ(attr_num, col_count);
79
80
0
  const int h_count = 10;
81
0
  const int r_count = 100;
82
0
  for (h = 0; h < h_count; h++) {
83
0
    for (r = 0; r < r_count; r++) {
84
      // LOG(INFO) << "inserting " << *pg_stmt;
85
      // Insert row.
86
0
      BeginTransaction();
87
0
      CHECK_YBC_STATUS(YBCPgExecInsert(pg_stmt));
88
0
      CommitTransaction();
89
90
0
      if (h == 0 && r == 0) {
91
0
        r++;
92
0
      }
93
94
      // Update the constant expresions to insert the next row.
95
      // TODO(neil) When we support binds, we can also call UpdateBind here.
96
0
      h_str = strings::Substitute("$0", h);
97
0
      CHECK_YBC_STATUS(YBCPgUpdateConstText(expr_id, h_str.c_str(), false));
98
0
      CHECK_YBC_STATUS(YBCPgUpdateConstInt8(expr_r1, r, false));
99
0
      val = strings::Substitute("$0-$1", h, r);
100
0
      CHECK_YBC_STATUS(YBCPgUpdateConstText(expr_val, val.c_str(), false));
101
0
    }
102
0
  }
103
104
  // Insert last row.
105
0
  BeginTransaction();
106
0
  CHECK_YBC_STATUS(YBCPgExecInsert(pg_stmt));
107
0
  CommitTransaction();
108
109
0
  pg_stmt = nullptr;
110
111
  // SELECT --------------------------------- A < r1 < B -------------------------------------------
112
0
  LOG(INFO) << "Test SELECTing from table WITH RANGE values";
113
0
  CHECK_YBC_STATUS(YBCPgNewSelect(kDefaultDatabaseOid, tab_oid,
114
0
                                  NULL /* prepare_params */, &pg_stmt));
115
116
  // Specify the selected expressions.
117
0
  YBCPgExpr colref;
118
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 1, DataType::STRING, &colref));
119
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
120
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 2, DataType::INT64, &colref));
121
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
122
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 3, DataType::STRING, &colref));
123
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
124
125
  // Set partition and range columns for SELECT to select a specific row.
126
  // SELECT ... WHERE hash = 0 AND id = seed.
127
0
  h = 1;
128
0
  int A = 10, B = 20;
129
0
  h_str = strings::Substitute("$0", h);
130
0
  CHECK_YBC_STATUS(YBCTestNewConstantText(pg_stmt, h_str.c_str(), false, &expr_id));
131
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, 1, expr_id));
132
0
  YBCPgExpr expr_r1_A;
133
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt8Op(pg_stmt, A, false, &expr_r1_A, true /* is_gt */));
134
0
  YBCPgExpr expr_r1_B;
135
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt8Op(pg_stmt, B, false, &expr_r1_B, false /* is_gt */));
136
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumnCondBetween(pg_stmt, 2, expr_r1_A, expr_r1_B));
137
138
  // Execute select statement.
139
0
  BeginTransaction();
140
0
  CHECK_YBC_STATUS(YBCPgExecSelect(pg_stmt, nullptr /* exec_params */));
141
142
  // Fetching rows and check their contents.
143
0
  uint64_t *values = static_cast<uint64_t*>(YBCPAlloc(col_count * sizeof(uint64_t)));
144
0
  bool *isnulls = static_cast<bool*>(YBCPAlloc(col_count * sizeof(bool)));
145
0
  int select_row_count = 0;
146
0
  YBCPgSysColumns syscols;
147
0
  for (int i = A; i <= B; i++) {
148
0
    bool has_data = false;
149
0
    CHECK_YBC_STATUS(YBCPgDmlFetch(pg_stmt, col_count, values, isnulls, &syscols, &has_data));
150
0
    if (!has_data) {
151
0
      break;
152
0
    }
153
0
    select_row_count++;
154
155
    // Print result
156
0
    LOG(INFO) << "ROW " << i << ": "
157
0
              << "h = (" << values[0] << ")"
158
0
              << ", r1 = " << values[1]
159
0
              << ", val = (" << values[2] << ")";
160
161
    // Check result.
162
0
    int col_index = 0;
163
164
0
    string selected_id = reinterpret_cast<char*>(values[col_index++]);
165
0
    string expected_id = strings::Substitute("$0", h);
166
0
    CHECK_EQ(selected_id, expected_id);
167
168
0
    int64_t r1 = values[col_index++];  // h : int64
169
0
    CHECK_LE(A, r1);
170
0
    CHECK_GE(B, r1);
171
172
0
    string selected_val = reinterpret_cast<char*>(values[col_index++]);
173
0
    string expected_val = strings::Substitute("$0-$1", h, r1);
174
0
    CHECK_EQ(selected_val, expected_val);
175
0
  }
176
0
  CHECK_EQ(select_row_count, B - A + 1) << "Unexpected row count";
177
0
  CommitTransaction();
178
179
0
  pg_stmt = nullptr;
180
181
  // SELECT --------------------------------- A < r1 -----------------------------------------------
182
0
  LOG(INFO) << "Test SELECTing from table WITH RANGE values: A < r1";
183
0
  CHECK_YBC_STATUS(YBCPgNewSelect(kDefaultDatabaseOid, tab_oid,
184
0
                                  NULL /* prepare_params */, &pg_stmt));
185
186
  // Specify the selected expressions.
187
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 1, DataType::STRING, &colref));
188
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
189
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 2, DataType::INT64, &colref));
190
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
191
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 3, DataType::STRING, &colref));
192
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
193
194
  // Set partition and range columns for SELECT to select a specific row.
195
  // SELECT ... WHERE hash = 0 AND id = seed.
196
0
  h = 1;
197
0
  A = 10;
198
0
  B = r_count - 1;
199
0
  h_str = strings::Substitute("$0", h);
200
0
  CHECK_YBC_STATUS(YBCTestNewConstantText(pg_stmt, h_str.c_str(), false, &expr_id));
201
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, 1, expr_id));
202
0
  expr_r1_A = nullptr;
203
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt8Op(pg_stmt, A, false, &expr_r1_A, true /* is_gt */));
204
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumnCondBetween(pg_stmt, 2, expr_r1_A, nullptr));
205
206
  // Execute select statement.
207
0
  BeginTransaction();
208
0
  CHECK_YBC_STATUS(YBCPgExecSelect(pg_stmt, nullptr /* exec_params */));
209
210
  // Fetching rows and check their contents.
211
0
  values = static_cast<uint64_t*>(YBCPAlloc(col_count * sizeof(uint64_t)));
212
0
  isnulls = static_cast<bool*>(YBCPAlloc(col_count * sizeof(bool)));
213
0
  select_row_count = 0;
214
0
  for (int i = A; i <= B; i++) {
215
0
    bool has_data = false;
216
0
    CHECK_YBC_STATUS(YBCPgDmlFetch(pg_stmt, col_count, values, isnulls, &syscols, &has_data));
217
0
    if (!has_data) {
218
0
      break;
219
0
    }
220
0
    select_row_count++;
221
222
    // Print result
223
0
    LOG(INFO) << "ROW " << i << ": "
224
0
              << "h = (" << values[0] << ")"
225
0
              << ", r1 = " << values[1]
226
0
              << ", val = (" << values[2] << ")";
227
228
    // Check result.
229
0
    int col_index = 0;
230
231
0
    string selected_id = reinterpret_cast<char*>(values[col_index++]);
232
0
    string expected_id = strings::Substitute("$0", h);
233
0
    CHECK_EQ(selected_id, expected_id);
234
235
0
    int64_t r1 = values[col_index++];  // h : int64
236
0
    CHECK_LE(A, r1);
237
0
    CHECK_GE(B, r1);
238
239
0
    string selected_val = reinterpret_cast<char*>(values[col_index++]);
240
0
    string expected_val = strings::Substitute("$0-$1", h, r1);
241
0
    CHECK_EQ(selected_val, expected_val);
242
0
  }
243
0
  CHECK_EQ(select_row_count, B - A + 1) << "Unexpected row count";
244
0
  CommitTransaction();
245
246
0
  pg_stmt = nullptr;
247
248
  // SELECT --------------------------------- r1 < B -----------------------------------------------
249
0
  LOG(INFO) << "Test SELECTing from table WITH RANGE values: r1 < B";
250
0
  CHECK_YBC_STATUS(YBCPgNewSelect(kDefaultDatabaseOid, tab_oid,
251
0
                                  NULL /* prepare_params */, &pg_stmt));
252
253
  // Specify the selected expressions.
254
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 1, DataType::STRING, &colref));
255
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
256
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 2, DataType::INT64, &colref));
257
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
258
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 3, DataType::STRING, &colref));
259
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
260
261
  // Set partition and range columns for SELECT to select a specific row.
262
  // SELECT ... WHERE hash = 0 AND id = seed.
263
0
  h = 1;
264
0
  A = 0;
265
0
  B = 20;
266
0
  h_str = strings::Substitute("$0", h);
267
0
  CHECK_YBC_STATUS(YBCTestNewConstantText(pg_stmt, h_str.c_str(), false, &expr_id));
268
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, 1, expr_id));
269
0
  expr_r1_B = nullptr;
270
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt8Op(pg_stmt, B, false, &expr_r1_B, false /* is_gt */));
271
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumnCondBetween(pg_stmt, 2, nullptr, expr_r1_B));
272
273
  // Execute select statement.
274
0
  BeginTransaction();
275
0
  CHECK_YBC_STATUS(YBCPgExecSelect(pg_stmt, nullptr /* exec_params */));
276
277
  // Fetching rows and check their contents.
278
0
  values = static_cast<uint64_t*>(YBCPAlloc(col_count * sizeof(uint64_t)));
279
0
  isnulls = static_cast<bool*>(YBCPAlloc(col_count * sizeof(bool)));
280
0
  select_row_count = 0;
281
0
  for (int i = A; i <= B; i++) {
282
0
    bool has_data = false;
283
0
    CHECK_YBC_STATUS(YBCPgDmlFetch(pg_stmt, col_count, values, isnulls, &syscols, &has_data));
284
0
    if (!has_data) {
285
0
      break;
286
0
    }
287
0
    select_row_count++;
288
289
    // Print result
290
0
    LOG(INFO) << "ROW " << i << ": "
291
0
              << "h = (" << values[0] << ")"
292
0
              << ", r1 = " << values[1]
293
0
              << ", val = (" << values[2] << ")";
294
295
    // Check result.
296
0
    int col_index = 0;
297
298
0
    string selected_id = reinterpret_cast<char*>(values[col_index++]);
299
0
    string expected_id = strings::Substitute("$0", h);
300
0
    CHECK_EQ(selected_id, expected_id);
301
302
0
    int64_t r1 = values[col_index++];  // h : int64
303
0
    CHECK_LE(A, r1);
304
0
    CHECK_GE(B, r1);
305
306
0
    string selected_val = reinterpret_cast<char*>(values[col_index++]);
307
0
    string expected_val = strings::Substitute("$0-$1", h, r1);
308
0
    CHECK_EQ(selected_val, expected_val);
309
0
  }
310
0
  CHECK_EQ(select_row_count, B - A + 1) << "Unexpected row count";
311
0
  CommitTransaction();
312
313
0
  pg_stmt = nullptr;
314
315
  // SELECT --------------------------------- A < r1 < A -------------------------------------------
316
0
  LOG(INFO) << "Test SELECTing from table WITH RANGE values: A < r1 < A";
317
0
  CHECK_YBC_STATUS(YBCPgNewSelect(kDefaultDatabaseOid, tab_oid,
318
0
                                  NULL /* prepare_params */, &pg_stmt));
319
320
  // Specify the selected expressions.
321
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 1, DataType::STRING, &colref));
322
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
323
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 2, DataType::INT64, &colref));
324
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
325
0
  CHECK_YBC_STATUS(YBCTestNewColumnRef(pg_stmt, 3, DataType::STRING, &colref));
326
0
  CHECK_YBC_STATUS(YBCPgDmlAppendTarget(pg_stmt, colref));
327
328
  // Set partition and range columns for SELECT to select a specific row.
329
  // SELECT ... WHERE hash = 0 AND id = seed.
330
0
  h = 1;
331
0
  A = 10;
332
0
  B = 10;
333
0
  h_str = strings::Substitute("$0", h);
334
0
  CHECK_YBC_STATUS(YBCTestNewConstantText(pg_stmt, h_str.c_str(), false, &expr_id));
335
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumn(pg_stmt, 1, expr_id));
336
0
  expr_r1_A = nullptr;
337
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt8Op(pg_stmt, A, false, &expr_r1_A, true /* is_gt */));
338
0
  expr_r1_B = nullptr;
339
0
  CHECK_YBC_STATUS(YBCTestNewConstantInt8Op(pg_stmt, B, false, &expr_r1_B, false /* is_gt */));
340
0
  CHECK_YBC_STATUS(YBCPgDmlBindColumnCondBetween(pg_stmt, 2, expr_r1_A, expr_r1_B));
341
342
  // Execute select statement.
343
0
  BeginTransaction();
344
0
  CHECK_YBC_STATUS(YBCPgExecSelect(pg_stmt, nullptr /* exec_params */));
345
346
  // Fetching rows and check their contents.
347
0
  values = static_cast<uint64_t*>(YBCPAlloc(col_count * sizeof(uint64_t)));
348
0
  isnulls = static_cast<bool*>(YBCPAlloc(col_count * sizeof(bool)));
349
0
  select_row_count = 0;
350
0
  for (int i = A; i <= B; i++) {
351
0
    bool has_data = false;
352
0
    CHECK_YBC_STATUS(YBCPgDmlFetch(pg_stmt, col_count, values, isnulls, &syscols, &has_data));
353
0
    if (!has_data) {
354
0
      break;
355
0
    }
356
0
    select_row_count++;
357
358
    // Print result
359
0
    LOG(INFO) << "ROW " << i << ": "
360
0
              << "h = (" << values[0] << ")"
361
0
              << ", r1 = " << values[1]
362
0
              << ", val = (" << values[2] << ")";
363
364
    // Check result.
365
0
    int col_index = 0;
366
367
0
    string selected_id = reinterpret_cast<char*>(values[col_index++]);
368
0
    string expected_id = strings::Substitute("$0", h);
369
0
    CHECK_EQ(selected_id, expected_id);
370
371
0
    int64_t r1 = values[col_index++];  // h : int64
372
0
    CHECK_LE(A, r1);
373
0
    CHECK_GE(B, r1);
374
375
0
    string selected_val = reinterpret_cast<char*>(values[col_index++]);
376
0
    string expected_val = strings::Substitute("$0-$1", h, r1);
377
0
    CHECK_EQ(selected_val, expected_val);
378
0
  }
379
0
  CHECK_EQ(select_row_count, B - A + 1) << "Unexpected row count";
380
0
  CommitTransaction();
381
382
0
  pg_stmt = nullptr;
383
0
}
384
385
} // namespace pggate
386
} // namespace yb