featurebase/sql3/planner/compilecreatefunction.go
Pat Okeeffe 284f62dcb9
create model, create function... all the goodies (#2264)
* create function, create/drop model; re-introduced limit; added COPY; var(); corr()

* review feedback
2023-04-04 17:44:29 -05:00

79 lines
2.2 KiB
Go

// Copyright 2023 Molecula Corp. All rights reserved.
package planner
import (
"strings"
"github.com/featurebasedb/featurebase/v3/sql3"
"github.com/featurebasedb/featurebase/v3/sql3/parser"
"github.com/featurebasedb/featurebase/v3/sql3/planner/types"
)
// compileCreateFunctionStatement compiles a parser.CreateFunctionStatement AST into a PlanOperator
func (p *ExecutionPlanner) compileCreateFunctionStatement(stmt *parser.CreateFunctionStatement) (types.PlanOperator, error) {
functionName := parser.IdentName(stmt.Name)
function := &functionSystemObject{
name: functionName,
}
lang := "sql"
if len(stmt.Options) > 0 {
for _, o := range stmt.Options {
switch strings.ToLower(o.Name.String()) {
case "language":
lit, ok := o.OptionExpr.(*parser.StringLit)
if !ok {
return nil, sql3.NewErrStringLiteral(o.OptionExpr.Pos().Line, o.OptionExpr.Pos().Column)
}
l := strings.ToLower(lit.Value)
switch l {
case "python":
lang = l
default:
return nil, sql3.NewErrInternalf("unsupported language '%s'", l)
}
}
}
}
function.language = lang
// TODO(pok) - hobble user defined functions for now
switch lang {
case "sql":
return nil, sql3.NewErrInternalf("unsupported language '%s'", lang)
case "python":
// return nil, sql3.NewErrInternalf("unsupported language '%s'", lang)
// function body is in the return statement
if len(stmt.Body) != 1 {
return nil, sql3.NewErrInternalf("unexpected body len '%d'", len(stmt.Body))
}
rs, ok := stmt.Body[0].(*parser.ReturnStatement)
if !ok {
return nil, sql3.NewErrInternalf("unexpected statement type '%T'", stmt.Body[0])
}
bexpr, ok := rs.ReturnExpr.(*parser.StringLit)
if !ok {
return nil, sql3.NewErrInternalf("unexpected expression type '%T'", rs.ReturnExpr)
}
function.body = bexpr.Value
default:
return nil, sql3.NewErrInternalf("unsupported language '%s'", lang)
}
fn := NewPlanOpCreateFunction(p, stmt.IfNotExists.IsValid(), function)
fn.AddWarning("🦖 here there be dragons! CREATE FUNCTION statement is experimental.")
query := NewPlanOpQuery(p, fn, p.sql)
return query, nil
}
func (p *ExecutionPlanner) analyzeCreateFunctionStatement(stmt *parser.CreateFunctionStatement) error {
return nil
}