Commit 096f9376 authored by cznic's avatar cznic

Expose new column metadata. Updates #85.

parent 85fd3bdf
......@@ -14,6 +14,11 @@
//
// Change list
//
// 2015-05-02: The Schema field of table __Table now correctly reflects any
// column constraints and/or defaults. Also, the (*DB).Info method now has that
// information provided in new ColumInfo fields NotNull, Constraint and
// Default.
//
// 2015-04-20: Added support for {LEFT,RIGHT,FULL} [OUTER] JOIN.
//
// 2015-04-18: Column definitions can now have constraints and defaults.
......@@ -1897,6 +1902,27 @@
//
// The Ordinal column defines the 1-based index of the column in the record.
//
// Columns2 Table
//
// The table __Colum2 lists all columns of all tables in the DB which have the
// constraint NOT NULL or which have a constraint expression defined or which
// have a default expression defined. The schema is
//
// CREATE TABLE __Column2 (TableName string, Name string, NotNull bool, ConstraintExpr string, DefaultExpr string)
//
// It's possible to obtain a consolidated recordset for all properties of all
// DB columns using
//
// SELECT
// __Column.TableName, __Column.Ordinal, __Column.Name, __Column.Type,
// __Column2.NotNull, __Column2.ConstraintExpr, __Column2.DefaultExpr,
// FROM __Column
// LEFT JOIN __Column2
// ON __Column.TableName == __Column2.TableName && __Column.Name == __Column2.Name
// ORDER BY __Column.TableName, __Column.Ordinal;
//
// The Name column is the column name in TableName. To
//
// Indices table
//
// The table __Index lists all indices in the DB. The schema is
......
......@@ -1266,7 +1266,17 @@ func (r tableRset) doSysTable(ctx *execCtx, onlyNames bool, f func(id interface{
rec[0] = ti.Name
a := []string{}
for _, ci := range ti.Columns {
a = append(a, fmt.Sprintf("%s %s", ci.Name, ci.Type))
s := ""
if ci.NotNull {
s += " NOT NULL"
}
if c := ci.Constraint; c != "" {
s += " " + c
}
if d := ci.Default; d != "" {
s += " DEFAULT " + d
}
a = append(a, fmt.Sprintf("%s %s%s", ci.Name, ci.Type, s))
}
rec[1] = fmt.Sprintf("CREATE TABLE %s (%s);", ti.Name, strings.Join(a, ", "))
id++
......@@ -2133,8 +2143,11 @@ func (t Type) String() string {
// ColumnInfo provides meta data describing a table column.
type ColumnInfo struct {
Name string // Column name.
Type Type // Column type (BigInt, BigRat, ...).
Name string // Column name.
Type Type // Column type (BigInt, BigRat, ...).
NotNull bool // Column cannot be NULL.
Constraint string // Constraint expression, if any.
Default string // Default expression, if any.
}
// TableInfo provides meta data describing a DB table.
......@@ -2166,11 +2179,42 @@ type DbInfo struct {
}
func (db *DB) info() (r *DbInfo, err error) {
_, hasColumn2 := db.root.tables["__Column2"]
r = &DbInfo{Name: db.Name()}
for nm, t := range db.root.tables {
ti := TableInfo{Name: nm}
m := map[string]*ColumnInfo{}
if hasColumn2 {
rs, err := selectColumn2.l[0].exec(&execCtx{db: db})
if err != nil {
return nil, err
}
ok := false
if err := rs.(recordset).do(
&execCtx{db: db, arg: []interface{}{nm}},
false,
func(id interface{}, data []interface{}) (more bool, err error) {
if ok {
ci := &ColumnInfo{NotNull: data[1].(bool), Constraint: data[2].(string), Default: data[3].(string)}
m[data[0].(string)] = ci
return true, nil
}
ok = true
return true, nil
},
); err != nil {
return nil, err
}
}
for _, c := range t.cols {
ti.Columns = append(ti.Columns, ColumnInfo{Name: c.name, Type: Type(c.typ)})
ci := ColumnInfo{Name: c.name, Type: Type(c.typ)}
if c2 := m[c.name]; c2 != nil {
ci.NotNull = c2.NotNull
ci.Constraint = c2.Constraint
ci.Default = c2.Default
}
ti.Columns = append(ti.Columns, ci)
}
r.Tables = append(r.Tables, ti)
for i, x := range t.indices {
......
......@@ -3,7 +3,7 @@
//TODO Put your favorite license here
// yacc source generated by ebnf2y[1]
// at 2015-05-01 13:37:03.502227056 +0200 CEST
// at 2015-05-02 15:30:47.324178453 +0200 CEST
//
// $ ebnf2y -o ql.y -oe ql.ebnf -start StatementList -pkg ql -p _
//
......
......@@ -10593,3 +10593,80 @@ ORDER BY t.s, employee.LastName;
[B Robinson 34 34 Clerical]
[B Smith 34 34 Clerical]
[B Williams <nil> <nil> <nil>]
-- 889 // https://github.com/cznic/ql/issues/85
BEGIN TRANSACTION;
CREATE TABLE t1 (a int, b int, c int);
CREATE TABLE t2 (a int, b int NOT NULL, c int);
CREATE TABLE t3 (a int, b int a < b && b < c, c int);
CREATE TABLE t4 (a int, b int a < b && b < c DEFAULT (a+c)/2, c int);
CREATE TABLE t5 (a int, b int NOT NULL DEFAULT (a+c)/2, c int);
CREATE TABLE t6 (a int, b int DEFAULT (a+c)/2, c int);
COMMIT;
SELECT * FROM __Table ORDER BY Name;
|sName, sSchema
[__Column2 CREATE TABLE __Column2 (TableName string, Name string, NotNull bool, ConstraintExpr string, DefaultExpr string);]
[t1 CREATE TABLE t1 (a int64, b int64, c int64);]
[t2 CREATE TABLE t2 (a int64, b int64 NOT NULL, c int64);]
[t3 CREATE TABLE t3 (a int64, b int64 a<b&&b<c, c int64);]
[t4 CREATE TABLE t4 (a int64, b int64 a<b&&b<c DEFAULT (a+c)/2, c int64);]
[t5 CREATE TABLE t5 (a int64, b int64 NOT NULL DEFAULT (a+c)/2, c int64);]
[t6 CREATE TABLE t6 (a int64, b int64 DEFAULT (a+c)/2, c int64);]
-- 890 // https://github.com/cznic/ql/issues/85
BEGIN TRANSACTION;
CREATE TABLE t1 (a int, b int, c int);
CREATE TABLE t2 (a int, b int NOT NULL, c int);
CREATE TABLE t3 (a int, b int a < b && b < c, c int);
CREATE TABLE t4 (a int, b int a < b && b < c DEFAULT (a+c)/2, c int);
CREATE TABLE t5 (a int, b int NOT NULL DEFAULT (a+c)/2, c int);
CREATE TABLE t6 (a int, b int DEFAULT (a+c)/2, c int);
COMMIT;
SELECT * FROM __Column2 ORDER BY TableName, Name;
|sTableName, sName, bNotNull, sConstraintExpr, sDefaultExpr
[t2 b true ]
[t3 b false a<b&&b<c ]
[t4 b false a<b&&b<c (a+c)/2]
[t5 b true (a+c)/2]
[t6 b false (a+c)/2]
-- 891 // https://github.com/cznic/ql/issues/85
BEGIN TRANSACTION;
CREATE TABLE t1 (a int, b int, c int);
CREATE TABLE t2 (a int, b int NOT NULL, c int);
CREATE TABLE t3 (a int, b int a < b && b < c, c int);
CREATE TABLE t4 (a int, b int a < b && b < c DEFAULT (a+c)/2, c int);
CREATE TABLE t5 (a int, b int NOT NULL DEFAULT (a+c)/2, c int);
CREATE TABLE t6 (a int, b int DEFAULT (a+c)/2, c int);
COMMIT;
SELECT
__Column.TableName, __Column.Ordinal, __Column.Name, __Column.Type,
__Column2.NotNull, __Column2.ConstraintExpr, __Column2.DefaultExpr,
FROM __Column
LEFT JOIN __Column2
ON __Column.TableName == __Column2.TableName && __Column.Name == __Column2.Name
ORDER BY __Column.TableName, __Column.Ordinal;
|s__Column.TableName, l__Column.Ordinal, s__Column.Name, s__Column.Type, ?__Column2.NotNull, ?__Column2.ConstraintExpr, ?__Column2.DefaultExpr
[__Column2 1 TableName string <nil> <nil> <nil>]
[__Column2 2 Name string <nil> <nil> <nil>]
[__Column2 3 NotNull bool <nil> <nil> <nil>]
[__Column2 4 ConstraintExpr string <nil> <nil> <nil>]
[__Column2 5 DefaultExpr string <nil> <nil> <nil>]
[t1 1 a int64 <nil> <nil> <nil>]
[t1 2 b int64 <nil> <nil> <nil>]
[t1 3 c int64 <nil> <nil> <nil>]
[t2 1 a int64 <nil> <nil> <nil>]
[t2 2 b int64 true ]
[t2 3 c int64 <nil> <nil> <nil>]
[t3 1 a int64 <nil> <nil> <nil>]
[t3 2 b int64 false a<b&&b<c ]
[t3 3 c int64 <nil> <nil> <nil>]
[t4 1 a int64 <nil> <nil> <nil>]
[t4 2 b int64 false a<b&&b<c (a+c)/2]
[t4 3 c int64 <nil> <nil> <nil>]
[t5 1 a int64 <nil> <nil> <nil>]
[t5 2 b int64 true (a+c)/2]
[t5 3 c int64 <nil> <nil> <nil>]
[t6 1 a int64 <nil> <nil> <nil>]
[t6 2 b int64 false (a+c)/2]
[t6 3 c int64 <nil> <nil> <nil>]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment