【GaussDB】507内核新特性-PLSQL字节码(二)
前言
上一篇《【GaussDB】507内核新特性-PLSQL字节码(一)》讲了正常使用的情况,这篇来讲讲使用约束。
一般来说,一个功能在哪些场景下支持,哪些场景下不支持,往往要么写白名单,要么写黑名单,不会两个都写上。
白名单意味着:产品保证在这些场景下可用,如果试出了在白名单以外的场景也可用,官方不保证没问题,用出问题不算BUG,设计如此;
黑名单意味着:产品明确这些场景有问题,如果发现黑名单里的东西是支持的,那是BUG,官方不保证每次都能正常使用。黑名单以外的场景都支持,测出问题那是BUG,官方会负责修复或者改文档增加黑名单内容。
但这次GaussDB把黑白名单都放文档里了,对于PLSQL这一复杂的开发语言而言,不可能两个章节就能把所有的场景都描述进去,所以这个黑白双名单就有点耐人寻味了。
本文环境参数配置
gs_guc reload -I all -N all -c "ddl_invalid_mode='invalid'";
gs_guc reload -I all -N all -c "enable_force_create_obj=on";
gs_guc reload -I all -N all -c "a_format_dev_version='s6'"
gs_guc reload -I all -N all -c "behavior_compat_options='aformat_null_test,aformat_regexp_match,allow_procedure_compile_check,bind_procedure_searchpath,compat_cursor,convert_string_digit_to_numeric,correct_to_number,current_sysdate,display_leading_zero,dynamic_sql_compat,enable_bpcharlikebpchar_compare,enable_case_when_alias,enable_crosstype_integer_operator,enable_ora_joinop_in_updatestmt,enable_use_ora_timestamptz,end_month_calculate,forbid_package_function_with_prefix,forbid_skip_tableof_empty_str_elem,forbid_update_multi_same_tables,plsql_rollback_keep_user,plsql_security_definer,plstmt_implicit_savepoint,proc_implicit_for_loop_variable,proc_outparam_override,proc_outparam_transfer_length,rownum_type_compat,show_full_error_lineno,sys_function_without_brackets,tableof_elem_constraints,time_constexpr_compact,truncate_numeric_tail_zero,unbind_divide_bound,varray_compat'"
gs_guc reload -I all -N all -c "plsql_code_type='BYTECODE'"
注意当前版本的自治事务不会从主事务复制plsql_code_type参数,因此需要全局设置。
另外,为了方便从日志观察,全局打开了字节码的日志
gs_guc reload -I all -N all -c "logging_module = 'on(BYTECODE)'"
测试
下面开始根据官方文档所说的约束,逐条开始进行测试,但有些一眼看破的东西我就懒得写代码测了,写个说明完事。
-
目前不支持的DFX功能:PLDEBUGGER(打开PLDEBUGGER时,函数或存储过程将通过传统引擎执行),PG_STAT_USER_FUNCTIONS视图(仅统计通过传统引擎执行存储过程或函数的时间)。
这里应该是指DBE_PLDEBUGGER存储过程调试功能,以及自定义函数统计信息收集视图 -
不支持PACKAGE实例化。
字节码按照proc维度实例化,package里的procedure和function是可以实例化的,只是package本身不作为一个整体实例化 -
不支持匿名块。
直接执行的匿名块不是保存在数据库里的对象,没有pg_proc的oid,就不支持,但是通过匿名块执行的proc,或者proc里嵌套的匿名块是支持的。另外,包的初始化匿名块也不支持,但含有初始化匿名块的包内的proc是支持的。
gaussdb=> create or replace package pkg_test1 is
gaussdb$> x int;
gaussdb$> procedure a1 ;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=>
gaussdb=> create or replace package body pkg_test1 is
gaussdb$> procedure a1 is
gaussdb$> begin
gaussdb$> x:=x+1;
gaussdb$> end;
gaussdb$> begin
gaussdb$> x:=0;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE BODY
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call pkg_test1.a1();
LOG: [ByteCode] BC019 proc 177 isn't pllanguage.
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 32976.
LOG: [ByteCode] Function: a1(), InterpreterBytecode:
[0] exec_stmt_begin
[21] loadn_pkg 0
[26] iconst1
[27] function func: int4pl
[40] storen_pkg 0
[45] exec_stmt_end
[58] exec_stmt_begin
[79] exec_stmt_end
[92] return0 5
LOG: Start ByteCode!
-[ RECORD 1 ]
a1 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=>
gaussdb=> select bytecode from dump_plsql_bytecode('pkg_test1.a1'::regproc);
-[ RECORD 1 ]-------------------------
bytecode | [0] exec_stmt_begin
| [21] loadn_pkg 0
| [26] iconst1
| [27] function func: int4pl
| [40] storen_pkg 0
| [45] exec_stmt_end
| [58] exec_stmt_begin
| [79] exec_stmt_end
| [92] return0 5
|
gaussdb=>
- 不支持TRIGGER。
trigger本身不是pl对象,它需要关联一个proc,就算是使用O的匿名块语法,也会隐式创建一个同名的proc
gaussdb=> CREATE TABLE test_trigger_src_tbl(id1 INT, id2 INT, id3 INT);
CREATE TABLE
gaussdb=> CREATE TABLE test_trigger_des_tbl(id1 INT, id2 INT, id3 INT);
CREATE TABLE
gaussdb=> CREATE TRIGGER insert_trigger_with_anonyblock
gaussdb-> BEFORE INSERT ON test_trigger_src_tbl
gaussdb-> FOR EACH ROW
gaussdb-> DECLARE
gaussdb-> BEGIN
gaussdb$> INSERT INTO test_trigger_des_tbl VALUES(NEW.id1, NEW.id2, NEW.id3);
gaussdb$> RETURN NEW;
gaussdb$> END;
gaussdb$> /
CREATE TRIGGER
gaussdb=> select * from pg_trigger where tgname='insert_trigger_with_anonyblock';
-[ RECORD 1 ]--+-------------------------------
tgrelid | 32977
tgname | insert_trigger_with_anonyblock
tgfoid | 32983
tgtype | 7
tgenabled | O
tgisinternal | f
tgconstrrelid | 0
tgconstrindid | 0
tgconstraint | 0
tgdeferrable | f
tginitdeferred | f
tgnargs | 0
tgattr |
tgargs | \x
tgqual |
tgowner | 16547
gaussdb=> select * from pg_proc where proname='insert_trigger_with_anonyblock';
-[ RECORD 1 ]-------+--------------------------------------------------------------------
proname | insert_trigger_with_anonyblock
pronamespace | 16550
proowner | 16547
prolang | 11442
procost | 100
prorows | 0
provariadic | 0
protransform | -
proisagg | f
proiswindow | f
prosecdef | t
proleakproof | f
proisstrict | f
proretset | f
provolatile | v
pronargs | 0
pronargdefaults | 0
prorettype | 2279
proargtypes |
proallargtypes |
proargmodes |
proargnames |
proargdefaults |
prosrc | DECLARE
| BEGIN
| INSERT INTO test_trigger_des_tbl VALUES(NEW.id1, NEW.id2, NEW.id3);
| RETURN NEW;
| END
probin |
proconfig |
proacl | {admin=X/admin}
prodefaultargpos |
fencedmode | f
proshippable | f
propackage | f
prokind | t
proargsrc |
propackageid | 0
proisprivate | f
proargtypesext |
prodefaultargposext |
allargtypes |
allargtypesext |
gaussdb=>
gaussdb=> set client_min_messages = log;
SET
gaussdb=> insert into test_trigger_src_tbl values (1,2,3);
LOG: [ByteCode] BC003 bytecode doesn't support trigger func.
LOG: [ByteCode] BC053 bytecode only support select statement.
LOG: [ByteCode] BC039 This function doesn't support bytecode, func_oid: 32983.
INSERT 0 1
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('insert_trigger_with_anonyblock'::regproc);
-[ RECORD 1 ]-----------
bytecode | Not supported
gaussdb=>
测试的确是 Not supported 。
- 不支持返回集合的函数。
这里就有点描述不清了,以下我分三个场景测试
- returns setof
gaussdb=> DROP TABLE if exists t1;
NOTICE: table "t1" does not exist, skipping
DROP TABLE
gaussdb=> CREATE TABLE t1(a int);
CREATE TABLE
gaussdb=> INSERT INTO t1 VALUES(1),(10);
INSERT 0 2
gaussdb=> CREATE OR REPLACE FUNCTION fun_for_return_next() RETURNS SETOF t1 AS $$
gaussdb$> DECLARE
gaussdb$> r t1%ROWTYPE;
gaussdb$> BEGIN
gaussdb$> FOR r IN select * from t1
gaussdb$> LOOP
gaussdb$> RETURN NEXT r;
gaussdb$> END LOOP;
gaussdb$> RETURN;
gaussdb$> END;
gaussdb$> $$ LANGUAGE plpgsql;
CREATE FUNCTION
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call fun_for_return_next();
LOG: [ByteCode] BC004 bytecode doesn't support func which returns set.
LOG: [ByteCode] BC030 Stmt RETURN NEXT does not support with some error, lineno: 7.
LOG: [ByteCode] BC039 This function doesn't support bytecode, func_oid: 32988.
-[ RECORD 1 ]
a | 1
-[ RECORD 2 ]
a | 10
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode((select oid from pg_proc where proname='fun_for_return_next'));
-[ RECORD 1 ]-----------
bytecode | Not supported
gaussdb=>
- returns table
gaussdb=> CREATE OR REPLACE FUNCTION fun_for_return_next2() RETURNS table (a int) AS $$
gaussdb$> DECLARE
gaussdb$> r t1%ROWTYPE;
gaussdb$> BEGIN
gaussdb$> RETURN query select * from t1;
gaussdb$> END;
gaussdb$> $$ LANGUAGE plpgsql;
CREATE FUNCTION
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call fun_for_return_next2(null);
LOG: [ByteCode] BC004 bytecode doesn't support func which returns set.
LOG: [ByteCode] BC013 The bytecode does not allow parameters except in & out.
LOG: [ByteCode] BC039 This function doesn't support bytecode, func_oid: 32991.
-[ RECORD 1 ]
a | 1
-[ RECORD 2 ]
a | 10
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode((select oid from pg_proc where proname='fun_for_return_next2'));
-[ RECORD 1 ]-----------
bytecode | Not supported
gaussdb=>
- return type (is table of )
gaussdb=> create type ty_test5 as (a int,b int);
CREATE TYPE
gaussdb=> create type tyt_test5 is table of ty_test5;
CREATE TYPE
gaussdb=> create function f5 return tyt_test5 is
gaussdb$> v tyt_test5:=tyt_test5();
gaussdb$> begin
gaussdb$> v.extend;
gaussdb$> v(1):=ty_test5(1,2);
gaussdb$> return v;
gaussdb$> end;
gaussdb$> /
CREATE FUNCTION
gaussdb=> set client_min_messages = log;
SET
gaussdb=> select f5();
LOG: [ByteCode] BC019 proc 6149 isn't pllanguage.
CONTEXT: referenced column: f5
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 32997.
CONTEXT: referenced column: f5
LOG: [ByteCode] Function: f5(), InterpreterBytecode:
[0] create_nesttable tyt_test5 0
[9] storen_nesttable 9
[22] exec_stmt_begin
[43] loadn_expand 9
[48] iconst1
[49] function func: nesttable_extend
[62] storen_nesttable 9
[75] exec_stmt_end
[88] exec_stmt_begin
[109] iconst1
[110] iconst2
[111] eval_rowexpr
[120] expand_and_load_table 9
[125] iconst1
[126] store_nesttable_elem 2249 -1
[135] exec_stmt_end
[148] exec_stmt_begin
[169] loadn_expand 9
[174] transfer
[179] exec_stmt_end
[192] return 5
CONTEXT: referenced column: f5
LOG: Start ByteCode!
CONTEXT: referenced column: f5
-[ RECORD 1 ]-
f5 | {"(1,2)"}
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode((select oid from pg_proc where proname='f5'));
-[ RECORD 1 ]-----------------------------------
bytecode | [0] create_nesttable tyt_test5 0
| [9] storen_nesttable 9
| [22] exec_stmt_begin
| [43] loadn_expand 9
| [48] iconst1
| [49] function func: nesttable_extend
| [62] storen_nesttable 9
| [75] exec_stmt_end
| [88] exec_stmt_begin
| [109] iconst1
| [110] iconst2
| [111] eval_rowexpr
| [120] expand_and_load_table 9
| [125] iconst1
| [126] store_nesttable_elem 2249 -1
| [135] exec_stmt_end
| [148] exec_stmt_begin
| [169] loadn_expand 9
| [174] transfer
| [179] exec_stmt_end
| [192] return 5
|
gaussdb=>
return 嵌套表类型是支持的,returns setof/table 是不支持的。
- 不支持高级包以及系统函数。
自定义pl存储过程里使用系统函数不会导致自定义存储过程不支持字节码,像下面这种日志其实没有影响
LOG: [ByteCode] BC019 proc 7752 isn't pllanguage.
LOG: [ByteCode] BC019 proc 1724 isn't pllanguage.
- 不支持带有出参的FUNCTION在表达式中嵌套调用。
这个用法在GaussDB本来就是会报错的,与字节码无关
gaussdb=> create function f1(o out int) return varchar2 is
gaussdb$> begin
gaussdb$> return 'a';
gaussdb$> end;
gaussdb$> /
CREATE FUNCTION
gaussdb=> set client_min_messages = log;
SET
gaussdb=> declare
gaussdb-> x text;
gaussdb-> o int;
gaussdb-> begin
gaussdb$> x:=x||f1(o);
gaussdb$> end;
gaussdb$> /
ERROR: Function f1 with out parameters cannot be called by an expression.
CONTEXT: PL/pgSQL function inline_code_block line 5 at assignment
gaussdb=> reset client_min_messages;
RESET
gaussdb=>
不嵌套,直接x:=f1(o);是可以使用字节码的
- 不支持RETURN复合类型的带有出参的FUNCTION。
gaussdb=> create type ty_test1 as (a int,b int);
CREATE TYPE
gaussdb=> create or replace function f2(o out int) return ty_test1 is
gaussdb$> x ty_test1:=ty_test1();
gaussdb$> begin
gaussdb$> return x;
gaussdb$> end;
gaussdb$> /
CREATE FUNCTION
gaussdb=> set client_min_messages = log;
SET
gaussdb=> declare
gaussdb-> x ty_test1;
gaussdb-> v int;
gaussdb-> begin
gaussdb$> x:=f2(v);
gaussdb$> end;
gaussdb$> /
LOG: [ByteCode] BC057 bytecode doesn't support function with outparam return record.
CONTEXT: SQL statement "CALL f2(v)"
PL/pgSQL function inline_code_block line 5 at assignment
LOG: [ByteCode] BC059 bytecode does not support return var is not out param var.
CONTEXT: SQL statement "CALL f2(v)"
PL/pgSQL function inline_code_block line 5 at assignment
LOG: [ByteCode] BC030 Stmt RETURN does not support with some error, lineno: 4.
CONTEXT: SQL statement "CALL f2(v)"
PL/pgSQL function inline_code_block line 5 at assignment
LOG: [ByteCode] BC039 This function doesn't support bytecode, func_oid: 33002.
CONTEXT: SQL statement "CALL f2(v)"
PL/pgSQL function inline_code_block line 5 at assignment
ANONYMOUS BLOCK EXECUTE
gaussdb=> reset client_min_messages;
RESET
gaussdb=>
这里其实报了两个不支持,一是不支持带出参的函数返回record/复合类型,二是不支持返回值不是出参值("返回值是出参值"指的是PG风格带出参的function,out参数其实就是定义的return,但既然必须要开启proc_outparam_override,就肯定不会是PG风格的出参,不知该如何理解)
- 不支持PROCEDURE显式指定RETURN值(正常用法PROCEDURE无需RETURN值)。
gaussdb=> create or replace procedure p1 is
gaussdb$> begin
gaussdb$> return '';
gaussdb$> end;
gaussdb$> /
WARNING: RETURN cannot have a parameter in a function returning void.
DETAIL: N/A
CONTEXT: compilation of PL/pgSQL function "p1" near line 3
WARNING: Procedure created with compilation errors.
CREATE PROCEDURE
gaussdb=>
这玩意本身就会编译报错,无法执行的。
- 不支持子程序。
gaussdb=> create or replace procedure p2 is
gaussdb$> a int;
gaussdb$> procedure p3 is
gaussdb$> begin
gaussdb$> null;
gaussdb$> end;
gaussdb$> begin
gaussdb$> p3();
gaussdb$> a:=a+1;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p2();
LOG: [ByteCode] BC068 bytecode neither support nest sub procedure/function nor subtype.
-[ RECORD 1 ]
p2 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p2'::regproc);
-[ RECORD 1 ]-----------
bytecode | Not supported
gaussdb=>
的确不支持
- 主事务不支持嵌套调用自治事务的表达式执行字节码(自治事务创建的新SESSION执行存储过程可以通过字节码框架执行)。
这里需要注意,自治事务是新开连接,而且plsql_code_type这个参数的值不会从主事务复制到自治事务,因此自治事务如果要使用字节码,则需要在非会话级设置,比如database/role/instance级别
- 存储过程里嵌套了一个自治事务的匿名块
gaussdb=> create or replace procedure p_main2 is
gaussdb$> x int:=0;
gaussdb$> begin
gaussdb$> x:=x+1;
gaussdb$> declare
gaussdb$> PRAGMA AUTONOMOUS_TRANSACTION;
gaussdb$> begin
gaussdb$> x:=x+2;
gaussdb$> end;
gaussdb$> x:=x+3;
gaussdb$> end;
gaussdb$> /
ERROR: Autonomous transactions do not support nested anonymous blocks.
DETAIL: N/A
gaussdb=>
创建就报错
- 自治事务里调用另一个非自治事务的存储过程
gaussdb=> create or replace procedure p_main2 is
gaussdb$> x int:=0;
gaussdb$> begin
gaussdb$> x:=x+1;
gaussdb$> x:=x+3;
gaussdb$> commit;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> create or replace procedure p_autom2 is
gaussdb$> x int;
gaussdb$> PRAGMA AUTONOMOUS_TRANSACTION;
gaussdb$> begin
gaussdb$> raise notice 'plsql_code_type:%',current_setting('plsql_code_type');
gaussdb$> raise notice 'client_min_messages:%',current_setting('client_min_messages');raise notice 'logging_module:%',current_setting('logging_module');
gaussdb$> x:=x+1;
gaussdb$> p_main2();
gaussdb$> commit;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> alter database postgres set client_min_messages = log;
NOTICE: SET "client_min_messages" TO "log" will only take effect after restarting session.
ALTER DATABASE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p_autom2();
LOG: [ByteCode] BC019 proc 177 isn't pllanguage.
CONTEXT: referenced column: p_autom2
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33007.
CONTEXT: referenced column: p_autom2
LOG: [ByteCode] Function: p_autom2(), InterpreterBytecode:
[0] exec_stmt_begin
[21] exec_stmt_treebased
[34] exec_stmt_end
[47] exec_stmt_begin
[68] exec_stmt_treebased
[81] exec_stmt_end
[94] exec_stmt_begin
[115] exec_stmt_treebased
[128] exec_stmt_end
[141] exec_stmt_begin
[162] loadn 9
[167] iconst1
[168] function func: int4pl
[181] storen 9
[186] exec_stmt_end
[199] exec_stmt_begin
[220] procedure expression expr: CALL p_main2()
[257] exec_stmt_end
[270] nop_pop
[271] exec_stmt_begin
[292] exec_stmt_treebased_transaction
[305] exec_stmt_end
[318] exec_stmt_begin
[339] exec_stmt_end
[352] return0 5
CONTEXT: referenced column: p_autom2
LOG: Start ByteCode!
CONTEXT: referenced column: p_autom2
NOTICE: plsql_code_type:BYTECODE
CONTEXT: referenced column: p_autom2
NOTICE: client_min_messages:log
CONTEXT: referenced column: p_autom2
NOTICE: logging_module:ALL,on(BYTECODE),off(COMMAND,DFS,GUC,GSCLEAN,HDFS,ORC,SLRU,MEM_CTL,AUTOVAC,CACHE,ADIO,SSL,GDS,TBLSPC,WLM,OBS,INDEX,EXECUTOR,OPFUSION,GPC,GSC,VEC_EXECUTOR,STREAM,LLVM,OPT,OPT_REWRITE,CBOPT_REWRITE,OPT_JOIN,OPT_AGG,OPT_CHOICE,OPT_SUBPLAN,OPT_SETOP,OPT_SKEW,OPT_PLANNER,OPT_STAT_EXT,OPT_SHIPPING,OPT_DSL_REWRITE,SPM,SPM_BG,SPM_KEY_FLOW,UDF,COOP_ANALYZE,WLMCP,ACCELERATE,MOT,PLANHINT,PARQUET,PGSTAT,CARBONDATA,SNAPSHOT,XACT,HANDLE,CLOG,EC,REMOTE,CN_RETRY,PLSQL,PLSQL_COMPILE,PLSQL_TRANS,TEXTSEARCH,SEQ,REDO,FUNCTION,PARSER,INSTR,WDR_SNAPSHOT,GSMONITOR,WDR_REPORT,ASP_REPORT,BLACKBOX,INCRE_CKPT,INCRE_BG_WRITER,DBL_WRT,RTO_RPO,HEARTBEAT,COMM_IPC,COMM_PARAM,TIMESERIES,SCHEMA,GTT,SEGMENT_PAGE,LIGHTPROXY,HOTKEY,THREAD_POOL,OPT_AI,WALRECEIVER,USTORE,UPAGE,UBTREE,UNDO,TIMECAPSULE,GEN_COL,DCF,AI4DB,DB4AI,ABO,MOD_ABOFEEDBACK,ASCEND,PLDEBUGGER,ADVISOR,SEC,SEC_FE,SEC_LEGER,SEC_POLICY,SEC_SDD,SEC_TDE,COMM_FRAMEWORK,COMM_PROXY,COMM_POOLER,COMM_STATUS,VACUUM,JOB,SPI,NEST_COMPILE,RESOWNER,GSSTACK,LOGICAL_DECODE,GPRC,DISASTER_READ,STANDBY_READ,SQL_APPLY,REPSYNC,SQLPATCH,PARTITION,UBT_NEWPAGE,GS_DEPENDENCY,GPI,LWLOCK,LOCK,UNIQUE_SQL,GLC,SRF,DBLINK,BARRIER_CREATOR,EXRTO_PAGE_P,SEQ_TUP_P,BT_TUP_P,DISPATCH_VERIFY,HBKT,HBKT_CBI,DBE_STATS,DBE_XMLGEN,MESSAGE_QUEUE,DBE_ALERT,GS_ILM,GSPERF,PARAMETERIZE,EXEC_REMOTE,UBTREE_PARA,BTREE_PARA,ANTI_CACHE,ANTI_RECYCLER,VERIFYLOG,PARALLEL_BUILD,GS_REPAIR,AUTHID,CCINDEX,ONLINE_DDL,MTD,EXRTO_BUFFER,WAL,HTAP,UALT,GTM_LITE_READ_S,UGIN,LOCAL_CACHE,BIINDEX,ONDEMAND,DATEA,TURBO_COMPRESS,GS_SIGNAL,AUTOHINT,EXRTO_READ_RECY,CHARACTER,ABNORMAL_SQL,GAUSS_STOR,BUFFILE,BUFFER,PAGE,SELCACHE,UTIL,FUNC_DEPEND,MOD_DBE_LOB,EXEC_CACHE,ROWID,WAL_IMAGE_CHECK,CHECK_XLOG_GEN,SHARE_STORAGE,MOD_TOOLKIT)
CONTEXT: referenced column: p_autom2
LOG: [ByteCode] BC019 proc 177 isn't pllanguage.
CONTEXT: SQL statement "CALL p_main2()"
PL/pgSQL function p_autom2() line 8 at PERFORM
referenced column: p_autom2
LOG: [ByteCode] BC019 proc 177 isn't pllanguage.
CONTEXT: SQL statement "CALL p_main2()"
PL/pgSQL function p_autom2() line 8 at PERFORM
referenced column: p_autom2
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33006.
CONTEXT: SQL statement "CALL p_main2()"
PL/pgSQL function p_autom2() line 8 at PERFORM
referenced column: p_autom2
LOG: [ByteCode] Function: p_main2(), InterpreterBytecode:
[0] iconst0
[1] storen 9
[6] exec_stmt_begin
[27] loadn 9
[32] iconst1
[33] function func: int4pl
[46] storen 9
[51] exec_stmt_end
[64] exec_stmt_begin
[85] loadn 9
[90] iconst3
[91] function func: int4pl
[104] storen 9
[109] exec_stmt_end
[122] exec_stmt_begin
[143] exec_stmt_treebased_transaction
[156] exec_stmt_end
[169] exec_stmt_begin
[190] exec_stmt_end
[203] return0 5
CONTEXT: SQL statement "CALL p_main2()"
PL/pgSQL function p_autom2() line 8 at PERFORM
referenced column: p_autom2
LOG: [ByteCode] Function: CALL p_main2(), InterpreterBytecode:
[0] nop_push
[1] invokemethod_definer func: p_main2
CONTEXT: PL/pgSQL function p_autom2() line 8 at PERFORM
referenced column: p_autom2
-[ RECORD 1 ]
p_autom2 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> alter database postgres reset client_min_messages;
NOTICE: SET "client_min_messages" TO "(null)" will only take effect after restarting session.
ALTER DATABASE
gaussdb=> select bytecode from dump_plsql_bytecode('p_main2'::regproc);
-[ RECORD 1 ]-------------------------------------
bytecode | [0] iconst0
| [1] storen 9
| [6] exec_stmt_begin
| [27] loadn 9
| [32] iconst1
| [33] function func: int4pl
| [46] storen 9
| [51] exec_stmt_end
| [64] exec_stmt_begin
| [85] loadn 9
| [90] iconst3
| [91] function func: int4pl
| [104] storen 9
| [109] exec_stmt_end
| [122] exec_stmt_begin
| [143] exec_stmt_treebased_transaction
| [156] exec_stmt_end
| [169] exec_stmt_begin
| [190] exec_stmt_end
| [203] return0 5
|
gaussdb=> select bytecode from dump_plsql_bytecode('p_autom2'::regproc);
-[ RECORD 1 ]----------------------------------------------
bytecode | [0] exec_stmt_begin
| [21] exec_stmt_treebased
| [34] exec_stmt_end
| [47] exec_stmt_begin
| [68] exec_stmt_treebased
| [81] exec_stmt_end
| [94] exec_stmt_begin
| [115] exec_stmt_treebased
| [128] exec_stmt_end
| [141] exec_stmt_begin
| [162] loadn 9
| [167] iconst1
| [168] function func: int4pl
| [181] storen 9
| [186] exec_stmt_end
| [199] exec_stmt_begin
| [220] procedure expression expr: CALL p_main2()
| [257] exec_stmt_end
| [270] nop_pop
| [271] exec_stmt_begin
| [292] exec_stmt_treebased_transaction
| [305] exec_stmt_end
| [318] exec_stmt_begin
| [339] exec_stmt_end
| [352] return0 5
|
gaussdb=>
两个存储过程都支持字节码。
这里注意,自治事务没有复制主事务的client_min_messages参数,所以额外在数据库级别上设置了一下,否则打不出这个日志
- 存储过程里调用了另一个自治事务的存储过程
gaussdb=> create or replace procedure p_autom1 is
gaussdb$> x int;
gaussdb$> PRAGMA AUTONOMOUS_TRANSACTION;
gaussdb$> begin
gaussdb$> x:=x+1;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> create or replace procedure p_main1 is
gaussdb$> begin
gaussdb$> p_autom1();
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> alter database postgres set client_min_messages = log;
NOTICE: SET "client_min_messages" TO "log" will only take effect after restarting session.
ALTER DATABASE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p_main1();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33009.
LOG: [ByteCode] Function: p_main1(), InterpreterBytecode:
[0] exec_stmt_begin
[21] procedure expression expr: CALL p_autom1()
[58] exec_stmt_end
[71] nop_pop
[72] exec_stmt_begin
[93] exec_stmt_end
[106] return0 5
LOG: Start ByteCode!
LOG: [ByteCode] BC072 Expression: CALL p_autom1() is degenerated.
CONTEXT: PL/pgSQL function p_main1() line 3 at PERFORM
LOG: [ByteCode] BC019 proc 177 isn't pllanguage.
CONTEXT: referenced column: p_autom1
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33008.
CONTEXT: referenced column: p_autom1
LOG: [ByteCode] Function: p_autom1(), InterpreterBytecode:
[0] exec_stmt_begin
[21] loadn 9
[26] iconst1
[27] function func: int4pl
[40] storen 9
[45] exec_stmt_end
[58] exec_stmt_begin
[79] exec_stmt_end
[92] return0 5
CONTEXT: referenced column: p_autom1
LOG: Start ByteCode!
CONTEXT: referenced column: p_autom1
-[ RECORD 1 ]
p_main1 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> alter database postgres reset client_min_messages;
NOTICE: SET "client_min_messages" TO "(null)" will only take effect after restarting session.
ALTER DATABASE
gaussdb=> select bytecode from dump_plsql_bytecode('p_autom1'::regproc);
-[ RECORD 1 ]-------------------------
bytecode | [0] exec_stmt_begin
| [21] loadn 9
| [26] iconst1
| [27] function func: int4pl
| [40] storen 9
| [45] exec_stmt_end
| [58] exec_stmt_begin
| [79] exec_stmt_end
| [92] return0 5
|
gaussdb=> select bytecode from dump_plsql_bytecode('p_main1'::regproc);
-[ RECORD 1 ]----------------------------------------------
bytecode | [0] exec_stmt_begin
| [21] procedure expression expr: CALL p_autom1()
| [58] exec_stmt_end
| [71] nop_pop
| [72] exec_stmt_begin
| [93] exec_stmt_end
| [106] return0 5
|
gaussdb=>
主事务和自治事务的存储过程都支持字节码
- 自治事务的双重嵌套
gaussdb=> create or replace procedure p_autom3 is
gaussdb$> x int;
gaussdb$> PRAGMA AUTONOMOUS_TRANSACTION;
gaussdb$> begin
gaussdb$> x:=x+1;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> create or replace procedure p_autom4 is
gaussdb$> x int;
gaussdb$> PRAGMA AUTONOMOUS_TRANSACTION;
gaussdb$> begin
gaussdb$> p_autom3();
gaussdb$> x:=x+1;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> create or replace procedure p_main3 is
gaussdb$> begin
gaussdb$> p_autom4();
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> alter database postgres set client_min_messages = log;
NOTICE: SET "client_min_messages" TO "log" will only take effect after restarting session.
ALTER DATABASE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p_main3();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33012.
LOG: [ByteCode] Function: p_main3(), InterpreterBytecode:
[0] exec_stmt_begin
[21] procedure expression expr: CALL p_autom4()
[58] exec_stmt_end
[71] nop_pop
[72] exec_stmt_begin
[93] exec_stmt_end
[106] return0 5
LOG: Start ByteCode!
LOG: [ByteCode] BC072 Expression: CALL p_autom4() is degenerated.
CONTEXT: PL/pgSQL function p_main3() line 3 at PERFORM
LOG: [ByteCode] BC019 proc 177 isn't pllanguage.
CONTEXT: referenced column: p_autom4
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33011.
CONTEXT: referenced column: p_autom4
LOG: [ByteCode] Function: p_autom4(), InterpreterBytecode:
[0] exec_stmt_begin
[21] procedure expression expr: CALL p_autom3()
[58] exec_stmt_end
[71] nop_pop
[72] exec_stmt_begin
[93] loadn 9
[98] iconst1
[99] function func: int4pl
[112] storen 9
[117] exec_stmt_end
[130] exec_stmt_begin
[151] exec_stmt_end
[164] return0 5
CONTEXT: referenced column: p_autom4
LOG: Start ByteCode!
CONTEXT: referenced column: p_autom4
LOG: [ByteCode] BC072 Expression: CALL p_autom3() is degenerated.
CONTEXT: PL/pgSQL function p_autom4() line 5 at PERFORM
referenced column: p_autom4
LOG: [ByteCode] BC019 proc 177 isn't pllanguage.
CONTEXT: referenced column: p_autom3
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33010.
CONTEXT: referenced column: p_autom3
LOG: [ByteCode] Function: p_autom3(), InterpreterBytecode:
[0] exec_stmt_begin
[21] loadn 9
[26] iconst1
[27] function func: int4pl
[40] storen 9
[45] exec_stmt_end
[58] exec_stmt_begin
[79] exec_stmt_end
[92] return0 5
CONTEXT: referenced column: p_autom3
LOG: Start ByteCode!
CONTEXT: referenced column: p_autom3
-[ RECORD 1 ]
p_main3 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> alter database postgres reset client_min_messages;
NOTICE: SET "client_min_messages" TO "(null)" will only take effect after restarting session.
ALTER DATABASE
gaussdb=> select bytecode from dump_plsql_bytecode('p_autom3'::regproc);
-[ RECORD 1 ]-------------------------
bytecode | [0] exec_stmt_begin
| [21] loadn 9
| [26] iconst1
| [27] function func: int4pl
| [40] storen 9
| [45] exec_stmt_end
| [58] exec_stmt_begin
| [79] exec_stmt_end
| [92] return0 5
|
gaussdb=> select bytecode from dump_plsql_bytecode('p_autom4'::regproc);
-[ RECORD 1 ]----------------------------------------------
bytecode | [0] exec_stmt_begin
| [21] procedure expression expr: CALL p_autom3()
| [58] exec_stmt_end
| [71] nop_pop
| [72] exec_stmt_begin
| [93] loadn 9
| [98] iconst1
| [99] function func: int4pl
| [112] storen 9
| [117] exec_stmt_end
| [130] exec_stmt_begin
| [151] exec_stmt_end
| [164] return0 5
|
gaussdb=> select bytecode from dump_plsql_bytecode('p_main3'::regproc);
-[ RECORD 1 ]----------------------------------------------
bytecode | [0] exec_stmt_begin
| [21] procedure expression expr: CALL p_autom4()
| [58] exec_stmt_end
| [71] nop_pop
| [72] exec_stmt_begin
| [93] exec_stmt_end
| [106] return0 5
|
gaussdb=>
主事务和两个自治事务都支持字节码
- 表达式是自治事务的函数
gaussdb=> create function f6 return int is
gaussdb$> PRAGMA AUTONOMOUS_TRANSACTION;
gaussdb$> begin
gaussdb$> return 1;
gaussdb$> end;
gaussdb$> /
CREATE FUNCTION
gaussdb=> create procedure p6 is
gaussdb$> v int;
gaussdb$> begin
gaussdb$> v:=f6();
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> alter database postgres set client_min_messages = log;
NOTICE: SET "client_min_messages" TO "log" will only take effect after restarting session.
ALTER DATABASE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p6();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33014.
LOG: [ByteCode] Function: p6(), InterpreterBytecode:
[0] exec_stmt_begin
[21] expression expr: SELECT f6()
[58] storen 9
[63] exec_stmt_end
[76] exec_stmt_begin
[97] exec_stmt_end
[110] return0 5
LOG: Start ByteCode!
LOG: [ByteCode] BC072 Expression: SELECT f6() is degenerated.
CONTEXT: PL/pgSQL function p6() line 4 at assignment
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33013.
CONTEXT: referenced column: f6
LOG: [ByteCode] Function: f6(), InterpreterBytecode:
[0] exec_stmt_begin
[21] iconst1
[22] exec_stmt_end
[35] return 5
CONTEXT: referenced column: f6
LOG: Start ByteCode!
CONTEXT: referenced column: f6
-[ RECORD 1 ]
p6 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> alter database postgres reset client_min_messages;
NOTICE: SET "client_min_messages" TO "(null)" will only take effect after restarting session.
ALTER DATABASE
gaussdb=> select bytecode from dump_plsql_bytecode('f6'::regproc);
-[ RECORD 1 ]------------------
bytecode | [0] exec_stmt_begin
| [21] iconst1
| [22] exec_stmt_end
| [35] return 5
|
gaussdb=> select bytecode from dump_plsql_bytecode('p6'::regproc);
-[ RECORD 1 ]--------------------------------
bytecode | [0] exec_stmt_begin
| [21] expression expr: SELECT f6()
| [58] storen 9
| [63] exec_stmt_end
| [76] exec_stmt_begin
| [97] exec_stmt_end
| [110] return0 5
|
gaussdb=>
主事务和自治事务都支持字节码
上面测了5种场景,并没有测出不支持的情况。
- 不支持SUBTYPE类型。
GaussDB里有两个subtype的概念
- PG原生的RANGE类型里指定subtype ,不过这样应该叫不支持range类型
gaussdb=> CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);
CREATE TYPE
gaussdb=> create procedure p5 is
gaussdb$> v float8_range;
gaussdb$> begin
gaussdb$> v:='[1,5]';
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p5();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33027.
LOG: [ByteCode] Function: p5(), InterpreterBytecode:
[0] exec_stmt_begin
[21] const64
[30] outputfunction func: textout
[39] inputfunction func: range_in
[56] storen_copy1 9
[61] exec_stmt_end
[74] exec_stmt_begin
[95] exec_stmt_end
[108] return0 5
LOG: Start ByteCode!
-[ RECORD 1 ]
p5 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p5'::regproc);
-[ RECORD 1 ]--------------------------------
bytecode | [0] exec_stmt_begin
| [21] const64
| [30] outputfunction func: textout
| [39] inputfunction func: range_in
| [56] storen_copy1 9
| [61] exec_stmt_end
| [74] exec_stmt_begin
| [95] exec_stmt_end
| [108] return0 5
|
gaussdb=>
这种实测是支持的
- ORACLE风格package里的subtype
gaussdb=> create package pkg5 is
gaussdb$> subtype varchar8 is varchar2(8);
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=> create package pkg6 is
gaussdb$> procedure p6 ;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=> create package body pkg6 is
gaussdb$> procedure p6 is
gaussdb$> v pkg5.varchar8;
gaussdb$> begin
gaussdb$> v:=1;
gaussdb$> end;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE BODY
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call pkg6.p6();
LOG: [ByteCode] BC036 bytecode does not support to cast subtype.
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33032.
LOG: [ByteCode] Function: p6(), InterpreterBytecode:
[0] const_null
[1] inputfunction func: subtype_in
[18] storen_copy1 9
[23] exec_stmt_begin
[44] exec_stmt_treebased
[57] exec_stmt_end
[70] exec_stmt_begin
[91] exec_stmt_end
[104] return0 5
LOG: Start ByteCode!
-[ RECORD 1 ]
p6 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('pkg6.p6'::regproc);
-[ RECORD 1 ]---------------------------------
bytecode | [0] const_null
| [1] inputfunction func: subtype_in
| [18] storen_copy1 9
| [23] exec_stmt_begin
| [44] exec_stmt_treebased
| [57] exec_stmt_end
| [70] exec_stmt_begin
| [91] exec_stmt_end
| [104] return0 5
|
gaussdb=>
这个实测也是支持的
弄个subtype类型的参数
gaussdb=> create or replace package pkg6 is
gaussdb$> procedure p6 ;
gaussdb$> procedure p7(i pkg5.varchar8);
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=> create or replace package body pkg6 is
gaussdb$> procedure p6 is
gaussdb$> v pkg5.varchar8;
gaussdb$> begin
gaussdb$> v:=1;
gaussdb$> end;
gaussdb$> procedure p7(i pkg5.varchar8) is
gaussdb$> v pkg5.varchar8;
gaussdb$> begin
gaussdb$> v:=i;
gaussdb$> end;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE BODY
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call pkg6.p7(1);
LOG: [ByteCode] BC036 bytecode does not support to cast subtype.
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33033.
LOG: [ByteCode] Function: p7(pkg5.varchar8), InterpreterBytecode:
[0] const_null
[1] inputfunction func: subtype_in
[18] storen_copy1 10
[23] exec_stmt_begin
[44] exec_stmt_treebased
[57] exec_stmt_end
[70] exec_stmt_begin
[91] exec_stmt_end
[104] return0 5
LOG: Start ByteCode!
-[ RECORD 1 ]
p7 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('pkg6.p7'::regproc);
-[ RECORD 1 ]---------------------------------
bytecode | [0] const_null
| [1] inputfunction func: subtype_in
| [18] storen_copy1 10
| [23] exec_stmt_begin
| [44] exec_stmt_treebased
| [57] exec_stmt_end
| [70] exec_stmt_begin
| [91] exec_stmt_end
| [104] return0 5
|
gaussdb=>
也是支持的,这说明文档不对
- 不支持游标循环语句SELECT返回的列数与语句中的游标变量列数不一致。
可能指的是fetch into ,ORACLE里需保证列对应,但GaussDB里支持源列和目标列数不一致
gaussdb=> create or replace procedure p7 is
gaussdb$> v1 int;
gaussdb$> v2 int;
gaussdb$> cursor c is
gaussdb$> select 1 c1,2 c2,3 c3 from dual ;
gaussdb$> begin
gaussdb$> open c;
gaussdb$> fetch c into v1,v2;
gaussdb$> close c;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p7();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33034.
LOG: [ByteCode] Function: p7(), InterpreterBytecode:
[0] exec_stmt_begin
[21] exec_stmt_treebased_open
[34] exec_stmt_end
[47] exec_stmt_begin
[68] exec_stmt_treebased_fetch
[81] exec_stmt_end
[94] exec_stmt_begin
[115] exec_stmt_treebased_close
[128] exec_stmt_end
[141] exec_stmt_begin
[162] exec_stmt_end
[175] return0 5
LOG: Start ByteCode!
-[ RECORD 1 ]
p7 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p7'::regproc);
-[ RECORD 1 ]-------------------------------
bytecode | [0] exec_stmt_begin
| [21] exec_stmt_treebased_open
| [34] exec_stmt_end
| [47] exec_stmt_begin
| [68] exec_stmt_treebased_fetch
| [81] exec_stmt_end
| [94] exec_stmt_begin
| [115] exec_stmt_treebased_close
| [128] exec_stmt_end
| [141] exec_stmt_begin
| [162] exec_stmt_end
| [175] return0 5
|
gaussdb=>
这种情况是支持的
放循环里
gaussdb=> create or replace procedure p8 is
gaussdb$> v1 int;
gaussdb$> v2 int;
gaussdb$> cursor c is
gaussdb$> select 1 c1,2 c2,3 c3 from dual ;
gaussdb$> begin
gaussdb$> open c;
gaussdb$> loop
gaussdb$> if c%notfound then exit;
gaussdb$> end if;
gaussdb$> fetch c into v1,v2;
gaussdb$> raise notice 'v1:%,v2:%',v1,v2;
gaussdb$> end loop;
gaussdb$> close c;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p8();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33038.
LOG: [ByteCode] Function: p8(), InterpreterBytecode:
[0] exec_stmt_begin
[21] exec_stmt_treebased_open
[34] exec_stmt_end
[47] exec_stmt_begin
[68] loopwhile
[73] exec_stmt_begin
[94] loadn_cursor_attributes 11
[103] if_or_when 49
[108] exec_stmt_begin
[129] exec_stmt_end
[142] goto 122
[147] goto 5
[152] exec_stmt_end
[165] exec_stmt_begin
[186] exec_stmt_treebased_fetch
[199] exec_stmt_end
[212] exec_stmt_begin
[233] exec_stmt_treebased
[246] exec_stmt_end
[259] goto -191
[264] exec_stmt_end
[277] exec_stmt_begin
[298] exec_stmt_treebased_close
[311] exec_stmt_end
[324] exec_stmt_begin
[345] exec_stmt_end
[358] return0 5
LOG: Start ByteCode!
NOTICE: v1:1,v2:2
NOTICE: v1:1,v2:2
-[ RECORD 1 ]
p8 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p8'::regproc);
-[ RECORD 1 ]-------------------------------
bytecode | [0] exec_stmt_begin
| [21] exec_stmt_treebased_open
| [34] exec_stmt_end
| [47] exec_stmt_begin
| [68] loopwhile
| [73] exec_stmt_begin
| [94] loadn_cursor_attributes 11
| [103] if_or_when 49
| [108] exec_stmt_begin
| [129] exec_stmt_end
| [142] goto 122
| [147] goto 5
| [152] exec_stmt_end
| [165] exec_stmt_begin
| [186] exec_stmt_treebased_fetch
| [199] exec_stmt_end
| [212] exec_stmt_begin
| [233] exec_stmt_treebased
| [246] exec_stmt_end
| [259] goto -191
| [264] exec_stmt_end
| [277] exec_stmt_begin
| [298] exec_stmt_treebased_close
| [311] exec_stmt_end
| [324] exec_stmt_begin
| [345] exec_stmt_end
| [358] return0 5
|
gaussdb=>
也是支持的,
反过来,让游标列数比目标参数列少
gaussdb=> create or replace procedure p9 is
gaussdb$> v1 int;
gaussdb$> v2 int;
gaussdb$> v3 int;
gaussdb$> v4 int;
gaussdb$> cursor c is
gaussdb$> select 1 c1,2 c2,3 c3 from dual ;
gaussdb$> begin
gaussdb$> open c;
gaussdb$> loop
gaussdb$> if c%notfound then exit;
gaussdb$> end if;
gaussdb$> fetch c into v1,v2,v3,v4;
gaussdb$> raise notice 'v1:%,v2:%,v3:%,v4:%',v1,v2,v3,v4;
gaussdb$> end loop;
gaussdb$> close c;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p9();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33042.
LOG: [ByteCode] Function: p9(), InterpreterBytecode:
[0] exec_stmt_begin
[21] exec_stmt_treebased_open
[34] exec_stmt_end
[47] exec_stmt_begin
[68] loopwhile
[73] exec_stmt_begin
[94] loadn_cursor_attributes 13
[103] if_or_when 49
[108] exec_stmt_begin
[129] exec_stmt_end
[142] goto 122
[147] goto 5
[152] exec_stmt_end
[165] exec_stmt_begin
[186] exec_stmt_treebased_fetch
[199] exec_stmt_end
[212] exec_stmt_begin
[233] exec_stmt_treebased
[246] exec_stmt_end
[259] goto -191
[264] exec_stmt_end
[277] exec_stmt_begin
[298] exec_stmt_treebased_close
[311] exec_stmt_end
[324] exec_stmt_begin
[345] exec_stmt_end
[358] return0 5
LOG: Start ByteCode!
NOTICE: v1:1,v2:2,v3:3,v4:<NULL>
NOTICE: v1:1,v2:2,v3:3,v4:<NULL>
-[ RECORD 1 ]
p9 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p9'::regproc);
-[ RECORD 1 ]-------------------------------
bytecode | [0] exec_stmt_begin
| [21] exec_stmt_treebased_open
| [34] exec_stmt_end
| [47] exec_stmt_begin
| [68] loopwhile
| [73] exec_stmt_begin
| [94] loadn_cursor_attributes 13
| [103] if_or_when 49
| [108] exec_stmt_begin
| [129] exec_stmt_end
| [142] goto 122
| [147] goto 5
| [152] exec_stmt_end
| [165] exec_stmt_begin
| [186] exec_stmt_treebased_fetch
| [199] exec_stmt_end
| [212] exec_stmt_begin
| [233] exec_stmt_treebased
| [246] exec_stmt_end
| [259] goto -191
| [264] exec_stmt_end
| [277] exec_stmt_begin
| [298] exec_stmt_treebased_close
| [311] exec_stmt_end
| [324] exec_stmt_begin
| [345] exec_stmt_end
| [358] return0 5
|
gaussdb=>
也是支持的,
让into 的是一个record变量
gaussdb=> create or replace procedure p99 is
gaussdb$> type t_r is record(v1 int,v2 int);
gaussdb$> r t_r;
gaussdb$> cursor c is
gaussdb$> select 1 c1,2 c2,3 c3 from dual ;
gaussdb$> begin
gaussdb$> open c;
gaussdb$> loop
gaussdb$> if c%notfound then exit;
gaussdb$> end if;
gaussdb$> fetch c into r;
gaussdb$> raise notice 'r:%',r::text;
gaussdb$> end loop;
gaussdb$> close c;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p99();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33046.
LOG: [ByteCode] Function: p99(), InterpreterBytecode:
[0] exec_stmt_begin
[21] exec_stmt_treebased_open
[34] exec_stmt_end
[47] exec_stmt_begin
[68] loopwhile
[73] exec_stmt_begin
[94] loadn_cursor_attributes 13
[103] if_or_when 49
[108] exec_stmt_begin
[129] exec_stmt_end
[142] goto 122
[147] goto 5
[152] exec_stmt_end
[165] exec_stmt_begin
[186] exec_stmt_treebased_fetch
[199] exec_stmt_end
[212] exec_stmt_begin
[233] exec_stmt_treebased
[246] exec_stmt_end
[259] goto -191
[264] exec_stmt_end
[277] exec_stmt_begin
[298] exec_stmt_treebased_close
[311] exec_stmt_end
[324] exec_stmt_begin
[345] exec_stmt_end
[358] return0 5
LOG: Start ByteCode!
ERROR: Assignment and variable field do not match.
CONTEXT: PL/pgSQL function p99() line 11 at FETCH
gaussdb=> reset client_min_messages;
RESET
执行会报错 ERROR: Assignment and variable field do not match.
gaussdb=> create or replace procedure p98 is
gaussdb$> type t_r is record(v1 int,v2 int,v3 int);
gaussdb$> r t_r;
gaussdb$> cursor c is
gaussdb$> select 1 c1,2 c2 from dual ;
gaussdb$> begin
gaussdb$> open c;
gaussdb$> loop
gaussdb$> if c%notfound then exit;
gaussdb$> end if;
gaussdb$> fetch c into r;
gaussdb$> raise notice 'r:%',r::text;
gaussdb$> end loop;
gaussdb$> close c;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p98();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33052.
LOG: [ByteCode] Function: p98(), InterpreterBytecode:
[0] exec_stmt_begin
[21] exec_stmt_treebased_open
[34] exec_stmt_end
[47] exec_stmt_begin
[68] loopwhile
[73] exec_stmt_begin
[94] loadn_cursor_attributes 14
[103] if_or_when 49
[108] exec_stmt_begin
[129] exec_stmt_end
[142] goto 122
[147] goto 5
[152] exec_stmt_end
[165] exec_stmt_begin
[186] exec_stmt_treebased_fetch
[199] exec_stmt_end
[212] exec_stmt_begin
[233] exec_stmt_treebased
[246] exec_stmt_end
[259] goto -191
[264] exec_stmt_end
[277] exec_stmt_begin
[298] exec_stmt_treebased_close
[311] exec_stmt_end
[324] exec_stmt_begin
[345] exec_stmt_end
[358] return0 5
LOG: Start ByteCode!
ERROR: Assignment and variable field do not match.
CONTEXT: PL/pgSQL function p98() line 11 at FETCH
gaussdb=> reset client_min_messages;
RESET
gaussdb=>
这种反过来也会报错,ERROR: Assignment and variable field do not match.
所以没找到对应的不支持场景
- 不支持RECORD变量的读取和赋值列值(如:va record; va.c1 := 1;)。
游标的一行/row函数/复合类型不带参数名的构造,类型都是record,但复合类型带参数名的构造的类型则是复合类型自己。
gaussdb=> select pg_typeof(row(1,1));
-[ RECORD 1 ]-----
pg_typeof | record
gaussdb=> create type ty_test2 as (a int,b int);
CREATE TYPE
gaussdb=> select pg_typeof(ty_test2(1,1));
-[ RECORD 1 ]-----
pg_typeof | record
gaussdb=> select pg_typeof(ty_test2(a=>1,b=>1));
-[ RECORD 1 ]-------
pg_typeof | ty_test2
gaussdb=>
gaussdb=> create procedure p10 is
gaussdb$> begin
gaussdb$> for rec in (select 1 a,2 b from dual)
gaussdb$> loop
gaussdb$> raise notice '%',pg_typeof(rec);
gaussdb$> rec.a:=3;
gaussdb$> end loop;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p10();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33067.
LOG: [ByteCode] Function: p10(), InterpreterBytecode:
[0] exec_stmt_begin
[21] fors_prepare
[46] fors 105
[59] exec_stmt_begin
[80] exec_stmt_treebased
[93] exec_stmt_end
[106] exec_stmt_begin
[127] iconst3
[128] storen 9
[133] exec_stmt_end
[146] goto -100
[151] exec_stmt_end
[164] exec_stmt_begin
[185] exec_stmt_end
[198] return0 5
LOG: Start ByteCode!
NOTICE: record
-[ RECORD 1 ]
p10 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p10'::regproc);
-[ RECORD 1 ]------------------------
bytecode | [0] exec_stmt_begin
| [21] fors_prepare
| [46] fors 105
| [59] exec_stmt_begin
| [80] exec_stmt_treebased
| [93] exec_stmt_end
| [106] exec_stmt_begin
| [127] iconst3
| [128] storen 9
| [133] exec_stmt_end
| [146] goto -100
| [151] exec_stmt_end
| [164] exec_stmt_begin
| [185] exec_stmt_end
| [198] return0 5
|
gaussdb=>
测试下来其实是支持的
gaussdb=> create procedure p11 is
gaussdb$> type t_rec is record(a int,b int);
gaussdb$> v t_rec;
gaussdb$> begin
gaussdb$> v.a:=1;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p11();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33068.
LOG: [ByteCode] Function: p11(), InterpreterBytecode:
[0] exec_stmt_begin
[21] iconst1
[22] storen 10
[27] exec_stmt_end
[40] exec_stmt_begin
[61] exec_stmt_end
[74] return0 5
LOG: Start ByteCode!
-[ RECORD 1 ]
p11 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p11'::regproc);
-[ RECORD 1 ]-------------------
bytecode | [0] exec_stmt_begin
| [21] iconst1
| [22] storen 10
| [27] exec_stmt_end
| [40] exec_stmt_begin
| [61] exec_stmt_end
| [74] return0 5
|
gaussdb=>
这种也支持
至于文档里说的那个例子,本身就是个错的,没有定义record的结构,c1列是哪里来的?
- 不支持PACKAGE中RECORD变量的读取和复制。
同上,没必要单独强调package,这里还有错别字,"复制"应该是"赋值"
gaussdb=> create or replace package pkg11 is
gaussdb$> type t_rec is record(a int,b int);
gaussdb$> procedure p11 ;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=> create or replace package body pkg11 is
gaussdb$> procedure p11 is
gaussdb$> v t_rec;
gaussdb$> begin
gaussdb$> v.a:=1;
gaussdb$> raise notice '%',v.a;
gaussdb$> end;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE BODY
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call pkg11.p11();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33073.
LOG: [ByteCode] Function: p11(), InterpreterBytecode:
[0] exec_stmt_begin
[21] iconst1
[22] storen 11
[27] exec_stmt_end
[40] exec_stmt_begin
[61] exec_stmt_treebased
[74] exec_stmt_end
[87] exec_stmt_begin
[108] exec_stmt_end
[121] return0 5
LOG: Start ByteCode!
NOTICE: 1
-[ RECORD 1 ]
p11 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('pkg11.p11'::regproc);
-[ RECORD 1 ]------------------------
bytecode | [0] exec_stmt_begin
| [21] iconst1
| [22] storen 11
| [27] exec_stmt_end
| [40] exec_stmt_begin
| [61] exec_stmt_treebased
| [74] exec_stmt_end
| [87] exec_stmt_begin
| [108] exec_stmt_end
| [121] return0 5
|
gaussdb=>
也是支持的
- 不支持REFCURSOR类型的出入参转换为其他类型(例如:REFCURSOR转换为VARCHAR2,或进行拼接运算操作等)。
游标类型的参数强转没什么意义 一个 "" 的字符串而已
gaussdb=> create or replace package pkg12 is
gaussdb$> procedure p1(o out sys_refcursor);
gaussdb$> procedure p2;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=> create or replace package body pkg12 is
gaussdb$> procedure p1(o out sys_refcursor) is
gaussdb$> begin
gaussdb$> open o for select 1 a,2 b from dual;
gaussdb$> raise notice '%',o::text;
gaussdb$> end;
gaussdb$> procedure p2 is
gaussdb$> cr sys_refcursor;
gaussdb$> begin
gaussdb$> p1(cr);
gaussdb$> raise notice '%','aaaa'||cr::text;
gaussdb$> end;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE BODY
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call pkg12.p2();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33079.
LOG: [ByteCode] Function: p2(), InterpreterBytecode:
[0] exec_stmt_begin
[21] procedure expression expr: CALL p1(cr)
[58] nop_pop
[59] exec_stmt_end
[72] exec_stmt_begin
[93] exec_stmt_treebased
[106] exec_stmt_end
[119] exec_stmt_begin
[140] exec_stmt_end
[153] return0 5
LOG: Start ByteCode!
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33078.
CONTEXT: PL/pgSQL function p2() line 10 at SQL statement
LOG: [ByteCode] Function: p1(), InterpreterBytecode:
[0] exec_stmt_begin
[21] exec_stmt_treebased_open
[34] exec_stmt_end
[47] exec_stmt_begin
[68] exec_stmt_treebased
[81] exec_stmt_end
[94] exec_stmt_begin
[115] loadn_return_cursor 0
[120] transfer
[125] exec_stmt_end
[138] return 5
CONTEXT: PL/pgSQL function p2() line 10 at SQL statement
LOG: [ByteCode] Function: CALL p1(cr), InterpreterBytecode:
[0] nop_push
[1] invokemethod_definer func: p1
[30] storen_copy_cursor 9
CONTEXT: PL/pgSQL function p2() line 10 at SQL statement
NOTICE: <unnamed portal 9>
CONTEXT: PL/pgSQL function p2() line 10 at SQL statement
NOTICE: aaaa<unnamed portal 9>
-[ RECORD 1 ]
p2 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('pkg12.p2'::regproc);
-[ RECORD 1 ]------------------------------------------
bytecode | [0] exec_stmt_begin
| [21] procedure expression expr: CALL p1(cr)
| [58] nop_pop
| [59] exec_stmt_end
| [72] exec_stmt_begin
| [93] exec_stmt_treebased
| [106] exec_stmt_end
| [119] exec_stmt_begin
| [140] exec_stmt_end
| [153] return0 5
|
gaussdb=> select bytecode from dump_plsql_bytecode('pkg12.p1'::regproc);
-[ RECORD 1 ]-----------------------------
bytecode | [0] exec_stmt_begin
| [21] exec_stmt_treebased_open
| [34] exec_stmt_end
| [47] exec_stmt_begin
| [68] exec_stmt_treebased
| [81] exec_stmt_end
| [94] exec_stmt_begin
| [115] loadn_return_cursor 0
| [120] transfer
| [125] exec_stmt_end
| [138] return 5
|
gaussdb=>
不过这么测下来,竟然是支持的。
- 不支持伪类型(具体请参见伪类型)作为函数或存储过程出入参。
| 名称 | 描述 |
|---|---|
| any | 表示函数接受任何输入数据类型。 |
| anyelement | 表示函数接受任何数据类型。 |
| anyarray | 表示函数接受任意数组数据类型。 |
| anynonarray | 表示函数接受任意非数组数据类型。 |
| anyenum | 表示函数接受任意枚举数据类型。 |
| anyrange | 表示函数接受任意范围数据类型。 |
| cstring | 表示函数接受或者返回一个空结尾的C字符串。 |
| internal | 表示函数接受或者返回一种服务器内部的数据类型。 |
| language_handler | 声明一个过程语言调用句柄返回language_handler。 |
| fdw_handler | 声明一个外部数据封装器返回fdw_handler。 |
| record | 标识函数返回一个未声明的行类型。 |
| trigger | 声明一个触发器函数返回trigger。 |
| void | 表示函数不返回值。 |
| opaque | 一个已经过时的类型,以前用于所有上面这些用途。 |
ORACLE里也没这些东西,直接迁移过来的不会用,但是自己写一些通用工具函数时要注意了。
gaussdb=> create or replace function f12(anyelement) return text as
gaussdb$> begin
gaussdb$> return $1::text;
gaussdb$> end;
gaussdb$> /
CREATE FUNCTION
gaussdb=> set client_min_messages = log;
SET
gaussdb=> select f12(1);
LOG: [ByteCode] BC070 Bytecode does not support parameter with pseudo type.
CONTEXT: referenced column: f12
LOG: [ByteCode] BC039 This function doesn't support bytecode, func_oid: 33080.
CONTEXT: referenced column: f12
-[ RECORD 1 ]
f12 | 1
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('f12'::regproc);
-[ RECORD 1 ]-----------
bytecode | Not supported
gaussdb=>
- 不支持循环游标语句使用跨PACKAGE的CURSOR变量。
gaussdb=> create package pkg13 is
gaussdb$> cursor c is select 1 a,2 b from dual;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=> create package pkg14 is
gaussdb$> procedure p ;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=> create or replace package body pkg14 is
gaussdb$> procedure p is
gaussdb$> r pkg13.c%rowtype;
gaussdb$> begin
gaussdb$> open pkg13.c;
gaussdb$> loop
gaussdb$> if pkg13.c%notfound then exit;
gaussdb$> end if;
gaussdb$> fetch pkg13.c into r;
gaussdb$> raise notice '%',r;
gaussdb$> end loop;
gaussdb$> close pkg13.c;
gaussdb$> end;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE BODY
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call pkg14.p();
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33086.
LOG: [ByteCode] Function: p(), InterpreterBytecode:
[0] exec_stmt_begin
[21] exec_stmt_treebased_open
[34] exec_stmt_end
[47] exec_stmt_begin
[68] loopwhile
[73] exec_stmt_begin
[94] loadn_pkg_cursor_attributes 12
[103] if_or_when 49
[108] exec_stmt_begin
[129] exec_stmt_end
[142] goto 122
[147] goto 5
[152] exec_stmt_end
[165] exec_stmt_begin
[186] exec_stmt_treebased_fetch
[199] exec_stmt_end
[212] exec_stmt_begin
[233] exec_stmt_treebased
[246] exec_stmt_end
[259] goto -191
[264] exec_stmt_end
[277] exec_stmt_begin
[298] exec_stmt_treebased_close
[311] exec_stmt_end
[324] exec_stmt_begin
[345] exec_stmt_end
[358] return0 5
LOG: Start ByteCode!
NOTICE: (1,2)
NOTICE: (1,2)
-[ RECORD 1 ]
p |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('pkg14.p'::regproc);
-[ RECORD 1 ]----------------------------------
bytecode | [0] exec_stmt_begin
| [21] exec_stmt_treebased_open
| [34] exec_stmt_end
| [47] exec_stmt_begin
| [68] loopwhile
| [73] exec_stmt_begin
| [94] loadn_pkg_cursor_attributes 12
| [103] if_or_when 49
| [108] exec_stmt_begin
| [129] exec_stmt_end
| [142] goto 122
| [147] goto 5
| [152] exec_stmt_end
| [165] exec_stmt_begin
| [186] exec_stmt_treebased_fetch
| [199] exec_stmt_end
| [212] exec_stmt_begin
| [233] exec_stmt_treebased
| [246] exec_stmt_end
| [259] goto -191
| [264] exec_stmt_end
| [277] exec_stmt_begin
| [298] exec_stmt_treebased_close
| [311] exec_stmt_end
| [324] exec_stmt_begin
| [345] exec_stmt_end
| [358] return0 5
|
gaussdb=>
实测其实是支持的
- 不支持包含对入参进行赋值的存储过程或函数。
在ORACLE里,入参本身就不允许赋值,GaussDB没做强控制
gaussdb=> create procedure p15( a int) is
gaussdb$> begin
gaussdb$> a:=1;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p15(1);
LOG: [ByteCode] BC066 in-param can't be changed.
LOG: [ByteCode] BC039 This function doesn't support bytecode, func_oid: 33087.
-[ RECORD 1 ]
p15 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p15'::regproc);
-[ RECORD 1 ]-----------
bytecode | Not supported
这种不合规用法的确会导致该函数整个无法使用字节码
- 不支持BULK COLLECT语句。
gaussdb=> CREATE TABLE customers(id int,name varchar);
CREATE TABLE
gaussdb=> INSERT INTO customers VALUES(1,'ab');
INSERT 0 1
gaussdb=> create procedure p16 is
gaussdb$> type id_list is varray(6) of customers.id%type;
gaussdb$> id_arr id_list;
gaussdb$> begin
gaussdb$> select id bulk collect into id_arr from customers;
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p16();
LOG: [Bytecode] BC077 bulk collect does not support.
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33093.
LOG: [ByteCode] Function: p16(), InterpreterBytecode:
[0] exec_stmt_begin
[21] exec_stmt_treebased
[34] exec_stmt_end
[47] exec_stmt_begin
[68] exec_stmt_end
[81] return0 5
LOG: Start ByteCode!
-[ RECORD 1 ]
p16 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p16'::regproc);
-[ RECORD 1 ]------------------------
bytecode | [0] exec_stmt_begin
| [21] exec_stmt_treebased
| [34] exec_stmt_end
| [47] exec_stmt_begin
| [68] exec_stmt_end
| [81] return0 5
|
gaussdb=>
的确不支持,但是没有导致这个存储过程不支持字节码,这是个好消息
- 不支持FORALL批量查询语句带有SAVE EXCEPTIONS。
gaussdb=> CREATE TABLE hdfs_t1 (
gaussdb(> title NUMBER(6),
gaussdb(> did VARCHAR2(20),
gaussdb(> data_period VARCHAR2(25),
gaussdb(> kind VARCHAR2(25),
gaussdb(> interval VARCHAR2(20),
gaussdb(> time DATE,
gaussdb(> isModified VARCHAR2(10)
gaussdb(> );
CREATE TABLE
gaussdb=> INSERT INTO hdfs_t1 VALUES( 8, 'Donald', 'OConnell', 'DOCONNEL', '650.507.9833', to_date('21-06-1999', 'dd-mm-yyyy'), 'SH_CLERK' );
INSERT 0 1
gaussdb=> CREATE OR REPLACE PROCEDURE proc_forall()
gaussdb-> AS
gaussdb$> BEGIN
gaussdb$> FORALL i IN 100..120 save exceptions
gaussdb$> update hdfs_t1 set title = title + 100*i;
gaussdb$> END;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> CALL proc_forall();
LOG: [ByteCode] BC027 Stmtfori is not support save_exceptions, plsql: FORALL i IN 100..120 save exceptions.
LOG: [ByteCode] BC030 Stmt FOR with integer loop variable does not support with some error, lineno: 3.
LOG: [ByteCode] BC039 This function doesn't support bytecode, func_oid: 33098.
-[ RECORD 1 ]-
proc_forall |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('proc_forall'::regproc);
-[ RECORD 1 ]-----------
bytecode | Not supported
gaussdb=>
的确不支持,不过这个用得少
- 不支持函数或存储过程的参数默认值为PACKAGE变量。
gaussdb=> create or replace package test_pkg is
gaussdb$> xx int:=10000;
gaussdb$> PROCEDURE bc_loop2(i int default xx);
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=> create or replace package body test_pkg is
gaussdb$> PROCEDURE bc_loop2(i int default xx) is
gaussdb$> L_COUNT NUMBER:=0;
gaussdb$> BEGIN
gaussdb$> LOOP
gaussdb$> IF L_COUNT > i THEN
gaussdb$> RAISE INFO 'count is %',L_COUNT;
gaussdb$> EXIT;
gaussdb$> END IF;
gaussdb$> L_COUNT:=L_COUNT+1;
gaussdb$> END LOOP;
gaussdb$> END;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE BODY
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call test_pkg.bc_loop2(20);
LOG: [ByteCode] BC007 bytecode doesn't support parameters with package default value.
LOG: [ByteCode] BC019 proc 7752 isn't pllanguage.
LOG: [ByteCode] BC019 proc 1724 isn't pllanguage.
LOG: [ByteCode] BC039 This function doesn't support bytecode, func_oid: 33100.
INFO: count is 21
-[ RECORD 1 ]
bc_loop2 |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('test_pkg.bc_loop2'::regproc);
-[ RECORD 1 ]-----------
bytecode | Not supported
gaussdb=>
这种用得还挺多,只要用了就整个存储过程不支持了。
- 不支持存储过程或函数OUT出参具有多个列或带有数组下标的复杂变量(如:type arrayInt is varray(16) of int; val arrayInt; val(1) = 1;)。
可能是指out出参不能为复合类型或者数组类型?
gaussdb=> create type ty_test3 as (a int,b int);
CREATE TYPE
gaussdb=> create type tyt_test3 is table of ty_test3;
CREATE TYPE
gaussdb=> create type tyt_test4 is table of ty_test3 index by binary_integer ;
ERROR: Creation outside PL/SQL is not supported.
gaussdb=> create type tyt_test5 is varray(16) of int;
ERROR: syntax error at or near "varray"
LINE 1: create type tyt_test5 is varray(16) of int;
^
gaussdb=>
后两种类型不能单独创建
gaussdb=> create or replace procedure p17( o out ty_test3) is
gaussdb$> begin
gaussdb$> o:=ty_test3();
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p17(null);
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33118.
LOG: [ByteCode] Function: p17(), InterpreterBytecode:
[0] exec_stmt_begin
[21] eval_rowexpr
[30] store_row
[47] storen 0
[52] storen 1
[57] exec_stmt_end
[70] exec_stmt_begin
[91] loadn 0
[96] loadn 1
[101] eval_rowexpr
[110] transfer
[115] exec_stmt_end
[128] return 5
LOG: Start ByteCode!
-[ RECORD 1 ]
a |
b |
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p17'::regproc);
-[ RECORD 1 ]-------------------
bytecode | [0] exec_stmt_begin
| [21] eval_rowexpr
| [30] store_row
| [47] storen 0
| [52] storen 1
| [57] exec_stmt_end
| [70] exec_stmt_begin
| [91] loadn 0
| [96] loadn 1
| [101] eval_rowexpr
| [110] transfer
| [115] exec_stmt_end
| [128] return 5
|
gaussdb=>
这个是支持的
gaussdb=> create or replace procedure p18( o out tyt_test3,o2 out ty_test3) is
gaussdb$> begin
gaussdb$> o:=tyt_test3();
gaussdb$> o.extend;
gaussdb$> o(1):=ty_test3(1,2);
gaussdb$> o2:=o(1);
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p18(null,null);
LOG: [ByteCode] BC019 proc 6149 isn't pllanguage.
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33119.
LOG: [ByteCode] Function: p18(), InterpreterBytecode:
[0] exec_stmt_begin
[21] create_nesttable tyt_test3 0
[30] storen_nesttable 0
[43] exec_stmt_end
[56] exec_stmt_begin
[77] loadn_expand 0
[82] iconst1
[83] function func: nesttable_extend
[96] storen_nesttable 0
[109] exec_stmt_end
[122] exec_stmt_begin
[143] iconst1
[144] iconst2
[145] eval_rowexpr
[154] expand_and_load_table 0
[159] iconst1
[160] store_nesttable_elem 2249 -1
[169] exec_stmt_end
[182] exec_stmt_begin
[203] loadn_expand 0
[208] iconst1
[209] tableofelem 33117
[214] store_row
[231] storen 1
[236] storen 2
[241] exec_stmt_end
[254] exec_stmt_begin
[275] loadn_expand 0
[280] loadn 1
[285] loadn 2
[290] eval_rowexpr
[299] eval_rowexpr
[308] transfer
[313] exec_stmt_end
[326] return 5
LOG: Start ByteCode!
-[ RECORD 1 ]-
o | {"(1,2)"}
o2 | (1,2)
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p18'::regproc);
-[ RECORD 1 ]-----------------------------------
bytecode | [0] exec_stmt_begin
| [21] create_nesttable tyt_test3 0
| [30] storen_nesttable 0
| [43] exec_stmt_end
| [56] exec_stmt_begin
| [77] loadn_expand 0
| [82] iconst1
| [83] function func: nesttable_extend
| [96] storen_nesttable 0
| [109] exec_stmt_end
| [122] exec_stmt_begin
| [143] iconst1
| [144] iconst2
| [145] eval_rowexpr
| [154] expand_and_load_table 0
| [159] iconst1
| [160] store_nesttable_elem 2249 -1
| [169] exec_stmt_end
| [182] exec_stmt_begin
| [203] loadn_expand 0
| [208] iconst1
| [209] tableofelem 33117
| [214] store_row
| [231] storen 1
| [236] storen 2
| [241] exec_stmt_end
| [254] exec_stmt_begin
| [275] loadn_expand 0
| [280] loadn 1
| [285] loadn 2
| [290] eval_rowexpr
| [299] eval_rowexpr
| [308] transfer
| [313] exec_stmt_end
| [326] return 5
|
gaussdb=>
也是支持的
gaussdb=> create package pkg19 is
gaussdb$> type tyt_test4 is table of ty_test3 index by binary_integer ;
gaussdb$> type tyt_test5 is varray(16) of int;
gaussdb$> procedure p(o1 out tyt_test4 ,o2 out tyt_test5);
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE
gaussdb=> create or replace package body pkg19 is
gaussdb$> procedure p(o1 out tyt_test4 ,o2 out tyt_test5) is
gaussdb$> i int:=1;
gaussdb$> begin
gaussdb$> o1(i):=ty_test3(1,2);
gaussdb$> o2:=tyt_test5();
gaussdb$> o2.extend;
gaussdb$> o2(i):=1;
gaussdb$> end;
gaussdb$> end;
gaussdb$> /
CREATE PACKAGE BODY
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call pkg19.p(null,null);
LOG: [ByteCode] BC019 proc 6014 isn't pllanguage.
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33134.
LOG: [ByteCode] Function: p(), InterpreterBytecode:
[0] create_tableofindex pkg19.tyt_test4 integer 0
[13] storen_tableofindex 2
[26] iconst1
[27] storen 14
[32] exec_stmt_begin
[53] iconst1
[54] iconst2
[55] eval_rowexpr
[64] expand_and_load_table 2
[69] loadn 14
[74] store_tableofindex_elem 2249 -1
[83] exec_stmt_end
[96] exec_stmt_begin
[117] const64
[126] storen_array 3 integer[] -1
[139] exec_stmt_end
[152] exec_stmt_begin
[173] loadn_expand 3
[178] iconst1
[179] function func: array_extendnull
[192] storen_array 3 integer[] -1
[205] exec_stmt_end
[218] exec_stmt_begin
[239] iconst1
[240] op_check_and_load_array integer[] -1 3
[253] loadn 14
[258] store_array_elem integer -1 1
[271] exec_stmt_end
[284] exec_stmt_begin
[305] loadn_expand 2
[310] loadn_expand 3
[315] eval_rowexpr
[324] transfer
[329] exec_stmt_end
[342] return 5
LOG: Start ByteCode!
-[ RECORD 1 ]--------------------
o1 | {indexbyType:int,1=>"(1,2)"}
o2 | {1}
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('pkg19.p'::regproc);
-[ RECORD 1 ]------------------------------------------------
bytecode | [0] create_tableofindex pkg19.tyt_test4 integer 0
| [13] storen_tableofindex 2
| [26] iconst1
| [27] storen 14
| [32] exec_stmt_begin
| [53] iconst1
| [54] iconst2
| [55] eval_rowexpr
| [64] expand_and_load_table 2
| [69] loadn 14
| [74] store_tableofindex_elem 2249 -1
| [83] exec_stmt_end
| [96] exec_stmt_begin
| [117] const64
| [126] storen_array 3 integer[] -1
| [139] exec_stmt_end
| [152] exec_stmt_begin
| [173] loadn_expand 3
| [178] iconst1
| [179] function func: array_extendnull
| [192] storen_array 3 integer[] -1
| [205] exec_stmt_end
| [218] exec_stmt_begin
| [239] iconst1
| [240] op_check_and_load_array integer[] -1 3
| [253] loadn 14
| [258] store_array_elem integer -1 1
| [271] exec_stmt_end
| [284] exec_stmt_begin
| [305] loadn_expand 2
| [310] loadn_expand 3
| [315] eval_rowexpr
| [324] transfer
| [329] exec_stmt_end
| [342] return 5
|
gaussdb=>
也是支持的,没测出不支持的场景
- 对于存储过程或函数INOUT参数,仅不包含运算的单一参数类型变量支持字节码框架。
可能是指inout参数不能被赋值
gaussdb=> create procedure p20(io1 inout int,io2 inout varchar2) is
gaussdb$> begin
gaussdb$> io1:=1;
gaussdb$> io1:=io1+1;
gaussdb$> io2:='a';
gaussdb$> io2:=io2||'a';
gaussdb$> end;
gaussdb$> /
CREATE PROCEDURE
gaussdb=> set client_min_messages = log;
SET
gaussdb=> call p20(null,null);
LOG: [ByteCode] BC019 proc 177 isn't pllanguage.
LOG: [ByteCode] BC019 proc 1258 isn't pllanguage.
LOG: [ByteCode] BC040 This function supports bytecode, func_oid: 33135.
LOG: [ByteCode] Function: p20(integer,character varying), InterpreterBytecode:
[0] exec_stmt_begin
[21] iconst1
[22] storen 0
[27] exec_stmt_end
[40] exec_stmt_begin
[61] loadn 0
[66] iconst1
[67] function func: int4pl
[80] storen 0
[85] exec_stmt_end
[98] exec_stmt_begin
[119] const64
[128] storen_outparam 1043 1
[137] exec_stmt_end
[150] exec_stmt_begin
[171] loadn 1
[176] const64
[185] function func: textcat
[198] storen_outparam 1043 1
[207] exec_stmt_end
[220] exec_stmt_begin
[241] loadn 0
[246] loadn 1
[251] eval_rowexpr
[260] transfer
[265] exec_stmt_end
[278] return 5
LOG: Start ByteCode!
-[ RECORD 1 ]
io1 | 2
io2 | aa
gaussdb=> reset client_min_messages;
RESET
gaussdb=> select bytecode from dump_plsql_bytecode('p20'::regproc);
-[ RECORD 1 ]---------------------------
bytecode | [0] exec_stmt_begin
| [21] iconst1
| [22] storen 0
| [27] exec_stmt_end
| [40] exec_stmt_begin
| [61] loadn 0
| [66] iconst1
| [67] function func: int4pl
| [80] storen 0
| [85] exec_stmt_end
| [98] exec_stmt_begin
| [119] const64
| [128] storen_outparam 1043 1
| [137] exec_stmt_end
| [150] exec_stmt_begin
| [171] loadn 1
| [176] const64
| [185] function func: textcat
| [198] storen_outparam 1043 1
| [207] exec_stmt_end
| [220] exec_stmt_begin
| [241] loadn 0
| [246] loadn 1
| [251] eval_rowexpr
| [260] transfer
| [265] exec_stmt_end
| [278] return 5
|
gaussdb=>
也支持
非常规分析
官方文档描述有限,估计有些不支持的场景都没试出来。
观察字节码模块的日志,可以得出一个规律,字节码的日志都带了[ByteCode],所以可以尝试在二进制里搜索所有有关的日志。
strings gaussdb |grep "\[ByteCode\]"
[ByteCode] Function: %s, InterpreterBytecode:
[ByteCode] BC017 can't find valid proc %u.
[ByteCode] BC018 can't find valid languageTuple.
[ByteCode] BC019 proc %u isn't pllanguage.
[ByteCode] BC070 Bytecode does not support parameter with pseudo type.
[ByteCode] BC013 The bytecode does not allow parameters except in & out.
[ByteCode] BC073 Bytecode is invalid, because the expr in Function: %s (func oid: %u) is changed to complex expr.Expr: %s
[ByteCode] BC071 Bytecode is invalid, because the type of expr in Function: %s (func oid: %u) is changed.
[ByteCode] BC076 occurs error: %s during bytecode processExpr
[ByteCode] BC072 Expression: %s is degenerated.
[ByteCode] BC065 assign outparam Failed
[ByteCode] outparam only supports var type & row type.
[ByteCode] BC079 func %u doesn't support bytecode because of permission error.
[ByteCode] BC064 Statements that ignore output parameters contain output parameters
[ByteCode] BC020 This expr type %d does not support.
[ByteCode] BC022 Param kind is PARAM_EXTERN.
[ByteCode] BC055 function(%u) with outparam called in simple expr does not support.
[ByteCode] BC023 FieldSelect input expression is null or fieldnum less 1.
[ByteCode] BC025 MinMaxExpr op is invalid.
[ByteCode] BC045 This xml type is not support, xml type: %d.
[ByteCode] BC024 CompositeExpr node has incorrect type.
[ByteCode] BC032 bytecode row type param includes column except var & row.
[ByteCode] BC036 bytecode does not support to cast subtype.
[ByteCode] BC037 bytecode does not support to cast tableof type.
[ByteCode] BC038 Typecast hashentry is NULL, valtype: %u, valtypmod: %d, reqtype: %u, reqtypmod: %d.
[ByteCode] BC052 bytecode only support independent statement.
[ByteCode] BC053 bytecode only support select statement.
[ByteCode] BC054 Simple expr check occurs exeception. Failed to eval simple expr.
[ByteCode] BC062 bytecode doesn't support query returning more row fields than the row variable has in loop stmt.
[ByteCode] BC066 in-param can't be changed.
[ByteCode] BC074 This function can not supports bytecode, func_oid: %u.Please check the GUC parameter behavior_compat_flags.
[ByteCode] BC002 bytecode doesn't support during package instantiation.
[ByteCode] BC067 bytecode doesn't support system functions.
[ByteCode] BC001 only support bytecode in A_FORMAT.
[ByteCode] BC003 bytecode doesn't support trigger func.
[ByteCode] BC004 bytecode doesn't support func which returns set.
[ByteCode] BC056 bytecode doesn't support function with outparam when proc_outparam_override is off.
[ByteCode] BC057 bytecode doesn't support function with outparam return record.
[ByteCode] BC007 bytecode doesn't support parameters with package default value.
[ByteCode] BC008 exists invalid parameter type %d.
[ByteCode] BC039 This function doesn't support bytecode, func_oid: %u.
[ByteCode] BC068 bytecode neither support nest sub procedure/function nor subtype.
[ByteCode] BC016 occurs exception during bytecode processStatement
[ByteCode] BC031 proc exists in unsupported namespace, it's in %s.
[ByteCode] BC040 This function supports bytecode, func_oid: %u.
[ByteCode] BC048 Bytecode does not support invalid typeoid. typeoid is %u
[ByteCode] exit or continue stmt label not match.
[ByteCode] BC044 Node type is not A_Indices, node type: %d.
[ByteCode] BC042 Node type is A_Indices.
[ByteCode] BC043 Attname %s's num is invalid.
[ByteCode] BC078 stack size is unexpected.
[ByteCode] BC041 Node type is not A_Indices, node type: %d.
[ByteCode] BC046 Neither GSPLSQL_COLLECTION_ARAY nor GSPLSQL_COLLECTION_TABLE are not supported.
[ByteCode] BC047 This datumtype %d is not support in assigntarget.
[ByteCode] BC049 unknown assign target.
[ByteCode] BC033 non-scalar variables are not supported in get_diag statement.
[ByteCode] BC034 This diagnostic type %d does not support.
[ByteCode] BC075 Assignment and variable field do not match in execsql statement, sql is :%s
[ByteCode] BC061 not spport func with out param used in execsql statement, sql is :%s
[ByteCode] BC058 bytecode does not support funtion with out paramter don't have return value.
[ByteCode] BC059 bytecode does not support return var is not out param var.
[ByteCode] BC060 bytecode does not support procedure return a value.
[ByteCode] BC028 bytecode doesn't support tuple return.
[ByteCode] BC029 This stmt type %s does not support, lineno: %d.
[ByteCode] BC030 Stmt %s does not support with some error, lineno: %d.
[ByteCode] BC063 bytecode doesn't support diff pkg cursor in loop stmt.
[ByteCode] BC027 Stmtfori is not support save_exceptions, plsql: %s.
不过这里面并非所有的日志都是不支持的,有些正常输出的日志也在里面,而且无法区分像BC019那种局部不支持但存储过程整体支持的有哪些,甚至还有一些重复的,比如BC044和BC041,都是Node type is not A_Indices, node type: %d. (A_Indices是数组的下标访问,是或不是会怎样?)。
另外,还有一部分不支持字节码的情况,在非字节码运行时也是不支持的,创建就报错了,正确的代码不会遇到。
但仅从二进制里捞出来的这些不支持日志的场景数量上来说,明显是比官方文档里的要多的,有些日志我也没测出对应的场景,所以不能仅从官方文档上去看,还是得使用实际的存储过程代码去测试,才能准确知道字节码的支持情况。
略微有点力竭,官方文档不完善,而且没有源码,面对字节码这样一个新功能,或者说新的执行框架,个人盲测无法穷尽所有场景。我暂时先把本次测试汇总成一个表格吧,究竟这个功能能不能在生产环境上使用,建议以华为官方口径为准。
| 日志 | 是否约束 | 对应文档 | 是否有命中日志 | 自测是否支持字节码 | 备注 |
|---|---|---|---|---|---|
| BC001 only support bytecode in A_FORMAT. | Y | 只有ORACLE兼容模式支持 | |||
| BC002 bytecode doesn't support during package instantiation. | Y | 不支持PACKAGE实例化。 | |||
| BC003 bytecode doesn't support trigger func. | Y | 不支持TRIGGER | Y | N | |
| BC004 bytecode doesn't support func which returns set. | Y | 不支持返回集合的函数 | Y | N | |
| BC007 bytecode doesn't support parameters with package default value. | Y | 不支持函数或存储过程的参数默认值为PACKAGE变量 | Y | N | |
| BC008 exists invalid parameter type %d. | Y | 存在无效的参数类型 | |||
| BC013 The bytecode does not allow parameters except in & out. | Y | Y | N | 不允许in和out之外的参数,RETURNS TABLE时会报 | |
| BC016 occurs exception during bytecode processStatement | Y | 处理语句时遇到错误 | |||
| BC017 can't find valid proc %u. | Y | 不能发现有效的proc | |||
| BC018 can't find valid languageTuple. | Y | 不能发现有效的语言元组 | |||
| BC019 proc %u isn't pllanguage. | Y | Y | proc不是pl语言 | ||
| BC020 This expr type %d does not support. | Y | 这种表达式类型不支持 | |||
| BC022 Param kind is PARAM_EXTERN. | 参数类型是PARAM_EXTERN | ||||
| BC023 FieldSelect input expression is null or fieldnum less 1. | Y | FieldSelect输入表达式是空或者fieldnum小于1 | |||
| BC024 CompositeExpr node has incorrect type. | Y | 复合类型表达式节点有不正确的类型 | |||
| BC025 MinMaxExpr op is invalid. | Y | MinMaxExpr操作无效 | |||
| BC027 Stmtfori is not support save_exceptions, plsql: %s. | Y | 不支持FORALL批量查询语句带有SAVE EXCEPTIONS | Y | N | |
| BC028 bytecode doesn't support tuple return. | Y | 不支持返回行 | |||
| BC029 This stmt type %s does not support, lineno: %d. | Y | 特定的语句类型不支持 | |||
| BC030 Stmt %s does not support with some error, lineno: %d. | Y | Y | N | 由于一些错误,语句XXX不支持 | |
| BC031 proc exists in unsupported namespace, it's in %s. | Y | 不支持高级包以及系统函数。 | |||
| BC032 bytecode row type param includes column except var & row. | Y | 行类型参数含有不是var和row的列 | |||
| BC033 non-scalar variables are not supported in get_diag statement. | Y | 非标量变量不支持在get_diag语句里 | |||
| BC034 This diagnostic type %d does not support. | Y | 这个诊断类型不支持 | |||
| BC036 bytecode does not support to cast subtype. | Y | 不支持转换subtype | |||
| BC037 bytecode does not support to cast tableof type. | Y | 不支持转换tableof类型 | |||
| BC038 Typecast hashentry is NULL, valtype: %u, valtypmod: %d, reqtype: %u, reqtypmod: %d. | Y | 类型转换hashentry是null | |||
| BC039 This function doesn't support bytecode, func_oid: %u. | Y | N | 首次执行,该函数不支持字节码时会输出此日志 | ||
| BC040 This function supports bytecode, func_oid: %u. | 首次执行,该函数支持字节码时会输出此日志 | ||||
| BC041 Node type is not A_Indices, node type: %d. | ? | 不是数组下标节点 | |||
| BC042 Node type is A_Indices. | ? | 是数组下标节点 | |||
| BC043 Attname %s's num is invalid. | ? | 列名的列号是无效的 | |||
| BC044 Node type is not A_Indices, node type: %d. | ? | 不是数组下标节点 | |||
| BC045 This xml type is not support, xml type: %d. | Y | 这种xml类型不支持 | |||
| BC046 Neither GSPLSQL_COLLECTION_ARAY nor GSPLSQL_COLLECTION_TABLE are not supported. | Y | 集合数组和集合表都不支持 | |||
| BC047 This datumtype %d is not support in assigntarget. | Y | 这个datumtype不支持用于赋值目标 | |||
| BC048 Bytecode does not support invalid typeoid. typeoid is %u | Y | 不支持无效的类型oid | |||
| BC049 unknown assign target. | ? | 未知的赋值目标 | |||
| BC052 bytecode only support independent statement. | Y | 只支持独立语句 | |||
| BC053 bytecode only support select statement. | Y | 只支持select语句 | |||
| BC054 Simple expr check occurs exeception. Failed to eval simple expr. | Y | 简单表达式遇到错误,计算简单表达式失败 | |||
| BC055 function(%u) with outparam called in simple expr does not support. | Y | 被简单表达式调用的带出参的函数不支持 | |||
| BC056 bytecode doesn't support function with outparam when proc_outparam_override is off. | Y | 该特性仅在兼容性参数behavior_compat_options设置中包含compat_cursor、allow_procedure_compile_check、proc_outparam_override、dynamic_sql_compat、proc_outparam_transfer_length以及varray_compat参数选项时,支持执行字节码 | O兼容一般都会打开proc_outparam_override | ||
| BC057 bytecode doesn't support function with outparam return record. | Y | 不支持RETURN复合类型的带有出参的FUNCTION | Y | N | |
| BC058 bytecode does not support funtion with out paramter don't have return value. | Y | 函数没有返回值 | |||
| BC059 bytecode does not support return var is not out param var. | Y | 函数不支持返回值不是出参 | |||
| BC060 bytecode does not support procedure return a value. | Y | 不支持PROCEDURE显式指定RETURN值 | |||
| BC061 not spport func with out param used in execsql statement, sql is :%s | ? | 执行SQL里不支持使用带出参的函数 | |||
| BC062 bytecode doesn't support query returning more row fields than the row variable has in loop stmt. | Y | 不支持游标循环语句SELECT返回的列数与语句中的游标变量列数不一致。 | Y | ||
| BC063 bytecode doesn't support diff pkg cursor in loop stmt. | Y | 不支持循环游标语句使用跨PACKAGE的CURSOR变量 | Y | ||
| BC064 Statements that ignore output parameters contain output parameters | Y | 忽略了出参的语句包含有出参 | |||
| BC065 assign outparam Failed | Y | 赋值出参失败 | |||
| BC066 in-param can't be changed. | Y | 不支持包含对入参进行赋值的存储过程或函数 | Y | N | |
| BC067 bytecode doesn't support system functions. | Y | 不支持高级包以及系统函数 | |||
| BC068 bytecode neither support nest sub procedure/function nor subtype. | Y | 不支持子程序。 | Y | N | |
| BC070 Bytecode does not support parameter with pseudo type. | Y | 不支持伪类型(具体请参见伪类型)作为函数或存储过程出入参。 | Y | N | |
| BC071 Bytecode is invalid, because the type of expr in Function: %s (func oid: %u) is changed. | Y | 函数中表达式的类型被改成 | |||
| BC072 Expression: %s is degenerated. | ? | Y | 表达式被退化 (自治事务会出现) | ||
| BC073 Bytecode is invalid, because the expr in Function: %s (func oid: %u) is changed to complex expr.Expr: %s | Y | 函数中的表达式被改变成复杂表达式 | |||
| BC074 This function can not supports bytecode, func_oid: %u.Please check the GUC parameter behavior_compat_flags. | Y | 该特性仅在兼容性参数behavior_compat_options设置中包含compat_cursor、allow_procedure_compile_check、proc_outparam_override、dynamic_sql_compat、proc_outparam_transfer_length以及varray_compat参数选项时,支持执行字节码 | O兼容这些一般都要打开 | ||
| BC075 Assignment and variable field do not match in execsql statement, sql is :%s | ? | 执行SQL的赋值和变量个数不匹配 | |||
| BC076 occurs error: %s during bytecode processExpr | Y | 处理表达式遇到错误 | |||
| BC078 stack size is unexpected. | ? | 栈大小非预期 | |||
| BC079 func %u doesn't support bytecode because of permission error. | Y | 权限错误 | |||
| exit or continue stmt label not match. | Y | exit 或 continue 后面的语句标签在前面找不到 | |||
| Function: %s, InterpreterBytecode: | Y | Y | 在这一行日志下开始输出字节码序列 | ||
| outparam only supports var type & row type. | Y | 出参只支持var类型和row类型 |
关于这个字节码特性,我写了两篇了,后续我打算把这两篇内容喂给AI,让AI继续写第三篇。
未完待续~

