Repository: cockroachdb/cockroach
Pull request #146452: docgen: add alter virtual cluster diagram
Author: login: katmayb
Labels: name: backport-25.2.x
description: Flags PRs that need to be backported to 25.2
name: v25.3.0-prerelease
Created: 2025-05-09T15:41:56Z | Merged: 2025-05-19T21:22:23Z

Epic: none

Release note: None

Release justification: non-production code change


Diff:
diff --git a/docs/generated/sql/bnf/BUILD.bazel b/docs/generated/sql/bnf/BUILD.bazel
index 17820f8ce063..ca5ddb3959cb 100644
--- a/docs/generated/sql/bnf/BUILD.bazel
+++ b/docs/generated/sql/bnf/BUILD.bazel
@@ -67,6 +67,11 @@ FILES = [
     "alter_view",
     "alter_view_owner_stmt",
     "alter_view_set_schema_stmt",
+    "alter_virtual_cluster_capability",
+    "alter_virtual_cluster",
+    "alter_virtual_cluster_rename",
+    "alter_virtual_cluster_replication",
+    "alter_virtual_cluster_service",
     "alter_zone_database_stmt",
     "alter_zone_index_stmt",
     "alter_zone_partition_stmt",
diff --git a/docs/generated/sql/bnf/alter_stmt.bnf b/docs/generated/sql/bnf/alter_stmt.bnf
index 50297fc69343..7f3d1a6b4739 100644
--- a/docs/generated/sql/bnf/alter_stmt.bnf
+++ b/docs/generated/sql/bnf/alter_stmt.bnf
@@ -1,3 +1,4 @@
 alter_stmt ::=
 	alter_ddl_stmt
 	| alter_role_stmt
+	| alter_virtual_cluster_stmt
diff --git a/docs/generated/sql/bnf/alter_virtual_cluster.bnf b/docs/generated/sql/bnf/alter_virtual_cluster.bnf
new file mode 100644
index 000000000000..3fa9c0f25719
--- /dev/null
+++ b/docs/generated/sql/bnf/alter_virtual_cluster.bnf
@@ -0,0 +1,13 @@
+alter_virtual_cluster_stmt ::=
+	'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'PAUSE' 'REPLICATION'
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'RESUME' 'REPLICATION'
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'COMPLETE' 'REPLICATION' 'TO' 'SYSTEM' 'TIME' timestamp
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'COMPLETE' 'REPLICATION' 'TO' 'LATEST'
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'SET' 'REPLICATION' replication_options ( ( ',' replication_options ) )*
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'SET' 'REPLICATION' 'SOURCE' source_replication_options_list
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'START' 'REPLICATION' 'OF' virtual_cluster_spec 'ON' physical_cluster opt_with_replication_options
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'GRANT' 'ALL' 'CAPABILITIES'
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'REVOKE' 'ALL' 'CAPABILITIES'
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'RENAME' 'TO' virtual_cluster_spec
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'START' 'SERVICE' 'SHARED'
+	| 'ALTER' 'VIRTUAL' 'CLUSTER' virtual_cluster_spec 'STOP' 'SERVICE'
diff --git a/docs/generated/sql/bnf/alter_virtual_cluster_capability.bnf b/docs/generated/sql/bnf/alter_virtual_cluster_capability.bnf
new file mode 100644
index 000000000000..56d92436e028
--- /dev/null
+++ b/docs/generated/sql/bnf/alter_virtual_cluster_capability.bnf
@@ -0,0 +1,3 @@
+alter_virtual_cluster_capability_stmt ::=
+	'ALTER' virtual_cluster virtual_cluster_spec 'GRANT' 'ALL' 'CAPABILITIES'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'REVOKE' 'ALL' 'CAPABILITIES'
diff --git a/docs/generated/sql/bnf/alter_virtual_cluster_rename.bnf b/docs/generated/sql/bnf/alter_virtual_cluster_rename.bnf
new file mode 100644
index 000000000000..c68552c9bac8
--- /dev/null
+++ b/docs/generated/sql/bnf/alter_virtual_cluster_rename.bnf
@@ -0,0 +1,2 @@
+alter_virtual_cluster_rename_stmt ::=
+	'ALTER' virtual_cluster virtual_cluster_spec 'RENAME' 'TO' d_expr
diff --git a/docs/generated/sql/bnf/alter_virtual_cluster_replication.bnf b/docs/generated/sql/bnf/alter_virtual_cluster_replication.bnf
new file mode 100644
index 000000000000..e8cb230d0c5b
--- /dev/null
+++ b/docs/generated/sql/bnf/alter_virtual_cluster_replication.bnf
@@ -0,0 +1,8 @@
+alter_virtual_cluster_replication_stmt ::=
+	'ALTER' virtual_cluster virtual_cluster_spec 'PAUSE' 'REPLICATION'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'RESUME' 'REPLICATION'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'COMPLETE' 'REPLICATION' 'TO' 'SYSTEM' 'TIME' a_expr
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'COMPLETE' 'REPLICATION' 'TO' 'LATEST'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'SET' 'REPLICATION' replication_options_list
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'SET' 'REPLICATION' 'SOURCE' source_replication_options_list
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'START' 'REPLICATION' 'OF' d_expr 'ON' d_expr opt_with_replication_options
diff --git a/docs/generated/sql/bnf/alter_virtual_cluster_service.bnf b/docs/generated/sql/bnf/alter_virtual_cluster_service.bnf
new file mode 100644
index 000000000000..908e6df21082
--- /dev/null
+++ b/docs/generated/sql/bnf/alter_virtual_cluster_service.bnf
@@ -0,0 +1,3 @@
+alter_virtual_cluster_service_stmt ::=
+	'ALTER' virtual_cluster virtual_cluster_spec 'START' 'SERVICE' 'SHARED'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'STOP' 'SERVICE'
diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf
index e88f1db29f34..d174889670f5 100644
--- a/docs/generated/sql/bnf/stmt_block.bnf
+++ b/docs/generated/sql/bnf/stmt_block.bnf
@@ -194,6 +194,7 @@ legacy_end_stmt ::=
 alter_stmt ::=
 	alter_ddl_stmt
 	| alter_role_stmt
+	| alter_virtual_cluster_stmt
 
 backup_stmt ::=
 	'BACKUP' opt_backup_targets 'INTO' sconst_or_placeholder 'IN' string_or_placeholder_opt_list opt_as_of_clause opt_with_backup_options
@@ -569,6 +570,12 @@ alter_role_stmt ::=
 	| 'ALTER' 'ROLE_ALL' 'ALL' opt_in_database set_or_reset_clause
 	| 'ALTER' 'USER_ALL' 'ALL' opt_in_database set_or_reset_clause
 
+alter_virtual_cluster_stmt ::=
+	alter_virtual_cluster_replication_stmt
+	| alter_virtual_cluster_capability_stmt
+	| alter_virtual_cluster_rename_stmt
+	| alter_virtual_cluster_service_stmt
+
 opt_backup_targets ::=
 	backup_targets
 
@@ -1816,6 +1823,26 @@ set_or_reset_clause ::=
 	| 'RESET_ALL' 'ALL'
 	| 'RESET' session_var
 
+alter_virtual_cluster_replication_stmt ::=
+	'ALTER' virtual_cluster virtual_cluster_spec 'PAUSE' 'REPLICATION'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'RESUME' 'REPLICATION'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'COMPLETE' 'REPLICATION' 'TO' 'SYSTEM' 'TIME' a_expr
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'COMPLETE' 'REPLICATION' 'TO' 'LATEST'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'SET' 'REPLICATION' replication_options_list
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'SET' 'REPLICATION' 'SOURCE' source_replication_options_list
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'START' 'REPLICATION' 'OF' d_expr 'ON' d_expr opt_with_replication_options
+
+alter_virtual_cluster_capability_stmt ::=
+	'ALTER' virtual_cluster virtual_cluster_spec 'GRANT' 'ALL' 'CAPABILITIES'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'REVOKE' 'ALL' 'CAPABILITIES'
+
+alter_virtual_cluster_rename_stmt ::=
+	'ALTER' virtual_cluster virtual_cluster_spec 'RENAME' 'TO' d_expr
+
+alter_virtual_cluster_service_stmt ::=
+	'ALTER' virtual_cluster virtual_cluster_spec 'START' 'SERVICE' 'SHARED'
+	| 'ALTER' virtual_cluster virtual_cluster_spec 'STOP' 'SERVICE'
+
 backup_options_list ::=
 	( backup_options ) ( ( ',' backup_options ) )*
 
@@ -2484,6 +2511,49 @@ opt_policy_exprs ::=
 role_options ::=
 	( role_option ) ( ( role_option ) )*
 
+virtual_cluster ::=
+	'VIRTUAL' 'CLUSTER'
+
+virtual_cluster_spec ::=
+	d_expr
+	| '[' a_expr ']'
+
+replication_options_list ::=
+	( replication_options ) ( ( ',' replication_options ) )*
+
+source_replication_options_list ::=
+	( source_replication_options ) ( ( ',' source_replication_options ) )*
+
+d_expr ::=
+	'ICONST'
+	| 'FCONST'
+	| 'SCONST'
+	| 'BCONST'
+	| 'BITCONST'
+	| typed_literal
+	| interval_value
+	| 'TRUE'
+	| 'FALSE'
+	| 'NULL'
+	| column_path_with_star
+	| '@' iconst64
+	| 'PLACEHOLDER'
+	| '(' a_expr ')' '.' '*'
+	| '(' a_expr ')' '.' unrestricted_name
+	| '(' a_expr ')' '.' '@' 'ICONST'
+	| '(' a_expr ')'
+	| func_expr
+	| select_with_parens
+	| labeled_row
+	| 'ARRAY' select_with_parens
+	| 'ARRAY' row
+	| 'ARRAY' array_expr
+
+opt_with_replication_options ::=
+	'WITH' replication_options_list
+	| 'WITH' 'OPTIONS' '(' replication_options_list ')'
+	| 
+
 backup_options ::=
 	'ENCRYPTION_PASSPHRASE' '=' string_or_placeholder
 	| 'REVISION_HISTORY'
@@ -3224,34 +3294,42 @@ role_option ::=
 	| 'BYPASSRLS'
 	| 'NOBYPASSRLS'
 
+replication_options ::=
+	'RETENTION' '=' d_expr
+	| 'READ' 'VIRTUAL' 'CLUSTER'
+
+source_replication_options ::=
+	'EXPIRATION' 'WINDOW' '=' d_expr
+
+typed_literal ::=
+	func_name_no_crdb_extra 'SCONST'
+	| const_typename 'SCONST'
+
+interval_value ::=
+	'INTERVAL' 'SCONST' opt_interval_qualifier
+	| 'INTERVAL' '(' iconst32 ')' 'SCONST'
+
+column_path_with_star ::=
+	column_path
+	| db_object_name_component '.' unrestricted_name '.' unrestricted_name '.' '*'
+	| db_object_name_component '.' unrestricted_name '.' '*'
+	| db_object_name_component '.' '*'
+
+func_expr ::=
+	func_application within_group_clause filter_clause over_clause
+	| func_expr_common_subexpr
+
+labeled_row ::=
+	row
+	| '(' row 'AS' name_list ')'
+
+array_expr ::=
+	'[' opt_expr_list ']'
+	| '[' array_expr_list ']'
+
 include_all_clusters ::=
 	'INCLUDE_ALL_VIRTUAL_CLUSTERS'
 
-d_expr ::=
-	'ICONST'
-	| 'FCONST'
-	| 'SCONST'
-	| 'BCONST'
-	| 'BITCONST'
-	| typed_literal
-	| interval_value
-	| 'TRUE'
-	| 'FALSE'
-	| 'NULL'
-	| column_path_with_star
-	| '@' iconst64
-	| 'PLACEHOLDER'
-	| '(' a_expr ')' '.' '*'
-	| '(' a_expr ')' '.' unrestricted_name
-	| '(' a_expr ')' '.' '@' 'ICONST'
-	| '(' a_expr ')'
-	| func_expr
-	| select_with_parens
-	| labeled_row
-	| 'ARRAY' select_with_parens
-	| 'ARRAY' row
-	| 'ARRAY' array_expr
-
 array_subscripts ::=
 	( array_subscript ) ( ( array_subscript ) )*
 
@@ -3712,31 +3790,54 @@ subject_clause ::=
 	'SUBJECT' string_or_placeholder
 	| 'SUBJECT' 'NULL'
 
-typed_literal ::=
-	func_name_no_crdb_extra 'SCONST'
-	| const_typename 'SCONST'
+func_name_no_crdb_extra ::=
+	type_function_name_no_crdb_extra
+	| prefixed_column_path
 
-interval_value ::=
-	'INTERVAL' 'SCONST' opt_interval_qualifier
-	| 'INTERVAL' '(' iconst32 ')' 'SCONST'
+opt_interval_qualifier ::=
+	interval_qualifier
+	| 
 
-column_path_with_star ::=
-	column_path
-	| db_object_name_component '.' unrestricted_name '.' unrestricted_name '.' '*'
-	| db_object_name_component '.' unrestricted_name '.' '*'
-	| db_object_name_component '.' '*'
+within_group_clause ::=
+	'WITHIN' 'GROUP' '(' single_sort_clause ')'
+	| 
 
-func_expr ::=
-	func_application within_group_clause filter_clause over_clause
-	| func_expr_common_subexpr
+filter_clause ::=
+	'FILTER' '(' 'WHERE' a_expr ')'
+	| 
 
-labeled_row ::=
-	row
-	| '(' row 'AS' name_list ')'
+over_clause ::=
+	'OVER' window_specification
+	| 'OVER' window_name
+	| 
 
-array_expr ::=
-	'[' opt_expr_list ']'
-	| '[' array_expr_list ']'
+func_expr_common_subexpr ::=
+	'COLLATION' 'FOR' '(' a_expr ')'
+	| 'CURRENT_DATE'
+	| 'CURRENT_SCHEMA'
+	| 'CURRENT_CATALOG'
+	| 'CURRENT_TIMESTAMP'
+	| 'CURRENT_TIME'
+	| 'LOCALTIMESTAMP'
+	| 'LOCALTIME'
+	| 'CURRENT_USER'
+	| 'CURRENT_ROLE'
+	| 'SESSION_USER'
+	| 'USER'
+	| 'CAST' '(' a_expr 'AS' cast_target ')'
+	| 'ANNOTATE_TYPE' '(' a_expr ',' typename ')'
+	| 'IF' '(' a_expr ',' a_expr ',' a_expr ')'
+	| 'IFERROR' '(' a_expr ',' a_expr ',' a_expr ')'
+	| 'IFERROR' '(' a_expr ',' a_expr ')'
+	| 'ISERROR' '(' a_expr ')'
+	| 'ISERROR' '(' a_expr ',' a_expr ')'
+	| 'NULLIF' '(' a_expr ',' a_expr ')'
+	| 'IFNULL' '(' a_expr ',' a_expr ')'
+	| 'COALESCE' '(' expr_list ')'
+	| special_function
+
+array_expr_list ::=
+	( array_expr ) ( ( ',' array_expr ) )*
 
 array_subscript ::=
 	'[' a_expr ']'
@@ -4655,54 +4756,41 @@ table_rls_mode ::=
 partition_by_index ::=
 	partition_by
 
-func_name_no_crdb_extra ::=
-	type_function_name_no_crdb_extra
-	| prefixed_column_path
-
-opt_interval_qualifier ::=
-	interval_qualifier
-	| 
-
-within_group_clause ::=
-	'WITHIN' 'GROUP' '(' single_sort_clause ')'
-	| 
-
-filter_clause ::=
-	'FILTER' '(' 'WHERE' a_expr ')'
-	| 
+single_sort_clause ::=
+	'ORDER' 'BY' sortby
+	| 'ORDER' 'BY' sortby ',' sortby_list
+	| 'ORDER' 'BY' sortby_index ',' sortby_list
 
-over_clause ::=
-	'OVER' window_specification
-	| 'OVER' window_name
-	| 
+window_specification ::=
+	'(' opt_existing_window_name opt_partition_clause opt_sort_clause_no_index opt_frame_clause ')'
 
-func_expr_common_subexpr ::=
-	'COLLATION' 'FOR' '(' a_expr ')'
-	| 'CURRENT_DATE'
-	| 'CURRENT_SCHEMA'
-	| 'CURRENT_CATALOG'
-	| 'CURRENT_TIMESTAMP'
-	| 'CURRENT_TIME'
-	| 'LOCALTIMESTAMP'
-	| 'LOCALTIME'
-	| 'CURRENT_USER'
-	| 'CURRENT_ROLE'
-	| 'SESSION_USER'
-	| 'USER'
-	| 'CAST' '(' a_expr 'AS' cast_target ')'
-	| 'ANNOTATE_TYPE' '(' a_expr ',' typename ')'
-	| 'IF' '(' a_expr ',' a_expr ',' a_expr ')'
-	| 'IFERROR' '(' a_expr ',' a_expr ',' a_expr ')'
-	| 'IFERROR' '(' a_expr ',' a_expr ')'
-	| 'ISERROR' '(' a_expr ')'
-	| 'ISERROR' '(' a_expr ',' a_expr ')'
-	| 'NULLIF' '(' a_expr ',' a_expr ')'
-	| 'IFNULL' '(' a_expr ',' a_expr ')'
-	| 'COALESCE' '(' expr_list ')'
-	| special_function
+window_name ::=
+	name
 
-array_expr_list ::=
-	( array_expr ) ( ( ',' array_expr ) )*
+special_function ::=
+	'CURRENT_DATE' '(' ')'
+	| 'CURRENT_SCHEMA' '(' ')'
+	| 'CURRENT_TIMESTAMP' '(' ')'
+	| 'CURRENT_TIMESTAMP' '(' a_expr ')'
+	| 'CURRENT_TIME' '(' ')'
+	| 'CURRENT_TIME' '(' a_expr ')'
+	| 'LOCALTIMESTAMP' '(' ')'
+	| 'LOCALTIMESTAMP' '(' a_expr ')'
+	| 'LOCALTIME' '(' ')'
+	| 'LOCALTIME' '(' a_expr ')'
+	| 'CURRENT_USER' '(' ')'
+	| 'SESSION_USER' '(' ')'
+	| 'EXTRACT' '(' extract_list ')'
+	| 'EXTRACT_DURATION' '(' extract_list ')'
+	| 'OVERLAY' '(' overlay_list ')'
+	| 'POSITION' '(' position_list ')'
+	| 'SUBSTRING' '(' substr_list ')'
+	| 'TRIM' '(' 'BOTH' trim_list ')'
+	| 'TRIM' '(' 'LEADING' trim_list ')'
+	| 'TRIM' '(' 'TRAILING' trim_list ')'
+	| 'TRIM' '(' trim_list ')'
+	| 'GREATEST' '(' expr_list ')'
+	| 'LEAST' '(' expr_list ')'
 
 opt_slice_bound ::=
 	a_expr
@@ -4883,41 +4971,44 @@ reference_actions ::=
 	| reference_on_delete reference_on_update
 	| 
 
-single_sort_clause ::=
-	'ORDER' 'BY' sortby
-	| 'ORDER' 'BY' sortby ',' sortby_list
-	| 'ORDER' 'BY' sortby_index ',' sortby_list
+opt_existing_window_name ::=
+	name
+	| 
 
-window_specification ::=
-	'(' opt_existing_window_name opt_partition_clause opt_sort_clause_no_index opt_frame_clause ')'
+opt_partition_clause ::=
+	'PARTITION' 'BY' expr_list
+	| 
 
-window_name ::=
-	name
+opt_frame_clause ::=
+	'RANGE' frame_extent opt_frame_exclusion
+	| 'ROWS' frame_extent opt_frame_exclusion
+	| 'GROUPS' frame_extent opt_frame_exclusion
+	| 
 
-special_function ::=
-	'CURRENT_DATE' '(' ')'
-	| 'CURRENT_SCHEMA' '(' ')'
-	| 'CURRENT_TIMESTAMP' '(' ')'
-	| 'CURRENT_TIMESTAMP' '(' a_expr ')'
-	| 'CURRENT_TIME' '(' ')'
-	| 'CURRENT_TIME' '(' a_expr ')'
-	| 'LOCALTIMESTAMP' '(' ')'
-	| 'LOCALTIMESTAMP' '(' a_expr ')'
-	| 'LOCALTIME' '(' ')'
-	| 'LOCALTIME' '(' a_expr ')'
-	| 'CURRENT_USER' '(' ')'
-	| 'SESSION_USER' '(' ')'
-	| 'EXTRACT' '(' extract_list ')'
-	| 'EXTRACT_DURATION' '(' extract_list ')'
-	| 'OVERLAY' '(' overlay_list ')'
-	| 'POSITION' '(' position_list ')'
-	| 'SUBSTRING' '(' substr_list ')'
-	| 'TRIM' '(' 'BOTH' trim_list ')'
-	| 'TRIM' '(' 'LEADING' trim_list ')'
-	| 'TRIM' '(' 'TRAILING' trim_list ')'
-	| 'TRIM' '(' trim_list ')'
-	| 'GREATEST' '(' expr_list ')'
-	| 'LEAST' '(' expr_list ')'
+extract_list ::=
+	extract_arg 'FROM' a_expr
+	| expr_list
+
+overlay_list ::=
+	a_expr overlay_placing substr_from substr_for
+	| a_expr overlay_placing substr_from
+	| expr_list
+
+position_list ::=
+	b_expr 'IN' b_expr
+	| 
+
+substr_list ::=
+	a_expr substr_from substr_for
+	| a_expr substr_for substr_from
+	| a_expr substr_from
+	| a_expr substr_for
+	| opt_expr_list
+
+trim_list ::=
+	a_expr 'FROM' expr_list
+	| 'FROM' expr_list
+	| expr_list
 
 list_partition ::=
 	partition 'VALUES' 'IN' '(' expr_list ')' opt_partition_by
@@ -4960,44 +5051,35 @@ reference_on_update ::=
 reference_on_delete ::=
 	'ON' 'DELETE' reference_action
 
-opt_existing_window_name ::=
-	name
-	| 
-
-opt_partition_clause ::=
-	'PARTITION' 'BY' expr_list
-	| 
+frame_extent ::=
+	frame_bound
+	| 'BETWEEN' frame_bound 'AND' frame_bound
 
-opt_frame_clause ::=
-	'RANGE' frame_extent opt_frame_exclusion
-	| 'ROWS' frame_extent opt_frame_exclusion
-	| 'GROUPS' frame_extent opt_frame_exclusion
+opt_frame_exclusion ::=
+	'EXCLUDE' 'CURRENT' 'ROW'
+	| 'EXCLUDE' 'GROUP'
+	| 'EXCLUDE' 'TIES'
+	| 'EXCLUDE' 'NO' 'OTHERS'
 	| 
 
-extract_list ::=
-	extract_arg 'FROM' a_expr
-	| expr_list
-
-overlay_list ::=
-	a_expr overlay_placing substr_from substr_for
-	| a_expr overlay_placing substr_from
-	| expr_list
+extract_arg ::=
+	'identifier'
+	| 'YEAR'
+	| 'MONTH'
+	| 'DAY'
+	| 'HOUR'
+	| 'MINUTE'
+	| 'SECOND'
+	| 'SCONST'
 
-position_list ::=
-	b_expr 'IN' b_expr
-	| 
+overlay_placing ::=
+	'PLACING' a_expr
 
-substr_list ::=
-	a_expr substr_from substr_for
-	| a_expr substr_for substr_from
-	| a_expr substr_from
-	| a_expr substr_for
-	| opt_expr_list
+substr_from ::=
+	'FROM' a_expr
 
-trim_list ::=
-	a_expr 'FROM' expr_list
-	| 'FROM' expr_list
-	| expr_list
+substr_for ::=
+	'FOR' a_expr
 
 opt_partition_by ::=
 	partition_by
@@ -5035,35 +5117,12 @@ reference_action ::=
 	| 'SET' 'NULL'
 	| 'SET' 'DEFAULT'
 
-frame_extent ::=
-	frame_bound
-	| 'BETWEEN' frame_bound 'AND' frame_bound
-
-opt_frame_exclusion ::=
-	'EXCLUDE' 'CURRENT' 'ROW'
-	| 'EXCLUDE' 'GROUP'
-	| 'EXCLUDE' 'TIES'
-	| 'EXCLUDE' 'NO' 'OTHERS'
-	| 
-
-extract_arg ::=
-	'identifier'
-	| 'YEAR'
-	| 'MONTH'
-	| 'DAY'
-	| 'HOUR'
-	| 'MINUTE'
-	| 'SECOND'
-	| 'SCONST'
-
-overlay_placing ::=
-	'PLACING' a_expr
-
-substr_from ::=
-	'FROM' a_expr
-
-substr_for ::=
-	'FOR' a_expr
+frame_bound ::=
+	'UNBOUNDED' 'PRECEDING'
+	| 'UNBOUNDED' 'FOLLOWING'
+	| 'CURRENT' 'ROW'
+	| a_expr 'PRECEDING'
+	| a_expr 'FOLLOWING'
 
 opt_name_parens ::=
 	'(' name ')'
@@ -5072,10 +5131,3 @@ opt_name_parens ::=
 generated_as ::=
 	'AS'
 	| generated_always_as
-
-frame_bound ::=
-	'UNBOUNDED' 'PRECEDING'
-	| 'UNBOUNDED' 'FOLLOWING'
-	| 'CURRENT' 'ROW'
-	| a_expr 'PRECEDING'
-	| a_expr 'FOLLOWING'
diff --git a/pkg/cmd/docgen/diagrams.go b/pkg/cmd/docgen/diagrams.go
index 66ff9368a296..efe291498bf0 100644
--- a/pkg/cmd/docgen/diagrams.go
+++ b/pkg/cmd/docgen/diagrams.go
@@ -575,6 +575,29 @@ var specs = []stmtSpec{
 		replace: map[string]string{"relation_expr": "view_name", "'RENAME' 'TO' view_name": "'RENAME' 'TO' view_new_name"},
 		unlink:  []string{"view_name", "view_new_name"},
 	},
+	{
+		name:    "alter_virtual_cluster",
+		stmt:    "alter_virtual_cluster_stmt",
+		inline:  []string{"virtual_cluster", "replication_options_list", "alter_virtual_cluster_capability_stmt", "alter_virtual_cluster_replication_stmt", "alter_virtual_cluster_rename_stmt", "alter_virtual_cluster_service_stmt"},
+		replace: map[string]string{"'ON' d_expr": "'ON' physical_cluster", "d_expr": "virtual_cluster_spec", "a_expr": "timestamp"},
+		unlink:  []string{"physical_cluster", "virtual_cluster_spec", "timestamp"},
+	},
+	{
+		name: "alter_virtual_cluster_capability",
+		stmt: "alter_virtual_cluster_capability_stmt",
+	},
+	{
+		name: "alter_virtual_cluster_replication",
+		stmt: "alter_virtual_cluster_replication_stmt",
+	},
+	{
+		name: "alter_virtual_cluster_rename",
+		stmt: "alter_virtual_cluster_rename_stmt",
+	},
+	{
+		name: "alter_virtual_cluster_service",
+		stmt: "alter_virtual_cluster_service_stmt",
+	},
 	{
 		name:    "alter_zone_database_stmt",
 		inline:  []string{"set_zone_config", "var_set_list"},
diff --git a/pkg/gen/bnf.bzl b/pkg/gen/bnf.bzl
index a7afd4c65497..db076f782ef2 100644
--- a/pkg/gen/bnf.bzl
+++ b/pkg/gen/bnf.bzl
@@ -67,6 +67,11 @@ BNF_SRCS = [
     "//docs/generated/sql/bnf:alter_view.bnf",
     "//docs/generated/sql/bnf:alter_view_owner_stmt.bnf",
     "//docs/generated/sql/bnf:alter_view_set_schema_stmt.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_capability.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_rename.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_replication.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_service.bnf",
     "//docs/generated/sql/bnf:alter_zone_database_stmt.bnf",
     "//docs/generated/sql/bnf:alter_zone_index_stmt.bnf",
     "//docs/generated/sql/bnf:alter_zone_partition_stmt.bnf",
diff --git a/pkg/gen/diagrams.bzl b/pkg/gen/diagrams.bzl
index 44c257c8c49c..28e706401b58 100644
--- a/pkg/gen/diagrams.bzl
+++ b/pkg/gen/diagrams.bzl
@@ -67,6 +67,11 @@ DIAGRAMS_SRCS = [
     "//docs/generated/sql/bnf:alter_view.html",
     "//docs/generated/sql/bnf:alter_view_owner.html",
     "//docs/generated/sql/bnf:alter_view_set_schema.html",
+    "//docs/generated/sql/bnf:alter_virtual_cluster.html",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_capability.html",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_rename.html",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_replication.html",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_service.html",
     "//docs/generated/sql/bnf:alter_zone_database.html",
     "//docs/generated/sql/bnf:alter_zone_index.html",
     "//docs/generated/sql/bnf:alter_zone_partition.html",
diff --git a/pkg/gen/docs.bzl b/pkg/gen/docs.bzl
index 35284a39e77f..0852ad96c7fd 100644
--- a/pkg/gen/docs.bzl
+++ b/pkg/gen/docs.bzl
@@ -77,6 +77,11 @@ DOCS_SRCS = [
     "//docs/generated/sql/bnf:alter_view.bnf",
     "//docs/generated/sql/bnf:alter_view_owner_stmt.bnf",
     "//docs/generated/sql/bnf:alter_view_set_schema_stmt.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_capability.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_rename.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_replication.bnf",
+    "//docs/generated/sql/bnf:alter_virtual_cluster_service.bnf",
     "//docs/generated/sql/bnf:alter_zone_database_stmt.bnf",
     "//docs/generated/sql/bnf:alter_zone_index_stmt.bnf",
     "//docs/generated/sql/bnf:alter_zone_partition_stmt.bnf",
diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y
index 48803462e979..341b7c819f7d 100644
--- a/pkg/sql/parser/sql.y
+++ b/pkg/sql/parser/sql.y
@@ -7841,7 +7841,6 @@ alter_virtual_cluster_reset_stmt:
 alter_virtual_cluster_rename_stmt:
   ALTER virtual_cluster virtual_cluster_spec RENAME TO d_expr
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantRename{
       TenantSpec: $3.tenantSpec(),
       NewName: &tree.TenantSpec{IsName: true, Expr: $6.expr()},
@@ -7865,7 +7864,6 @@ alter_virtual_cluster_service_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec START SERVICE SHARED
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantService{
       TenantSpec: $3.tenantSpec(),
       Command: tree.TenantStartServiceShared,
@@ -7873,7 +7871,6 @@ alter_virtual_cluster_service_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec STOP SERVICE
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantService{
       TenantSpec: $3.tenantSpec(),
       Command: tree.TenantStopService,
@@ -7895,7 +7892,6 @@ alter_virtual_cluster_service_stmt:
 alter_virtual_cluster_replication_stmt:
   ALTER virtual_cluster virtual_cluster_spec PAUSE REPLICATION
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Command: tree.PauseJob,
@@ -7903,7 +7899,6 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec RESUME REPLICATION
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Command: tree.ResumeJob,
@@ -7911,7 +7906,6 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec COMPLETE REPLICATION TO SYSTEM TIME a_expr
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Cutover: &tree.ReplicationCutoverTime{
@@ -7921,7 +7915,6 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec COMPLETE REPLICATION TO LATEST
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Cutover: &tree.ReplicationCutoverTime{
@@ -7931,7 +7924,6 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec SET REPLICATION replication_options_list
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Options: *$6.tenantReplicationOptions(),
@@ -7939,7 +7931,6 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec SET REPLICATION SOURCE source_replication_options_list
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Producer: true,
@@ -7948,7 +7939,6 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec START REPLICATION OF d_expr ON d_expr opt_with_replication_options
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: $7.expr()},
@@ -8011,7 +8001,6 @@ to_or_eq:
 alter_virtual_cluster_capability_stmt:
   ALTER virtual_cluster virtual_cluster_spec GRANT CAPABILITY virtual_cluster_capability_list
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantCapability{
       TenantSpec: $3.tenantSpec(),
       Capabilities: $6.tenantCapabilities(),
@@ -8019,7 +8008,6 @@ alter_virtual_cluster_capability_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec GRANT ALL CAPABILITIES
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantCapability{
       TenantSpec: $3.tenantSpec(),
       AllCapabilities: true,
@@ -8027,7 +8015,6 @@ alter_virtual_cluster_capability_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec REVOKE CAPABILITY virtual_cluster_capability_list
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantCapability{
       TenantSpec: $3.tenantSpec(),
       Capabilities: $6.tenantCapabilities(),
@@ -8036,7 +8023,6 @@ alter_virtual_cluster_capability_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec REVOKE ALL CAPABILITIES
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantCapability{
       TenantSpec: $3.tenantSpec(),
       AllCapabilities: true,


Reviews:
user: login: msbutler
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-09T19:36:13Z
user: login: taroface
body: Just 1 comment/question. Also, I wanted to check if you followed the step (in [step 4](https://cockroachlabs.atlassian.net/wiki/spaces/ED/pages/1134166645/SQL+Grammar+Documentation#Update-diagram-source-and-generate-diagram)) to verify that the actual HTML files have the updated content that you want. If not, I recommend doing this, since this is a more involved change.
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-09T20:16:41Z
user: login: katmayb
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-09T20:23:37Z
user: login: taroface
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-09T20:37:33Z
user: login: taroface
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-09T20:37:46Z
user: login: katmayb
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T19:38:09Z

Review comments:
diff_hunk: @@ -575,6 +575,29 @@ var specs = []stmtSpec{
 		replace: map[string]string{"relation_expr": "view_name", "'RENAME' 'TO' view_name": "'RENAME' 'TO' view_new_name"},
 		unlink:  []string{"view_name", "view_new_name"},
 	},
+	{
+		name:    "alter_virtual_cluster",
+		stmt:    "alter_virtual_cluster_stmt",
+		inline:  []string{"virtual_cluster", "replication_options_list", "alter_virtual_cluster_capability_stmt", "alter_virtual_cluster_replication_stmt", "alter_virtual_cluster_rename_stmt", "alter_virtual_cluster_service_stmt"},
+		replace: map[string]string{"'ON' d_expr": "'ON' physical_cluster", "d_expr": "virtual_cluster_spec", "a_expr": "timestamp"},
+		unlink:  []string{"physical_cluster", "virtual_cluster_spec", "timestamp"},
+	},
+	{
path: pkg/cmd/docgen/diagrams.go
user: login: taroface
body: I'm unclear on why the following 4 entries are necessary, unless you intend to use the separate generated BNF files elsewhere. If you inlined them in the `alter_virtual_cluster` definition, shouldn't they all appear under that single diagram (as you showed in the screenshot)?
created_at: 2025-05-09T20:14:32Z
author_association: COLLABORATOR
diff_hunk: @@ -575,6 +575,29 @@ var specs = []stmtSpec{
 		replace: map[string]string{"relation_expr": "view_name", "'RENAME' 'TO' view_name": "'RENAME' 'TO' view_new_name"},
 		unlink:  []string{"view_name", "view_new_name"},
 	},
+	{
+		name:    "alter_virtual_cluster",
+		stmt:    "alter_virtual_cluster_stmt",
+		inline:  []string{"virtual_cluster", "replication_options_list", "alter_virtual_cluster_capability_stmt", "alter_virtual_cluster_replication_stmt", "alter_virtual_cluster_rename_stmt", "alter_virtual_cluster_service_stmt"},
+		replace: map[string]string{"'ON' d_expr": "'ON' physical_cluster", "d_expr": "virtual_cluster_spec", "a_expr": "timestamp"},
+		unlink:  []string{"physical_cluster", "virtual_cluster_spec", "timestamp"},
+	},
+	{
path: pkg/cmd/docgen/diagrams.go
user: login: katmayb
body: hmmmm, it seemed like they were necessary when I used `dev generate bnf`... that is, I followed the error messages and added the required stmt entries. I can take another look if you've seen that these aren't necessary.
created_at: 2025-05-09T20:23:37Z
author_association: NONE
diff_hunk: @@ -575,6 +575,29 @@ var specs = []stmtSpec{
 		replace: map[string]string{"relation_expr": "view_name", "'RENAME' 'TO' view_name": "'RENAME' 'TO' view_new_name"},
 		unlink:  []string{"view_name", "view_new_name"},
 	},
+	{
+		name:    "alter_virtual_cluster",
+		stmt:    "alter_virtual_cluster_stmt",
+		inline:  []string{"virtual_cluster", "replication_options_list", "alter_virtual_cluster_capability_stmt", "alter_virtual_cluster_replication_stmt", "alter_virtual_cluster_rename_stmt", "alter_virtual_cluster_service_stmt"},
+		replace: map[string]string{"'ON' d_expr": "'ON' physical_cluster", "d_expr": "virtual_cluster_spec", "a_expr": "timestamp"},
+		unlink:  []string{"physical_cluster", "virtual_cluster_spec", "timestamp"},
+	},
+	{
path: pkg/cmd/docgen/diagrams.go
user: login: taroface
body: If you followed the output then I think that's fine!
created_at: 2025-05-09T20:37:33Z
author_association: COLLABORATOR
diff_hunk: @@ -575,6 +575,29 @@ var specs = []stmtSpec{
 		replace: map[string]string{"relation_expr": "view_name", "'RENAME' 'TO' view_name": "'RENAME' 'TO' view_new_name"},
 		unlink:  []string{"view_name", "view_new_name"},
 	},
+	{
+		name:    "alter_virtual_cluster",
+		stmt:    "alter_virtual_cluster_stmt",
+		inline:  []string{"virtual_cluster", "replication_options_list", "alter_virtual_cluster_capability_stmt", "alter_virtual_cluster_replication_stmt", "alter_virtual_cluster_rename_stmt", "alter_virtual_cluster_service_stmt"},
+		replace: map[string]string{"'ON' d_expr": "'ON' physical_cluster", "d_expr": "virtual_cluster_spec", "a_expr": "timestamp"},
+		unlink:  []string{"physical_cluster", "virtual_cluster_spec", "timestamp"},
+	},
+	{
path: pkg/cmd/docgen/diagrams.go
user: login: katmayb
body: Just to note here as well, I followed step 4 and the content looked good 👍 Thanks!
created_at: 2025-05-15T19:38:09Z
author_association: NONE

PR comments:
user: login: blathers-crl[bot]
created_at: 2025-05-09T15:42:01Z
body: It looks like your PR touches production code but doesn't add or edit any test code. Did you consider adding tests to your PR?

It looks like your PR touches SQL parser code but doesn't add or edit parser tests. Please make sure you add or edit parser tests if you edit the parser.

<sub>:owl: Hoot! I am a [Blathers](https://github.com/apps/blathers-crl), a bot for [CockroachDB](https://github.com/cockroachdb). My owner is [dev-inf](https://github.com/orgs/cockroachdb/teams/dev-inf).</sub>
author_association: NONE
user: login: cockroach-teamcity
created_at: 2025-05-09T15:42:06Z
body: 

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/cockroachdb/cockroach/146452)
<!-- Reviewable:end -->

author_association: MEMBER
user: login: katmayb
created_at: 2025-05-09T15:44:42Z
body: <img width="1040" alt="Screenshot 2025-05-08 at 2 13 11 PM" src="https://github.com/user-attachments/assets/2b2e728c-9618-43b1-b3e1-b03d080493e4" />
These included changes would result in the attached image.
author_association: NONE
user: login: katmayb
created_at: 2025-05-13T12:08:33Z
body: bors r=msbutler
author_association: NONE
user: login: craig[bot]
created_at: 2025-05-13T12:50:22Z
body: Build failed:
  * [check_generated_code](https://github.com/cockroachdb/cockroach/actions/runs/14996935438/job/42133367972)
author_association: CONTRIBUTOR
user: login: katmayb
created_at: 2025-05-15T14:53:55Z
body: bors r=msbutler
author_association: NONE
user: login: craig[bot]
created_at: 2025-05-15T15:05:02Z
body: Build failed:
  * [check_generated_code](https://github.com/cockroachdb/cockroach/actions/runs/15048277172/job/42296322767)
author_association: CONTRIBUTOR
user: login: katmayb
created_at: 2025-05-19T20:11:50Z
body: bors r-
author_association: NONE
user: login: katmayb
created_at: 2025-05-19T20:12:42Z
body: bors r+
author_association: NONE
user: login: craig[bot]
created_at: 2025-05-19T21:22:23Z
body: Build succeeded:
  * [lint](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508752319)
  * [linux_amd64_fips_build](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508753718)
  * [local_roachtest_fips](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508753269)
  * [examples_orms](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508751675)
  * [local_roachtest](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508752907)
  * [unit_tests](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508754129)
  * [docker_image_amd64](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508751962)
  * [acceptance](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508751292)
  * [check_generated_code](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508750871)
  * [linux_amd64_build](https://github.com/cockroachdb/cockroach/actions/runs/15122782519/job/42508752607)
author_association: CONTRIBUTOR