forked from oceanbase/oceanbase
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathob_sql_context.h
More file actions
814 lines (760 loc) · 30.1 KB
/
Copy pathob_sql_context.h
File metadata and controls
814 lines (760 loc) · 30.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_SQL_CONTEXT_
#define OCEANBASE_SQL_CONTEXT_
#include "ob_sql_utils.h"
#include "lib/net/ob_addr.h"
#include "lib/hash/ob_placement_hashset.h"
#include "lib/container/ob_2d_array.h"
#include "sql/optimizer/ob_table_partition_info.h"
#include "sql/monitor/ob_exec_stat.h"
#include "lib/hash_func/murmur_hash.h"
#include "sql/ob_sql_temp_table.h"
#include "sql/plan_cache/ob_plan_cache_util.h"
#include "observer/omt/ob_tenant_config_mgr.h"
#include "share/client_feedback/ob_feedback_partition_struct.h"
#include "sql/dblink/ob_dblink_utils.h"
#ifdef OB_BUILD_SPM
#include "sql/spm/ob_spm_define.h"
#endif
namespace oceanbase
{
namespace common
{
class ObMySQLProxy;
class ObPartMgr;
}
namespace share
{
namespace schema
{
class ObSchemaGetterGuard;
class ObTableSchema;
class ObColumnSchemaV2;
}
}
namespace pl
{
class ObPL;
}
namespace sql
{
typedef common::ObIArray<ObTablePartitionInfo *> ObTablePartitionInfoArray;
//ObLocationConstraint如果只有一项, 则仅需要约束该location type是否一致;
// 如果有多项,则需要校验每一项location对应的物理分布是否一样
struct LocationConstraint;
typedef common::ObSEArray<LocationConstraint, 1, common::ModulePageAllocator, true> ObLocationConstraint;
typedef common::ObFixedArray<LocationConstraint, common::ObIAllocator> ObPlanLocationConstraint;
typedef common::ObSEArray<int64_t, 4, common::ModulePageAllocator, true> ObPwjConstraint;
typedef common::ObFixedArray<int64_t, common::ObIAllocator> ObPlanPwjConstraint;
class ObShardingInfo;
struct LocationConstraint
{
enum InclusionType {
NotSubset = 0, // no inclusion relationship
LeftIsSuperior, // left contains all the elements in right set
RightIsSuperior // right contains all the elements in left set
};
enum ConstraintFlag {
NoExtraFlag = 0,
IsMultiPartInsert = 1,
// 分区裁剪后基表只涉及到一个一级分区
SinglePartition = 1 << 1,
// 分区裁剪后基表每个一级分区都只涉及一个二级分区
SingleSubPartition = 1 << 2,
// is duplicate table not in dml
DupTabNotInDML = 1 << 3
};
TableLocationKey key_;
ObTableLocationType phy_loc_type_;
int64_t constraint_flags_;
// only used in plan generate
ObTablePartitionInfo *table_partition_info_;
LocationConstraint() : key_(), phy_loc_type_(), constraint_flags_(NoExtraFlag), table_partition_info_(NULL) {}
inline uint64_t hash() const {
uint64_t hash_ret = key_.hash();
hash_ret = common::murmurhash(&phy_loc_type_, sizeof(ObTableLocationType), hash_ret);
return hash_ret;
}
inline void add_constraint_flag(ConstraintFlag flag) { constraint_flags_ |= flag; }
inline bool is_multi_part_insert() const { return constraint_flags_ & IsMultiPartInsert; }
inline bool is_partition_single() const { return constraint_flags_ & SinglePartition; }
inline bool is_subpartition_single() const { return constraint_flags_ & SingleSubPartition; }
inline bool is_dup_table_not_in_dml() const {return constraint_flags_ & DupTabNotInDML; }
bool operator==(const LocationConstraint &other) const;
bool operator!=(const LocationConstraint &other) const;
// calculate the inclusion relationship between ObLocationConstraints
static int calc_constraints_inclusion(const ObLocationConstraint *left,
const ObLocationConstraint *right,
InclusionType &inclusion_result);
TO_STRING_KV(K_(key), K_(phy_loc_type), K_(constraint_flags));
};
struct ObLocationConstraintContext
{
enum InclusionType {
NotSubset = 0, // no inclusion relationship
LeftIsSuperior, // left contains all the elements in right set
RightIsSuperior // right contains all the elements in left set
};
ObLocationConstraintContext()
: base_table_constraints_(),
strict_constraints_(),
non_strict_constraints_(),
dup_table_replica_cons_()
{
}
~ObLocationConstraintContext()
{
}
static int calc_constraints_inclusion(const ObPwjConstraint *left,
const ObPwjConstraint *right,
InclusionType &inclusion_result);
TO_STRING_KV(K_(base_table_constraints),
K_(strict_constraints),
K_(non_strict_constraints),
K_(dup_table_replica_cons));
// 基表location约束,包括TABLE_SCAN算子上的基表和INSERT算子上的基表
ObLocationConstraint base_table_constraints_;
// 严格partition wise join约束,要求同一个分组内的基表分区逻辑上和物理上都相等。
// 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移
common::ObSEArray<ObPwjConstraint *, 8, common::ModulePageAllocator, true> strict_constraints_;
// 严格partition wise join约束,要求用一个分组内的基表分区物理上相等。
// 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移
common::ObSEArray<ObPwjConstraint *, 8, common::ModulePageAllocator, true> non_strict_constraints_;
// constraints for duplicate table's replica selection
// if not found values in this array, just use local server's replica.
common::ObSEArray<ObDupTabConstraint, 1, common::ModulePageAllocator, true> dup_table_replica_cons_;
};
class ObIVtScannerableFactory;
class ObSQLSessionMgr;
class ObSQLSessionInfo;
class ObIVirtualTableIteratorFactory;
class ObRawExpr;
class ObSQLSessionInfo;
class ObSelectStmt;
class ObMultiStmtItem
{
public:
ObMultiStmtItem()
: is_part_of_multi_stmt_(false),
seq_num_(0),
sql_(),
batched_queries_(NULL),
is_ps_mode_(false),
ab_cnt_(0)
{
}
ObMultiStmtItem(bool is_part_of_multi, int64_t seq_num, const common::ObString &sql)
: is_part_of_multi_stmt_(is_part_of_multi),
seq_num_(seq_num),
sql_(sql),
batched_queries_(NULL),
is_ps_mode_(false),
ab_cnt_(0)
{
}
ObMultiStmtItem(bool is_part_of_multi,
int64_t seq_num,
const common::ObString &sql,
const common::ObIArray<ObString> *queries,
bool is_multi_vas_opt)
: is_part_of_multi_stmt_(is_part_of_multi),
seq_num_(seq_num),
sql_(sql),
batched_queries_(queries),
is_ps_mode_(false),
ab_cnt_(0)
{
}
virtual ~ObMultiStmtItem() {}
void reset()
{
is_part_of_multi_stmt_ = false;
seq_num_ = 0;
sql_.reset();
batched_queries_ = NULL;
}
inline bool is_part_of_multi_stmt() const { return is_part_of_multi_stmt_; }
inline int64_t get_seq_num() const { return seq_num_; }
inline const common::ObString &get_sql() const { return sql_; }
inline bool is_batched_multi_stmt() const
{
bool is_batch = false;
if (is_ps_mode_) {
is_batch = (ab_cnt_ > 0);
} else {
is_batch = NULL != batched_queries_;
}
return is_batch;
}
inline int64_t get_batched_stmt_cnt() const
{
int64_t batch_cnt = 0;
if (is_ps_mode_) {
batch_cnt = ab_cnt_;
} else if (batched_queries_ != nullptr) {
batch_cnt = batched_queries_->count();
}
return batch_cnt;
}
inline const common::ObIArray<ObString> *get_queries() const { return batched_queries_; }
inline void set_batched_queries(const common::ObIArray<ObString> *batched_queries)
{ batched_queries_ = batched_queries; }
inline bool is_ab_batch_opt() { return (is_ps_mode_ && ab_cnt_ > 0); }
inline void set_ps_mode(bool ps) { is_ps_mode_ = ps; }
inline bool is_ps_mode() { return is_ps_mode_; }
inline void set_ab_cnt(int64_t cnt) { ab_cnt_ = cnt; }
inline int64_t get_ab_cnt() { return ab_cnt_; }
TO_STRING_KV(K_(is_part_of_multi_stmt), K_(seq_num), K_(sql), KPC_(batched_queries),
K_(is_ps_mode), K_(ab_cnt));
private:
bool is_part_of_multi_stmt_; // 是否为multi stmt,非multi stmt也使用这个结构体,因此需要这个标记
int64_t seq_num_; // 表示是在multi stmt中的第几条
common::ObString sql_;
// is set only when doing multi-stmt optimization
const common::ObIArray<ObString> *batched_queries_;
bool is_ps_mode_;
int64_t ab_cnt_;
};
struct ObInsertRewriteOptCtx
{
ObInsertRewriteOptCtx()
: can_do_opt_(false),
row_count_(0)
{}
void set_can_do_insert_batch_opt(int64_t row_count)
{
can_do_opt_ = true;
row_count_ = row_count;
}
bool is_do_insert_batch_opt() const
{
bool bret = false;
if (can_do_opt_ && row_count_ > 1) {
bret = true;
}
return bret;
}
inline void clear()
{
can_do_opt_ = false;
row_count_ = 0;
}
inline void reset() { clear(); }
bool can_do_opt_;
int64_t row_count_;
};
class ObQueryRetryInfo
{
public:
ObQueryRetryInfo()
: inited_(false),
is_rpc_timeout_(false),
last_query_retry_err_(common::OB_SUCCESS),
retry_cnt_(0),
query_switch_leader_retry_timeout_ts_(0)
{
}
virtual ~ObQueryRetryInfo() {}
int init();
void reset();
void clear();
void clear_state_before_each_retry()
{
is_rpc_timeout_ = false;
// 这里不能清除逐次重试累计的成员,如:invalid_servers_,last_query_retry_err_
}
bool is_inited() const { return inited_; }
void set_is_rpc_timeout(bool is_rpc_timeout);
bool is_rpc_timeout() const;
void set_last_query_retry_err(int last_query_retry_err)
{
last_query_retry_err_ = last_query_retry_err;
}
bool should_fast_fail(uint64_t tenant_id)
{
bool fast_fail = false;
if (0 == query_switch_leader_retry_timeout_ts_) {
query_switch_leader_retry_timeout_ts_ = INT64_MAX;
// start timing from first retry, not from query start
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
if (tenant_config.is_valid()) {
int64_t timeout = tenant_config->ob_query_switch_leader_retry_timeout;
if (timeout > 0) {
query_switch_leader_retry_timeout_ts_ = timeout + common::ObTimeUtility::current_time();
}
}
}
if (query_switch_leader_retry_timeout_ts_ < common::ObTimeUtility::current_time()) {
fast_fail = true;
}
return fast_fail;
}
// 1. timeout 场景下,尽量反馈上次的错误码,使得报错原因可理解
// 2. 其余场景下,用于获取上次错误码,来决策本地重试行为(如 remote plan 优化走不走)
int get_last_query_retry_err() const { return last_query_retry_err_; }
void inc_retry_cnt() { retry_cnt_++; }
int64_t get_retry_cnt() const { return retry_cnt_; }
TO_STRING_KV(K_(inited), K_(is_rpc_timeout), K_(last_query_retry_err));
private:
bool inited_; // 这个变量用于写一些防御性代码,基本没用
// 用于标记是否是rpc返回的timeout错误码(包括本地超时和回包中的超时错误码)
bool is_rpc_timeout_;
// 重试阶段可以将错误码的处理分为三类:
// 1.重试到超时,将timeout返回给客户端;
// 2.不再重试的错误码,直接将其返回给客客户端;
// 3.重试到超时,但是将原始错误码返回给客户端,当前仅有 OB_NOT_SUPPORTED,
// 对于这类错误码需要正确记录到last_query_retry_err_中,不应该被类型1或2的错误码覆盖。
int last_query_retry_err_;
// this value include local retry & packet retry
int64_t retry_cnt_;
// for fast fail,
int64_t query_switch_leader_retry_timeout_ts_;
private:
DISALLOW_COPY_AND_ASSIGN(ObQueryRetryInfo);
};
class ObSqlSchemaGuard
{
public:
ObSqlSchemaGuard()
{ reset(); }
~ObSqlSchemaGuard()
{ reset(); }
void set_schema_guard(share::schema::ObSchemaGetterGuard *schema_guard)
{ schema_guard_ = schema_guard; }
share::schema::ObSchemaGetterGuard *get_schema_guard() const
{ return schema_guard_; }
void reset();
int get_dblink_schema(const uint64_t tenant_id,
const uint64_t dblink_id,
const share::schema::ObDbLinkSchema *&dblink_schema);
int get_table_schema(uint64_t dblink_id,
const common::ObString &database_name,
const common::ObString &table_name,
const share::schema::ObTableSchema *&table_schema,
sql::ObSQLSessionInfo *session_info,
const ObString &dblink_name,
bool is_reverse_link);
int set_link_table_schema(uint64_t dblink_id,
const common::ObString &database_name,
share::schema::ObTableSchema *table_schema);
int get_table_schema(uint64_t table_id,
uint64_t ref_table_id,
const ObDMLStmt *stmt,
const ObTableSchema *&table_schema);
int get_table_schema(uint64_t table_id,
const TableItem *table_item,
const ObTableSchema *&table_schema);
int get_table_schema(uint64_t table_id,
const share::schema::ObTableSchema *&table_schema,
bool is_link = false) const;
int get_column_schema(uint64_t table_id, const common::ObString &column_name,
const share::schema::ObColumnSchemaV2 *&column_schema,
bool is_link = false) const;
int get_column_schema(uint64_t table_id, uint64_t column_id,
const share::schema::ObColumnSchemaV2 *&column_schema,
bool is_link = false) const;
int get_table_schema_version(const uint64_t table_id, int64_t &schema_version) const;
int get_can_read_index_array(uint64_t table_id,
uint64_t *index_tid_array,
int64_t &size,
bool with_mv,
bool with_global_index = true,
bool with_domain_index = true,
bool with_spatial_index = true);
int get_link_table_schema(uint64_t table_id,
const share::schema::ObTableSchema *&table_schema) const;
int get_link_column_schema(uint64_t table_id, const common::ObString &column_name,
const share::schema::ObColumnSchemaV2 *&column_schema) const;
int get_link_column_schema(uint64_t table_id, uint64_t column_id,
const share::schema::ObColumnSchemaV2 *&column_schema) const;
int fetch_link_current_scn(uint64_t dblink_id, uint64_t tenant_id, ObSQLSessionInfo *session_info,
uint64_t ¤t_scn);
// get current scn from dblink. return OB_INVALID_ID if remote server not support current_scn
int get_link_current_scn(uint64_t dblink_id, uint64_t tenant_id, ObSQLSessionInfo *session_info,
uint64_t ¤t_scn);
public:
static TableItem *get_table_item_by_ref_id(const ObDMLStmt *stmt, uint64_t ref_table_id);
static bool is_link_table(const ObDMLStmt *stmt, uint64_t table_id);
private:
share::schema::ObSchemaGetterGuard *schema_guard_;
common::ObArenaAllocator allocator_;
common::ObSEArray<const share::schema::ObTableSchema *, 1> table_schemas_;
uint64_t next_link_table_id_;
// key is dblink_id, value is current scn.
common::hash::ObHashMap<uint64_t, uint64_t> dblink_scn_;
};
#ifndef OB_BUILD_SPM
struct ObBaselineKey
{
ObBaselineKey()
: db_id_(common::OB_INVALID_ID),
constructed_sql_(),
sql_id_() {}
ObBaselineKey(uint64_t db_id, const ObString &constructed_sql, const ObString &sql_id)
: db_id_(db_id),
constructed_sql_(constructed_sql),
sql_id_(sql_id) {}
inline void reset()
{
db_id_ = common::OB_INVALID_ID;
constructed_sql_.reset();
sql_id_.reset();
}
TO_STRING_KV(K_(db_id),
K_(constructed_sql),
K_(sql_id));
uint64_t db_id_;
common::ObString constructed_sql_;
common::ObString sql_id_;
};
struct ObSpmCacheCtx
{
ObSpmCacheCtx()
: bl_key_()
{}
inline void reset() { bl_key_.reset(); }
ObBaselineKey bl_key_;
};
#endif
struct ObSqlCtx
{
OB_UNIS_VERSION(1);
public:
ObSqlCtx();
~ObSqlCtx() { reset(); }
int set_partition_infos(const ObTablePartitionInfoArray &info, common::ObIAllocator &allocator);
int set_related_user_var_names(const common::ObIArray<common::ObString> &user_var_names, common::ObIAllocator &allocator);
int set_location_constraints(const ObLocationConstraintContext &location_constraint,
ObIAllocator &allocator);
int set_multi_stmt_rowkey_pos(const common::ObIArray<int64_t> &multi_stmt_rowkey_pos,
common::ObIAllocator &alloctor);
void reset();
bool handle_batched_multi_stmt() const { return multi_stmt_item_.is_batched_multi_stmt(); }
void reset_reroute_info() {
if (nullptr != reroute_info_) {
op_reclaim_free(reroute_info_);
}
reroute_info_ = NULL;
}
share::ObFeedbackRerouteInfo *get_or_create_reroute_info()
{
if (nullptr == reroute_info_) {
reroute_info_ = op_reclaim_alloc(share::ObFeedbackRerouteInfo);
}
return reroute_info_;
}
share::ObFeedbackRerouteInfo *get_reroute_info() {
return reroute_info_;
}
bool is_batch_params_execute() const
{
return multi_stmt_item_.is_batched_multi_stmt() || is_do_insert_batch_opt();
}
int64_t get_batch_params_count() const
{
int64_t count = 0;
if (multi_stmt_item_.is_batched_multi_stmt()) {
count = multi_stmt_item_.get_batched_stmt_cnt();
} else if (is_do_insert_batch_opt()) {
count = get_insert_batch_row_cnt();
}
return count;
}
bool is_do_insert_batch_opt() const
{
return ins_opt_ctx_.is_do_insert_batch_opt();
}
inline int64_t get_insert_batch_row_cnt() const
{
return ins_opt_ctx_.row_count_;
}
void set_is_do_insert_batch_opt(int64_t row_count)
{
ins_opt_ctx_.set_can_do_insert_batch_opt(row_count);
}
void reset_do_insert_batch_opt()
{
ins_opt_ctx_.reset();
}
void set_enable_strict_defensive_check(bool v)
{
enable_strict_defensive_check_ = v;
}
bool get_enable_strict_defensive_check()
{
return enable_strict_defensive_check_;
}
void set_enable_user_defined_rewrite(bool v)
{
enable_user_defined_rewrite_ = v;
}
bool get_enable_user_defined_rewrite()
{
return enable_user_defined_rewrite_;
}
// release dynamic allocated memory
//
void clear();
public:
ObMultiStmtItem multi_stmt_item_;
ObSQLSessionInfo *session_info_;
share::schema::ObSchemaGetterGuard *schema_guard_;
pl::ObPLBlockNS *secondary_namespace_;
bool plan_cache_hit_;
bool self_add_plan_; //used for retry query, and add plan to plan cache in this query;
int disable_privilege_check_; //internal user set disable privilege check
bool force_print_trace_; // [OUT]if the trace log is enabled by hint
bool is_show_trace_stmt_; // [OUT]
int64_t retry_times_;
char sql_id_[common::OB_MAX_SQL_ID_LENGTH + 1];
ExecType exec_type_;
bool is_prepare_protocol_;
bool is_pre_execute_;
bool is_prepare_stage_;
bool is_dynamic_sql_;
bool is_dbms_sql_;
bool is_cursor_;
bool is_remote_sql_;
uint64_t statement_id_;
common::ObString cur_sql_;
stmt::StmtType stmt_type_;
common::ObFixedArray<ObTablePartitionInfo*, common::ObIAllocator> partition_infos_;
bool is_restore_;
common::ObFixedArray<common::ObString, common::ObIAllocator> related_user_var_names_;
//use for plan cache support dist plan
// 基表location约束,包括TABLE_SCAN算子上的基表和INSERT算子上的基表
common::ObFixedArray<LocationConstraint, common::ObIAllocator> base_constraints_;
// 严格partition wise join约束,要求同一个分组内的基表分区逻辑上和物理上都相等。
// 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移
common::ObFixedArray<ObPwjConstraint *, common::ObIAllocator> strict_constraints_;
// 严格partition wise join约束,要求用一个分组内的基表分区物理上相等。
// 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移
common::ObFixedArray<ObPwjConstraint *, common::ObIAllocator> non_strict_constraints_;
// constraints for duplicate table's replica selection
// if not found values in this array, just use local server's replica.
common::ObFixedArray<ObDupTabConstraint, common::ObIAllocator> dup_table_replica_cons_;
// wether need late compilation
bool need_late_compile_;
// 从resolver传递过来的常量约束
// all_possible_const_param_constraints_ 表示该sql中可能的全部常量约束
// all_plan_const_param_constraints_ 表示该sql中存在的全部常量约束
// 比如:create table t (a bigint, b bigint as (a + 1 + 2), c bigint as (a + 2 + 3), index idx_b(b), index idx_c(c));
// 对于:select * from t where a + 1 + 2 > 0;
// 有:all_plan_const_param_constraints_ = {[1, 2]}, all_possible_const_param_constraints_ = {[1, 2], [2, 3]}
// 对于:select * from t where a + 3 + 4 > 0;
// 有:all_plan_const_param_constraints_ = {}, all_possible_const_param_constraints_ = {[1, 2], [2, 3]}
common::ObIArray<ObPCConstParamInfo> *all_plan_const_param_constraints_;
common::ObIArray<ObPCConstParamInfo> *all_possible_const_param_constraints_;
common::ObIArray<ObPCParamEqualInfo> *all_equal_param_constraints_;
common::ObDList<ObPreCalcExprConstraint> *all_pre_calc_constraints_;
common::ObIArray<ObExprConstraint> *all_expr_constraints_;
common::ObIArray<ObPCPrivInfo> *all_priv_constraints_;
bool need_match_all_params_; //only used for matching plans
bool is_ddl_from_primary_;//备集群从主库同步过来需要处理的ddl sql语句
const sql::ObStmt *cur_stmt_;
const ObPhysicalPlan *cur_plan_;
bool can_reroute_sql_; // 是否可以重新路由
bool is_sensitive_; // 是否含有敏感信息,若有则不记入 sql_audit
bool is_protocol_weak_read_; // record whether proxy set weak read for this request in protocol flag
common::ObFixedArray<int64_t, common::ObIAllocator> multi_stmt_rowkey_pos_;
ObRawExpr *flashback_query_expr_;
ObSpmCacheCtx spm_ctx_;
bool is_execute_call_stmt_;
bool enable_sql_resource_manage_;
uint64_t res_map_rule_id_;
int64_t res_map_rule_param_idx_;
uint64_t res_map_rule_version_;
bool is_text_ps_mode_;
uint64_t first_plan_hash_;
common::ObString first_outline_data_;
bool is_bulk_;
ObInsertRewriteOptCtx ins_opt_ctx_;
union
{
uint32_t flags_;
struct {
uint32_t enable_strict_defensive_check_: 1; //TRUE if the _enable_defensive_check is '2'
uint32_t enable_user_defined_rewrite_ : 1;//TRUE if enable_user_defined_rewrite_rules is open
uint32_t is_from_pl_ : 1;
uint32_t reserved_ : 29;
};
};
TO_STRING_KV(K(stmt_type_));
private:
share::ObFeedbackRerouteInfo *reroute_info_;
};
struct ObQueryCtx
{
public:
ObQueryCtx()
: question_marks_count_(0),
calculable_items_(),
ab_param_exprs_(),
fetch_cur_time_(true),
is_contain_virtual_table_(false),
is_contain_inner_table_(false),
is_contain_select_for_update_(false),
has_dml_write_stmt_(false),
ins_values_batch_opt_(false),
available_tb_id_(common::OB_INVALID_ID - 1),
stmt_count_(0),
subquery_count_(0),
temp_table_count_(0),
anonymous_view_count_(0),
all_user_variable_(),
need_match_all_params_(false),
has_udf_(false),
disable_udf_parallel_(false),
has_is_table_(false),
reference_obj_tables_(),
is_table_gen_col_with_udf_(false),
query_hint_(),
#ifdef OB_BUILD_SPM
is_spm_evolution_(false),
#endif
literal_stmt_type_(stmt::T_NONE),
sql_stmt_(),
sql_stmt_coll_type_(CS_TYPE_INVALID),
prepare_param_count_(0),
is_prepare_stmt_(false),
has_nested_sql_(false),
tz_info_(NULL),
res_map_rule_id_(common::OB_INVALID_ID),
res_map_rule_param_idx_(common::OB_INVALID_INDEX),
root_stmt_(NULL),
udf_has_select_stmt_(false)
{
}
TO_STRING_KV(N_PARAM_NUM, question_marks_count_,
N_FETCH_CUR_TIME, fetch_cur_time_,
K_(calculable_items));
void reset()
{
question_marks_count_ = 0;
calculable_items_.reset();
fetch_cur_time_ = true;
is_contain_virtual_table_ = false;
is_contain_inner_table_ = false;
is_contain_select_for_update_ = false;
has_dml_write_stmt_ = false;
ins_values_batch_opt_ = false;
available_tb_id_ = common::OB_INVALID_ID - 1;
stmt_count_ = 0;
subquery_count_ = 0;
temp_table_count_ = 0;
anonymous_view_count_ = 0;
all_user_variable_.reset();
need_match_all_params_= false;
has_udf_ = false;
disable_udf_parallel_ = false;
has_is_table_ = false;
sql_schema_guard_.reset();
reference_obj_tables_.reset();
is_table_gen_col_with_udf_ = false;
query_hint_.reset();
#ifdef OB_BUILD_SPM
is_spm_evolution_ = false;
#endif
literal_stmt_type_ = stmt::T_NONE;
sql_stmt_.reset();
sql_stmt_coll_type_ = CS_TYPE_INVALID;
prepare_param_count_ = 0;
is_prepare_stmt_ = false;
has_nested_sql_ = false;
tz_info_ = NULL;
res_map_rule_id_ = common::OB_INVALID_ID;
res_map_rule_param_idx_ = common::OB_INVALID_INDEX;
root_stmt_ = NULL;
udf_has_select_stmt_ = false;
}
int64_t get_new_stmt_id() { return stmt_count_++; }
int64_t get_new_subquery_id() { return ++subquery_count_; }
int64_t get_temp_table_id() { return ++temp_table_count_; }
int64_t get_anonymous_view_id() { return ++anonymous_view_count_; }
ObQueryHint &get_query_hint_for_update() { return query_hint_; };
const ObQueryHint &get_query_hint() const { return query_hint_; };
const ObGlobalHint &get_global_hint() const { return query_hint_.get_global_hint(); }
int get_qb_name(int64_t stmt_id, ObString &qb_name) const { return query_hint_.get_qb_name(stmt_id, qb_name); }
void set_literal_stmt_type(const stmt::StmtType type) { literal_stmt_type_ = type; }
stmt::StmtType get_literal_stmt_type() const { return literal_stmt_type_; }
inline common::ObString &get_sql_stmt() { return sql_stmt_; }
inline const common::ObString &get_sql_stmt() const { return sql_stmt_; }
inline void set_sql_stmt(const char *sql, int32_t sql_len) { sql_stmt_.assign_ptr(sql, sql_len); }
inline void set_sql_stmt(const common::ObString sql_stmt) { sql_stmt_ = sql_stmt; }
void set_sql_stmt_coll_type(common::ObCollationType coll_type) { sql_stmt_coll_type_ = coll_type;}
common::ObCollationType get_sql_stmt_coll_type() { return sql_stmt_coll_type_; }
void set_prepare_param_count(const int64_t prepare_param_count) { prepare_param_count_ = prepare_param_count; }
int64_t get_prepare_param_count() const { return prepare_param_count_; }
bool is_prepare_stmt() const { return is_prepare_stmt_; }
void set_is_prepare_stmt(bool is_prepare) { is_prepare_stmt_ = is_prepare; }
bool has_nested_sql() const { return has_nested_sql_; }
void set_has_nested_sql(bool has_nested_sql) { has_nested_sql_ = has_nested_sql; }
void set_timezone_info(const common::ObTimeZoneInfo *tz_info) { tz_info_ = tz_info; }
const common::ObTimeZoneInfo *get_timezone_info() const { return tz_info_; }
public:
static const int64_t CALCULABLE_EXPR_NUM = 1;
typedef common::ObSEArray<ObHiddenColumnItem, CALCULABLE_EXPR_NUM, common::ModulePageAllocator, true> CalculableItems;
public:
int64_t question_marks_count_;
CalculableItems calculable_items_;
//array binding param exprs, mark the all array binding param expr in the batch stmt
common::ObSEArray<ObRawExpr*, 4, common::ModulePageAllocator, true> ab_param_exprs_;
common::ObSArray<share::schema::ObSchemaObjVersion> global_dependency_tables_;
bool fetch_cur_time_;
bool is_contain_virtual_table_;
bool is_contain_inner_table_;
bool is_contain_select_for_update_;
bool has_dml_write_stmt_;
bool ins_values_batch_opt_;
uint64_t available_tb_id_;
int64_t stmt_count_;
int64_t subquery_count_;
int64_t temp_table_count_;
int64_t anonymous_view_count_;
// record all system variables or user variables in this statement
common::ObSArray<ObVarInfo, common::ModulePageAllocator, true> variables_;
common::ObSArray<ObPCConstParamInfo, common::ModulePageAllocator, true> all_plan_const_param_constraints_;
common::ObSArray<ObPCConstParamInfo, common::ModulePageAllocator, true> all_possible_const_param_constraints_;
common::ObSArray<ObPCParamEqualInfo, common::ModulePageAllocator, true> all_equal_param_constraints_;
common::ObSEArray<ObRawExpr*, 4, common::ModulePageAllocator, true> var_init_exprs_;
common::ObDList<ObPreCalcExprConstraint> all_pre_calc_constraints_;
common::ObSArray<ObExprConstraint, common::ModulePageAllocator, true> all_expr_constraints_;
common::ObSArray<ObPCPrivInfo, common::ModulePageAllocator, true> all_priv_constraints_;
common::ObSArray<ObUserVarIdentRawExpr *, common::ModulePageAllocator, true> all_user_variable_;
common::hash::ObHashMap<uint64_t, ObObj, common::hash::NoPthreadDefendMode> calculable_expr_results_;
bool need_match_all_params_; //only used for matching plans
bool has_udf_;
bool disable_udf_parallel_; //used to deterministic pl udf parallel execute
bool has_is_table_; // used to mark query has information schema table
ObSqlSchemaGuard sql_schema_guard_;
share::schema::ObReferenceObjTable reference_obj_tables_;
bool is_table_gen_col_with_udf_; // for data consistent check
ObQueryHint query_hint_;
#ifdef OB_BUILD_SPM
bool is_spm_evolution_;
#endif
stmt::StmtType literal_stmt_type_;
common::ObString sql_stmt_;
common::ObCollationType sql_stmt_coll_type_;
int64_t prepare_param_count_;
bool is_prepare_stmt_;
bool has_nested_sql_;
const common::ObTimeZoneInfo *tz_info_;
uint64_t res_map_rule_id_;
int64_t res_map_rule_param_idx_;
ObDMLStmt *root_stmt_;
bool udf_has_select_stmt_; // udf has select stmt, not contain other dml stmt
};
} /* ns sql*/
} /* ns oceanbase */
#endif //OCEANBASE_SQL_CONTEXT_