diff --git a/presto-docs/src/main/sphinx/connector/iceberg.rst b/presto-docs/src/main/sphinx/connector/iceberg.rst
index 42b857d3266c3..c2c8943d87d0a 100644
--- a/presto-docs/src/main/sphinx/connector/iceberg.rst
+++ b/presto-docs/src/main/sphinx/connector/iceberg.rst
@@ -2224,7 +2224,7 @@ Querying branches and tags
Iceberg supports branches and tags which are named references to snapshots.
-Query Iceberg table by specifying the branch name:
+Query Iceberg table by specifying the branch name using ``FOR SYSTEM_VERSION AS OF``:
.. code-block:: sql
@@ -2239,6 +2239,21 @@ Query Iceberg table by specifying the branch name:
30 | mexico | 3 | comment
(3 rows)
+Alternatively, you can query a branch using the dot notation syntax with quoted identifiers:
+
+.. code-block:: sql
+
+ SELECT * FROM "nation.branch_testBranch";
+
+.. code-block:: text
+
+ nationkey | name | regionkey | comment
+ -----------+---------------+-----------+---------
+ 10 | united states | 1 | comment
+ 20 | canada | 2 | comment
+ 30 | mexico | 3 | comment
+ (3 rows)
+
Query Iceberg table by specifying the tag name:
.. code-block:: sql
@@ -2253,6 +2268,8 @@ Query Iceberg table by specifying the tag name:
20 | canada | 2 | comment
(3 rows)
+**Note:** The dot notation syntax ``"
.branch_"`` requires double quotes to prevent the SQL parser from interpreting the dot as a schema.table separator. This syntax works for both querying (SELECT) and mutating (INSERT, UPDATE, DELETE, MERGE) branch data.
+
Mutating Iceberg Branches
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedTestBase.java b/presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedTestBase.java
index fa2d9ee9e9b49..20703ba2a7b55 100644
--- a/presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedTestBase.java
+++ b/presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedTestBase.java
@@ -2432,6 +2432,30 @@ public void testRefsTable()
assertQuery("SELECT * FROM test_table_references FOR SYSTEM_VERSION AS OF 'testTag' where id1=1", "VALUES(1, NULL)");
}
+ @Test
+ public void testQueryBranch()
+ {
+ assertUpdate("CREATE TABLE test_branch_dot_notation (id BIGINT, name VARCHAR, value BIGINT)");
+ assertUpdate("INSERT INTO test_branch_dot_notation VALUES (1, 'Alice', 100), (2, 'Bob', 200)", 2);
+ Table icebergTable = loadTable("test_branch_dot_notation");
+ icebergTable.manageSnapshots().createBranch("audit_branch").commit();
+ assertUpdate("INSERT INTO test_branch_dot_notation VALUES (3, 'Charlie', 300), (4, 'David', 400)", 2);
+ // Test querying branch using FOR SYSTEM_VERSION AS OF syntax
+ assertQuery("SELECT count(*) FROM test_branch_dot_notation FOR SYSTEM_VERSION AS OF 'audit_branch'", "VALUES 2");
+ assertQuery("SELECT count(*) FROM test_branch_dot_notation FOR SYSTEM_VERSION AS OF 'main'", "VALUES 4");
+ // Test querying branch using dot notation syntax
+ assertQuery("SELECT count(*) FROM \"test_branch_dot_notation.branch_audit_branch\"", "VALUES 2");
+ assertQuery("SELECT id, name, value FROM \"test_branch_dot_notation.branch_audit_branch\" ORDER BY id",
+ "VALUES (1, 'Alice', 100), (2, 'Bob', 200)");
+ // Verify both syntaxes return the same results by comparing actual results
+ MaterializedResult resultWithForSyntax = computeActual("SELECT id FROM test_branch_dot_notation FOR SYSTEM_VERSION AS OF 'audit_branch' ORDER BY id");
+ MaterializedResult resultWithDotNotation = computeActual("SELECT id FROM \"test_branch_dot_notation.branch_audit_branch\" ORDER BY id");
+ assertEquals(resultWithForSyntax, resultWithDotNotation);
+ // Test that main table has all records
+ assertQuery("SELECT count(*) FROM test_branch_dot_notation", "VALUES 4");
+ assertQuerySucceeds("DROP TABLE test_branch_dot_notation");
+ }
+
@Test
public void testMetadataLogTable()
{