This is an automated email from the ASF dual-hosted git repository.

maxyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 47f626c6cc7fc6a7dd320e0c170f133a33b69952
Author: Zhang Mingli <[email protected]>
AuthorDate: Mon Nov 25 15:36:39 2024 +0800

    Avoid REFREH fast path if matview has foreign tables.
    
    For matview has foreign tables, we never know the data
    status.
    Since we usually create a matview has read external tables,
    the initial data status is Up-to-date.
    That will make REFRESH fail to do the real thing with
    fast path feature, the worst case is we never try to get
    the external data during REFRESH.
    
    Authored-by: Zhang Mingli [email protected]
---
 src/backend/catalog/gp_matview_aux.c | 23 ++++++++++++++++--
 src/backend/commands/matview.c       |  3 ++-
 src/include/catalog/gp_matview_aux.h |  5 +++-
 src/test/regress/expected/aqumv.out  | 46 ++++++++++++++++++++++++++++++++++++
 src/test/regress/sql/aqumv.sql       |  7 ++++++
 5 files changed, 80 insertions(+), 4 deletions(-)

diff --git a/src/backend/catalog/gp_matview_aux.c 
b/src/backend/catalog/gp_matview_aux.c
index 3a3c1a0659..a43bd27cd4 100644
--- a/src/backend/catalog/gp_matview_aux.c
+++ b/src/backend/catalog/gp_matview_aux.c
@@ -50,7 +50,7 @@ static void SetMatviewAuxStatus_guts(Oid mvoid, char status);
  * Return NIL if the query we think it's useless.
  */
 List*
-GetViewBaseRelids(const Query *viewQuery)
+GetViewBaseRelids(const Query *viewQuery, bool *has_foreign)
 {
        List    *relids = NIL;
        Node    *mvjtnode;
@@ -100,6 +100,9 @@ GetViewBaseRelids(const Query *viewQuery)
                relkind != RELKIND_FOREIGN_TABLE)
                return NIL;
 
+       if (has_foreign)
+               *has_foreign = relkind == RELKIND_FOREIGN_TABLE;
+
        /*
         * inherit tables are not supported.
         * FIXME: left a door for partition table which will be supported soon.
@@ -140,11 +143,12 @@ InsertMatviewAuxEntry(Oid mvoid, const Query *viewQuery, 
bool skipdata)
        Datum           values[Natts_gp_matview_aux];
        List            *relids;
        NameData        mvname;
+       bool            has_foreign = false;
 
        Assert(OidIsValid(mvoid));
 
        /* Empty relids means the view is not supported now. */
-       relids = GetViewBaseRelids(viewQuery);
+       relids = GetViewBaseRelids(viewQuery, &has_foreign);
        if (relids == NIL)
                return;
        
@@ -157,6 +161,8 @@ InsertMatviewAuxEntry(Oid mvoid, const Query *viewQuery, 
bool skipdata)
 
        namestrcpy(&mvname, get_rel_name(mvoid));
        values[Anum_gp_matview_aux_mvname - 1] = NameGetDatum(&mvname);
+
+       values[Anum_gp_matview_aux_has_foreign - 1] = BoolGetDatum(has_foreign);
        
        if (skipdata)
                values[Anum_gp_matview_aux_datastatus - 1] = 
CharGetDatum(MV_DATA_STATUS_EXPIRED);
@@ -449,6 +455,19 @@ MatviewUsableForAppendAgg(Oid mvoid)
                        (auxform->datastatus == 
MV_DATA_STATUS_EXPIRED_INSERT_ONLY));
 }
 
