mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-30 03:26:47 -05:00
implemented dolt_hashof_db function which returns the root hash of a database
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
// Copyright 2024 Dolthub, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package dfunctions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
"github.com/dolthub/go-mysql-server/sql/types"
|
||||
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess"
|
||||
)
|
||||
|
||||
const HashOfDatabaseFuncName = "dolt_hashof_db"
|
||||
|
||||
type HashOfDatabase struct{}
|
||||
|
||||
// NewHashOfDatabase creates a new HashOfDatabase expression.
|
||||
func NewHashOfDatabase() sql.Expression {
|
||||
return &HashOfDatabase{}
|
||||
}
|
||||
|
||||
// Children implements the Expression interface.
|
||||
func (t *HashOfDatabase) Children() []sql.Expression {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Eval implements the Expression interface.
|
||||
func (t *HashOfDatabase) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
|
||||
dbName := ctx.GetCurrentDatabase()
|
||||
ds := dsess.DSessFromSess(ctx.Session)
|
||||
roots, ok := ds.GetRoots(ctx, dbName)
|
||||
if !ok {
|
||||
return nil, sql.ErrDatabaseNotFound.New(dbName)
|
||||
}
|
||||
|
||||
h, err := roots.Working.HashOf()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting hash of the database '%s': %w", dbName, err)
|
||||
}
|
||||
|
||||
return h.String(), nil
|
||||
}
|
||||
|
||||
// String implements the Stringer interface.
|
||||
func (t *HashOfDatabase) String() string {
|
||||
return fmt.Sprintf("%s()", HashOfDatabaseFuncName)
|
||||
}
|
||||
|
||||
// Description implements the FunctionExpression interface
|
||||
func (t *HashOfDatabase) Description() string {
|
||||
return "returns a hash of the contents of the current database, typically used for detecting if a database has changed"
|
||||
}
|
||||
|
||||
// IsNullable implements the Expression interface.
|
||||
func (t *HashOfDatabase) IsNullable() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Resolved implements the Expression interface.
|
||||
func (*HashOfDatabase) Resolved() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// WithChildren implements the Expression interface.
|
||||
func (t *HashOfDatabase) WithChildren(children ...sql.Expression) (sql.Expression, error) {
|
||||
if len(children) != 0 {
|
||||
return nil, sql.ErrInvalidChildrenNumber.New(t, len(children), 1)
|
||||
}
|
||||
return NewHashOfDatabase(), nil
|
||||
}
|
||||
|
||||
// Type implements the Expression interface.
|
||||
func (t *HashOfDatabase) Type() sql.Type {
|
||||
return types.Text
|
||||
}
|
||||
@@ -25,6 +25,7 @@ var DoltFunctions = []sql.Function{
|
||||
sql.Function2{Name: DoltMergeBaseFuncName, Fn: NewMergeBase},
|
||||
sql.Function2{Name: HasAncestorFuncName, Fn: NewHasAncestor},
|
||||
sql.Function1{Name: HashOfTableFuncName, Fn: NewHashOfTable},
|
||||
sql.Function0{Name: HashOfDatabaseFuncName, Fn: NewHashOfDatabase},
|
||||
}
|
||||
|
||||
// DolthubApiFunctions are the DoltFunctions that get exposed to Dolthub Api.
|
||||
|
||||
@@ -735,6 +735,62 @@ var DoltScripts = []queries.ScriptTest{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "dolt_hashof_db tests",
|
||||
SetUpScript: []string{
|
||||
"CREATE TABLE t1 (pk int primary key);",
|
||||
"CREATE TABLE t2 (pk int primary key);",
|
||||
"CREATE TABLE t3 (pk int primary key);",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "SHOW TABLES;",
|
||||
Expected: []sql.Row{
|
||||
{"t1"},
|
||||
{"t2"},
|
||||
{"t3"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT dolt_hashof_db();",
|
||||
Expected: []sql.Row{{"8s7m7m4djgi775km2e9iegrcjaqibq3a"}},
|
||||
},
|
||||
{
|
||||
Query: "INSERT INTO t1 VALUES (1);",
|
||||
Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT dolt_hashof_db();",
|
||||
Expected: []sql.Row{{"vm5tdcu609k8ocjpvf2mttqnog68jf8g"}},
|
||||
},
|
||||
|
||||
{
|
||||
Query: "SELECT dolt_hashof_db();",
|
||||
Expected: []sql.Row{{"vm5tdcu609k8ocjpvf2mttqnog68jf8g"}},
|
||||
},
|
||||
{
|
||||
Query: "INSERT INTO t2 VALUES (1);",
|
||||
Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT dolt_hashof_db();",
|
||||
Expected: []sql.Row{{"ceip16r8mongns5t454huj3pj0hgtgeo"}},
|
||||
},
|
||||
|
||||
{
|
||||
Query: "SELECT dolt_hashof_db();",
|
||||
Expected: []sql.Row{{"ceip16r8mongns5t454huj3pj0hgtgeo"}},
|
||||
},
|
||||
{
|
||||
Query: "create procedure proc1() SELECT * FROM t3;",
|
||||
Expected: []sql.Row{{types.OkResult{}}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT dolt_hashof_db();",
|
||||
Expected: []sql.Row{{"nes9a42uqmoin7i56lmdg4qo7ad79tk5"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// https://github.com/dolthub/dolt/issues/7384
|
||||
Name: "multiple unresolved foreign keys can be created on the same table",
|
||||
|
||||
Reference in New Issue
Block a user