mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-07 08:50:34 -06:00
Merge pull request #4644 from dolthub/taylor/diff-dot-sql
Support two and three dot syntax in `dolt_diff` table function
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
@@ -34,6 +35,7 @@ type DiffSummaryTableFunction struct {
|
||||
|
||||
fromCommitExpr sql.Expression
|
||||
toCommitExpr sql.Expression
|
||||
dotCommitExpr sql.Expression
|
||||
tableNameExpr sql.Expression
|
||||
database sql.Database
|
||||
}
|
||||
@@ -84,16 +86,29 @@ func (ds *DiffSummaryTableFunction) FunctionName() string {
|
||||
return "dolt_diff_summary"
|
||||
}
|
||||
|
||||
// Resolved implements the sql.Resolvable interface
|
||||
func (ds *DiffSummaryTableFunction) Resolved() bool {
|
||||
if ds.tableNameExpr != nil {
|
||||
return ds.fromCommitExpr.Resolved() && ds.toCommitExpr.Resolved() && ds.tableNameExpr.Resolved()
|
||||
func (ds *DiffSummaryTableFunction) commitsResolved() bool {
|
||||
if ds.dotCommitExpr != nil {
|
||||
return ds.dotCommitExpr.Resolved()
|
||||
}
|
||||
return ds.fromCommitExpr.Resolved() && ds.toCommitExpr.Resolved()
|
||||
}
|
||||
|
||||
// Resolved implements the sql.Resolvable interface
|
||||
func (ds *DiffSummaryTableFunction) Resolved() bool {
|
||||
if ds.tableNameExpr != nil {
|
||||
return ds.commitsResolved() && ds.tableNameExpr.Resolved()
|
||||
}
|
||||
return ds.commitsResolved()
|
||||
}
|
||||
|
||||
// String implements the Stringer interface
|
||||
func (ds *DiffSummaryTableFunction) String() string {
|
||||
if ds.dotCommitExpr != nil {
|
||||
if ds.tableNameExpr != nil {
|
||||
return fmt.Sprintf("DOLT_DIFF_SUMMARY(%s, %s)", ds.dotCommitExpr.String(), ds.tableNameExpr.String())
|
||||
}
|
||||
return fmt.Sprintf("DOLT_DIFF_SUMMARY(%s)", ds.dotCommitExpr.String())
|
||||
}
|
||||
if ds.tableNameExpr != nil {
|
||||
return fmt.Sprintf("DOLT_DIFF_SUMMARY(%s, %s, %s)", ds.fromCommitExpr.String(), ds.toCommitExpr.String(), ds.tableNameExpr.String())
|
||||
}
|
||||
@@ -154,7 +169,12 @@ func (ds *DiffSummaryTableFunction) CheckPrivileges(ctx *sql.Context, opChecker
|
||||
|
||||
// Expressions implements the sql.Expressioner interface.
|
||||
func (ds *DiffSummaryTableFunction) Expressions() []sql.Expression {
|
||||
exprs := []sql.Expression{ds.fromCommitExpr, ds.toCommitExpr}
|
||||
exprs := []sql.Expression{}
|
||||
if ds.dotCommitExpr != nil {
|
||||
exprs = append(exprs, ds.dotCommitExpr)
|
||||
} else {
|
||||
exprs = append(exprs, ds.fromCommitExpr, ds.toCommitExpr)
|
||||
}
|
||||
if ds.tableNameExpr != nil {
|
||||
exprs = append(exprs, ds.tableNameExpr)
|
||||
}
|
||||
@@ -163,8 +183,8 @@ func (ds *DiffSummaryTableFunction) Expressions() []sql.Expression {
|
||||
|
||||
// WithExpressions implements the sql.Expressioner interface.
|
||||
func (ds *DiffSummaryTableFunction) WithExpressions(expression ...sql.Expression) (sql.Node, error) {
|
||||
if len(expression) < 2 || len(expression) > 3 {
|
||||
return nil, sql.ErrInvalidArgumentNumber.New(ds.FunctionName(), "2 or 3", len(expression))
|
||||
if len(expression) < 1 {
|
||||
return nil, sql.ErrInvalidArgumentNumber.New(ds.FunctionName(), "1 to 3", len(expression))
|
||||
}
|
||||
|
||||
for _, expr := range expression {
|
||||
@@ -173,19 +193,37 @@ func (ds *DiffSummaryTableFunction) WithExpressions(expression ...sql.Expression
|
||||
}
|
||||
}
|
||||
|
||||
ds.fromCommitExpr = expression[0]
|
||||
ds.toCommitExpr = expression[1]
|
||||
if len(expression) == 3 {
|
||||
ds.tableNameExpr = expression[2]
|
||||
if strings.Contains(expression[0].String(), "..") {
|
||||
if len(expression) < 1 || len(expression) > 2 {
|
||||
return nil, sql.ErrInvalidArgumentNumber.New(ds.FunctionName(), "1 or 2", len(expression))
|
||||
}
|
||||
ds.dotCommitExpr = expression[0]
|
||||
if len(expression) == 2 {
|
||||
ds.tableNameExpr = expression[1]
|
||||
}
|
||||
} else {
|
||||
if len(expression) < 2 || len(expression) > 3 {
|
||||
return nil, sql.ErrInvalidArgumentNumber.New(ds.FunctionName(), "2 or 3", len(expression))
|
||||
}
|
||||
ds.fromCommitExpr = expression[0]
|
||||
ds.toCommitExpr = expression[1]
|
||||
if len(expression) == 3 {
|
||||
ds.tableNameExpr = expression[2]
|
||||
}
|
||||
}
|
||||
|
||||
// validate the expressions
|
||||
if !sql.IsText(ds.fromCommitExpr.Type()) {
|
||||
return nil, sql.ErrInvalidArgumentDetails.New(ds.FunctionName(), ds.fromCommitExpr.String())
|
||||
}
|
||||
|
||||
if !sql.IsText(ds.toCommitExpr.Type()) {
|
||||
return nil, sql.ErrInvalidArgumentDetails.New(ds.FunctionName(), ds.toCommitExpr.String())
|
||||
if ds.dotCommitExpr != nil {
|
||||
if !sql.IsText(ds.dotCommitExpr.Type()) {
|
||||
return nil, sql.ErrInvalidArgumentDetails.New(ds.FunctionName(), ds.dotCommitExpr.String())
|
||||
}
|
||||
} else {
|
||||
if !sql.IsText(ds.fromCommitExpr.Type()) {
|
||||
return nil, sql.ErrInvalidArgumentDetails.New(ds.FunctionName(), ds.fromCommitExpr.String())
|
||||
}
|
||||
if !sql.IsText(ds.toCommitExpr.Type()) {
|
||||
return nil, sql.ErrInvalidArgumentDetails.New(ds.FunctionName(), ds.toCommitExpr.String())
|
||||
}
|
||||
}
|
||||
|
||||
if ds.tableNameExpr != nil {
|
||||
@@ -199,7 +237,7 @@ func (ds *DiffSummaryTableFunction) WithExpressions(expression ...sql.Expression
|
||||
|
||||
// RowIter implements the sql.Node interface
|
||||
func (ds *DiffSummaryTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) {
|
||||
fromCommitVal, toCommitVal, tableName, err := ds.evaluateArguments()
|
||||
fromCommitVal, toCommitVal, dotCommitVal, tableName, err := ds.evaluateArguments()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,13 +247,18 @@ func (ds *DiffSummaryTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.
|
||||
return nil, fmt.Errorf("unexpected database type: %T", ds.database)
|
||||
}
|
||||
|
||||
sess := dsess.DSessFromSess(ctx.Session)
|
||||
fromRoot, _, err := sess.ResolveRootForRef(ctx, sqledb.Name(), fromCommitVal)
|
||||
fromCommitStr, toCommitStr, err := loadCommitStrings(ctx, fromCommitVal, toCommitVal, dotCommitVal, sqledb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
toRoot, _, err := sess.ResolveRootForRef(ctx, sqledb.Name(), toCommitVal)
|
||||
sess := dsess.DSessFromSess(ctx.Session)
|
||||
fromRoot, _, err := sess.ResolveRootForRef(ctx, sqledb.Name(), fromCommitStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
toRoot, _, err := sess.ResolveRootForRef(ctx, sqledb.Name(), toCommitStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -256,42 +299,43 @@ func (ds *DiffSummaryTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.
|
||||
return NewDiffSummaryTableFunctionRowIter(diffSummaries), nil
|
||||
}
|
||||
|
||||
// evaluateArguments returns fromCommitValStr, toCommitValStr and tableName.
|
||||
// It evaluates the argument expressions to turn them into values this DiffTableFunction
|
||||
// evaluateArguments returns fromCommitVal, toCommitVal, dotCommitVal, and tableName.
|
||||
// It evaluates the argument expressions to turn them into values this DiffSummaryTableFunction
|
||||
// can use. Note that this method only evals the expressions, and doesn't validate the values.
|
||||
func (ds *DiffSummaryTableFunction) evaluateArguments() (string, string, string, error) {
|
||||
func (ds *DiffSummaryTableFunction) evaluateArguments() (interface{}, interface{}, interface{}, string, error) {
|
||||
var tableName string
|
||||
if ds.tableNameExpr != nil {
|
||||
tableNameVal, err := ds.tableNameExpr.Eval(ds.ctx, nil)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
return nil, nil, nil, "", err
|
||||
}
|
||||
tn, ok := tableNameVal.(string)
|
||||
if !ok {
|
||||
return "", "", "", ErrInvalidTableName.New(ds.tableNameExpr.String())
|
||||
return nil, nil, nil, "", ErrInvalidTableName.New(ds.tableNameExpr.String())
|
||||
}
|
||||
tableName = tn
|
||||
}
|
||||
|
||||
if ds.dotCommitExpr != nil {
|
||||
dotCommitVal, err := ds.dotCommitExpr.Eval(ds.ctx, nil)
|
||||
if err != nil {
|
||||
return nil, nil, nil, "", err
|
||||
}
|
||||
|
||||
return nil, nil, dotCommitVal, tableName, nil
|
||||
}
|
||||
|
||||
fromCommitVal, err := ds.fromCommitExpr.Eval(ds.ctx, nil)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
fromCommitValStr, ok := fromCommitVal.(string)
|
||||
if !ok {
|
||||
return "", "", "", fmt.Errorf("received '%v' when expecting commit hash string", fromCommitVal)
|
||||
return nil, nil, nil, "", err
|
||||
}
|
||||
|
||||
toCommitVal, err := ds.toCommitExpr.Eval(ds.ctx, nil)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
toCommitValStr, ok := toCommitVal.(string)
|
||||
if !ok {
|
||||
return "", "", "", fmt.Errorf("received '%v' when expecting commit hash string", toCommitVal)
|
||||
return nil, nil, nil, "", err
|
||||
}
|
||||
|
||||
return fromCommitValStr, toCommitValStr, tableName, nil
|
||||
return fromCommitVal, toCommitVal, nil, tableName, nil
|
||||
}
|
||||
|
||||
// getDiffSummaryNodeFromDelta returns diffSummaryNode object and whether there is data diff or not. It gets tables
|
||||
|
||||
@@ -21,6 +21,8 @@ import (
|
||||
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/diff"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/merge"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/rowconv"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess"
|
||||
@@ -40,6 +42,7 @@ type DiffTableFunction struct {
|
||||
ctx *sql.Context
|
||||
fromCommitExpr sql.Expression
|
||||
toCommitExpr sql.Expression
|
||||
dotCommitExpr sql.Expression
|
||||
tableNameExpr sql.Expression
|
||||
database sql.Database
|
||||
sqlSch sql.Schema
|
||||
@@ -79,6 +82,11 @@ func (dtf *DiffTableFunction) WithDatabase(database sql.Database) (sql.Node, err
|
||||
|
||||
// Expressions implements the sql.Expressioner interface
|
||||
func (dtf *DiffTableFunction) Expressions() []sql.Expression {
|
||||
if dtf.dotCommitExpr != nil {
|
||||
return []sql.Expression{
|
||||
dtf.dotCommitExpr, dtf.tableNameExpr,
|
||||
}
|
||||
}
|
||||
return []sql.Expression{
|
||||
dtf.fromCommitExpr, dtf.toCommitExpr, dtf.tableNameExpr,
|
||||
}
|
||||
@@ -86,8 +94,8 @@ func (dtf *DiffTableFunction) Expressions() []sql.Expression {
|
||||
|
||||
// WithExpressions implements the sql.Expressioner interface
|
||||
func (dtf *DiffTableFunction) WithExpressions(expression ...sql.Expression) (sql.Node, error) {
|
||||
if len(expression) != 3 {
|
||||
return nil, sql.ErrInvalidArgumentNumber.New(dtf.FunctionName(), 3, len(expression))
|
||||
if len(expression) < 2 {
|
||||
return nil, sql.ErrInvalidArgumentNumber.New(dtf.FunctionName(), "2 to 3", len(expression))
|
||||
}
|
||||
|
||||
// TODO: For now, we will only support literal / fully-resolved arguments to the
|
||||
@@ -99,16 +107,27 @@ func (dtf *DiffTableFunction) WithExpressions(expression ...sql.Expression) (sql
|
||||
}
|
||||
}
|
||||
|
||||
dtf.fromCommitExpr = expression[0]
|
||||
dtf.toCommitExpr = expression[1]
|
||||
dtf.tableNameExpr = expression[2]
|
||||
if strings.Contains(expression[0].String(), "..") {
|
||||
if len(expression) != 2 {
|
||||
return nil, sql.ErrInvalidArgumentNumber.New(fmt.Sprintf("%v with .. or ...", dtf.FunctionName()), 2, len(expression))
|
||||
}
|
||||
dtf.dotCommitExpr = expression[0]
|
||||
dtf.tableNameExpr = expression[1]
|
||||
} else {
|
||||
if len(expression) != 3 {
|
||||
return nil, sql.ErrInvalidArgumentNumber.New(dtf.FunctionName(), 3, len(expression))
|
||||
}
|
||||
dtf.fromCommitExpr = expression[0]
|
||||
dtf.toCommitExpr = expression[1]
|
||||
dtf.tableNameExpr = expression[2]
|
||||
}
|
||||
|
||||
fromCommitVal, toCommitVal, tableName, err := dtf.evaluateArguments()
|
||||
fromCommitVal, toCommitVal, dotCommitVal, tableName, err := dtf.evaluateArguments()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = dtf.generateSchema(dtf.ctx, fromCommitVal, toCommitVal, tableName)
|
||||
err = dtf.generateSchema(dtf.ctx, fromCommitVal, toCommitVal, dotCommitVal, tableName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -127,29 +146,29 @@ func (dtf *DiffTableFunction) RowIter(ctx *sql.Context, _ sql.Row) (sql.RowIter,
|
||||
// TODO: When we add support for joining on table functions, we'll need to evaluate this against the
|
||||
// specified row. That row is what has the left_table context in a join query.
|
||||
// This will expand the test cases we need to cover significantly.
|
||||
fromCommit, toCommit, _, err := dtf.evaluateArguments()
|
||||
fromCommitVal, toCommitVal, dotCommitVal, _, err := dtf.evaluateArguments()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fromHash, fromOk := fromCommit.(string)
|
||||
toHash, toOk := toCommit.(string)
|
||||
if !fromOk || !toOk {
|
||||
return nil, fmt.Errorf("expected strings for from and to revisions, got: %v, %v", fromHash, toHash)
|
||||
}
|
||||
|
||||
sqledb, ok := dtf.database.(Database)
|
||||
if !ok {
|
||||
panic("unable to get dolt database")
|
||||
return nil, fmt.Errorf("unable to get dolt database")
|
||||
}
|
||||
ddb := sqledb.GetDoltDB()
|
||||
|
||||
dp := dtables.NewDiffPartition(dtf.tableDelta.ToTable, dtf.tableDelta.FromTable, toHash, fromHash, dtf.toDate, dtf.fromDate, dtf.tableDelta.ToSch, dtf.tableDelta.FromSch)
|
||||
fromCommitStr, toCommitStr, err := loadCommitStrings(ctx, fromCommitVal, toCommitVal, dotCommitVal, sqledb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ddb := sqledb.GetDoltDB()
|
||||
dp := dtables.NewDiffPartition(dtf.tableDelta.ToTable, dtf.tableDelta.FromTable, toCommitStr, fromCommitStr, dtf.toDate, dtf.fromDate, dtf.tableDelta.ToSch, dtf.tableDelta.FromSch)
|
||||
|
||||
return NewDiffTableFunctionRowIterForSinglePartition(*dp, ddb, dtf.joiner), nil
|
||||
}
|
||||
|
||||
// findMatchingDelta returns the best matching table delta for the table name given, taking renames into account
|
||||
// findMatchingDelta returns the best matching table delta for the table name
|
||||
// given, taking renames into account
|
||||
func findMatchingDelta(deltas []diff.TableDelta, tableName string) diff.TableDelta {
|
||||
tableName = strings.ToLower(tableName)
|
||||
for _, d := range deltas {
|
||||
@@ -168,25 +187,132 @@ func findMatchingDelta(deltas []diff.TableDelta, tableName string) diff.TableDel
|
||||
return diff.TableDelta{}
|
||||
}
|
||||
|
||||
// loadDetailsForRef loads the root, hash, and timestamp for the specified ref value
|
||||
func loadDetailsForRef(
|
||||
ctx *sql.Context,
|
||||
ref interface{},
|
||||
ddb Database,
|
||||
) (*doltdb.RootValue, string, *types.Timestamp, error) {
|
||||
hashStr, ok := ref.(string)
|
||||
if !ok {
|
||||
return nil, "", nil, fmt.Errorf("received '%v' when expecting commit hash string", ref)
|
||||
type refDetails struct {
|
||||
root *doltdb.RootValue
|
||||
hashStr string
|
||||
commitTime *types.Timestamp
|
||||
}
|
||||
|
||||
// loadDetailsForRef loads the root, hash, and timestamp for the specified from
|
||||
// and to ref values
|
||||
func loadDetailsForRefs(ctx *sql.Context, fromRef, toRef, dotRef interface{}, db Database) (*refDetails, *refDetails, error) {
|
||||
fromCommitStr, toCommitStr, err := loadCommitStrings(ctx, fromRef, toRef, dotRef, db)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sess := dsess.DSessFromSess(ctx.Session)
|
||||
|
||||
root, commitTime, err := sess.ResolveRootForRef(ctx, ddb.Name(), hashStr)
|
||||
fromDetails, err := resolveRoot(ctx, sess, db.Name(), fromCommitStr)
|
||||
if err != nil {
|
||||
return nil, "", nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return root, hashStr, commitTime, nil
|
||||
toDetails, err := resolveRoot(ctx, sess, db.Name(), toCommitStr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return fromDetails, toDetails, nil
|
||||
}
|
||||
|
||||
func resolveCommitStrings(ctx *sql.Context, fromRef, toRef, dotRef interface{}, db Database) (string, string, error) {
|
||||
if dotRef != nil {
|
||||
dotStr, err := interfaceToString(dotRef)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
sess := dsess.DSessFromSess(ctx.Session)
|
||||
|
||||
if strings.Contains(dotStr, "...") {
|
||||
refs := strings.Split(dotStr, "...")
|
||||
|
||||
headRef, err := sess.CWBHeadRef(ctx, db.Name())
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
rightCm, err := resolveCommit(ctx, db.ddb, headRef, refs[0])
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
leftCm, err := resolveCommit(ctx, db.ddb, headRef, refs[1])
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
mergeBase, err := merge.MergeBase(ctx, rightCm, leftCm)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
return mergeBase.String(), refs[1], nil
|
||||
} else {
|
||||
refs := strings.Split(dotStr, "..")
|
||||
return refs[0], refs[1], nil
|
||||
}
|
||||
}
|
||||
|
||||
fromStr, err := interfaceToString(fromRef)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
toStr, err := interfaceToString(toRef)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
return fromStr, toStr, nil
|
||||
}
|
||||
|
||||
// loadCommitStrings gets the to and from commit strings, using the common
|
||||
// ancestor as the from commit string for three dot diff
|
||||
func loadCommitStrings(ctx *sql.Context, fromRef, toRef, dotRef interface{}, db Database) (string, string, error) {
|
||||
fromStr, toStr, err := resolveCommitStrings(ctx, fromRef, toRef, dotRef, db)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if len(fromStr) == 0 || len(toStr) == 0 {
|
||||
return "", "", fmt.Errorf("expected strings for from and to revisions, got: %v, %v", fromStr, toStr)
|
||||
}
|
||||
|
||||
return fromStr, toStr, nil
|
||||
}
|
||||
|
||||
// interfaceToString converts an interface to a string
|
||||
func interfaceToString(r interface{}) (string, error) {
|
||||
str, ok := r.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("received '%v' when expecting commit hash string", str)
|
||||
}
|
||||
return str, nil
|
||||
}
|
||||
|
||||
func resolveRoot(ctx *sql.Context, sess *dsess.DoltSession, dbName, hashStr string) (*refDetails, error) {
|
||||
root, commitTime, err := sess.ResolveRootForRef(ctx, dbName, hashStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &refDetails{root, hashStr, commitTime}, nil
|
||||
}
|
||||
|
||||
func resolveCommit(ctx *sql.Context, ddb *doltdb.DoltDB, headRef ref.DoltRef, cSpecStr string) (*doltdb.Commit, error) {
|
||||
rightCs, err := doltdb.NewCommitSpec(cSpecStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rightCm, err := ddb.Resolve(ctx, rightCs, headRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rightCm, nil
|
||||
}
|
||||
|
||||
// WithChildren implements the sql.Node interface
|
||||
@@ -199,7 +325,7 @@ func (dtf *DiffTableFunction) WithChildren(node ...sql.Node) (sql.Node, error) {
|
||||
|
||||
// CheckPrivileges implements the sql.Node interface
|
||||
func (dtf *DiffTableFunction) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool {
|
||||
_, _, tableName, err := dtf.evaluateArguments()
|
||||
_, _, _, tableName, err := dtf.evaluateArguments()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -211,46 +337,58 @@ func (dtf *DiffTableFunction) CheckPrivileges(ctx *sql.Context, opChecker sql.Pr
|
||||
|
||||
// evaluateArguments evaluates the argument expressions to turn them into values this DiffTableFunction
|
||||
// can use. Note that this method only evals the expressions, and doesn't validate the values.
|
||||
func (dtf *DiffTableFunction) evaluateArguments() (interface{}, interface{}, string, error) {
|
||||
func (dtf *DiffTableFunction) evaluateArguments() (interface{}, interface{}, interface{}, string, error) {
|
||||
if !dtf.Resolved() {
|
||||
return nil, nil, "", nil
|
||||
return nil, nil, nil, "", nil
|
||||
}
|
||||
|
||||
if !sql.IsText(dtf.tableNameExpr.Type()) {
|
||||
return nil, nil, "", sql.ErrInvalidArgumentDetails.New(dtf.FunctionName(), dtf.tableNameExpr.String())
|
||||
}
|
||||
|
||||
if !sql.IsText(dtf.fromCommitExpr.Type()) {
|
||||
return nil, nil, "", sql.ErrInvalidArgumentDetails.New(dtf.FunctionName(), dtf.fromCommitExpr.String())
|
||||
}
|
||||
|
||||
if !sql.IsText(dtf.toCommitExpr.Type()) {
|
||||
return nil, nil, "", sql.ErrInvalidArgumentDetails.New(dtf.FunctionName(), dtf.toCommitExpr.String())
|
||||
return nil, nil, nil, "", sql.ErrInvalidArgumentDetails.New(dtf.FunctionName(), dtf.tableNameExpr.String())
|
||||
}
|
||||
|
||||
tableNameVal, err := dtf.tableNameExpr.Eval(dtf.ctx, nil)
|
||||
if err != nil {
|
||||
return nil, nil, "", err
|
||||
return nil, nil, nil, "", err
|
||||
}
|
||||
|
||||
tableName, ok := tableNameVal.(string)
|
||||
if !ok {
|
||||
return nil, nil, "", ErrInvalidTableName.New(dtf.tableNameExpr.String())
|
||||
return nil, nil, nil, "", ErrInvalidTableName.New(dtf.tableNameExpr.String())
|
||||
}
|
||||
|
||||
if dtf.dotCommitExpr != nil {
|
||||
if !sql.IsText(dtf.dotCommitExpr.Type()) {
|
||||
return nil, nil, nil, "", sql.ErrInvalidArgumentDetails.New(dtf.FunctionName(), dtf.dotCommitExpr.String())
|
||||
}
|
||||
|
||||
dotCommitVal, err := dtf.dotCommitExpr.Eval(dtf.ctx, nil)
|
||||
if err != nil {
|
||||
return nil, nil, nil, "", err
|
||||
}
|
||||
|
||||
return nil, nil, dotCommitVal, tableName, nil
|
||||
}
|
||||
|
||||
if !sql.IsText(dtf.fromCommitExpr.Type()) {
|
||||
return nil, nil, nil, "", sql.ErrInvalidArgumentDetails.New(dtf.FunctionName(), dtf.fromCommitExpr.String())
|
||||
}
|
||||
if !sql.IsText(dtf.toCommitExpr.Type()) {
|
||||
return nil, nil, nil, "", sql.ErrInvalidArgumentDetails.New(dtf.FunctionName(), dtf.toCommitExpr.String())
|
||||
}
|
||||
|
||||
fromCommitVal, err := dtf.fromCommitExpr.Eval(dtf.ctx, nil)
|
||||
if err != nil {
|
||||
return nil, nil, "", err
|
||||
return nil, nil, nil, "", err
|
||||
}
|
||||
|
||||
toCommitVal, err := dtf.toCommitExpr.Eval(dtf.ctx, nil)
|
||||
if err != nil {
|
||||
return nil, nil, "", err
|
||||
return nil, nil, nil, "", err
|
||||
}
|
||||
|
||||
return fromCommitVal, toCommitVal, tableName, nil
|
||||
return fromCommitVal, toCommitVal, nil, tableName, nil
|
||||
}
|
||||
|
||||
func (dtf *DiffTableFunction) generateSchema(ctx *sql.Context, fromCommitVal, toCommitVal interface{}, tableName string) error {
|
||||
func (dtf *DiffTableFunction) generateSchema(ctx *sql.Context, fromCommitVal, toCommitVal, dotCommitVal interface{}, tableName string) error {
|
||||
if !dtf.Resolved() {
|
||||
return nil
|
||||
}
|
||||
@@ -260,7 +398,7 @@ func (dtf *DiffTableFunction) generateSchema(ctx *sql.Context, fromCommitVal, to
|
||||
return fmt.Errorf("unexpected database type: %T", dtf.database)
|
||||
}
|
||||
|
||||
delta, err := dtf.cacheTableDelta(ctx, fromCommitVal, toCommitVal, tableName, sqledb)
|
||||
delta, err := dtf.cacheTableDelta(ctx, fromCommitVal, toCommitVal, dotCommitVal, tableName, sqledb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -308,22 +446,18 @@ func (dtf *DiffTableFunction) generateSchema(ctx *sql.Context, fromCommitVal, to
|
||||
|
||||
// cacheTableDelta caches and returns an appropriate table delta for the table name given, taking renames into
|
||||
// consideration. Returns a sql.ErrTableNotFound if the given table name cannot be found in either revision.
|
||||
func (dtf *DiffTableFunction) cacheTableDelta(ctx *sql.Context, fromCommitVal interface{}, toCommitVal interface{}, tableName string, db Database) (diff.TableDelta, error) {
|
||||
fromRoot, _, fromDate, err := loadDetailsForRef(ctx, fromCommitVal, db)
|
||||
func (dtf *DiffTableFunction) cacheTableDelta(ctx *sql.Context, fromCommitVal, toCommitVal, dotCommitVal interface{}, tableName string, db Database) (diff.TableDelta, error) {
|
||||
fromRefDetails, toRefDetails, err := loadDetailsForRefs(ctx, fromCommitVal, toCommitVal, dotCommitVal, db)
|
||||
if err != nil {
|
||||
return diff.TableDelta{}, err
|
||||
}
|
||||
|
||||
toRoot, _, toDate, err := loadDetailsForRef(ctx, toCommitVal, db)
|
||||
fromTable, _, fromTableExists, err := fromRefDetails.root.GetTableInsensitive(ctx, tableName)
|
||||
if err != nil {
|
||||
return diff.TableDelta{}, err
|
||||
}
|
||||
|
||||
fromTable, _, fromTableExists, err := fromRoot.GetTableInsensitive(ctx, tableName)
|
||||
if err != nil {
|
||||
return diff.TableDelta{}, err
|
||||
}
|
||||
toTable, _, toTableExists, err := toRoot.GetTableInsensitive(ctx, tableName)
|
||||
toTable, _, toTableExists, err := toRefDetails.root.GetTableInsensitive(ctx, tableName)
|
||||
if err != nil {
|
||||
return diff.TableDelta{}, err
|
||||
}
|
||||
@@ -333,13 +467,13 @@ func (dtf *DiffTableFunction) cacheTableDelta(ctx *sql.Context, fromCommitVal in
|
||||
}
|
||||
|
||||
// TODO: it would be nice to limit this to just the table under consideration, not all tables with a diff
|
||||
deltas, err := diff.GetTableDeltas(ctx, fromRoot, toRoot)
|
||||
deltas, err := diff.GetTableDeltas(ctx, fromRefDetails.root, toRefDetails.root)
|
||||
if err != nil {
|
||||
return diff.TableDelta{}, err
|
||||
}
|
||||
|
||||
dtf.fromDate = fromDate
|
||||
dtf.toDate = toDate
|
||||
dtf.fromDate = fromRefDetails.commitTime
|
||||
dtf.toDate = toRefDetails.commitTime
|
||||
|
||||
delta := findMatchingDelta(deltas, tableName)
|
||||
|
||||
@@ -389,11 +523,19 @@ func (dtf *DiffTableFunction) Schema() sql.Schema {
|
||||
|
||||
// Resolved implements the sql.Resolvable interface
|
||||
func (dtf *DiffTableFunction) Resolved() bool {
|
||||
if dtf.dotCommitExpr != nil {
|
||||
return dtf.tableNameExpr.Resolved() && dtf.dotCommitExpr.Resolved()
|
||||
}
|
||||
return dtf.tableNameExpr.Resolved() && dtf.fromCommitExpr.Resolved() && dtf.toCommitExpr.Resolved()
|
||||
}
|
||||
|
||||
// String implements the Stringer interface
|
||||
func (dtf *DiffTableFunction) String() string {
|
||||
if dtf.dotCommitExpr != nil {
|
||||
return fmt.Sprintf("DOLT_DIFF(%s, %s)",
|
||||
dtf.dotCommitExpr.String(),
|
||||
dtf.tableNameExpr.String())
|
||||
}
|
||||
return fmt.Sprintf("DOLT_DIFF(%s, %s, %s)",
|
||||
dtf.fromCommitExpr.String(),
|
||||
dtf.toCommitExpr.String(),
|
||||
|
||||
@@ -767,6 +767,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT * FROM dolt_diff('main~', 'main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
{
|
||||
// Without access to the database, dolt_diff with dots should fail with a database access error
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT * FROM dolt_diff('main~..main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
{
|
||||
// Without access to the database, dolt_diff_summary should fail with a database access error
|
||||
User: "tester",
|
||||
@@ -774,6 +781,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT * FROM dolt_diff_summary('main~', 'main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
{
|
||||
// Without access to the database, dolt_diff_summary with dots should fail with a database access error
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT * FROM dolt_diff_summary('main~..main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
{
|
||||
// Without access to the database, dolt_log should fail with a database access error
|
||||
User: "tester",
|
||||
@@ -795,6 +809,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT COUNT(*) FROM dolt_diff('main~', 'main', 'test');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
// After granting access to mydb.test, dolt_diff with dots should work
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT COUNT(*) FROM dolt_diff('main~..main', 'test');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
// With access to the db, but not the table, dolt_diff should fail
|
||||
User: "tester",
|
||||
@@ -802,6 +823,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT * FROM dolt_diff('main~', 'main', 'test2');",
|
||||
ExpectedErr: sql.ErrPrivilegeCheckFailed,
|
||||
},
|
||||
{
|
||||
// With access to the db, but not the table, dolt_diff with dots should fail
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT * FROM dolt_diff('main~..main', 'test2');",
|
||||
ExpectedErr: sql.ErrPrivilegeCheckFailed,
|
||||
},
|
||||
{
|
||||
// With access to the db, but not the table, dolt_diff_summary should fail
|
||||
User: "tester",
|
||||
@@ -809,6 +837,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT * FROM dolt_diff_summary('main~', 'main', 'test2');",
|
||||
ExpectedErr: sql.ErrPrivilegeCheckFailed,
|
||||
},
|
||||
{
|
||||
// With access to the db, but not the table, dolt_diff_summary with dots should fail
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT * FROM dolt_diff_summary('main~...main', 'test2');",
|
||||
ExpectedErr: sql.ErrPrivilegeCheckFailed,
|
||||
},
|
||||
{
|
||||
// With access to the db, dolt_diff_summary should fail for all tables if no access any of tables
|
||||
User: "tester",
|
||||
@@ -816,6 +851,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT * FROM dolt_diff_summary('main~', 'main');",
|
||||
ExpectedErr: sql.ErrPrivilegeCheckFailed,
|
||||
},
|
||||
{
|
||||
// With access to the db, dolt_diff_summary with dots should fail for all tables if no access any of tables
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT * FROM dolt_diff_summary('main~...main');",
|
||||
ExpectedErr: sql.ErrPrivilegeCheckFailed,
|
||||
},
|
||||
{
|
||||
// Revoke select on mydb.test
|
||||
User: "root",
|
||||
@@ -830,6 +872,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT * FROM dolt_diff('main~', 'main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
{
|
||||
// After revoking access, dolt_diff with dots should fail
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT * FROM dolt_diff('main~..main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
{
|
||||
// Grant multi-table access for all of mydb
|
||||
User: "root",
|
||||
@@ -844,6 +893,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT COUNT(*) FROM dolt_diff('main~', 'main', 'test');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
// After granting access to the entire db, dolt_diff should work
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT COUNT(*) FROM dolt_diff('main~..main', 'test');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
// After granting access to the entire db, dolt_diff_summary should work
|
||||
User: "tester",
|
||||
@@ -851,6 +907,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT COUNT(*) FROM dolt_diff_summary('main~', 'main');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
// After granting access to the entire db, dolt_diff_summary with dots should work
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT COUNT(*) FROM dolt_diff_summary('main~...main');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
// After granting access to the entire db, dolt_log should work
|
||||
User: "tester",
|
||||
@@ -872,6 +935,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT * FROM dolt_diff('main~', 'main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
{
|
||||
// After revoking access, dolt_diff with dots should fail
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT * FROM dolt_diff('main~...main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
{
|
||||
// After revoking access, dolt_diff_summary should fail
|
||||
User: "tester",
|
||||
@@ -900,6 +970,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT COUNT(*) FROM dolt_diff('main~', 'main', 'test');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
// After granting global access to *.*, dolt_diff should work
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT COUNT(*) FROM dolt_diff('main~...main', 'test');",
|
||||
Expected: []sql.Row{{1}},
|
||||
},
|
||||
{
|
||||
// Revoke global access
|
||||
User: "root",
|
||||
@@ -914,6 +991,13 @@ var DoltUserPrivTests = []queries.UserPrivilegeTest{
|
||||
Query: "SELECT * FROM dolt_diff('main~', 'main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
{
|
||||
// After revoking global access, dolt_diff with dots should fail
|
||||
User: "tester",
|
||||
Host: "localhost",
|
||||
Query: "SELECT * FROM dolt_diff('main~..main', 'test');",
|
||||
ExpectedErr: sql.ErrDatabaseAccessDeniedForUser,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -4418,6 +4502,10 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
"set @Commit2 = dolt_commit('-am', 'inserting into t');",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "SELECT * from dolt_diff();",
|
||||
ExpectedErr: sql.ErrInvalidArgumentNumber,
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('t');",
|
||||
ExpectedErr: sql.ErrInvalidArgumentNumber,
|
||||
@@ -4470,6 +4558,43 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "SELECT * from dolt_diff(hashof('main'), @Commit2, LOWER('T'));",
|
||||
ExpectedErr: sqle.ErrInvalidNonLiteralArgument,
|
||||
},
|
||||
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('main..main~');",
|
||||
ExpectedErr: sql.ErrInvalidArgumentNumber,
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('main..main~', 'extra', 't');",
|
||||
ExpectedErr: sql.ErrInvalidArgumentNumber,
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('main..main^', 123);",
|
||||
ExpectedErr: sql.ErrInvalidArgumentDetails,
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('main..main~', 'doesnotexist');",
|
||||
ExpectedErr: sql.ErrTableNotFound,
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('fakefakefakefakefakefakefakefake..main', 't');",
|
||||
ExpectedErrStr: "target commit not found",
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('main..fakefakefakefakefakefakefakefake', 't');",
|
||||
ExpectedErrStr: "target commit not found",
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('fakefakefakefakefakefakefakefake...main', 't');",
|
||||
ExpectedErrStr: "target commit not found",
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('main...fakefakefakefakefakefakefakefake', 't');",
|
||||
ExpectedErrStr: "target commit not found",
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff('main..main~', LOWER('T'));",
|
||||
ExpectedErr: sqle.ErrInvalidNonLiteralArgument,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -4573,6 +4698,14 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
{nil, nil, nil, 3, "five", "six", "added"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT from_pk, from_c1, from_c2, to_pk, to_c1, to_c2, diff_type from dolt_diff('STAGED..WORKING', 't') order by coalesce(from_pk, to_pk);",
|
||||
Expected: []sql.Row{
|
||||
{1, "one", "two", 1, "one", "100", "modified"},
|
||||
{2, "three", "four", nil, nil, nil, "removed"},
|
||||
{nil, nil, nil, 3, "five", "six", "added"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT from_pk, from_c1, from_c2, to_pk, to_c1, to_c2, diff_type from dolt_diff('WORKING', 'STAGED', 't') order by coalesce(from_pk, to_pk);",
|
||||
Expected: []sql.Row{
|
||||
@@ -4585,6 +4718,10 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "SELECT from_pk, from_c1, from_c2, to_pk, to_c1, to_c2, diff_type from dolt_diff('WORKING', 'WORKING', 't') order by coalesce(from_pk, to_pk);",
|
||||
Expected: []sql.Row{},
|
||||
},
|
||||
{
|
||||
Query: "SELECT from_pk, from_c1, from_c2, to_pk, to_c1, to_c2, diff_type from dolt_diff('WORKING..WORKING', 't') order by coalesce(from_pk, to_pk);",
|
||||
Expected: []sql.Row{},
|
||||
},
|
||||
{
|
||||
Query: "SELECT from_pk, from_c1, from_c2, to_pk, to_c1, to_c2, diff_type from dolt_diff('STAGED', 'STAGED', 't') order by coalesce(from_pk, to_pk);",
|
||||
Expected: []sql.Row{},
|
||||
@@ -4639,6 +4776,13 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
{2, "two", 2, "two", "three", "modified"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT to_pk, to_c1, from_pk, from_c1, from_c2, diff_type from dolt_diff('main..branch1', 't');",
|
||||
Expected: []sql.Row{
|
||||
{nil, nil, 1, "one", "two", "removed"},
|
||||
{2, "two", 2, "two", "three", "modified"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT to_pk, to_c1, to_c2, from_pk, from_c1, diff_type from dolt_diff('branch1', 'main', 't');",
|
||||
Expected: []sql.Row{
|
||||
@@ -4646,6 +4790,13 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
{2, "two", "three", 2, "two", "modified"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT to_pk, to_c1, to_c2, from_pk, from_c1, diff_type from dolt_diff('branch1..main', 't');",
|
||||
Expected: []sql.Row{
|
||||
{1, "one", "two", nil, nil, "added"},
|
||||
{2, "two", "three", 2, "two", "modified"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT to_pk, to_c1, from_pk, from_c1, from_c2, diff_type from dolt_diff('main~', 'branch1', 't');",
|
||||
Expected: []sql.Row{
|
||||
@@ -4653,6 +4804,41 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
{2, "two", nil, nil, nil, "added"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT to_pk, to_c1, from_pk, from_c1, from_c2, diff_type from dolt_diff('main~..branch1', 't');",
|
||||
Expected: []sql.Row{
|
||||
{nil, nil, 1, "one", "two", "removed"},
|
||||
{2, "two", nil, nil, nil, "added"},
|
||||
},
|
||||
},
|
||||
|
||||
// Three dot
|
||||
{
|
||||
Query: "SELECT to_pk, to_c1, from_pk, from_c1, from_c2, diff_type from dolt_diff('main...branch1', 't');",
|
||||
Expected: []sql.Row{
|
||||
{nil, nil, 1, "one", "two", "removed"},
|
||||
{2, "two", nil, nil, nil, "added"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT to_pk, to_c1, to_c2, from_pk, from_c1, diff_type from dolt_diff('branch1...main', 't');",
|
||||
Expected: []sql.Row{
|
||||
{2, "two", "three", nil, nil, "added"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT to_pk, to_c1, from_pk, from_c1, from_c2, diff_type from dolt_diff('main~...branch1', 't');",
|
||||
Expected: []sql.Row{
|
||||
{nil, nil, 1, "one", "two", "removed"},
|
||||
{2, "two", nil, nil, nil, "added"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT to_pk, to_c1, from_pk, from_c1, from_c2, diff_type from dolt_diff('main...branch1~', 't');",
|
||||
Expected: []sql.Row{
|
||||
{nil, nil, 1, "one", "two", "removed"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -4880,6 +5066,10 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "select from_a, from_b, from_commit, to_commit, diff_type from dolt_diff('HEAD~', 'HEAD', 't1')",
|
||||
Expected: []sql.Row{{1, 2, "HEAD~", "HEAD", "removed"}},
|
||||
},
|
||||
{
|
||||
Query: "select from_a, from_b, from_commit, to_commit, diff_type from dolt_diff('HEAD~..HEAD', 't1')",
|
||||
Expected: []sql.Row{{1, 2, "HEAD~", "HEAD", "removed"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -4899,6 +5089,10 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "select to_a, to_b, from_commit, to_commit, diff_type from dolt_diff('HEAD~', 'HEAD', 't2')",
|
||||
Expected: []sql.Row{{3, 4, "HEAD~", "HEAD", "added"}},
|
||||
},
|
||||
{
|
||||
Query: "select to_a, to_b, from_commit, to_commit, diff_type from dolt_diff('HEAD~..HEAD', 't2')",
|
||||
Expected: []sql.Row{{3, 4, "HEAD~", "HEAD", "added"}},
|
||||
},
|
||||
{
|
||||
// Maybe confusing? We match the old table name as well
|
||||
Query: "select to_a, to_b, from_commit, to_commit, diff_type from dolt_diff('HEAD~', 'HEAD', 't1')",
|
||||
@@ -4928,10 +5122,18 @@ var DiffTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "select to_pk2, to_col1, from_pk, from_col1, diff_type from dolt_diff('HEAD~', 'HEAD', 't1')",
|
||||
Expected: []sql.Row{{1, 100, 1, 1, "modified"}},
|
||||
},
|
||||
{
|
||||
Query: "select to_pk2, to_col1, from_pk, from_col1, diff_type from dolt_diff('HEAD~..HEAD', 't1')",
|
||||
Expected: []sql.Row{{1, 100, 1, 1, "modified"}},
|
||||
},
|
||||
{
|
||||
Query: "select to_pk2a, to_pk2b, to_col1, from_pk1a, from_pk1b, from_col1, diff_type from dolt_diff('HEAD~', 'HEAD', 't2');",
|
||||
Expected: []sql.Row{{1, 1, 100, 1, 1, 1, "modified"}},
|
||||
},
|
||||
{
|
||||
Query: "select to_pk2a, to_pk2b, to_col1, from_pk1a, from_pk1b, from_col1, diff_type from dolt_diff('HEAD~..HEAD', 't2');",
|
||||
Expected: []sql.Row{{1, 1, 100, 1, 1, 1, "modified"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -5451,6 +5653,10 @@ var DiffSummaryTableFunctionScriptTests = []queries.ScriptTest{
|
||||
"set @Commit2 = dolt_commit('-am', 'inserting into t');",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary();",
|
||||
ExpectedErr: sql.ErrInvalidArgumentNumber,
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('t');",
|
||||
ExpectedErr: sql.ErrInvalidArgumentNumber,
|
||||
@@ -5479,14 +5685,26 @@ var DiffSummaryTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "SELECT * from dolt_diff_summary('fake-branch', @Commit2, 't');",
|
||||
ExpectedErrStr: "branch not found: fake-branch",
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('fake-branch..main', 't');",
|
||||
ExpectedErrStr: "branch not found: fake-branch",
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary(@Commit1, 'fake-branch', 't');",
|
||||
ExpectedErrStr: "branch not found: fake-branch",
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main..fake-branch', 't');",
|
||||
ExpectedErrStr: "branch not found: fake-branch",
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary(@Commit1, @Commit2, 'doesnotexist');",
|
||||
ExpectedErr: sql.ErrTableNotFound,
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main^..main', 'doesnotexist');",
|
||||
ExpectedErr: sql.ErrTableNotFound,
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary(@Commit1, concat('fake', '-', 'branch'), 't');",
|
||||
ExpectedErr: sqle.ErrInvalidNonLiteralArgument,
|
||||
@@ -5499,6 +5717,10 @@ var DiffSummaryTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "SELECT * from dolt_diff_summary(@Commit1, @Commit2, LOWER('T'));",
|
||||
ExpectedErr: sqle.ErrInvalidNonLiteralArgument,
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main..main~', LOWER('T'));",
|
||||
ExpectedErr: sqle.ErrInvalidNonLiteralArgument,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -5702,6 +5924,10 @@ var DiffSummaryTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "SELECT * from dolt_diff_summary('STAGED', 'WORKING', 't')",
|
||||
Expected: []sql.Row{{"t", 0, 1, 1, 1, 3, 3, 1, 2, 2, 6, 6}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('STAGED..WORKING', 't')",
|
||||
Expected: []sql.Row{{"t", 0, 1, 1, 1, 3, 3, 1, 2, 2, 6, 6}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('WORKING', 'STAGED', 't')",
|
||||
Expected: []sql.Row{{"t", 0, 1, 1, 1, 3, 3, 1, 2, 2, 6, 6}},
|
||||
@@ -5710,6 +5936,10 @@ var DiffSummaryTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "SELECT * from dolt_diff_summary('WORKING', 'WORKING', 't')",
|
||||
Expected: []sql.Row{},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('WORKING..WORKING', 't')",
|
||||
Expected: []sql.Row{},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('STAGED', 'STAGED', 't')",
|
||||
Expected: []sql.Row{},
|
||||
@@ -5751,20 +5981,83 @@ var DiffSummaryTableFunctionScriptTests = []queries.ScriptTest{
|
||||
"select dolt_checkout('main');",
|
||||
"insert into t values (2, 'two', 'three');",
|
||||
"set @Commit6 = dolt_commit('-am', 'inserting row 2 in main');",
|
||||
|
||||
"create table newtable (pk int primary key);",
|
||||
"insert into newtable values (1), (2);",
|
||||
"set @Commit7 = dolt_commit('-Am', 'new table newtable');",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main', 'branch1', 't');",
|
||||
Expected: []sql.Row{{"t", 0, 0, 1, 1, 0, 4, 0, 2, 1, 6, 2}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main..branch1', 't');",
|
||||
Expected: []sql.Row{{"t", 0, 0, 1, 1, 0, 4, 0, 2, 1, 6, 2}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main', 'branch1');",
|
||||
Expected: []sql.Row{
|
||||
{"t", 0, 0, 1, 1, 0, 4, 0, 2, 1, 6, 2},
|
||||
{"newtable", 0, 0, 2, 0, 0, 2, 0, 2, 0, 2, 0},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main..branch1');",
|
||||
Expected: []sql.Row{
|
||||
{"t", 0, 0, 1, 1, 0, 4, 0, 2, 1, 6, 2},
|
||||
{"newtable", 0, 0, 2, 0, 0, 2, 0, 2, 0, 2, 0},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('branch1', 'main', 't');",
|
||||
Expected: []sql.Row{{"t", 0, 1, 0, 1, 4, 0, 1, 1, 2, 2, 6}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main~', 'branch1', 't');",
|
||||
Query: "SELECT * from dolt_diff_summary('branch1..main', 't');",
|
||||
Expected: []sql.Row{{"t", 0, 1, 0, 1, 4, 0, 1, 1, 2, 2, 6}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main~2', 'branch1', 't');",
|
||||
Expected: []sql.Row{{"t", 0, 1, 1, 0, 2, 3, 0, 1, 1, 3, 2}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main~2..branch1', 't');",
|
||||
Expected: []sql.Row{{"t", 0, 1, 1, 0, 2, 3, 0, 1, 1, 3, 2}},
|
||||
},
|
||||
|
||||
// Three dot
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main...branch1', 't');",
|
||||
Expected: []sql.Row{{"t", 0, 1, 1, 0, 2, 3, 0, 1, 1, 3, 2}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main...branch1');",
|
||||
Expected: []sql.Row{{"t", 0, 1, 1, 0, 2, 3, 0, 1, 1, 3, 2}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('branch1...main', 't');",
|
||||
Expected: []sql.Row{{"t", 1, 1, 0, 0, 3, 0, 0, 1, 2, 3, 6}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('branch1...main');",
|
||||
Expected: []sql.Row{
|
||||
{"t", 1, 1, 0, 0, 3, 0, 0, 1, 2, 3, 6},
|
||||
{"newtable", 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 2},
|
||||
},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('branch1...main^');",
|
||||
Expected: []sql.Row{{"t", 1, 1, 0, 0, 3, 0, 0, 1, 2, 3, 6}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('branch1...main', 'newtable');",
|
||||
Expected: []sql.Row{{"newtable", 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 2}},
|
||||
},
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('main...main', 'newtable');",
|
||||
Expected: []sql.Row{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -5922,11 +6215,20 @@ var DiffSummaryTableFunctionScriptTests = []queries.ScriptTest{
|
||||
Query: "select * from dolt_diff_summary('HEAD~', 'HEAD', 't2')",
|
||||
Expected: []sql.Row{{"t2", 1, 1, 0, 0, 2, 0, 0, 1, 2, 2, 4}},
|
||||
},
|
||||
{
|
||||
Query: "select * from dolt_diff_summary('HEAD~..HEAD', 't2')",
|
||||
Expected: []sql.Row{{"t2", 1, 1, 0, 0, 2, 0, 0, 1, 2, 2, 4}},
|
||||
},
|
||||
{
|
||||
// Old table name can be matched as well
|
||||
Query: "select * from dolt_diff_summary('HEAD~', 'HEAD', 't1')",
|
||||
Expected: []sql.Row{{"t1", 1, 1, 0, 0, 2, 0, 0, 1, 2, 2, 4}},
|
||||
},
|
||||
{
|
||||
// Old table name can be matched as well
|
||||
Query: "select * from dolt_diff_summary('HEAD~..HEAD', 't1')",
|
||||
Expected: []sql.Row{{"t1", 1, 1, 0, 0, 2, 0, 0, 1, 2, 2, 4}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user