+bool
+MatviewHasForeignTables(Oid mvoid)
+{
+       HeapTuple mvauxtup = SearchSysCacheCopy1(MVAUXOID, 
ObjectIdGetDatum(mvoid));
+
+       /* Not a candidate we recorded. */
+       if (!HeapTupleIsValid(mvauxtup))
+               return false;
+
+       Form_gp_matview_aux auxform = (Form_gp_matview_aux) GETSTRUCT(mvauxtup);
+       return auxform->has_foreign;
+}
+
 /*
  * Is the view data up to date?
  * In most cases, we should use this function to check if view
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 3d814f501e..8b14f1c9f5 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -482,7 +482,8 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char 
*queryString,
        if (gp_enable_refresh_fast_path &&
                !RelationIsIVM(matviewRel) &&
                !stmt->skipData &&
-               MatviewIsUpToDate(matviewOid))
+               MatviewIsUpToDate(matviewOid) &&
+               !MatviewHasForeignTables(matviewOid))
        {
                table_close(matviewRel, NoLock);
 
diff --git a/src/include/catalog/gp_matview_aux.h 
b/src/include/catalog/gp_matview_aux.h
index 21e714075d..febd951375 100644
--- a/src/include/catalog/gp_matview_aux.h
+++ b/src/include/catalog/gp_matview_aux.h
@@ -27,6 +27,7 @@ CATALOG(gp_matview_aux,7153,GpMatviewAuxId) 
BKI_SHARED_RELATION
 {
        Oid                     mvoid;  /* materialized view oid */
        NameData        mvname; /* materialized view name */
+       bool            has_foreign;    /* view query has foreign tables? */
        /* view's data status */
        char            datastatus; 
 } FormData_gp_matview_aux;
@@ -57,12 +58,14 @@ extern void InsertMatviewAuxEntry(Oid mvoid, const Query 
*viewQuery, bool skipda
 
 extern void RemoveMatviewAuxEntry(Oid mvoid);
 
-extern List* GetViewBaseRelids(const Query *viewQuery);
+extern List* GetViewBaseRelids(const Query *viewQuery, bool *has_foreign);
 
 extern void SetRelativeMatviewAuxStatus(Oid relid, char status);
 
 extern void SetMatviewAuxStatus(Oid mvoid, char status);
 
+extern bool MatviewHasForeignTables(Oid mvoid);
+
 extern bool MatviewUsableForAppendAgg(Oid mvoid);
 
 extern bool MatviewIsGeneralyUpToDate(Oid mvoid);
diff --git a/src/test/regress/expected/aqumv.out 
b/src/test/regress/expected/aqumv.out
index 552a477868..ba4772e826 100644
--- a/src/test/regress/expected/aqumv.out
+++ b/src/test/regress/expected/aqumv.out
@@ -2682,6 +2682,52 @@ select * from aqumv_ext_r where id = 5;
   5
 (1 row)
 
+-- refresh matview has foreign tables should not go fast path. 
+select * from aqumv_ext_mv;
+ id 
+----
+  5
+  6
+  9
+ 10
+  2
+  3
+  4
+  7
+  8
+  1
+(10 rows)
+
+INSERT INTO aqumv_ext_w SELECT * FROM generate_series(10, 15);
+set local gp_enable_refresh_fast_path = on;
+select datastatus from gp_matview_aux where mvoid = 
'aqumv_ext_mv'::regclass::oid;
+ datastatus 
+------------
+ u
+(1 row)
+
+refresh materialized view aqumv_ext_mv;
+select * from aqumv_ext_mv;
+ id 
+----
+  2
+  3
+  4
+  7
+  8
+  1
+ 12
+ 15
+  5
+  6
+  9
+ 10
+ 10
+ 11
+ 13
+ 14
+(16 rows)
+
 abort;
 --
 -- End of test external table
diff --git a/src/test/regress/sql/aqumv.sql b/src/test/regress/sql/aqumv.sql
index 6fe1973355..8fee68f311 100644
--- a/src/test/regress/sql/aqumv.sql
+++ b/src/test/regress/sql/aqumv.sql
@@ -669,6 +669,13 @@ explain (costs off, verbose)
 select * from aqumv_ext_r where id = 5;
 select * from aqumv_ext_r where id = 5;
 
+-- refresh matview has foreign tables should not go fast path. 
+select * from aqumv_ext_mv;
+INSERT INTO aqumv_ext_w SELECT * FROM generate_series(10, 15);
+set local gp_enable_refresh_fast_path = on;
+select datastatus from gp_matview_aux where mvoid = 
'aqumv_ext_mv'::regclass::oid;
+refresh materialized view aqumv_ext_mv;
+select * from aqumv_ext_mv;
 abort;
 --
 -- End of test external table


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to