Skip to content

Support for weak binding views to allow dropping of underlying objects #585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: BABEL_5_X_DEV__PG_17_X
Choose a base branch
from
Open
8 changes: 8 additions & 0 deletions src/backend/commands/dropcmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "commands/defrem.h"
#include "commands/tablecmds.h"
#include "miscadmin.h"
#include "parser/parser.h"
#include "parser/parse_type.h"
Expand Down Expand Up @@ -131,6 +132,13 @@ RemoveObjects(DropStmt *stmt)
table_close(relation, NoLock);

add_exact_object_address(&address, objects);

/* Check for strong views and handle weak views */
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not move the open table into the hook implement ?

if ((stmt->removeType == OBJECT_FUNCTION) && view_dependency_hook)
{
if (!(*view_dependency_hook)(&address, NULL, NULL))
continue;
}
Comment on lines +137 to +141
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make the hook generic and add all TSQL related check within the hook function. We're not worried about hook overhead in a DDL execution. Also, there's already a hook for this task - InvokeObjectDropHook. Let's plugin this hook here.

}

/* Here we really delete them. */
Expand Down
8 changes: 8 additions & 0 deletions src/backend/commands/tablecmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ InvokePreDropColumnHook_type InvokePreDropColumnHook = NULL;
check_extended_attoptions_hook_type check_extended_attoptions_hook = NULL;
find_attr_by_name_from_column_def_list_hook_type
find_attr_by_name_from_column_def_list_hook = NULL;
view_dependency_hook_type view_dependency_hook = NULL;

/*
* State information for ALTER TABLE
Expand Down Expand Up @@ -1676,6 +1677,13 @@ RemoveRelations(DropStmt *drop)
{
InvokeObjectDropHook(RelationRelationId,relOid,0);
}

/* Check for strong views and handle weak views */
if ((drop->removeType == OBJECT_TABLE || drop->removeType == OBJECT_VIEW) && view_dependency_hook)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move this part also into the hook : (drop->removeType == OBJECT_TABLE || drop->removeType == OBJECT_VIEW) ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use InvokeObjectDropHook which already there in the function.

{
if (!(*view_dependency_hook)(&obj, NULL, NULL))
continue;
}
Comment on lines +1680 to +1686
Copy link
Contributor

Choose a reason for hiding this comment

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

Let us move all comments and conditions inside the hook. Also would naming it pre_drop_object_hook make sense ?

}

performMultipleDeletions(objects, drop->behavior, flags);
Expand Down
6 changes: 6 additions & 0 deletions src/backend/commands/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "parser/analyze.h"
#include "parser/parser.h"
#include "parser/parse_relation.h"
#include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteHandler.h"
Expand All @@ -36,6 +37,8 @@ static void checkViewColumns(TupleDesc newdesc, TupleDesc olddesc);

inherit_view_constraints_from_table_hook_type inherit_view_constraints_from_table_hook = NULL;

check_view_dependencies_hook_type check_view_dependencies_hook = NULL;

/*---------------------------------------------------------------------
* DefineVirtualRelation
*
Expand Down Expand Up @@ -381,6 +384,9 @@ DefineView(ViewStmt *stmt, const char *queryString,

viewParse = parse_analyze_fixedparams(rawstmt, queryString, NULL, 0, NULL);

if (check_view_dependencies_hook)
(*check_view_dependencies_hook)(viewParse);

Comment on lines +387 to +389
Copy link
Contributor

Choose a reason for hiding this comment

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

The function parse_analyze_fixedparams already has a hook inside it - post_parse_analyze_hook(). Let's use that.

/*
* The grammar should ensure that the result is a single SELECT Query.
* However, it doesn't forbid SELECT INTO, so we have to check for that.
Expand Down
10 changes: 9 additions & 1 deletion src/backend/rewrite/rewriteHandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "utils/rel.h"

bbfViewHasInsteadofTrigger_hook_type bbfViewHasInsteadofTrigger_hook = NULL; /** BBF Hook to check Instead Of trigger on View */
view_repair_hook_type view_repair_hook = NULL;

