From 867e569dd34fd92e6cd7ea680c95c842cb846baa Mon Sep 17 00:00:00 2001 From: totaj Date: Tue, 8 Apr 2025 19:31:43 +0800 Subject: [PATCH] Fix multi SQL in one single query bug. --- src/gausskernel/process/tcop/postgres.cpp | 12 +- .../runtime/executor/lightProxy.cpp | 2 + src/include/executor/lightProxy.h | 3 +- .../regress/input/multi_simple_query.source | 15 +++ .../multi_simple_query/MultiSimpleQuery.class | Bin 0 -> 2883 bytes .../multi_simple_query/MultiSimpleQuery.java | 114 ++++++++++++++++++ .../regress/output/multi_simple_query.source | 27 +++++ src/test/regress/parallel_schedule0C | 2 +- 8 files changed, 168 insertions(+), 7 deletions(-) create mode 100755 src/test/regress/input/multi_simple_query.source create mode 100644 src/test/regress/jdbc_test/multi_simple_query/MultiSimpleQuery.class create mode 100644 src/test/regress/jdbc_test/multi_simple_query/MultiSimpleQuery.java create mode 100755 src/test/regress/output/multi_simple_query.source diff --git a/src/gausskernel/process/tcop/postgres.cpp b/src/gausskernel/process/tcop/postgres.cpp index dca4362af9..b95f827065 100755 --- a/src/gausskernel/process/tcop/postgres.cpp +++ b/src/gausskernel/process/tcop/postgres.cpp @@ -2620,11 +2620,12 @@ static void exec_simple_query(const char* query_string, MessageType messageType, was_logged = true; } +#ifdef ENABLE_MULTIPLE_NODES /* Light proxy is only enabled for single query from 'Q' message */ bool runLightProxyCheck = (msg != NULL) && IS_PGXC_COORDINATOR && !IsConnFromCoord() && u_sess->attr.attr_sql.enable_light_proxy && (list_length(parsetree_list) == 1) && (query_string_len < SECUREC_MEM_MAX_LEN); - +#endif bool runOpfusionCheck = (msg != NULL) && IS_PGXC_DATANODE && u_sess->attr.attr_sql.enable_opfusion && (list_length(parsetree_list) == 1) && (query_string_len < SECUREC_MEM_MAX_LEN); @@ -2849,7 +2850,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, EndCommand(completionTag, dest); (void)MemoryContextSwitchTo(t_thrd.mem_cxt.msg_mem_cxt); MemoryContextReset(OptimizerContext); - break; + continue; } } } @@ -2870,7 +2871,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, finish_xact_command(); EndCommand(completionTag, dest); MemoryContextReset(OptimizerContext); - break; + continue; } #ifdef ENABLE_MOT /* check cross engine queries and transactions violation for MOT */ @@ -2892,7 +2893,8 @@ static void exec_simple_query(const char* query_string, MessageType messageType, errmsg("Explicit prepare transaction is not supported for memory table"))); } #endif - + +#ifdef ENABLE_MULTIPLE_NODES /* Try using light proxy to execute query */ if (runLightProxyCheck && exec_query_through_light_proxy(querytree_list, parsetree, snapshot_set, msg, OptimizerContext)) { @@ -2902,7 +2904,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, collectSimpleQuery(query_string, isCollect); break; } - +#endif // Mixed statement judgments if (ENABLE_REMOTE_EXECUTE && libpqsw_process_query_message(commandTag, querytree_list, querystringForLibpqsw, is_multistmt, lnext(parsetree_item) == NULL)) { diff --git a/src/gausskernel/runtime/executor/lightProxy.cpp b/src/gausskernel/runtime/executor/lightProxy.cpp index cb3e88b994..5e76f92df4 100644 --- a/src/gausskernel/runtime/executor/lightProxy.cpp +++ b/src/gausskernel/runtime/executor/lightProxy.cpp @@ -1333,6 +1333,7 @@ bool IsLightProxyOn(void) return (u_sess->exec_cxt.cur_light_proxy_obj != NULL); } +#ifdef ENABLE_MULTIPLE_NODES bool exec_query_through_light_proxy(List* querytree_list, Node* parsetree, bool snapshot_set, StringInfo msg, MemoryContext OptimizerContext) { @@ -1383,6 +1384,7 @@ bool exec_query_through_light_proxy(List* querytree_list, Node* parsetree, bool } return false; } +#endif void GPCDropLPIfNecessary(const char *stmt_name, bool need_drop_dnstmt, bool need_del, CachedPlanSource *reset_plan) { if (stmt_name == NULL || stmt_name[0] == '\0' || !IS_PGXC_COORDINATOR) return; diff --git a/src/include/executor/lightProxy.h b/src/include/executor/lightProxy.h index 9b7e5c981e..e8e48569b3 100644 --- a/src/include/executor/lightProxy.h +++ b/src/include/executor/lightProxy.h @@ -202,8 +202,9 @@ private: lightProxyMsgCtl *m_msgctl; }; - +#ifdef ENABLE_MULTIPLE_NODES extern bool exec_query_through_light_proxy(List* querytree_list, Node* parsetree, bool snapshot_set, StringInfo msg, MemoryContext OptimizerContext); +#endif #endif /* SRC_INCLUDE_EXECUTOR_LIGHTPROXY_H_ */ diff --git a/src/test/regress/input/multi_simple_query.source b/src/test/regress/input/multi_simple_query.source new file mode 100755 index 0000000000..9b95ed0872 --- /dev/null +++ b/src/test/regress/input/multi_simple_query.source @@ -0,0 +1,15 @@ +DROP USER IF EXISTS multi_simple_query CASCADE; +CREATE USER multi_simple_query WITH PASSWORD "tom@1234"; +SET ROLE multi_simple_query PASSWORD 'tom@1234'; +create table multi_simple_query1(a int); +create table msq2(a int); +insert into msq2 values(1); +insert into msq2 values(2); +\! chmod -R 700 @abs_bindir@/../jre +\! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/jdbc_test/gsjdbc400.jar:@abs_builddir@/jdbc_test/multi_simple_query/. MultiSimpleQuery @portstring@ 2>&1 +select * from multi_simple_query1 order by 1; +select * from msq2 order by 1; +DROP TABLE multi_simple_query1; +DROP TABLE msq2; +RESET ROLE; +DROP USER IF EXISTS multi_simple_query CASCADE; diff --git a/src/test/regress/jdbc_test/multi_simple_query/MultiSimpleQuery.class b/src/test/regress/jdbc_test/multi_simple_query/MultiSimpleQuery.class new file mode 100644 index 0000000000000000000000000000000000000000..6dff280f240aa46e6e516964bf99edfb207d868b GIT binary patch literal 2883 zcmcguTUQfT6#h;K%n(M=ASfytt ze}S*s2b6ZLKK7yg4}I=$aCJ$)lK}%>R$Z%WbtTy|XPT`uEfxRlRB>IxTfQ}jvFz2h;c0Qyh37PFE=8PuqPpa|5)W3(WkjtXZ!5(@@Yruk~Zn4^jf_7QDTt)^$O{ zq=w>xU_aw8nHHmKOJ0357$rR=5X-q0FE3A6Dy`OR#SW~TRVv$Zv?9H`y(%jMUFhbf z>lJ&;t{)UVNzc8e0z8Yp90prsbX@jH20 zR%J2Zp<9D*AV9B%ih&v2rf3c6gkQ<$r7UdGaL2%1+%xbQJ{RcpWss1Ls`dD^!eP8@ zdS*!m(zEWF%C-t`z`z%{FVMb3+Nu=BCo3wMLDyj+_Z6f~wZx?7mJ%g@I+eIRB|Vui z2m1#S@7zlncz`bre1)$Ke1nGuzQuP2zDKu#AMlX1sHUsxpBv4*N?2g~l2G0ixC(2` za(w9p3CjuGL`fBWJj6Ckw?8ps+7;<1`@04x^IoE=sz{`f($xR>w0FH`!jxSYc-^R(tvJr}r8tff>k>bf{fpo|8Tk%}Fv_-qH_j zezRPbPC;PjTe^9nQ!@w|zJNCAdLukitl7VKt18e& zlOt~rJAPm~d1@_p6k??ul{tHY>hu`%OeNU%3YD;7v!-LR$v9(*%V*dU=yP{{;>RiI zR)|(>I6N%3?`&w?lV*v&!k$~sW@6O{Y>u7QwKr+b1BDF1|Rz1;+e7aa6 z@5p>5kmt(<3cthTFr6;Qy+h)PfWd5+oPcE>U-9WN>c~6Hne(4YjZ|8!Y-@7(t);Ec z+pf>hR#GT}j`~40aWzS}3=cl4}@SD_ggX z8XGW(jnqp}vx67)CY-@$jAASLsJ#u*c`7t$*tPuI522w+&nd!OIR?U9#S!|er{)8Z z>7K)CflN<4K8KbFF80LNgfH>dY|oB4v_&w~@d*2S=CD>E9c_=!VV%GutYNC{QLfq} zPzlffrMA`+%sFfj7`0xY9><&SDc`-Sm_oL{LDHN!h$VDtv~p z+#m!%Cs#=Z-i0_Tx`BXgA}F0KSvM0;VHXbY|3sE)jS-}){5Nug1FwKXw74Hr_=r~1 zv^z-41H6w8;2sX*J`Pu58-)H6of`HKH1Ri@H0)jf0;}esBch?78w$RTd8|NPxaO+L zioPIzjcT?o;JJ4J&zU87ZeD;f@jt+T-9^e>ZJi&NR62@VksZ-oP z&6dd!SOwk)CC-vFigWy&M~+Zlr?oMRbCt(M+Pp%mmr%lGOye5iyitR&<3B*SpEU~G z?>3?Y5!f2v65rZgmwJv5GHj`B{B7sS=~U-P&xWUl(-7@!h{e;gl_div*;G?(Ba6GY hxbILxK~Z9=VC|EhNYzYG?gP5_y<>KtET_} literal 0 HcmV?d00001 diff --git a/src/test/regress/jdbc_test/multi_simple_query/MultiSimpleQuery.java b/src/test/regress/jdbc_test/multi_simple_query/MultiSimpleQuery.java new file mode 100644 index 0000000000..dd4296d572 --- /dev/null +++ b/src/test/regress/jdbc_test/multi_simple_query/MultiSimpleQuery.java @@ -0,0 +1,114 @@ +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.CallableStatement; +import java.sql.Types; +import java.sql.*; + +public class MultiSimpleQuery { + + //创建数据库连接。 + public static Connection GetConnection(String username, String passwd, String port) { + String driver = "org.postgresql.Driver"; + String sourceURL = "jdbc:postgresql://localhost:" + port + "/regression?loggerLevel=off&preferQueryMode=simple"; + Connection conn = null; + try { + //加载数据库驱动。 + Class.forName(driver).newInstance(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + try { + //创建数据库连接。 + conn = DriverManager.getConnection(sourceURL, username, passwd); + System.out.println("Connection succeed!"); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + return conn; + } + + public static void Test2(Connection conn) { + Statement stmt1 = null; + try { + stmt1 = conn.createStatement(); + stmt1.executeUpdate("set enable_query_parameterization=off;"); + stmt1.executeUpdate("set enable_iud_fusion=on;"); + + String sql = "delete from msq2 where a=1; delete from msq2 where a=2"; + boolean ress = stmt1.execute(sql); + while (ress) { + ResultSet rs = stmt1.getResultSet(); + while (rs.next()) { + System.out.println(rs.getString(1)); + } + rs.close(); + ress = stmt1.getMoreResults(); + } + stmt1.close(); + } catch (SQLException e) { + if (stmt1 != null) { + try { + stmt1.close(); + } catch (SQLException e1) { + e1.printStackTrace(); + } + } + e.printStackTrace(); + } + } + + public static void Test1(Connection conn) { + Statement stmt1 = null; + try { + stmt1 = conn.createStatement(); + stmt1.executeUpdate("set enable_query_parameterization=on;"); + + String sql = "insert into multi_simple_query1 values(1); insert into multi_simple_query1 values(2)"; + boolean ress = stmt1.execute(sql); + while (ress) { + ResultSet rs = stmt1.getResultSet(); + while (rs.next()) { + System.out.println(rs.getString(1)); + } + rs.close(); + ress = stmt1.getMoreResults(); + } + stmt1.close(); + } catch (SQLException e) { + if (stmt1 != null) { + try { + stmt1.close(); + } catch (SQLException e1) { + e1.printStackTrace(); + } + } + e.printStackTrace(); + } + } + + /** + * 主程序,逐步调用各静态方法。 + * @param args + */ + public static void main(String[] args) { + //创建数据库连接。 + Connection conn = GetConnection("multi_simple_query", "tom@1234", args[0]); + + Test1(conn); + Test2(conn); + try { + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + + } + +} \ No newline at end of file diff --git a/src/test/regress/output/multi_simple_query.source b/src/test/regress/output/multi_simple_query.source new file mode 100755 index 0000000000..f5b39c27f6 --- /dev/null +++ b/src/test/regress/output/multi_simple_query.source @@ -0,0 +1,27 @@ +DROP USER IF EXISTS multi_simple_query CASCADE; +NOTICE: role "multi_simple_query" does not exist, skipping +CREATE USER multi_simple_query WITH PASSWORD "tom@1234"; +SET ROLE multi_simple_query PASSWORD 'tom@1234'; +create table multi_simple_query1(a int); +create table msq2(a int); +insert into msq2 values(1); +insert into msq2 values(2); +\! chmod -R 700 @abs_bindir@/../jre +\! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/jdbc_test/gsjdbc400.jar:@abs_builddir@/jdbc_test/multi_simple_query/. MultiSimpleQuery @portstring@ 2>&1 +Connection succeed! +select * from multi_simple_query1 order by 1; + a +--- + 1 + 2 +(2 rows) + +select * from msq2 order by 1; + a +--- +(0 rows) + +DROP TABLE multi_simple_query1; +DROP TABLE msq2; +RESET ROLE; +DROP USER IF EXISTS multi_simple_query CASCADE; diff --git a/src/test/regress/parallel_schedule0C b/src/test/regress/parallel_schedule0C index 3a70b3d314..6b104d0f13 100644 --- a/src/test/regress/parallel_schedule0C +++ b/src/test/regress/parallel_schedule0C @@ -29,7 +29,7 @@ test: explain_pbe test: pg_object_type dump_object_type pg_anydata_type #test jdbc pbe for bypass -test: bypass_pbe +test: bypass_pbe multi_simple_query #test: partition for hash list test: pbe_hash_list_partition test: hw_partition_list_insert -- Gitee