cayleygraph/cayley · error
not a SQL quadstore: %T
Error message
not a SQL quadstore: %T
What it means
Select (a SQL-specific query shape) can only be executed against a *sql.QuadStore. BuildIterator type-asserts the provided graph.QuadStore; if a different implementation is passed, it returns an iterator that resolves to this error instead of panicking.
Source
Thrown at graph/sql/shape.go:309
return s.Limit > 0 || s.Offset > 0
}
func (s Select) Columns() []string {
names := make([]string, 0, len(s.Fields))
for _, f := range s.Fields {
name := f.Alias
if name == "" {
name = f.Name
}
names = append(names, name)
}
return names
}
func (s Select) BuildIterator(qs graph.QuadStore) iterator.Shape {
sq, ok := qs.(*QuadStore)
if !ok {
return iterator.NewError(fmt.Errorf("not a SQL quadstore: %T", qs))
}
return sq.newIterator(s)
}
func (s Select) Optimize(ctx context.Context, r shape.Optimizer) (shape.Shape, bool) {
// TODO: call optimize on sub-tables? but what if it decides to de-optimize our SQL shape?
return s, false
}
func (s *Select) AppendParam(o Value) Expr {
s.Params = append(s.Params, o)
return Placeholder{}
}
func (s *Select) WhereEq(tbl, field string, v Value) {
s.Where = append(s.Where, Where{
Table: tbl,
Field: field,View on GitHub (pinned to 81dcd7d73e)
Solutions
- Ensure the QuadStore passed to the query was opened via graph/sql.New or Init
- Check which backend your configuration actually selects; align query-building code with it
- Only use sql.Select shapes when the store is the SQL implementation
- For other backends, use their native query path (e.g. general iterator shapes)
Example fix
// before
qs, _ := graph.NewQuadStore("memory", "")
it := sql.Select{...}.BuildIterator(qs) // error
// after
qs, _ := graph.NewQuadStore("sql", addr)
it := sql.Select{...}.BuildIterator(qs) Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := qs.(*sql.QuadStore); !ok {
return errors.New("sql.Select requires a sql quadstore")
} Type guard
func isSQLQuadStore(qs graph.QuadStore) bool {
_, ok := qs.(*sql.QuadStore)
return ok
} Try / catch
it := sql.Select{...}.BuildIterator(qs)
// iterator resolves to error; check on next()
if it.Next(ctx) {
// ok
} else if err := it.Err(); err != nil && strings.Contains(err.Error(), "not a SQL quadstore") {
// rebuild query with the correct backend
} Prevention
- Pair sql.Select shapes only with stores opened via sql.New
- Verify the backend selected by config matches query-building code
- Add an assertion after opening the store
When it happens
Trigger: Passing a memory, badger, or other non-SQL QuadStore to a query pipeline built with sql.Select, e.g. memstore QS + SQL shape optimizer output.
Common situations: Mixing backends: building queries with the SQL package while the application opened a memory store; optimizer pipelines that hand shapes to the wrong QuadStore instance.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- unexpected token: %T
- unknown type of graph.Ref; not meant for this quadstore. app
- cannot scan %T to NodeHash
- unsupported time format: %T: %v
- token not valid
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/0cde275098db7ab9.
Report an issue: GitHub.