* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* 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 PSL v2 for more details.
* ---------------------------------------------------------------------------------------
*
* parse_hint.h
* Table parse hint header file, include struct member declaration.
*
*
* IDENTIFICATION
* src/include/parser/parse_hint.h
*
* ---------------------------------------------------------------------------------------
*/
#ifndef PARSE_HINT_h
#define PARSE_HINT_h
#include "optimizer/streamplan.h"
#include "parser/parse_node.h"
#include "tcop/dest.h"
#include "utils/guc.h"
#include "utils/plancache.h"
#define HINT_NESTLOOP "NestLoop"
#define HINT_MERGEJOIN "MergeJoin"
#define HINT_HASHJOIN "HashJoin"
#define HINT_NO "No"
#define HINT_LEADING "Leading"
#define HINT_ROWS "Rows"
#define HINT_BROADCAST "Broadcast"
#define HINT_REDISTRIBUTE "Redistribute"
#define HINT_BLOCKNAME "BlockName"
#define HINT_TABLESCAN "TableScan"
#define HINT_INDEXSCAN "IndexScan"
#define HINT_INDEXONLYSCAN "IndexOnlyScan"
#define HINT_SKEW "Skew"
#define HINT_MULTI_NODE "MultiNode"
#define HINT_NULL "Null"
#define HINT_TRUE "True"
#define HINT_FALSE "False"
#define HINT_PRED_PUSH "Predpush"
#define HINT_PRED_PUSH_SAME_LEVEL "Predpush_Same_Level"
#define HINT_REWRITE "Rewrite_rule"
#define HINT_GATHER "Gather"
#define HINT_NO_EXPAND "No_expand"
#define HINT_SET "Set"
#define HINT_CPLAN "Use_cplan"
#define HINT_GPLAN "Use_gplan"
#define HINT_CHOOSE_ADAPTIVE_GPLAN "Choose_adaptive_gplan"
#define HINT_NO_GPC "No_gpc"
#define HINT_SQL_IGNORE "Ignore_error"
#define BLOCK_COMMENT_START "/*"
#define BLOCK_COMMENT_END "*/"
#define HINT_COMMENT_KEYWORD "+"
#define HINT_START BLOCK_COMMENT_START HINT_COMMENT_KEYWORD
#define HINT_END BLOCK_COMMENT_END
typedef struct pull_hint_warning_context {
List* warning;
} pull_hint_warning_context;
#define append_warning_to_list(root, hint, format, ...) \
do { \
StringInfoData buf; \
char* hint_string = descHint(hint); \
initStringInfo(&buf); \
appendStringInfo(&buf, format, ##__VA_ARGS__); \
root->glob->hint_warning = lappend(root->glob->hint_warning, makeString(buf.data)); \
pfree(hint_string); \
} while (0)
extern THR_LOCAL List* hint_list;
extern THR_LOCAL List* hint_warning;
typedef enum HintKeyword {
HINT_KEYWORD_NESTLOOP = 0,
HINT_KEYWORD_MERGEJOIN,
HINT_KEYWORD_HASHJOIN,
HINT_KEYWORD_LEADING,
HINT_KEYWORD_ROWS,
HINT_KEYWORD_BROADCAST,
HINT_KEYWORD_REDISTRIBUTE,
HINT_KEYWORD_BLOCKNAME,
HINT_KEYWORD_TABLESCAN,
HINT_KEYWORD_INDEXSCAN,
HINT_KEYWORD_INDEXONLYSCAN,
HINT_KEYWORD_SKEW,
HINT_KEYWORD_PREDPUSH,
HINT_KEYWORD_PREDPUSH_SAME_LEVEL,
HINT_KEYWORD_REWRITE,
HINT_KEYWORD_GATHER,
HINT_KEYWORD_NO_EXPAND,
HINT_KEYWORD_SET,
HINT_KEYWORD_CPLAN,
HINT_KEYWORD_GPLAN,
HINT_KEYWORD_IGNORE,
HINT_KEYWORD_CHOOSE_ADAPTIVE_GPLAN,
HINT_KEYWORD_NO_GPC,
} HintKeyword;
typedef enum HintStatus {
HINT_STATE_NOTUSED = 0,
HINT_STATE_USED,
HINT_STATE_DUPLICATION,
HINT_STATE_ERROR
} HintStatus;
typedef enum GatherSource {
HINT_GATHER_GUC = 0,
HINT_GATHER_REL,
HINT_GATHER_JOIN,
HINT_GATHER_ALL,
HINT_GATHER_UNKNOWN
} GatherSource;
struct Hint {
NodeTag type;
List* relnames;
HintKeyword hint_keyword;
HintStatus state;
};
typedef struct LeadingHint {
Hint base;
bool join_order_hint;
} LeadingHint;
typedef struct JoinMethodHint {
Hint base;
bool negative;
Relids joinrelids;
Relids inner_joinrelids;
} JoinMethodHint;
typedef enum RowsValueType {
RVT_ABSOLUTE,
RVT_ADD,
RVT_SUB,
RVT_MULTI
} RowsValueType;
typedef struct RowsHint {
Hint base;
Relids joinrelids;
char* rows_str;
RowsValueType value_type;
double rows;
} RowsHint;
typedef struct StreamHint {
Hint base;
bool negative;
Relids joinrelids;
StreamType stream_type;
} StreamHint;
typedef struct BlockNameHint {
Hint base;
} BlockNameHint;
typedef struct ScanMethodHint {
Hint base;
bool negative;
Relids relid;
List* indexlist;
} ScanMethodHint;
typedef struct SkewHint {
Hint base;
Relids relid;
List* column_list;
List* value_list;
} SkewHint;
typedef struct MultiNodeHint {
Hint base;
bool multi_node_hint;
} MultiNodeHint;
typedef struct SkewRelInfo {
NodeTag type;
char* relation_name;
Oid relation_oid;
RangeTblEntry* rte;
RangeTblEntry* parent_rte;
} SkewRelInfo;
typedef struct SkewColumnInfo {
NodeTag type;
Oid relation_Oid;
char* column_name;
AttrNumber attnum;
Oid column_typid;
Expr* expr;
} SkewColumnInfo;
typedef struct SkewValueInfo {
NodeTag type;
bool support_redis;
Const* const_value;
} SkewValueInfo;
typedef struct SkewHintTransf {
NodeTag type;
SkewHint* before;
List* rel_info_list;
List* column_info_list;
List* value_info_list;
} SkewHintTransf;
typedef struct PredpushHint {
Hint base;
bool negative;
char *dest_name;
int dest_id;
Relids candidates;
} PredpushHint;
typedef struct PredpushSameLevelHint {
Hint base;
bool negative;
char *dest_name;
int dest_id;
Relids candidates;
} PredpushSameLevelHint;
typedef struct RewriteHint {
Hint base;
List* param_names;
unsigned int param_bits;
} RewriteHint;
typedef struct GatherHint {
Hint base;
GatherSource source;
} GatherHint;
typedef struct NoExpandHint {
Hint base;
} NoExpandHint;
typedef struct SetHint {
Hint base;
char* name;
char* value;
} SetHint;
typedef struct PlanCacheHint {
Hint base;
bool chooseCustomPlan;
GplanSelectionMethod method;
} PlanCacheHint;
typedef struct NoGPCHint {
Hint base;
} NoGPCHint;
typedef struct SqlIgnoreHint {
Hint base;
bool sql_ignore_hint;
} SqlIgnoreHint;
typedef struct hintKeyword {
const char* name;
int value;
} hintKeyword;
extern HintState* HintStateCreate();
extern HintState* create_hintstate(const char* hints);
extern HintState* create_hintstate_worker(const char* hint_str);
extern List* find_specific_join_hint(
HintState* hstate, Relids joinrelids, Relids innerrelids, HintKeyword keyWord, bool leading = true);
extern List* find_specific_scan_hint(HintState* hstate, Relids relids, HintKeyword keyWord);
extern ScanMethodHint* find_scan_hint(HintState* hstate, Relids relid, HintKeyword keyWord);
extern char* descHint(Hint* hint);
extern void hintDelete(Hint* hint);
extern void desc_hint_in_state(PlannerInfo* root, HintState* hstate);
extern void transform_hints(PlannerInfo* root, Query* parse, HintState* hstate);
extern void check_scan_hint_validity(PlannerInfo* root);
extern void adjust_scanhint_relid(HintState* hstate, Index oldIdx, Index newIdx);
extern bool pull_hint_warning_walker(Node* node, pull_hint_warning_context* context);
extern List* retrieve_query_hint_warning(Node* parse);
extern void output_utility_hint_warning(Node* query, int lev);
extern void output_hint_warning(List* warning, int lev);
extern void HintStateDelete(HintState* hintState);
extern bool permit_predpush(PlannerInfo *root);
extern bool permit_from_rewrite_hint(PlannerInfo *root, unsigned int params);
extern Relids predpush_candidates_same_level(PlannerInfo *root);
extern bool is_predpush_same_level_matched(PredpushSameLevelHint* hint, Relids relids, ParamPathInfo* ppi);
extern bool permit_gather(PlannerInfo *root, GatherSource src = HINT_GATHER_GUC);
extern GatherSource get_gather_hint_source(PlannerInfo *root);
extern bool check_set_hint_in_white_list(const char* name);
extern bool has_no_expand_hint(Query* subquery);
extern bool has_no_gpc_hint(HintState* hintState);
extern void RemoveQueryHintByType(Query* query, HintKeyword hint);
extern bool CheckNodeNameHint(HintState* hintstate);
#define skip_space(str) \
while (isspace(*str)) \
str++;
#endif