mirror of
				https://github.com/chaisql/chai.git
				synced 2025-10-31 19:02:48 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			161 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package parser
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/genjidb/genji/database"
 | |
| 	"github.com/genjidb/genji/document"
 | |
| 	"github.com/genjidb/genji/sql/query"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| )
 | |
| 
 | |
| func TestParserCreateTable(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		name     string
 | |
| 		s        string
 | |
| 		expected query.Statement
 | |
| 		errored  bool
 | |
| 	}{
 | |
| 		{"Basic", "CREATE TABLE test", query.CreateTableStmt{TableName: "test"}, false},
 | |
| 		{"If not exists", "CREATE TABLE IF NOT EXISTS test", query.CreateTableStmt{TableName: "test", IfNotExists: true}, false},
 | |
| 		{"With primary key", "CREATE TABLE test(foo INTEGER PRIMARY KEY)",
 | |
| 			query.CreateTableStmt{
 | |
| 				TableName: "test",
 | |
| 				Info: database.TableInfo{
 | |
| 					FieldConstraints: []database.FieldConstraint{
 | |
| 						{Path: parsePath(t, "foo"), Type: document.IntegerValue, IsPrimaryKey: true},
 | |
| 					},
 | |
| 				},
 | |
| 			}, false},
 | |
| 		{"With primary key twice", "CREATE TABLE test(foo PRIMARY KEY PRIMARY KEY)",
 | |
| 			query.CreateTableStmt{}, true},
 | |
| 		{"With type", "CREATE TABLE test(foo INTEGER)",
 | |
| 			query.CreateTableStmt{
 | |
| 				TableName: "test",
 | |
| 				Info: database.TableInfo{
 | |
| 					FieldConstraints: []database.FieldConstraint{
 | |
| 						{Path: parsePath(t, "foo"), Type: document.IntegerValue},
 | |
| 					},
 | |
| 				},
 | |
| 			}, false},
 | |
| 		{"With not null", "CREATE TABLE test(foo NOT NULL)",
 | |
| 			query.CreateTableStmt{
 | |
| 				TableName: "test",
 | |
| 				Info: database.TableInfo{
 | |
| 					FieldConstraints: []database.FieldConstraint{
 | |
| 						{Path: parsePath(t, "foo"), IsNotNull: true},
 | |
| 					},
 | |
| 				},
 | |
| 			}, false},
 | |
| 		{"With not null twice", "CREATE TABLE test(foo NOT NULL NOT NULL)",
 | |
| 			query.CreateTableStmt{}, true},
 | |
| 		{"With type and not null", "CREATE TABLE test(foo INTEGER NOT NULL)",
 | |
| 			query.CreateTableStmt{
 | |
| 				TableName: "test",
 | |
| 				Info: database.TableInfo{
 | |
| 					FieldConstraints: []database.FieldConstraint{
 | |
| 						{Path: parsePath(t, "foo"), Type: document.IntegerValue, IsNotNull: true},
 | |
| 					},
 | |
| 				},
 | |
| 			}, false},
 | |
| 		{"With not null and primary key", "CREATE TABLE test(foo INTEGER NOT NULL PRIMARY KEY)",
 | |
| 			query.CreateTableStmt{
 | |
| 				TableName: "test",
 | |
| 				Info: database.TableInfo{
 | |
| 					FieldConstraints: []database.FieldConstraint{
 | |
| 						{Path: parsePath(t, "foo"), Type: document.IntegerValue, IsPrimaryKey: true, IsNotNull: true},
 | |
| 					},
 | |
| 				},
 | |
| 			}, false},
 | |
| 		{"With primary key and not null", "CREATE TABLE test(foo INTEGER PRIMARY KEY NOT NULL)",
 | |
| 			query.CreateTableStmt{
 | |
| 				TableName: "test",
 | |
| 				Info: database.TableInfo{
 | |
| 					FieldConstraints: []database.FieldConstraint{
 | |
| 						{Path: parsePath(t, "foo"), Type: document.IntegerValue, IsPrimaryKey: true, IsNotNull: true},
 | |
| 					},
 | |
| 				},
 | |
| 			}, false},
 | |
| 		{"With multiple constraints", "CREATE TABLE test(foo INTEGER PRIMARY KEY, bar INTEGER NOT NULL, baz[4][1].bat TEXT)",
 | |
| 			query.CreateTableStmt{
 | |
| 				TableName: "test",
 | |
| 				Info: database.TableInfo{
 | |
| 					FieldConstraints: []database.FieldConstraint{
 | |
| 						{Path: parsePath(t, "foo"), Type: document.IntegerValue, IsPrimaryKey: true},
 | |
| 						{Path: parsePath(t, "bar"), Type: document.IntegerValue, IsNotNull: true},
 | |
| 						{Path: parsePath(t, "baz[4][1].bat"), Type: document.TextValue},
 | |
| 					},
 | |
| 				},
 | |
| 			}, false},
 | |
| 		{"With multiple primary keys", "CREATE TABLE test(foo PRIMARY KEY, bar PRIMARY KEY)",
 | |
| 			query.CreateTableStmt{}, true},
 | |
| 		{"With all supported fixed size data types",
 | |
| 			"CREATE TABLE test(d double, b bool)",
 | |
| 			query.CreateTableStmt{
 | |
| 				TableName: "test",
 | |
| 				Info: database.TableInfo{
 | |
| 					FieldConstraints: []database.FieldConstraint{
 | |
| 						{Path: parsePath(t, "d"), Type: document.DoubleValue},
 | |
| 						{Path: parsePath(t, "b"), Type: document.BoolValue},
 | |
| 					},
 | |
| 				},
 | |
| 			}, false},
 | |
| 		{"With all supported variable size data types",
 | |
| 			"CREATE TABLE test(i integer, b blob, byt bytes, t text, a array, d document)",
 | |
| 			query.CreateTableStmt{
 | |
| 				TableName: "test",
 | |
| 				Info: database.TableInfo{
 | |
| 					FieldConstraints: []database.FieldConstraint{
 | |
| 						{Path: parsePath(t, "i"), Type: document.IntegerValue},
 | |
| 						{Path: parsePath(t, "b"), Type: document.BlobValue},
 | |
| 						{Path: parsePath(t, "byt"), Type: document.BlobValue},
 | |
| 						{Path: parsePath(t, "t"), Type: document.TextValue},
 | |
| 						{Path: parsePath(t, "a"), Type: document.ArrayValue},
 | |
| 						{Path: parsePath(t, "d"), Type: document.DocumentValue},
 | |
| 					},
 | |
| 				},
 | |
| 			}, false},
 | |
| 	}
 | |
