Get rid of *most* of the context.Background() references in sql3 package (#2238)

* Thread context through sql3 DATABASE operations

* Get rid of *most* of the context.Background() references
This commit is contained in:
Travis Turner 2023-02-10 13:40:46 -06:00 committed by GitHub
parent 126be915a9
commit bc450a91ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 152 additions and 143 deletions

View file

@ -13,12 +13,12 @@ import (
// compileAlterDatabaseStatement compiles an ALTER DATABASE statement into a
// PlanOperator.
func (p *ExecutionPlanner) compileAlterDatabaseStatement(stmt *parser.AlterDatabaseStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileAlterDatabaseStatement(ctx context.Context, stmt *parser.AlterDatabaseStatement) (_ types.PlanOperator, err error) {
databaseName := parser.IdentName(stmt.Name)
// does the database exist
dbname := dax.DatabaseName(databaseName)
db, err := p.schemaAPI.DatabaseByName(context.Background(), dbname)
db, err := p.schemaAPI.DatabaseByName(ctx, dbname)
if err != nil {
if isDatabaseNotFoundError(err) {
return nil, sql3.NewErrDatabaseNotFound(stmt.Name.NamePos.Line, stmt.Name.NamePos.Column, databaseName)

View file

@ -23,12 +23,12 @@ const (
// compileAlterTableStatement compiles an ALTER TABLE statement into a
// PlanOperator.
func (p *ExecutionPlanner) compileAlterTableStatement(stmt *parser.AlterTableStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileAlterTableStatement(ctx context.Context, stmt *parser.AlterTableStatement) (_ types.PlanOperator, err error) {
tableName := parser.IdentName(stmt.Name)
// does the table exist
tname := dax.TableName(tableName)
tbl, err := p.schemaAPI.TableByName(context.Background(), tname)
tbl, err := p.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return nil, sql3.NewErrTableNotFound(stmt.Name.NamePos.Line, stmt.Name.NamePos.Column, tableName)
@ -63,7 +63,7 @@ func (p *ExecutionPlanner) compileAlterTableStatement(stmt *parser.AlterTableSta
}
}
column, err := p.compileColumn(col)
column, err := p.compileColumn(ctx, col)
if err != nil {
return nil, err
}

View file

@ -19,11 +19,11 @@ import (
// compileBulkInsertStatement compiles a BULK INSERT statement into a
// PlanOperator.
func (p *ExecutionPlanner) compileBulkInsertStatement(stmt *parser.BulkInsertStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileBulkInsertStatement(ctx context.Context, stmt *parser.BulkInsertStatement) (_ types.PlanOperator, err error) {
tableName := parser.IdentName(stmt.Table)
tname := dax.TableName(tableName)
tbl, err := p.schemaAPI.TableByName(context.Background(), tname)
tbl, err := p.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return nil, sql3.NewErrTableNotFound(stmt.Table.NamePos.Line, stmt.Table.NamePos.Column, tableName)
@ -31,7 +31,7 @@ func (p *ExecutionPlanner) compileBulkInsertStatement(stmt *parser.BulkInsertSta
return nil, err
}
err = p.checkAccess(context.Background(), tableName, accessTypeWriteData)
err = p.checkAccess(ctx, tableName, accessTypeWriteData)
if err != nil {
return nil, err
}
@ -157,11 +157,11 @@ func (p *ExecutionPlanner) compileBulkInsertStatement(stmt *parser.BulkInsertSta
// analyzeBulkInsertStatement analyzes a BULK INSERT statement and returns an
// error if anything is invalid.
func (p *ExecutionPlanner) analyzeBulkInsertStatement(stmt *parser.BulkInsertStatement) error {
func (p *ExecutionPlanner) analyzeBulkInsertStatement(ctx context.Context, stmt *parser.BulkInsertStatement) error {
// check referred to table exists
tableName := parser.IdentName(stmt.Table)
tname := dax.TableName(tableName)
tbl, err := p.schemaAPI.TableByName(context.Background(), tname)
tbl, err := p.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return sql3.NewErrTableNotFound(stmt.Table.NamePos.Line, stmt.Table.NamePos.Column, tableName)
@ -293,7 +293,7 @@ func (p *ExecutionPlanner) analyzeBulkInsertStatement(stmt *parser.BulkInsertSta
if !parser.IsValidTypeName(typeName) {
return sql3.NewErrUnknownType(m.Type.Name.NamePos.Line, m.Type.Name.NamePos.Column, typeName)
}
ex, err := p.analyzeExpression(m.MapExpr, stmt)
ex, err := p.analyzeExpression(ctx, m.MapExpr, stmt)
if err != nil {
return err
}
@ -330,7 +330,7 @@ func (p *ExecutionPlanner) analyzeBulkInsertStatement(stmt *parser.BulkInsertSta
}
for i, t := range stmt.TransformList {
ex, err := p.analyzeExpression(t, stmt)
ex, err := p.analyzeExpression(ctx, t, stmt)
if err != nil {
return err
}

View file

@ -3,6 +3,7 @@
package planner
import (
"context"
"strconv"
"strings"
"time"
@ -24,7 +25,7 @@ type createTableField struct {
// compileCreateTableStatement compiles a CREATE TABLE statement into a
// PlanOperator.
func (p *ExecutionPlanner) compileCreateTableStatement(stmt *parser.CreateTableStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileCreateTableStatement(ctx context.Context, stmt *parser.CreateTableStatement) (_ types.PlanOperator, err error) {
tableName := parser.IdentName(stmt.Name)
failIfExists := !stmt.IfNotExists.IsValid()
@ -60,7 +61,7 @@ func (p *ExecutionPlanner) compileCreateTableStatement(stmt *parser.CreateTableS
continue
}
column, err := p.compileColumn(col)
column, err := p.compileColumn(ctx, col)
if err != nil {
return nil, err
}
@ -75,7 +76,7 @@ func (p *ExecutionPlanner) compileCreateTableStatement(stmt *parser.CreateTableS
}
// compiles a column def
func (p *ExecutionPlanner) compileColumn(col *parser.ColumnDefinition) (*createTableField, error) {
func (p *ExecutionPlanner) compileColumn(ctx context.Context, col *parser.ColumnDefinition) (*createTableField, error) {
var err error
columnName := parser.IdentName(col.Name)
typeName := parser.IdentName(col.Type.Name)
@ -124,7 +125,7 @@ func (p *ExecutionPlanner) compileColumn(col *parser.ColumnDefinition) (*createT
// method. There is a case where a BITNOT expression could get
// through, but that value as a string will fail in
// strconv.ParseInt() conversion.
if _, err := p.analyzeUnaryExpression(e, nil); err != nil {
if _, err := p.analyzeUnaryExpression(ctx, e, nil); err != nil {
return nil, err
}
@ -151,7 +152,7 @@ func (p *ExecutionPlanner) compileColumn(col *parser.ColumnDefinition) (*createT
// method. There is a case where a BITNOT expression could get
// through, but that value as a string will fail in
// strconv.ParseInt() conversion.
if _, err := p.analyzeUnaryExpression(e, nil); err != nil {
if _, err := p.analyzeUnaryExpression(ctx, e, nil); err != nil {
return nil, err
}

View file

@ -3,6 +3,8 @@
package planner
import (
"context"
"github.com/featurebasedb/featurebase/v3/sql3/parser"
"github.com/featurebasedb/featurebase/v3/sql3/planner/types"
)
@ -43,9 +45,9 @@ func (p *ExecutionPlanner) compileAlterViewStatement(stmt *parser.AlterViewState
return query, nil
}
func (p *ExecutionPlanner) analyzeCreateViewStatement(stmt *parser.CreateViewStatement) error {
func (p *ExecutionPlanner) analyzeCreateViewStatement(ctx context.Context, stmt *parser.CreateViewStatement) error {
//analyze the select
_, err := p.analyzeSelectStatement(stmt.Select)
_, err := p.analyzeSelectStatement(ctx, stmt.Select)
if err != nil {
return err
}
@ -53,9 +55,9 @@ func (p *ExecutionPlanner) analyzeCreateViewStatement(stmt *parser.CreateViewSta
return nil
}
func (p *ExecutionPlanner) analyzeAlterViewStatement(stmt *parser.AlterViewStatement) error {
func (p *ExecutionPlanner) analyzeAlterViewStatement(ctx context.Context, stmt *parser.AlterViewStatement) error {
//analyze the select
_, err := p.analyzeSelectStatement(stmt.Select)
_, err := p.analyzeSelectStatement(ctx, stmt.Select)
if err != nil {
return err
}

View file

@ -3,6 +3,8 @@
package planner
import (
"context"
"github.com/featurebasedb/featurebase/v3/sql3/parser"
"github.com/featurebasedb/featurebase/v3/sql3/planner/types"
)
@ -52,16 +54,16 @@ func (p *ExecutionPlanner) compileDeleteStatement(stmt *parser.DeleteStatement)
return query.WithChildren(children...)
}
func (p *ExecutionPlanner) analyzeDeleteStatement(stmt *parser.DeleteStatement) error {
func (p *ExecutionPlanner) analyzeDeleteStatement(ctx context.Context, stmt *parser.DeleteStatement) error {
_, err := p.analyzeSource(stmt.Source, stmt)
_, err := p.analyzeSource(ctx, stmt.Source, stmt)
if err != nil {
return err
}
// if we have a where clause, check that
if stmt.WhereExpr != nil {
expr, err := p.analyzeExpression(stmt.WhereExpr, stmt)
expr, err := p.analyzeExpression(ctx, stmt.WhereExpr, stmt)
if err != nil {
return err
}

View file

@ -13,10 +13,10 @@ import (
// compileDropDatabaseStatement compiles a DROP DATABASE statement into a
// PlanOperator.
func (p *ExecutionPlanner) compileDropDatabaseStatement(stmt *parser.DropDatabaseStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileDropDatabaseStatement(ctx context.Context, stmt *parser.DropDatabaseStatement) (_ types.PlanOperator, err error) {
databaseName := parser.IdentName(stmt.Name)
dbname := dax.DatabaseName(databaseName)
db, err := p.schemaAPI.DatabaseByName(context.Background(), dbname)
db, err := p.schemaAPI.DatabaseByName(ctx, dbname)
if err != nil {
if isDatabaseNotFoundError(err) {
return nil, sql3.NewErrDatabaseNotFound(stmt.Name.NamePos.Line, stmt.Name.NamePos.Column, databaseName)

View file

@ -14,10 +14,10 @@ import (
// compileDropTableStatement compiles a DROP TABLE statement into a
// PlanOperator.
func (p *ExecutionPlanner) compileDropTableStatement(stmt *parser.DropTableStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileDropTableStatement(ctx context.Context, stmt *parser.DropTableStatement) (_ types.PlanOperator, err error) {
tableName := parser.IdentName(stmt.Name)
tname := dax.TableName(tableName)
tbl, err := p.schemaAPI.TableByName(context.Background(), tname)
tbl, err := p.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return nil, sql3.NewErrTableNotFound(stmt.Name.NamePos.Line, stmt.Name.NamePos.Column, tableName)

View file

@ -3,15 +3,17 @@
package planner
import (
"context"
"github.com/featurebasedb/featurebase/v3/sql3"
"github.com/featurebasedb/featurebase/v3/sql3/parser"
"github.com/featurebasedb/featurebase/v3/sql3/planner/types"
)
// compileDropViewStatement compiles a DROP VIEW statement into a PlanOperator.
func (p *ExecutionPlanner) compileDropViewStatement(stmt *parser.DropViewStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileDropViewStatement(ctx context.Context, stmt *parser.DropViewStatement) (_ types.PlanOperator, err error) {
viewName := parser.IdentName(stmt.Name)
v, err := p.getViewByName(viewName)
v, err := p.getViewByName(ctx, viewName)
if err != nil {
return nil, err
}

View file

@ -14,14 +14,14 @@ import (
)
// compileInsertStatement compiles an INSERT statement into a PlanOperator.
func (p *ExecutionPlanner) compileInsertStatement(stmt *parser.InsertStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileInsertStatement(ctx context.Context, stmt *parser.InsertStatement) (_ types.PlanOperator, err error) {
tableName := parser.IdentName(stmt.Table)
targetColumns := []*qualifiedRefPlanExpression{}
insertValues := [][]types.PlanExpression{}
tname := dax.TableName(tableName)
tbl, err := p.schemaAPI.TableByName(context.Background(), tname)
tbl, err := p.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return nil, sql3.NewErrTableNotFound(stmt.Table.NamePos.Line, stmt.Table.NamePos.Column, tableName)
@ -72,11 +72,11 @@ func (p *ExecutionPlanner) compileInsertStatement(stmt *parser.InsertStatement)
// analyzeInsertStatement analyzes an INSERT statement and returns and error if
// anything is invalid.
func (p *ExecutionPlanner) analyzeInsertStatement(stmt *parser.InsertStatement) error {
func (p *ExecutionPlanner) analyzeInsertStatement(ctx context.Context, stmt *parser.InsertStatement) error {
// Check that referred table exists.
tableName := parser.IdentName(stmt.Table)
tname := dax.TableName(tableName)
tbl, err := p.schemaAPI.TableByName(context.Background(), tname)
tbl, err := p.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return sql3.NewErrTableNotFound(stmt.Table.NamePos.Line, stmt.Table.NamePos.Column, tableName)
@ -171,7 +171,7 @@ func (p *ExecutionPlanner) analyzeInsertStatement(stmt *parser.InsertStatement)
// Check each of the expressions.
for _, tuple := range stmt.TupleList {
for i, expr := range tuple.Exprs {
e, err := p.analyzeExpression(expr, stmt)
e, err := p.analyzeExpression(ctx, expr, stmt)
if err != nil {
return err
}

View file

@ -378,24 +378,24 @@ func (p *ExecutionPlanner) compileSource(scope *PlanOpQuery, source parser.Sourc
}
}
func (p *ExecutionPlanner) analyzeSource(source parser.Source, scope parser.Statement) (parser.Source, error) {
func (p *ExecutionPlanner) analyzeSource(ctx context.Context, source parser.Source, scope parser.Statement) (parser.Source, error) {
if source == nil {
return nil, nil
}
switch source := source.(type) {
case *parser.JoinClause:
x, err := p.analyzeSource(source.X, scope)
x, err := p.analyzeSource(ctx, source.X, scope)
if err != nil {
return nil, err
}
y, err := p.analyzeSource(source.Y, scope)
y, err := p.analyzeSource(ctx, source.Y, scope)
if err != nil {
return nil, err
}
if source.Constraint != nil {
switch join := source.Constraint.(type) {
case *parser.OnConstraint:
ex, err := p.analyzeExpression(join.X, scope)
ex, err := p.analyzeExpression(ctx, join.X, scope)
if err != nil {
return nil, err
}
@ -409,7 +409,7 @@ func (p *ExecutionPlanner) analyzeSource(source parser.Source, scope parser.Stat
return source, nil
case *parser.ParenSource:
x, err := p.analyzeSource(source.X, scope)
x, err := p.analyzeSource(ctx, source.X, scope)
if err != nil {
return nil, err
}
@ -421,7 +421,7 @@ func (p *ExecutionPlanner) analyzeSource(source parser.Source, scope parser.Stat
objectName := parser.IdentName(source.Name)
// check views first
view, err := p.getViewByName(objectName)
view, err := p.getViewByName(ctx, objectName)
if err != nil {
return nil, err
}
@ -438,7 +438,7 @@ func (p *ExecutionPlanner) analyzeSource(source parser.Source, scope parser.Stat
return nil, sql3.NewErrInternalf("unexpected ast type")
}
// analyze the select statement
expr, err := p.analyzeSelectStatement(sel)
expr, err := p.analyzeSelectStatement(ctx, sel)
if err != nil {
return nil, err
}
@ -457,7 +457,7 @@ func (p *ExecutionPlanner) analyzeSource(source parser.Source, scope parser.Stat
// check table exists
tname := dax.TableName(objectName)
tbl, err := p.schemaAPI.TableByName(context.Background(), tname)
tbl, err := p.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return nil, sql3.NewErrTableOrViewNotFound(source.Name.NamePos.Line, source.Name.NamePos.Column, objectName)
@ -482,7 +482,7 @@ func (p *ExecutionPlanner) analyzeSource(source parser.Source, scope parser.Stat
// check it actually is a table valued function - we only support one right now; subtable()
switch strings.ToUpper(source.Name.Name) {
case "SUBTABLE":
_, err := p.analyzeCallExpression(source.Call, scope)
_, err := p.analyzeCallExpression(ctx, source.Call, scope)
if err != nil {
return nil, err
}
@ -510,7 +510,7 @@ func (p *ExecutionPlanner) analyzeSource(source parser.Source, scope parser.Stat
return source, nil
case *parser.SelectStatement:
expr, err := p.analyzeSelectStatement(source)
expr, err := p.analyzeSelectStatement(ctx, source)
if err != nil {
return nil, err
}
@ -525,9 +525,9 @@ func (p *ExecutionPlanner) analyzeSource(source parser.Source, scope parser.Stat
}
}
func (p *ExecutionPlanner) analyzeSelectStatement(stmt *parser.SelectStatement) (parser.Expr, error) {
func (p *ExecutionPlanner) analyzeSelectStatement(ctx context.Context, stmt *parser.SelectStatement) (parser.Expr, error) {
// analyze source first - needed for name resolution
source, err := p.analyzeSource(stmt.Source, stmt)
source, err := p.analyzeSource(ctx, stmt.Source, stmt)
if err != nil {
return nil, err
}
@ -538,7 +538,7 @@ func (p *ExecutionPlanner) analyzeSelectStatement(stmt *parser.SelectStatement)
}
for _, col := range stmt.Columns {
expr, err := p.analyzeExpression(col.Expr, stmt)
expr, err := p.analyzeExpression(ctx, col.Expr, stmt)
if err != nil {
return nil, err
}
@ -547,7 +547,7 @@ func (p *ExecutionPlanner) analyzeSelectStatement(stmt *parser.SelectStatement)
}
}
expr, err := p.analyzeExpression(stmt.TopExpr, stmt)
expr, err := p.analyzeExpression(ctx, stmt.TopExpr, stmt)
if err != nil {
return nil, err
}
@ -558,20 +558,20 @@ func (p *ExecutionPlanner) analyzeSelectStatement(stmt *parser.SelectStatement)
stmt.TopExpr = expr
}
expr, err = p.analyzeExpression(stmt.HavingExpr, stmt)
expr, err = p.analyzeExpression(ctx, stmt.HavingExpr, stmt)
if err != nil {
return nil, err
}
stmt.HavingExpr = expr
expr, err = p.analyzeExpression(stmt.WhereExpr, stmt)
expr, err = p.analyzeExpression(ctx, stmt.WhereExpr, stmt)
if err != nil {
return nil, err
}
stmt.WhereExpr = expr
for i, g := range stmt.GroupByExprs {
expr, err = p.analyzeExpression(g, stmt)
expr, err = p.analyzeExpression(ctx, g, stmt)
if err != nil {
return nil, err
}
@ -580,7 +580,7 @@ func (p *ExecutionPlanner) analyzeSelectStatement(stmt *parser.SelectStatement)
}
}
expr, err = p.analyzeExpression(stmt.HavingExpr, stmt)
expr, err = p.analyzeExpression(ctx, stmt.HavingExpr, stmt)
if err != nil {
return nil, err
}

View file

@ -14,8 +14,8 @@ import (
"github.com/pkg/errors"
)
func (p *ExecutionPlanner) compileShowDatabasesStatement(stmt parser.Statement) (types.PlanOperator, error) {
dbs, err := p.schemaAPI.Databases(context.Background())
func (p *ExecutionPlanner) compileShowDatabasesStatement(ctx context.Context, stmt parser.Statement) (types.PlanOperator, error) {
dbs, err := p.schemaAPI.Databases(ctx)
if err != nil {
return nil, errors.Wrap(err, "getting databases")
}
@ -73,8 +73,8 @@ func (p *ExecutionPlanner) compileShowDatabasesStatement(stmt parser.Statement)
return NewPlanOpQuery(p, NewPlanOpProjection(columns, NewPlanOpFeatureBaseDatabases(p, dbs)), p.sql), nil
}
func (p *ExecutionPlanner) compileShowTablesStatement(stmt parser.Statement) (types.PlanOperator, error) {
tbls, err := p.schemaAPI.Tables(context.Background())
func (p *ExecutionPlanner) compileShowTablesStatement(ctx context.Context, stmt parser.Statement) (types.PlanOperator, error) {
tbls, err := p.schemaAPI.Tables(ctx)
if err != nil {
return nil, errors.Wrap(err, "getting tables")
}
@ -138,10 +138,10 @@ func (p *ExecutionPlanner) compileShowTablesStatement(stmt parser.Statement) (ty
return NewPlanOpQuery(p, NewPlanOpProjection(columns, NewPlanOpFeatureBaseTables(p, pilosa.TablesToIndexInfos(tbls))), p.sql), nil
}
func (p *ExecutionPlanner) compileShowColumnsStatement(stmt *parser.ShowColumnsStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileShowColumnsStatement(ctx context.Context, stmt *parser.ShowColumnsStatement) (_ types.PlanOperator, err error) {
tableName := parser.IdentName(stmt.TableName)
tname := dax.TableName(tableName)
tbl, err := p.schemaAPI.TableByName(context.Background(), tname)
tbl, err := p.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return nil, sql3.NewErrTableNotFound(stmt.TableName.NamePos.Line, stmt.TableName.NamePos.Column, tableName)
@ -229,10 +229,10 @@ func (p *ExecutionPlanner) compileShowColumnsStatement(stmt *parser.ShowColumnsS
return NewPlanOpQuery(p, NewPlanOpProjection(columns, NewPlanOpFeatureBaseColumns(tbl)), p.sql), nil
}
func (p *ExecutionPlanner) compileShowCreateTableStatement(stmt *parser.ShowCreateTableStatement) (_ types.PlanOperator, err error) {
func (p *ExecutionPlanner) compileShowCreateTableStatement(ctx context.Context, stmt *parser.ShowCreateTableStatement) (_ types.PlanOperator, err error) {
tableName := parser.IdentName(stmt.TableName)
tname := dax.TableName(tableName)
if _, err := p.schemaAPI.TableByName(context.Background(), tname); err != nil {
if _, err := p.schemaAPI.TableByName(ctx, tname); err != nil {
if isTableNotFoundError(err) {
return nil, sql3.NewErrTableNotFound(stmt.TableName.NamePos.Line, stmt.TableName.NamePos.Column, tableName)
}

View file

@ -61,7 +61,7 @@ func NewExecutionPlanner(executor pilosa.Executor, schemaAPI pilosa.SchemaAPI, s
// to produce a query plan.
func (p *ExecutionPlanner) CompilePlan(ctx context.Context, stmt parser.Statement) (types.PlanOperator, error) {
// call analyze first
err := p.analyzePlan(stmt)
err := p.analyzePlan(ctx, stmt)
if err != nil {
return nil, err
}
@ -71,35 +71,35 @@ func (p *ExecutionPlanner) CompilePlan(ctx context.Context, stmt parser.Statemen
case *parser.SelectStatement:
rootOperator, err = p.compileSelectStatement(stmt, false)
case *parser.ShowDatabasesStatement:
rootOperator, err = p.compileShowDatabasesStatement(stmt)
rootOperator, err = p.compileShowDatabasesStatement(ctx, stmt)
case *parser.ShowTablesStatement:
rootOperator, err = p.compileShowTablesStatement(stmt)
rootOperator, err = p.compileShowTablesStatement(ctx, stmt)
case *parser.ShowColumnsStatement:
rootOperator, err = p.compileShowColumnsStatement(stmt)
rootOperator, err = p.compileShowColumnsStatement(ctx, stmt)
case *parser.ShowCreateTableStatement:
rootOperator, err = p.compileShowCreateTableStatement(stmt)
rootOperator, err = p.compileShowCreateTableStatement(ctx, stmt)
case *parser.CreateDatabaseStatement:
rootOperator, err = p.compileCreateDatabaseStatement(stmt)
case *parser.CreateTableStatement:
rootOperator, err = p.compileCreateTableStatement(stmt)
rootOperator, err = p.compileCreateTableStatement(ctx, stmt)
case *parser.CreateViewStatement:
rootOperator, err = p.compileCreateViewStatement(stmt)
case *parser.AlterDatabaseStatement:
rootOperator, err = p.compileAlterDatabaseStatement(stmt)
rootOperator, err = p.compileAlterDatabaseStatement(ctx, stmt)
case *parser.AlterTableStatement:
rootOperator, err = p.compileAlterTableStatement(stmt)
rootOperator, err = p.compileAlterTableStatement(ctx, stmt)
case *parser.AlterViewStatement:
rootOperator, err = p.compileAlterViewStatement(stmt)
case *parser.DropDatabaseStatement:
rootOperator, err = p.compileDropDatabaseStatement(stmt)
rootOperator, err = p.compileDropDatabaseStatement(ctx, stmt)
case *parser.DropTableStatement:
rootOperator, err = p.compileDropTableStatement(stmt)
rootOperator, err = p.compileDropTableStatement(ctx, stmt)
case *parser.DropViewStatement:
rootOperator, err = p.compileDropViewStatement(stmt)
rootOperator, err = p.compileDropViewStatement(ctx, stmt)
case *parser.InsertStatement:
rootOperator, err = p.compileInsertStatement(stmt)
rootOperator, err = p.compileInsertStatement(ctx, stmt)
case *parser.BulkInsertStatement:
rootOperator, err = p.compileBulkInsertStatement(stmt)
rootOperator, err = p.compileBulkInsertStatement(ctx, stmt)
case *parser.DeleteStatement:
rootOperator, err = p.compileDeleteStatement(stmt)
default:
@ -126,10 +126,10 @@ func (p *ExecutionPlanner) RehydratePlanOp(ctx context.Context, reader io.Reader
}
}
func (p *ExecutionPlanner) analyzePlan(stmt parser.Statement) error {
func (p *ExecutionPlanner) analyzePlan(ctx context.Context, stmt parser.Statement) error {
switch stmt := stmt.(type) {
case *parser.SelectStatement:
_, err := p.analyzeSelectStatement(stmt)
_, err := p.analyzeSelectStatement(ctx, stmt)
return err
case *parser.ShowDatabasesStatement:
return nil
@ -144,13 +144,13 @@ func (p *ExecutionPlanner) analyzePlan(stmt parser.Statement) error {
case *parser.CreateTableStatement:
return p.analyzeCreateTableStatement(stmt)
case *parser.CreateViewStatement:
return p.analyzeCreateViewStatement(stmt)
return p.analyzeCreateViewStatement(ctx, stmt)
case *parser.AlterDatabaseStatement:
return p.analyzeAlterDatabaseStatement(stmt)
case *parser.AlterTableStatement:
return p.analyzeAlterTableStatement(stmt)
case *parser.AlterViewStatement:
return p.analyzeAlterViewStatement(stmt)
return p.analyzeAlterViewStatement(ctx, stmt)
case *parser.DropDatabaseStatement:
return nil
case *parser.DropTableStatement:
@ -158,11 +158,11 @@ func (p *ExecutionPlanner) analyzePlan(stmt parser.Statement) error {
case *parser.DropViewStatement:
return nil
case *parser.InsertStatement:
return p.analyzeInsertStatement(stmt)
return p.analyzeInsertStatement(ctx, stmt)
case *parser.BulkInsertStatement:
return p.analyzeBulkInsertStatement(stmt)
return p.analyzeBulkInsertStatement(ctx, stmt)
case *parser.DeleteStatement:
return p.analyzeDeleteStatement(stmt)
return p.analyzeDeleteStatement(ctx, stmt)
default:
return sql3.NewErrInternalf("cannot analyze statement: %T", stmt)
}

View file

@ -1076,14 +1076,16 @@ func newSubqueryPlanExpression(op types.PlanOperator) *subqueryPlanExpression {
}
func (n *subqueryPlanExpression) Evaluate(currentRow []interface{}) (interface{}, error) {
ctx := context.Background()
//get an iterator
iter, err := n.op.Iterator(context.Background(), currentRow)
iter, err := n.op.Iterator(ctx, currentRow)
if err != nil {
return nil, err
}
//get the first row
row, err := iter.Next(context.Background())
row, err := iter.Next(ctx)
if err != nil {
if err == types.ErrNoMoreRows {
//no rows, so return null
@ -1095,7 +1097,7 @@ func (n *subqueryPlanExpression) Evaluate(currentRow []interface{}) (interface{}
result := row[0]
//make sure we don't have a next row - this is an error
_, err = iter.Next(context.Background())
_, err = iter.Next(ctx)
if err != nil && err == types.ErrNoMoreRows {
return result, nil
}

View file

@ -3,6 +3,7 @@
package planner
import (
"context"
"strconv"
"strings"
@ -11,23 +12,23 @@ import (
)
// analyze a parser.Expr. returns the analyzed parser.Expr
func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Statement) (parser.Expr, error) {
func (p *ExecutionPlanner) analyzeExpression(ctx context.Context, expr parser.Expr, scope parser.Statement) (parser.Expr, error) {
if expr == nil {
return nil, nil
}
switch e := expr.(type) {
case *parser.BinaryExpr:
return p.analyzeBinaryExpression(e, scope)
return p.analyzeBinaryExpression(ctx, e, scope)
case *parser.BoolLit:
return e, nil
case *parser.Call:
return p.analyzeCallExpression(e, scope)
return p.analyzeCallExpression(ctx, e, scope)
case *parser.CastExpr:
analyzedExpr, err := p.analyzeExpression(e.X, scope)
analyzedExpr, err := p.analyzeExpression(ctx, e.X, scope)
if err != nil {
return nil, err
}
@ -45,7 +46,7 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
case *parser.ExprList:
for i, ex := range e.Exprs {
listExpr, err := p.analyzeExpression(ex, scope)
listExpr, err := p.analyzeExpression(ctx, ex, scope)
if err != nil {
return nil, err
}
@ -80,7 +81,7 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
},
ColumnIndex: oc.ColumnIndex,
}
return p.analyzeExpression(ident, scope)
return p.analyzeExpression(ctx, ident, scope)
case *parser.InsertStatement:
return nil, sql3.NewErrColumnNotFound(e.NamePos.Line, e.NamePos.Column, e.Name)
@ -106,7 +107,7 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
},
ColumnIndex: oc.ColumnIndex,
}
return p.analyzeExpression(ident, scope)
return p.analyzeExpression(ctx, ident, scope)
default:
return nil, sql3.NewErrInternalf("unhandled scope type '%T'", sc)
@ -151,7 +152,7 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
return e, nil
case *parser.ParenExpr:
pexpr, err := p.analyzeExpression(e.X, scope)
pexpr, err := p.analyzeExpression(ctx, e.X, scope)
if err != nil {
return nil, err
}
@ -160,7 +161,7 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
case *parser.SetLiteralExpr:
for i, ex := range e.Members {
listExpr, err := p.analyzeExpression(ex, scope)
listExpr, err := p.analyzeExpression(ctx, ex, scope)
if err != nil {
return nil, err
}
@ -200,7 +201,7 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
case *parser.TupleLiteralExpr:
memberTypes := make([]parser.ExprDataType, 0)
for i, ex := range e.Members {
memberExpr, err := p.analyzeExpression(ex, scope)
memberExpr, err := p.analyzeExpression(ctx, ex, scope)
if err != nil {
return nil, err
}
@ -265,24 +266,24 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
}
case *parser.Range:
return p.analyzeRangeExpression(e, scope)
return p.analyzeRangeExpression(ctx, e, scope)
case *parser.CaseExpr:
operand, err := p.analyzeExpression(e.Operand, scope)
operand, err := p.analyzeExpression(ctx, e.Operand, scope)
if err != nil {
return nil, err
}
e.Operand = operand
for i, ex := range e.Blocks {
block, err := p.analyzeCaseBlockExpression(ex, e, scope)
block, err := p.analyzeCaseBlockExpression(ctx, ex, e, scope)
if err != nil {
return nil, err
}
e.Blocks[i] = block
}
elseExpr, err := p.analyzeExpression(e.ElseExpr, scope)
elseExpr, err := p.analyzeExpression(ctx, e.ElseExpr, scope)
if err != nil {
return nil, err
}
@ -331,10 +332,10 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
return e, nil
case *parser.UnaryExpr:
return p.analyzeUnaryExpression(e, scope)
return p.analyzeUnaryExpression(ctx, e, scope)
case *parser.SelectStatement:
selExpr, err := p.analyzeSelectStatement(e)
selExpr, err := p.analyzeSelectStatement(ctx, e)
if err != nil {
return nil, err
}
@ -349,9 +350,9 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
}
}
func (p *ExecutionPlanner) analyzeUnaryExpression(expr *parser.UnaryExpr, scope parser.Statement) (parser.Expr, error) {
func (p *ExecutionPlanner) analyzeUnaryExpression(ctx context.Context, expr *parser.UnaryExpr, scope parser.Statement) (parser.Expr, error) {
x, err := p.analyzeExpression(expr.X, scope)
x, err := p.analyzeExpression(ctx, expr.X, scope)
if err != nil {
return nil, err
}
@ -390,15 +391,15 @@ func (p *ExecutionPlanner) analyzeUnaryExpression(expr *parser.UnaryExpr, scope
}
}
func (p *ExecutionPlanner) analyzeBinaryExpression(expr *parser.BinaryExpr, scope parser.Statement) (parser.Expr, error) {
func (p *ExecutionPlanner) analyzeBinaryExpression(ctx context.Context, expr *parser.BinaryExpr, scope parser.Statement) (parser.Expr, error) {
//analyze both sides first
x, err := p.analyzeExpression(expr.X, scope)
x, err := p.analyzeExpression(ctx, expr.X, scope)
if err != nil {
return nil, err
}
expr.X = x
y, err := p.analyzeExpression(expr.Y, scope)
y, err := p.analyzeExpression(ctx, expr.Y, scope)
if err != nil {
return nil, err
}
@ -757,14 +758,14 @@ func (p *ExecutionPlanner) analyzeBinaryExpression(expr *parser.BinaryExpr, scop
}
}
func (p *ExecutionPlanner) analyzeRangeExpression(expr *parser.Range, scope parser.Statement) (parser.Expr, error) {
func (p *ExecutionPlanner) analyzeRangeExpression(ctx context.Context, expr *parser.Range, scope parser.Statement) (parser.Expr, error) {
//analyze subscripts
x, err := p.analyzeExpression(expr.X, scope)
x, err := p.analyzeExpression(ctx, expr.X, scope)
if err != nil {
return nil, err
}
expr.X = x
y, err := p.analyzeExpression(expr.Y, scope)
y, err := p.analyzeExpression(ctx, expr.Y, scope)
if err != nil {
return nil, err
}
@ -802,13 +803,13 @@ func (p *ExecutionPlanner) analyzeRangeExpression(expr *parser.Range, scope pars
return expr, nil
}
func (p *ExecutionPlanner) analyzeCaseBlockExpression(expr *parser.CaseBlock, caseScope *parser.CaseExpr, scope parser.Statement) (*parser.CaseBlock, error) {
x, err := p.analyzeExpression(expr.Body, scope)
func (p *ExecutionPlanner) analyzeCaseBlockExpression(ctx context.Context, expr *parser.CaseBlock, caseScope *parser.CaseExpr, scope parser.Statement) (*parser.CaseBlock, error) {
x, err := p.analyzeExpression(ctx, expr.Body, scope)
if err != nil {
return nil, err
}
expr.Body = x
y, err := p.analyzeExpression(expr.Condition, scope)
y, err := p.analyzeExpression(ctx, expr.Condition, scope)
if err != nil {
return nil, err
}

View file

@ -3,6 +3,7 @@
package planner
import (
"context"
"strings"
"github.com/featurebasedb/featurebase/v3/sql3"
@ -10,10 +11,10 @@ import (
)
// analyze a *parser.Call and return the parser.Expr
func (p *ExecutionPlanner) analyzeCallExpression(call *parser.Call, scope parser.Statement) (parser.Expr, error) {
func (p *ExecutionPlanner) analyzeCallExpression(ctx context.Context, call *parser.Call, scope parser.Statement) (parser.Expr, error) {
//analyze all the args
for i, a := range call.Args {
arg, err := p.analyzeExpression(a, scope)
arg, err := p.analyzeExpression(ctx, a, scope)
if err != nil {
return nil, err
}
@ -27,7 +28,7 @@ func (p *ExecutionPlanner) analyzeCallExpression(call *parser.Call, scope parser
NamePos: call.Star,
Name: "_id",
}
arg, err := p.analyzeExpression(newArg, scope)
arg, err := p.analyzeExpression(ctx, newArg, scope)
if err != nil {
return nil, err
}

View file

@ -5,7 +5,6 @@ package planner
import (
"context"
"fmt"
"log"
"github.com/featurebasedb/featurebase/v3/dax"
"github.com/featurebasedb/featurebase/v3/sql3"
@ -98,7 +97,6 @@ func (i *alterDatabaseRowIter) Next(ctx context.Context) (types.Row, error) {
return nil, sql3.NewErrInvalidDatabaseOption(0, 0, i.option.String())
}
log.Printf("DEEBUG: SetDatabaseOption: %s = %s", optName, optValue)
if err := i.planner.schemaAPI.SetDatabaseOption(ctx, i.database.ID, optName, optValue); err != nil {
return nil, err
}

View file

@ -80,7 +80,7 @@ func newAlterViewIter(planner *ExecutionPlanner, view *viewSystemObject) *alterV
func (i *alterViewIter) Next(ctx context.Context) (types.Row, error) {
// now check in the views table to see if it exists
v, err := i.planner.getViewByName(i.view.name)
v, err := i.planner.getViewByName(ctx, i.view.name)
if err != nil {
return nil, err
}
@ -89,7 +89,7 @@ func (i *alterViewIter) Next(ctx context.Context) (types.Row, error) {
}
// now store the view into fb_views
err = i.planner.updateView(i.view)
err = i.planner.updateView(ctx, i.view)
if err != nil {
return nil, err
}

View file

@ -86,7 +86,7 @@ func newCreateViewIter(planner *ExecutionPlanner, ifNotExists bool, view *viewSy
func (i *createViewIter) Next(ctx context.Context) (types.Row, error) {
// make sure we have no existing table named the same as our view
viewName := dax.TableName(i.view.name)
tbl, err := i.planner.schemaAPI.TableByName(context.Background(), viewName)
tbl, err := i.planner.schemaAPI.TableByName(ctx, viewName)
if err != nil {
if !isTableNotFoundError(err) {
return nil, err
@ -100,7 +100,7 @@ func (i *createViewIter) Next(ctx context.Context) (types.Row, error) {
}
// now check in the views table to see if it is exists
v, err := i.planner.getViewByName(i.view.name)
v, err := i.planner.getViewByName(ctx, i.view.name)
if err != nil {
return nil, err
}
@ -112,7 +112,7 @@ func (i *createViewIter) Next(ctx context.Context) (types.Row, error) {
}
// now store the view into fb_views
err = i.planner.insertView(i.view)
err = i.planner.insertView(ctx, i.view)
if err != nil {
return nil, err
}

View file

@ -82,7 +82,7 @@ func (i *dropViewRowIter) Next(ctx context.Context) (types.Row, error) {
}
// check in the views table to see if it exists
v, err := i.planner.getViewByName(i.viewName)
v, err := i.planner.getViewByName(ctx, i.viewName)
if err != nil {
return nil, err
}
@ -93,7 +93,7 @@ func (i *dropViewRowIter) Next(ctx context.Context) (types.Row, error) {
return nil, sql3.NewErrViewNotFound(0, 0, i.viewName)
}
err = i.planner.deleteView(i.viewName)
err = i.planner.deleteView(ctx, i.viewName)
if err != nil {
return nil, err
}

View file

@ -116,8 +116,8 @@ func (i *showDatabasesRowIter) Next(ctx context.Context) (types.Row, error) {
dbID := i.dbs[i.rowIndex].ID
dbName := i.dbs[i.rowIndex].Name
createdAt := time.Unix(0, i.dbs[i.rowIndex].CreatedAt)
updatedAt := time.Unix(0, i.dbs[i.rowIndex].UpdatedAt)
createdAt := time.Unix(i.dbs[i.rowIndex].CreatedAt, 0)
updatedAt := time.Unix(i.dbs[i.rowIndex].UpdatedAt, 0)
row := []interface{}{
dbID,
dbName,

View file

@ -139,7 +139,7 @@ func (i *distinctScanRowIter) Next(ctx context.Context) (types.Row, error) {
//go get the schema def and map names to indexes in the resultant row
tname := dax.TableName(i.tableName)
table, err := i.planner.schemaAPI.TableByName(context.Background(), tname)
table, err := i.planner.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return nil, sql3.NewErrInternalf("table not found '%s'", i.tableName)

View file

@ -143,7 +143,7 @@ func (i *tableScanRowIter) Next(ctx context.Context) (types.Row, error) {
//go get the schema def and map names to indexes in the resultant row
tname := dax.TableName(i.tableName)
table, err := i.planner.schemaAPI.TableByName(context.Background(), tname)
table, err := i.planner.schemaAPI.TableByName(ctx, tname)
if err != nil {
if isTableNotFoundError(err) {
return nil, sql3.NewErrInternalf("table not found '%s'", i.tableName)

View file

@ -18,8 +18,8 @@ type viewSystemObject struct {
statement string
}
func (p *ExecutionPlanner) ensureViewsSystemTableExists() error {
_, err := p.schemaAPI.TableByName(context.Background(), "fb_views")
func (p *ExecutionPlanner) ensureViewsSystemTableExists(ctx context.Context) error {
_, err := p.schemaAPI.TableByName(ctx, "fb_views")
if err != nil {
if !isTableNotFoundError(err) {
return err
@ -99,7 +99,7 @@ func (p *ExecutionPlanner) ensureViewsSystemTableExists() error {
description: "system table for views",
}
// call next on our iterator to create the table
_, err := iter.Next(context.Background())
_, err := iter.Next(ctx)
if err != nil && err != types.ErrNoMoreRows {
return err
}
@ -107,13 +107,13 @@ func (p *ExecutionPlanner) ensureViewsSystemTableExists() error {
return nil
}
func (p *ExecutionPlanner) getViewByName(name string) (*viewSystemObject, error) {
err := p.ensureViewsSystemTableExists()
func (p *ExecutionPlanner) getViewByName(ctx context.Context, name string) (*viewSystemObject, error) {
err := p.ensureViewsSystemTableExists(ctx)
if err != nil {
return nil, err
}
tbl, err := p.schemaAPI.TableByName(context.Background(), "fb_views")
tbl, err := p.schemaAPI.TableByName(ctx, "fb_views")
if err != nil {
return nil, sql3.NewErrTableNotFound(0, 0, "fb_views")
}
@ -136,7 +136,7 @@ func (p *ExecutionPlanner) getViewByName(name string) (*viewSystemObject, error)
topExpr: nil,
}
row, err := iter.Next(context.Background())
row, err := iter.Next(ctx)
if err != nil {
if err == types.ErrNoMoreRows {
// view does not exist
@ -151,8 +151,8 @@ func (p *ExecutionPlanner) getViewByName(name string) (*viewSystemObject, error)
}, nil
}
func (p *ExecutionPlanner) insertView(view *viewSystemObject) error {
err := p.ensureViewsSystemTableExists()
func (p *ExecutionPlanner) insertView(ctx context.Context, view *viewSystemObject) error {
err := p.ensureViewsSystemTableExists(ctx)
if err != nil {
return err
}
@ -183,15 +183,15 @@ func (p *ExecutionPlanner) insertView(view *viewSystemObject) error {
},
},
}
_, err = iter.Next(context.Background())
_, err = iter.Next(ctx)
if err != nil && err != types.ErrNoMoreRows {
return err
}
return nil
}
func (p *ExecutionPlanner) updateView(view *viewSystemObject) error {
err := p.ensureViewsSystemTableExists()
func (p *ExecutionPlanner) updateView(ctx context.Context, view *viewSystemObject) error {
err := p.ensureViewsSystemTableExists(ctx)
if err != nil {
return err
}
@ -216,15 +216,15 @@ func (p *ExecutionPlanner) updateView(view *viewSystemObject) error {
},
},
}
_, err = iter.Next(context.Background())
_, err = iter.Next(ctx)
if err != nil && err != types.ErrNoMoreRows {
return err
}
return nil
}
func (p *ExecutionPlanner) deleteView(viewName string) error {
err := p.ensureViewsSystemTableExists()
func (p *ExecutionPlanner) deleteView(ctx context.Context, viewName string) error {
err := p.ensureViewsSystemTableExists(ctx)
if err != nil {
return err
}
@ -239,7 +239,7 @@ func (p *ExecutionPlanner) deleteView(viewName string) error {
parser.NewDataTypeBool(),
),
}
_, err = iter.Next(context.Background())
_, err = iter.Next(ctx)
if err != nil && err != types.ErrNoMoreRows {
return err
}