本文整理汇总了Golang中github.com/cockroachdb/cockroach/structured.TableDescriptor类的典型用法代码示例。如果您正苦于以下问题:Golang TableDescriptor类的具体用法?Golang TableDescriptor怎么用?Golang TableDescriptor使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了TableDescriptor类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: makeIndexKeyVals
func makeIndexKeyVals(desc *structured.TableDescriptor,
index structured.IndexDescriptor) ([]parser.Datum, error) {
vals := make([]parser.Datum, len(index.ColumnIDs))
for i, id := range index.ColumnIDs {
col, err := desc.FindColumnByID(id)
if err != nil {
return nil, err
}
switch col.Type.Kind {
case structured.ColumnType_BIT, structured.ColumnType_INT:
vals[i] = parser.DInt(0)
case structured.ColumnType_FLOAT:
vals[i] = parser.DFloat(0)
case structured.ColumnType_CHAR, structured.ColumnType_TEXT,
structured.ColumnType_BLOB:
vals[i] = parser.DString("")
default:
return nil, util.Errorf("TODO(pmattis): decoded index key: %s", col.Type.Kind)
}
}
if !index.Unique {
// Non-unique columns are suffixed by the primary index key.
pkVals, err := makeIndexKeyVals(desc, desc.PrimaryIndex)
if err != nil {
return nil, err
}
vals = append(vals, pkVals...)
}
return vals, nil
}
示例2: getTableDesc
func (db *DB) getTableDesc(path string) (*structured.TableDescriptor, error) {
nsID, name, err := db.lookupTable(path)
if err != nil {
return nil, err
}
if name == "" {
return nil, fmt.Errorf("empty table name: %s", path)
}
gr, err := db.Get(keys.MakeNameMetadataKey(nsID, name))
if err != nil {
return nil, err
}
if !gr.Exists() {
return nil, fmt.Errorf("unable to find table \"%s\"", path)
}
descKey := gr.ValueBytes()
desc := structured.TableDescriptor{}
if err := db.GetProto(descKey, &desc); err != nil {
return nil, err
}
if err := desc.Validate(); err != nil {
return nil, err
}
return &desc, nil
}
示例3: getTableDesc
func (s *Server) getTableDesc(database string, qname parser.QualifiedName) (
*structured.TableDescriptor, error) {
var err error
qname, err = s.normalizeTableName(database, qname)
if err != nil {
return nil, err
}
dbID, err := s.lookupDatabase(qname.Database())
if err != nil {
return nil, err
}
gr, err := s.db.Get(keys.MakeNameMetadataKey(dbID, qname.Table()))
if err != nil {
return nil, err
}
if !gr.Exists() {
return nil, fmt.Errorf("table \"%s\" does not exist", qname)
}
descKey := gr.ValueBytes()
desc := structured.TableDescriptor{}
if err := s.db.GetProto(descKey, &desc); err != nil {
return nil, err
}
if err := desc.Validate(); err != nil {
return nil, err
}
return &desc, nil
}
示例4: processColumns
func (s *Server) processColumns(desc *structured.TableDescriptor,
node parser.Columns) ([]structured.ColumnDescriptor, error) {
if node == nil {
return desc.Columns, nil
}
cols := make([]structured.ColumnDescriptor, len(node))
for i, n := range node {
switch nt := n.(type) {
case *parser.StarExpr:
return s.processColumns(desc, nil)
case *parser.NonStarExpr:
switch et := nt.Expr.(type) {
case *parser.ColName:
// TODO(pmattis): If et.Qualifier is not empty, verify it matches the
// table name.
var err error
col, err := desc.FindColumnByName(et.Name)
if err != nil {
return nil, err
}
cols[i] = *col
default:
return nil, fmt.Errorf("unexpected node: %T", nt.Expr)
}
}
}
return cols, nil
}
示例5: getTableDesc
func (c *conn) getTableDesc(table *parser.TableName) (*structured.TableDescriptor, error) {
if err := c.normalizeTableName(table); err != nil {
return nil, err
}
dbID, err := c.lookupDatabase(table.Qualifier)
if err != nil {
return nil, err
}
gr, err := c.db.Get(keys.MakeNameMetadataKey(dbID, table.Name))
if err != nil {
return nil, err
}
if !gr.Exists() {
return nil, fmt.Errorf("table \"%s\" does not exist", table)
}
descKey := gr.ValueBytes()
desc := structured.TableDescriptor{}
if err := c.db.GetProto(descKey, &desc); err != nil {
return nil, err
}
if err := desc.Validate(); err != nil {
return nil, err
}
return &desc, nil
}
示例6: DropTable
// DropTable drops a table.
// Privileges: WRITE on table.
// Notes: postgres allows only the table owner to DROP a table.
// mysql requires the DROP privilege on the table.
func (p *planner) DropTable(n *parser.DropTable) (planNode, error) {
// TODO(XisiHuang): should do truncate and delete descriptor in
// the same txn
for i, tableQualifiedName := range n.Names {
if err := tableQualifiedName.NormalizeTableName(p.session.Database); err != nil {
return nil, err
}
dbDesc, err := p.getDatabaseDesc(tableQualifiedName.Database())
if err != nil {
return nil, err
}
tbKey := tableKey{dbDesc.ID, tableQualifiedName.Table()}
nameKey := tbKey.Key()
gr, err := p.txn.Get(nameKey)
if err != nil {
return nil, err
}
if !gr.Exists() {
if n.IfExists {
// Noop.
continue
}
// Key does not exist, but we want it to: error out.
return nil, fmt.Errorf("table %q does not exist", tbKey.Name())
}
tableDesc := structured.TableDescriptor{}
if err := p.txn.GetProto(gr.ValueBytes(), &tableDesc); err != nil {
return nil, err
}
if err := tableDesc.Validate(); err != nil {
return nil, err
}
if !tableDesc.HasPrivilege(p.user, parser.PrivilegeWrite) {
return nil, fmt.Errorf("user %s does not have %s privilege on table %s",
p.user, parser.PrivilegeWrite, tableDesc.Name)
}
if _, err = p.Truncate(&parser.Truncate{Tables: n.Names[i : i+1]}); err != nil {
return nil, err
}
// Delete table descriptor
descKey := gr.ValueBytes()
b := &client.Batch{}
b.Del(descKey)
b.Del(nameKey)
err = p.txn.Run(b)
if err != nil {
return nil, err
}
}
return &valuesNode{}, nil
}
示例7: RenameTable
// RenameTable renames a table. Old path and new path have the form
// "<namespace>.<table>".
func (db *DB) RenameTable(oldPath, newPath string) error {
// TODO(pmattis): Should we allow both the old and new name to exist
// simultaneously for a period of time? The thought is to allow an
// application to access the table via either name while the application is
// being upgraded. Alternatively, instead of a rename table operation perhaps
// there should be a link table operation which adds a "hard link" to the
// table. Similar to a file, a table would not be removed until all of the
// hard links are removed.
oldNSID, oldName, err := db.lookupTable(oldPath)
if err != nil {
return err
}
newNSID, newName, err := db.lookupTable(newPath)
if err != nil {
return err
}
if newName == "" {
return fmt.Errorf("empty table name: %s", newPath)
}
return db.Txn(func(txn *Txn) error {
oldNameKey := keys.MakeNameMetadataKey(oldNSID, oldName)
gr, err := txn.Get(oldNameKey)
if err != nil {
return err
}
if !gr.Exists() {
return fmt.Errorf("unable to find table \"%s\"", oldPath)
}
descKey := gr.ValueBytes()
desc := structured.TableDescriptor{}
if err := txn.GetProto(descKey, &desc); err != nil {
return err
}
desc.Name = strings.ToLower(newPath)
if err := structured.ValidateTableDesc(desc); err != nil {
return err
}
newNameKey := keys.MakeNameMetadataKey(newNSID, newName)
b := &Batch{}
b.Put(descKey, &desc)
// If the new name already exists the conditional put will fail causing the
// transaction to fail.
b.CPut(newNameKey, descKey, nil)
b.Del(oldNameKey)
return txn.Commit(b)
})
}
示例8: decodeIndexKey
func decodeIndexKey(desc *structured.TableDescriptor,
index structured.IndexDescriptor, vals map[string]parser.Datum, key []byte) ([]byte, error) {
if !bytes.HasPrefix(key, keys.TableDataPrefix) {
return nil, fmt.Errorf("%s: invalid key prefix: %q", desc.Name, key)
}
key = bytes.TrimPrefix(key, keys.TableDataPrefix)
var tableID uint64
key, tableID = encoding.DecodeUvarint(key)
if uint32(tableID) != desc.ID {
return nil, fmt.Errorf("%s: unexpected table ID: %d != %d", desc.Name, desc.ID, tableID)
}
var indexID uint64
key, indexID = encoding.DecodeUvarint(key)
if uint32(indexID) != index.ID {
return nil, fmt.Errorf("%s: unexpected index ID: %d != %d", desc.Name, index.ID, indexID)
}
for _, id := range index.ColumnIDs {
col, err := desc.FindColumnByID(id)
if err != nil {
return nil, err
}
switch col.Type.Kind {
case structured.ColumnType_BIT, structured.ColumnType_INT:
var i int64
key, i = encoding.DecodeVarint(key)
vals[col.Name] = parser.DInt(i)
case structured.ColumnType_FLOAT:
var f float64
key, f = encoding.DecodeNumericFloat(key)
vals[col.Name] = parser.DFloat(f)
case structured.ColumnType_CHAR, structured.ColumnType_TEXT,
structured.ColumnType_BLOB:
var r []byte
key, r = encoding.DecodeBytes(key, nil)
vals[col.Name] = parser.DString(r)
default:
return nil, util.Errorf("TODO(pmattis): decoded index key: %s", col.Type.Kind)
}
}
return key, nil
}
示例9: processColumns
func (p *planner) processColumns(desc *structured.TableDescriptor,
node parser.QualifiedNames) ([]structured.ColumnDescriptor, error) {
if node == nil {
return desc.Columns, nil
}
cols := make([]structured.ColumnDescriptor, len(node))
for i, n := range node {
// TODO(pmattis): If the name is qualified, verify the table name matches
// desc.Name.
var err error
col, err := desc.FindColumnByName(n.Column())
if err != nil {
return nil, err
}
cols[i] = *col
}
return cols, nil
}
示例10: CreateTable
// CreateTable creates a table from the specified schema. Table creation will
// fail if the table name is already in use. The table name is required to have
// the form "<namespace>.<table>".
func (db *DB) CreateTable(desc *structured.TableDescriptor) error {
desc.Name = strings.ToLower(desc.Name)
if err := desc.AllocateIDs(); err != nil {
return err
}
nsID, name, err := db.lookupTable(desc.Name)
if err != nil {
return err
}
if name == "" {
return fmt.Errorf("empty table name: %s", desc.Name)
}
nameKey := keys.MakeNameMetadataKey(nsID, name)
// This isn't strictly necessary as the conditional put below will fail if
// the key already exists, but it seems good to avoid the table ID allocation
// in most cases when the table already exists.
if gr, err := db.Get(nameKey); err != nil {
return err
} else if gr.Exists() {
return fmt.Errorf("table \"%s\" already exists", desc.Name)
}
ir, err := db.Inc(keys.DescIDGenerator, 1)
if err != nil {
return err
}
desc.ID = uint32(ir.ValueInt() - 1)
// TODO(pmattis): Be cognizant of error messages when this is ported to the
// server. The error currently returned below is likely going to be difficult
// to interpret.
return db.Txn(func(txn *Txn) error {
descKey := keys.MakeDescMetadataKey(desc.ID)
b := &Batch{}
b.CPut(nameKey, descKey, nil)
b.Put(descKey, desc)
return txn.Commit(b)
})
}
示例11: makeTableDesc
func makeTableDesc(p *parser.CreateTable) (structured.TableDescriptor, error) {
desc := structured.TableDescriptor{}
desc.Name = p.Table.String()
for _, def := range p.Defs {
switch d := def.(type) {
case *parser.ColumnTableDef:
col := structured.ColumnDescriptor{
Name: d.Name,
Nullable: (d.Nullable != parser.NotNull),
}
switch t := d.Type.(type) {
case *parser.BitType:
col.Type.Kind = structured.ColumnType_BIT
col.Type.Width = int32(t.N)
case *parser.IntType:
col.Type.Kind = structured.ColumnType_INT
col.Type.Width = int32(t.N)
case *parser.FloatType:
col.Type.Kind = structured.ColumnType_FLOAT
col.Type.Precision = int32(t.Prec)
case *parser.DecimalType:
col.Type.Kind = structured.ColumnType_DECIMAL
col.Type.Width = int32(t.Scale)
col.Type.Precision = int32(t.Prec)
case *parser.DateType:
col.Type.Kind = structured.ColumnType_DATE
case *parser.TimeType:
col.Type.Kind = structured.ColumnType_TIME
case *parser.TimestampType:
col.Type.Kind = structured.ColumnType_TIMESTAMP
case *parser.CharType:
col.Type.Kind = structured.ColumnType_CHAR
col.Type.Width = int32(t.N)
case *parser.TextType:
col.Type.Kind = structured.ColumnType_TEXT
case *parser.BlobType:
col.Type.Kind = structured.ColumnType_BLOB
}
desc.Columns = append(desc.Columns, col)
// Create any associated index.
if d.PrimaryKey || d.Unique {
index := structured.IndexDescriptor{
Unique: true,
ColumnNames: []string{d.Name},
}
if d.PrimaryKey {
index.Name = "primary"
}
desc.Indexes = append(desc.Indexes, index)
}
case *parser.IndexTableDef:
index := structured.IndexDescriptor{
Name: d.Name,
Unique: d.Unique,
ColumnNames: d.Columns,
}
desc.Indexes = append(desc.Indexes, index)
default:
return desc, fmt.Errorf("unsupported table def: %T", def)
}
}
return desc, nil
}
示例12: makeTableDesc
func makeTableDesc(p *parser.CreateTable) (structured.TableDescriptor, error) {
desc := structured.TableDescriptor{}
desc.Name = p.Table.Table()
for _, def := range p.Defs {
switch d := def.(type) {
case *parser.ColumnTableDef:
col := structured.ColumnDescriptor{
Name: string(d.Name),
Nullable: (d.Nullable != parser.NotNull),
}
switch t := d.Type.(type) {
case *parser.BitType:
col.Type.Kind = structured.ColumnType_BIT
col.Type.Width = int32(t.N)
case *parser.BoolType:
col.Type.Kind = structured.ColumnType_BOOL
case *parser.IntType:
col.Type.Kind = structured.ColumnType_INT
col.Type.Width = int32(t.N)
case *parser.FloatType:
col.Type.Kind = structured.ColumnType_FLOAT
col.Type.Precision = int32(t.Prec)
case *parser.DecimalType:
col.Type.Kind = structured.ColumnType_DECIMAL
col.Type.Width = int32(t.Scale)
col.Type.Precision = int32(t.Prec)
case *parser.DateType:
col.Type.Kind = structured.ColumnType_DATE
case *parser.TimeType:
col.Type.Kind = structured.ColumnType_TIME
case *parser.TimestampType:
col.Type.Kind = structured.ColumnType_TIMESTAMP
case *parser.CharType:
col.Type.Kind = structured.ColumnType_CHAR
col.Type.Width = int32(t.N)
case *parser.TextType:
col.Type.Kind = structured.ColumnType_TEXT
case *parser.BlobType:
col.Type.Kind = structured.ColumnType_BLOB
default:
panic(fmt.Sprintf("unexpected type %T", t))
}
desc.Columns = append(desc.Columns, col)
// Create any associated index.
if d.PrimaryKey || d.Unique {
index := structured.IndexDescriptor{
Unique: true,
ColumnNames: []string{string(d.Name)},
}
if d.PrimaryKey {
index.Name = structured.PrimaryKeyIndexName
desc.PrimaryIndex = index
} else {
desc.Indexes = append(desc.Indexes, index)
}
}
case *parser.IndexTableDef:
index := structured.IndexDescriptor{
Name: string(d.Name),
Unique: d.Unique,
ColumnNames: d.Columns,
}
if d.PrimaryKey {
// Only override the index name if it hasn't been set by the user.
if index.Name == "" {
index.Name = structured.PrimaryKeyIndexName
}
desc.PrimaryIndex = index
} else {
desc.Indexes = append(desc.Indexes, index)
}
default:
return desc, fmt.Errorf("unsupported table def: %T", def)
}
}
return desc, nil
}
示例13: Select
// Select selects rows from a single table.
func (s *Server) Select(session *Session, p *parser.Select, args []sqlwire.Datum, resp *sqlwire.Response) error {
if len(p.Exprs) != 1 {
return fmt.Errorf("TODO(pmattis): unsupported select exprs: %s", p.Exprs)
}
if _, ok := p.Exprs[0].(*parser.StarExpr); !ok {
return fmt.Errorf("TODO(pmattis): unsupported select expr: %s", p.Exprs)
}
if len(p.From) != 1 {
return fmt.Errorf("TODO(pmattis): unsupported from: %s", p.From)
}
var desc *structured.TableDescriptor
{
ate, ok := p.From[0].(*parser.AliasedTableExpr)
if !ok {
return fmt.Errorf("TODO(pmattis): unsupported from: %s", p.From)
}
table, ok := ate.Expr.(parser.QualifiedName)
if !ok {
return fmt.Errorf("TODO(pmattis): unsupported from: %s", p.From)
}
var err error
desc, err = s.getTableDesc(session.Database, table)
if err != nil {
return err
}
}
// Retrieve all of the keys that start with our index key prefix.
startKey := proto.Key(encodeIndexKeyPrefix(desc.ID, desc.Indexes[0].ID))
endKey := startKey.PrefixEnd()
sr, err := s.db.Scan(startKey, endKey, 0)
if err != nil {
return err
}
// All of the columns for a particular row will be grouped together. We loop
// over the returned key/value pairs and decode the key to extract the
// columns encoded within the key and the column ID. We use the column ID to
// lookup the column and decode the value. All of these values go into a map
// keyed by column name. When the index key changes we output a row
// containing the current values.
//
// The TODOs here are too numerous to list. This is only performing a full
// table scan using the primary key.
var rows []sqlwire.Result_Row
var primaryKey []byte
vals := valMap{}
for _, kv := range sr {
if primaryKey != nil && !bytes.HasPrefix(kv.Key, primaryKey) {
if output, err := shouldOutputRow(p.Where, vals); err != nil {
return err
} else if output {
rows = append(rows, outputRow(desc.Columns, vals))
}
vals = valMap{}
}
remaining, err := decodeIndexKey(desc, desc.Indexes[0], vals, kv.Key)
if err != nil {
return err
}
primaryKey = []byte(kv.Key[:len(kv.Key)-len(remaining)])
_, colID := encoding.DecodeUvarint(remaining)
if err != nil {
return err
}
col, err := desc.FindColumnByID(uint32(colID))
if err != nil {
return err
}
vals[col.Name] = unmarshalValue(*col, kv)
if log.V(2) {
log.Infof("Scan %q -> %v", kv.Key, vals[col.Name])
}
}
if output, err := shouldOutputRow(p.Where, vals); err != nil {
return err
} else if output {
rows = append(rows, outputRow(desc.Columns, vals))
}
resp.Results = []sqlwire.Result{
{
Columns: make([]string, len(desc.Columns)),
Rows: rows,
},
}
for i, col := range desc.Columns {
resp.Results[0].Columns[i] = col.Name
}
return nil
}
示例14: SchemaFromModel
// SchemaFromModel allows the easy construction of a TableDescriptor from a Go
// struct. Columns are created for each exported field in the struct. The "db"
// struct tag is used to control the mapping of field name to column name and
// to indicate exported fields which should be skipped.
//
// type User struct {
// ID int
// Name string `db:"old_name"`
// Ignored int `db:"-"`
// }
//
// Indexes are specified using the "roach" struct tag declaration.
//
// type User struct {
// ID int `roach:"primary key"`
// Name string `db:"old_name" roach:"index"`
// }
//
// The following "roach" options are supported:
//
// "primary key [(columns...)]" - creates a unique index on <columns> and
// marks it as the primary key for the table. If <columns> is not specified
// it defaults to the name of the column the option is associated with.
//
// "index" [(columns...)]" - creates an index on <columns>.
//
// "unique index" [(columns...)]" - creates a unique index on <columns>.
func SchemaFromModel(obj interface{}) (structured.TableDescriptor, error) {
desc := structured.TableDescriptor{}
m, err := getDBFields(deref(reflect.TypeOf(obj)))
if err != nil {
return desc, err
}
desc.Name = strings.ToLower(reflect.TypeOf(obj).Name())
// Create the columns for the table.
for name, sf := range m {
colType := structured.ColumnType{}
// TODO(pmattis): The mapping from Go-type Kind to column-type Kind is
// likely not complete or correct, but this is probably going away pretty
// soon with the move to SQL.
switch sf.Type.Kind() {
case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
reflect.Uint64, reflect.Uintptr:
colType.Kind = structured.ColumnType_INT
case reflect.Float32, reflect.Float64:
colType.Kind = structured.ColumnType_FLOAT
case reflect.String:
colType.Kind = structured.ColumnType_TEXT
}
col := structured.ColumnDescriptor{
Name: name,
Type: colType,
}
desc.Columns = append(desc.Columns, col)
}
// Create the indexes for the table.
for name, f := range m {
tag := f.Tag.Get("roach")
if tag == "" {
continue
}
for _, opt := range strings.Split(tag, ";") {
match := schemaOptRE.FindStringSubmatch(opt)
if match == nil {
return desc, fmt.Errorf("invalid schema option: %s", opt)
}
cmd := match[1]
var params []string
if len(match[2]) > 0 {
params = strings.Split(match[2], ",")
} else {
params = []string{name}
}
var index structured.IndexDescriptor
switch strings.ToLower(cmd) {
case "primary key":
index.Name = structured.PrimaryKeyIndexName
index.Unique = true
case "unique index":
index.Name = strings.Join(params, ":")
index.Unique = true
case "index":
index.Name = strings.Join(params, ":")
}
index.ColumnNames = params
desc.Indexes = append(desc.Indexes, index)
}
}
// Normalize the column and index order.
sort.Sort(columnsByName(desc.Columns))
sort.Sort(indexesByName(desc.Indexes))
//.........这里部分代码省略.........
示例15: Select
// Select selects rows from a single table.
// Privileges: READ on table
// Notes: postgres requires SELECT. Also requires UPDATE on "FOR UPDATE".
// mysql requires SELECT.
func (p *planner) Select(n *parser.Select) (planNode, error) {
var desc *structured.TableDescriptor
var index *structured.IndexDescriptor
var visibleCols []structured.ColumnDescriptor
switch len(n.From) {
case 0:
// desc remains nil.
case 1:
var err error
desc, err = p.getAliasedTableDesc(n.From[0])
if err != nil {
return nil, err
}
if !desc.HasPrivilege(p.user, parser.PrivilegeRead) {
return nil, fmt.Errorf("user %s does not have %s privilege on table %s",
p.user, parser.PrivilegeRead, desc.Name)
}
// This is only kosher because we know that getAliasedDesc() succeeded.
qname := n.From[0].(*parser.AliasedTableExpr).Expr.(*parser.QualifiedName)
indexName := qname.Index()
if indexName != "" && !strings.EqualFold(desc.PrimaryIndex.Name, indexName) {
for i := range desc.Indexes {
if strings.EqualFold(desc.Indexes[i].Name, indexName) {
// Remove all but the matching index from the descriptor.
desc.Indexes = desc.Indexes[i : i+1]
index = &desc.Indexes[0]
break
}
}
if index == nil {
return nil, fmt.Errorf("index \"%s\" not found", indexName)
}
// If the table was not aliased, use the index name instead of the table
// name for fully-qualified columns in the expression.
if n.From[0].(*parser.AliasedTableExpr).As == "" {
desc.Alias = index.Name
}
// Strip out any columns from the table that are not present in the
// index.
indexColIDs := map[structured.ColumnID]struct{}{}
for _, colID := range index.ColumnIDs {
indexColIDs[colID] = struct{}{}
}
for _, col := range desc.Columns {
if _, ok := indexColIDs[col.ID]; !ok {
continue
}
visibleCols = append(visibleCols, col)
}
} else {
index = &desc.PrimaryIndex
visibleCols = desc.Columns
}
default:
return nil, util.Errorf("TODO(pmattis): unsupported FROM: %s", n.From)
}
// Loop over the select expressions and expand them into the expressions
// we're going to use to generate the returned column set and the names for
// those columns.
exprs := make([]parser.Expr, 0, len(n.Exprs))
columns := make([]string, 0, len(n.Exprs))
for _, e := range n.Exprs {
// If a QualifiedName has a StarIndirection suffix we need to match the
// prefix of the qualified name to one of the tables in the query and
// then expand the "*" into a list of columns.
if qname, ok := e.Expr.(*parser.QualifiedName); ok {
if err := qname.NormalizeColumnName(); err != nil {
return nil, err
}
if qname.IsStar() {
if desc == nil {
return nil, fmt.Errorf("\"%s\" with no tables specified is not valid", qname)
}
if e.As != "" {
return nil, fmt.Errorf("\"%s\" cannot be aliased", qname)
}
tableName := qname.Table()
if tableName != "" && !strings.EqualFold(desc.Alias, tableName) {
return nil, fmt.Errorf("table \"%s\" not found", tableName)
}
if index != &desc.PrimaryIndex {
for _, col := range index.ColumnNames {
columns = append(columns, col)
exprs = append(exprs, &parser.QualifiedName{Base: parser.Name(col)})
}
} else {
for _, col := range desc.Columns {
columns = append(columns, col.Name)
exprs = append(exprs, &parser.QualifiedName{Base: parser.Name(col.Name)})
//.........这里部分代码省略.........