Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions contrib/ivorysql_ora/src/sysview/sysview--1.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1088,4 +1088,107 @@ SELECT
decode(bitand(s.flags, 64), 64, 'Y', 'N') AS session_flag,null AS keep_value
FROM PG_SEQUENCE s,pg_class c where s.seqrelid = c.oid and c.relowner::regrole = current_user::regrole;

CREATE OR REPLACE VIEW SYS.DBA_VIEWS AS
SELECT
SYS.ORA_CASE_TRANS(
PG_GET_USERBYID(C.RELOWNER)::VARCHAR2
)::VARCHAR2(128) AS OWNER,
SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS VIEW_NAME,
LENGTH(pg_get_viewdef(C.OID))::NUMBER(38) AS TEXT_LENGTH,
SYS.ORA_CASE_TRANS(pg_get_viewdef(C.OID)::VARCHAR2)::TEXT AS TEXT,
SYS.ORA_CASE_TRANS(pg_get_viewdef(C.OID)::VARCHAR2)::VARCHAR2(4000) AS TEXT_VC,
NULL::NUMBER(38) AS TYPE_TEXT_LENGTH,
NULL::VARCHAR2(4000) AS TYPE_TEXT,
NULL::NUMBER(38) AS OID_TEXT_LENGTH,
NULL::VARCHAR2(4000) AS OID_TEXT,
NULL::VARCHAR2(128) AS VIEW_TYPE_OWNER,
NULL::VARCHAR2(128) AS VIEW_TYPE,
NULL::VARCHAR2(128) AS SUPERVIEW_NAME,
NULL::VARCHAR2(1) AS EDITIONING_VIEW,
NULL::VARCHAR2(1) AS READ_ONLY,
NULL::VARCHAR2(1) AS CONTAINER_DATA,
NULL::VARCHAR2(12) AS BEQUEATH,
0::VARCHAR2(256) AS ORIGIN_CON_ID,
NULL::VARCHAR2(100) AS DEFAULT_COLLATION,
NULL::VARCHAR2(3) AS CONTAINERS_DEFAULT,
NULL::VARCHAR2(3) AS CONTAINER_MAP,
NULL::VARCHAR2(3) AS EXTENDED_DATA_LINK,
NULL::VARCHAR2(3) AS EXTENDED_DATA_LINK_MAP,
NULL::VARCHAR2(3) AS HAS_SENSITIVE_COLUMN,
NULL::VARCHAR2(3) AS ADMIT_NULL,
NULL::VARCHAR2(3) AS PDB_LOCAL_ONLY
FROM
PG_CLASS AS C
WHERE
C.RELKIND = 'v';
GRANT SELECT ON SYS.DBA_VIEWS TO PUBLIC;

CREATE OR REPLACE VIEW SYS.ALL_VIEWS AS
SELECT
SYS.ORA_CASE_TRANS(
PG_GET_USERBYID(C.RELOWNER)::VARCHAR2
)::VARCHAR2(128) AS OWNER,
SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS VIEW_NAME,
LENGTH(pg_get_viewdef(C.OID))::NUMBER(38) AS TEXT_LENGTH,
SYS.ORA_CASE_TRANS(pg_get_viewdef(C.OID)::VARCHAR2)::TEXT AS TEXT,
SYS.ORA_CASE_TRANS(pg_get_viewdef(C.OID)::VARCHAR2)::VARCHAR2(4000) AS TEXT_VC,
NULL::NUMBER(38) AS TYPE_TEXT_LENGTH,
NULL::VARCHAR2(4000) AS TYPE_TEXT,
NULL::NUMBER(38) AS OID_TEXT_LENGTH,
NULL::VARCHAR2(4000) AS OID_TEXT,
NULL::VARCHAR2(128) AS VIEW_TYPE_OWNER,
NULL::VARCHAR2(128) AS VIEW_TYPE,
NULL::VARCHAR2(128) AS SUPERVIEW_NAME,
NULL::VARCHAR2(1) AS EDITIONING_VIEW,
NULL::VARCHAR2(1) AS READ_ONLY,
NULL::VARCHAR2(1) AS CONTAINER_DATA,
NULL::VARCHAR2(12) AS BEQUEATH,
0::VARCHAR2(256) AS ORIGIN_CON_ID,
NULL::VARCHAR2(100) AS DEFAULT_COLLATION,
NULL::VARCHAR2(3) AS CONTAINERS_DEFAULT,
NULL::VARCHAR2(3) AS CONTAINER_MAP,
NULL::VARCHAR2(3) AS EXTENDED_DATA_LINK,
NULL::VARCHAR2(3) AS EXTENDED_DATA_LINK_MAP,
NULL::VARCHAR2(3) AS HAS_SENSITIVE_COLUMN,
NULL::VARCHAR2(3) AS ADMIT_NULL,
NULL::VARCHAR2(3) AS PDB_LOCAL_ONLY
FROM
PG_CLASS AS C
WHERE
C.RELKIND = 'v'
AND HAS_ANY_COLUMN_PRIVILEGE(C.OID, 'SELECT');
GRANT SELECT ON SYS.ALL_VIEWS TO PUBLIC;

