Merge branch 'master' of gitee.com:opengauss/openGauss-server into helper

This commit is contained in:
仲夏十三
2022-05-20 07:40:19 +00:00
committed by Gitee
10 changed files with 365 additions and 31 deletions

View File

@ -70,6 +70,7 @@
THR_LOCAL bool skip_read_extern_fields = false;
#define IS_DATANODE_BUT_NOT_SINGLENODE (IS_PGXC_DATANODE && !IS_SINGLE_NODE)
/*
* Macros to simplify reading of different kinds of fields. Use these
* wherever possible to reduce the chance for silly typos. Note that these
@ -401,24 +402,27 @@ THR_LOCAL bool skip_read_extern_fields = false;
token = pg_strtok(&length); /* skip :fldname */ \
local_node->fldname = _readBitmapset()
#define READ_TYPEINFO_FIELD(fldname) \
do { \
if (local_node->fldname >= FirstBootstrapObjectId) { \
IF_EXIST(exprtypename) \
{ \
char* exprtypename = NULL; \
char* exprtypenamespace = NULL; \
token = pg_strtok(&length); \
token = pg_strtok(&length); \
exprtypename = nullable_string(token, length); \
token = pg_strtok(&length); \
token = pg_strtok(&length); \
exprtypenamespace = nullable_string(token, length); \
local_node->fldname = get_typeoid(get_namespace_oid(exprtypenamespace, false), exprtypename); \
pfree_ext(exprtypename); \
pfree_ext(exprtypenamespace); \
} \
} \
#define READ_TYPEINFO_FIELD(fldname) \
do { \
if (local_node->fldname >= FirstBootstrapObjectId) { \
IF_EXIST(exprtypename) \
{ \
char* exprtypename = NULL; \
char* exprtypenamespace = NULL; \
token = pg_strtok(&length); \
token = pg_strtok(&length); \
exprtypename = nullable_string(token, length); \
token = pg_strtok(&length); \
token = pg_strtok(&length); \
exprtypenamespace = nullable_string(token, length); \
/* No need to reset field on CN or singlenode, keep pg_strtok() for forward compatibility */ \
if (IS_DATANODE_BUT_NOT_SINGLENODE) { \
local_node->fldname = get_typeoid(get_namespace_oid(exprtypenamespace, false), exprtypename); \
} \
pfree_ext(exprtypename); \
pfree_ext(exprtypenamespace); \
} \
} \
} while (0)
#define READ_TYPEINFO(typePtr) \
@ -493,9 +497,30 @@ THR_LOCAL bool skip_read_extern_fields = false;
token = pg_strtok(&length); \
token = pg_strtok(&length); \
funcnamespace = nullable_string(token, length); \
if (IS_PGXC_DATANODE && !skip_read_extern_fields) { \
local_node->fldname = \
get_func_oid(funcname, get_namespace_oid(funcnamespace, false), (Expr*)local_node); \
bool notfound = false; \
if (IS_DATANODE_BUT_NOT_SINGLENODE && !skip_read_extern_fields) { \
Oid funcoid = InvalidOid; \
do { \
Oid nspid = get_namespace_oid(funcnamespace, true); \
if (!OidIsValid(nspid)) { \
notfound = true; \
break; \
} \
funcoid = get_func_oid(funcname, nspid, (Expr*)local_node); \
} while (0); \
if (notfound || !OidIsValid(funcoid)) { \
ereport(ERROR, \
(errmodule(MOD_OPT), errcode(ERRCODE_UNDEFINED_OBJECT), \
errmsg("Cannot identify function %s.%s while deserializing field.", \
funcname, funcnamespace), \
errdetail("Function with oid %u or its namespace may be renamed", \
local_node->fldname), \
errhint("Please rebuild column defalt expression, views etc. that are" \
" related to this renamed object."), \
errcause("Object renamed after recorded as nodetree."), \
erraction("Rebuild relevant object."))); \
} \
local_node->fldname = funcoid; \
} \
pfree_ext(funcname); \
pfree_ext(funcnamespace); \
@ -525,7 +550,7 @@ THR_LOCAL bool skip_read_extern_fields = false;
token = pg_strtok(&length); \
token = pg_strtok(&length); \
oprrightname = nullable_string(token, length); \
if (IS_PGXC_DATANODE) { \
if (IS_DATANODE_BUT_NOT_SINGLENODE) { \
namespaceId = get_namespace_oid(opnamespace, false); \
oprleft = get_typeoid(namespaceId, oprleftname); \
oprright = oprleft; \
@ -568,7 +593,7 @@ THR_LOCAL bool skip_read_extern_fields = false;
token = pg_strtok(&length); \
token = pg_strtok(&length); \
oprrightname = nullable_string(token, length); \
if (IS_PGXC_DATANODE) { \
if (IS_DATANODE_BUT_NOT_SINGLENODE) { \
namespaceId = get_namespace_oid(opnamespace, false); \
oprleft = get_typeoid(namespaceId, oprleftname); \
oprright = oprleft; \
@ -2126,14 +2151,21 @@ static FuncExpr* _readFuncExpr(void)
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE), errmsg("NULL seqNamespace for nextval()")));
}
if (!IS_PGXC_COORDINATOR && !skip_read_extern_fields) {
Oid seqid = get_valid_relname_relid(seqNamespace, seqName);
if (IS_DATANODE_BUT_NOT_SINGLENODE && !skip_read_extern_fields) {
Oid seqid = get_valid_relname_relid(seqNamespace, seqName, true);
Const* firstArg = (Const*)linitial(local_node->args);
if (OidIsValid(seqid)) {
Const* firstArg = (Const*)linitial(local_node->args);
if (firstArg != NULL) {
firstArg->constvalue = ObjectIdGetDatum(seqid);
}
} else {
ereport(ERROR, (errmodule(MOD_OPT), errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("Cannot identify sequence %s.%s while deserializing field.", seqNamespace, seqName),
errdetail("Sequence with oid %u or its namespace may be renamed",
DatumGetObjectId(firstArg->constvalue)),
errhint("Please rebuild column defalt expression, views etc. that are related to this sequence"),
errcause("Object renamed after recorded as nodetree."), erraction("Rebuild relevant object.")));
}
}
pfree_ext(seqName);

View File

@ -1723,7 +1723,7 @@ char* get_relname_relid_extend(
extern bool StreamTopConsumerAmI();
/* same as get_relname_relid except we check for cache invalidation here */
Oid get_valid_relname_relid(const char* relnamespace, const char* relname)
Oid get_valid_relname_relid(const char* relnamespace, const char* relname, bool nsp_missing_ok)
{
Oid nspid = InvalidOid;
Oid oldnspid = InvalidOid;
@ -1747,7 +1747,10 @@ Oid get_valid_relname_relid(const char* relnamespace, const char* relname)
if (EnableLocalSysCache()) {
thrd_inval_count = t_thrd.lsc_cxt.lsc->inval_cxt.SIMCounter;
}
nspid = get_namespace_oid(relnamespace, false);
nspid = get_namespace_oid(relnamespace, nsp_missing_ok);
if (!OidIsValid(nspid)) {
return InvalidOid;
}
relid = get_relname_relid(relname, nspid);
/*
* In bootstrap processing mode, we don't bother with locking

View File

@ -1181,6 +1181,17 @@ static Node* pull_up_simple_subquery(PlannerInfo* root, Node* jtnode, RangeTblEn
return jtnode;
}
/*
* We must flatten any join alias Vars in the subquery's targetlist,
* because pulling up the subquery's subqueries might have changed their
* expansions into arbitrary expressions, which could affect
* pullup_replace_vars' decisions about whether PlaceHolderVar wrappers
* are needed for tlist entries. (Likely it'd be better to do
* flatten_join_alias_vars on the whole query tree at some earlier stage,
* maybe even in the rewriter; but for now let's just fix this case here.)
*/
subquery->targetList = (List *) flatten_join_alias_vars(subroot, (Node *) subquery->targetList);
/*
* Adjust level-0 varnos in subquery so that we can append its rangetable
* to upper query's. We have to fix the subquery's append_rel_list as

View File

@ -213,7 +213,7 @@ extern bool check_rel_is_partitioned(Oid relid);
extern Oid partid_get_parentid(Oid partid);
extern bool is_not_strict_agg(Oid funcOid);
extern bool is_pgxc_class_table(Oid tableoid);
extern Oid get_valid_relname_relid(const char* relnamespace, const char* relname);
extern Oid get_valid_relname_relid(const char* relnamespace, const char* relname, bool nsp_missing_ok = false);
extern bool get_func_iswindow(Oid funcid);
extern char get_func_prokind(Oid funcid);
extern char get_typecategory(Oid typid);

View File

@ -0,0 +1,116 @@
create schema deserialize_func1;
set current_schema = deserialize_func1;
create sequence test_seq;
create or replace function test_func() return int
as
begin
return 1;
end;
/
create table t1(key int, id int default nextval('test_seq'));
create table t2(key int, id int default test_func());
select * from pg_get_tabledef('deserialize_func1.t1');
pg_get_tabledef
------------------------------------------------------
SET search_path = deserialize_func1; +
CREATE TABLE t1 ( +
key integer, +
id integer DEFAULT nextval('test_seq'::regclass)+
) +
WITH (orientation=row, compression=no);
(1 row)
select * from pg_get_tabledef('deserialize_func1.t2');
pg_get_tabledef
-----------------------------------------
SET search_path = deserialize_func1; +
CREATE TABLE t2 ( +
key integer, +
id integer DEFAULT test_func() +
) +
WITH (orientation=row, compression=no);
(1 row)
alter schema deserialize_func1 rename to deserialize_func2;
select * from pg_get_tabledef('deserialize_func2.t1');
pg_get_tabledef
------------------------------------------------------------------------
SET search_path = deserialize_func2; +
CREATE TABLE t1 ( +
key integer, +
id integer DEFAULT nextval('deserialize_func2.test_seq'::regclass)+
) +
WITH (orientation=row, compression=no);
(1 row)
select * from pg_get_tabledef('deserialize_func2.t2');
pg_get_tabledef
------------------------------------------------------
SET search_path = deserialize_func2; +
CREATE TABLE t2 ( +
key integer, +
id integer DEFAULT deserialize_func2.test_func()+
) +
WITH (orientation=row, compression=no);
(1 row)
alter table deserialize_func2.t1 alter column id drop default;
alter table deserialize_func2.t1 alter column id set default nextval('deserialize_func2.test_seq');
select * from pg_get_tabledef('deserialize_func2.t1');
pg_get_tabledef
------------------------------------------------------------------------
SET search_path = deserialize_func2; +
CREATE TABLE t1 ( +
key integer, +
id integer DEFAULT nextval('deserialize_func2.test_seq'::regclass)+
) +
WITH (orientation=row, compression=no);
(1 row)
alter table deserialize_func2.t2 alter column id drop default;
alter table deserialize_func2.t2 alter column id set default deserialize_func2.test_func();
select * from pg_get_tabledef('deserialize_func2.t2');
pg_get_tabledef
------------------------------------------------------
SET search_path = deserialize_func2; +
CREATE TABLE t2 ( +
key integer, +
id integer DEFAULT deserialize_func2.test_func()+
) +
WITH (orientation=row, compression=no);
(1 row)
set current_schema = deserialize_func2;
create type type1 as (a int);
create view v1 as select '(1)'::type1;
alter type type1 rename to type2;
select pg_get_viewdef('v1');
pg_get_viewdef
-------------------------------
SELECT '(1)'::type2 AS type1;
(1 row)
drop view v1 cascade;
create table atest12 as select x as a, 10001-x as b from generate_series(1, 10000) x;
create function func1(integer, integer) returns boolean as $$begin return $1 < $2; end $$ language plpgsql immutable;
create operator <<< (procedure=func1, leftarg=integer, rightarg=integer, restrict=scalarltsel);
create view atest12v as select * from atest12 where b <<< 5;
select pg_get_viewdef('atest12v');
pg_get_viewdef
-------------------------------------------------
SELECT * FROM atest12 WHERE (atest12.b <<< 5);
(1 row)
drop schema if exists deserialize_func1 cascade;
NOTICE: schema "deserialize_func1" does not exist, skipping
drop schema if exists deserialize_func2 cascade;
NOTICE: drop cascades to 9 other objects
DETAIL: drop cascades to sequence test_seq
drop cascades to function test_func()
drop cascades to table t1
drop cascades to table t2
drop cascades to type type2
drop cascades to table atest12
drop cascades to function func1(integer,integer)
drop cascades to operator <<<(integer,integer)
drop cascades to view atest12v

View File

@ -0,0 +1,55 @@
CREATE TABLE t11 (
sec_code character(6) NOT NULL,
issue_type character(3) NOT NULL
);
CREATE TABLE t22 (
company_code character(6) NOT NULL,
list_profit_flag character(1) NOT NULL
);
CREATE TABLE t33 (
company_code character(6) NOT NULL,
issue_flag character(6) NOT NULL
);
insert into t11 values(1,'S04');
insert into t22 values(1,'Y');
insert into t33 values(1,'1');
insert into t33 values(2,'2');
select
T5.issue_type
,T6.is_type
from
(
select T1.sec_code
,issue_type
--,case when list_profit_flag='Y' then '是' else '否' end as list_profit_flag
from
(
select sec_code
,case when issue_type in ('S04','S05','S06','S09') then '增发'
when issue_type in ('S01','S02') then '首发'
else '其他' end as issue_type
from t11
)T1
left join
(
select list_profit_flag
,company_code
from t22
)T2
on T1.sec_code=T2.company_code
)T5
full join
(
SELECT CASE
WHEN issue_flag = ANY (ARRAY['1'::bpchar, '3'::bpchar, '11'::bpchar]) THEN '首发'::text
ELSE '增发'::text
END AS is_type from t33
)T6
on T5.issue_type=T6.is_type
;
issue_type | is_type
------------+---------
增发 | 增发
| 首发
(2 rows)

View File

@ -25,7 +25,7 @@ test: pldeveloper_gs_source
test: index_advisor
test: pl_debugger_server pl_debugger_client
test: update_for_wait_s1 update_for_wait_s2
test: plan_hint plan_hint_set plan_hint_no_expand plan_hint_iud null_test_opt
test: plan_hint plan_hint_set plan_hint_no_expand plan_hint_iud null_test_opt deserialize_func
test: large_sequence int16 gs_dump_sequence
test: gs_dump_tableof
test: analyze_commands
@ -917,3 +917,4 @@ test: gs_global_config_audit
test: detail
test: gs_dump_encrypt
test: composite_datum_record
test: join_test_alias

View File

@ -5238,7 +5238,7 @@ static void check_global_variables()
}
}
#define BASE_PGXC_LIKE_MACRO_NUM 1401
#define BASE_PGXC_LIKE_MACRO_NUM 1402
static void check_pgxc_like_macros()
{
#ifdef BUILD_BY_CMAKE

View File

@ -0,0 +1,63 @@
create schema deserialize_func1;
set current_schema = deserialize_func1;
create sequence test_seq;
create or replace function test_func() return int
as
begin
return 1;
end;
/
create table t1(key int, id int default nextval('test_seq'));
create table t2(key int, id int default test_func());
select * from pg_get_tabledef('deserialize_func1.t1');
select * from pg_get_tabledef('deserialize_func1.t2');
alter schema deserialize_func1 rename to deserialize_func2;
select * from pg_get_tabledef('deserialize_func2.t1');
select * from pg_get_tabledef('deserialize_func2.t2');
alter table deserialize_func2.t1 alter column id drop default;
alter table deserialize_func2.t1 alter column id set default nextval('deserialize_func2.test_seq');
select * from pg_get_tabledef('deserialize_func2.t1');
alter table deserialize_func2.t2 alter column id drop default;
alter table deserialize_func2.t2 alter column id set default deserialize_func2.test_func();
select * from pg_get_tabledef('deserialize_func2.t2');
set current_schema = deserialize_func2;
create type type1 as (a int);
create view v1 as select '(1)'::type1;
alter type type1 rename to type2;
select pg_get_viewdef('v1');
drop view v1 cascade;
create table atest12 as select x as a, 10001-x as b from generate_series(1, 10000) x;
create function func1(integer, integer) returns boolean as $$begin return $1 < $2; end $$ language plpgsql immutable;
create operator <<< (procedure=func1, leftarg=integer, rightarg=integer, restrict=scalarltsel);
create view atest12v as select * from atest12 where b <<< 5;
select pg_get_viewdef('atest12v');
drop schema if exists deserialize_func1 cascade;
drop schema if exists deserialize_func2 cascade;

View File

@ -0,0 +1,53 @@
CREATE TABLE t11 (
sec_code character(6) NOT NULL,
issue_type character(3) NOT NULL
);
CREATE TABLE t22 (
company_code character(6) NOT NULL,
list_profit_flag character(1) NOT NULL
);
CREATE TABLE t33 (
company_code character(6) NOT NULL,
issue_flag character(6) NOT NULL
);
insert into t11 values(1,'S04');
insert into t22 values(1,'Y');
insert into t33 values(1,'1');
insert into t33 values(2,'2');
select
T5.issue_type
,T6.is_type
from
(
select T1.sec_code
,issue_type
--,case when list_profit_flag='Y' then '' else '' end as list_profit_flag
from
(
select sec_code
,case when issue_type in ('S04','S05','S06','S09') then '增发'
when issue_type in ('S01','S02') then '首发'
else '其他' end as issue_type
from t11
)T1
left join
(
select list_profit_flag
,company_code
from t22
)T2
on T1.sec_code=T2.company_code
)T5
full join
(
SELECT CASE
WHEN issue_flag = ANY (ARRAY['1'::bpchar, '3'::bpchar, '11'::bpchar]) THEN '首发'::text
ELSE '增发'::text
END AS is_type from t33
)T6
on T5.issue_type=T6.is_type
;