|
|
@@ -587,19 +587,11 @@ func getTableMetadata(session *Session, keyspaceName string) ([]TableMetadata, e
|
|
|
return tables, nil
|
|
|
}
|
|
|
|
|
|
-// query for only the column metadata in the specified keyspace from system.schema_columns
|
|
|
-func getColumnMetadata(
|
|
|
- session *Session,
|
|
|
- keyspaceName string,
|
|
|
-) ([]ColumnMetadata, error) {
|
|
|
- // Deal with differences in protocol versions
|
|
|
- var stmt string
|
|
|
- var scan func(*Iter, *ColumnMetadata, *[]byte) bool
|
|
|
- if session.cfg.ProtoVersion == 1 {
|
|
|
- // V1 does not support the type column, and all returned rows are
|
|
|
- // of kind "regular".
|
|
|
- stmt = `
|
|
|
- SELECT
|
|
|
+func (s *Session) scanColumnMetadataV1(keyspace string) ([]ColumnMetadata, error) {
|
|
|
+ // V1 does not support the type column, and all returned rows are
|
|
|
+ // of kind "regular".
|
|
|
+ const stmt = `
|
|
|
+ SELECT
|
|
|
columnfamily_name,
|
|
|
column_name,
|
|
|
component_index,
|
|
|
@@ -608,54 +600,57 @@ func getColumnMetadata(
|
|
|
index_type,
|
|
|
index_options
|
|
|
FROM system.schema_columns
|
|
|
- WHERE keyspace_name = ?
|
|
|
- `
|
|
|
- scan = func(
|
|
|
- iter *Iter,
|
|
|
- column *ColumnMetadata,
|
|
|
- indexOptionsJSON *[]byte,
|
|
|
- ) bool {
|
|
|
- // all columns returned by V1 are regular
|
|
|
- column.Kind = ColumnRegular
|
|
|
- return iter.Scan(
|
|
|
- &column.Table,
|
|
|
- &column.Name,
|
|
|
- &column.ComponentIndex,
|
|
|
- &column.Validator,
|
|
|
- &column.Index.Name,
|
|
|
- &column.Index.Type,
|
|
|
- &indexOptionsJSON,
|
|
|
- )
|
|
|
+ WHERE keyspace_name = ?`
|
|
|
+
|
|
|
+ var columns []ColumnMetadata
|
|
|
+
|
|
|
+ rows := s.control.query(stmt, keyspace).Scanner()
|
|
|
+ for rows.Next() {
|
|
|
+ var (
|
|
|
+ column = ColumnMetadata{Keyspace: keyspace}
|
|
|
+ indexOptionsJSON []byte
|
|
|
+ )
|
|
|
+
|
|
|
+ // all columns returned by V1 are regular
|
|
|
+ column.Kind = ColumnRegular
|
|
|
+
|
|
|
+ err := rows.Scan(&column.Table,
|
|
|
+ &column.Name,
|
|
|
+ &column.ComponentIndex,
|
|
|
+ &column.Validator,
|
|
|
+ &column.Index.Name,
|
|
|
+ &column.Index.Type,
|
|
|
+ &indexOptionsJSON)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
}
|
|
|
- } else if session.useSystemSchema { // Cassandra 3.x+
|
|
|
- stmt = `
|
|
|
- SELECT
|
|
|
- table_name,
|
|
|
- column_name,
|
|
|
- clustering_order,
|
|
|
- type,
|
|
|
- kind,
|
|
|
- position
|
|
|
- FROM system_schema.columns
|
|
|
- WHERE keyspace_name = ?
|
|
|
- `
|
|
|
- scan = func(
|
|
|
- iter *Iter,
|
|
|
- column *ColumnMetadata,
|
|
|
- indexOptionsJSON *[]byte,
|
|
|
- ) bool {
|
|
|
- return iter.Scan(
|
|
|
- &column.Table,
|
|
|
- &column.Name,
|
|
|
- &column.ClusteringOrder,
|
|
|
- &column.Validator,
|
|
|
- &column.Kind,
|
|
|
- &column.ComponentIndex,
|
|
|
- )
|
|
|
+
|
|
|
+ if len(indexOptionsJSON) > 0 {
|
|
|
+ err := json.Unmarshal(indexOptionsJSON, &column.Index.Options)
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Errorf(
|
|
|
+ "Invalid JSON value '%s' as index_options for column '%s' in table '%s': %v",
|
|
|
+ indexOptionsJSON,
|
|
|
+ column.Name,
|
|
|
+ column.Table,
|
|
|
+ err)
|
|
|
+ }
|
|
|
}
|
|
|
- } else {
|
|
|
- // V2+ supports the type column
|
|
|
- stmt = `
|
|
|
+
|
|
|
+ columns = append(columns, column)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := rows.Err(); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return columns, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (s *Session) scanColumnMetadataV2(keyspace string) ([]ColumnMetadata, error) {
|
|
|
+ // V2+ supports the type column
|
|
|
+ const stmt = `
|
|
|
SELECT
|
|
|
columnfamily_name,
|
|
|
column_name,
|
|
|
@@ -666,57 +661,112 @@ func getColumnMetadata(
|
|
|
index_options,
|
|
|
type
|
|
|
FROM system.schema_columns
|
|
|
- WHERE keyspace_name = ?
|
|
|
- `
|
|
|
- scan = func(
|
|
|
- iter *Iter,
|
|
|
- column *ColumnMetadata,
|
|
|
- indexOptionsJSON *[]byte,
|
|
|
- ) bool {
|
|
|
- return iter.Scan(
|
|
|
- &column.Table,
|
|
|
- &column.Name,
|
|
|
- &column.ComponentIndex,
|
|
|
- &column.Validator,
|
|
|
- &column.Index.Name,
|
|
|
- &column.Index.Type,
|
|
|
- &indexOptionsJSON,
|
|
|
- &column.Kind,
|
|
|
- )
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // get the columns metadata
|
|
|
- columns := []ColumnMetadata{}
|
|
|
- column := ColumnMetadata{Keyspace: keyspaceName}
|
|
|
+ WHERE keyspace_name = ?`
|
|
|
+
|
|
|
+ var columns []ColumnMetadata
|
|
|
+
|
|
|
+ rows := s.control.query(stmt, keyspace).Scanner()
|
|
|
+ for rows.Next() {
|
|
|
+ var (
|
|
|
+ column = ColumnMetadata{Keyspace: keyspace}
|
|
|
+ indexOptionsJSON []byte
|
|
|
+ )
|
|
|
+
|
|
|
+ err := rows.Scan(&column.Table,
|
|
|
+ &column.Name,
|
|
|
+ &column.ComponentIndex,
|
|
|
+ &column.Validator,
|
|
|
+ &column.Index.Name,
|
|
|
+ &column.Index.Type,
|
|
|
+ &indexOptionsJSON,
|
|
|
+ &column.Kind,
|
|
|
+ )
|
|
|
|
|
|
- var indexOptionsJSON []byte
|
|
|
-
|
|
|
- iter := session.control.query(stmt, keyspaceName)
|
|
|
-
|
|
|
- for scan(iter, &column, &indexOptionsJSON) {
|
|
|
- var err error
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
|
|
|
- // decode the index options
|
|
|
- if indexOptionsJSON != nil {
|
|
|
- err = json.Unmarshal(indexOptionsJSON, &column.Index.Options)
|
|
|
+ if len(indexOptionsJSON) > 0 {
|
|
|
+ err := json.Unmarshal(indexOptionsJSON, &column.Index.Options)
|
|
|
if err != nil {
|
|
|
- iter.Close()
|
|
|
return nil, fmt.Errorf(
|
|
|
"Invalid JSON value '%s' as index_options for column '%s' in table '%s': %v",
|
|
|
indexOptionsJSON,
|
|
|
column.Name,
|
|
|
column.Table,
|
|
|
- err,
|
|
|
- )
|
|
|
+ err)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
columns = append(columns, column)
|
|
|
- column = ColumnMetadata{Keyspace: keyspaceName}
|
|
|
}
|
|
|
|
|
|
- err := iter.Close()
|
|
|
+ if err := rows.Err(); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return columns, nil
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func (s *Session) scanColumnMetadataSystem(keyspace string) ([]ColumnMetadata, error) {
|
|
|
+ const stmt = `
|
|
|
+ SELECT
|
|
|
+ table_name,
|
|
|
+ column_name,
|
|
|
+ clustering_order,
|
|
|
+ type,
|
|
|
+ kind,
|
|
|
+ position
|
|
|
+ FROM system_schema.columns
|
|
|
+ WHERE keyspace_name = ?`
|
|
|
+
|
|
|
+ var columns []ColumnMetadata
|
|
|
+
|
|
|
+ rows := s.control.query(stmt, keyspace).Scanner()
|
|
|
+ for rows.Next() {
|
|
|
+ column := ColumnMetadata{Keyspace: keyspace}
|
|
|
+
|
|
|
+ err := rows.Scan(&column.Table,
|
|
|
+ &column.Name,
|
|
|
+ &column.ClusteringOrder,
|
|
|
+ &column.Validator,
|
|
|
+ &column.Kind,
|
|
|
+ &column.ComponentIndex,
|
|
|
+ )
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ columns = append(columns, column)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := rows.Err(); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO(zariel): get column index info from system_schema.indexes
|
|
|
+
|
|
|
+ return columns, nil
|
|
|
+}
|
|
|
+
|
|
|
+// query for only the column metadata in the specified keyspace from system.schema_columns
|
|
|
+func getColumnMetadata(session *Session, keyspaceName string) ([]ColumnMetadata, error) {
|
|
|
+ var (
|
|
|
+ columns []ColumnMetadata
|
|
|
+ err error
|
|
|
+ )
|
|
|
+
|
|
|
+ // Deal with differences in protocol versions
|
|
|
+ if session.cfg.ProtoVersion == 1 {
|
|
|
+ columns, err = session.scanColumnMetadataV1(keyspaceName)
|
|
|
+ } else if session.useSystemSchema { // Cassandra 3.x+
|
|
|
+ columns, err = session.scanColumnMetadataSystem(keyspaceName)
|
|
|
+ } else {
|
|
|
+ columns, err = session.scanColumnMetadataV2(keyspaceName)
|
|
|
+ }
|
|
|
+
|
|
|
if err != nil && err != ErrNotFound {
|
|
|
return nil, fmt.Errorf("Error querying column schema: %v", err)
|
|
|
}
|