修复并行创建函数同时成功

This commit is contained in:
ganyang
2022-07-05 19:42:48 +08:00
parent 2b2d3ae382
commit bfb3754eb9
6 changed files with 80 additions and 40 deletions

View File

@ -1419,17 +1419,23 @@ Oid ProcedureCreate(const char* procedureName, Oid procNamespace, Oid propackage
/* A db do not overload a function by arguments.*/
NameData* pkgname = NULL;
char* schemaName = get_namespace_name(procNamespace);
if (OidIsValid(propackageid)) {
pkgname = GetPackageName(propackageid);
}
if (pkgname == NULL) {
name = list_make2(makeString(schemaName), makeString(pstrdup(procedureName)));
} else {
name = list_make3(makeString(schemaName), makeString(pstrdup(pkgname->data)), makeString(pstrdup(procedureName)));
}
#ifndef ENABLE_MULTIPLE_NODES
if (pkgname == NULL) {
LockProcName(schemaName, NULL, procedureName);
} else {
LockProcName(schemaName, pkgname->data, procedureName);
}
#endif
if (isOraStyle && !package) {
if (OidIsValid(propackageid)) {
pkgname = GetPackageName(propackageid);
}
if (pkgname == NULL) {
name = list_make2(makeString(get_namespace_name(procNamespace)), makeString(pstrdup(procedureName)));
} else {
name = list_make3(makeString(get_namespace_name(procNamespace)), makeString(pstrdup(pkgname->data)), makeString(pstrdup(procedureName)));
}
List* name = list_make2(makeString(get_namespace_name(procNamespace)), makeString(pstrdup(procedureName)));
FuncCandidateList listfunc = FuncnameGetCandidates(name, -1, NULL, false, false, true);
if (listfunc) {
if (listfunc->next)
@ -2663,4 +2669,27 @@ static void CheckInParameterConflicts(CatCList* catlist, const char* procedureNa
}
}
}
/*
* Due to procedure has no unique index on parameters, it maybe insert same data
* and this function prevent insert procedure with same funcname and funcargs,
*/
void LockProcName(char* schemaname, char* pkgname, const char* funcname)
{
if (u_sess->attr.attr_common.upgrade_mode != 0) {
return;
}
Oid schemaOid = SchemaNameGetSchemaOid(schemaname, false);
if (IsPackageSchemaOid(schemaOid)) {
return;
}
if (pkgname != NULL) {
List* funcnameList = list_make2(makeString(pstrdup(pkgname)), makeString(pstrdup(funcname)));
uint32 hash_value = string_hash(NameListToQuotedString(funcnameList), NAMEDATALEN + NAMEDATALEN);
LockDatabaseObject(ProcedureRelationId, schemaOid, hash_value, ExclusiveLock);
} else {
uint32 hash_value = string_hash(funcname, NAMEDATALEN);
LockDatabaseObject(ProcedureRelationId, schemaOid, hash_value, ExclusiveLock);
}
}
#endif

View File

@ -1359,13 +1359,6 @@ Datum plpgsql_validator(PG_FUNCTION_ARGS)
PG_RE_THROW();
}
PG_END_TRY();
/* Skip validation on Initdb */
#ifndef ENABLE_MULTIPLE_NODES
if (!IsInitdb && u_sess->plsql_cxt.isCreateFunction) {
ProcInsertGsSource(funcoid, true);
}
#endif
bool isNotComipilePkg = u_sess->plsql_cxt.curr_compile_context == NULL ||
(u_sess->plsql_cxt.curr_compile_context != NULL &&
u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package == NULL);
@ -1386,7 +1379,11 @@ Datum plpgsql_validator(PG_FUNCTION_ARGS)
u_sess->ClientAuthInProgress = saved_client_auth;
}
}
#ifndef ENABLE_MULTIPLE_NODES
if (!IsInitdb && u_sess->plsql_cxt.isCreateFunction) {
ProcInsertGsSource(funcoid, true);
}
#endif
#ifndef ENABLE_MULTIPLE_NODES
u_sess->plsql_cxt.isCreateFunction = false;
u_sess->opt_cxt.query_dop = outerDop;

View File

@ -1842,9 +1842,22 @@ void AlterFunction(AlterFunctionStmt* stmt)
DefElem* shippable_item = NULL;
DefElem* package_item = NULL;
bool isNull = false;
rel = heap_open(ProcedureRelationId, RowExclusiveLock);
funcOid = LookupFuncNameTypeNames(stmt->func->funcname, stmt->func->funcargs, false);
#ifndef ENABLE_MULTIPLE_NODES
char* schemaName = NULL;
char* pkgname = NULL;
char* procedureName = NULL;
DeconstructQualifiedName(stmt->func->funcname, &schemaName, &procedureName, &pkgname);
if (schemaName == NULL) {
tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
procForm = (Form_pg_proc)GETSTRUCT(tup);
schemaName = get_namespace_name(procForm->pronamespace);
ReleaseSysCache(tup);
}
LockProcName(schemaName, pkgname, procedureName);
#endif
rel = heap_open(ProcedureRelationId, RowExclusiveLock);
/* if the function is a builtin function, its Oid is less than 10000.
* we can't allow alter the builtin functions
*/