CREATE OR REPLACE VIEW SYS.USER_VIEWS AS
SELECT
SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS VIEW_NAME,
LENGTH(pg_get_viewdef(C.OID))::NUMBER(38) AS TEXT_LENGTH,
SYS.ORA_CASE_TRANS(pg_get_viewdef(C.OID)::VARCHAR2)::TEXT AS TEXT,
SYS.ORA_CASE_TRANS(pg_get_viewdef(C.OID)::VARCHAR2)::VARCHAR2(4000) AS TEXT_VC,
NULL::NUMBER(38) AS TYPE_TEXT_LENGTH,
NULL::VARCHAR2(4000) AS TYPE_TEXT,
NULL::NUMBER(38) AS OID_TEXT_LENGTH,
NULL::VARCHAR2(4000) AS OID_TEXT,
NULL::VARCHAR2(128) AS VIEW_TYPE_OWNER,
NULL::VARCHAR2(128) AS VIEW_TYPE,
NULL::VARCHAR2(128) AS SUPERVIEW_NAME,
NULL::VARCHAR2(1) AS EDITIONING_VIEW,
NULL::VARCHAR2(1) AS READ_ONLY,
NULL::VARCHAR2(1) AS CONTAINER_DATA,
NULL::VARCHAR2(12) AS BEQUEATH,
0::VARCHAR2(256) AS ORIGIN_CON_ID,
NULL::VARCHAR2(100) AS DEFAULT_COLLATION,
NULL::VARCHAR2(3) AS CONTAINERS_DEFAULT,
NULL::VARCHAR2(3) AS CONTAINER_MAP,
NULL::VARCHAR2(3) AS EXTENDED_DATA_LINK,
NULL::VARCHAR2(3) AS EXTENDED_DATA_LINK_MAP,
NULL::VARCHAR2(3) AS HAS_SENSITIVE_COLUMN,
NULL::VARCHAR2(3) AS ADMIT_NULL,
NULL::VARCHAR2(3) AS PDB_LOCAL_ONLY
FROM
PG_CLASS AS C
WHERE
C.RELKIND = 'v'
AND PG_GET_USERBYID(C.RELOWNER) = CURRENT_USER;
GRANT SELECT ON SYS.USER_VIEWS TO PUBLIC;

2 changes: 1 addition & 1 deletion contrib/tsm_system_rows/expected/tsm_system_rows.out
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ SELECT * FROM vv;
20
(1 row)

DROP EXTENSION tsm_system_rows; -- fail, view depends on extension
DROP EXTENSION tsm_system_rows; -- fail, view depends on extension ,but success in Oracle because of FORCE VIEW
ERROR: cannot drop extension tsm_system_rows because other objects depend on it
DETAIL: view vv depends on function system_rows(internal)
HINT: Use DROP ... CASCADE to drop the dependent objects too.
5 changes: 1 addition & 4 deletions contrib/tsm_system_rows/expected/tsm_system_rows_1.out
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,4 @@ SELECT * FROM vv;
20
(1 row)

