Copilot commented on code in PR #11189:
URL: https://github.com/apache/gravitino/pull/11189#discussion_r3280829289


##########
flink-connector/flink-common/src/main/java/org/apache/gravitino/flink/connector/catalog/BaseCatalog.java:
##########
@@ -261,16 +327,28 @@ public void renameTable(ObjectPath tablePath, String 
newTableName, boolean ignor
 
     if (catalog().asTableCatalog().tableExists(identifier)) {

Review Comment:
   The pre-check for rename conflicts only calls 
`catalog().asTableCatalog().tableExists(...)`. If the rename target is an 
existing *view* (in catalogs where views are not surfaced as tables), this 
method will miss the conflict and proceed. Consider also checking 
`catalog().asViewCatalog().viewExists(...)` (handling 
`UnsupportedOperationException`) before attempting the rename, and throwing 
`TableAlreadyExistException` when it’s taken.
   



##########
flink-connector/flink-common/src/test/java/org/apache/gravitino/flink/connector/catalog/TestBaseCatalog.java:
##########
@@ -136,33 +150,170 @@ public void testToGravitinoDistributionDefaultsToNone() {
   }
 
   @Test
-  public void testListViewsReturnsEmptyWithoutDelegation() throws Exception {
-    AbstractCatalog delegate = Mockito.mock(AbstractCatalog.class);
-    BaseCatalog catalog = new TestableBaseCatalog(delegate);
+  public void testListViewsReturnsEmptyWhenViewCatalogUnsupported() throws 
Exception {
+    Catalog gravitinoCatalog = mockUnsupportedViewCatalog();
+    BaseCatalog catalog =
+        new TestableBaseCatalog(Mockito.mock(AbstractCatalog.class), 
gravitinoCatalog);
 
     List<String> views = catalog.listViews("db");
 
     Assertions.assertTrue(views.isEmpty());
-    Mockito.verifyNoInteractions(delegate);
+  }
+
+  @Test
+  public void testListViewsDelegatesToViewCatalog() throws Exception {
+    ViewCatalog viewCatalog = Mockito.mock(ViewCatalog.class);
+    Mockito.when(viewCatalog.listViews(Namespace.of("db")))
+        .thenReturn(
+            new NameIdentifier[] {NameIdentifier.of("db", "v1"), 
NameIdentifier.of("db", "v2")});
+    Catalog gravitinoCatalog = Mockito.mock(Catalog.class);
+    Mockito.when(gravitinoCatalog.asViewCatalog()).thenReturn(viewCatalog);
+
+    BaseCatalog catalog =
+        new TestableBaseCatalog(Mockito.mock(AbstractCatalog.class), 
gravitinoCatalog);
+
+    List<String> views = catalog.listViews("db");
+
+    Assertions.assertEquals(ImmutableList.of("v1", "v2"), views);
+  }
+
+  @Test
+  public void testGetGravitinoViewChangesSetAndRemoveProperty() {
+    List<TableChange> tableChanges =
+        ImmutableList.of(TableChange.set("k1", "v1"), TableChange.reset("k2"));
+
+    org.apache.flink.table.api.Schema schema =
+        Schema.newBuilder().column("id", DataTypes.INT()).build();

Review Comment:
   This test uses a fully qualified name `org.apache.flink.table.api.Schema` 
even though `Schema` is already imported at the top of the file. Please use the 
imported type to keep the code consistent and avoid unnecessary verbosity.
   



##########
flink-connector/flink-common/src/test/java/org/apache/gravitino/flink/connector/integration/test/hive/FlinkHiveCatalogIT.java:
##########
@@ -745,6 +748,278 @@ public void testDefaultFormatAndSerdeApplied() {
         true);
   }
 
+  @Test
+  public void testCreateView() {
+    String schemaName = "test_hive_create_view_db";
+    String viewName = "test_view_create";
+    String tableName = "test_view_base_table";
+    doWithSchema(
+        currentCatalog(),
+        schemaName,
+        catalog -> {
+          TestUtils.assertTableResult(
+              sql("CREATE TABLE %s (id INT, name STRING) WITH 
('connector'='hive')", tableName),
+              ResultKind.SUCCESS);
+          TestUtils.assertTableResult(
+              sql(
+                  "CREATE VIEW %s COMMENT 'view comment' AS SELECT id, name 
FROM %s",
+                  viewName, tableName),
+              ResultKind.SUCCESS);
+
+          // Verify via Gravitino ViewCatalog
+          ViewCatalog viewCatalog = catalog.asViewCatalog();
+          View view = viewCatalog.loadView(NameIdentifier.of(schemaName, 
viewName));
+          Assertions.assertEquals(viewName, view.name());
+          Assertions.assertEquals("view comment", view.comment());
+          Assertions.assertEquals(1, view.representations().length);
+          Assertions.assertInstanceOf(SQLRepresentation.class, 
view.representations()[0]);
+
+          // Verify via Flink catalog API
+          Optional<Catalog> flinkCatalog = tableEnv.getCatalog(catalog.name());
+          Assertions.assertTrue(flinkCatalog.isPresent());
+          try {
+            CatalogBaseTable flinkTable =
+                ((GravitinoHiveCatalog) flinkCatalog.get())
+                    .getTable(new ObjectPath(schemaName, viewName));
+            Assertions.assertEquals(CatalogBaseTable.TableKind.VIEW, 
flinkTable.getTableKind());
+          } catch (TableNotExistException e) {
+            Assertions.fail("view should exist in Flink catalog: " + 
e.getMessage());
+          }
+        },
+        true);
+  }
+
+  @Test
+  public void testListViews() {
+    String schemaName = "test_hive_list_views_db";
+    String tableName = "test_list_view_base";
+    String view1 = "test_list_view_1";
+    String view2 = "test_list_view_2";
+    doWithSchema(
+        currentCatalog(),
+        schemaName,
+        catalog -> {
+          TestUtils.assertTableResult(
+              sql("CREATE TABLE %s (id INT) WITH ('connector'='hive')", 
tableName),
+              ResultKind.SUCCESS);
+          TestUtils.assertTableResult(
+              sql("CREATE VIEW %s AS SELECT id FROM %s", view1, tableName), 
ResultKind.SUCCESS);
+          TestUtils.assertTableResult(
+              sql("CREATE VIEW %s AS SELECT id FROM %s", view2, tableName), 
ResultKind.SUCCESS);
+
+          List<String> views = Arrays.asList(tableEnv.listViews());
+          Assertions.assertTrue(views.contains(view1), "view1 not found in 
SHOW VIEWS");
+          Assertions.assertTrue(views.contains(view2), "view2 not found in 
SHOW VIEWS");
+
+          // Tables should not appear in listViews
+          Assertions.assertFalse(views.contains(tableName), "table should not 
appear in listViews");
+
+          // Verify via Gravitino ViewCatalog
+          ViewCatalog viewCatalog = catalog.asViewCatalog();
+          NameIdentifier[] gravitinoViews =
+              
viewCatalog.listViews(org.apache.gravitino.Namespace.of(schemaName));
+          List<String> gravitinoViewNames =

Review Comment:
   Avoid using a fully qualified class name inside the method body 
(`org.apache.gravitino.Namespace.of(...)`). Please add an import for 
`org.apache.gravitino.Namespace` (or reuse an existing one) and reference 
`Namespace.of(...)` directly to match the project's import style guidelines.



##########
flink-connector/flink-common/src/test/java/org/apache/gravitino/flink/connector/catalog/TestBaseCatalog.java:
##########
@@ -136,33 +150,170 @@ public void testToGravitinoDistributionDefaultsToNone() {
   }
 
   @Test
-  public void testListViewsReturnsEmptyWithoutDelegation() throws Exception {
-    AbstractCatalog delegate = Mockito.mock(AbstractCatalog.class);
-    BaseCatalog catalog = new TestableBaseCatalog(delegate);
+  public void testListViewsReturnsEmptyWhenViewCatalogUnsupported() throws 
Exception {
+    Catalog gravitinoCatalog = mockUnsupportedViewCatalog();
+    BaseCatalog catalog =
+        new TestableBaseCatalog(Mockito.mock(AbstractCatalog.class), 
gravitinoCatalog);
 
     List<String> views = catalog.listViews("db");
 
     Assertions.assertTrue(views.isEmpty());
-    Mockito.verifyNoInteractions(delegate);
+  }
+
+  @Test
+  public void testListViewsDelegatesToViewCatalog() throws Exception {
+    ViewCatalog viewCatalog = Mockito.mock(ViewCatalog.class);
+    Mockito.when(viewCatalog.listViews(Namespace.of("db")))
+        .thenReturn(
+            new NameIdentifier[] {NameIdentifier.of("db", "v1"), 
NameIdentifier.of("db", "v2")});
+    Catalog gravitinoCatalog = Mockito.mock(Catalog.class);
+    Mockito.when(gravitinoCatalog.asViewCatalog()).thenReturn(viewCatalog);
+
+    BaseCatalog catalog =
+        new TestableBaseCatalog(Mockito.mock(AbstractCatalog.class), 
gravitinoCatalog);
+
+    List<String> views = catalog.listViews("db");
+
+    Assertions.assertEquals(ImmutableList.of("v1", "v2"), views);
+  }
+
+  @Test
+  public void testGetGravitinoViewChangesSetAndRemoveProperty() {
+    List<TableChange> tableChanges =
+        ImmutableList.of(TableChange.set("k1", "v1"), TableChange.reset("k2"));
+
+    org.apache.flink.table.api.Schema schema =
+        Schema.newBuilder().column("id", DataTypes.INT()).build();
+
+    ViewChange[] changes =
+        BaseCatalog.getGravitinoViewChanges(
+            tableChanges, resolveView(schema, "SELECT 1", "comment"), 
Dialects.FLINK);
+
+    Assertions.assertEquals(2, changes.length);
+    Assertions.assertInstanceOf(ViewChange.SetProperty.class, changes[0]);
+    Assertions.assertEquals("k1", ((ViewChange.SetProperty) 
changes[0]).getProperty());
+    Assertions.assertEquals("v1", ((ViewChange.SetProperty) 
changes[0]).getValue());
+
+    Assertions.assertInstanceOf(ViewChange.RemoveProperty.class, changes[1]);
+    Assertions.assertEquals("k2", ((ViewChange.RemoveProperty) 
changes[1]).getProperty());
+  }
+
+  @Test
+  public void testGetGravitinoViewChangesBodyReplaceOnStructuralChange() {
+    List<TableChange> tableChanges =
+        ImmutableList.of(
+            TableChange.add(Column.physical("id", DataTypes.INT())), 
TableChange.set("k1", "v1"));
+
+    org.apache.flink.table.api.Schema schema =
+        Schema.newBuilder().column("id", DataTypes.INT()).build();

Review Comment:
   This test uses a fully qualified name `org.apache.flink.table.api.Schema` 
even though `Schema` is already imported. Please use the imported type for 
consistency.



##########
flink-connector/flink-common/src/test/java/org/apache/gravitino/flink/connector/catalog/TestBaseCatalog.java:
##########
@@ -136,33 +150,170 @@ public void testToGravitinoDistributionDefaultsToNone() {
   }
 
   @Test
-  public void testListViewsReturnsEmptyWithoutDelegation() throws Exception {
-    AbstractCatalog delegate = Mockito.mock(AbstractCatalog.class);
-    BaseCatalog catalog = new TestableBaseCatalog(delegate);
+  public void testListViewsReturnsEmptyWhenViewCatalogUnsupported() throws 
Exception {
+    Catalog gravitinoCatalog = mockUnsupportedViewCatalog();
+    BaseCatalog catalog =
+        new TestableBaseCatalog(Mockito.mock(AbstractCatalog.class), 
gravitinoCatalog);
 
     List<String> views = catalog.listViews("db");
 
     Assertions.assertTrue(views.isEmpty());
-    Mockito.verifyNoInteractions(delegate);
+  }
+
+  @Test
+  public void testListViewsDelegatesToViewCatalog() throws Exception {
+    ViewCatalog viewCatalog = Mockito.mock(ViewCatalog.class);
+    Mockito.when(viewCatalog.listViews(Namespace.of("db")))
+        .thenReturn(
+            new NameIdentifier[] {NameIdentifier.of("db", "v1"), 
NameIdentifier.of("db", "v2")});
+    Catalog gravitinoCatalog = Mockito.mock(Catalog.class);
+    Mockito.when(gravitinoCatalog.asViewCatalog()).thenReturn(viewCatalog);
+
+    BaseCatalog catalog =
+        new TestableBaseCatalog(Mockito.mock(AbstractCatalog.class), 
gravitinoCatalog);
+
+    List<String> views = catalog.listViews("db");
+
+    Assertions.assertEquals(ImmutableList.of("v1", "v2"), views);
+  }
+
+  @Test
+  public void testGetGravitinoViewChangesSetAndRemoveProperty() {
+    List<TableChange> tableChanges =
+        ImmutableList.of(TableChange.set("k1", "v1"), TableChange.reset("k2"));
+
+    org.apache.flink.table.api.Schema schema =
+        Schema.newBuilder().column("id", DataTypes.INT()).build();
+
+    ViewChange[] changes =
+        BaseCatalog.getGravitinoViewChanges(
+            tableChanges, resolveView(schema, "SELECT 1", "comment"), 
Dialects.FLINK);
+
+    Assertions.assertEquals(2, changes.length);
+    Assertions.assertInstanceOf(ViewChange.SetProperty.class, changes[0]);
+    Assertions.assertEquals("k1", ((ViewChange.SetProperty) 
changes[0]).getProperty());
+    Assertions.assertEquals("v1", ((ViewChange.SetProperty) 
changes[0]).getValue());
+
+    Assertions.assertInstanceOf(ViewChange.RemoveProperty.class, changes[1]);
+    Assertions.assertEquals("k2", ((ViewChange.RemoveProperty) 
changes[1]).getProperty());
+  }
+
+  @Test
+  public void testGetGravitinoViewChangesBodyReplaceOnStructuralChange() {
+    List<TableChange> tableChanges =
+        ImmutableList.of(
+            TableChange.add(Column.physical("id", DataTypes.INT())), 
TableChange.set("k1", "v1"));
+
+    org.apache.flink.table.api.Schema schema =
+        Schema.newBuilder().column("id", DataTypes.INT()).build();
+
+    ViewChange[] changes =
+        BaseCatalog.getGravitinoViewChanges(
+            tableChanges, resolveView(schema, "SELECT id FROM t", "new 
comment"), Dialects.FLINK);
+
+    // Should have exactly one SetProperty and one ReplaceView (order may vary)
+    Assertions.assertEquals(2, changes.length);
+    ViewChange.SetProperty setProp =
+        (ViewChange.SetProperty)
+            Arrays.stream(changes)
+                .filter(c -> c instanceof ViewChange.SetProperty)
+                .findFirst()
+                .orElseThrow(() -> new AssertionError("expected SetProperty"));
+    Assertions.assertEquals("k1", setProp.getProperty());
+    Assertions.assertEquals("v1", setProp.getValue());
+
+    ViewChange.ReplaceView replaceView =
+        (ViewChange.ReplaceView)
+            Arrays.stream(changes)
+                .filter(c -> c instanceof ViewChange.ReplaceView)
+                .findFirst()
+                .orElseThrow(() -> new AssertionError("expected ReplaceView"));
+    Assertions.assertEquals("new comment", replaceView.getComment());
+    Assertions.assertEquals(1, replaceView.getRepresentations().length);
+    Assertions.assertInstanceOf(SQLRepresentation.class, 
replaceView.getRepresentations()[0]);
+    SQLRepresentation sqlRep = (SQLRepresentation) 
replaceView.getRepresentations()[0];
+    Assertions.assertEquals(Dialects.FLINK, sqlRep.dialect());
+    Assertions.assertEquals("SELECT id FROM t", sqlRep.sql());
+  }
+
+  @Test
+  public void testGetGravitinoViewChangesFullReplace() {
+    org.apache.flink.table.api.Schema schema =
+        Schema.newBuilder().column("id", DataTypes.INT()).build();

Review Comment:
   This test uses a fully qualified name `org.apache.flink.table.api.Schema` 
even though `Schema` is already imported. Please use the imported type to match 
the project's import style guidelines.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to