From 621d5004a611ccdfced06ed195f0db56cc534fe1 Mon Sep 17 00:00:00 2001 From: openGaussDev Date: Fri, 4 Mar 2022 18:01:54 +0800 Subject: [PATCH] fix error Offering: openGaussDev More detail: fix error Match-id-2ac331e2403136e00b782c83860331a198dbfcc1 --- src/common/pl/plpgsql/src/pl_exec.cpp | 11 -- src/gausskernel/runtime/executor/execQual.cpp | 24 +-- .../regress/expected/hw_package_single.out | 151 ++++++++++++++++++ src/test/regress/sql/hw_package_single.sql | 104 ++++++++++++ 4 files changed, 267 insertions(+), 23 deletions(-) diff --git a/src/common/pl/plpgsql/src/pl_exec.cpp b/src/common/pl/plpgsql/src/pl_exec.cpp index d9de55074..e4884c071 100644 --- a/src/common/pl/plpgsql/src/pl_exec.cpp +++ b/src/common/pl/plpgsql/src/pl_exec.cpp @@ -7986,11 +7986,6 @@ void exec_assign_value(PLpgSQL_execstate* estate, PLpgSQL_datum* target, Datum v bool is_have_huge_clob = false; struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(value)); value = fetch_lob_value_from_tuple(lob_pointer, InvalidOid, &is_null, &is_have_huge_clob); - if (is_have_huge_clob) { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("huge clob do not support as record element."))); - } } PLpgSQL_assignlist* assignvar = (PLpgSQL_assignlist*)target; List* assignlist = assignvar->assignlist; @@ -10666,12 +10661,6 @@ static void exec_move_row(PLpgSQL_execstate* estate, valtype = InvalidOid; } - if (valtype == CLOBOID && !isnull && VARATT_IS_HUGE_TOAST_POINTER(value)) { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("huge clob do not support as record element."))); - } - /* accept function's return value for cursor */ if (isnull == false && CheckTypeIsCursor(row, valtype, fnum) && estate->cursor_return_data != NULL) { diff --git a/src/gausskernel/runtime/executor/execQual.cpp b/src/gausskernel/runtime/executor/execQual.cpp index 36eef088b..f2b2db060 100644 --- a/src/gausskernel/runtime/executor/execQual.cpp +++ b/src/gausskernel/runtime/executor/execQual.cpp @@ -2274,7 +2274,6 @@ static Datum ExecMakeFunctionResultNoSets( bool savedProConfigIsSet = u_sess->SPI_cxt.is_proconfig_set; bool proIsProcedure = false; bool supportTranaction = false; - bool is_have_huge_clob = false; #ifdef ENABLE_MULTIPLE_NODES if (IS_PGXC_COORDINATOR && (t_thrd.proc->workingVersionNum >= STP_SUPPORT_COMMIT_ROLLBACK)) { @@ -2401,11 +2400,6 @@ static Datum ExecMakeFunctionResultNoSets( if (has_refcursor && fcinfo->argTypes[i] == REFCURSOROID) econtext->is_cursor = true; fcinfo->arg[i] = ExecEvalExpr(argstate, econtext, &fcinfo->argnull[i], NULL); - if (is_external_clob(fcinfo->argTypes[i], fcinfo->argnull[i], fcinfo->arg[i])) { - bool is_null = false; - struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(fcinfo->arg[i])); - fcinfo->arg[i] = fetch_lob_value_from_tuple(lob_pointer, InvalidOid, &is_null, &is_have_huge_clob); - } ExecTableOfIndexInfo execTableOfIndexInfo; initExecTableOfIndexInfo(&execTableOfIndexInfo, econtext); ExecEvalParamExternTableOfIndex((Node*)argstate->expr, &execTableOfIndexInfo); @@ -2457,11 +2451,6 @@ static Datum ExecMakeFunctionResultNoSets( pgstat_init_function_usage(fcinfo, &fcusage); - if (fcinfo->flinfo->fn_addr != textcat && is_have_huge_clob) { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("huge clob do not support as function in parameter"))); - } fcinfo->isnull = false; if (u_sess->instr_cxt.global_instr != NULL && fcinfo->flinfo->fn_addr == plpgsql_call_handler) { StreamInstrumentation* save_global_instr = u_sess->instr_cxt.global_instr; @@ -2469,6 +2458,17 @@ static Datum ExecMakeFunctionResultNoSets( result = FunctionCallInvoke(fcinfo); // node will be free at here or else; u_sess->instr_cxt.global_instr = save_global_instr; } else { + if (fcinfo->argTypes[0] == CLOBOID && fcinfo->argTypes[1] == CLOBOID && fcinfo->flinfo->fn_addr == textcat) { + bool is_null = false; + if (fcinfo->arg[0] != 0 && VARATT_IS_EXTERNAL_LOB(fcinfo->arg[0])) { + struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(fcinfo->arg[0])); + fcinfo->arg[0] = fetch_lob_value_from_tuple(lob_pointer, InvalidOid, &is_null); + } + if (fcinfo->arg[1] != 0 && VARATT_IS_EXTERNAL_LOB(fcinfo->arg[1])) { + struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(fcinfo->arg[1])); + fcinfo->arg[1] = fetch_lob_value_from_tuple(lob_pointer, InvalidOid, &is_null); + } + } result = FunctionCallInvoke(fcinfo); } *isNull = fcinfo->isnull; @@ -6027,7 +6027,7 @@ Datum fetch_lob_value_from_tuple(varatt_lob_pointer* lob_pointer, Oid update_oid if (*is_null) { new_attr = (Datum)0; } else { - if (VARATT_IS_SHORT(attr) || VARATT_IS_EXTERNAL(attr)) { + if (VARATT_IS_SHORT(attr) || VARATT_IS_EXTERNAL(attr) || VARATT_IS_4B(attr)) { new_attr = PointerGetDatum(attr); } else if (VARATT_IS_HUGE_TOAST_POINTER(attr)) { if (unlikely(origin_tuple->tupTableType == UHEAP_TUPLE)) { diff --git a/src/test/regress/expected/hw_package_single.out b/src/test/regress/expected/hw_package_single.out index f99807a79..19bfe590d 100644 --- a/src/test/regress/expected/hw_package_single.out +++ b/src/test/regress/expected/hw_package_single.out @@ -304,6 +304,7 @@ BEGIN END; / call test_substr(); +23 test_substr ------------- @@ -538,5 +539,155 @@ LINE 1: select proc_test1('1',''); HINT: No function matches the given name and argument types. You might need to add explicit type casts. CONTEXT: referenced column: proc_test1 drop procedure proc_test1; +--test write+update +create table test_clob(a int, b clob); +create table test_blob(a int, b blob); +insert into test_clob values(1, 'abc'); +insert into test_clob values(2, 'zzz'); +insert into test_blob values(1, 'abc'); +insert into test_blob values(2, 'fffffff'); +create or replace procedure test_clob_write +as + dest_clob clob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_clob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_clob; + dbe_lob.write(dest_clob, 1, 1, 'ddd'); + return; +end; +/ +call test_clob_write(); + test_clob_write +----------------- + +(1 row) + +select * from test_clob; + a | b +---+----- + 2 | zzz + 1 | dbc +(2 rows) + +create or replace procedure test_lob_write_nodyna +as +declare + dest_clob clob; +begin + select b from test_clob where a = 2 into dest_clob; + dbe_lob.write(dest_clob, 1, 1, 'eeee'); + DBE_OUTPUT.print_line(dest_clob); + return; +end; +/ +call test_lob_write_nodyna(); + test_lob_write_nodyna +----------------------- + +(1 row) + +select * from test_clob; + a | b +---+----- + 1 | dbc + 2 | ezz +(2 rows) + +create or replace procedure test_blob_write +as + dest_blob blob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_blob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_blob; + dbe_lob.write(dest_blob, 1, 1, 'ddd'); + return; +end; +/ +call test_blob_write(); + test_blob_write +----------------- + +(1 row) + +select * from test_blob; + a | b +---+---------- + 2 | 0FFFFFFF + 1 | 0DBC +(2 rows) + +--test append+update +create or replace procedure test_clob_append +as + dest_clob clob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_clob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_clob; + dbe_lob.append(dest_clob, 'ddd'); + return; +end; +/ +call test_clob_append(); + test_clob_append +------------------ + +(1 row) + +select * from test_clob; + a | b +---+-------- + 2 | ezz + 1 | dbcddd +(2 rows) + +create or replace procedure test_blob_append +as + dest_blob blob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_blob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_blob; + dbe_lob.append(dest_blob, 'ddd'); + return; +end; +/ +call test_blob_append(); + test_blob_append +------------------ + +(1 row) + +select * from test_blob; + a | b +---+---------- + 2 | 0FFFFFFF + 1 | 0DBC0DDD +(2 rows) + +--test read +create or replace procedure test_clob_read +as + dest_clob clob; + buf clob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_clob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_clob; + dbe_lob.read(dest_clob, 1, 1, buf); + DBE_OUTPUT.print_line(buf); + return; +end; +/ +call test_clob_read(); +d + test_clob_read +---------------- + +(1 row) + +drop table if exists test_clob; \c regression; drop database IF EXISTS pl_test_pkg_single; diff --git a/src/test/regress/sql/hw_package_single.sql b/src/test/regress/sql/hw_package_single.sql index ced0cb9f0..4a8acede2 100644 --- a/src/test/regress/sql/hw_package_single.sql +++ b/src/test/regress/sql/hw_package_single.sql @@ -345,6 +345,110 @@ end; select proc_test1('1',''); drop procedure proc_test1; + +--test write+update +create table test_clob(a int, b clob); +create table test_blob(a int, b blob); + +insert into test_clob values(1, 'abc'); +insert into test_clob values(2, 'zzz'); + +insert into test_blob values(1, 'abc'); +insert into test_blob values(2, 'fffffff'); + +create or replace procedure test_clob_write +as + dest_clob clob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_clob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_clob; + dbe_lob.write(dest_clob, 1, 1, 'ddd'); + return; +end; +/ +call test_clob_write(); +select * from test_clob; + +create or replace procedure test_lob_write_nodyna +as +declare + dest_clob clob; +begin + select b from test_clob where a = 2 into dest_clob; + dbe_lob.write(dest_clob, 1, 1, 'eeee'); + DBE_OUTPUT.print_line(dest_clob); + return; +end; +/ + +call test_lob_write_nodyna(); +select * from test_clob; + +create or replace procedure test_blob_write +as + dest_blob blob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_blob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_blob; + dbe_lob.write(dest_blob, 1, 1, 'ddd'); + return; +end; +/ +call test_blob_write(); +select * from test_blob; + +--test append+update +create or replace procedure test_clob_append +as + dest_clob clob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_clob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_clob; + dbe_lob.append(dest_clob, 'ddd'); + return; +end; +/ + +call test_clob_append(); +select * from test_clob; + +create or replace procedure test_blob_append +as + dest_blob blob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_blob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_blob; + dbe_lob.append(dest_blob, 'ddd'); + return; +end; +/ + +call test_blob_append(); +select * from test_blob; + +--test read +create or replace procedure test_clob_read +as + dest_clob clob; + buf clob; + PSV_SQL varchar(100); +begin + PSV_SQL := 'select b from test_clob where a = 1'; + EXECUTE IMMEDIATE PSV_SQL into dest_clob; + dbe_lob.read(dest_clob, 1, 1, buf); + DBE_OUTPUT.print_line(buf); + return; +end; +/ + +call test_clob_read(); + +drop table if exists test_clob; + \c regression; drop database IF EXISTS pl_test_pkg_single;