diff --git a/src/common/interfaces/libpq/fe-exec.cpp b/src/common/interfaces/libpq/fe-exec.cpp index 3f864123c25ce221ecd5e2755c8931b007d74812..7582b88568db0ce1b5c8b656134825d7411085f3 100644 --- a/src/common/interfaces/libpq/fe-exec.cpp +++ b/src/common/interfaces/libpq/fe-exec.cpp @@ -18,6 +18,7 @@ #include #include #include +#include "libpq/LocalTable.h" #include "libpq/libpq-fe.h" #include "libpq/libpq-int.h" @@ -44,6 +45,8 @@ #endif #endif /* HAVE_CE */ + +Client client; /* keep this in same order as ExecStatusType in libpq-fe.h */ char* const pgresStatus[] = {"PGRES_EMPTY_QUERY", "PGRES_COMMAND_OK", @@ -1204,8 +1207,54 @@ fail: * Returns: 1 if successfully submitted * 0 if error (conn->errorMessage is set) */ -int PQsendQuery(PGconn* conn, const char* query) +int PQsendQuery(PGconn* conn, const char* query)//改这好insert要改成 (pos=,pt) 原语句应该是 (pt) { + string qs_cpy(query); + string qs_seven(qs_cpy,0,7); + transform(qs_seven.begin(), qs_seven.end(), qs_seven.begin(), (int(*)(int))tolower); + string temp; + if(qs_seven=="*insert"||qs_seven=="*select") + { + //插入时,原语句是 *Insert into table values('pt'); 表结构是cd ct密文(加密列) + //这里要加上根据明文在本地表中计算pos,并改写sql 目标"Insert into table values(pos=15,'pt');" 交给密态功能去加密 + if (qs_seven=="*insert")//要改写 + { + int qs_pre_pos = qs_cpy.find("("); + string qs_pre(qs_cpy, 1, qs_pre_pos);//Insert into table values( + int pt_begin=qs_cpy.find("'", qs_pre_pos); + int pt_end=qs_cpy.find("'", pt_begin+1); + string plaintext(qs_cpy, pt_begin+1, pt_end - pt_begin-1); + int pos=client.insert_table(plaintext); + temp=qs_pre + "pos=" + to_string(pos) + "," + "'" + plaintext + "');"; + } + + //搜索时,原语句是"*Select name,card from talbe where plaintext>'abc' and plaintext<='bcd';" + //where pt>'ptmin' and pt<='ptmax'要改成pos> and pos<= 目标"Select name,card from talbe where pos>8 and pos<=15;" + if(qs_seven=="*select") + { + string qs_cpy_lower(qs_cpy); + transform(qs_cpy_lower.begin(), qs_cpy_lower.end(), qs_cpy_lower.begin(), (int(*)(int))tolower); + int qs_pre_pos = qs_cpy_lower.find("where"); + string qs_pre(qs_cpy, 1, qs_pre_pos + 5);//Select name,card from talbe where //where后有个空格 + //cout <'", qs_pre_pos); + int ptmin_end = qs_cpy.find("'",ptmin_begin+2); + string ptmin(qs_cpy, ptmin_begin + 2, ptmin_end - ptmin_begin - 2); + int ptmax_begin = qs_cpy.find("<='", qs_pre_pos); + int ptmax_end = qs_cpy.find("'", ptmax_begin + 3); + string ptmax(qs_cpy, ptmax_begin + 3, ptmax_end - ptmax_begin - 3); + temp=qs_pre+"pos>"+ to_string(client.search_left(ptmin)) +" pos<="+ to_string(client.search_right(ptmax)) +";"; + } + } + else + { + temp = query; + } + const char* query_changed = temp.c_str(); + query=query_changed; + + if (!PQsendQueryStart(conn)) return 0; @@ -1216,7 +1265,7 @@ int PQsendQuery(PGconn* conn, const char* query) #ifdef HAVE_CE StatementData statementData (conn, query); - if (conn->client_logic->enable_client_encryption) { + if (conn->client_logic->enable_client_encryption) {//开启了密态 #if ((!defined(ENABLE_MULTIPLE_NODES)) && (!defined(ENABLE_PRIVATEGAUSS))) conn->client_logic->query_type = CE_IGNORE; #endif @@ -1224,7 +1273,7 @@ int PQsendQuery(PGconn* conn, const char* query) bool clientLogicRet = Processor::run_pre_query(&statementData); if (!clientLogicRet) return 0; - query = statementData.params.adjusted_query; + query = statementData.params.adjusted_query;//const??在这改成的加密的内容,所以这之后insert要改成 (pos= ,ct) } else { conn->client_logic->disable_once = false; } @@ -1235,7 +1284,7 @@ int PQsendQuery(PGconn* conn, const char* query) const char *client_logic_str = "encryptedwith"; if (temp_query != NULL && ((strcasestr(temp_query, global_setting_str) != NULL) || (strcasestr(temp_query, column_setting_str) != NULL) || - (strcasestr(temp_query, client_logic_str) != NULL))) { + (strcasestr(temp_query, client_logic_str) != NULL))) {//不走 free(temp_query); temp_query = NULL; printfPQExpBuffer(&conn->errorMessage, @@ -1253,7 +1302,7 @@ int PQsendQuery(PGconn* conn, const char* query) #endif /* construct the outgoing Query message */ - if (pqPutMsgStart('Q', false, conn) < 0 || pqPuts(query, conn) < 0 || pqPutMsgEnd(conn) < 0) { + if (pqPutMsgStart('Q', false, conn) < 0 || pqPuts(query, conn) < 0 || pqPutMsgEnd(conn) < 0) {//不走 pqHandleSendFailure(conn); #ifdef HAVE_CE #if ((!defined(ENABLE_MULTIPLE_NODES)) && (!defined(ENABLE_PRIVATEGAUSS))) @@ -1276,7 +1325,7 @@ int PQsendQuery(PGconn* conn, const char* query) * Give the data a push. In nonblock mode, don't complain if we're unable * to send it all; PQgetResult() will do any additional flushing needed. */ - if (pqFlush(conn) < 0) { + if (pqFlush(conn) < 0) {//不走 pqHandleSendFailure(conn); #ifdef HAVE_CE #if ((!defined(ENABLE_MULTIPLE_NODES)) && (!defined(ENABLE_PRIVATEGAUSS))) diff --git a/src/gausskernel/process/tcop/postgres.cpp b/src/gausskernel/process/tcop/postgres.cpp index e57ccf93a333f6f96c440074db5579e24ca3894f..b845d84ed17fefb66dbdff5b9250467939740fc1 100644 --- a/src/gausskernel/process/tcop/postgres.cpp +++ b/src/gausskernel/process/tcop/postgres.cpp @@ -23,6 +23,7 @@ #include #include +#include #ifdef HAVE_SYS_RESOURCE_H #include @@ -171,10 +172,20 @@ extern int optreset; /* might not be declared by system headers */ #include "streaming/dictcache.h" #include "parser/parse_target.h" #include "streaming/streaming_catalog.h" +#include "OPE_Node.h" +#include #ifdef ENABLE_MOT #include "storage/mot/jit_exec.h" #endif +std::map update; +OPE_Node *root = nullptr; +long long start_update = -1; +long long end_update = -1; + + + + THR_LOCAL VerifyCopyCommandIsReparsed copy_need_to_be_reparse = NULL; #define GSCGROUP_ATTACH_TASK() \ @@ -2035,6 +2046,9 @@ void exec_init_poolhandles(void) #endif } + + + /* * exec_simple_query * @@ -2047,6 +2061,101 @@ void exec_init_poolhandles(void) */ static void exec_simple_query(const char* query_string, MessageType messageType, StringInfo msg = NULL) { + string qs_cpy(query_string); + string qs_six(qs_cpy,0,6); + transform(qs_six.begin(), qs_six.end(), qs_six.begin(), (int(*)(int))tolower); + string temp; + + if(qs_six=="insert"||qs_six=="select") + { + //query_string是这种"Insert into table values(pos=15,'fa54e');" + //插入时 + if(qs_six=="insert")//如果是insert,先初始化一下 + { + start_update = -1; + end_update = -1; + update.clear(); + if (root == nullptr) + { + root_initial(); + } + int fpos_begin = qs_cpy.find("pos="); + if (fpos_begin != qs_cpy.npos)//如果格式符合,这里改写query_string pos ct 改成插入 cd 'ct' + { + //前缀 + int qs_pre_pos = qs_cpy.find("("); + string qs_pre(qs_cpy, 0, qs_pre_pos+1);//qs_pre 是Insert into talbe values( + int fpos_end = qs_cpy.find(","); + string spos(qs_cpy, fpos_begin + 4, fpos_end - fpos_begin - 4); + int pos = atoi(spos.c_str()); + int ct_begin = fpos_end + 2; + int ct_end = qs_cpy.find("'", ct_begin); + string cipher(qs_cpy, ct_begin, ct_end - ct_begin); + //long long start_update = -1; + //long end_update = -1; + //update.clear(); + long long re = root->insert(pos, cipher); + temp=qs_pre + to_string(re) + "," + "'" + cipher + "');"; + if(re==0) + { + LeafNode *leftchild=(LeafNode*)root->getminLeafNode(); + for(leftchild;leftchild->right_bro!=NULL;leftchild=leftchild->right_bro)//除了最后一个叶节点的遍历 + { + for(int j=0;jencoding.size();j++) + { + if((leftchild->encoding[j] >= lower_bound() && leftchild->encoding[j] < upper_bound()) || leftchild->encoding[j] == 0) + temp+"update table set encoding = "+to_string(get_update(leftchild->cipher[j]))+"where encoding="+to_string(leftchild->encoding[j])+";"; + }//确定性加密会导致相同明文相同密文有相同的encoding,原因是在触发get_update时会相同的密文改成一样的encoding + } + for(int j=0;jencoding.size();j++) + { + if((leftchild->encoding[j] >= lower_bound() && leftchild->encoding[j] < upper_bound()) || leftchild->encoding[j] == 0) + temp+"update table set encoding = "+to_string(get_update(leftchild->cipher[j]))+" where ciphertext="+ leftchild->cipher[j] +";"; + }//试试改的行不行 + } + } + else + temp = query_string; + } + + //query_string是这种"Select name,card from talbe where pos>8 and pos<=15;" + //搜索时 + if (qs_six == "select") + { + int lpos_begin = qs_cpy.find("pos>"); + if (lpos_begin != qs_cpy.npos)//如果格式符合,这里改写query_string pos> pos<= 改成encoding> encoding<= + { + //前缀 + string qs_pre(qs_cpy, 0, lpos_begin); + //左边界 + int lpos_end = qs_cpy.find(" ",lpos_begin); + string lspos(qs_cpy, lpos_begin + 4, lpos_end - lpos_begin - 4); + int lpos = atoi(lspos.c_str()); + //右边界 + int rpos_begin = qs_cpy.find("pos<="); + int rpos_end = qs_cpy.find(";", rpos_begin); + string rspos(qs_cpy, rpos_begin + 5, rpos_end - rpos_begin - 5); + int rpos = atoi(rspos.c_str()); + //cout << rpos << endl; + long long lcd = root->search(lpos); + long long rcd = root->search(rpos); + temp = qs_pre + "encoding>" + to_string(lcd)+" and encoding<=" + to_string(rcd) + ";"; + } + else + temp = query_string; + } + } + else + { + temp = query_string; + } + const char* query_string_changed = temp.c_str(); + query_string=query_string_changed; + + + + + CommandDest dest = (CommandDest)t_thrd.postgres_cxt.whereToSendOutput; MemoryContext oldcontext; MemoryContext OptimizerContext; @@ -2116,7 +2225,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * 2. Do basic parsing of the query or queries (this should be safe even if * we are in aborted transaction state! */ - if (HYBRID_MESSAGE != messageType) { + if (HYBRID_MESSAGE != messageType) {//rangequery 走这 pgstat_report_activity(STATE_RUNNING, query_string); t_thrd.postgres_cxt.debug_query_string = query_string; query_string_len = strlen(query_string); @@ -2144,13 +2253,13 @@ static void exec_simple_query(const char* query_string, MessageType messageType, if (ENABLE_WORKLOAD_CONTROL && SqlIsValid(query_string) && (IS_PGXC_COORDINATOR || IS_SINGLE_NODE)) { if (IsConnFromCoord()) t_thrd.wlm_cxt.wlmalarm_dump_active = WLMIsDumpActive(query_string); - else { + else {//走这 u_sess->wlm_cxt->is_active_statements_reset = false; if (g_instance.wlm_cxt->dynamic_workload_inited) { dywlm_parallel_ready(query_string); dywlm_client_max_reserve(); - } else { + } else {//走这 WLMParctlReady(query_string); WLMParctlReserve(PARCTL_GLOBAL); } @@ -2184,7 +2293,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, if (HYBRID_MESSAGE == messageType) { parsetree_list = pg_parse_query(sql_query_string); - } else { + } else {//走这 if (copy_need_to_be_reparse != NULL && g_instance.status == NoShutdown) { bool reparse_query = false; gs_stl::gs_string reparsed_query; @@ -2199,7 +2308,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, } /* Log immediately if dictated by log_statement */ - if (check_log_statement(parsetree_list)) { + if (check_log_statement(parsetree_list)) {//bu走 char* mask_string = NULL; mask_string = maskPassword(query_string); @@ -2229,7 +2338,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, /* * Before executor, check the status of password. */ - if (!t_thrd.postgres_cxt.password_changed) { + if (!t_thrd.postgres_cxt.password_changed) {//bu走 ForceModifyInitialPwd((const char*)query_string, parsetree_list); } @@ -2237,7 +2346,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * Read password status from pg_user_status. If is in aborted block, don't check. */ Oid current_user = GetUserId(); - if (current_user != BOOTSTRAP_SUPERUSERID) { + if (current_user != BOOTSTRAP_SUPERUSERID) {//bu走 if (!IsAbortedTransactionBlockState() && GetAccountPasswordExpired(current_user) == EXPIRED_STATUS) { ForceModifyExpiredPwd((const char*)query_string, parsetree_list); } @@ -2252,7 +2361,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, isTopLevel = (list_length(parsetree_list) == 1); stp_retore_old_xact_stmt_state(isTopLevel); - if (isTopLevel != 1) + if (isTopLevel != 1)//bu走 t_thrd.explain_cxt.explain_perf_mode = EXPLAIN_NORMAL; /* Apply for a new memory context for analyze and rewrite as well as pg_plan_queries */ @@ -2264,12 +2373,12 @@ static void exec_simple_query(const char* query_string, MessageType messageType, bool is_multi_query_text = false; /* When the query is multi query like "begin;...end;" , we need update query statement for WLM collect Info */ - if (t_thrd.wlm_cxt.collect_info->sdetail.statement != NULL && list_length(parsetree_list) > 1) { + if (t_thrd.wlm_cxt.collect_info->sdetail.statement != NULL && list_length(parsetree_list) > 1) {//bu走 is_multi_query_text = true; } /* just for cooperation analysis. */ - if (IS_PGXC_COORDINATOR && u_sess->pgxc_cxt.is_gc_fdw) { + if (IS_PGXC_COORDINATOR && u_sess->pgxc_cxt.is_gc_fdw) {//bu走 u_sess->attr.attr_sql.enable_stream_operator = false; u_sess->opt_cxt.qrw_inlist2join_optmode = QRW_INLIST2JOIN_DISABLE; } @@ -2301,7 +2410,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * get_next_snippet which cut the multi-query by query_string_locationlist. */ if ((IS_PGXC_COORDINATOR || IS_SINGLE_NODE) && PointerIsValid(query_string_locationlist) && - list_length(query_string_locationlist) > 1) { + list_length(query_string_locationlist) > 1) {//bu走 oldcontext = MemoryContextSwitchTo(t_thrd.mem_cxt.msg_mem_cxt); is_multistmt = true; query_string_single = @@ -2320,7 +2429,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, } } -#ifdef ENABLE_MULTIPLE_NODES +#ifdef ENABLE_MULTIPLE_NODES//bu走 /* * By default we do not want Datanodes or client Coordinators to contact GTM directly, @@ -2350,7 +2459,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * might be safe to allow some additional utility commands in this * state, but not many...) */ - if (IsAbortedTransactionBlockState() && !IsTransactionExitStmt(parsetree)) + if (IsAbortedTransactionBlockState() && !IsTransactionExitStmt(parsetree))//bu走 ereport(ERROR, (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION), errmsg("current transaction is aborted, " @@ -2394,12 +2503,12 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * @hdfs * If we received a hybridmessage, we use sql_query_string to analyze and rewrite. */ - if (HYBRID_MESSAGE != messageType) + if (HYBRID_MESSAGE != messageType)//走这 querytree_list = pg_analyze_and_rewrite(parsetree, query_string, NULL, 0); else querytree_list = pg_analyze_and_rewrite(parsetree, sql_query_string, NULL, 0); -#ifdef ENABLE_MOT +#ifdef ENABLE_MOT//bu走 /* check cross engine queries and transactions violation for MOT */ StorageEngineType storageEngineType = SE_TYPE_UNSPECIFIED; if (querytree_list) { @@ -2437,7 +2546,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, } #endif - /* Try using light proxy to execute query */ + /* Try using light proxy to execute query *///bu走 if (runLightProxyCheck && exec_query_through_light_proxy(querytree_list, parsetree, snapshot_set, msg, OptimizerContext)) { (void)MemoryContextSwitchTo(oldcontext); @@ -2447,7 +2556,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, plantree_list = pg_plan_queries(querytree_list, 0, NULL); randomPlanInfo = get_random_plan_string(); - if (was_logged != false && randomPlanInfo != NULL) { + if (was_logged != false && randomPlanInfo != NULL) {//bu走 ereport(LOG, (errmsg("%s", randomPlanInfo), errhidestmt(true))); pfree(randomPlanInfo); } @@ -2459,24 +2568,24 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * If we received a hybridmessage, we attach additional information to plantree_list's node. * Additional information is a string which can be recovered into a struct by call string to node. */ - if (HYBRID_MESSAGE == messageType) + if (HYBRID_MESSAGE == messageType)//bu走 attach_info_to_plantree_list(plantree_list, &attachInfoCtx); /* Done with the snapshot used for parsing/planning */ - if (snapshot_set != false) + if (snapshot_set != false)//走这 PopActiveSnapshot(); /* If we got a cancel signal in analysis or planning, quit */ CHECK_FOR_INTERRUPTS(); -#ifdef PGXC +#ifdef PGXC//走这 /* PGXC_DATANODE */ /* Flag to indicate whether vacuum needs getting Xid from GTM */ bool vacuumForceXid = false; /* If the parsetree is a vacuum statement */ - if (IsA(parsetree, VacuumStmt)) { + if (IsA(parsetree, VacuumStmt)) {//bu走 /* copy the parsetree */ VacuumStmt* vacstmt = (VacuumStmt*)parsetree; @@ -2490,12 +2599,12 @@ static void exec_simple_query(const char* query_string, MessageType messageType, /* Force getting Xid from GTM if neither an autovacuum nor a vacuum(analyze) to one relation */ if ((IS_PGXC_DATANODE || IsConnFromCoord()) && (vacuumForceXid || IsA(parsetree, ClusterStmt)) && - IsPostmasterEnvironment) + IsPostmasterEnvironment)//bu走 SetForceXidFromGTM(true); /* Commands like reindex database ..., coordinator don't send snapshot down, need to get from GTM. */ if ((IS_PGXC_DATANODE || IsConnFromCoord()) && IsA(parsetree, ReindexStmt) && - ((ReindexStmt*)parsetree)->kind == OBJECT_DATABASE && IsPostmasterEnvironment) + ((ReindexStmt*)parsetree)->kind == OBJECT_DATABASE && IsPostmasterEnvironment)//bu走 SetForceXidFromGTM(true); #endif /* SQL bypass */ @@ -2503,8 +2612,27 @@ static void exec_simple_query(const char* query_string, MessageType messageType, (void)MemoryContextSwitchTo(oldcontext); void* opFusionObj = OpFusion::FusionFactory( OpFusion::getFusionType(NULL, NULL, plantree_list), oldcontext, NULL, plantree_list, NULL); - if (opFusionObj != NULL) { + if (opFusionObj != NULL) {//bu走,insert走了 ((OpFusion*)opFusionObj)->setCurrentOpFusionObj((OpFusion*)opFusionObj); + //在这改 + // + + + + + + + + + + + + + + + + + if (OpFusion::process(FUSION_EXECUTE, NULL, completionTag, isTopLevel, NULL)) { CommandCounterIncrement(); finish_xact_command(); @@ -2524,14 +2652,17 @@ static void exec_simple_query(const char* query_string, MessageType messageType, /* Don't display the portal in pg_cursors */ portal->visible = false; - /* + /*我们不需要将任何内容复制到门户中, + 因为我们在这里传递的所有内容都在t_thrd.mem_cxt中。 + Msg_mem_cxt,它将比门户存在的时间更长。如果我们收到一个hybridmessage, + 我们将sql_query_string作为原始查询字符串发送给PortalDefineQuery。 * We don't have to copy anything into the portal, because everything * we are passing here is in t_thrd.mem_cxt.msg_mem_cxt, which will outlive the * portal anyway. If we received a hybridmesage, we send sql_query_string * to PortalDefineQuery as the original query string. */ - if (HYBRID_MESSAGE != messageType) { - if (is_multistmt && (IsConnFromApp() || IsConnFromInternalTool())) { + if (HYBRID_MESSAGE != messageType) {//走这 + if (is_multistmt && (IsConnFromApp() || IsConnFromInternalTool())) {//走这 PortalDefineQuery(portal, NULL, query_string_single[stmt_num - 1], commandTag, plantree_list, NULL); } else PortalDefineQuery(portal, NULL, query_string, commandTag, plantree_list, NULL); @@ -2539,7 +2670,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, PortalDefineQuery(portal, NULL, sql_query_string, commandTag, plantree_list, NULL); } - if (ENABLE_WORKLOAD_CONTROL && IS_PGXC_COORDINATOR && is_multi_query_text) { + if (ENABLE_WORKLOAD_CONTROL && IS_PGXC_COORDINATOR && is_multi_query_text) {//bu走 if (t_thrd.wlm_cxt.collect_info->sdetail.statement) { pfree_ext(t_thrd.wlm_cxt.collect_info->sdetail.statement); } @@ -2568,7 +2699,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * backward compatibility...) */ format = 0; /* TEXT is default */ - if (IsA(parsetree, FetchStmt)) { + if (IsA(parsetree, FetchStmt)) {//bu走 FetchStmt* stmt = (FetchStmt*)parsetree; if (!stmt->ismove) { @@ -2584,7 +2715,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * Now we can create the destination receiver object. */ receiver = CreateDestReceiver(dest); - if (dest == DestRemote) + if (dest == DestRemote)//走这 SetRemoteDestReceiverParams(receiver, portal); /* @@ -2593,7 +2724,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, (void)MemoryContextSwitchTo(oldcontext); if (u_sess->attr.attr_resource.use_workload_manager && g_instance.wlm_cxt->gscgroup_init_done && - !IsAbortedTransactionBlockState()) { + !IsAbortedTransactionBlockState()) {//bu走 u_sess->wlm_cxt->cgroup_last_stmt = u_sess->wlm_cxt->cgroup_stmt; u_sess->wlm_cxt->cgroup_stmt = WLMIsSpecialCommand(parsetree, portal); } @@ -2615,7 +2746,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * start a new xact command for the next command (if any). */ finish_xact_command(); - } else if (lnext(parsetree_item) == NULL) { + } else if (lnext(parsetree_item) == NULL) {//走这 /* * If this is the last parsetree of the query string, close down * transaction statement before reporting command-complete. This @@ -2662,18 +2793,18 @@ static void exec_simple_query(const char* query_string, MessageType messageType, /* * If there were no parsetrees, return EmptyQueryResponse message. */ - if (parsetree_list == NULL) + if (parsetree_list == NULL)//bu走 NullCommand(dest); /* release global active counts */ - if (ENABLE_WORKLOAD_CONTROL) { - if (g_instance.wlm_cxt->dynamic_workload_inited) { + if (ENABLE_WORKLOAD_CONTROL) {//走这 + if (g_instance.wlm_cxt->dynamic_workload_inited) {//bu走 if (t_thrd.wlm_cxt.parctl_state.simple == 0) dywlm_client_release(&t_thrd.wlm_cxt.parctl_state); else WLMReleaseGroupActiveStatement(); dywlm_client_max_release(&t_thrd.wlm_cxt.parctl_state); - } else { + } else {//走这 WLMParctlRelease(&t_thrd.wlm_cxt.parctl_state); } WLMSetCollectInfoStatusFinish(); @@ -2686,7 +2817,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, case 1: ereport(DEBUG1, (errmsg("duration: %s ms, queryid %ld, unique id %lu", msec_str, u_sess->debug_query_id, u_sess->slow_query_cxt.slow_query.unique_sql_id), errhidestmt(true))); break; - case 2: { + case 2: {//走这 char* mask_string = NULL; MASK_PASSWORD_START(mask_string, query_string); @@ -2701,7 +2832,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, break; } - if (save_log_statement_stats) + if (save_log_statement_stats)//bu走 ShowUsage("QUERY STATISTICS"); TRACE_POSTGRESQL_QUERY_DONE(query_string); @@ -2713,13 +2844,13 @@ static void exec_simple_query(const char* query_string, MessageType messageType, * If we received a hybridmesage, we applied additional memory. At the end of * exec_simple_query, we free them. */ - if (HYBRID_MESSAGE == messageType) { + if (HYBRID_MESSAGE == messageType) {//bu走 pfree_ext(info_query_string); pfree_ext(sql_query_string); } /* Free the memory of query_string_single malloced in get_next_snippet. */ - if (is_multistmt) { + if (is_multistmt) {//bu走 for (int i = 0; i < stmt_num; i++) { pfree(query_string_single[i]); query_string_single[i] = NULL; diff --git a/src/include/OPE_Node.h b/src/include/OPE_Node.h new file mode 100644 index 0000000000000000000000000000000000000000..a12de892b2995a5f5381280de047bdc35dbb1c16 --- /dev/null +++ b/src/include/OPE_Node.h @@ -0,0 +1,372 @@ +#pragma once +#include +#include +#include +#include +#include +using namespace std; +/*initalize all*/ + +class OPE_Node { +public: + int type; + int parent_index; + OPE_Node* parent = NULL; + virtual OPE_Node* getminLeafNode() { return NULL; }; + virtual void rebalance() {}; + virtual long long insert(int pos, string cipher) { return 0; }; + virtual long long search(int pos) {return 0; }; + virtual void traverse(){return ; }; +}; + +unsigned int M = 8; +extern OPE_Node *root; +extern long long start_update; +extern long long end_update; +extern std::map update; + + +class InternalNode : public OPE_Node { +public: + /*internal node*/ + std::vector child_num; //子节点共有的加密值个数 + std::vector child; //子节点 + + InternalNode(); + void insert_node(int index, OPE_Node *new_node); + OPE_Node* getminLeafNode() override; + void rebalance() override; + long long insert(int pos, string cipher) override; + long long search(int pos) override; + void traverse() override; +}; + +class LeafNode : public OPE_Node { + /*leaf node*/ +public: + std::vector cipher;//密文 + std::vector encoding;//密文 + LeafNode* left_bro = NULL; + LeafNode* right_bro = NULL; + long long lower = -1; + long long upper = -1; + + LeafNode(); + OPE_Node* getminLeafNode() override; + long long Encode(unsigned int pos); + void rebalance()override; + long long insert(int pos, string cipher) override; + long long search(int pos) override; + //void traverse() override; +}; + + + +InternalNode::InternalNode() { + this->type = 2; + this->parent_index = -1; + this->parent = NULL; +} + +OPE_Node* InternalNode::getminLeafNode() +{ + return child[0]; +} + +void InternalNode::insert_node(int index, OPE_Node *new_node) +{ + //在子节点index处插入新节点 + this->child.insert(this->child.begin() + index, new_node); + if (new_node->type == 1) {//叶节点,则child_num+叶节点有的密文数量 + this->child_num.insert(this->child_num.begin() + index, ((LeafNode *)new_node)->cipher.size()); + ((LeafNode *)new_node)->parent = this; + } + else { + int res = 0;//中间节点,则child_num+这个中间节点的child_num总数 + for (size_t i = 0; i < ((InternalNode *)new_node)->child_num.size(); i++) + { + res += ((InternalNode *)new_node)->child_num.at(i);//at()是获取内容 + } + this->child_num.insert(this->child_num.begin() + index, res); + ((InternalNode *)new_node)->parent = this; + } + + for (unsigned int i = 0; i < this->child.size(); i++) { + this->child.at(i)->parent_index = i;//每个孩子的父亲index(不是父亲节点)是自己的标号,就是孩子序号 + if (this->child.at(i)->type == 1) { + LeafNode *tmp = (LeafNode*)this->child.at(i); + this->child_num.at(i) = tmp->cipher.size();//为什么叶节点要再更新一次?前面不是插入了吗 + } + } + /* + for (int i = 1; i < this->child.size(); i++) { + this->child.at(i)->parent_index = i; + } + */ + + if (this->child.size() >= M) { + this->rebalance(); + } +} + + +void InternalNode::rebalance() { + InternalNode* new_node = new InternalNode(); + int middle = floor(this->child.size()*0.5);//向下取整 + while (middle > 0) { + new_node->child.insert(new_node->child.begin(), this->child.at(this->child.size()-1));//取要分裂节点的最后,前插进分裂出的节点 + new_node->child_num.insert(new_node->child_num.begin(), this->child_num.at(this->child_num.size()-1)); + this->child.pop_back(); + this->child_num.pop_back(); + middle--; + } + for (unsigned int i = 0; i < new_node->child.size(); i++) { + new_node->child.at(i)->parent_index = i; + new_node->child.at(i)->parent = new_node; + } + if (!this->parent) {//如果根节点分裂则需要新的根节点 + InternalNode *new_root = new InternalNode(); + new_root->insert_node(0, this); + new_root->insert_node(1, new_node); + root = new_root; + } else { + int res = 0; + for (size_t i = 0; i < this->child_num.size(); i++) { + res += this->child_num.at(i); + } + ((InternalNode*)this->parent)->child_num.at(this->parent_index) = res; + ((InternalNode*)this->parent)->insert_node(this->parent_index + 1, new_node);//这个节点插入分裂节点的父节点 + + } + +} + +long long InternalNode::insert(int pos, string cipher) {//这是插入一个叶节点即数据 + + for (unsigned int i = 0; i < this->child.size(); i++) { + if (pos > this->child_num.at(i)) { + pos = pos - this->child_num.at(i); + } + else { + this->child_num.at(i)++; + return this->child.at(i)->insert(pos, cipher);//如果child.at(i)是中间节点则递归,否则insert调用的是叶节点的插入,讲通了 + } + } + //当插入的是最后一个的时候是这两句起作用,如树里有8个节点 root是|4|4|,插入的pos是9 + this->child_num.back() = this->child_num.back()++; + return this->child.back()->insert(pos, cipher); + +} + +long long InternalNode::search(int pos) { + + for (unsigned int i = 0; i < this->child.size(); i++) { + if (pos < this->child_num.at(i)) { + return this->child.at(i)->search(pos);//同insert,最后调用叶节点search + } + else { + pos = pos - this->child_num.at(i); + } + } + return 0; +} + + + +LeafNode::LeafNode() { + this->type = 1; + this->parent_index = -1; + this->parent = NULL; + +} + +OPE_Node* LeafNode::getminLeafNode() +{ + return this; +} + +void Recode(vector node_list) { + // ofstream out("logfh.txt",ios::app); + // out<<"enter recode"<<"\n"; + // out.close(); + long long left_bound = node_list.at(0)->lower; + long long right_bound = node_list.back()->upper; + int total_cipher_num = 0; + + for (size_t i = 0; i < node_list.size(); i++) { + total_cipher_num += node_list.at(i)->cipher.size(); + } + // ofstream out1("logfh.txt",ios::app); + // out1< total_cipher_num) { + // ofstream out3("logfh.txt",ios::app); + // out3<<"enter if"<<"\n"; + // out3.close(); + + start_update = left_bound; + end_update = right_bound; + long long frag = floor((right_bound - left_bound ) / total_cipher_num); + assert(frag >= 1);//条件成立则不执行 + long long cd = left_bound; + // out<<"**************************\n"; + // out.setf(ios::fixed); + // out<lower = cd;//还是把这堆叶节点里最小边界赋给左边 + // out<<"############################\n"; + for (unsigned int j = 0; j < node_list.at(i)->encoding.size(); j++) { + node_list.at(i)->encoding.at(j) = cd;//同时最小编码也是最小边界 + update.insert(make_pair(node_list.at(i)->cipher.at(j), cd));//插入密文 编码映射字典里 + // out<cipher.at(j)<<"\n"; + cd = cd + frag;//以平均差值为分界 + } + node_list.at(i)->upper = cd;//上界赋为最后一个cd + } + node_list.back()->upper = right_bound;//然后又改成了之前的右边界? + // out.close(); + // ofstream out4("logfh.txt",ios::app); + // out4<<"out if"<<"\n"; + // out4.close(); + } + else {//有左右兄弟就和左右兄弟平分上下界,否则就扩展边界但是不能超过root的届 + if (node_list.at(0)->left_bro) { + node_list.insert(node_list.begin(), node_list.at(0)->left_bro); + } + if (node_list.back()->right_bro) { + node_list.push_back(node_list.back()->right_bro); + } + else { + node_list.back()->upper += pow(2, 32); + if(node_list.back()->upper >= pow(2, 60)) node_list.back()->upper = pow(2, 60); + } + Recode(node_list); + } + // ofstream out2("logfh.txt",ios::app); + // out2<<"out recode"<<"\n"; + // out2.close(); + +} + +long long LeafNode::Encode(unsigned int pos) { + long long left = this->lower; + long long right = this->upper; + // ofstream out("lidongjieencode.txt",ios::app); + + if (pos > 0) {//pos是0开始 + left = this->encoding.at(pos - 1);//left则变成前面一个的encoding + } + if (pos < this->encoding.size() - 1) {//pos不是最后位置 + right = this->encoding.at(pos + 1); + } + if (floor(right - left) < 2) {//边界太小了 + std::vector node_list; + node_list.push_back(this); + Recode(node_list); + // out<encoding.at(pos)<<" & "<encoding.at(pos) = re;//其实是左右边界的中间值 + // out<encoding.at(pos)<<" "<encoding.at(pos); + } + +} + +void LeafNode::rebalance() { + LeafNode* new_node = new LeafNode(); + int middle = floor(this->cipher.size()*0.5); + while (middle > 0) { + new_node->cipher.insert(new_node->cipher.begin(), this->cipher.back()); + new_node->encoding.insert(new_node->encoding.begin(), this->encoding.back()); + this->encoding.pop_back(); + this->cipher.pop_back(); + middle--; + } + new_node->lower = new_node->encoding.at(0); + new_node->upper = this->upper; + this->upper = new_node->encoding.at(0); + if (this->right_bro) { + this->right_bro->left_bro = new_node; + } + new_node->right_bro = this->right_bro; + this->right_bro = new_node; + new_node->left_bro = this; + if (!this->parent) {//这个叶节点是根节点 + InternalNode *new_root = new InternalNode(); + new_root->insert_node(0, this); + new_root->insert_node(1, new_node); + root = new_root; + } + else { + ((InternalNode*)this->parent)->child_num.at(this->parent_index) = this->cipher.size();//分裂的节点在父结点中对应的数据数目也要分出去 + if (this->cipher.size() >= M) { + printf("error\n"); + } + ((InternalNode*)this->parent)->insert_node(this->parent_index + 1, new_node); + } + +} + +long long LeafNode::insert(int pos, string cipher) { + this->cipher.insert(this->cipher.begin() + pos, cipher);//cipher是vector + this->encoding.insert(this->encoding.begin() + pos, -1);//-1插进去后在Encode改 + long long cd = this->Encode(pos); + if (this->cipher.size() >= M) { + this->rebalance(); + } + return cd; + +} + +long long LeafNode::search(int pos) { + return this->encoding.at(pos);//pos是按照0 1 2 3顺序来的 +} + +void InternalNode::traverse() { + for (unsigned int i = 0; i < this->child.size(); i++) { + this->child.at(i)->traverse(); + } +} +// void LeafNode::traverse() { +// ofstream out("lidongjietest.txt",ios::app);//追加写入 +// out<<"********************"<<"\n"; +// out.setf(ios::fixed);//定点形式显示浮点数 +// for (unsigned int i = 0; i < this->encoding.size(); i++) { +// out<lower<<" "<encoding.at(i)<<" "<upper<<"\n"; +// } +// out<<"********************"<<"\n"; +// out.close(); +// } + + +void root_initial() { + root = new LeafNode(); + ((LeafNode*)root)->lower = 0; + ((LeafNode*)root)->upper = pow(2, 60);//2的60次方 + update.clear(); +}; + +long long upper_bound() { + return end_update; +} + +long long lower_bound() { + return start_update; +} + +long long get_update(string cipher) { + if (update.count(cipher) > 0) { + return update[cipher]; + } + return 0; +} + diff --git a/src/include/libpq/LocalTable.h b/src/include/libpq/LocalTable.h new file mode 100644 index 0000000000000000000000000000000000000000..30a2b09b0cc96805b2043bcb3fb8713ac3027af3 --- /dev/null +++ b/src/include/libpq/LocalTable.h @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +using namespace std; + +bool mycomp(string a, string b) +{ + if (a.size() < b.size()) + { + return true; + } + if (a.size() > b.size()) + { + return false; + } + if (a.size() == b.size()) + { + return a < b; + } +} + + + +class Client{ +public: + vector sortedkey; + vector count; + int insert_table(string pt); + int search_left(string pt); + int search_right(string pt); +}; + + +int Client::insert_table(string pt) +{ + int pos=0; + vector::iterator insert_pos; + insert_pos = lower_bound(sortedkey.begin(), sortedkey.end(), pt,mycomp);//第一个大于等于pt的值的位置 + int temp = insert_pos - sortedkey.begin();//可能为0 + if (sortedkey.end() == insert_pos)//插入的是目前最大的 + { + sortedkey.insert(insert_pos, pt); + count.insert(count.begin()+temp, 1); + } + else if (sortedkey[temp] != pt)//没有一样值的,是新数据 + { + sortedkey.insert(insert_pos, pt); + count.insert(count.begin() + temp, 1); + } + else + { + count[temp] = count[temp] + 1;//重复值,不插入sortkey + } + srand(time(nullptr)); + pos = accumulate(count.begin(), count.begin() + temp, 0) + rand() % count[temp]; + return pos; +} + +int Client::search_left(string pt) +{ + vector::iterator lse_pos; + lse_pos = lower_bound(sortedkey.begin(), sortedkey.end(), pt,mycomp);//第一个大于等于pt位置的值的 + int left_pos = 0; + if (lse_pos == sortedkey.end()) + { + left_pos = accumulate(count.begin(), count.end(), 0); + } + else + { + int temp = lse_pos - sortedkey.begin(); + left_pos = accumulate(count.begin(), count.begin() + temp + 1, 0); + } + left_pos=left_pos-1; + return left_pos; +} + +int Client::search_right(string pt) +{ + vector::iterator rse_pos; + rse_pos = lower_bound(sortedkey.begin(), sortedkey.end(), pt,mycomp);//第一个大于等于pt位置的值的 + int right_pos=0; + if(rse_pos==sortedkey.end()) + { + right_pos=accumulate(count.begin(),count.end(),0); + } + else + { + int temp=rse_pos-sortedkey.begin(); + right_pos=accumulate(count.begin(),count.begin()+temp+1,0); + } + right_pos=right_pos-1; + return right_pos; +} \ No newline at end of file diff --git a/test.sql b/test.sql new file mode 100644 index 0000000000000000000000000000000000000000..6d8d0bc47950270a36f194665c6112b550b06ae7 --- /dev/null +++ b/test.sql @@ -0,0 +1,24 @@ +create database testdb; +\c testdb; +-- CREATE CLIENT MASTER KEY ImgCMK1 WITH (KEY_STORE = localkms, KEY_PATH = "key_path_value1", ALGORITHM = RSA_2048); +-- CREATE CLIENT MASTER KEY ImgCMK WITH (KEY_STORE = localkms, KEY_PATH = "key_path_value2", ALGORITHM = RSA_2048); +-- CREATE COLUMN ENCRYPTION KEY ImgCEK1 WITH VALUES (CLIENT_MASTER_KEY = ImgCMK1, ALGORITHM = AEAD_AES_256_CBC_HMAC_SHA256); +-- CREATE COLUMN ENCRYPTION KEY ImgCEK WITH VALUES (CLIENT_MASTER_KEY = ImgCMK, ALGORITHM = AEAD_AES_256_CBC_HMAC_SHA256); +CREATE CLIENT MASTER KEY ImgCMK_ope WITH (KEY_STORE = localkms, KEY_PATH = "key_path_value_ope", ALGORITHM = RSA_2048); +CREATE COLUMN ENCRYPTION KEY ImgCEK_ope WITH VALUES (CLIENT_MASTER_KEY = ImgCMK_ope, ALGORITHM = AEAD_AES_256_CBC_HMAC_SHA256); +--初次创建会有问题,删掉重启数据库后重新创建 +SELECT * FROM gs_client_global_keys; +SELECT column_key_name,column_key_distributed_id ,global_key_id,key_owner FROM gs_column_keys; + + +-- CREATE COLUMN ENCRYPTION KEY ImgCEK1 WITH VALUES (CLIENT_MASTER_KEY = ImgCMK1, ALGORITHM = AEAD_AES_256_CBC_HMAC_SHA256); +CREATE TABLE ope_testtable (encoding bigint, ct text encrypted with (column_encryption_key = ImgCEK_ope, encryption_type = DETERMINISTIC)); +*Insert into ope_testtable values('5'); +*Insert into ope_testtable values('7'); +*Insert into ope_testtable values('9'); +*Insert into ope_testtable values('15'); +*Insert into ope_testtable values('11'); +*Select * from ope_testtable where pt>'7' and pt<='11'; +*Select * from ope_testtable where pt>'5' and pt<='9'; +select * from ope_testtable; +DROP TABLE ope_testtable; \ No newline at end of file