| 
 | |
| 	for _, test := range tests {
 | |
| 		t.Run(test.name, func(t *testing.T) {
 | |
| 			q, err := ParseQuery(test.s)
 | |
| 			if test.errored {
 | |
| 				require.Error(t, err)
 | |
| 				return
 | |
| 			}
 | |
| 			require.NoError(t, err)
 | |
| 			require.Len(t, q.Statements, 1)
 | |
| 			require.EqualValues(t, test.expected, q.Statements[0])
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestParserCreateIndex(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		name     string
 | |
| 		s        string
 | |
| 		expected query.Statement
 | |
| 		errored  bool
 | |
| 	}{
 | |
| 		{"Basic", "CREATE INDEX idx ON test (foo)", query.CreateIndexStmt{IndexName: "idx", TableName: "test", Path: parsePath(t, "foo")}, false},
 | |
| 		{"If not exists", "CREATE INDEX IF NOT EXISTS idx ON test (foo.bar[1])", query.CreateIndexStmt{IndexName: "idx", TableName: "test", Path: parsePath(t, "foo.bar[1]"), IfNotExists: true}, false},
 | |
| 		{"Unique", "CREATE UNIQUE INDEX IF NOT EXISTS idx ON test (foo[3].baz)", query.CreateIndexStmt{IndexName: "idx", TableName: "test", Path: parsePath(t, "foo[3].baz"), IfNotExists: true, Unique: true}, false},
 | |
| 		{"No fields", "CREATE INDEX idx ON test", nil, true},
 | |
| 		{"More than 1 path", "CREATE INDEX idx ON test (foo, bar)", nil, true},
 | |
| 	}
 | |
| 
 | |
| 	for _, test := range tests {
 | |
| 		t.Run(test.name, func(t *testing.T) {
 | |
| 			q, err := ParseQuery(test.s)
 | |
| 			if test.errored {
 | |
| 				require.Error(t, err)
 | |
| 				return
 | |
| 			}
 | |
| 			require.NoError(t, err)
 | |
| 			require.Len(t, q.Statements, 1)
 | |
| 			require.EqualValues(t, test.expected, q.Statements[0])
 | |
| 		})
 | |
| 	}
 | |
| }
 | 
