Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

*: add information_schema db with files and column_statistics tables #430

Merged
merged 1 commit into from
Oct 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ var queries = []struct {
},
{
`SHOW DATABASES`,
[]sql.Row{{"mydb"}, {"foo"}},
[]sql.Row{{"mydb"}, {"foo"}, {"information_schema"}},
},
{
`SELECT s FROM mytable WHERE s LIKE '%d row'`,
Expand Down Expand Up @@ -465,6 +465,47 @@ var queries = []struct {
`SELECT CONNECTION_ID()`,
[]sql.Row{{uint32(1)}},
},
{
`
SELECT DISTINCT
tablespace_name, file_name, logfile_group_name, extent_size, initial_size, engine
FROM
information_schema.files
WHERE
file_type = 'DATAFILE'
ORDER BY tablespace_name, logfile_group_name
`,
[]sql.Row{},
},
{
`
SELECT
logfile_group_name, file_name, total_extents, initial_size, engine, extra
FROM
information_schema.files
WHERE
file_type = 'UNDO LOG' AND
file_name IS NOT NULL AND
logfile_group_name IS NOT NULL
GROUP BY
logfile_group_name, file_name, engine, total_extents, initial_size
ORDER BY
logfile_group_name
`,
[]sql.Row{},
},
{
`
SELECT
column_name
FROM
information_schema.column_statistics
WHERE
schema_name = 'foo' AND
table_name = 'bar';
`,
[]sql.Row{},
},
}

func TestQueries(t *testing.T) {
Expand Down Expand Up @@ -937,6 +978,7 @@ func newEngineWithParallelism(t *testing.T, parallelism int) *sqle.Engine {
catalog := sql.NewCatalog()
catalog.AddDatabase(db)
catalog.AddDatabase(db2)
catalog.AddDatabase(sqle.NewInformationSchemaDB())

var a *analyzer.Analyzer
if parallelism > 1 {
Expand Down
150 changes: 150 additions & 0 deletions information_schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package sqle // import "gopkg.in/src-d/go-mysql-server.v0"

import (
"fmt"
"io"

"gopkg.in/src-d/go-mysql-server.v0/sql"
)

const (
InformationSchemaDBName = "information_schema"
FilesTableName = "files"
ColumnStatisticsTableName = "column_statistics"
)

type informationSchemaDB struct {
name string
tables map[string]sql.Table
}

var _ sql.Database = (*informationSchemaDB)(nil)

// NewInformationSchemaDB creates a new INFORMATION_SCHEMA Database.
func NewInformationSchemaDB() sql.Database {
return &informationSchemaDB{
name: InformationSchemaDBName,
tables: map[string]sql.Table{
FilesTableName: newFilesTable(),
ColumnStatisticsTableName: newColumnStatisticsTable(),
},
}
}

// Name implements the sql.Database interface.
func (i *informationSchemaDB) Name() string { return i.name }

// Tables implements the sql.Database interface.
func (i *informationSchemaDB) Tables() map[string]sql.Table { return i.tables }

func newFilesTable() sql.Table {
return &emptyTable{
name: FilesTableName,
schema: filesSchema,
}
}

var filesSchema = sql.Schema{
&sql.Column{Name: "file_id", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "file_name", Type: sql.Text, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "file_type", Type: sql.Text, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "tablespace_name", Type: sql.Text, Source: FilesTableName},
&sql.Column{Name: "table_catalog", Type: sql.Text, Source: FilesTableName},
&sql.Column{Name: "table_schema", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "table_name", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "logfile_group_name", Type: sql.Text, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "logfile_group_number", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "engine", Type: sql.Text, Source: FilesTableName},
&sql.Column{Name: "fulltext_keys", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "deleted_rows", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "update_count", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "free_extents", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "total_extents", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "extent_size", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "initial_size", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "maximum_size", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "autoextend_size", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "creation_time", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "last_update_time", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "last_access_time", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "recover_time", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "transaction_counter", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "version", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "row_format", Type: sql.Text, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "table_rows", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "avg_row_length", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "data_length", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "max_data_length", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "index_length", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "data_free", Type: sql.Int64, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "create_time", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "update_time", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "check_time", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "checksum", Type: sql.Blob, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "status", Type: sql.Text, Source: FilesTableName, Nullable: true},
&sql.Column{Name: "extra", Type: sql.Blob, Source: FilesTableName, Nullable: true},
}

func newColumnStatisticsTable() sql.Table {
return &emptyTable{
name: ColumnStatisticsTableName,
schema: columnStatisticsSchema,
}
}

var columnStatisticsSchema = sql.Schema{
&sql.Column{Name: "schema_name", Type: sql.Text, Source: ColumnStatisticsTableName},
&sql.Column{Name: "table_name", Type: sql.Text, Source: ColumnStatisticsTableName},
&sql.Column{Name: "column_name", Type: sql.Text, Source: ColumnStatisticsTableName},
&sql.Column{Name: "histogram", Type: sql.JSON, Source: ColumnStatisticsTableName},
}

type emptyTable struct {
name string
schema sql.Schema
}

var _ sql.Table = (*emptyTable)(nil)

// Name implements the sql.Table interface.
func (t *emptyTable) Name() string { return t.name }

// String implements the sql.Table interface.
func (t *emptyTable) String() string { return printTable(t.name, t.schema) }

// Schema implements the sql.Table interface.
func (t *emptyTable) Schema() sql.Schema { return t.schema }

// Partitions implements the sql.Table interface.
func (t *emptyTable) Partitions(_ *sql.Context) (sql.PartitionIter, error) {
return new(partitionIter), nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This iterator should return no partitions

}

// PartitionRows implements the sql.Table interface.
func (t *emptyTable) PartitionRows(_ *sql.Context, _ sql.Partition) (sql.RowIter, error) {
return sql.RowsToRowIter(), nil
}

func printTable(name string, tableSchema sql.Schema) string {
p := sql.NewTreePrinter()
_ = p.WriteNode("Table(%s)", name)
var schema = make([]string, len(tableSchema))
for i, col := range tableSchema {
schema[i] = fmt.Sprintf(
"Column(%s, %s, nullable=%v)",
col.Name,
col.Type.Type().String(),
col.Nullable,
)
}
_ = p.WriteChildren(schema...)
return p.String()
}

type partitionIter struct{}

var _ sql.PartitionIter = (*partitionIter)(nil)

func (p *partitionIter) Next() (sql.Partition, error) { return nil, io.EOF }

func (p *partitionIter) Close() error { return nil }