解决缺陷:修改存在plsql依赖的类型的schema导致重建报错
This commit is contained in:
@ -321,8 +321,7 @@ static void out_drop_stmt(ArchiveHandle* AH, const TocEntry* te)
|
||||
char* dropStmt = NULL;
|
||||
char* dropStmtOrig = NULL;
|
||||
errno_t rc = EOK;
|
||||
if (*te->dropStmt != '\0')
|
||||
{
|
||||
if (*te->dropStmt != '\0') {
|
||||
dropStmt = try_remove_nsname_in_drop_stmt(ropt, te->dropStmt, strlen(te->dropStmt) + PATCH_LEN);
|
||||
dropStmtOrig = dropStmt;
|
||||
if (strstr(te->dropStmt, "IF EXISTS") != NULL ||
|
||||
@ -386,8 +385,8 @@ static void out_drop_stmt(ArchiveHandle* AH, const TocEntry* te)
|
||||
}
|
||||
ahprintf(AH, "%s", ftStmt->data);
|
||||
destroyPQExpBuffer(ftStmt);
|
||||
free(dropStmtOrig);
|
||||
}
|
||||
free(dropStmtOrig);
|
||||
}
|
||||
}
|
||||
/* Public */
|
||||
|
||||
@ -72,6 +72,65 @@ static inline Oid gsplsql_parse_pkg_var_and_attrs4(GsDependObjDesc* obj, List* v
|
||||
static inline Oid gsplsql_parse_pkg_var_and_attrs3(GsDependObjDesc* obj, ListCell* var_name, ListCell** attr_list);
|
||||
static inline Oid gsplsql_parse_pkg_var_obj2(GsDependObjDesc* obj, ListCell* var_name);
|
||||
|
||||
static bool gsplsql_exist_func_object_in_dependencies_obj(char* nsp_name, char* pkg_name,
|
||||
const char* old_func_head_name, const char* old_func_name);
|
||||
static bool gsplsql_exist_func_object_in_dependencies(char* nsp_name, char* pkg_name, const char* old_func_head_name);
|
||||
|
||||
bool gsplsql_exists_func_obj(Oid nsp_oid, Oid pkg_oid, const char* old_func_head_name, const char* old_func_name)
|
||||
{
|
||||
char* nsp_name = get_namespace_name(nsp_oid);
|
||||
char* pkg_name = pstrdup("null");
|
||||
if (OidIsValid(pkg_oid)) {
|
||||
pfree_ext(pkg_name);
|
||||
pkg_name = GetPackageName(pkg_oid);
|
||||
}
|
||||
bool exists_func = gsplsql_exist_func_object_in_dependencies_obj(nsp_name, pkg_name, old_func_head_name, old_func_name) ||
|
||||
gsplsql_exist_func_object_in_dependencies(nsp_name, pkg_name, old_func_head_name);
|
||||
pfree_ext(pkg_name);
|
||||
pfree_ext(nsp_name);
|
||||
return exists_func;
|
||||
}
|
||||
|
||||
bool gsplsql_exists_schema_name(const char* schema_name)
|
||||
{
|
||||
bool has_schema = false;
|
||||
Assert(schema_name != NULL);
|
||||
// check gs_dependencies_obj
|
||||
int key_num = 0;
|
||||
ScanKeyData key[1];
|
||||
ScanKeyInit(&key[key_num++], Anum_gs_dependencies_obj_schemaname, BTEqualStrategyNumber,
|
||||
F_NAMEEQ, NameGetDatum(schema_name));
|
||||
bool is_null = false;
|
||||
HeapTuple tuple;
|
||||
Relation obj_rel = heap_open(DependenciesObjRelationId, AccessShareLock);
|
||||
SysScanDesc scan = systable_beginscan(obj_rel, DependenciesObjNameIndexId, true, SnapshotSelf, key_num, key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
has_schema = true;
|
||||
break;
|
||||
}
|
||||
systable_endscan(scan);
|
||||
heap_close(obj_rel, AccessShareLock);
|
||||
if (has_schema) {
|
||||
return has_schema;
|
||||
}
|
||||
// check gs_dependencies
|
||||
int key_num_dep = 0;
|
||||
ScanKeyData key_dep[1];
|
||||
ScanKeyInit(&key_dep[key_num_dep++], Anum_gs_dependencies_schemaname, BTEqualStrategyNumber,
|
||||
F_NAMEEQ, NameGetDatum(schema_name));
|
||||
HeapTuple tuple_dep;
|
||||
Relation dep_rel = heap_open(DependenciesRelationId, AccessShareLock);
|
||||
SysScanDesc scan_dep = systable_beginscan(dep_rel, DependenciesNameIndexId, true, SnapshotSelf,
|
||||
key_num_dep, key_dep);
|
||||
while (HeapTupleIsValid(tuple_dep = systable_getnext(scan_dep))) {
|
||||
has_schema = true;
|
||||
break;
|
||||
}
|
||||
systable_endscan(scan_dep);
|
||||
heap_close(dep_rel, AccessShareLock);
|
||||
return has_schema;
|
||||
}
|
||||
|
||||
void gsplsql_init_gs_depend_obj_desc(GsDependObjDesc* object)
|
||||
{
|
||||
object->schemaName = NULL;
|
||||
@ -1483,3 +1542,78 @@ static DependenciesDatum *gsplsql_make_var_depend_datum(const PLpgSQL_datum *dat
|
||||
}
|
||||
return (DependenciesDatum*)var_node;
|
||||
}
|
||||
|
||||
static bool gsplsql_exist_func_object_in_dependencies_obj(char* nsp_name, char* pkg_name,
|
||||
const char* old_func_head_name, const char* old_func_name)
|
||||
{
|
||||
int keyNum = 0;
|
||||
Assert(nsp_name != NULL && pkg_name != NULL);
|
||||
ScanKeyData key[2];
|
||||
ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_schemaname, BTEqualStrategyNumber,
|
||||
F_NAMEEQ, NameGetDatum(nsp_name));
|
||||
ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_packagename, BTEqualStrategyNumber,
|
||||
F_NAMEEQ, NameGetDatum(pkg_name));
|
||||
bool is_null = false;
|
||||
HeapTuple tuple;
|
||||
Relation obj_rel = heap_open(DependenciesObjRelationId, AccessShareLock);
|
||||
SysScanDesc scan = systable_beginscan(obj_rel, DependenciesObjNameIndexId, true, SnapshotSelf, keyNum, key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Datum name_datum = heap_getattr(tuple, Anum_gs_dependencies_obj_name,
|
||||
RelationGetDescr(obj_rel), &is_null);
|
||||
Assert(name_datum != 0);
|
||||
char* obj_name = TextDatumGetCString(name_datum);
|
||||
if (strcmp(old_func_head_name, obj_name) == 0 || strcmp(old_func_name, obj_name) == 0) {
|
||||
Datum type_datum = heap_getattr(tuple, Anum_gs_dependencies_obj_type,
|
||||
RelationGetDescr(obj_rel), &is_null);
|
||||
int type = DatumGetInt32(type_datum);
|
||||
if (type == GSDEPEND_OBJECT_TYPE_FUNCTION ||
|
||||
type == GSDEPEND_OBJECT_TYPE_PROCHEAD || type == GSDEPEND_OBJECT_TYPE_UNDEFIND) {
|
||||
pfree_ext(obj_name);
|
||||
systable_endscan(scan);
|
||||
heap_close(obj_rel, AccessShareLock);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pfree_ext(obj_name);
|
||||
}
|
||||
systable_endscan(scan);
|
||||
heap_close(obj_rel, AccessShareLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gsplsql_exist_func_object_in_dependencies(char* nsp_name, char* pkg_name, const char* old_func_head_name)
|
||||
{
|
||||
int keyNum = 0;
|
||||
Assert(nsp_name != NULL && pkg_name != NULL);
|
||||
ScanKeyData key[2];
|
||||
ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_schemaname, BTEqualStrategyNumber,
|
||||
F_NAMEEQ, NameGetDatum(nsp_name));
|
||||
ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_packagename, BTEqualStrategyNumber,
|
||||
F_NAMEEQ, NameGetDatum(pkg_name));
|
||||
bool is_null = false;
|
||||
HeapTuple tuple;
|
||||
Relation dep_rel = heap_open(DependenciesRelationId, AccessShareLock);
|
||||
SysScanDesc scan = systable_beginscan(dep_rel, DependenciesNameIndexId, true, SnapshotSelf, keyNum, key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan))) {
|
||||
Datum name_datum = heap_getattr(tuple, Anum_gs_dependencies_objectname,
|
||||
RelationGetDescr(dep_rel), &is_null);
|
||||
Assert(name_datum != 0);
|
||||
char* obj_name = TextDatumGetCString(name_datum);
|
||||
if (strcmp(old_func_head_name, obj_name) == 0) {
|
||||
Datum refobj_pos_datum = heap_getattr(tuple, Anum_gs_dependencies_refobjpos,
|
||||
RelationGetDescr(dep_rel), &is_null);
|
||||
int refobj_pos = DatumGetInt32(refobj_pos_datum);
|
||||
if (refobj_pos == GSDEPEND_REFOBJ_POS_IN_PROCHEAD ||
|
||||
refobj_pos == GSDEPEND_REFOBJ_POS_IN_PROCBODY) {
|
||||
pfree_ext(obj_name);
|
||||
systable_endscan(scan);
|
||||
heap_close(dep_rel, AccessShareLock);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pfree_ext(obj_name);
|
||||
}
|
||||
systable_endscan(scan);
|
||||
heap_close(dep_rel, AccessShareLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -19,29 +19,6 @@
|
||||
* IDENTIFICATION
|
||||
* src/common/backend/utils/gsplsql/gsobject_gsdependencies.cpp
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openGauss is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* gsobject_gsdependencies.cpp
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/common/backend/utils/gsplsql/gsobject_gsdependencies.cpp
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -1086,10 +1063,6 @@ static bool gsplsql_update_proc_header(CreateFunctionStmt *stmt, Oid funcid)
|
||||
prorettype = VOIDOID;
|
||||
returnsSet = false;
|
||||
}
|
||||
if (has_undefined) {
|
||||
ereport(
|
||||
LOG, (errmsg("the function header has an unknown dependency. function oid is %u", funcid)));
|
||||
}
|
||||
char* parameter_defaults_str = NULL;
|
||||
if (parameter_defaults != NIL) {
|
||||
parameter_defaults_str = nodeToString(parameter_defaults);
|
||||
@ -1139,8 +1112,6 @@ static bool gsplsql_update_proc_header(CreateFunctionStmt *stmt, Oid funcid)
|
||||
CacheInvalidateFunction(funcid, InvalidOid);
|
||||
if (!is_proc_info_changed(funcid, parameter_types, all_parameter_types, parameter_defaults_str,
|
||||
prorettype, returnsSet)) {
|
||||
ereport(LOG, (errcode(ERRCODE_PLPGSQL_ERROR),
|
||||
errmsg("The header of function %u does not need to be modified.", funcid)));
|
||||
pfree_ext(parameter_defaults_str);
|
||||
return has_undefined;
|
||||
}
|
||||
@ -1252,7 +1223,7 @@ static bool is_proc_info_changed(Oid funcid, oidvector *new_parameter_types, Arr
|
||||
}
|
||||
size_tmp = allpara_count * sizeof(Oid);
|
||||
Oid *p_argtypes = (Oid *)palloc(size_tmp);
|
||||
rc = memcpy_s(p_argtypes, size_tmp, ARR_DATA_PTR(new_all_parameter_types), size_tmp);
|
||||
rc = memcpy_s(p_argtypes, size_tmp, ARR_DATA_PTR(arr), size_tmp);
|
||||
securec_check(rc, "\0", "\0");
|
||||
oidvector *allpara_type = buildoidvector(p_argtypes, allpara_count);
|
||||
if (!DatumGetBool(DirectFunctionCall2(oidvectoreq, PointerGetDatum(allpara_type),
|
||||
@ -1485,8 +1456,6 @@ static void gsplsql_delete_dependencies_object_by_oid(Oid oid)
|
||||
if (!HeapTupleIsValid(tuple)) {
|
||||
systable_endscan(scan);
|
||||
heap_close(dep_rel, RowExclusiveLock);
|
||||
ereport(LOG, (errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("dependencies object %u does not exist.", oid)));
|
||||
return;
|
||||
}
|
||||
simple_heap_delete(dep_rel, &tuple->t_self, 0, true);
|
||||
|
||||
@ -66,6 +66,7 @@
|
||||
#include "utils/rel_gs.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "gs_policy/gs_policy_masking.h"
|
||||
#include "catalog/gs_dependencies_fn.h"
|
||||
|
||||
/*
|
||||
* Executes an ALTER OBJECT / RENAME TO statement. Based on the object
|
||||
@ -736,6 +737,21 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
|
||||
|
||||
IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
|
||||
&proc->proargtypes, nspOid);
|
||||
|
||||
if (enable_plpgsql_gsdependency_guc()) {
|
||||
const char* old_func_format = format_procedure_no_visible(objid);
|
||||
const char* old_func_name = NameStr(proc->proname);
|
||||
bool is_null = false;
|
||||
Datum package_oid_datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_packageid, &is_null);
|
||||
Oid pkg_oid = DatumGetObjectId(package_oid_datum);
|
||||
if (gsplsql_exists_func_obj(oldNspOid, pkg_oid, old_func_format, old_func_name)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
|
||||
errmsg("The set schema operator of %s is not allowed, "
|
||||
"because it is referenced by the other object.",
|
||||
NameStr(proc->proname))));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (classId == CollationRelationId) {
|
||||
Form_pg_collation coll = (Form_pg_collation) GETSTRUCT(tup);
|
||||
|
||||
@ -1977,6 +1977,20 @@ ObjectAddress RenameFunction(List* name, List* argtypes, const char* newname)
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceOid));
|
||||
|
||||
if (enable_plpgsql_gsdependency_guc()) {
|
||||
const char* old_func_format = format_procedure_no_visible(procOid);
|
||||
const char* old_func_name = strVal(llast(name));
|
||||
bool is_null = false;
|
||||
Datum package_oid_datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_packageid, &is_null);
|
||||
Oid pkg_oid = DatumGetObjectId(package_oid_datum);
|
||||
if (gsplsql_exists_func_obj(namespaceOid, pkg_oid, old_func_format, old_func_name)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
|
||||
errmsg("The rename operator of %s is not allowed, because it is referenced by the other object.",
|
||||
NameStr(procForm->proname))));
|
||||
}
|
||||
}
|
||||
|
||||
/* rename */
|
||||
(void)namestrcpy(&(procForm->proname), newname);
|
||||
simple_heap_update(rel, &tup->t_self, tup);
|
||||
@ -3232,6 +3246,20 @@ Oid AlterFunctionNamespace_oid(Oid procOid, Oid nspOid)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (enable_plpgsql_gsdependency_guc()) {
|
||||
const char* old_func_format = format_procedure_no_visible(procOid);
|
||||
const char* old_func_name = NameStr(proc->proname);
|
||||
bool is_null = false;
|
||||
Datum package_oid_datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_packageid, &is_null);
|
||||
Oid pkg_oid = DatumGetObjectId(package_oid_datum);
|
||||
if (gsplsql_exists_func_obj(oldNspOid, pkg_oid, old_func_format, old_func_name)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
|
||||
errmsg("The set schema operator of %s is not allowed, "
|
||||
"because it is referenced by the other object.",
|
||||
NameStr(proc->proname))));
|
||||
}
|
||||
}
|
||||
/* OK, modify the pg_proc row */
|
||||
/* tup is a copy, so we can scribble directly on it */
|
||||
proc->pronamespace = nspOid;
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "utils/snapmgr.h"
|
||||
#include "gs_ledger/ledger_utils.h"
|
||||
#include "gs_ledger/userchain.h"
|
||||
#include "catalog/gs_dependencies_fn.h"
|
||||
|
||||
#ifdef PGXC
|
||||
#include "pgxc/pgxc.h"
|
||||
@ -589,6 +590,13 @@ ObjectAddress RenameSchema(const char* oldname, const char* newname)
|
||||
existTimeSeriesTbl->data)));
|
||||
}
|
||||
|
||||
if (enable_plpgsql_gsdependency_guc() && gsplsql_exists_schema_name(oldname)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
|
||||
errmsg("The rename operator of %s is not allowed, because it is referenced by the other object.",
|
||||
oldname)));
|
||||
}
|
||||
|
||||
/* Before rename schema (with blockchain) rename related ledger tables first */
|
||||
bool is_null = true;
|
||||
Datum datum = SysCacheGetAttr(NAMESPACENAME, tup, Anum_pg_namespace_nspblockchain, &is_null);
|
||||
|
||||
@ -21639,6 +21639,14 @@ void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid, Object
|
||||
|
||||
Assert(objsMoved != NULL);
|
||||
|
||||
if (enable_plpgsql_gsdependency_guc() &&
|
||||
gsplsql_is_object_depend(rel->rd_rel->reltype, GSDEPEND_OBJECT_TYPE_TYPE)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
|
||||
errmsg("The set schema operator of %s is not allowed, "
|
||||
"because it is referenced by another object.", NameStr(rel->rd_rel->relname))));
|
||||
}
|
||||
|
||||
/* OK, modify the pg_class row and pg_depend entry */
|
||||
classRel = heap_open(RelationRelationId, RowExclusiveLock);
|
||||
|
||||
|
||||
@ -3688,6 +3688,13 @@ Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses* objsMoved)
|
||||
errmsg("cannot alter array type %s", format_type_be(typeOid)),
|
||||
errhint("You can alter type %s, which will alter the array type as well.", format_type_be(elemOid))));
|
||||
|
||||
if (enable_plpgsql_gsdependency_guc() &&
|
||||
gsplsql_is_object_depend(typeOid, GSDEPEND_OBJECT_TYPE_TYPE)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
|
||||
errmsg("The set schema operator of %s is not allowed, because it is referenced by the other object.",
|
||||
get_typename(typeOid))));
|
||||
}
|
||||
/* and do the work */
|
||||
return AlterTypeNamespaceInternal(typeOid, nspOid, false, true, objsMoved);
|
||||
}
|
||||
|
||||
@ -143,4 +143,7 @@ extern void gsplsql_delete_unrefer_depend_obj_oid(Oid ref_obj_oid, bool skip_in_
|
||||
extern bool gsplsql_check_type_depend_ast_equal(Relation obj_rel, Oid obj_oid, const char* equal_ast);
|
||||
extern bool gsplsql_search_depend_obj_by_oid(Oid oid, GsDependObjDesc* obj_desc);
|
||||
extern void gsplsql_remove_type_gs_dependency(const GsDependObjDesc* obj_desc);
|
||||
extern bool gsplsql_exists_func_obj(Oid nsp_oid, Oid pkg_oid, const char* old_func_head_name,
|
||||
const char* old_func_name);
|
||||
extern bool gsplsql_exists_schema_name(const char* schema_name);
|
||||
#endif /* GS_DEPENDENCIES_FN_H */
|
||||
|
||||
@ -387,13 +387,91 @@ INFO: call xxx: (1,aaa,aaaaa,,,), yyy: (2,bbb,bbbbb,,,), p_in: (1,zhang,M,1,2,3
|
||||
|
||||
(1 row)
|
||||
|
||||
-- test 6
|
||||
drop type if exists r1;
|
||||
drop table if exists stu;
|
||||
create table stu(sno int, name varchar, sex varchar, cno int);
|
||||
create type r1 as (a int, c stu%RowType);
|
||||
create schema plpgsql_recompile_new;
|
||||
create or replace procedure test_proc(p_in r1)
|
||||
is
|
||||
declare
|
||||
v1 stu%RowType;
|
||||
begin
|
||||
RAISE INFO 'call p_in: %', p_in;
|
||||
end;
|
||||
/
|
||||
call test_proc((1,(1,'zhang','M',1)));
|
||||
INFO: call p_in: (1,"(1,zhang,M,1)")
|
||||
test_proc
|
||||
-----------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- rename report error
|
||||
ALTER TYPE r1 RENAME to r1_rename;
|
||||
ERROR: The rename operator of r1 is not allowed, because it is referenced by the other object.
|
||||
ALTER TYPE r1 RENAME ATTRIBUTE a TO new_a;
|
||||
ERROR: cannot rename attribute of the type because it is dependent on another object.
|
||||
ALTER TABLE stu RENAME TO stu_rename;
|
||||
ERROR: The rename operator on stu is not allowed, because it is dependent on another object.
|
||||
ALTER TABLE stu RENAME COLUMN cno TO new_cno;
|
||||
ERROR: cannot rename attribute of the type because it is dependent on another object.
|
||||
ALTER PROCEDURE test_proc(r1) RENAME TO test_proc_rename;
|
||||
ERROR: The rename operator of test_proc is not allowed, because it is referenced by the other object.
|
||||
ALTER SCHEMA plpgsql_recompile RENAME TO plpgsql_recompile_rename;
|
||||
ERROR: The rename operator of plpgsql_recompile is not allowed, because it is referenced by the other object.
|
||||
call test_proc((1.0,(1,'zhang','M',1)));
|
||||
INFO: call p_in: (1,"(1,zhang,M,1)")
|
||||
test_proc
|
||||
-----------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- set schema report error
|
||||
ALTER TYPE r1 SET SCHEMA plpgsql_recompile_new;
|
||||
ERROR: The set schema operator of r1 is not allowed, because it is referenced by the other object.
|
||||
ALTER TABLE stu SET SCHEMA plpgsql_recompile_new;
|
||||
ERROR: The set schema operator of stu is not allowed, because it is referenced by another object.
|
||||
ALTER PROCEDURE test_proc(r1) SET SCHEMA plpgsql_recompile_new;
|
||||
ERROR: The set schema operator of test_proc is not allowed, because it is referenced by the other object.
|
||||
call test_proc((1.0,(1,'zhang','M',1)));
|
||||
INFO: call p_in: (1,"(1,zhang,M,1)")
|
||||
test_proc
|
||||
-----------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- drop and recreate
|
||||
drop type r1;
|
||||
drop table stu;
|
||||
drop procedure test_proc;
|
||||
create table stu(sno int, name varchar, sex varchar, cno int);
|
||||
create type r1 as (a int, c stu%RowType);
|
||||
create or replace procedure test_proc(p_in r1)
|
||||
is
|
||||
declare
|
||||
v1 stu%RowType;
|
||||
begin
|
||||
RAISE INFO 'call p_in: %', p_in;
|
||||
end;
|
||||
/
|
||||
call test_proc((1,(1,'zhang','M',1)));
|
||||
INFO: call p_in: (1,"(1,zhang,M,1)")
|
||||
test_proc
|
||||
-----------
|
||||
|
||||
(1 row)
|
||||
|
||||
drop type r1;
|
||||
drop table stu;
|
||||
drop procedure test_proc;
|
||||
-- clean
|
||||
drop schema plpgsql_recompile_new cascade;
|
||||
drop schema plpgsql_recompile cascade;
|
||||
NOTICE: drop cascades to 7 other objects
|
||||
--?.*
|
||||
DETAIL: drop cascades to type s_type
|
||||
drop cascades to function type_alter(s_type)
|
||||
drop cascades to table stu
|
||||
drop cascades to type r1
|
||||
drop cascades to function test_subtype_proc()
|
||||
--?.*
|
||||
drop cascades to function plpgsql_recompile.proc1(s_type)
|
||||
|
||||
@ -203,6 +203,60 @@ call pkg.proc1((1,'zhang','M',1,2,3));
|
||||
alter package pkg compile;
|
||||
call pkg.proc1((1,'zhang','M',1,2,3));
|
||||
|
||||
-- test 6
|
||||
drop type if exists r1;
|
||||
drop table if exists stu;
|
||||
create table stu(sno int, name varchar, sex varchar, cno int);
|
||||
create type r1 as (a int, c stu%RowType);
|
||||
create schema plpgsql_recompile_new;
|
||||
|
||||
create or replace procedure test_proc(p_in r1)
|
||||
is
|
||||
declare
|
||||
v1 stu%RowType;
|
||||
begin
|
||||
RAISE INFO 'call p_in: %', p_in;
|
||||
end;
|
||||
/
|
||||
call test_proc((1,(1,'zhang','M',1)));
|
||||
|
||||
-- rename report error
|
||||
ALTER TYPE r1 RENAME to r1_rename;
|
||||
ALTER TYPE r1 RENAME ATTRIBUTE a TO new_a;
|
||||
ALTER TABLE stu RENAME TO stu_rename;
|
||||
ALTER TABLE stu RENAME COLUMN cno TO new_cno;
|
||||
ALTER PROCEDURE test_proc(r1) RENAME TO test_proc_rename;
|
||||
ALTER SCHEMA plpgsql_recompile RENAME TO plpgsql_recompile_rename;
|
||||
call test_proc((1.0,(1,'zhang','M',1)));
|
||||
|
||||
-- set schema report error
|
||||
ALTER TYPE r1 SET SCHEMA plpgsql_recompile_new;
|
||||
ALTER TABLE stu SET SCHEMA plpgsql_recompile_new;
|
||||
ALTER PROCEDURE test_proc(r1) SET SCHEMA plpgsql_recompile_new;
|
||||
call test_proc((1.0,(1,'zhang','M',1)));
|
||||
|
||||
-- drop and recreate
|
||||
drop type r1;
|
||||
drop table stu;
|
||||
drop procedure test_proc;
|
||||
|
||||
create table stu(sno int, name varchar, sex varchar, cno int);
|
||||
create type r1 as (a int, c stu%RowType);
|
||||
create or replace procedure test_proc(p_in r1)
|
||||
is
|
||||
declare
|
||||
v1 stu%RowType;
|
||||
begin
|
||||
RAISE INFO 'call p_in: %', p_in;
|
||||
end;
|
||||
/
|
||||
call test_proc((1,(1,'zhang','M',1)));
|
||||
|
||||
drop type r1;
|
||||
drop table stu;
|
||||
drop procedure test_proc;
|
||||
|
||||
-- clean
|
||||
drop schema plpgsql_recompile_new cascade;
|
||||
drop schema plpgsql_recompile cascade;
|
||||
reset behavior_compat_options;
|
||||
|
||||
Reference in New Issue
Block a user