forked from huawei/openGauss-server
b_sql_plugin插件内核适配修改
This commit is contained in:
parent
c10de5f198
commit
59ff629c95
|
@ -97,6 +97,7 @@ PG_MODULE_MAGIC;
|
||||||
|
|
||||||
extern "C" void _PG_init(void);
|
extern "C" void _PG_init(void);
|
||||||
extern "C" void _PG_fini(void);
|
extern "C" void _PG_fini(void);
|
||||||
|
extern "C" void set_gsaudit_prehook(ProcessUtility_hook_type func);
|
||||||
|
|
||||||
#define POLICY_STR_BUFF_LEN 512
|
#define POLICY_STR_BUFF_LEN 512
|
||||||
#define POLICY_TMP_BUFF_LEN 256
|
#define POLICY_TMP_BUFF_LEN 256
|
||||||
|
@ -1781,7 +1782,7 @@ void install_audit_hook()
|
||||||
* preserve the chains.
|
* preserve the chains.
|
||||||
*/
|
*/
|
||||||
next_ExecutorStart_hook = ExecutorStart_hook;
|
next_ExecutorStart_hook = ExecutorStart_hook;
|
||||||
next_ProcessUtility_hook = ProcessUtility_hook;
|
set_gsaudit_prehook(ProcessUtility_hook);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Install audit hooks, the interface for GaussDB kernel user as below
|
* Install audit hooks, the interface for GaussDB kernel user as below
|
||||||
|
@ -1821,6 +1822,19 @@ void install_label_hook()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is used for setting prev_ProcessUtility to rewrite
|
||||||
|
* standard_ProcessUtility by other extension.
|
||||||
|
*/
|
||||||
|
void set_gsaudit_prehook(ProcessUtility_hook_type func)
|
||||||
|
{
|
||||||
|
if (next_ProcessUtility_hook != NULL) {
|
||||||
|
ereport(WARNING, (errmsg("next_ProcessUtility_hook in security_plugin cannot be set since it's not null")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
next_ProcessUtility_hook = func;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define GUC variables and install hooks upon module load.
|
* Define GUC variables and install hooks upon module load.
|
||||||
* NOTE: _PG_init will be invoked(installed) many times
|
* NOTE: _PG_init will be invoked(installed) many times
|
||||||
|
|
|
@ -52,6 +52,10 @@ static_assert(sizeof(false) == sizeof(char), "illegal bool size");
|
||||||
static struct HTAB* nameHash = NULL;
|
static struct HTAB* nameHash = NULL;
|
||||||
static struct HTAB* oidHash = NULL;
|
static struct HTAB* oidHash = NULL;
|
||||||
|
|
||||||
|
/* for b_sql_plugin */
|
||||||
|
struct HTAB* b_nameHash = NULL;
|
||||||
|
struct HTAB* b_oidHash = NULL;
|
||||||
|
|
||||||
const int g_nfuncgroups = sizeof(g_func_groups) / sizeof(FuncGroup);
|
const int g_nfuncgroups = sizeof(g_func_groups) / sizeof(FuncGroup);
|
||||||
|
|
||||||
static const int MAX_PROC_NAME_LEN = NAMEDATALEN;
|
static const int MAX_PROC_NAME_LEN = NAMEDATALEN;
|
||||||
|
@ -114,7 +118,11 @@ static const FuncGroup* NameHashTableAccess(HASHACTION action, const char* name,
|
||||||
|
|
||||||
Assert(name != NULL);
|
Assert(name != NULL);
|
||||||
|
|
||||||
|
if (DB_IS_CMPT(B_FORMAT) && b_nameHash != NULL && u_sess->attr.attr_sql.b_sql_plugin) {
|
||||||
|
result = (HashEntryNameToFuncGroup *)hash_search(b_nameHash, &temp_name, action, &found);
|
||||||
|
} else {
|
||||||
result = (HashEntryNameToFuncGroup *)hash_search(nameHash, &temp_name, action, &found);
|
result = (HashEntryNameToFuncGroup *)hash_search(nameHash, &temp_name, action, &found);
|
||||||
|
}
|
||||||
if (action == HASH_ENTER) {
|
if (action == HASH_ENTER) {
|
||||||
Assert(!found);
|
Assert(!found);
|
||||||
result->group = group;
|
result->group = group;
|
||||||
|
@ -136,7 +144,11 @@ static const Builtin_func* OidHashTableAccess(HASHACTION action, Oid oid, const
|
||||||
bool found = false;
|
bool found = false;
|
||||||
Assert(oid > 0);
|
Assert(oid > 0);
|
||||||
|
|
||||||
|
if (DB_IS_CMPT(B_FORMAT) && b_oidHash != NULL && u_sess->attr.attr_sql.b_sql_plugin) {
|
||||||
|
result = (HashEntryOidToBuiltinFunc *)hash_search(b_oidHash, &oid, action, &found);
|
||||||
|
} else {
|
||||||
result = (HashEntryOidToBuiltinFunc *)hash_search(oidHash, &oid, action, &found);
|
result = (HashEntryOidToBuiltinFunc *)hash_search(oidHash, &oid, action, &found);
|
||||||
|
}
|
||||||
if (action == HASH_ENTER) {
|
if (action == HASH_ENTER) {
|
||||||
Assert(!found);
|
Assert(!found);
|
||||||
result->func = func;
|
result->func = func;
|
||||||
|
|
|
@ -287,6 +287,10 @@ Query* transformTopLevelStmt(ParseState* pstate, Node* parseTree, bool isFirstNo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (u_sess->hook_cxt.transformStmtHook != NULL) {
|
||||||
|
return
|
||||||
|
((transformStmtFunc)(u_sess->hook_cxt.transformStmtHook))(pstate, parseTree, isFirstNode, isCreateView);
|
||||||
|
}
|
||||||
return transformStmt(pstate, parseTree, isFirstNode, isCreateView);
|
return transformStmt(pstate, parseTree, isFirstNode, isCreateView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@
|
||||||
#include "instruments/instr_workload.h"
|
#include "instruments/instr_workload.h"
|
||||||
#include "gs_policy/policy_common.h"
|
#include "gs_policy/policy_common.h"
|
||||||
#include "utils/knl_relcache.h"
|
#include "utils/knl_relcache.h"
|
||||||
|
#include "commands/extension.h"
|
||||||
#ifndef WIN32_ONLY_COMPILER
|
#ifndef WIN32_ONLY_COMPILER
|
||||||
#include "dynloader.h"
|
#include "dynloader.h"
|
||||||
#else
|
#else
|
||||||
|
@ -2703,6 +2704,10 @@ void PostgresInitializer::InitExtensionVariable()
|
||||||
if (init_session_vars != NULL)
|
if (init_session_vars != NULL)
|
||||||
(*init_session_vars)();
|
(*init_session_vars)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check whether the extension has been created */
|
||||||
|
const char* b_sql_plugin = "b_sql_plugin";
|
||||||
|
u_sess->attr.attr_sql.b_sql_plugin = CheckIfExtensionExists(b_sql_plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostgresInitializer::FinishInit()
|
void PostgresInitializer::FinishInit()
|
||||||
|
|
|
@ -104,10 +104,23 @@ void InitHypopg()
|
||||||
isExplain = false;
|
isExplain = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is used for setting prev_utility_hook to rewrite
|
||||||
|
* standard_ProcessUtility by extension.
|
||||||
|
*/
|
||||||
|
void set_hypopg_prehook(ProcessUtility_hook_type func)
|
||||||
|
{
|
||||||
|
if (prev_utility_hook != NULL) {
|
||||||
|
ereport(WARNING, (errmsg("prev_utility_hook in hypopg cannot be set since it's not null")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prev_utility_hook = func;
|
||||||
|
}
|
||||||
|
|
||||||
void hypopg_register_hook()
|
void hypopg_register_hook()
|
||||||
{
|
{
|
||||||
// register hooks
|
// register hooks
|
||||||
prev_utility_hook = ProcessUtility_hook;
|
set_hypopg_prehook(ProcessUtility_hook);
|
||||||
ProcessUtility_hook = hypo_utility_hook;
|
ProcessUtility_hook = hypo_utility_hook;
|
||||||
|
|
||||||
prev_ExecutorEnd_hook = ExecutorEnd_hook;
|
prev_ExecutorEnd_hook = ExecutorEnd_hook;
|
||||||
|
|
|
@ -1175,6 +1175,10 @@ void CreateExtension(CreateExtensionStmt* stmt)
|
||||||
FEATURE_NOT_PUBLIC_ERROR("EXTENSION is not yet supported.");
|
FEATURE_NOT_PUBLIC_ERROR("EXTENSION is not yet supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pg_strcasecmp(stmt->extname, "b_sql_plugin") == 0 && !DB_IS_CMPT(B_FORMAT)) {
|
||||||
|
ereport(ERROR,
|
||||||
|
(errmsg("please create extension \"%s\" with B type DBCOMPATIBILITY", stmt->extname)));
|
||||||
|
}
|
||||||
/* Check extension name validity before any filesystem access */
|
/* Check extension name validity before any filesystem access */
|
||||||
check_valid_extension_name(stmt->extname);
|
check_valid_extension_name(stmt->extname);
|
||||||
|
|
||||||
|
@ -1414,6 +1418,10 @@ void CreateExtension(CreateExtensionStmt* stmt)
|
||||||
|
|
||||||
u_sess->exec_cxt.extension_is_valid = true;
|
u_sess->exec_cxt.extension_is_valid = true;
|
||||||
|
|
||||||
|
if (pg_strcasecmp(stmt->extname, "b_sql_plugin") == 0) {
|
||||||
|
u_sess->attr.attr_sql.b_sql_plugin = true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert new tuple into pg_extension, and create dependency entries.
|
* Insert new tuple into pg_extension, and create dependency entries.
|
||||||
*/
|
*/
|
||||||
|
@ -2917,3 +2925,26 @@ void RepallocSessionVarsArrayIfNecessary()
|
||||||
u_sess->attr.attr_common.extension_session_vars_array_size = currExtensionNum * 2;
|
u_sess->attr.attr_common.extension_session_vars_array_size = currExtensionNum * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CheckIfExtensionExists(const char* extname)
|
||||||
|
{
|
||||||
|
Relation rel;
|
||||||
|
ScanKeyData entry[1];
|
||||||
|
SysScanDesc scandesc;
|
||||||
|
HeapTuple tuple;
|
||||||
|
bool isExists = false;
|
||||||
|
|
||||||
|
/* search pg_extension to check if extension exists. */
|
||||||
|
rel = heap_open(ExtensionRelationId, AccessShareLock);
|
||||||
|
ScanKeyInit(&entry[0], Anum_pg_extension_extname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(extname));
|
||||||
|
scandesc = systable_beginscan(rel, ExtensionNameIndexId, true, NULL, 1, entry);
|
||||||
|
tuple = systable_getnext(scandesc);
|
||||||
|
|
||||||
|
isExists = HeapTupleIsValid(tuple);
|
||||||
|
|
||||||
|
systable_endscan(scandesc);
|
||||||
|
|
||||||
|
heap_close(rel, AccessShareLock);
|
||||||
|
|
||||||
|
return isExists;
|
||||||
|
}
|
||||||
|
|
|
@ -124,6 +124,19 @@ static const AuditFuncMap g_auditFuncMap[] = {
|
||||||
};
|
};
|
||||||
static const int g_auditFuncMapNum = sizeof(g_auditFuncMap) / sizeof(AuditFuncMap);
|
static const int g_auditFuncMapNum = sizeof(g_auditFuncMap) / sizeof(AuditFuncMap);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is used for setting prev_ProcessUtility to rewrite
|
||||||
|
* standard_ProcessUtility by extension.
|
||||||
|
*/
|
||||||
|
void set_pgaudit_prehook(ProcessUtility_hook_type func)
|
||||||
|
{
|
||||||
|
if (prev_ProcessUtility != NULL) {
|
||||||
|
ereport(WARNING, (errmsg("prev_ProcessUtility in pgaudit cannot be set since it's not null")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prev_ProcessUtility = func;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Brief : perfstat_agent_init()
|
* Brief : perfstat_agent_init()
|
||||||
* Description : Module load callback.
|
* Description : Module load callback.
|
||||||
|
@ -137,7 +150,7 @@ void pgaudit_agent_init(void)
|
||||||
}
|
}
|
||||||
prev_ExecutorEnd = ExecutorEnd_hook;
|
prev_ExecutorEnd = ExecutorEnd_hook;
|
||||||
ExecutorEnd_hook = pgaudit_ExecutorEnd;
|
ExecutorEnd_hook = pgaudit_ExecutorEnd;
|
||||||
prev_ProcessUtility = ProcessUtility_hook;
|
set_pgaudit_prehook(ProcessUtility_hook);
|
||||||
ProcessUtility_hook = (ProcessUtility_hook_type)pgaudit_ProcessUtility;
|
ProcessUtility_hook = (ProcessUtility_hook_type)pgaudit_ProcessUtility;
|
||||||
u_sess->exec_cxt.g_pgaudit_agent_attached = true;
|
u_sess->exec_cxt.g_pgaudit_agent_attached = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,9 @@
|
||||||
#include "catalog/pg_database.h"
|
#include "catalog/pg_database.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
|
#include "catalog/pg_extension.h"
|
||||||
#include "commands/async.h"
|
#include "commands/async.h"
|
||||||
|
#include "commands/extension.h"
|
||||||
#include "commands/matview.h"
|
#include "commands/matview.h"
|
||||||
#include "commands/prepare.h"
|
#include "commands/prepare.h"
|
||||||
#include "commands/user.h"
|
#include "commands/user.h"
|
||||||
|
@ -819,6 +821,22 @@ void client_read_ended(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ENABLE_MULTIPLE_NODES
|
||||||
|
#define INIT_PLUGIN_OBJECT "init_plugin_object"
|
||||||
|
void InitBSqlPluginHookIfNeeded()
|
||||||
|
{
|
||||||
|
const char* b_sql_plugin = "b_sql_plugin";
|
||||||
|
CFunInfo tmpCF;
|
||||||
|
if (!CheckIfExtensionExists(b_sql_plugin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpCF = load_external_function(b_sql_plugin, INIT_PLUGIN_OBJECT, false, false);
|
||||||
|
if (tmpCF.user_fn != NULL) {
|
||||||
|
((void* (*)(void))(tmpCF.user_fn))();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do raw parsing (only).
|
* Do raw parsing (only).
|
||||||
|
@ -847,12 +865,10 @@ List* pg_parse_query(const char* query_string, List** query_string_locationlist)
|
||||||
|
|
||||||
List* (*parser_hook)(const char*, List**) = raw_parser;
|
List* (*parser_hook)(const char*, List**) = raw_parser;
|
||||||
#ifndef ENABLE_MULTIPLE_NODES
|
#ifndef ENABLE_MULTIPLE_NODES
|
||||||
if (u_sess->attr.attr_sql.enable_custom_parser) {
|
|
||||||
int id = GetCustomParserId();
|
int id = GetCustomParserId();
|
||||||
if (id >= 0 && g_instance.raw_parser_hook[id] != NULL) {
|
if (id >= 0 && g_instance.raw_parser_hook[id] != NULL) {
|
||||||
parser_hook = (List* (*)(const char*, List**))g_instance.raw_parser_hook[id];
|
parser_hook = (List* (*)(const char*, List**))g_instance.raw_parser_hook[id];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
raw_parsetree_list = parser_hook(query_string, query_string_locationlist);
|
raw_parsetree_list = parser_hook(query_string, query_string_locationlist);
|
||||||
|
|
||||||
|
@ -7554,6 +7570,12 @@ int PostgresMain(int argc, char* argv[], const char* dbname, const char* usernam
|
||||||
if (IS_PGXC_COORDINATOR)
|
if (IS_PGXC_COORDINATOR)
|
||||||
init_set_params_htab();
|
init_set_params_htab();
|
||||||
|
|
||||||
|
#ifndef ENABLE_MULTIPLE_NODES
|
||||||
|
if (u_sess->proc_cxt.MyDatabaseId != InvalidOid && DB_IS_CMPT(B_FORMAT)) {
|
||||||
|
InitBSqlPluginHookIfNeeded();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember stand-alone backend startup time
|
* Remember stand-alone backend startup time
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -767,6 +767,10 @@ static void init_session_share_memory()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ENABLE_MULTIPLE_NODES
|
||||||
|
extern void InitBSqlPluginHookIfNeeded();
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool InitSession(knl_session_context* session)
|
static bool InitSession(knl_session_context* session)
|
||||||
{
|
{
|
||||||
/* non't send ereport to client now */
|
/* non't send ereport to client now */
|
||||||
|
@ -840,6 +844,13 @@ static bool InitSession(knl_session_context* session)
|
||||||
char* username = session->proc_cxt.MyProcPort->user_name;
|
char* username = session->proc_cxt.MyProcPort->user_name;
|
||||||
t_thrd.proc_cxt.PostInit->SetDatabaseAndUser(dbname, InvalidOid, username);
|
t_thrd.proc_cxt.PostInit->SetDatabaseAndUser(dbname, InvalidOid, username);
|
||||||
t_thrd.proc_cxt.PostInit->InitSession();
|
t_thrd.proc_cxt.PostInit->InitSession();
|
||||||
|
|
||||||
|
#ifndef ENABLE_MULTIPLE_NODES
|
||||||
|
if (u_sess->proc_cxt.MyDatabaseId != InvalidOid && DB_IS_CMPT(B_FORMAT)) {
|
||||||
|
InitBSqlPluginHookIfNeeded();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Assert(CheckMyDatabaseMatch());
|
Assert(CheckMyDatabaseMatch());
|
||||||
|
|
||||||
SetProcessingMode(NormalProcessing);
|
SetProcessingMode(NormalProcessing);
|
||||||
|
|
|
@ -48,5 +48,5 @@ extern bool CheckExtensionValid(const char *extentName);
|
||||||
extern bool CheckExtensionSqlValid(char *queryString);
|
extern bool CheckExtensionSqlValid(char *queryString);
|
||||||
|
|
||||||
extern void RepallocSessionVarsArrayIfNecessary();
|
extern void RepallocSessionVarsArrayIfNecessary();
|
||||||
|
extern bool CheckIfExtensionExists(const char* extname);
|
||||||
#endif /* EXTENSION_H */
|
#endif /* EXTENSION_H */
|
||||||
|
|
|
@ -238,6 +238,7 @@ typedef struct knl_session_attr_sql {
|
||||||
#ifndef ENABLE_MULTIPLE_NODES
|
#ifndef ENABLE_MULTIPLE_NODES
|
||||||
bool enable_custom_parser;
|
bool enable_custom_parser;
|
||||||
#endif
|
#endif
|
||||||
|
bool b_sql_plugin;
|
||||||
} knl_session_attr_sql;
|
} knl_session_attr_sql;
|
||||||
|
|
||||||
#endif /* SRC_INCLUDE_KNL_KNL_SESSION_ATTR_SQL */
|
#endif /* SRC_INCLUDE_KNL_KNL_SESSION_ATTR_SQL */
|
||||||
|
|
|
@ -2623,6 +2623,7 @@ typedef struct knl_u_clientConnTime_context {
|
||||||
|
|
||||||
typedef struct knl_u_hook_context {
|
typedef struct knl_u_hook_context {
|
||||||
void *analyzerRoutineHook;
|
void *analyzerRoutineHook;
|
||||||
|
void *transformStmtHook;
|
||||||
} knl_u_hook_context;
|
} knl_u_hook_context;
|
||||||
|
|
||||||
typedef struct knl_session_context {
|
typedef struct knl_session_context {
|
||||||
|
|
|
@ -88,6 +88,8 @@ typedef struct AnalyzerRoutine {
|
||||||
transformSelectStmtHook transSelect;
|
transformSelectStmtHook transSelect;
|
||||||
} AnalyzerRoutine;
|
} AnalyzerRoutine;
|
||||||
|
|
||||||
|
typedef Query* (*transformStmtFunc)(ParseState* pstate, Node* parseTree, bool isFirstNode, bool isCreateView);
|
||||||
|
|
||||||
extern void transformOperatorPlus(ParseState* pstate, Node** whereClause);
|
extern void transformOperatorPlus(ParseState* pstate, Node** whereClause);
|
||||||
extern bool IsColumnRefPlusOuterJoin(const ColumnRef* cf);
|
extern bool IsColumnRefPlusOuterJoin(const ColumnRef* cf);
|
||||||
extern PlusJoinRTEItem* makePlusJoinRTEItem(RangeTblEntry* rte, bool hasplus);
|
extern PlusJoinRTEItem* makePlusJoinRTEItem(RangeTblEntry* rte, bool hasplus);
|
||||||
|
|
Loading…
Reference in New Issue