/* We use a list of these to detect recursion in RewriteQuery */
typedef struct rewrite_event
Expand Down Expand Up @@ -4403,7 +4404,6 @@ RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length)
return rewritten;
}


/*
* QueryRewrite -
* Primary entry point to the query rewriter.
Expand Down Expand Up @@ -4431,6 +4431,14 @@ QueryRewrite(Query *parsetree)
Assert(parsetree->canSetTag);

/*
* Step 0 (Babelfish extension)
*
* If this is a view with broken rules, try to repair it
* using the definition from babelfish_view_def
*/
if (view_repair_hook)
(*view_repair_hook)(parsetree);
/*
Comment on lines +4434 to +4441
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we use a more generic name. pre_query_rewrite_hook

Copy link
Contributor

Choose a reason for hiding this comment

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

+1
Let's use the name pre_QueryRewrite_hook.

* Step 1
*
* Apply all non-SELECT rules possibly getting 0 or many queries
Expand Down
17 changes: 14 additions & 3 deletions src/bin/pg_dump/pg_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ static void setupDumpWorker(Archive *AH);
static TableInfo *getRootTableInfo(const TableInfo *tbinfo);
static bool forcePartitionRootLoad(const TableInfo *tbinfo);
static void read_dump_filters(const char *filename, DumpOptions *dopt);

static PQExpBuffer createDummyViewAsClause(Archive *fout, const TableInfo *tbinfo);

int
main(int argc, char **argv)
Expand Down Expand Up @@ -15856,8 +15856,19 @@ createViewAsClause(Archive *fout, const TableInfo *tbinfo)
len = PQgetlength(res, 0, 0);

if (len == 0)
pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
tbinfo->dobj.name);
{
/*
* Handle broken views (with empty definitions)
* Instead of failing, create a dummy SELECT that preserves the structure
*/
PQclear(res);
destroyPQExpBuffer(query);

/* Use createDummyViewAsClause to generate a compatible structure */
result = createDummyViewAsClause(fout, tbinfo);

return result;
}
Comment on lines -15859 to +15871
Copy link
Contributor

Choose a reason for hiding this comment

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

Whenever we modify in pg_dump, we make sure that this is a Babelfish Database. Check the functions with bbf prefix. Ideally, the logic should be,

if (bbfShouldDumpViews(Archive *fout, const TableInfo *tbinfo))
{
    createTSQLViewAsClause()
    return;
}

Within createTSQLViewAsClause, we should do all the handlings.


/* Strip off the trailing semicolon so that other things may follow. */
Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
Expand Down
4 changes: 4 additions & 0 deletions src/include/commands/tablecmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,8 @@ typedef int (*find_attr_by_name_from_column_def_list_hook_type) (
extern PGDLLEXPORT find_attr_by_name_from_column_def_list_hook_type
find_attr_by_name_from_column_def_list_hook;

/* Hook for handling view dependencies during table drops */
typedef bool (*view_dependency_hook_type) (const ObjectAddress *droppedObject, Relation depRel, ViewStmt *viewstmt);
extern PGDLLIMPORT view_dependency_hook_type view_dependency_hook;

#endif /* TABLECMDS_H */
3 changes: 3 additions & 0 deletions src/include/commands/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ extern PGDLLEXPORT store_view_definition_hook_type store_view_definition_hook;

typedef void (*inherit_view_constraints_from_table_hook_type) (ColumnDef *col, Oid tableOid, AttrNumber colId);
extern PGDLLEXPORT inherit_view_constraints_from_table_hook_type inherit_view_constraints_from_table_hook;

typedef bool (*check_view_dependencies_hook_type) (Query *viewParse);
extern check_view_dependencies_hook_type check_view_dependencies_hook;
#endif /* VIEW_H */
4 changes: 4 additions & 0 deletions src/include/rewrite/rewriteHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,8 @@ extern void error_view_not_updatable(Relation view,
List *mergeActionList,
const char *detail);

/* View repair hook */
typedef bool (*view_repair_hook_type) (Query *parsetree);
extern PGDLLEXPORT view_repair_hook_type view_repair_hook;

#endif /* REWRITEHANDLER_H */