github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/doltdb/system_table.go (about)

     1  // Copyright 2019 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package doltdb
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"sort"
    21  	"strings"
    22  
    23  	"github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo"
    24  
    25  	"github.com/dolthub/dolt/go/libraries/doltcore/schema"
    26  	"github.com/dolthub/dolt/go/libraries/utils/funcitr"
    27  	"github.com/dolthub/dolt/go/libraries/utils/set"
    28  	"github.com/dolthub/dolt/go/store/types"
    29  )
    30  
    31  const (
    32  	// DoltNamespace is the name prefix of dolt system tables. We reserve all tables that begin with dolt_ for system use.
    33  	DoltNamespace = "dolt"
    34  )
    35  
    36  var ErrSystemTableCannotBeModified = errors.New("system tables cannot be dropped or altered")
    37  
    38  var OldDocsSchema = schema.MustSchemaFromCols(schema.NewColCollection(
    39  	schema.NewColumn(DocPkColumnName, schema.DocNameTag, types.StringKind, true, schema.NotNullConstraint{}),
    40  	schema.NewColumn(DocTextColumnName, schema.DocTextTag, types.StringKind, false),
    41  ))
    42  
    43  var DocsSchema schema.Schema
    44  
    45  func init() {
    46  	docTextCol, err := schema.NewColumnWithTypeInfo(DocTextColumnName, schema.DocTextTag, typeinfo.LongTextType, false, "", false, "")
    47  	if err != nil {
    48  		panic(err)
    49  	}
    50  	doltDocsColumns := schema.NewColCollection(
    51  		schema.NewColumn(DocPkColumnName, schema.DocNameTag, types.StringKind, true, schema.NotNullConstraint{}),
    52  		docTextCol,
    53  	)
    54  	DocsSchema = schema.MustSchemaFromCols(doltDocsColumns)
    55  }
    56  
    57  // HasDoltPrefix returns a boolean whether or not the provided string is prefixed with the DoltNamespace. Users should
    58  // not be able to create tables in this reserved namespace.
    59  func HasDoltPrefix(s string) bool {
    60  	return strings.HasPrefix(strings.ToLower(s), DoltNamespace)
    61  }
    62  
    63  // IsFullTextTable returns a boolean stating whether the given table is one of the pseudo-index tables used by Full-Text
    64  // indexes.
    65  func IsFullTextTable(name string) bool {
    66  	return HasDoltPrefix(name) && (strings.HasSuffix(name, "_fts_config") ||
    67  		strings.HasSuffix(name, "_fts_position") ||
    68  		strings.HasSuffix(name, "_fts_doc_count") ||
    69  		strings.HasSuffix(name, "_fts_global_count") ||
    70  		strings.HasSuffix(name, "_fts_row_count"))
    71  }
    72  
    73  // IsReadOnlySystemTable returns whether the table name given is a system table that should not be included in command line
    74  // output (e.g. dolt status) by default.
    75  func IsReadOnlySystemTable(name string) bool {
    76  	return HasDoltPrefix(name) && !set.NewStrSet(writeableSystemTables).Contains(name) && !IsFullTextTable(name)
    77  }
    78  
    79  // IsNonAlterableSystemTable returns whether the table name given is a system table that cannot be dropped or altered
    80  // by the user.
    81  func IsNonAlterableSystemTable(name string) bool {
    82  	return (IsReadOnlySystemTable(name) && !IsFullTextTable(name)) || strings.ToLower(name) == SchemasTableName
    83  }
    84  
    85  // GetNonSystemTableNames gets non-system table names
    86  func GetNonSystemTableNames(ctx context.Context, root RootValue) ([]string, error) {
    87  	tn, err := root.GetTableNames(ctx, DefaultSchemaName)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  	tn = funcitr.FilterStrings(tn, func(n string) bool {
    92  		return !HasDoltPrefix(n)
    93  	})
    94  	sort.Strings(tn)
    95  	return tn, nil
    96  }
    97  
    98  // GetSystemTableNames gets system table names
    99  func GetSystemTableNames(ctx context.Context, root RootValue) ([]string, error) {
   100  	p, err := GetPersistedSystemTables(ctx, root)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  
   105  	g, err := GetGeneratedSystemTables(ctx, root)
   106  	if err != nil {
   107  
   108  	}
   109  
   110  	s := append(p, g...)
   111  	sort.Strings(s)
   112  
   113  	return s, nil
   114  }
   115  
   116  // GetPersistedSystemTables returns table names of all persisted system tables.
   117  func GetPersistedSystemTables(ctx context.Context, root RootValue) ([]string, error) {
   118  	tn, err := root.GetTableNames(ctx, DefaultSchemaName)
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  	sort.Strings(tn)
   123  	return funcitr.FilterStrings(tn, HasDoltPrefix), nil
   124  }
   125  
   126  // GetGeneratedSystemTables returns table names of all generated system tables.
   127  func GetGeneratedSystemTables(ctx context.Context, root RootValue) ([]string, error) {
   128  	s := set.NewStrSet(generatedSystemTables)
   129  
   130  	tn, err := root.GetTableNames(ctx, DefaultSchemaName)
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  
   135  	for _, pre := range generatedSystemTablePrefixes {
   136  		s.Add(funcitr.MapStrings(tn, func(s string) string { return pre + s })...)
   137  	}
   138  
   139  	return s.AsSlice(), nil
   140  }
   141  
   142  // GetAllTableNames returns table names for all persisted and generated tables.
   143  func GetAllTableNames(ctx context.Context, root RootValue) ([]string, error) {
   144  	n, err := GetNonSystemTableNames(ctx, root)
   145  	if err != nil {
   146  		return nil, err
   147  	}
   148  	s, err := GetSystemTableNames(ctx, root)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	return append(n, s...), nil
   153  }
   154  
   155  // The set of reserved dolt_ tables that should be considered part of user space, like any other user-created table,
   156  // for the purposes of the dolt command line. These tables cannot be created or altered explicitly, but can be updated
   157  // like normal SQL tables.
   158  var writeableSystemTables = []string{
   159  	DocTableName,
   160  	DoltQueryCatalogTableName,
   161  	SchemasTableName,
   162  	ProceduresTableName,
   163  	IgnoreTableName,
   164  	RebaseTableName,
   165  }
   166  
   167  var persistedSystemTables = []string{
   168  	DocTableName,
   169  	DoltQueryCatalogTableName,
   170  	SchemasTableName,
   171  	ProceduresTableName,
   172  	IgnoreTableName,
   173  }
   174  
   175  var generatedSystemTables = []string{
   176  	BranchesTableName,
   177  	RemoteBranchesTableName,
   178  	LogTableName,
   179  	TableOfTablesInConflictName,
   180  	TableOfTablesWithViolationsName,
   181  	CommitsTableName,
   182  	CommitAncestorsTableName,
   183  	StatusTableName,
   184  	RemotesTableName,
   185  }
   186  
   187  var generatedSystemViewPrefixes = []string{
   188  	DoltBlameViewPrefix,
   189  }
   190  
   191  var generatedSystemTablePrefixes = []string{
   192  	DoltDiffTablePrefix,
   193  	DoltCommitDiffTablePrefix,
   194  	DoltHistoryTablePrefix,
   195  	DoltConfTablePrefix,
   196  	DoltConstViolTablePrefix,
   197  }
   198  
   199  const (
   200  	// LicenseDoc is the key for accessing the license within the docs table
   201  	LicenseDoc = "LICENSE.md"
   202  	// ReadmeDoc is the key for accessing the readme within the docs table
   203  	ReadmeDoc = "README.md"
   204  )
   205  
   206  const (
   207  	// DocTableName is the name of the dolt table containing documents such as the license and readme
   208  	DocTableName = "dolt_docs"
   209  	// DocPkColumnName is the name of the pk column in the docs table
   210  	DocPkColumnName = "doc_name"
   211  	//DocTextColumnName is the name of the column containing the document contents in the docs table
   212  	DocTextColumnName = "doc_text"
   213  )
   214  
   215  const (
   216  	// DoltQueryCatalogTableName is the name of the query catalog table
   217  	DoltQueryCatalogTableName = "dolt_query_catalog"
   218  
   219  	// QueryCatalogIdCol is the name of the primary key column of the query catalog table
   220  	QueryCatalogIdCol = "id"
   221  
   222  	// QueryCatalogOrderCol is the column containing the order of the queries in the catalog
   223  	QueryCatalogOrderCol = "display_order"
   224  
   225  	// QueryCatalogNameCol is the name of the column containing the name of a query in the catalog
   226  	QueryCatalogNameCol = "name"
   227  
   228  	// QueryCatalogQueryCol is the name of the column containing the query of a catalog entry
   229  	QueryCatalogQueryCol = "query"
   230  
   231  	// QueryCatalogDescriptionCol is the name of the column containing the description of a query in the catalog
   232  	QueryCatalogDescriptionCol = "description"
   233  )
   234  
   235  const (
   236  	// SchemasTableName is the name of the dolt schema fragment table
   237  	SchemasTableName = "dolt_schemas"
   238  	// SchemasTablesIdCol is an incrementing integer that represents the insertion index.
   239  	// Deprecated: This column is no longer used and will be removed in a future release.
   240  	SchemasTablesIdCol = "id"
   241  	// SchemasTablesTypeCol is the name of the column that stores the type of a schema fragment  in the dolt_schemas table
   242  	SchemasTablesTypeCol = "type"
   243  	// SchemasTablesNameCol The name of the column that stores the name of a schema fragment in the dolt_schemas table
   244  	SchemasTablesNameCol = "name"
   245  	// SchemasTablesFragmentCol The name of the column that stores the SQL fragment of a schema element in the
   246  	// dolt_schemas table
   247  	SchemasTablesFragmentCol = "fragment"
   248  	// SchemasTablesExtraCol The name of the column that stores extra information about a schema element in the
   249  	// dolt_schemas table
   250  	SchemasTablesExtraCol = "extra"
   251  	// SchemasTablesSqlModeCol is the name of the column that stores the SQL_MODE string used when this fragment
   252  	// was originally defined. Mode settings, such as ANSI_QUOTES, are needed to correctly parse the fragment.
   253  	SchemasTablesSqlModeCol = "sql_mode"
   254  )
   255  
   256  const (
   257  	// DoltBlameViewPrefix is the prefix assigned to all the generated blame tables
   258  	DoltBlameViewPrefix = "dolt_blame_"
   259  	// DoltHistoryTablePrefix is the prefix assigned to all the generated history tables
   260  	DoltHistoryTablePrefix = "dolt_history_"
   261  	// DoltDiffTablePrefix is the prefix assigned to all the generated diff tables
   262  	DoltDiffTablePrefix = "dolt_diff_"
   263  	// DoltCommitDiffTablePrefix is the prefix assigned to all the generated commit diff tables
   264  	DoltCommitDiffTablePrefix = "dolt_commit_diff_"
   265  	// DoltConfTablePrefix is the prefix assigned to all the generated conflict tables
   266  	DoltConfTablePrefix = "dolt_conflicts_"
   267  	// DoltConstViolTablePrefix is the prefix assigned to all the generated constraint violation tables
   268  	DoltConstViolTablePrefix = "dolt_constraint_violations_"
   269  )
   270  
   271  const (
   272  	// LogTableName is the log system table name
   273  	LogTableName = "dolt_log"
   274  
   275  	// DiffTableName is the name of the table with a map of commits to tables changed
   276  	DiffTableName = "dolt_diff"
   277  
   278  	// ColumnDiffTableName is the name of the table with a map of commits to tables and columns changed
   279  	ColumnDiffTableName = "dolt_column_diff"
   280  
   281  	// TableOfTablesInConflictName is the conflicts system table name
   282  	TableOfTablesInConflictName = "dolt_conflicts"
   283  
   284  	// TableOfTablesWithViolationsName is the constraint violations system table name
   285  	TableOfTablesWithViolationsName = "dolt_constraint_violations"
   286  
   287  	// SchemaConflictsTableName is the schema conflicts system table name
   288  	SchemaConflictsTableName = "dolt_schema_conflicts"
   289  
   290  	// BranchesTableName is the branches system table name
   291  	BranchesTableName = "dolt_branches"
   292  
   293  	// RemoteBranchesTableName is the all-branches system table name
   294  	RemoteBranchesTableName = "dolt_remote_branches"
   295  
   296  	// RemotesTableName is the remotes system table name
   297  	RemotesTableName = "dolt_remotes"
   298  
   299  	// CommitsTableName is the commits system table name
   300  	CommitsTableName = "dolt_commits"
   301  
   302  	// CommitAncestorsTableName is the commit_ancestors system table name
   303  	CommitAncestorsTableName = "dolt_commit_ancestors"
   304  
   305  	// StatusTableName is the status system table name.
   306  	StatusTableName = "dolt_status"
   307  
   308  	// MergeStatusTableName is the merge status system table name.
   309  	MergeStatusTableName = "dolt_merge_status"
   310  
   311  	// TagsTableName is the tags table name
   312  	TagsTableName = "dolt_tags"
   313  
   314  	IgnoreTableName = "dolt_ignore"
   315  
   316  	// RebaseTableName is the rebase system table name.
   317  	RebaseTableName = "dolt_rebase"
   318  
   319  	// StatisticsTableName is the statistics system table name
   320  	StatisticsTableName = "dolt_statistics"
   321  )
   322  
   323  const (
   324  	// ProceduresTableName is the name of the dolt stored procedures table.
   325  	ProceduresTableName = "dolt_procedures"
   326  	// ProceduresTableNameCol is the name of the stored procedure. Using CREATE PROCEDURE, will always be lowercase.
   327  	ProceduresTableNameCol = "name"
   328  	// ProceduresTableCreateStmtCol is the CREATE PROCEDURE statement for this stored procedure.
   329  	ProceduresTableCreateStmtCol = "create_stmt"
   330  	// ProceduresTableCreatedAtCol is the time that the stored procedure was created at, in UTC.
   331  	ProceduresTableCreatedAtCol = "created_at"
   332  	// ProceduresTableModifiedAtCol is the time that the stored procedure was last modified, in UTC.
   333  	ProceduresTableModifiedAtCol = "modified_at"
   334  	// ProceduresTableSqlModeCol is the name of the column that stores the SQL_MODE string used when this fragment
   335  	// was originally defined. Mode settings, such as ANSI_QUOTES, are needed to correctly parse the fragment.
   336  	ProceduresTableSqlModeCol = "sql_mode"
   337  )