DROP EXTENSION tsm_system_rows; -- fail, view depends on extension
ERROR: cannot drop extension tsm_system_rows because other objects depend on it
DETAIL: view vv depends on function system_rows(internal)
HINT: Use DROP ... CASCADE to drop the dependent objects too.
DROP EXTENSION tsm_system_rows; -- fail, view depends on extension ,but success in Oracle because of FORCE VIEW
2 changes: 1 addition & 1 deletion contrib/tsm_system_rows/sql/tsm_system_rows.sql
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ CREATE VIEW vv AS

SELECT * FROM vv;

DROP EXTENSION tsm_system_rows; -- fail, view depends on extension
DROP EXTENSION tsm_system_rows; -- fail, view depends on extension ,but success in Oracle because of FORCE VIEW
2 changes: 1 addition & 1 deletion contrib/tsm_system_time/expected/tsm_system_time.out
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM vv;
Sampling: system_time ('20'::double precision)
(2 rows)

DROP EXTENSION tsm_system_time; -- fail, view depends on extension
DROP EXTENSION tsm_system_time; -- fail, view depends on extension ,but success in Oracle because of FORCE VIEW
ERROR: cannot drop extension tsm_system_time because other objects depend on it
DETAIL: view vv depends on function system_time(internal)
HINT: Use DROP ... CASCADE to drop the dependent objects too.
5 changes: 1 addition & 4 deletions contrib/tsm_system_time/expected/tsm_system_time_1.out
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,4 @@ EXPLAIN (COSTS OFF) SELECT * FROM vv;
Sampling: system_time ('20'::pg_catalog.float8)
(2 rows)

DROP EXTENSION tsm_system_time; -- fail, view depends on extension
ERROR: cannot drop extension tsm_system_time because other objects depend on it
DETAIL: view vv depends on function system_time(internal)
HINT: Use DROP ... CASCADE to drop the dependent objects too.
DROP EXTENSION tsm_system_time; -- fail, view depends on extension ,but success in Oracle because of FORCE VIEW
2 changes: 1 addition & 1 deletion contrib/tsm_system_time/sql/tsm_system_time.sql
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ CREATE VIEW vv AS

EXPLAIN (COSTS OFF) SELECT * FROM vv;

DROP EXTENSION tsm_system_time; -- fail, view depends on extension
DROP EXTENSION tsm_system_time; -- fail, view depends on extension ,but success in Oracle because of FORCE VIEW
148 changes: 141 additions & 7 deletions src/backend/catalog/dependency.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@
#include "commands/sequence.h"
#include "commands/trigger.h"
#include "commands/typecmds.h"
#include "commands/tablecmds.h"
#include "commands/view.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
Expand All @@ -89,9 +91,9 @@
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/packagecache.h"
#include "commands/tablecmds.h"
#include "funcapi.h"
#include "lib/qunique.h"
#include "utils/ora_compatible.h"
#include "utils/guc.h"



Expand Down Expand Up @@ -162,7 +164,8 @@ static void findDependentObjects(const ObjectAddress *object,
static void reportDependentObjects(const ObjectAddresses *targetObjects,
DropBehavior behavior,
int flags,
const ObjectAddress *origObject);
const ObjectAddress *origObject,
bool *refinddepobjects);
static void deleteOneObject(const ObjectAddress *object,
Relation *depRel, int32 flags);
static void doDeletion(const ObjectAddress *object, int flags);
Expand Down Expand Up @@ -284,6 +287,7 @@ performDeletion(const ObjectAddress *object,
{
Relation depRel;
ObjectAddresses *targetObjects;
bool need_refinddepobj = false;

/*
* We save some cycles by opening pg_depend just once and passing the
Expand Down Expand Up @@ -317,7 +321,22 @@ performDeletion(const ObjectAddress *object,
reportDependentObjects(targetObjects,
behavior,
flags,
object);
object,
&need_refinddepobj);

if (ORA_PARSER == compatible_db && need_refinddepobj)
{
free_object_addresses(targetObjects);
targetObjects = new_object_addresses();

findDependentObjects(object,
DEPFLAG_ORIGINAL,
flags,
NULL, /* empty stack */
targetObjects,
NULL, /* no pendingObjects */
&depRel);
}

