mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
statement without a units qualifier causes it to be set to 0 Co-authored-by: Adrian Walker <adrian.walker@molecula.comm>
87 lines
2.5 KiB
Go
87 lines
2.5 KiB
Go
// Copyright 2021 Molecula Corp. All rights reserved.
|
|
|
|
package planner
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
|
|
"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 := strings.ToLower(parser.IdentName(stmt.Name))
|
|
failIfExists := !stmt.IfNotExists.IsValid()
|
|
|
|
// By default, a database needs at least 1 unit for simple querying, so by
|
|
// setting the default to 1, users can simply type `CREATE DATABASE [name]` without
|
|
// needing to append `WITH UNITS 1;`
|
|
units := 1
|
|
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
|
|
}
|