View File

@ -1640,6 +1640,7 @@ extern void exec_get_datum_type_info(PLpgSQL_execstate* estate, PLpgSQL_datum* d
extern Datum exec_simple_cast_datum(
PLpgSQL_execstate* estate, Datum value, Oid valtype, Oid reqtype, int32 reqtypmod, bool isnull);
extern void ResetCursorOption(Portal portal, bool reset);
extern void LockProcName(char* schemaname, char* pkgname, const char* funcname);
#ifndef ENABLE_MULTIPLE_NODES
extern void ResetCursorAtrribute(Portal portal);
#endif

View File

@ -836,7 +836,12 @@ begin
null;
end;
/
set behavior_compat_options='';
set plsql_show_all_error to on;
set check_function_bodies to off;
create or replace procedure test1 is begin null; end;
/
set check_function_bodies to on;
select name,type,status,src from DBE_PLDEVELOPER.gs_source order by name;
name | type | status | src
--------------+--------------+--------+---------------------------------------------------------------------------------
@ -945,7 +950,8 @@ select name,type,status,src from DBE_PLDEVELOPER.gs_source order by name;
| | | begin +
| | | insert int a; +
| | | end;
(16 rows)
test1 | procedure | t | create or replace procedure test1 is begin null; end;
(17 rows)
select name,type,line,src from DBE_PLDEVELOPER.gs_errors order by name;
name | type | line | src
@ -996,11 +1002,6 @@ select rolname, name, status, type, src from DBE_PLDEVELOPER.gs_source s join pg
| | | | return var1; +
| | | | end; +
| | | | $$;
gs_developper | error2 | t | package | CREATE OR REPLACE PACKAGE error2 IS +
| | | | a int;b int; +
| | | | FUNCTION func1(a in int, b inout int, c out int) return int; +
| | | | FUNCTION func2(a in int, b inout int, c out int) return int; +
| | | | END error2;
gs_developper | error2 | f | package body | CREATE OR REPLACE PACKAGE BODY error2 IS +
| | | | FUNCTION func1 (a in int, b inout int c out int) return int +
| | | | IS +
@ -1018,6 +1019,11 @@ select rolname, name, status, type, src from DBE_PLDEVELOPER.gs_source s join pg
| | | | RETURN(a1 + a + b); +
| | | | END; +
| | | | END error2;
gs_developper | error2 | t | package | CREATE OR REPLACE PACKAGE error2 IS +
| | | | a int;b int; +
| | | | FUNCTION func1(a in int, b inout int, c out int) return int; +
| | | | FUNCTION func2(a in int, b inout int, c out int) return int; +
| | | | END error2;
gs_developper | func00 | t | procedure | create or replace procedure func00 +
| | | | is +
| | | | begin +
@ -1051,19 +1057,6 @@ select rolname, name, status, type, src from DBE_PLDEVELOPER.gs_source s join pg
| | | | a inv%d; +
| | | | procedure proc1(c ff%F); +
| | | | end pkg2;
gs_developper | pkg3 | f | package body | create or replace package body pkg3 +
| | | | is +
| | | | a b c d; +
| | | | procedure proc1() +
| | | | is +
| | | | begin +
| | | | insert int asd asd; +
| | | | end; +
| | | | end pkg3;
gs_developper | pkg3 | t | package | create or replace package pkg3 +
| | | | is +
| | | | a int; +
| | | | end pkg3;
gs_developper | pkg4 | f | package | create or replace package pkg4 +
| | | | is +
| | | | a a; +
@ -1091,14 +1084,15 @@ select rolname, name, status, type, src from DBE_PLDEVELOPER.gs_source s join pg
| | | | begin +
| | | | insert int a; +
| | | | end;
(16 rows)
gs_developper | test1 | t | procedure | create or replace procedure test1 is begin null; end;
(15 rows)
truncate DBE_PLDEVELOPER.gs_source;
truncate DBE_PLDEVELOPER.gs_errors;
reset role;
reset behavior_compat_options;
drop schema gs_source cascade;
NOTICE: drop cascades to 14 other objects
NOTICE: drop cascades to 15 other objects
DETAIL: drop cascades to function gourav88(integer,integer,integer)
drop cascades to function func1()
drop cascades to function mask()
@ -1113,5 +1107,6 @@ drop cascades to function gs_source.func1(integer,integer)
drop cascades to function gs_source.func2(integer,integer)
drop cascades to function func00()
drop cascades to function skipinsertgssource()
drop cascades to function test1()
drop role jackson_src;
drop role gs_developper;

View File

@ -283,7 +283,12 @@ begin
null;
end;
/
set behavior_compat_options='';
set plsql_show_all_error to on;
set check_function_bodies to off;
create or replace procedure test1 is begin null; end;
/
set check_function_bodies to on;
select name,type,status,src from DBE_PLDEVELOPER.gs_source order by name;
select name,type,line,src from DBE_PLDEVELOPER.gs_errors order by name;
drop package if exists pkg4;