mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 02:44:59 +00:00
* Implement Schemar.SetDatabaseOption(option, value string) This replaces the temporary `SetDatabaseOptions()` method, which replaced the entire DatabaseOptions struct, with `SetDatabaseOption` which takes an option/value pair of strings to set. * Add SetDatabaseOption to controller http handler and client This commit also: - renames some `writeLog` to `writelog` - updates ApplyDirective to call resource.Unlock() on any resources being removed from the local worker * Add Database related methods to SchemaAPI interface Currently all implementations of this interface are implemented with "unimplemented" errors on those methods. Next will be to implement the necessary methods. * SQL: CREATE DATABASE and SHOW DATABASES * SQL: DROP DATABASE * SQL: Add UNITS option to CREATE DATABASE * SQL: ALTER DATABASE * User serverlessStorage.Remove[*]Resource instead of resource.Unlock() * Add WITH keyword to CREATE/ALTER DATABASE * fix some WITH logic * linter fixes * WITH on CREATE DATABASE is not required
83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
// Copyright 2021 Molecula Corp. All rights reserved.
|
|
|
|
package planner
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/featurebasedb/featurebase/v3/sql3"
|
|
"github.com/featurebasedb/featurebase/v3/sql3/parser"
|
|
"github.com/featurebasedb/featurebase/v3/sql3/planner/types"
|
|
)
|
|
|
|
// compileCreateDatabaseStatement compiles a CREATE DATABASE statement into a
|
|
// PlanOperator.
|
|
func (p *ExecutionPlanner) compileCreateDatabaseStatement(stmt *parser.CreateDatabaseStatement) (_ types.PlanOperator, err error) {
|
|
databaseName := parser.IdentName(stmt.Name)
|
|
failIfExists := !stmt.IfNotExists.IsValid()
|
|
|
|
units := 0
|
|
description := ""
|
|
|
|
// apply database options
|
|
if stmt.With.IsValid() {
|
|
for _, option := range stmt.Options {
|
|
switch o := option.(type) {
|
|
case *parser.UnitsOption:
|
|
e := o.Expr.(*parser.IntegerLit)
|
|
i, err := strconv.ParseInt(e.Value, 10, 64)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
units = int(i)
|
|
case *parser.CommentOption:
|
|
e := o.Expr.(*parser.StringLit)
|
|
description = e.Value
|
|
}
|
|
}
|
|
}
|
|
|
|
cop := NewPlanOpCreateDatabase(p, databaseName, failIfExists, units, description)
|
|
return NewPlanOpQuery(p, cop, p.sql), nil
|
|
}
|
|
|
|
// analyzeCreateDatabaseStatement analyzes a CREATE DATABASE statement and
|
|
// returns an error if anything is invalid.
|
|
func (p *ExecutionPlanner) analyzeCreateDatabaseStatement(stmt *parser.CreateDatabaseStatement) error {
|
|
if stmt.With.IsValid() {
|
|
// no checks if WITH is not provided
|
|
return nil
|
|
}
|
|
|
|
//check database options
|
|
for _, option := range stmt.Options {
|
|
|
|
switch o := option.(type) {
|
|
case *parser.UnitsOption:
|
|
//check the type of the expression
|
|
literal, ok := o.Expr.(*parser.IntegerLit)
|
|
if !ok {
|
|
return sql3.NewErrIntegerLiteral(o.Expr.Pos().Line, o.Expr.Pos().Column)
|
|
}
|
|
// units needs to be >=0 and we'll cap conservatively at 10000
|
|
i, err := strconv.ParseInt(literal.Value, 10, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if i < 0 || i > 10000 {
|
|
return sql3.NewErrInvalidUnitsValue(o.Expr.Pos().Line, o.Expr.Pos().Column, i)
|
|
}
|
|
|
|
case *parser.CommentOption:
|
|
_, ok := o.Expr.(*parser.StringLit)
|
|
if !ok {
|
|
return sql3.NewErrStringLiteral(o.Expr.Pos().Line, o.Expr.Pos().Column)
|
|
}
|
|
|
|
default:
|
|
return sql3.NewErrInternalf("unhandled database option type '%T'", option)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|