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

Allow database name contain uppercase characters #2504

Merged
merged 15 commits into from
Apr 26, 2023
12 changes: 6 additions & 6 deletions integration/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,11 @@ func TestCollectionName(t *testing.T) {
Name: "InvalidNamespace",
Code: 73,
Message: fmt.Sprintf(
"Fully qualified namespace is too long. Namespace: testcollectionname.%s Max: 255",
"Fully qualified namespace is too long. Namespace: TestCollectionName.%s Max: 255",
collectionName300,
),
},
alt: fmt.Sprintf("Invalid collection name: 'testcollectionname.%s'", collectionName300),
alt: fmt.Sprintf("Invalid collection name: 'TestCollectionName.%s'", collectionName300),
},
"LongEnough": {
collection: collectionName235,
Expand All @@ -350,7 +350,7 @@ func TestCollectionName(t *testing.T) {
Code: 73,
Message: `Invalid collection name: collection_name_with_a-$`,
},
alt: `Invalid collection name: 'testcollectionname.collection_name_with_a-$'`,
alt: `Invalid collection name: 'TestCollectionName.collection_name_with_a-$'`,
},
"WithADash": {
collection: "collection_name_with_a-",
Expand All @@ -363,9 +363,9 @@ func TestCollectionName(t *testing.T) {
err: &mongo.CommandError{
Name: "InvalidNamespace",
Code: 73,
Message: "Invalid namespace specified 'testcollectionname.'",
Message: "Invalid namespace specified 'TestCollectionName.'",
},
alt: "Invalid collection name: 'testcollectionname.'",
alt: "Invalid collection name: 'TestCollectionName.'",
},
"Null": {
collection: "\x00",
Expand All @@ -374,7 +374,7 @@ func TestCollectionName(t *testing.T) {
Code: 73,
Message: "namespaces cannot have embedded null characters",
},
alt: "Invalid collection name: 'testcollectionname.\x00'",
alt: "Invalid collection name: 'TestCollectionName.\x00'",
},
"Dot": {
collection: "collection.name",
Expand Down
2 changes: 1 addition & 1 deletion integration/commands_administration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func TestCommandsAdministrationCreateDropList(t *testing.T) {
expectedErr = mongo.CommandError{
Code: 48,
Name: "NamespaceExists",
Message: `Collection testcommandsadministrationcreatedroplist.TestCommandsAdministrationCreateDropList already exists.`,
Message: `Collection TestCommandsAdministrationCreateDropList.TestCommandsAdministrationCreateDropList already exists.`,
}
AssertEqualError(t, expectedErr, err)

Expand Down
2 changes: 1 addition & 1 deletion integration/commands_diagnostic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ func TestCommandsDiagnosticValidate(t *testing.T) {

actual := ConvertDocument(t, doc)
expected := must.NotFail(types.NewDocument(
"ns", "testcommandsdiagnosticvalidate.TestCommandsDiagnosticValidate",
"ns", "TestCommandsDiagnosticValidate.TestCommandsDiagnosticValidate",
"nInvalidDocuments", int32(0),
"nNonCompliantDocuments", int32(0),
"nrecords", int32(0), // replaced below
Expand Down
9 changes: 5 additions & 4 deletions integration/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package integration
import (
"fmt"
"runtime"
"strings"
"sync"
"sync/atomic"
"testing"
Expand Down Expand Up @@ -112,7 +111,8 @@ func TestCreateStress(t *testing.T) {
func TestCreateOnInsertStressSameCollection(t *testing.T) {
setup.SkipForTigrisWithReason(t, "https://github.com/FerretDB/FerretDB/issues/1341")
ctx, collection := setup.Setup(t)
db := collection.Database().Client().Database(strings.ToLower(t.Name()))
// do not toLower() db name as it may contain uppercase letters
db := collection.Database().Client().Database(t.Name())

collNum := runtime.GOMAXPROCS(-1) * 10
collPrefix := "stress_same_collection"
Expand Down Expand Up @@ -149,7 +149,8 @@ func TestCreateOnInsertStressSameCollection(t *testing.T) {

func TestCreateOnInsertStressDiffCollection(t *testing.T) {
ctx, collection := setup.Setup(t)
db := collection.Database().Client().Database(strings.ToLower(t.Name()))
// do not toLower() db name as it may contain uppercase letters
db := collection.Database().Client().Database(t.Name())

collNum := runtime.GOMAXPROCS(-1) * 10
collPrefix := "stress_diff_collection_"
Expand Down Expand Up @@ -234,7 +235,7 @@ func TestCreateStressSameCollection(t *testing.T) {
mongo.CommandError{
Code: 48,
Name: "NamespaceExists",
Message: `Collection testcreatestresssamecollection.stress_same_collection already exists.`,
Message: `Collection TestCreateStressSameCollection.stress_same_collection already exists.`,
},
err,
)
Expand Down
2 changes: 1 addition & 1 deletion integration/findandmodify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestFindAndModifyEmptyCollectionName(t *testing.T) {
"EmptyCollectionName": {
err: &mongo.CommandError{
Code: 73,
Message: "Invalid namespace specified 'testfindandmodifyemptycollectionname-emptycollectionname.'",
Message: "Invalid namespace specified 'TestFindAndModifyEmptyCollectionName-EmptyCollectionName.'",
Name: "InvalidNamespace",
},
},
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/pg/pgdb/databases.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
)

// validateDatabaseNameRe validates FerretDB database / PostgreSQL schema names.
var validateDatabaseNameRe = regexp.MustCompile("^[a-z_-][a-z0-9_-]{0,62}$")
var validateDatabaseNameRe = regexp.MustCompile("^[a-zA-Z_-][a-zA-Z0-9_-]{0,62}$")

// Databases returns a sorted list of FerretDB databases / PostgreSQL schemas.
func Databases(ctx context.Context, tx pgx.Tx) ([]string, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/pg/pgdb/indexes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func TestCreateIndexIfNotExists(t *testing.T) {
require.NoError(t, err)

expectedIndexdef := fmt.Sprintf(
"CREATE INDEX %s ON %s.%s USING btree (((_jsonb -> 'foo'::text)), ((_jsonb -> 'bar'::text)) DESC)",
"CREATE INDEX %s ON \"%s\".%s USING btree (((_jsonb -> 'foo'::text)), ((_jsonb -> 'bar'::text)) DESC)",
pgIndexName, databaseName, tableName,
)
assert.Equal(t, expectedIndexdef, indexdef)
Expand Down
8 changes: 4 additions & 4 deletions internal/handlers/pg/pgdb/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func CalculateDBStats(ctx context.Context, tx pgx.Tx, db string) (*DBStats, erro
// See also https://www.postgresql.org/docs/15/functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT
sql = `
SELECT
SUM(pg_total_relation_size(schemaname || '.' || tablename))
SUM(pg_total_relation_size(quote_ident(schemaname) || '.' || quote_ident(tablename)))
FROM pg_tables
WHERE schemaname = $1`
args := []any{db}
Expand All @@ -116,7 +116,7 @@ func CalculateDBStats(ctx context.Context, tx pgx.Tx, db string) (*DBStats, erro
COALESCE(SUM(pg_table_size(c.oid)), 0) AS SizeTables,
COALESCE(SUM(pg_indexes_size(c.oid)), 0) AS SizeIndexes
FROM pg_tables AS t
LEFT JOIN pg_class AS c ON c.relname = t.tablename AND c.relnamespace = t.schemaname::regnamespace
LEFT JOIN pg_class AS c ON c.relname = t.tablename AND c.relnamespace = quote_ident(t.schemaname)::regnamespace
LEFT JOIN pg_indexes AS i ON i.schemaname = t.schemaname AND i.tablename = t.tablename
WHERE t.schemaname = $1 AND t.tablename NOT LIKE $2`
args = []any{db, reservedPrefix + "%"}
Expand Down Expand Up @@ -162,8 +162,8 @@ func CalculateCollStats(ctx context.Context, tx pgx.Tx, db, collection string) (
COALESCE(pg_table_size(oid), 0) AS SizeTable,
COALESCE(pg_indexes_size(oid), 0) AS SizeIndexes
FROM pg_class
WHERE oid = %s::regclass`,
quoteString(db+"."+metadata.table),
WHERE oid = '%s'::regclass`,
pgx.Identifier{db, metadata.table}.Sanitize(),
)
row := tx.QueryRow(ctx, sql)

Expand Down
4 changes: 2 additions & 2 deletions internal/util/testutil/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ func stack() []byte {
func DatabaseName(tb testing.TB) string {
tb.Helper()

// database names are always lowercase
name := strings.ToLower(tb.Name())
// database names may contain lowercase and uppercase characters
name := tb.Name()

name = strings.ReplaceAll(name, "/", "-")
name = strings.ReplaceAll(name, " ", "_")
Expand Down
1 change: 0 additions & 1 deletion website/docs/diff.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ slug: /diff/ # referenced in README.md and beacon
* database name must not include non-latin letters;
* collection name must be valid UTF-8 characters;
* database name must not start with a number;
* database name cannot contain capital letters;
9. For Tigris, FerretDB requires Tigris schema validation for `create` command: validator must be set as `$tigrisSchemaString`.
The value must be a JSON string representing JSON schema in [Tigris format](https://docs.tigrisdata.com/overview/schema).
10. FerretDB offers the same validation rules for the `scale` parameter in both the `collStats` and `dbStats` commands.
Expand Down