Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workbench tests for log, merge, table details #705

Merged
merged 20 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ require (
github.com/PuerkitoBio/goquery v1.8.1
github.com/cockroachdb/apd/v2 v2.0.3-0.20200518165714-d020e156310a
github.com/cockroachdb/errors v1.7.5
github.com/dolthub/dolt/go v0.40.5-0.20240919183209-28badac50053
github.com/dolthub/dolt/go v0.40.5-0.20240924203939-2f79023217f7
github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi v0.0.0-20240827111219-e4bb9ca3442d
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2
github.com/dolthub/go-icu-regex v0.0.0-20240916130659-0118adc6b662
github.com/dolthub/go-mysql-server v0.18.2-0.20240920224603-6f1a8518b048
github.com/dolthub/go-mysql-server v0.18.2-0.20240923181307-5aacdb13e45a
github.com/dolthub/sqllogictest/go v0.0.0-20240618184124-ca47f9354216
github.com/dolthub/vitess v0.0.0-20240919225659-2ad81685e772
github.com/fatih/color v1.13.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dolthub/dolt/go v0.40.5-0.20240919183209-28badac50053 h1:R0nHYkk/1a6BuDwcrGVhtJANqFmKmAfMGK0cUwo1/P0=
github.com/dolthub/dolt/go v0.40.5-0.20240919183209-28badac50053/go.mod h1:OkulohTdSGOFzq3YR3NxVxYLU4Z2GLUaYL8fb/f8cho=
github.com/dolthub/dolt/go v0.40.5-0.20240924203939-2f79023217f7 h1:Tgw1FOKBmOd0C+jZ/8nJuTwCdc5Sac8rlZLu6K0Pz70=
github.com/dolthub/dolt/go v0.40.5-0.20240924203939-2f79023217f7/go.mod h1:1HBB+xUaDISZ6GrUmiiD//Ij5wExAAV1nPDpU4xPrmg=
github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi v0.0.0-20240827111219-e4bb9ca3442d h1:RZkQeYOrDrOWzCxaP2ttkvg4E2TM9n8lnEsIBLKjqkM=
github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi v0.0.0-20240827111219-e4bb9ca3442d/go.mod h1:L5RDYZbC9BBWmoU2+TjTekeqqhFXX5EqH9ln00O0stY=
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 h1:u3PMzfF8RkKd3lB9pZ2bfn0qEG+1Gms9599cr0REMww=
Expand All @@ -224,8 +224,8 @@ github.com/dolthub/fslock v0.0.3 h1:iLMpUIvJKMKm92+N1fmHVdxJP5NdyDK5bK7z7Ba2s2U=
github.com/dolthub/fslock v0.0.3/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0=
github.com/dolthub/go-icu-regex v0.0.0-20240916130659-0118adc6b662 h1:aC17hZD6iwzBwwfO5M+3oBT5E5gGRiQPdn+vzpDXqIA=
github.com/dolthub/go-icu-regex v0.0.0-20240916130659-0118adc6b662/go.mod h1:KPUcpx070QOfJK1gNe0zx4pA5sicIK1GMikIGLKC168=
github.com/dolthub/go-mysql-server v0.18.2-0.20240920224603-6f1a8518b048 h1:cYdcm/bKRAupP51QfcWhelgDBNg1r36OKlAf7+meU4E=
github.com/dolthub/go-mysql-server v0.18.2-0.20240920224603-6f1a8518b048/go.mod h1:lGbU2bK+QNnlETdUjOOaE+UnlEUu31VaQOFKAFGyZN4=
github.com/dolthub/go-mysql-server v0.18.2-0.20240923181307-5aacdb13e45a h1:rpCmZj332eiBbzsHsq3Sj5AWzl3Q7szDObwI49UqA8Y=
github.com/dolthub/go-mysql-server v0.18.2-0.20240923181307-5aacdb13e45a/go.mod h1:lGbU2bK+QNnlETdUjOOaE+UnlEUu31VaQOFKAFGyZN4=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63 h1:OAsXLAPL4du6tfbBgK0xXHZkOlos63RdKYS3Sgw/dfI=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63/go.mod h1:lV7lUeuDhH5thVGDCKXbatwKy2KW80L4rMT46n+Y2/Q=
github.com/dolthub/ishell v0.0.0-20240701202509-2b217167d718 h1:lT7hE5k+0nkBdj/1UOSFwjWpNxf+LCApbRHgnCA17XE=
Expand Down
72 changes: 71 additions & 1 deletion server/ast/alter_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,22 @@ func nodeAlterTable(node *tree.AlterTable) (*vitess.AlterTable, error) {
if node == nil {
return nil, nil
}
return nil, fmt.Errorf("ALTER TABLE is not yet supported")

treeTableName := node.Table.ToTableName()
tableName, err := nodeTableName(&treeTableName)
if err != nil {
return nil, err
}

statements, err := nodeAlterTableCmds(node.Cmds, tableName, node.IfExists)
if err != nil {
return nil, err
}

return &vitess.AlterTable{
Table: tableName,
Statements: statements,
}, nil
}

// nodeAlterTableSetSchema handles *tree.AlterTableSetSchema nodes.
Expand All @@ -37,3 +52,58 @@ func nodeAlterTableSetSchema(node *tree.AlterTableSetSchema) (vitess.Statement,
}
return nil, fmt.Errorf("ALTER TABLE SET SCHEMA is not yet supported")
}

