diff --git a/docs/generated/sql/bnf/create_index_stmt.bnf b/docs/generated/sql/bnf/create_index_stmt.bnf index 1032956af07c..f381b65b3929 100644 --- a/docs/generated/sql/bnf/create_index_stmt.bnf +++ b/docs/generated/sql/bnf/create_index_stmt.bnf @@ -1,5 +1,5 @@ create_index_stmt ::= - 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name ( 'USING' name | ) '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( 'USING' 'HASH' | ) ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause - | 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name ( 'USING' name | ) '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( 'USING' 'HASH' | ) ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause + 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name ( 'USING' name | ) '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( 'USING' 'HASH' | ) ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause opt_index_visible + | 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name ( 'USING' name | ) '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( 'USING' 'HASH' | ) ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause opt_index_visible diff --git a/docs/generated/sql/bnf/create_index_with_storage_param.bnf b/docs/generated/sql/bnf/create_index_with_storage_param.bnf index 7fca6d8ff188..a13d2068588c 100644 --- a/docs/generated/sql/bnf/create_index_with_storage_param.bnf +++ b/docs/generated/sql/bnf/create_index_with_storage_param.bnf @@ -1,5 +1,5 @@ create_index_stmt ::= - 'CREATE' 'INDEX' opt_index_name 'ON' table_name '(' index_params ')' ( 'WITH' '(' ( ( ( storage_parameter_key '=' var_value ) ) ( ( ',' ( storage_parameter_key '=' var_value ) ) )* ) ')' ) - | 'CREATE' 'INDEX' 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' index_params ')' ( 'WITH' '(' ( ( ( storage_parameter_key '=' var_value ) ) ( ( ',' ( storage_parameter_key '=' var_value ) ) )* ) ')' ) - | 'CREATE' 'INVERTED' 'INDEX' opt_index_name 'ON' table_name '(' index_params ')' ( 'WITH' '(' ( ( ( storage_parameter_key '=' var_value ) ) ( ( ',' ( storage_parameter_key '=' var_value ) ) )* ) ')' ) - | 'CREATE' 'INVERTED' 'INDEX' 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' index_params ')' ( 'WITH' '(' ( ( ( storage_parameter_key '=' var_value ) ) ( ( ',' ( storage_parameter_key '=' var_value ) ) )* ) ')' ) + 'CREATE' 'INDEX' opt_index_name 'ON' table_name '(' index_params ')' ( 'WITH' '(' ( ( ( storage_parameter_key '=' var_value ) ) ( ( ',' ( storage_parameter_key '=' var_value ) ) )* ) ')' ) opt_index_visible + | 'CREATE' 'INDEX' 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' index_params ')' ( 'WITH' '(' ( ( ( storage_parameter_key '=' var_value ) ) ( ( ',' ( storage_parameter_key '=' var_value ) ) )* ) ')' ) opt_index_visible + | 'CREATE' 'INVERTED' 'INDEX' opt_index_name 'ON' table_name '(' index_params ')' ( 'WITH' '(' ( ( ( storage_parameter_key '=' var_value ) ) ( ( ',' ( storage_parameter_key '=' var_value ) ) )* ) ')' ) opt_index_visible + | 'CREATE' 'INVERTED' 'INDEX' 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' index_params ')' ( 'WITH' '(' ( ( ( storage_parameter_key '=' var_value ) ) ( ( ',' ( storage_parameter_key '=' var_value ) ) )* ) ')' ) opt_index_visible diff --git a/docs/generated/sql/bnf/create_inverted_index_stmt.bnf b/docs/generated/sql/bnf/create_inverted_index_stmt.bnf index aeebf9a9335a..aba83281bef5 100644 --- a/docs/generated/sql/bnf/create_inverted_index_stmt.bnf +++ b/docs/generated/sql/bnf/create_inverted_index_stmt.bnf @@ -1,5 +1,5 @@ create_index_stmt ::= - 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name opt_index_access_method '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' opt_hash_sharded ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause - | 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name opt_index_access_method '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' opt_hash_sharded ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause - | 'CREATE' ( 'UNIQUE' | ) 'INVERTED' 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause - | 'CREATE' ( 'UNIQUE' | ) 'INVERTED' 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause + 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name opt_index_access_method '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' opt_hash_sharded ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause opt_index_visible + | 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name opt_index_access_method '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' opt_hash_sharded ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause opt_index_visible + | 'CREATE' ( 'UNIQUE' | ) 'INVERTED' 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause opt_index_visible + | 'CREATE' ( 'UNIQUE' | ) 'INVERTED' 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause opt_index_visible diff --git a/docs/generated/sql/bnf/index_def.bnf b/docs/generated/sql/bnf/index_def.bnf index 02bf12633574..de6fef0a828a 100644 --- a/docs/generated/sql/bnf/index_def.bnf +++ b/docs/generated/sql/bnf/index_def.bnf @@ -1,19 +1,19 @@ index_def ::= - 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'COVERING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'STORING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'INCLUDE' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'COVERING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'STORING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'INCLUDE' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'COVERING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'STORING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'INCLUDE' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'COVERING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'STORING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'INCLUDE' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'INVERTED' 'INDEX' name '(' index_elem ( ( ',' index_elem ) )* ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause - | 'INVERTED' 'INDEX' '(' index_elem ( ( ',' index_elem ) )* ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause + 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'COVERING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'STORING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'INCLUDE' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'COVERING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'STORING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'INCLUDE' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'COVERING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'STORING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'INCLUDE' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'COVERING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'STORING' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'INCLUDE' '(' name_list ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INVERTED' 'INDEX' name '(' index_elem ( ( ',' index_elem ) )* ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INVERTED' 'INDEX' '(' index_elem ( ( ',' index_elem ) )* ')' ( 'PARTITION' ( 'ALL' | ) 'BY' partition_by_inner | ) opt_with_storage_parameter_list opt_where_clause opt_index_visible diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index 2a1c413dfd9a..aea0a8856ede 100644 --- a/docs/generated/sql/bnf/stmt_block.bnf +++ b/docs/generated/sql/bnf/stmt_block.bnf @@ -1620,10 +1620,10 @@ create_database_stmt ::= | 'CREATE' 'DATABASE' 'IF' 'NOT' 'EXISTS' database_name opt_with opt_template_clause opt_encoding_clause opt_lc_collate_clause opt_lc_ctype_clause opt_connection_limit opt_primary_region_clause opt_regions_list opt_survival_goal_clause create_index_stmt ::= - 'CREATE' opt_unique 'INDEX' opt_concurrently opt_index_name 'ON' table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause - | 'CREATE' opt_unique 'INDEX' opt_concurrently 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause - | 'CREATE' opt_unique 'INVERTED' 'INDEX' opt_concurrently opt_index_name 'ON' table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause - | 'CREATE' opt_unique 'INVERTED' 'INDEX' opt_concurrently 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + 'CREATE' opt_unique 'INDEX' opt_concurrently opt_index_name 'ON' table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'CREATE' opt_unique 'INDEX' opt_concurrently 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'CREATE' opt_unique 'INVERTED' 'INDEX' opt_concurrently opt_index_name 'ON' table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'CREATE' opt_unique 'INVERTED' 'INDEX' opt_concurrently 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible create_schema_stmt ::= 'CREATE' 'SCHEMA' qualifiable_schema_name @@ -2268,6 +2268,11 @@ opt_partition_by_index ::= opt_with_storage_parameter_list ::= 'WITH' '(' storage_parameter_list ')' +opt_index_visible ::= + 'NOT' 'VISIBLE' + | 'VISIBLE' + | + opt_schema_name ::= qualifiable_schema_name | @@ -3543,9 +3548,9 @@ storage_parameter_key ::= | 'SCONST' index_def ::= - 'INDEX' opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause - | 'INVERTED' 'INDEX' opt_name '(' index_params ')' opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + 'INDEX' opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'UNIQUE' 'INDEX' opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible + | 'INVERTED' 'INDEX' opt_name '(' index_params ')' opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible like_table_option_list ::= ( ) ( ( 'INCLUDING' like_table_option | 'EXCLUDING' like_table_option ) )* diff --git a/pkg/sql/create_index.go b/pkg/sql/create_index.go index fd3013a45ead..47d442d314c2 100644 --- a/pkg/sql/create_index.go +++ b/pkg/sql/create_index.go @@ -735,6 +735,12 @@ func (n *createIndexNode) startExec(params runParams) error { ) } + if n.n.NotVisible { + return unimplemented.Newf( + "Not Visible Index", + "creating a not visible index is not supported yet") + } + // Warn against creating a non-partitioned index on a partitioned table, // which is undesirable in most cases. // Avoid the warning if we have PARTITION ALL BY as all indexes will implicitly diff --git a/pkg/sql/create_table.go b/pkg/sql/create_table.go index f429c2e8c9f7..368afc222d8b 100644 --- a/pkg/sql/create_table.go +++ b/pkg/sql/create_table.go @@ -708,6 +708,13 @@ func addUniqueWithoutIndexTableDef( "partitioned unique constraints without an index are not supported", ) } + if d.NotVisible { + // Theoretically, this should never happen because this is not supported by + // the parser. This is just a safe check. + return pgerror.Newf(pgcode.IntegrityConstraintViolation, + "creating a unique constraint using UNIQUE WITH NOT VISIBLE INDEX is not supported", + ) + } // If there is a predicate, validate it. var predicate string @@ -1776,6 +1783,11 @@ func NewTableDesc( return nil, pgerror.Newf(pgcode.DuplicateRelation, "duplicate index name: %q", d.Name) } } + if d.NotVisible { + return nil, unimplemented.Newf( + "Not Visible Index", + "creating a not visible index is not supported yet") + } if err := validateColumnsAreAccessible(&desc, d.Columns); err != nil { return nil, err } @@ -1879,6 +1891,11 @@ func NewTableDesc( // We will add the unique constraint below. break } + if d.NotVisible { + return nil, unimplemented.Newf( + "Not Visible Index", + "creating a not visible index is not supported yet") + } // If the index is named, ensure that the name is unique. Unnamed // indexes will be given a unique auto-generated name later on when // AllocateIDs is called. diff --git a/pkg/sql/opt/exec/execbuilder/testdata/not_visible_index b/pkg/sql/opt/exec/execbuilder/testdata/not_visible_index new file mode 100644 index 000000000000..cc509036d0bc --- /dev/null +++ b/pkg/sql/opt/exec/execbuilder/testdata/not_visible_index @@ -0,0 +1,22 @@ +# LogicTest: local + +statement ok +CREATE TABLE t1 (k INT PRIMARY KEY, v INT, geom GEOMETRY) + +statement error pq: unimplemented: creating a not visible index is not supported yet +CREATE INDEX idx_k_invisible ON t1(v) NOT VISIBLE + +statement error pq: unimplemented: creating a not visible index is not supported yet +CREATE INVERTED INDEX idx_c_partial_invisible ON t1(geom) WHERE k >= v AND v = 3 NOT VISIBLE + +statement error pq: unimplemented: creating a not visible index is not supported yet +CREATE UNIQUE INDEX unique_idx ON t1(k) NOT VISIBLE + +statement error pq: unimplemented: creating a not visible index is not supported yet +CREATE TABLE t1_invisible (b INT, INDEX foo (b) WHERE b > 3 NOT VISIBLE) + +statement error pq: unimplemented: creating a not visible index is not supported yet +CREATE TABLE t2_invisible (k INT PRIMARY KEY, v INT, i INT, p INT, INDEX idx_v_invisible (v) NOT VISIBLE) + +statement error pq: unimplemented: creating a not visible index is not supported yet +CREATE TABLE t3_invisible (b INT, UNIQUE INDEX foo (b) WHERE b > 3 NOT VISIBLE) diff --git a/pkg/sql/opt/exec/execbuilder/tests/local/generated_test.go b/pkg/sql/opt/exec/execbuilder/tests/local/generated_test.go index c3f21645304e..eeba5bf2c292 100644 --- a/pkg/sql/opt/exec/execbuilder/tests/local/generated_test.go +++ b/pkg/sql/opt/exec/execbuilder/tests/local/generated_test.go @@ -337,6 +337,13 @@ func TestExecBuild_mvcc( runExecBuildLogicTest(t, "mvcc") } +func TestExecBuild_not_visible_index( + t *testing.T, +) { + defer leaktest.AfterTest(t)() + runExecBuildLogicTest(t, "not_visible_index") +} + func TestExecBuild_orderby( t *testing.T, ) { diff --git a/pkg/sql/opt/indexrec/hypothetical_index.go b/pkg/sql/opt/indexrec/hypothetical_index.go index e48c3349f63a..b9a6398192b8 100644 --- a/pkg/sql/opt/indexrec/hypothetical_index.go +++ b/pkg/sql/opt/indexrec/hypothetical_index.go @@ -114,7 +114,7 @@ func (hi *hypotheticalIndex) IsInverted() bool { // IsNotVisible is part of the cat.Index interface. func (hi *hypotheticalIndex) IsNotVisible() bool { // A hypotheticalIndex should not be invisible because there is no motivation - // to recommend an invisible index. + // to recommend a not visible index. return false } diff --git a/pkg/sql/opt/indexrec/hypothetical_table.go b/pkg/sql/opt/indexrec/hypothetical_table.go index 784f720cd1f5..6ccd9b4f7d9d 100644 --- a/pkg/sql/opt/indexrec/hypothetical_table.go +++ b/pkg/sql/opt/indexrec/hypothetical_table.go @@ -60,7 +60,7 @@ func BuildOptAndHypTableMaps( // index with the same key. Inverted indexes do not have stored columns, // so we should not make a recommendation if the same index already // exists. - // TODO(wenyihu6): We should still consider invisible indexes and make a + // TODO(wenyihu6): We should still consider not visible indexes and make a // recommendation to mark the index as visible if it is chosen. if !inverted || hypTable.existingRedundantIndex(&hypIndex) == nil { hypIndexes = append(hypIndexes, hypIndex) diff --git a/pkg/sql/opt/testutils/testcat/BUILD.bazel b/pkg/sql/opt/testutils/testcat/BUILD.bazel index 8a6a47a7c08a..417633a99f55 100644 --- a/pkg/sql/opt/testutils/testcat/BUILD.bazel +++ b/pkg/sql/opt/testutils/testcat/BUILD.bazel @@ -49,6 +49,7 @@ go_library( "//pkg/sql/types", "//pkg/sql/vtable", "//pkg/util", + "//pkg/util/errorutil/unimplemented", "//pkg/util/treeprinter", "@com_github_cockroachdb_errors//:errors", "@com_github_lib_pq//oid", diff --git a/pkg/sql/opt/testutils/testcat/create_index.go b/pkg/sql/opt/testutils/testcat/create_index.go index 25c98279b844..fdb63ba4c992 100644 --- a/pkg/sql/opt/testutils/testcat/create_index.go +++ b/pkg/sql/opt/testutils/testcat/create_index.go @@ -40,6 +40,7 @@ func (tc *Catalog) CreateIndex(stmt *tree.CreateIndex, version descpb.IndexDescr Inverted: stmt.Inverted, PartitionByIndex: stmt.PartitionByIndex, Predicate: stmt.Predicate, + NotVisible: stmt.NotVisible, } idxType := nonUniqueIndex diff --git a/pkg/sql/opt/testutils/testcat/create_table.go b/pkg/sql/opt/testutils/testcat/create_table.go index 820d7067aa6a..221619b558d0 100644 --- a/pkg/sql/opt/testutils/testcat/create_table.go +++ b/pkg/sql/opt/testutils/testcat/create_table.go @@ -30,6 +30,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sessiondatapb" "github.com/cockroachdb/cockroach/pkg/sql/types" "github.com/cockroachdb/cockroach/pkg/util" + "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" ) type indexType int @@ -704,6 +705,10 @@ func (tt *Table) addIndexWithVersion( tt.addUniqueConstraint(def.Name, def.Columns, def.Predicate, false /* withoutIndex */) } + if def.NotVisible { + panic(unimplemented.Newf("Not Visible Index", "creating a not visible index is not supported yet")) + } + idx := &Index{ IdxName: tt.makeIndexName(def.Name, def.Columns, typ), Unique: typ != nonUniqueIndex, diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index f822ad983ac2..f90e8b955b92 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -1360,7 +1360,7 @@ func (u *sqlSymUnion) routineBody() *tree.RoutineBody { %type overlay_placing %type opt_unique opt_concurrently opt_cluster opt_without_index -%type opt_index_access_method +%type opt_index_access_method opt_index_visible %type <*tree.Limit> limit_clause offset_clause opt_limit_clause %type select_fetch_first_value @@ -8150,7 +8150,7 @@ generated_by_default_as: GENERATED_BY_DEFAULT BY DEFAULT AS {} index_def: - INDEX opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + INDEX opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible { $$.val = &tree.IndexTableDef{ Name: tree.Name($2), @@ -8160,9 +8160,10 @@ index_def: PartitionByIndex: $8.partitionByIndex(), StorageParams: $9.storageParams(), Predicate: $10.expr(), + NotVisible: $11.bool(), } } -| UNIQUE INDEX opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause +| UNIQUE INDEX opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible { $$.val = &tree.UniqueConstraintTableDef{ IndexTableDef: tree.IndexTableDef { @@ -8173,10 +8174,11 @@ index_def: PartitionByIndex: $9.partitionByIndex(), StorageParams: $10.storageParams(), Predicate: $11.expr(), + NotVisible: $12.bool(), }, } } -| INVERTED INDEX opt_name '(' index_params ')' opt_partition_by_index opt_with_storage_parameter_list opt_where_clause +| INVERTED INDEX opt_name '(' index_params ')' opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible { $$.val = &tree.IndexTableDef{ Name: tree.Name($3), @@ -8185,6 +8187,7 @@ index_def: PartitionByIndex: $7.partitionByIndex(), StorageParams: $8.storageParams(), Predicate: $9.expr(), + NotVisible: $10.bool(), } } @@ -9028,7 +9031,7 @@ enum_val_list: // %SeeAlso: CREATE TABLE, SHOW INDEXES, SHOW CREATE, // WEBDOCS/create-index.html create_index_stmt: - CREATE opt_unique INDEX opt_concurrently opt_index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + CREATE opt_unique INDEX opt_concurrently opt_index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible { table := $7.unresolvedObjectName().ToTableName() $$.val = &tree.CreateIndex{ @@ -9043,9 +9046,10 @@ create_index_stmt: Predicate: $16.expr(), Inverted: $8.bool(), Concurrently: $4.bool(), + NotVisible: $17.bool(), } } -| CREATE opt_unique INDEX opt_concurrently IF NOT EXISTS index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause +| CREATE opt_unique INDEX opt_concurrently IF NOT EXISTS index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible { table := $10.unresolvedObjectName().ToTableName() $$.val = &tree.CreateIndex{ @@ -9061,9 +9065,10 @@ create_index_stmt: StorageParams: $18.storageParams(), Predicate: $19.expr(), Concurrently: $4.bool(), + NotVisible: $20.bool(), } } -| CREATE opt_unique INVERTED INDEX opt_concurrently opt_index_name ON table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause +| CREATE opt_unique INVERTED INDEX opt_concurrently opt_index_name ON table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible { table := $8.unresolvedObjectName().ToTableName() $$.val = &tree.CreateIndex{ @@ -9077,9 +9082,10 @@ create_index_stmt: StorageParams: $14.storageParams(), Predicate: $15.expr(), Concurrently: $5.bool(), + NotVisible: $16.bool(), } } -| CREATE opt_unique INVERTED INDEX opt_concurrently IF NOT EXISTS index_name ON table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause +| CREATE opt_unique INVERTED INDEX opt_concurrently IF NOT EXISTS index_name ON table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible { table := $11.unresolvedObjectName().ToTableName() $$.val = &tree.CreateIndex{ @@ -9094,6 +9100,7 @@ create_index_stmt: StorageParams: $17.storageParams(), Predicate: $18.expr(), Concurrently: $5.bool(), + NotVisible: $19.bool(), } } | CREATE opt_unique INDEX error // SHOW HELP: CREATE INDEX @@ -9213,6 +9220,20 @@ opt_asc_desc: $$.val = tree.DefaultDirection } +opt_index_visible: + NOT VISIBLE + { + $$.val = true + } +| VISIBLE + { + $$.val = false + } +| /* EMPTY */ + { + $$.val = false + } + alter_database_to_schema_stmt: ALTER DATABASE database_name CONVERT TO SCHEMA WITH PARENT database_name { diff --git a/pkg/sql/parser/testdata/create_index b/pkg/sql/parser/testdata/create_index index eb374741d473..7ed5040935e3 100644 --- a/pkg/sql/parser/testdata/create_index +++ b/pkg/sql/parser/testdata/create_index @@ -379,3 +379,68 @@ CREATE INVERTED INDEX ON a ((ARRAY[a, b])) CREATE INVERTED INDEX ON a (((ARRAY[(a), (b)]))) -- fully parenthesized CREATE INVERTED INDEX ON a ((ARRAY[a, b])) -- literals removed CREATE INVERTED INDEX ON _ ((ARRAY[_, _])) -- identifiers removed + +# The following test cases check parsing support for creating a not visible index. +parse +CREATE INDEX a ON b (c) VISIBLE +---- +CREATE INDEX a ON b (c) -- normalized! +CREATE INDEX a ON b (c) -- fully parenthesized +CREATE INDEX a ON b (c) -- literals removed +CREATE INDEX _ ON _ (_) -- identifiers removed + +parse +CREATE INDEX a ON b.c (d) NOT VISIBLE +---- +CREATE INDEX a ON b.c (d) NOT VISIBLE +CREATE INDEX a ON b.c (d) NOT VISIBLE -- fully parenthesized +CREATE INDEX a ON b.c (d) NOT VISIBLE -- literals removed +CREATE INDEX _ ON _._ (_) NOT VISIBLE -- identifiers removed + +parse +CREATE INDEX ON a ((ARRAY[a, b])) STORING (c, d) NOT VISIBLE +---- +CREATE INDEX ON a ((ARRAY[a, b])) STORING (c, d) NOT VISIBLE +CREATE INDEX ON a (((ARRAY[(a), (b)]))) STORING (c, d) NOT VISIBLE -- fully parenthesized +CREATE INDEX ON a ((ARRAY[a, b])) STORING (c, d) NOT VISIBLE -- literals removed +CREATE INDEX ON _ ((ARRAY[_, _])) STORING (_, _) NOT VISIBLE -- identifiers removed + +parse +CREATE INDEX a ON b (c) WITH (fillfactor = 100, y_bounds = 50) NOT VISIBLE +---- +CREATE INDEX a ON b (c) WITH (fillfactor = 100, y_bounds = 50) NOT VISIBLE +CREATE INDEX a ON b (c) WITH (fillfactor = (100), y_bounds = (50)) NOT VISIBLE -- fully parenthesized +CREATE INDEX a ON b (c) WITH (fillfactor = _, y_bounds = _) NOT VISIBLE -- literals removed +CREATE INDEX _ ON _ (_) WITH (_ = 100, _ = 50) NOT VISIBLE -- identifiers removed + +parse +CREATE UNIQUE INDEX idx ON a (((lower(a) || ' ') || lower(b))) NOT VISIBLE +---- +CREATE UNIQUE INDEX idx ON a (((lower(a) || ' ') || lower(b))) NOT VISIBLE +CREATE UNIQUE INDEX idx ON a (((((((lower((a))) || (' ')))) || (lower((b)))))) NOT VISIBLE -- fully parenthesized +CREATE UNIQUE INDEX idx ON a (((lower(a) || '_') || lower(b))) NOT VISIBLE -- literals removed +CREATE UNIQUE INDEX _ ON _ (((lower(_) || ' ') || lower(_))) NOT VISIBLE -- identifiers removed + +parse +CREATE INVERTED INDEX IF NOT EXISTS a ON b (c) WHERE d > 3 VISIBLE +---- +CREATE INVERTED INDEX IF NOT EXISTS a ON b (c) WHERE d > 3 -- normalized! +CREATE INVERTED INDEX IF NOT EXISTS a ON b (c) WHERE ((d) > (3)) -- fully parenthesized +CREATE INVERTED INDEX IF NOT EXISTS a ON b (c) WHERE d > _ -- literals removed +CREATE INVERTED INDEX IF NOT EXISTS _ ON _ (_) WHERE _ > 3 -- identifiers removed + +parse +CREATE INDEX geom_idx_2 ON some_spatial_table USING GIST(geom) WITH (s2_max_cells = 20, s2_max_level = 12, s2_level_mod = 3) NOT VISIBLE +---- +CREATE INVERTED INDEX geom_idx_2 ON some_spatial_table (geom) WITH (s2_max_cells = 20, s2_max_level = 12, s2_level_mod = 3) NOT VISIBLE -- normalized! +CREATE INVERTED INDEX geom_idx_2 ON some_spatial_table (geom) WITH (s2_max_cells = (20), s2_max_level = (12), s2_level_mod = (3)) NOT VISIBLE -- fully parenthesized +CREATE INVERTED INDEX geom_idx_2 ON some_spatial_table (geom) WITH (s2_max_cells = _, s2_max_level = _, s2_level_mod = _) NOT VISIBLE -- literals removed +CREATE INVERTED INDEX _ ON _ (_) WITH (_ = 20, _ = 12, _ = 3) NOT VISIBLE -- identifiers removed + +parse +CREATE UNIQUE INDEX IF NOT EXISTS a ON b (c) WHERE d > 3 NOT VISIBLE +---- +CREATE UNIQUE INDEX IF NOT EXISTS a ON b (c) WHERE d > 3 NOT VISIBLE +CREATE UNIQUE INDEX IF NOT EXISTS a ON b (c) WHERE ((d) > (3)) NOT VISIBLE -- fully parenthesized +CREATE UNIQUE INDEX IF NOT EXISTS a ON b (c) WHERE d > _ NOT VISIBLE -- literals removed +CREATE UNIQUE INDEX IF NOT EXISTS _ ON _ (_) WHERE _ > 3 NOT VISIBLE -- identifiers removed diff --git a/pkg/sql/parser/testdata/create_table b/pkg/sql/parser/testdata/create_table index fe3c018ddd44..0d22b1416f6f 100644 --- a/pkg/sql/parser/testdata/create_table +++ b/pkg/sql/parser/testdata/create_table @@ -2406,3 +2406,73 @@ CREATE TABLE visible (visible INT4) CREATE TABLE visible (visible INT4) -- fully parenthesized CREATE TABLE visible (visible INT4) -- literals removed CREATE TABLE _ (_ INT4) -- identifiers removed + +# The following test cases check parsing support for creating a not visible index. +parse +CREATE TABLE a (b INT8, c STRING, INDEX (b ASC, c DESC) STORING (c) NOT VISIBLE) +---- +CREATE TABLE a (b INT8, c STRING, INDEX (b ASC, c DESC) STORING (c) NOT VISIBLE) +CREATE TABLE a (b INT8, c STRING, INDEX (b ASC, c DESC) STORING (c) NOT VISIBLE) -- fully parenthesized +CREATE TABLE a (b INT8, c STRING, INDEX (b ASC, c DESC) STORING (c) NOT VISIBLE) -- literals removed +CREATE TABLE _ (_ INT8, _ STRING, INDEX (_ ASC, _ DESC) STORING (_) NOT VISIBLE) -- identifiers removed + +parse +CREATE TABLE a (b INT8, c STRING, INVERTED INDEX (b ASC, c DESC) WHERE c > 3 NOT VISIBLE) +---- +CREATE TABLE a (b INT8, c STRING, INVERTED INDEX (b ASC, c DESC) WHERE c > 3 NOT VISIBLE) +CREATE TABLE a (b INT8, c STRING, INVERTED INDEX (b ASC, c DESC) WHERE ((c) > (3)) NOT VISIBLE) -- fully parenthesized +CREATE TABLE a (b INT8, c STRING, INVERTED INDEX (b ASC, c DESC) WHERE c > _ NOT VISIBLE) -- literals removed +CREATE TABLE _ (_ INT8, _ STRING, INVERTED INDEX (_ ASC, _ DESC) WHERE _ > 3 NOT VISIBLE) -- identifiers removed + +# Creating an invisible unique index inside a table definition is supported by +# the grammar rule, but the parser will throw an error for the following +# statement. This is because the parser is doing a round trip in +# `pkg/testutils/sqlutils/pretty.go`. In sql.y, creating an unique index in a +# CREATE TABLE statement returns a new structure tree.UniqueConstraintTableDef. +# However, creating a unique constraint with not visible index is not supported by +# the parser. When the parser does a round trip for the following statement, it +# formats it to a pretty statement using the unique constraint definition. But +# the parser does not support unique constraint with not visible index syntax. So +# it will fail while parsing the pretty statement. Since logictest also performs +# a roundtrip check in pkg/sql/logictest/logic.go, logictest would also fail. +# But the following statement would still work in a cluster. +# This is a known issue. See more details in +# https://github.com/cockroachdb/cockroach/pull/65825. +error +CREATE TABLE a (b INT, UNIQUE INDEX foo (b) WHERE c > 3 NOT VISIBLE) +---- + +# The following test cases make sure that creating an invisible primary index is +# not supported by the parser. +error +CREATE TABLE a (b INT8 PRIMARY KEY NOT VISIBLE) +---- + +error +CREATE TABLE a (b INT8, c STRING, PRIMARY KEY (b, c, "0") NOT VISIBLE) +---- +at or near "visible": syntax error +DETAIL: source SQL: +CREATE TABLE a (b INT8, c STRING, PRIMARY KEY (b, c, "0") NOT VISIBLE) + ^ +HINT: try \h CREATE TABLE + +# The following test cases make sure that creating any constraints with +# not visible index is not supported by the parser. +error +CREATE TABLE a (b INT8, c STRING, CONSTRAINT d UNIQUE (b, c) NOT VISIBLE) +---- +at or near "visible": syntax error +DETAIL: source SQL: +CREATE TABLE a (b INT8, c STRING, CONSTRAINT d UNIQUE (b, c) NOT VISIBLE) + ^ +HINT: try \h CREATE TABLE + +error +CREATE TABLE a (b INT8, c STRING, CONSTRAINT d UNIQUE WITHOUT INDEX (b, c) NOT VISIBLE) +---- +at or near "visible": syntax error +DETAIL: source SQL: +CREATE TABLE a (b INT8, c STRING, CONSTRAINT d UNIQUE WITHOUT INDEX (b, c) NOT VISIBLE) + ^ +HINT: try \h CREATE TABLE diff --git a/pkg/sql/sem/tree/create.go b/pkg/sql/sem/tree/create.go index d82a1432cc5b..c1a07da5c44b 100644 --- a/pkg/sql/sem/tree/create.go +++ b/pkg/sql/sem/tree/create.go @@ -232,6 +232,7 @@ type CreateIndex struct { StorageParams StorageParams Predicate Expr Concurrently bool + NotVisible bool } // Format implements the NodeFormatter interface. @@ -283,6 +284,9 @@ func (node *CreateIndex) Format(ctx *FmtCtx) { ctx.WriteString(" WHERE ") ctx.FormatNode(node.Predicate) } + if node.NotVisible { + ctx.WriteString(" NOT VISIBLE") + } } // CreateTypeVariety represents a particular variety of user defined types. @@ -978,6 +982,7 @@ type IndexTableDef struct { PartitionByIndex *PartitionByIndex StorageParams StorageParams Predicate Expr + NotVisible bool } // Format implements the NodeFormatter interface. @@ -1013,6 +1018,9 @@ func (node *IndexTableDef) Format(ctx *FmtCtx) { ctx.WriteString(" WHERE ") ctx.FormatNode(node.Predicate) } + if node.NotVisible { + ctx.WriteString(" NOT VISIBLE") + } } // ConstraintTableDef represents a constraint definition within a CREATE TABLE @@ -1090,6 +1098,9 @@ func (node *UniqueConstraintTableDef) Format(ctx *FmtCtx) { ctx.WriteString(" WHERE ") ctx.FormatNode(node.Predicate) } + if node.NotVisible { + ctx.WriteString(" NOT VISIBLE") + } } // ReferenceAction is the method used to maintain referential integrity through diff --git a/pkg/sql/sem/tree/pretty.go b/pkg/sql/sem/tree/pretty.go index b1c4fab5d784..5f8515b712be 100644 --- a/pkg/sql/sem/tree/pretty.go +++ b/pkg/sql/sem/tree/pretty.go @@ -1609,6 +1609,7 @@ func (node *CreateIndex) doc(p *PrettyCfg) pretty.Doc { // [PARTITION BY ...] // [WITH ...] // [WHERE ...] + // [NOT VISIBLE] // title := make([]pretty.Doc, 0, 6) title = append(title, pretty.Keyword("CREATE")) @@ -1658,6 +1659,9 @@ func (node *CreateIndex) doc(p *PrettyCfg) pretty.Doc { if node.Predicate != nil { clauses = append(clauses, p.nestUnder(pretty.Keyword("WHERE"), p.Doc(node.Predicate))) } + if node.NotVisible { + clauses = append(clauses, pretty.Keyword(" NOT VISIBLE")) + } return p.nestUnder( pretty.Fold(pretty.ConcatSpace, title...), pretty.Group(pretty.Stack(clauses...))) @@ -1695,6 +1699,7 @@ func (node *IndexTableDef) doc(p *PrettyCfg) pretty.Doc { // [INTERLEAVE ...] // [PARTITION BY ...] // [WHERE ...] + // [NOT VISIBLE] // title := pretty.Keyword("INDEX") if node.Name != "" { @@ -1727,6 +1732,9 @@ func (node *IndexTableDef) doc(p *PrettyCfg) pretty.Doc { if node.Predicate != nil { clauses = append(clauses, p.nestUnder(pretty.Keyword("WHERE"), p.Doc(node.Predicate))) } + if node.NotVisible { + clauses = append(clauses, pretty.Keyword(" NOT VISIBLE")) + } if len(clauses) == 0 { return title @@ -1742,6 +1750,7 @@ func (node *UniqueConstraintTableDef) doc(p *PrettyCfg) pretty.Doc { // [INTERLEAVE ...] // [PARTITION BY ...] // [WHERE ...] + // [NOT VISIBLE] // // or (no constraint name): // @@ -1750,6 +1759,7 @@ func (node *UniqueConstraintTableDef) doc(p *PrettyCfg) pretty.Doc { // [INTERLEAVE ...] // [PARTITION BY ...] // [WHERE ...] + // [NOT VISIBLE] // clauses := make([]pretty.Doc, 0, 5) var title pretty.Doc @@ -1782,6 +1792,9 @@ func (node *UniqueConstraintTableDef) doc(p *PrettyCfg) pretty.Doc { if node.Predicate != nil { clauses = append(clauses, p.nestUnder(pretty.Keyword("WHERE"), p.Doc(node.Predicate))) } + if node.NotVisible { + clauses = append(clauses, pretty.Keyword(" NOT VISIBLE")) + } if len(clauses) == 0 { return title