mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
103 lines
2.2 KiB
Go
103 lines
2.2 KiB
Go
package query
|
|
|
|
import (
|
|
"pilosa/db"
|
|
"pilosa/util"
|
|
"strings"
|
|
)
|
|
|
|
type QueryInput interface{}
|
|
|
|
type QueryResults struct {
|
|
Data interface{}
|
|
}
|
|
|
|
type PqlList []PqlListItem
|
|
|
|
type PqlListItem struct {
|
|
Id *util.GUID
|
|
Label string
|
|
PQL string
|
|
}
|
|
|
|
type Query struct {
|
|
Id *util.GUID
|
|
Operation string
|
|
Args map[string]interface{}
|
|
Subqueries []Query
|
|
}
|
|
|
|
func QueryPlanForPQL(database *db.Database, pql string, destination *db.Location) (*QueryPlan, error) {
|
|
tokens, err := Lex(pql)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return QueryPlanForTokens(database, tokens, destination)
|
|
}
|
|
|
|
func QueryForPQL(pql string) (*Query, error) {
|
|
tokens, err := Lex(pql)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return QueryForTokens(tokens)
|
|
}
|
|
|
|
func QueryForTokens(tokens []Token) (*Query, error) {
|
|
query, err := Parse(tokens)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return query, nil
|
|
}
|
|
|
|
func QueryPlanForTokens(database *db.Database, tokens []Token, destination *db.Location) (*QueryPlan, error) {
|
|
query, err := QueryForTokens(tokens)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return QueryPlanForQuery(database, query, destination)
|
|
}
|
|
|
|
func QueryPlanForQuery(database *db.Database, query *Query, destination *db.Location) (*QueryPlan, error) {
|
|
query_planner := QueryPlanner{Database: database, Query: query}
|
|
id := util.RandomUUID()
|
|
query_plan, err := query_planner.Plan(query, &id, destination)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return query_plan, nil
|
|
}
|
|
|
|
func TokensToFilterStrings(tokens []Token) (string, []string) {
|
|
var whole []string
|
|
var filter string
|
|
var filters []string
|
|
var open_parens int
|
|
var in_square_brackets bool
|
|
var last_slice = 0
|
|
|
|
open_parens = -1
|
|
in_square_brackets = false
|
|
for i, _ := range tokens {
|
|
whole = append(whole, tokens[i].Text)
|
|
if tokens[i].Type == TYPE_FUNC {
|
|
last_slice = i
|
|
} else if tokens[i].Type == TYPE_LP {
|
|
open_parens += 1
|
|
} else if tokens[i].Type == TYPE_RP {
|
|
open_parens -= 1
|
|
if open_parens == 0 {
|
|
if !in_square_brackets {
|
|
filter = strings.Join(whole[2:], "")
|
|
} else {
|
|
filters = append(filters, strings.Join(whole[last_slice:], ""))
|
|
}
|
|
last_slice = i
|
|
}
|
|
} else if open_parens == 0 && tokens[i].Type == TYPE_LB {
|
|
in_square_brackets = true
|
|
}
|
|
}
|
|
return filter, filters
|
|
}
|