/* do the deed */
deleteObjectsInList(targetObjects, &depRel, flags);
Expand All @@ -344,6 +363,7 @@ performMultipleDeletions(const ObjectAddresses *objects,
Relation depRel;
ObjectAddresses *targetObjects;
int i;
bool need_refinddepobj = false;

/* No work if no objects... */
if (objects->numrefs <= 0)
Expand Down Expand Up @@ -393,7 +413,33 @@ performMultipleDeletions(const ObjectAddresses *objects,
reportDependentObjects(targetObjects,
behavior,
flags,
(objects->numrefs == 1 ? objects->refs : NULL));
(objects->numrefs == 1 ? objects->refs : NULL),
&need_refinddepobj);


if (ORA_PARSER == compatible_db && need_refinddepobj)
{
free_object_addresses(targetObjects);
targetObjects = new_object_addresses();

for (i = 0; i < objects->numrefs; i++)
{
const ObjectAddress *thisobj = objects->refs + i;

/*
* Obtain a deletion lock for every target object. (Preferably, this should have been handled by the caller, but in reality, many callers neglect to do so.)
*/
AcquireDeletionLock(thisobj, flags);

findDependentObjects(thisobj,
DEPFLAG_ORIGINAL,
flags,
NULL, /* empty stack */
targetObjects,
objects,
&depRel);
}
}

/* do the deed */
deleteObjectsInList(targetObjects, &depRel, flags);
Expand Down Expand Up @@ -1065,7 +1111,7 @@ findDependentObjects(const ObjectAddress *object,
}

/*
* Find out the dependent funciton which uses %TYPE or %ROWTYPE
* Find out the dependent funciton which uses %TYPE or %ROWTYPE
* in parameters datatype or return datatype.
*/
for (int i = 0; i < numDependentFuncPkgOids; i++)
Expand Down Expand Up @@ -1171,7 +1217,8 @@ static void
reportDependentObjects(const ObjectAddresses *targetObjects,
DropBehavior behavior,
int flags,
const ObjectAddress *origObject)
const ObjectAddress *origObject,
bool *refinddepobj)
{
int msglevel = (flags & PERFORM_DELETION_QUIETLY) ? DEBUG2 : NOTICE;
bool ok = true;
Expand Down Expand Up @@ -1219,6 +1266,89 @@ reportDependentObjects(const ObjectAddresses *targetObjects,
!message_level_is_interesting(msglevel))
return;

if (ORA_PARSER == compatible_db && behavior == DROP_RESTRICT)
{
/* Check if all dependencies that require CASCADE are views */
bool all_cascade_dep_is_view = true;
ObjectAddresses *viewObjects;

viewObjects = new_object_addresses();

for (i = targetObjects->numrefs - 1; i >= 0; i--)
{
const ObjectAddress *obj = &targetObjects->refs[i];
const ObjectAddressExtra *extra = &targetObjects->extras[i];
char *objDesc;

/* Skip the initial objects requested for deletion */
if (extra->flags & DEPFLAG_ORIGINAL)
continue;

/* Skip reporting for subcomponents, handled elsewhere */
if (extra->flags & DEPFLAG_SUBOBJECT)
continue;

objDesc = getObjectDescription(obj, false);

/* Ignore objects that are being dropped concurrently */
if (objDesc == NULL)
continue;

/*
* If the object was found via an automatic, internal, partition, or extension dependency,
* it is permitted to be removed even with RESTRICT.
*/
if (extra->flags & (DEPFLAG_AUTO |
DEPFLAG_INTERNAL |
DEPFLAG_PARTITION |
DEPFLAG_EXTENSION))
{
/*
* Log automatic cascades at DEBUG2 level for clarity.
*/
ereport(DEBUG2,
(errmsg_internal("drop auto-cascades to %s",
objDesc)));
}
else if (extra->flags & DEPFLAG_TYPE)
{
pfree(objDesc);
continue;
}
else
{
/* If any dependent object is not a view, set flag and exit loop */
if (get_rel_relkind(obj->objectId) != RELKIND_VIEW)
{
all_cascade_dep_is_view = false;
pfree(objDesc);
break;
}
else
add_exact_object_address(obj, viewObjects);
}
pfree(objDesc);
}

/* If all dependencies are views, mark them as invalid and trigger a recheck */
if (all_cascade_dep_is_view && viewObjects->numrefs > 0)
{
for (i = viewObjects->numrefs - 1; i >= 0; i--)
{
make_view_invalid(viewObjects->refs[i].objectId);
}

/*
* After invalidating views, re-evaluate dependencies to ensure consistency.
*/
if (refinddepobj)
*refinddepobj = true;
return;
}

free_object_addresses(viewObjects);
}
Comment on lines +1269 to +1350
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

RESTRICT path invalidation: free viewObjects on early return and guard relkind checks.

  • Leak: viewObjects is not freed on the early return path.
  • Minor: call get_rel_relkind() only for RelationRelationId objects.
-       if (all_cascade_dep_is_view && viewObjects->numrefs > 0)
+       if (all_cascade_dep_is_view && viewObjects->numrefs > 0)
        {
            for (i = viewObjects->numrefs - 1; i >= 0; i--)
            {
                make_view_invalid(viewObjects->refs[i].objectId);
            }
            /*
             * After invalidating views, re-evaluate dependencies to ensure consistency.
             */
            if (refinddepobj)
                *refinddepobj = true;
-           return;
+           free_object_addresses(viewObjects);
+           return;
        }
...
-           /*
-            * If any dependent object is not a view, set flag and exit loop
-            */
-           if (get_rel_relkind(obj->objectId) != RELKIND_VIEW)
+           /* Only relations can be views; otherwise, fail the "all views" test */
+           if (obj->classId != RelationRelationId ||
+               get_rel_relkind(obj->objectId) != RELKIND_VIEW)
            {
                all_cascade_dep_is_view = false;
                pfree(objDesc);
                break;
            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (ORA_PARSER == compatible_db && behavior == DROP_RESTRICT)
{
/* Check if all dependencies that require CASCADE are views */
bool all_cascade_dep_is_view = true;
ObjectAddresses *viewObjects;
viewObjects = new_object_addresses();
for (i = targetObjects->numrefs - 1; i >= 0; i--)
{
const ObjectAddress *obj = &targetObjects->refs[i];
const ObjectAddressExtra *extra = &targetObjects->extras[i];
char *objDesc;
/* Skip the initial objects requested for deletion */
if (extra->flags & DEPFLAG_ORIGINAL)
continue;
/* Skip reporting for subcomponents, handled elsewhere */
if (extra->flags & DEPFLAG_SUBOBJECT)
continue;
objDesc = getObjectDescription(obj, false);
/* Ignore objects that are being dropped concurrently */
if (objDesc == NULL)
continue;
/*
* If the object was found via an automatic, internal, partition, or extension dependency,
* it is permitted to be removed even with RESTRICT.
*/
if (extra->flags & (DEPFLAG_AUTO |
DEPFLAG_INTERNAL |
DEPFLAG_PARTITION |
DEPFLAG_EXTENSION))
{
/*
* Log automatic cascades at DEBUG2 level for clarity.
*/
ereport(DEBUG2,
(errmsg_internal("drop auto-cascades to %s",
objDesc)));
}
else if (extra->flags & DEPFLAG_TYPE)
{
pfree(objDesc);
continue;
}
else
{
/* If any dependent object is not a view, set flag and exit loop */
if (get_rel_relkind(obj->objectId) != RELKIND_VIEW)
{
all_cascade_dep_is_view = false;
pfree(objDesc);
break;
}
else
add_exact_object_address(obj, viewObjects);
}
pfree(objDesc);
}
/* If all dependencies are views, mark them as invalid and trigger a recheck */
if (all_cascade_dep_is_view && viewObjects->numrefs > 0)
{
for (i = viewObjects->numrefs - 1; i >= 0; i--)
{
make_view_invalid(viewObjects->refs[i].objectId);
}
/*
* After invalidating views, re-evaluate dependencies to ensure consistency.
*/
if (refinddepobj)
*refinddepobj = true;
return;
}
free_object_addresses(viewObjects);
}
if (ORA_PARSER == compatible_db && behavior == DROP_RESTRICT)
{
/* Check if all dependencies that require CASCADE are views */
bool all_cascade_dep_is_view = true;
ObjectAddresses *viewObjects;
viewObjects = new_object_addresses();
for (i = targetObjects->numrefs - 1; i >= 0; i--)
{
const ObjectAddress *obj = &targetObjects->refs[i];
const ObjectAddressExtra *extra = &targetObjects->extras[i];
char *objDesc;
/* Skip the initial objects requested for deletion */
if (extra->flags & DEPFLAG_ORIGINAL)
continue;
/* Skip reporting for subcomponents, handled elsewhere */
if (extra->flags & DEPFLAG_SUBOBJECT)
continue;
objDesc = getObjectDescription(obj, false);
/* Ignore objects that are being dropped concurrently */
if (objDesc == NULL)
continue;
/*
* If the object was found via an automatic, internal, partition, or extension dependency,
* it is permitted to be removed even with RESTRICT.
*/
if (extra->flags & (DEPFLAG_AUTO |
DEPFLAG_INTERNAL |
DEPFLAG_PARTITION |
DEPFLAG_EXTENSION))
{
/*
* Log automatic cascades at DEBUG2 level for clarity.
*/
ereport(DEBUG2,
(errmsg_internal("drop auto-cascades to %s",
objDesc)));
}
else if (extra->flags & DEPFLAG_TYPE)
{
pfree(objDesc);
continue;
}
else
{
/* Only relations can be views; otherwise, fail the "all views" test */
if (obj->classId != RelationRelationId ||
get_rel_relkind(obj->objectId) != RELKIND_VIEW)
{
all_cascade_dep_is_view = false;
pfree(objDesc);
break;
}
else
add_exact_object_address(obj, viewObjects);
}
pfree(objDesc);
}
/* If all dependencies are views, mark them as invalid and trigger a recheck */
if (all_cascade_dep_is_view && viewObjects->numrefs > 0)
{
for (i = viewObjects->numrefs - 1; i >= 0; i--)
{
make_view_invalid(viewObjects->refs[i].objectId);
}
/*
* After invalidating views, re-evaluate dependencies to ensure consistency.
*/
if (refinddepobj)
*refinddepobj = true;
free_object_addresses(viewObjects);
return;
}
free_object_addresses(viewObjects);
}
🤖 Prompt for AI Agents
In src/backend/catalog/dependency.c around lines 1269-1350, free viewObjects
before the early return and avoid calling get_rel_relkind() for non-relation
objects: free_object_addresses(viewObjects) right before returning when
all_cascade_dep_is_view is true; and change the relkind check to first verify
obj->classId == RelationRelationId and only call get_rel_relkind(obj->objectId)
in that case (treat non-relation objects as "not a view" so you set
all_cascade_dep_is_view = false and break).


/*
* We limit the number of dependencies reported to the client to
* MAX_REPORTED_DEPS, since client software may not deal well with
Expand Down Expand Up @@ -1577,6 +1707,10 @@ doDeletion(const ObjectAddress *object, int flags)
*/
if (relKind == RELKIND_SEQUENCE)
DeleteSequenceTuple(object->objectId);

if (ORA_PARSER == compatible_db && relKind == RELKIND_VIEW)
DeleteForceView(object->objectId);

break;
}

Expand Down
Loading