Skip to content

Commit ffd051e

Browse files
committed
sql: add schema descriptions as table and column comments
The steampipe CLI does this, and it's very helpful when trying to figure out what a specific table or column holds.
1 parent 883869c commit ffd051e

File tree

3 files changed

+33
-15
lines changed

3 files changed

+33
-15
lines changed

schema.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ func SchemaToSql(schema map[string]*proto.TableSchema, stmt *C.ImportForeignSche
6565
return nil
6666
}
6767

68-
log.Printf("[TRACE] SQL %s", sql)
69-
commands = C.lappend(commands, unsafe.Pointer(C.CString(sql)))
68+
for _, s := range sql {
69+
log.Printf("[TRACE] SQL %s", s)
70+
commands = C.lappend(commands, unsafe.Pointer(C.CString(s)))
71+
}
7072
}
7173

7274
return commands

sql/sql.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,38 @@ import (
88
"github.com/turbot/steampipe/pkg/db/db_common"
99
)
1010

11-
func GetSQLForTable(table string, tableSchema *proto.TableSchema, localSchema string, serverName string) (string, error) {
11+
func GetSQLForTable(table string, tableSchema *proto.TableSchema, localSchema string, serverName string) ([]string, error) {
1212
// escape everything
1313
serverName = db_common.PgEscapeName(serverName)
1414
localSchema = db_common.PgEscapeName(localSchema)
1515
escapedTableName := db_common.PgEscapeName(table)
1616
// we must escape differently for the option
1717
escapedTableString := db_common.PgEscapeString(table)
1818

19+
var commentStatements []string
20+
if tableSchema.Description != "" {
21+
tableDescription := db_common.PgEscapeString(tableSchema.Description)
22+
commentStatements = append(commentStatements, fmt.Sprintf("COMMENT ON FOREIGN TABLE %s.%s IS %s", localSchema, escapedTableName, tableDescription))
23+
}
24+
1925
var columnsString []string
2026
for i, c := range tableSchema.Columns {
2127
column := db_common.PgEscapeName(c.Name)
2228
t, err := sqlTypeForColumnType(c.Type)
2329
if err != nil {
24-
return "", err
30+
return nil, err
2531
}
2632
trailing := ","
2733
if i+1 == len(tableSchema.Columns) {
2834
trailing = ""
2935
}
3036

3137
columnsString = append(columnsString, fmt.Sprintf("%s %s%s", column, t, trailing))
38+
39+
if c.Description != "" {
40+
columnDescription := db_common.PgEscapeString(c.Description)
41+
commentStatements = append(commentStatements, fmt.Sprintf("COMMENT ON COLUMN %s.%s.%s IS %s", localSchema, escapedTableName, column, columnDescription))
42+
}
3243
}
3344

3445
sql := fmt.Sprintf(`CREATE FOREIGN TABLE IF NOT EXISTS %s.%s
@@ -42,7 +53,7 @@ SERVER %s OPTIONS (table %s)`,
4253
serverName,
4354
escapedTableString)
4455

45-
return sql, nil
56+
return append([]string{sql}, commentStatements...), nil
4657
}
4758

4859
func sqlTypeForColumnType(columnType proto.ColumnType) (string, error) {

sql/sql_test.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package sql
22

33
import (
4+
"slices"
45
"testing"
56

67
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
@@ -11,7 +12,7 @@ type getSQLForTableTest struct {
1112
tableSchema *proto.TableSchema
1213
localSchema string
1314
serverName string
14-
expected string
15+
expected []string
1516
}
1617

1718
var testCasesgetSQLForTable = map[string]getSQLForTableTest{
@@ -31,12 +32,14 @@ var testCasesgetSQLForTable = map[string]getSQLForTableTest{
3132
},
3233
localSchema: "aws",
3334
serverName: "steampipe",
34-
expected: `create foreign table "aws"."t1"
35+
expected: []string{
36+
`CREATE FOREIGN TABLE IF NOT EXISTS "aws"."t1"
3537
(
36-
"c1" text,
38+
"c1" text
3739
"c2" text
3840
)
39-
server "steampipe" OPTIONS (table $steampipe_escape$t1$steampipe_escape$)`},
41+
SERVER "steampipe" OPTIONS (table $steampipe_escape$t1$steampipe_escape$)`,
42+
}},
4043
"quotes in names": {
4144
table: "t1",
4245
tableSchema: &proto.TableSchema{
@@ -53,27 +56,29 @@ server "steampipe" OPTIONS (table $steampipe_escape$t1$steampipe_escape$)`},
5356
},
5457
localSchema: "aws",
5558
serverName: "steampipe",
56-
expected: `create foreign table "aws"."t1"
59+
expected: []string{
60+
`CREATE FOREIGN TABLE IF NOT EXISTS "aws"."t1"
5761
(
58-
"""c1""" text,
62+
"""c1""" text
5963
"c2 ""is"" partially quoted" text
6064
)
61-
server "steampipe" OPTIONS (table $steampipe_escape$t1$steampipe_escape$)`},
65+
SERVER "steampipe" OPTIONS (table $steampipe_escape$t1$steampipe_escape$)`,
66+
}},
6267
}
6368

6469
func TestGetSQLForTable(t *testing.T) {
6570
for name, test := range testCasesgetSQLForTable {
6671

6772
result, err := GetSQLForTable(test.table, test.tableSchema, test.localSchema, test.serverName)
6873
if err != nil {
69-
if test.expected != "ERROR" {
74+
if test.expected != nil {
7075
t.Errorf(`Test: '%s'' FAILED : unexpected error %v`, name, err)
7176
}
7277
continue
7378
}
7479

75-
if test.expected != result {
76-
t.Errorf("Test: '%s' FAILED : expected \n%s\ngot\n%s", name, test.expected, result)
80+
if !slices.Equal(test.expected, result) {
81+
t.Errorf("Test: '%s' FAILED : expected \n%v\ngot\n%v", name, test.expected, result)
7782
}
7883
}
7984
}

0 commit comments

Comments
 (0)