-
Notifications
You must be signed in to change notification settings - Fork 14
General update #48
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
base: main
Are you sure you want to change the base?
General update #48
Changes from all commits
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 |
|---|---|---|
| @@ -1,34 +1,32 @@ | ||
| package drivers | ||
|
|
||
| import ( | ||
| "log" | ||
| "fmt" | ||
|
|
||
| "github.com/PumpkinSeed/sqlfuzz/drivers/mysql" | ||
| "github.com/PumpkinSeed/sqlfuzz/drivers/postgres" | ||
| "github.com/PumpkinSeed/sqlfuzz/drivers/types" | ||
| ) | ||
|
|
||
| // New creates a new driver instance based on the flags | ||
| func New(f types.Flags) types.Driver { | ||
| func New(f types.Flags) (types.Driver, error) { | ||
| switch f.Driver { | ||
| case "mysql": | ||
| return mysql.New(f) | ||
| return mysql.New(f), nil | ||
| case "postgres": | ||
| return postgres.New(f) | ||
| return postgres.New(f), nil | ||
| default: | ||
| log.Fatal("Driver not implemented") | ||
| return nil | ||
| return nil, fmt.Errorf("driver %q not implemented", f.Driver) | ||
| } | ||
| } | ||
|
|
||
| func NewTestable(f types.Flags) types.Testable { | ||
| func NewTestable(f types.Flags) (types.Testable, error) { | ||
| switch f.Driver { | ||
| case "mysql": | ||
| return mysql.New(f) | ||
| return mysql.New(f), nil | ||
| case "postgres": | ||
| return postgres.New(f) | ||
| return postgres.New(f), nil | ||
| default: | ||
| log.Fatal("Testable not implemented") | ||
| return nil | ||
| return nil, fmt.Errorf("testable %q not implemented", f.Driver) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,11 +11,11 @@ import ( | |
|
|
||
| const ( | ||
| MySQLDescribeTemplate = `select column_name, data_type, character_maximum_length, column_default, is_nullable,numeric_precision,numeric_scale,extra,column_key | ||
| from INFORMATION_SCHEMA.COLUMNS where table_name = '%s'` | ||
| from INFORMATION_SCHEMA.COLUMNS where table_name = ?` | ||
| MySQLDescribeTableQuery = "SHOW TABLES;" | ||
| mysqlFKQuery = `SELECT CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME | ||
| from INFORMATION_SCHEMA.KEY_COLUMN_USAGE | ||
| where REFERENCED_TABLE_NAME <> 'NULL' and REFERENCED_COLUMN_NAME <> 'NULL' and TABLE_NAME = '%s'` | ||
| mysqlFKQuery = `SELECT CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME | ||
| from INFORMATION_SCHEMA.KEY_COLUMN_USAGE | ||
| where REFERENCED_TABLE_NAME <> 'NULL' and REFERENCED_COLUMN_NAME <> 'NULL' and TABLE_NAME = ?` | ||
| ) | ||
|
|
||
| var ( | ||
|
|
@@ -178,12 +178,11 @@ func (m MySQL) MapField(descriptor types.FieldDescriptor) types.Field { | |
| } | ||
|
|
||
| func (MySQL) Describe(table string, db *sql.DB) ([]types.FieldDescriptor, error) { | ||
| describeQuery := fmt.Sprintf(MySQLDescribeTemplate, table) | ||
| results, err := db.Query(describeQuery) | ||
| results, err := db.Query(MySQLDescribeTemplate, table) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| fkRows, err := db.Query(fmt.Sprintf(mysqlFKQuery, strings.ToLower(table))) | ||
| fkRows, err := db.Query(mysqlFKQuery, strings.ToLower(table)) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
@@ -214,7 +213,7 @@ func (m MySQL) MultiDescribe(tables []string, db *sql.DB) (tableToDescriptorMap | |
| } | ||
|
|
||
| func (MySQL) GetLatestColumnValue(table, column string, db *sql.DB) (interface{}, error) { | ||
| query := fmt.Sprintf("select %v from %v order by %v desc limit 1", column, table, column) | ||
| query := fmt.Sprintf("select `%s` from `%s` order by `%s` desc limit 1", column, table, column) | ||
|
||
| rows, err := db.Query(query) | ||
| if err != nil { | ||
| return nil, err | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,26 +68,26 @@ const CreateTable = `CREATE TABLE IF NOT EXISTS %s ( | |
|
|
||
| const ( | ||
| PSQLDescribeTemplate = `select column_name, data_type, character_maximum_length, column_default, is_nullable,numeric_precision,numeric_scale | ||
| from INFORMATION_SCHEMA.COLUMNS where table_name = '%s'` | ||
| from INFORMATION_SCHEMA.COLUMNS where table_name = $1` | ||
| PSQLConnectionTemplate = "host=%s port=%s user=%s password=%s dbname=%s sslmode=disable" | ||
| PSQLInsertTemplate = `INSERT INTO %s("%s") VALUES(%s)` | ||
| PSQLShowTablesQuery = "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';" | ||
| psqlForeignKeysQuery = ` | ||
| psqlForeignKeysQuery = ` | ||
| SELECT | ||
| tc.constraint_name, | ||
| tc.table_name, | ||
| kcu.column_name, | ||
| tc.constraint_name, | ||
| tc.table_name, | ||
| kcu.column_name, | ||
| ccu.table_name AS foreign_table_name, | ||
| ccu.column_name AS foreign_column_name | ||
| FROM | ||
| information_schema.table_constraints AS tc | ||
| ccu.column_name AS foreign_column_name | ||
| FROM | ||
| information_schema.table_constraints AS tc | ||
| JOIN information_schema.key_column_usage AS kcu | ||
| ON tc.constraint_name = kcu.constraint_name | ||
| AND tc.table_schema = kcu.table_schema | ||
| JOIN information_schema.constraint_column_usage AS ccu | ||
| ON ccu.constraint_name = tc.constraint_name | ||
| AND ccu.table_schema = tc.table_schema | ||
| WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='%s' | ||
| WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name=$1 | ||
| ` | ||
| ) | ||
|
|
||
|
|
@@ -243,19 +243,19 @@ func (p Postgres) MultiDescribe(tables []string, db *sql.DB) (tableToDescriptorM | |
| } | ||
|
|
||
| func (p Postgres) Describe(table string, db *sql.DB) ([]types.FieldDescriptor, error) { | ||
| results, err := db.Query(fmt.Sprintf(PSQLDescribeTemplate, strings.ToLower(table))) | ||
| results, err := db.Query(PSQLDescribeTemplate, strings.ToLower(table)) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| fkResults, err := db.Query(fmt.Sprintf(psqlForeignKeysQuery, strings.ToLower(table))) | ||
| fkResults, err := db.Query(psqlForeignKeysQuery, strings.ToLower(table)) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| return parsePostgresFields(results, fkResults) | ||
| } | ||
|
|
||
| func (p Postgres) GetLatestColumnValue(table, column string, db *sql.DB) (interface{}, error) { | ||
| query := fmt.Sprintf("select %s from %s order by %s desc limit 1", column, table, column) | ||
| query := fmt.Sprintf(`select "%s" from "%s" order by "%s" desc limit 1`, column, table, column) | ||
|
||
| rows, err := db.Query(query) | ||
| if err != nil { | ||
| return nil, err | ||
|
|
||
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.
This query filters out FK rows by comparing to the string literal
'NULL'. In MySQL INFORMATION_SCHEMA, these columns are NULL (not the string "NULL"), soIS NOT NULLis the clearer and idiomatic predicate (and avoids relying on NULL comparison semantics).