func (p *planner) getTableNames(dbDesc *DatabaseDescriptor) (parser.QualifiedNames, *roachpb.Error) { prefix := MakeNameMetadataKey(dbDesc.ID, "") sr, pErr := p.txn.Scan(prefix, prefix.PrefixEnd(), 0) if pErr != nil { return nil, pErr } var qualifiedNames parser.QualifiedNames for _, row := range sr { _, tableName, err := encoding.DecodeStringAscending( bytes.TrimPrefix(row.Key, prefix), nil) if err != nil { return nil, roachpb.NewError(err) } qname := &parser.QualifiedName{ Base: parser.Name(dbDesc.Name), Indirect: parser.Indirection{parser.NameIndirection(tableName)}, } if err := qname.NormalizeTableName(""); err != nil { return nil, roachpb.NewError(err) } qualifiedNames = append(qualifiedNames, qname) } return qualifiedNames, nil }
func decodeKeyPrint(key roachpb.Key) string { var buf bytes.Buffer for k := 0; len(key) > 0; k++ { var err error switch encoding.PeekType(key) { case encoding.Null: key, _ = encoding.DecodeIfNull(key) fmt.Fprintf(&buf, "/NULL") case encoding.NotNull: key, _ = encoding.DecodeIfNotNull(key) fmt.Fprintf(&buf, "/#") case encoding.Int: var i int64 key, i, err = encoding.DecodeVarintAscending(key) if err == nil { fmt.Fprintf(&buf, "/%d", i) } case encoding.Float: var f float64 key, f, err = encoding.DecodeFloatAscending(key, nil) if err == nil { fmt.Fprintf(&buf, "/%f", f) } case encoding.Bytes: var s string key, s, err = encoding.DecodeStringAscending(key, nil) if err == nil { fmt.Fprintf(&buf, "/%q", s) } case encoding.BytesDesc: var s string key, s, err = encoding.DecodeStringDescending(key, nil) if err == nil { fmt.Fprintf(&buf, "/%q", s) } case encoding.Time: var t time.Time key, t, err = encoding.DecodeTimeAscending(key) if err == nil { fmt.Fprintf(&buf, "/%s", t.UTC().Format(time.UnixDate)) } case encoding.TimeDesc: var t time.Time key, t, err = encoding.DecodeTimeDescending(key) if err == nil { fmt.Fprintf(&buf, "/%s", t.UTC().Format(time.UnixDate)) } default: // This shouldn't ever happen, but if it does let the loop exit. fmt.Fprintf(&buf, "/%q", []byte(key)) key = nil } if err != nil { fmt.Fprintf(&buf, "/<%v>", err) continue } } return buf.String() }
// ShowDatabases returns all the databases. // Privileges: None. // Notes: postgres does not have a "show databases" // mysql has a "SHOW DATABASES" permission, but we have no system-level permissions. func (p *planner) ShowDatabases(n *parser.ShowDatabases) (planNode, *roachpb.Error) { // TODO(pmattis): This could be implemented as: // // SELECT id FROM system.namespace WHERE parentID = 0 prefix := MakeNameMetadataKey(keys.RootNamespaceID, "") sr, pErr := p.txn.Scan(prefix, prefix.PrefixEnd(), 0) if pErr != nil { return nil, pErr } v := &valuesNode{columns: []column{{name: "Database", typ: parser.DummyString}}} for _, row := range sr { _, name, err := encoding.DecodeStringAscending( bytes.TrimPrefix(row.Key, prefix), nil) if err != nil { return nil, roachpb.NewError(err) } v.rows = append(v.rows, []parser.Datum{parser.DString(name)}) } return v, nil }
func decodeTableKey(valType parser.Datum, key []byte, dir encoding.Direction) ( parser.Datum, []byte, error) { if (dir != encoding.Ascending) && (dir != encoding.Descending) { return nil, nil, util.Errorf("invalid direction: %d", dir) } var isNull bool if key, isNull = encoding.DecodeIfNull(key); isNull { return parser.DNull, key, nil } var rkey []byte var err error switch valType.(type) { case parser.DBool: var i int64 if dir == encoding.Ascending { rkey, i, err = encoding.DecodeVarintAscending(key) } else { rkey, i, err = encoding.DecodeVarintDescending(key) } return parser.DBool(i != 0), rkey, err case parser.DInt: var i int64 if dir == encoding.Ascending { rkey, i, err = encoding.DecodeVarintAscending(key) } else { rkey, i, err = encoding.DecodeVarintDescending(key) } return parser.DInt(i), rkey, err case parser.DFloat: var f float64 if dir == encoding.Ascending { rkey, f, err = encoding.DecodeFloatAscending(key, nil) } else { rkey, f, err = encoding.DecodeFloatDescending(key, nil) } return parser.DFloat(f), rkey, err case *parser.DDecimal: var d *inf.Dec if dir == encoding.Ascending { rkey, d, err = encoding.DecodeDecimalAscending(key, nil) } else { rkey, d, err = encoding.DecodeDecimalDescending(key, nil) } dd := &parser.DDecimal{} dd.Set(d) return dd, rkey, err case parser.DString: var r string if dir == encoding.Ascending { rkey, r, err = encoding.DecodeStringAscending(key, nil) } else { rkey, r, err = encoding.DecodeStringDescending(key, nil) } return parser.DString(r), rkey, err case parser.DBytes: var r []byte if dir == encoding.Ascending { rkey, r, err = encoding.DecodeBytesAscending(key, nil) } else { rkey, r, err = encoding.DecodeBytesDescending(key, nil) } return parser.DBytes(r), rkey, err case parser.DDate: var t int64 if dir == encoding.Ascending { rkey, t, err = encoding.DecodeVarintAscending(key) } else { rkey, t, err = encoding.DecodeVarintDescending(key) } return parser.DDate(t), rkey, err case parser.DTimestamp: var t time.Time if dir == encoding.Ascending { rkey, t, err = encoding.DecodeTimeAscending(key) } else { rkey, t, err = encoding.DecodeTimeDescending(key) } return parser.DTimestamp{Time: t}, rkey, err case parser.DInterval: var d int64 if dir == encoding.Ascending { rkey, d, err = encoding.DecodeVarintAscending(key) } else { rkey, d, err = encoding.DecodeVarintDescending(key) } return parser.DInterval{Duration: time.Duration(d)}, rkey, err default: return nil, nil, util.Errorf("TODO(pmattis): decoded index key: %s", valType.Type()) } }