// nodeAlterTableCmds converts tree.AlterTableCmds into a slice of vitess.DDL
// instances that can be executed by GMS. |tableName| identifies the table
// being altered, and |ifExists| indicates whether the IF EXISTS clause was
// specified.
func nodeAlterTableCmds(
node tree.AlterTableCmds,
tableName vitess.TableName,
ifExists bool) ([]*vitess.DDL, error) {

if len(node) == 0 {
return nil, fmt.Errorf("no commands specified for ALTER TABLE statement")
} else if len(node) > 1 {
return nil, fmt.Errorf("ALTER TABLE with multiple commands is not yet supported")
}

vitessDdlCmds := make([]*vitess.DDL, 0, len(node))
for _, cmd := range node {
switch cmd := cmd.(type) {
case *tree.AlterTableAddConstraint:
statement, err := nodeAlterTableAddConstraint(cmd, tableName, ifExists)
if err != nil {
return nil, err
}
vitessDdlCmds = append(vitessDdlCmds, statement)

default:
return nil, fmt.Errorf("ALTER TABLE with unsupported command type %T", cmd)
}
}

return vitessDdlCmds, nil
}

// nodeAlterTableAddConstraint converts a tree.AlterTableAddConstraint instance
// into a vitess.DDL instance that can be executed by GMS. |tableName| identifies
// the table being altered, and |ifExists| indicates whether the IF EXISTS clause
// was specified.
func nodeAlterTableAddConstraint(
node *tree.AlterTableAddConstraint,
tableName vitess.TableName,
ifExists bool) (*vitess.DDL, error) {

if node.ValidationBehavior == tree.ValidationSkip {
return nil, fmt.Errorf("NOT VALID is not supported yet")
}

switch constraintDef := node.ConstraintDef.(type) {
case *tree.UniqueConstraintTableDef:
return nodeUniqueConstraintTableDef(constraintDef, tableName, ifExists)
default:
return nil, fmt.Errorf("ALTER TABLE with unsupported constraint "+
"definition type %T", node)
}
}
65 changes: 65 additions & 0 deletions server/ast/constraint_table_def.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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 ast

import (
"fmt"

vitess "github.com/dolthub/vitess/go/vt/sqlparser"

"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
)

// nodeUniqueConstraintTableDef converts a tree.UniqueConstraintTableDef instance
// into a vitess.DDL instance that can be executed by GMS. |tableName| identifies
// the table being altered, and |ifExists| indicates whether the IF EXISTS clause
// was specified.
func nodeUniqueConstraintTableDef(
node *tree.UniqueConstraintTableDef,
tableName vitess.TableName,
ifExists bool) (*vitess.DDL, error) {

if len(node.IndexParams.StorageParams) > 0 {
return nil, fmt.Errorf("STORAGE parameters not yet supported for indexes")
}

if node.IndexParams.Tablespace != "" {
return nil, fmt.Errorf("TABLESPACE is not yet supported")
}

if node.NullsNotDistinct {
return nil, fmt.Errorf("NULLS NOT DISTINCT is not yet supported")
}

columns, err := nodeIndexElemList(node.Columns)
if err != nil {
return nil, err
}

if node.PrimaryKey {
return &vitess.DDL{
Action: "alter",
Table: tableName,
IfExists: ifExists,
IndexSpec: &vitess.IndexSpec{
Action: "create",
Type: "primary",
Columns: columns,
},
}, nil
} else {
return nil, fmt.Errorf("Only PRIMARY KEY constraints are supported currently")
}
}
73 changes: 73 additions & 0 deletions server/ast/index_elem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2023 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 ast

import (
"fmt"

vitess "github.com/dolthub/vitess/go/vt/sqlparser"
"github.com/sirupsen/logrus"

"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
)

// nodeIndexElemList converts a tree.IndexElemList to a slice of vitess.IndexColumn.
func nodeIndexElemList(node tree.IndexElemList) ([]*vitess.IndexColumn, error) {
vitessIndexColumns := make([]*vitess.IndexColumn, 0, len(node))
for _, inputColumn := range node {
if inputColumn.Expr != nil {
return nil, fmt.Errorf("expression index attribute is not yet supported")
}
if inputColumn.Collation != "" {
return nil, fmt.Errorf("index attribute collation is not yet supported")
}
if inputColumn.OpClass != nil {
return nil, fmt.Errorf("index attribute operator class is not yet supported")
}
if inputColumn.ExcludeOp != nil {
return nil, fmt.Errorf("index attribute exclude operator is not yet supported")
}

switch inputColumn.Direction {
case tree.DefaultDirection:
// Defaults to ASC
case tree.Ascending:
// The only default supported in GMS for now
case tree.Descending:
logrus.Warn("descending indexes are not yet supported, ignoring sort order")
default:
return nil, fmt.Errorf("unknown index sorting direction encountered")
}

switch inputColumn.NullsOrder {
case tree.DefaultNullsOrder:
// TODO: the default NULL order is reversed compared to MySQL, so the default is technically always wrong.
// To prevent choking on every index, we allow this to proceed (even with incorrect results) for now.
case tree.NullsFirst:
// The only form supported in GMS for now
case tree.NullsLast:
return nil, fmt.Errorf("NULLS LAST for indexes is not yet supported")
default:
return nil, fmt.Errorf("unknown NULL ordering for index")
}

vitessIndexColumns = append(vitessIndexColumns, &vitess.IndexColumn{
Column: vitess.NewColIdent(string(inputColumn.Column)),
Order: vitess.AscScr,
})
}

return vitessIndexColumns, nil
}
48 changes: 5 additions & 43 deletions server/ast/index_table_def.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"fmt"

