-
Notifications
You must be signed in to change notification settings - Fork 133
Support PostgreSQL double qouted columns #590
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
Changes from 11 commits
2e455f9
7be4075
0e9054e
1a38169
add11fa
a212b74
2093651
37ea902
fd04d09
b3b222c
f375d1a
0e4ce09
195a359
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| package encryptor | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "testing" | ||
|
|
||
| "github.com/cossacklabs/acra/encryptor/config" | ||
| "github.com/cossacklabs/acra/sqlparser" | ||
| ) | ||
|
|
||
| func TestGetTableSchemaOfColumnMatchConfiTable(t *testing.T) { | ||
| tableName := "some_table" | ||
|
||
| configStr := fmt.Sprintf(` | ||
| schemas: | ||
| - table: %s | ||
| encrypted: | ||
| - column: "default_client_id" | ||
| - column: specified_client_id | ||
| client_id: specified_client_id | ||
| `, tableName) | ||
| schemaStore, err := config.MapTableSchemaStoreFromConfig([]byte(configStr)) | ||
| if err != nil { | ||
| t.Fatalf("Can't parse config: %s", err.Error()) | ||
| } | ||
|
|
||
| searchableQueryFilter := SearchableQueryFilter{ | ||
| schemaStore: schemaStore, | ||
| } | ||
|
|
||
| tableNamesWithQuotes := sqlparser.NewTableIdentWithQuotes(tableName, '"') | ||
| schemaTable := searchableQueryFilter.getTableSchemaOfColumn(&sqlparser.ColName{}, &AliasedTableName{ | ||
| TableName: sqlparser.TableName{ | ||
| Name: tableNamesWithQuotes, | ||
| }, | ||
| }, AliasToTableMap{}) | ||
|
|
||
| if schemaTable == nil { | ||
| t.Fatalf("Expect not nil schemaTable, matched with config") | ||
| } | ||
| } | ||
|
|
||
| func TestFilterInterestingTables(t *testing.T) { | ||
| tableName := "some_table" | ||
| configStr := fmt.Sprintf(` | ||
| schemas: | ||
| - table: %s | ||
| encrypted: | ||
| - column: "default_client_id" | ||
| - column: specified_client_id | ||
| client_id: specified_client_id | ||
| `, tableName) | ||
| schemaStore, err := config.MapTableSchemaStoreFromConfig([]byte(configStr)) | ||
| if err != nil { | ||
| t.Fatalf("Can't parse config: %s", err.Error()) | ||
| } | ||
|
|
||
| searchableQueryFilter := SearchableQueryFilter{ | ||
| schemaStore: schemaStore, | ||
| } | ||
|
|
||
| tableNamesWithQuotes := sqlparser.NewTableIdentWithQuotes(tableName, '"') | ||
|
|
||
| aliasedTable, _ := searchableQueryFilter.filterInterestingTables(sqlparser.TableExprs{ | ||
| &sqlparser.AliasedTableExpr{ | ||
| Expr: sqlparser.TableName{ | ||
| Name: tableNamesWithQuotes, | ||
| }, | ||
| }, | ||
| }) | ||
|
|
||
| if aliasedTable == nil { | ||
| t.Fatalf("Expect not nil aliasedTable, matched with config") | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,7 @@ import ( | |
| "github.com/cossacklabs/acra/sqlparser/dialect/mysql" | ||
| "github.com/cossacklabs/acra/sqlparser/dialect/postgresql" | ||
| "reflect" | ||
| "strconv" | ||
| "strings" | ||
| "testing" | ||
| "unsafe" | ||
|
|
@@ -535,6 +536,35 @@ func TestTableIdentMarshal(t *testing.T) { | |
| } | ||
| } | ||
|
|
||
| func TestTableIdentValueForConfig(t *testing.T) { | ||
| str := TableIdent{ | ||
| quote: 34, | ||
| v: "table", | ||
| } | ||
| b, err := json.Marshal(str) | ||
|
||
| if err != nil { | ||
| t.Fatal(err) | ||
| } | ||
| got := string(b) | ||
| want := `"table"` | ||
| if got != want { | ||
| t.Errorf("json.Marshal()= %s, want %s", got, want) | ||
| } | ||
| tableForConfig := str.ValueForConfig() | ||
| if tableForConfig == got { | ||
| t.Errorf("ValueForConfig should not be equal with init %s, want %s", got, want) | ||
| } | ||
|
|
||
| unquoted, err := strconv.Unquote(got) | ||
| if err != nil { | ||
| t.Fatal(err) | ||
| } | ||
|
|
||
| if tableForConfig != unquoted { | ||
| t.Errorf("ValueForConfig should be equal with unquoted value %s, want %s", got, want) | ||
| } | ||
| } | ||
|
|
||
| func TestHexDecode(t *testing.T) { | ||
| testcase := []struct { | ||
| in, out string | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -211,6 +211,33 @@ var ( | |
| output: "select /* string table alias */ 1 from t as 't1'", | ||
| // mysql allow to use single quote for column/table aliases | ||
| dialect: mysql.NewMySQLDialect(), | ||
| }, { | ||
| input: `select * from mytable where "AGE" = 1 and "TEST" = 'test'`, | ||
| // postgres allow to use double quote string for columns | ||
| dialect: postgresql.NewPostgreSQLDialect(), | ||
| }, { | ||
| // this is valid query ONLY for MySQL in default mode, for now, | ||
| // but invalid for PostgreSQL and MySQL in ANSI mode and maybe be changed in future | ||
| input: `insert into some_table(id, data) VALUES (10918, "test")`, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets add comment, that it is temporary valid for MySQL default settings, but invalid for PostgreSQL & MySQL with ANSI mode, and probably will be changed. It will help in the future to understand why this case will fail after future changes)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, also added TODO in |
||
| output: `insert into some_table(id, data) values (10918, 'test')`, | ||
| }, { | ||
| input: `insert into some_table(id, data) values (10918, 'test')`, | ||
| }, { | ||
| input: `select * from mytable where "test" = "test"`, | ||
| output: `select * from mytable where 'test' = 'test'`, | ||
| }, { | ||
| input: `select * from mytable where "test" = 1 and 'value' = 'value'`, | ||
| output: `select * from mytable where 'test' = 1 and 'value' = 'value'`, | ||
| }, { | ||
| input: `SELECT "id", "landline_number" AS "landlineNumber", "removal" FROM "users" AS "User" where "User"."is_active"`, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets add some somparison too:
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. plus I remember that you mentioned some integration tests with double quotes. Can we extend them with additional cases that we caught? |
||
| output: `select "id", "landline_number" as "landlineNumber", "removal" from "users" as "User" where "User"."is_active"`, | ||
| dialect: postgresql.NewPostgreSQLDialect(), | ||
| }, { | ||
| input: `select "id" from "users" as "User" where "User"."AGE" = 123`, | ||
| dialect: postgresql.NewPostgreSQLDialect(), | ||
| }, { | ||
| input: `select "id" from "users" as "User" where "AGE" = '123'`, | ||
| dialect: postgresql.NewPostgreSQLDialect(), | ||
| }, { | ||
| input: "select /* string table alias without as */ 1 from t 't1'", | ||
| output: "select /* string table alias without as */ 1 from t as 't1'", | ||
|
|
@@ -1322,11 +1349,17 @@ var ( | |
| ) | ||
|
|
||
| func TestValid(t *testing.T) { | ||
| var testDialect dialect.Dialect | ||
| for i, tcase := range validSQL { | ||
| if tcase.output == "" { | ||
| tcase.output = tcase.input | ||
| } | ||
| tree, err := New(ModeStrict).Parse(tcase.input) | ||
|
|
||
| testDialect = tcase.dialect | ||
| if tcase.dialect == nil { | ||
| testDialect = mysql.NewMySQLDialect() | ||
| } | ||
| tree, err := ParseWithDialect(testDialect, tcase.input) | ||
| if err != nil { | ||
| t.Errorf("Parse(%q) err: %v, want nil", tcase.input, err) | ||
| continue | ||
|
|
@@ -1656,6 +1689,9 @@ func TestConvert(t *testing.T) { | |
| input: "select convert('abc', decimal(4+9)) from t", | ||
| output: "syntax error at position 33", | ||
| }, | ||
| // TODO: added test cases to cover errors for MySQL ANSI mode | ||
| // `insert into table (id, name) values (125, "data")` currently, in ANSI mod its valid query with contains | ||
| // Rows {SQLVal(125), ColName("data")} - but it should fail with error | ||
| } | ||
|
|
||
| var dialect dialect.Dialect | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.