vitess "github.com/dolthub/vitess/go/vt/sqlparser"
"github.com/sirupsen/logrus"

"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
)
Expand All @@ -38,49 +37,12 @@ func nodeIndexTableDef(node *tree.IndexTableDef) (*vitess.IndexDefinition, error
if node.IndexParams.Tablespace != "" {
return nil, fmt.Errorf("tablespace is not yet supported")
}
columns := make([]*vitess.IndexColumn, len(node.Columns))
for i, indexElem := range node.Columns {
if indexElem.Expr != nil {
return nil, fmt.Errorf("expression index attribute is not yet supported")
}
if indexElem.Collation != "" {
return nil, fmt.Errorf("index attribute collation is not yet supported")
}
if indexElem.OpClass != nil {
return nil, fmt.Errorf("index attribute operator class is not yet supported")
}
switch indexElem.Direction {
case tree.DefaultDirection:
// Defaults to ASC
case tree.Ascending:
// The only default supported in GMS for now
case tree.Descending:
logrus.Warn("descending indexes are not yet supported, ignoring sort order")
default:
return nil, fmt.Errorf("unknown index sorting direction encountered")
}
if indexElem.Direction == tree.Descending {
logrus.Warn("descending indexes are not yet supported, ignoring sort order")
}
switch indexElem.NullsOrder {
case tree.DefaultNullsOrder:
// TODO: the default NULL order is reversed compared to MySQL, so the default is technically always wrong.
// To prevent choking on every index, we allow this to proceed (even with incorrect results) for now.
case tree.NullsFirst:
// The only form supported in GMS for now
case tree.NullsLast:
return nil, fmt.Errorf("NULLS LAST for indexes is not yet supported")
default:
return nil, fmt.Errorf("unknown NULL ordering for index")
}
if indexElem.ExcludeOp != nil {
return nil, fmt.Errorf("index attribute exclude operator is not yet supported")
}
columns[i] = &vitess.IndexColumn{
Column: vitess.NewColIdent(string(indexElem.Column)),
Order: vitess.AscScr,
}

columns, err := nodeIndexElemList(node.Columns)
if err != nil {
return nil, err
}

return &vitess.IndexDefinition{
Info: &vitess.IndexInfo{
Type: "",
Expand Down
72 changes: 72 additions & 0 deletions testing/go/alter_table_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// 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 _go

import (
"testing"

"github.com/dolthub/go-mysql-server/sql"
)

func TestAlterTableAddPrimaryKey(t *testing.T) {
RunScripts(t, []ScriptTest{
{
Name: "Add Primary Key",
SetUpScript: []string{
"CREATE TABLE test1 (a INT, b INT);",
"CREATE TABLE test2 (a INT, b INT, c INT);",
"CREATE TABLE pkTable1 (a INT PRIMARY KEY);",
"CREATE TABLE duplicateRows (a INT, b INT);",
"INSERT INTO duplicateRows VALUES (1, 2), (1, 2);",
},
Assertions: []ScriptTestAssertion{
{
Query: "ALTER TABLE test1 ADD PRIMARY KEY (a);",
Expected: []sql.Row{},
},
{
// Test the pk by inserting a duplicate value
Query: "INSERT into test1 values (1, 2), (1, 3);",
ExpectedErr: "duplicate primary key",
},
{
Query: "ALTER TABLE test2 ADD PRIMARY KEY (a, b);",
Expected: []sql.Row{},
},
{
// Test the pk by inserting a duplicate value
Query: "INSERT into test2 values (1, 2, 3), (1, 2, 4);",
ExpectedErr: "duplicate primary key",
},
{
Query: "ALTER TABLE pkTable1 ADD PRIMARY KEY (a);",
ExpectedErr: "Multiple primary keys defined",
},
{
Query: "ALTER TABLE duplicateRows ADD PRIMARY KEY (a);",
ExpectedErr: "duplicate primary key",
},
{
// TODO: This statement fails in analysis, because it can't find a table named
// doesNotExist – since IF EXISTS is specified, the analyzer should skip
// errors on resolving the table in this case.
Skip: true,
Query: "ALTER TABLE IF EXISTS doesNotExist ADD PRIMARY KEY (a, b);",
Expected: []sql.Row{},
},
},
},
})
}
Loading
Loading