mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 02:44:59 +00:00
implemented extract ddl; tightened up type related stuff (#2329)
* implemented extract ddl; tightened up type related stuff
* added some test coverage
* review feedback
(cherry picked from commit f62313762c)
This commit is contained in:
parent
a44b622aa0
commit
c304991e9f
55 changed files with 1832 additions and 1476 deletions
|
|
@ -162,7 +162,7 @@ func (q *Queryer) QuerySQL(ctx context.Context, qual dax.TableQualifier, sql str
|
|||
Fields: make([]*featurebase.WireQueryField, len(columns)),
|
||||
}
|
||||
for i, col := range columns {
|
||||
btype, err := dax.BaseTypeFromString(col.Type.TypeName())
|
||||
btype, err := dax.BaseTypeFromString(col.Type.BaseTypeName())
|
||||
if err != nil {
|
||||
applyError(errors.Wrap(err, "getting fieldtype from string"))
|
||||
return ret, nil
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
"mime"
|
||||
"net"
|
||||
"net/http"
|
||||
|
|
@ -1438,30 +1437,36 @@ func (h *Handler) handlePostSQL(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Write the closing bracket on any exit from this method.
|
||||
defer func() {
|
||||
var execTime int64 = 0
|
||||
// we are going to make best effort here - don't actually care about the error
|
||||
// if there was an error, the request.ElapsedTime will be zero
|
||||
request, _ := h.api.server.SystemLayer.ExecutionRequests().GetRequest(requestID.String())
|
||||
execTime = request.ElapsedTime.Microseconds()
|
||||
|
||||
var value []byte
|
||||
request, err := h.api.server.SystemLayer.ExecutionRequests().GetRequest(requestID.String())
|
||||
value, err = json.Marshal(execTime)
|
||||
if err != nil {
|
||||
value = big.NewInt(-1).Bytes()
|
||||
w.Write([]byte(`,"exec_time": 0`))
|
||||
} else {
|
||||
value, err = json.Marshal(request.ElapsedTime.Microseconds())
|
||||
if err != nil {
|
||||
value = big.NewInt(-1).Bytes()
|
||||
}
|
||||
w.Write([]byte(`,"exec_time":`))
|
||||
w.Write(value)
|
||||
}
|
||||
w.Write([]byte(`,"exec_time":`))
|
||||
w.Write(value)
|
||||
w.Write([]byte("}"))
|
||||
}()
|
||||
|
||||
// writeError is a helper function that can be called anywhere during the
|
||||
// output handling to insert an error into the json output.
|
||||
writeError := func(err error) {
|
||||
writeError := func(err error, withComma bool) {
|
||||
if err != nil {
|
||||
errMsg, err := json.Marshal(err.Error())
|
||||
if err != nil {
|
||||
errMsg = []byte(`"PROBLEM ENCODING ERROR MESSAGE"`)
|
||||
}
|
||||
w.Write([]byte(`,"error":`))
|
||||
if withComma {
|
||||
w.Write([]byte(`,"error":`))
|
||||
} else {
|
||||
w.Write([]byte(`"error":`))
|
||||
}
|
||||
w.Write(errMsg)
|
||||
}
|
||||
}
|
||||
|
|
@ -1499,7 +1504,7 @@ func (h *Handler) handlePostSQL(w http.ResponseWriter, r *http.Request) {
|
|||
// Get a query iterator.
|
||||
iter, err := rootOperator.Iterator(ctx, nil)
|
||||
if err != nil {
|
||||
writeError(err)
|
||||
writeError(err, false)
|
||||
writeWarnings(rootOperator.Warnings())
|
||||
return
|
||||
}
|
||||
|
|
@ -1510,15 +1515,15 @@ func (h *Handler) handlePostSQL(w http.ResponseWriter, r *http.Request) {
|
|||
Fields: make([]*WireQueryField, len(columns)),
|
||||
}
|
||||
for i, col := range columns {
|
||||
btype, err := dax.BaseTypeFromString(col.Type.TypeName())
|
||||
btype, err := dax.BaseTypeFromString(col.Type.BaseTypeName())
|
||||
if err != nil {
|
||||
writeError(err)
|
||||
writeError(err, false)
|
||||
writeWarnings(rootOperator.Warnings())
|
||||
return
|
||||
}
|
||||
schema.Fields[i] = &WireQueryField{
|
||||
Name: dax.FieldName(col.ColumnName),
|
||||
Type: strings.ToLower(col.Type.TypeDescription()), // TODO(tlt): remove this once sql3 uses BaseTypes.
|
||||
Type: col.Type.TypeDescription(),
|
||||
BaseType: btype,
|
||||
TypeInfo: col.Type.TypeInfo(),
|
||||
}
|
||||
|
|
@ -1529,7 +1534,7 @@ func (h *Handler) handlePostSQL(w http.ResponseWriter, r *http.Request) {
|
|||
h.logger.Errorf("write schema response error: %s", err)
|
||||
// Provide an empty list as the schema value to maintain valid json.
|
||||
w.Write([]byte("[]"))
|
||||
writeError(err)
|
||||
writeError(err, false)
|
||||
writeWarnings(rootOperator.Warnings())
|
||||
return
|
||||
}
|
||||
|
|
@ -1565,7 +1570,7 @@ func (h *Handler) handlePostSQL(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
w.Write([]byte("]"))
|
||||
|
||||
writeError(rowErr)
|
||||
writeError(rowErr, true)
|
||||
writeWarnings(rootOperator.Warnings())
|
||||
writePlan(rootOperator.Plan())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,114 +13,116 @@ type Node interface {
|
|||
fmt.Stringer
|
||||
}
|
||||
|
||||
func (*AlterTableStatement) node() {}
|
||||
func (*AnalyzeStatement) node() {}
|
||||
func (*Assignment) node() {}
|
||||
func (*ShowTablesStatement) node() {}
|
||||
func (*ShowColumnsStatement) node() {}
|
||||
func (*BeginStatement) node() {}
|
||||
func (*BinaryExpr) node() {}
|
||||
func (*BoolLit) node() {}
|
||||
func (*BulkInsertMapDefinition) node() {}
|
||||
func (*BulkInsertStatement) node() {}
|
||||
func (*CacheTypeConstraint) node() {}
|
||||
func (*Call) node() {}
|
||||
func (*CaseBlock) node() {}
|
||||
func (*CaseExpr) node() {}
|
||||
func (*CastExpr) node() {}
|
||||
func (*CheckConstraint) node() {}
|
||||
func (*ColumnDefinition) node() {}
|
||||
func (*CommitStatement) node() {}
|
||||
func (*CreateIndexStatement) node() {}
|
||||
func (*CreateTableStatement) node() {}
|
||||
func (*CreateFunctionStatement) node() {}
|
||||
func (*CreateViewStatement) node() {}
|
||||
func (*DateLit) node() {}
|
||||
func (*DefaultConstraint) node() {}
|
||||
func (*DeleteStatement) node() {}
|
||||
func (*DropIndexStatement) node() {}
|
||||
func (*DropTableStatement) node() {}
|
||||
func (*DropFunctionStatement) node() {}
|
||||
func (*DropViewStatement) node() {}
|
||||
func (*Exists) node() {}
|
||||
func (*ExplainStatement) node() {}
|
||||
func (*ExprList) node() {}
|
||||
func (*FilterClause) node() {}
|
||||
func (*FloatLit) node() {}
|
||||
func (*ForeignKeyArg) node() {}
|
||||
func (*ForeignKeyConstraint) node() {}
|
||||
func (*FrameSpec) node() {}
|
||||
func (*Ident) node() {}
|
||||
func (*Variable) node() {}
|
||||
func (*IndexedColumn) node() {}
|
||||
func (*InsertStatement) node() {}
|
||||
func (*JoinClause) node() {}
|
||||
func (*JoinOperator) node() {}
|
||||
func (*KeyPartitionsOption) node() {}
|
||||
func (*MinConstraint) node() {}
|
||||
func (*MaxConstraint) node() {}
|
||||
func (*NotNullConstraint) node() {}
|
||||
func (*NullLit) node() {}
|
||||
func (*IntegerLit) node() {}
|
||||
func (*OnConstraint) node() {}
|
||||
func (*OrderingTerm) node() {}
|
||||
func (*OverClause) node() {}
|
||||
func (*ParenExpr) node() {}
|
||||
func (*SetLiteralExpr) node() {}
|
||||
func (*ParenSource) node() {}
|
||||
func (*PrimaryKeyConstraint) node() {}
|
||||
func (*QualifiedRef) node() {}
|
||||
func (*QualifiedTableName) node() {}
|
||||
func (*Range) node() {}
|
||||
func (*ReleaseStatement) node() {}
|
||||
func (*ResultColumn) node() {}
|
||||
func (*RollbackStatement) node() {}
|
||||
func (*SavepointStatement) node() {}
|
||||
func (*SelectStatement) node() {}
|
||||
func (*ShardWidthOption) node() {}
|
||||
func (*StringLit) node() {}
|
||||
func (*TableValuedFunction) node() {}
|
||||
func (*TimeUnitConstraint) node() {}
|
||||
func (*TimeQuantumConstraint) node() {}
|
||||
func (*TupleLiteralExpr) node() {}
|
||||
func (*Type) node() {}
|
||||
func (*UnaryExpr) node() {}
|
||||
func (*UniqueConstraint) node() {}
|
||||
func (*UpdateStatement) node() {}
|
||||
func (*UpsertClause) node() {}
|
||||
func (*UsingConstraint) node() {}
|
||||
func (*Window) node() {}
|
||||
func (*WindowDefinition) node() {}
|
||||
func (*WithClause) node() {}
|
||||
func (*AlterTableStatement) node() {}
|
||||
func (*AnalyzeStatement) node() {}
|
||||
func (*Assignment) node() {}
|
||||
func (*ShowTablesStatement) node() {}
|
||||
func (*ShowColumnsStatement) node() {}
|
||||
func (*ShowCreateTableStatement) node() {}
|
||||
func (*BeginStatement) node() {}
|
||||
func (*BinaryExpr) node() {}
|
||||
func (*BoolLit) node() {}
|
||||
func (*BulkInsertMapDefinition) node() {}
|
||||
func (*BulkInsertStatement) node() {}
|
||||
func (*CacheTypeConstraint) node() {}
|
||||
func (*Call) node() {}
|
||||
func (*CaseBlock) node() {}
|
||||
func (*CaseExpr) node() {}
|
||||
func (*CastExpr) node() {}
|
||||
func (*CheckConstraint) node() {}
|
||||
func (*ColumnDefinition) node() {}
|
||||
func (*CommitStatement) node() {}
|
||||
func (*CreateIndexStatement) node() {}
|
||||
func (*CreateTableStatement) node() {}
|
||||
func (*CreateFunctionStatement) node() {}
|
||||
func (*CreateViewStatement) node() {}
|
||||
func (*DateLit) node() {}
|
||||
func (*DefaultConstraint) node() {}
|
||||
func (*DeleteStatement) node() {}
|
||||
func (*DropIndexStatement) node() {}
|
||||
func (*DropTableStatement) node() {}
|
||||
func (*DropFunctionStatement) node() {}
|
||||
func (*DropViewStatement) node() {}
|
||||
func (*Exists) node() {}
|
||||
func (*ExplainStatement) node() {}
|
||||
func (*ExprList) node() {}
|
||||
func (*FilterClause) node() {}
|
||||
func (*FloatLit) node() {}
|
||||
func (*ForeignKeyArg) node() {}
|
||||
func (*ForeignKeyConstraint) node() {}
|
||||
func (*FrameSpec) node() {}
|
||||
func (*Ident) node() {}
|
||||
func (*Variable) node() {}
|
||||
func (*IndexedColumn) node() {}
|
||||
func (*InsertStatement) node() {}
|
||||
func (*JoinClause) node() {}
|
||||
func (*JoinOperator) node() {}
|
||||
func (*KeyPartitionsOption) node() {}
|
||||
func (*MinConstraint) node() {}
|
||||
func (*MaxConstraint) node() {}
|
||||
func (*NotNullConstraint) node() {}
|
||||
func (*NullLit) node() {}
|
||||
func (*IntegerLit) node() {}
|
||||
func (*OnConstraint) node() {}
|
||||
func (*OrderingTerm) node() {}
|
||||
func (*OverClause) node() {}
|
||||
func (*ParenExpr) node() {}
|
||||
func (*SetLiteralExpr) node() {}
|
||||
func (*ParenSource) node() {}
|
||||
func (*PrimaryKeyConstraint) node() {}
|
||||
func (*QualifiedRef) node() {}
|
||||
func (*QualifiedTableName) node() {}
|
||||
func (*Range) node() {}
|
||||
func (*ReleaseStatement) node() {}
|
||||
func (*ResultColumn) node() {}
|
||||
func (*RollbackStatement) node() {}
|
||||
func (*SavepointStatement) node() {}
|
||||
func (*SelectStatement) node() {}
|
||||
func (*ShardWidthOption) node() {}
|
||||
func (*StringLit) node() {}
|
||||
func (*TableValuedFunction) node() {}
|
||||
func (*TimeUnitConstraint) node() {}
|
||||
func (*TimeQuantumConstraint) node() {}
|
||||
func (*TupleLiteralExpr) node() {}
|
||||
func (*Type) node() {}
|
||||
func (*UnaryExpr) node() {}
|
||||
func (*UniqueConstraint) node() {}
|
||||
func (*UpdateStatement) node() {}
|
||||
func (*UpsertClause) node() {}
|
||||
func (*UsingConstraint) node() {}
|
||||
func (*Window) node() {}
|
||||
func (*WindowDefinition) node() {}
|
||||
func (*WithClause) node() {}
|
||||
|
||||
type Statement interface {
|
||||
Node
|
||||
stmt()
|
||||
}
|
||||
|
||||
func (*AlterTableStatement) stmt() {}
|
||||
func (*AnalyzeStatement) stmt() {}
|
||||
func (*BeginStatement) stmt() {}
|
||||
func (*BulkInsertStatement) stmt() {}
|
||||
func (*ShowTablesStatement) stmt() {}
|
||||
func (*ShowColumnsStatement) stmt() {}
|
||||
func (*CommitStatement) stmt() {}
|
||||
func (*CreateIndexStatement) stmt() {}
|
||||
func (*CreateTableStatement) stmt() {}
|
||||
func (*CreateFunctionStatement) stmt() {}
|
||||
func (*CreateViewStatement) stmt() {}
|
||||
func (*DeleteStatement) stmt() {}
|
||||
func (*DropIndexStatement) stmt() {}
|
||||
func (*DropTableStatement) stmt() {}
|
||||
func (*DropFunctionStatement) stmt() {}
|
||||
func (*DropViewStatement) stmt() {}
|
||||
func (*ExplainStatement) stmt() {}
|
||||
func (*InsertStatement) stmt() {}
|
||||
func (*ReleaseStatement) stmt() {}
|
||||
func (*RollbackStatement) stmt() {}
|
||||
func (*SavepointStatement) stmt() {}
|
||||
func (*SelectStatement) stmt() {}
|
||||
func (*UpdateStatement) stmt() {}
|
||||
func (*AlterTableStatement) stmt() {}
|
||||
func (*AnalyzeStatement) stmt() {}
|
||||
func (*BeginStatement) stmt() {}
|
||||
func (*BulkInsertStatement) stmt() {}
|
||||
func (*ShowTablesStatement) stmt() {}
|
||||
func (*ShowColumnsStatement) stmt() {}
|
||||
func (*ShowCreateTableStatement) stmt() {}
|
||||
func (*CommitStatement) stmt() {}
|
||||
func (*CreateIndexStatement) stmt() {}
|
||||
func (*CreateTableStatement) stmt() {}
|
||||
func (*CreateFunctionStatement) stmt() {}
|
||||
func (*CreateViewStatement) stmt() {}
|
||||
func (*DeleteStatement) stmt() {}
|
||||
func (*DropIndexStatement) stmt() {}
|
||||
func (*DropTableStatement) stmt() {}
|
||||
func (*DropFunctionStatement) stmt() {}
|
||||
func (*DropViewStatement) stmt() {}
|
||||
func (*ExplainStatement) stmt() {}
|
||||
func (*InsertStatement) stmt() {}
|
||||
func (*ReleaseStatement) stmt() {}
|
||||
func (*RollbackStatement) stmt() {}
|
||||
func (*SavepointStatement) stmt() {}
|
||||
func (*SelectStatement) stmt() {}
|
||||
func (*UpdateStatement) stmt() {}
|
||||
|
||||
// CloneStatement returns a deep copy stmt.
|
||||
func CloneStatement(stmt Statement) Statement {
|
||||
|
|
@ -494,6 +496,23 @@ func (s *ShowColumnsStatement) String() string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
type ShowCreateTableStatement struct {
|
||||
Show Pos // position of SHOW
|
||||
Create Pos // position of CREATE
|
||||
Table Pos // position of CREATE
|
||||
TableName *Ident // name of table
|
||||
}
|
||||
|
||||
// String returns the string representation of the statement.
|
||||
func (s *ShowCreateTableStatement) String() string {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString("SHOW CREATE TABLE ")
|
||||
if s.TableName != nil {
|
||||
fmt.Fprintf(&buf, " %s", s.TableName.String())
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type BeginStatement struct {
|
||||
Begin Pos // position of BEGIN
|
||||
Deferred Pos // position of DEFERRED keyword
|
||||
|
|
|
|||
|
|
@ -3,43 +3,39 @@ package parser
|
|||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TODO(pok) make all these lower case
|
||||
const (
|
||||
FieldTypeBool = "BOOL"
|
||||
FieldTypeDecimal = "DECIMAL"
|
||||
FieldTypeID = "ID"
|
||||
FieldTypeIDSet = "IDSET"
|
||||
FieldTypeIDSetQuantum = "IDSETQ"
|
||||
FieldTypeInt = "INT"
|
||||
FieldTypeString = "STRING"
|
||||
FieldTypeStringSet = "STRINGSET"
|
||||
FieldTypeStringSetQuantum = "STRINGSETQ"
|
||||
FieldTypeTimestamp = "TIMESTAMP"
|
||||
"github.com/molecula/featurebase/v3/dax"
|
||||
)
|
||||
|
||||
func IsValidTypeName(typeName string) bool {
|
||||
switch strings.ToUpper(typeName) {
|
||||
case FieldTypeBool,
|
||||
FieldTypeDecimal,
|
||||
FieldTypeID,
|
||||
FieldTypeIDSet,
|
||||
FieldTypeInt,
|
||||
FieldTypeString,
|
||||
FieldTypeStringSet,
|
||||
FieldTypeTimestamp:
|
||||
switch strings.ToLower(typeName) {
|
||||
case dax.BaseTypeBool,
|
||||
dax.BaseTypeDecimal,
|
||||
dax.BaseTypeID,
|
||||
dax.BaseTypeIDSet,
|
||||
dax.BaseTypeInt,
|
||||
dax.BaseTypeString,
|
||||
dax.BaseTypeStringSet,
|
||||
dax.BaseTypeTimestamp:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ExprDataType is the interface for all language layer types
|
||||
type ExprDataType interface {
|
||||
exprDataType()
|
||||
TypeName() string
|
||||
TypeDescription() string
|
||||
// the base type name e.g. int or decimal
|
||||
BaseTypeName() string
|
||||
// additional type information - intended to be used outside the language
|
||||
// layer (marshalled over json, or otherwise serialized so that consumers
|
||||
// have access to complete type information)
|
||||
// TypeInfo is not used inside the language layer itself, as the concrete
|
||||
// types (e.g. DataTypeString) are used
|
||||
TypeInfo() map[string]interface{}
|
||||
// the full type specification as a string - intended to be human readable
|
||||
TypeDescription() string
|
||||
}
|
||||
|
||||
func (*DataTypeVoid) exprDataType() {}
|
||||
|
|
@ -64,12 +60,12 @@ func NewDataTypeVoid() *DataTypeVoid {
|
|||
return &DataTypeVoid{}
|
||||
}
|
||||
|
||||
func (*DataTypeVoid) TypeName() string {
|
||||
return "VOID"
|
||||
func (*DataTypeVoid) BaseTypeName() string {
|
||||
return "void"
|
||||
}
|
||||
|
||||
func (dt *DataTypeVoid) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeVoid) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -86,12 +82,12 @@ func NewDataTypeRange(subscriptType ExprDataType) *DataTypeRange {
|
|||
}
|
||||
}
|
||||
|
||||
func (dt *DataTypeRange) TypeName() string {
|
||||
return fmt.Sprintf("RANGE(%s)", dt.SubscriptType.TypeName())
|
||||
func (dt *DataTypeRange) BaseTypeName() string {
|
||||
return "range"
|
||||
}
|
||||
|
||||
func (dt *DataTypeRange) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return fmt.Sprintf("range(%s)", dt.SubscriptType.TypeDescription())
|
||||
}
|
||||
|
||||
func (*DataTypeRange) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -108,19 +104,19 @@ func NewDataTypeTuple(members []ExprDataType) *DataTypeTuple {
|
|||
}
|
||||
}
|
||||
|
||||
func (dt *DataTypeTuple) TypeName() string {
|
||||
func (dt *DataTypeTuple) BaseTypeName() string {
|
||||
return "tuple"
|
||||
}
|
||||
|
||||
func (dt *DataTypeTuple) TypeDescription() string {
|
||||
ms := ""
|
||||
for idx, m := range dt.Members {
|
||||
ms = ms + m.TypeName()
|
||||
ms = ms + m.TypeDescription()
|
||||
if idx+1 < len(dt.Members) {
|
||||
ms = ms + ", "
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("TUPLE(%s)", ms)
|
||||
}
|
||||
|
||||
func (dt *DataTypeTuple) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return fmt.Sprintf("tuple(%s)", ms)
|
||||
}
|
||||
|
||||
func (*DataTypeTuple) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -142,19 +138,19 @@ func NewDataTypeSubtable(columns []*SubtableColumn) *DataTypeSubtable {
|
|||
}
|
||||
}
|
||||
|
||||
func (dt *DataTypeSubtable) TypeName() string {
|
||||
func (dt *DataTypeSubtable) BaseTypeName() string {
|
||||
return "subtable"
|
||||
}
|
||||
|
||||
func (dt *DataTypeSubtable) TypeDescription() string {
|
||||
ms := ""
|
||||
for idx, m := range dt.Columns {
|
||||
ms = ms + m.DataType.TypeName()
|
||||
ms = ms + m.DataType.TypeDescription()
|
||||
if idx+1 < len(dt.Columns) {
|
||||
ms = ms + ", "
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("SUBTABLE(%s)", ms)
|
||||
}
|
||||
|
||||
func (dt *DataTypeSubtable) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return fmt.Sprintf("subtable(%s)", ms)
|
||||
}
|
||||
|
||||
func (*DataTypeSubtable) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -168,12 +164,12 @@ func NewDataTypeBool() *DataTypeBool {
|
|||
return &DataTypeBool{}
|
||||
}
|
||||
|
||||
func (*DataTypeBool) TypeName() string {
|
||||
return FieldTypeBool
|
||||
func (*DataTypeBool) BaseTypeName() string {
|
||||
return dax.BaseTypeBool
|
||||
}
|
||||
|
||||
func (dt *DataTypeBool) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeBool) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -190,12 +186,12 @@ func NewDataTypeDecimal(scale int64) *DataTypeDecimal {
|
|||
}
|
||||
}
|
||||
|
||||
func (d *DataTypeDecimal) TypeName() string {
|
||||
return FieldTypeDecimal
|
||||
func (d *DataTypeDecimal) BaseTypeName() string {
|
||||
return dax.BaseTypeDecimal
|
||||
}
|
||||
|
||||
func (d *DataTypeDecimal) TypeDescription() string {
|
||||
return fmt.Sprintf("%s(%d)", FieldTypeDecimal, d.Scale)
|
||||
return fmt.Sprintf("%s(%d)", dax.BaseTypeDecimal, d.Scale)
|
||||
}
|
||||
|
||||
func (d *DataTypeDecimal) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -211,12 +207,12 @@ func NewDataTypeID() *DataTypeID {
|
|||
return &DataTypeID{}
|
||||
}
|
||||
|
||||
func (*DataTypeID) TypeName() string {
|
||||
return FieldTypeID
|
||||
func (*DataTypeID) BaseTypeName() string {
|
||||
return dax.BaseTypeID
|
||||
}
|
||||
|
||||
func (dt *DataTypeID) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeID) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -230,18 +226,19 @@ func NewDataTypeIDSet() *DataTypeIDSet {
|
|||
return &DataTypeIDSet{}
|
||||
}
|
||||
|
||||
func (*DataTypeIDSet) TypeName() string {
|
||||
return FieldTypeIDSet
|
||||
func (*DataTypeIDSet) BaseTypeName() string {
|
||||
return dax.BaseTypeIDSet
|
||||
}
|
||||
|
||||
func (dt *DataTypeIDSet) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeIDSet) TypeInfo() map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO (pok) should time quantum be it's own type and not a constraint?
|
||||
type DataTypeIDSetQuantum struct {
|
||||
}
|
||||
|
||||
|
|
@ -249,12 +246,12 @@ func NewDataTypeIDSetQuantum() *DataTypeIDSetQuantum {
|
|||
return &DataTypeIDSetQuantum{}
|
||||
}
|
||||
|
||||
func (*DataTypeIDSetQuantum) TypeName() string {
|
||||
return FieldTypeIDSetQuantum
|
||||
func (*DataTypeIDSetQuantum) BaseTypeName() string {
|
||||
return dax.BaseTypeIDSet
|
||||
}
|
||||
|
||||
func (dt *DataTypeIDSetQuantum) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeIDSetQuantum) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -268,12 +265,12 @@ func NewDataTypeInt() *DataTypeInt {
|
|||
return &DataTypeInt{}
|
||||
}
|
||||
|
||||
func (*DataTypeInt) TypeName() string {
|
||||
return FieldTypeInt
|
||||
func (*DataTypeInt) BaseTypeName() string {
|
||||
return dax.BaseTypeInt
|
||||
}
|
||||
|
||||
func (dt *DataTypeInt) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeInt) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -287,12 +284,12 @@ func NewDataTypeString() *DataTypeString {
|
|||
return &DataTypeString{}
|
||||
}
|
||||
|
||||
func (*DataTypeString) TypeName() string {
|
||||
return FieldTypeString
|
||||
func (*DataTypeString) BaseTypeName() string {
|
||||
return dax.BaseTypeString
|
||||
}
|
||||
|
||||
func (dt *DataTypeString) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeString) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -306,12 +303,12 @@ func NewDataTypeStringSet() *DataTypeStringSet {
|
|||
return &DataTypeStringSet{}
|
||||
}
|
||||
|
||||
func (*DataTypeStringSet) TypeName() string {
|
||||
return FieldTypeStringSet
|
||||
func (*DataTypeStringSet) BaseTypeName() string {
|
||||
return dax.BaseTypeStringSet
|
||||
}
|
||||
|
||||
func (dt *DataTypeStringSet) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeStringSet) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -325,12 +322,12 @@ func NewDataTypeStringSetQuantum() *DataTypeStringSetQuantum {
|
|||
return &DataTypeStringSetQuantum{}
|
||||
}
|
||||
|
||||
func (*DataTypeStringSetQuantum) TypeName() string {
|
||||
return FieldTypeStringSetQuantum
|
||||
func (*DataTypeStringSetQuantum) BaseTypeName() string {
|
||||
return dax.BaseTypeStringSet
|
||||
}
|
||||
|
||||
func (dt *DataTypeStringSetQuantum) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeStringSetQuantum) TypeInfo() map[string]interface{} {
|
||||
|
|
@ -344,12 +341,12 @@ func NewDataTypeTimestamp() *DataTypeTimestamp {
|
|||
return &DataTypeTimestamp{}
|
||||
}
|
||||
|
||||
func (*DataTypeTimestamp) TypeName() string {
|
||||
return FieldTypeTimestamp
|
||||
func (*DataTypeTimestamp) BaseTypeName() string {
|
||||
return dax.BaseTypeTimestamp
|
||||
}
|
||||
|
||||
func (dt *DataTypeTimestamp) TypeDescription() string {
|
||||
return dt.TypeName()
|
||||
return dt.BaseTypeName()
|
||||
}
|
||||
|
||||
func (*DataTypeTimestamp) TypeInfo() map[string]interface{} {
|
||||
|
|
|
|||
|
|
@ -163,8 +163,10 @@ func (p *Parser) parseShowStatement() (Statement, error) {
|
|||
return p.parseShowTablesStatement(show)
|
||||
case COLUMNS:
|
||||
return p.parseShowColumnsStatement(show)
|
||||
case CREATE:
|
||||
return p.parseShowCreateStatement(show)
|
||||
default:
|
||||
return nil, p.errorExpected(p.pos, p.tok, "TABLES, COLUMNS")
|
||||
return nil, p.errorExpected(p.pos, p.tok, "TABLES, COLUMNS or CREATE")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,6 +202,33 @@ func (p *Parser) parseShowColumnsStatement(showPos Pos) (_ *ShowColumnsStatement
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseShowCreateStatement(showPos Pos) (Statement, error) {
|
||||
assert(p.peek() == CREATE)
|
||||
create, _, _ := p.scan()
|
||||
|
||||
switch p.peek() {
|
||||
case TABLE:
|
||||
return p.parseShowCreateTableStatement(showPos, create)
|
||||
default:
|
||||
return nil, p.errorExpected(p.pos, p.tok, "TABLES")
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseShowCreateTableStatement(showPos Pos, createPos Pos) (_ *ShowCreateTableStatement, err error) {
|
||||
assert(p.peek() == TABLE)
|
||||
table, _, _ := p.scan()
|
||||
|
||||
var stmt ShowCreateTableStatement
|
||||
stmt.Show = showPos
|
||||
stmt.Create = createPos
|
||||
stmt.Table = table
|
||||
|
||||
if stmt.TableName, err = p.parseIdent("table name"); err != nil {
|
||||
return &stmt, err
|
||||
}
|
||||
return &stmt, nil
|
||||
}
|
||||
|
||||
/*func (p *Parser) parseBeginStatement() (*BeginStatement, error) {
|
||||
assert(p.peek() == BEGIN)
|
||||
|
||||
|
|
|
|||
|
|
@ -627,8 +627,8 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
Show: pos(0),
|
||||
Tables: pos(5),
|
||||
})
|
||||
AssertParseStatementError(t, `SHOW`, `1:4: expected TABLES, COLUMNS, found 'EOF'`)
|
||||
AssertParseStatementError(t, `SHOW BLAH`, `1:6: expected TABLES, COLUMNS, found BLAH`)
|
||||
AssertParseStatementError(t, `SHOW`, `1:4: expected TABLES, COLUMNS or CREATE, found 'EOF'`)
|
||||
AssertParseStatementError(t, `SHOW BLAH`, `1:6: expected TABLES, COLUMNS or CREATE, found BLAH`)
|
||||
})
|
||||
|
||||
t.Run("ShowColumns", func(t *testing.T) {
|
||||
|
|
@ -641,13 +641,29 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
NamePos: pos(18),
|
||||
},
|
||||
})
|
||||
AssertParseStatementError(t, `SHOW`, `1:4: expected TABLES, COLUMNS, found 'EOF'`)
|
||||
AssertParseStatementError(t, `SHOW`, `1:4: expected TABLES, COLUMNS or CREATE, found 'EOF'`)
|
||||
AssertParseStatementError(t, `SHOW COLUMNS`, `1:12: expected FROM, found 'EOF'`)
|
||||
AssertParseStatementError(t, `SHOW COLUMNS FOO`, `1:14: expected FROM, found FOO`)
|
||||
AssertParseStatementError(t, `SHOW COLUMNS FROM`, `1:17: expected table name, found 'EOF'`)
|
||||
AssertParseStatementError(t, `SHOW COLUMNS FROM 12`, `1:19: expected table name, found 12`)
|
||||
})
|
||||
|
||||
t.Run("ShowCreateTable", func(t *testing.T) {
|
||||
AssertParseStatement(t, `SHOW CREATE TABLE FOO`, &parser.ShowCreateTableStatement{
|
||||
Show: pos(0),
|
||||
Create: pos(5),
|
||||
Table: pos(12),
|
||||
TableName: &parser.Ident{
|
||||
Name: "FOO",
|
||||
NamePos: pos(18),
|
||||
},
|
||||
})
|
||||
AssertParseStatementError(t, `SHOW`, `1:4: expected TABLES, COLUMNS or CREATE, found 'EOF'`)
|
||||
AssertParseStatementError(t, `SHOW CREATE`, `1:11: expected TABLES, found 'EOF'`)
|
||||
AssertParseStatementError(t, `SHOW CREATE TABLE`, `1:17: expected table name, found 'EOF'`)
|
||||
AssertParseStatementError(t, `SHOW CREATE TABLE 12`, `1:19: expected table name, found 12`)
|
||||
})
|
||||
|
||||
t.Run("Explain", func(t *testing.T) {
|
||||
/*t.Run("", func(t *testing.T) {
|
||||
AssertParseStatement(t, `EXPLAIN BEGIN`, &parser.ExplainStatement{
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ func (p *ExecutionPlanner) analyzeBulkInsertStatement(stmt *parser.BulkInsertSta
|
|||
if stmt.TransformList != nil {
|
||||
t := stmt.TransformList[idx]
|
||||
if !typesAreAssignmentCompatible(colDataType, t.DataType()) {
|
||||
return sql3.NewErrTypeAssignmentIncompatible(t.Pos().Line, t.Pos().Column, t.DataType().TypeName(), colDataType.TypeName())
|
||||
return sql3.NewErrTypeAssignmentIncompatible(t.Pos().Line, t.Pos().Column, t.DataType().TypeDescription(), colDataType.TypeDescription())
|
||||
}
|
||||
} else {
|
||||
// this assumes that map and col list have already been checked for length
|
||||
|
|
@ -347,7 +347,7 @@ func (p *ExecutionPlanner) analyzeBulkInsertStatement(stmt *parser.BulkInsertSta
|
|||
return err
|
||||
}
|
||||
if !typesAreAssignmentCompatible(colDataType, t) {
|
||||
return sql3.NewErrTypeAssignmentIncompatible(me.MapExpr.Pos().Line, me.MapExpr.Pos().Column, t.TypeName(), colDataType.TypeName())
|
||||
return sql3.NewErrTypeAssignmentIncompatible(me.MapExpr.Pos().Line, me.MapExpr.Pos().Column, t.TypeDescription(), colDataType.TypeDescription())
|
||||
}
|
||||
}
|
||||
break
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
pilosa "github.com/featurebasedb/featurebase/v3"
|
||||
"github.com/featurebasedb/featurebase/v3/pql"
|
||||
"github.com/featurebasedb/featurebase/v3/sql3"
|
||||
"github.com/featurebasedb/featurebase/v3/sql3/parser"
|
||||
"github.com/featurebasedb/featurebase/v3/sql3/planner/types"
|
||||
pilosa "github.com/molecula/featurebase/v3"
|
||||
"github.com/molecula/featurebase/v3/dax"
|
||||
"github.com/molecula/featurebase/v3/pql"
|
||||
"github.com/molecula/featurebase/v3/sql3"
|
||||
"github.com/molecula/featurebase/v3/sql3/parser"
|
||||
"github.com/molecula/featurebase/v3/sql3/planner/types"
|
||||
)
|
||||
|
||||
type createTableField struct {
|
||||
|
|
@ -49,7 +50,7 @@ func (p *ExecutionPlanner) compileCreateTableStatement(stmt *parser.CreateTableS
|
|||
typeName := parser.IdentName(col.Type.Name)
|
||||
|
||||
if strings.ToLower(columnName) == "_id" {
|
||||
if strings.EqualFold(typeName, parser.FieldTypeString) {
|
||||
if strings.EqualFold(typeName, dax.BaseTypeString) {
|
||||
isKeyed = true
|
||||
}
|
||||
continue
|
||||
|
|
@ -181,10 +182,10 @@ func (p *ExecutionPlanner) compileColumn(col *parser.ColumnDefinition) (*createT
|
|||
}
|
||||
}
|
||||
|
||||
switch strings.ToUpper(typeName) {
|
||||
case parser.FieldTypeBool:
|
||||
switch strings.ToLower(typeName) {
|
||||
case dax.BaseTypeBool:
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeBool())
|
||||
case parser.FieldTypeDecimal:
|
||||
case dax.BaseTypeDecimal:
|
||||
// Get the scale value.
|
||||
scale, err = strconv.ParseInt(col.Type.Scale.Value, 10, 64)
|
||||
if err != nil {
|
||||
|
|
@ -201,27 +202,27 @@ func (p *ExecutionPlanner) compileColumn(col *parser.ColumnDefinition) (*createT
|
|||
}
|
||||
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeDecimal(scale, min, max))
|
||||
case parser.FieldTypeID:
|
||||
case dax.BaseTypeID:
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeMutex(cacheType, cacheSize))
|
||||
case parser.FieldTypeIDSet:
|
||||
case dax.BaseTypeIDSet:
|
||||
if timeQuantum != "" {
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeTime(timeQuantum, ttl))
|
||||
} else {
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeSet(cacheType, cacheSize))
|
||||
}
|
||||
case parser.FieldTypeInt:
|
||||
case dax.BaseTypeInt:
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeInt(min.ToInt64(0), max.ToInt64(0)))
|
||||
case parser.FieldTypeString:
|
||||
case dax.BaseTypeString:
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeMutex(cacheType, cacheSize))
|
||||
column.fos = append(column.fos, pilosa.OptFieldKeys())
|
||||
case parser.FieldTypeStringSet:
|
||||
case dax.BaseTypeStringSet:
|
||||
if timeQuantum != "" {
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeTime(timeQuantum, ttl))
|
||||
} else {
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeSet(cacheType, cacheSize))
|
||||
}
|
||||
column.fos = append(column.fos, pilosa.OptFieldKeys())
|
||||
case parser.FieldTypeTimestamp:
|
||||
case dax.BaseTypeTimestamp:
|
||||
column.fos = append(column.fos, pilosa.OptFieldTypeTimestamp(epoch, timeUnit))
|
||||
}
|
||||
return column, nil
|
||||
|
|
@ -246,7 +247,7 @@ func (p *ExecutionPlanner) analyzeCreateTableStatement(stmt *parser.CreateTableS
|
|||
|
||||
if strings.ToLower(columnName) == "_id" {
|
||||
//check the type
|
||||
if !(strings.EqualFold(typeName, parser.FieldTypeID) || strings.EqualFold(typeName, parser.FieldTypeString)) {
|
||||
if !(strings.EqualFold(typeName, dax.BaseTypeID) || strings.EqualFold(typeName, dax.BaseTypeString)) {
|
||||
return sql3.NewErrTableIDColumnType(col.Type.Name.NamePos.Line, col.Type.Name.NamePos.Column)
|
||||
}
|
||||
//make sure we have no constraints
|
||||
|
|
@ -324,7 +325,7 @@ func (p *ExecutionPlanner) analyzeColumn(typeName string, col *parser.ColumnDefi
|
|||
switch c := con.(type) {
|
||||
case *parser.CacheTypeConstraint:
|
||||
//make sure we have a set or mutex type
|
||||
if !(strings.EqualFold(typeName, parser.FieldTypeString) || strings.EqualFold(typeName, parser.FieldTypeStringSet) || strings.EqualFold(typeName, parser.FieldTypeID) || strings.EqualFold(typeName, parser.FieldTypeIDSet)) {
|
||||
if !(strings.EqualFold(typeName, dax.BaseTypeString) || strings.EqualFold(typeName, dax.BaseTypeStringSet) || strings.EqualFold(typeName, dax.BaseTypeID) || strings.EqualFold(typeName, dax.BaseTypeIDSet)) {
|
||||
return sql3.NewErrBadColumnConstraint(col.Name.NamePos.Line, col.Name.NamePos.Column, "CACHETYPE", typeName)
|
||||
}
|
||||
//check the type of the expression for SIZE
|
||||
|
|
@ -362,7 +363,7 @@ func (p *ExecutionPlanner) analyzeColumn(typeName string, col *parser.ColumnDefi
|
|||
|
||||
case *parser.TimeUnitConstraint:
|
||||
//make sure we have an timestamp type
|
||||
if !strings.EqualFold(typeName, parser.FieldTypeTimestamp) {
|
||||
if !strings.EqualFold(typeName, dax.BaseTypeTimestamp) {
|
||||
return sql3.NewErrBadColumnConstraint(col.Name.NamePos.Line, col.Name.NamePos.Column, "TIMEUNIT", typeName)
|
||||
}
|
||||
//check the type of the expression
|
||||
|
|
@ -384,7 +385,7 @@ func (p *ExecutionPlanner) analyzeColumn(typeName string, col *parser.ColumnDefi
|
|||
|
||||
case *parser.TimeQuantumConstraint:
|
||||
//make sure we have a set type
|
||||
if !(strings.EqualFold(typeName, parser.FieldTypeStringSet) || strings.EqualFold(typeName, parser.FieldTypeIDSet)) {
|
||||
if !(strings.EqualFold(typeName, dax.BaseTypeStringSet) || strings.EqualFold(typeName, dax.BaseTypeIDSet)) {
|
||||
return sql3.NewErrBadColumnConstraint(col.Name.NamePos.Line, col.Name.NamePos.Column, "TIMEQUANTUM", typeName)
|
||||
}
|
||||
//check the type of the expression
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ func (p *ExecutionPlanner) analyzeInsertStatement(stmt *parser.InsertStatement)
|
|||
|
||||
// Type check against same ordinal position in column type list.
|
||||
if !typesAreAssignmentCompatible(typeNames[i], e.DataType()) {
|
||||
return sql3.NewErrTypeAssignmentIncompatible(expr.Pos().Line, expr.Pos().Column, e.DataType().TypeName(), typeNames[i].TypeName())
|
||||
return sql3.NewErrTypeAssignmentIncompatible(expr.Pos().Line, expr.Pos().Column, e.DataType().TypeDescription(), typeNames[i].TypeDescription())
|
||||
}
|
||||
|
||||
tuple.Exprs[i] = e
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package planner
|
|||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
pilosa "github.com/featurebasedb/featurebase/v3"
|
||||
"github.com/featurebasedb/featurebase/v3/sql3"
|
||||
|
|
@ -18,32 +19,61 @@ func (p *ExecutionPlanner) compileShowTablesStatement(stmt parser.Statement) (ty
|
|||
return nil, errors.Wrap(err, "getting schema")
|
||||
}
|
||||
|
||||
columns := []types.PlanExpression{&qualifiedRefPlanExpression{
|
||||
tableName: "fb$tables",
|
||||
columnName: "name",
|
||||
columnIndex: 0,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$tables",
|
||||
columnName: "created_at",
|
||||
columnIndex: 1,
|
||||
dataType: parser.NewDataTypeTimestamp(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$tables",
|
||||
columnName: "track_existence",
|
||||
columnIndex: 2,
|
||||
dataType: parser.NewDataTypeBool(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$tables",
|
||||
columnName: "keys",
|
||||
columnIndex: 3,
|
||||
dataType: parser.NewDataTypeBool(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$tables",
|
||||
columnName: "shard_width",
|
||||
columnIndex: 4,
|
||||
dataType: parser.NewDataTypeInt(),
|
||||
}}
|
||||
columns := []types.PlanExpression{
|
||||
&qualifiedRefPlanExpression{
|
||||
tableName: "fb_tables",
|
||||
columnName: "_id",
|
||||
columnIndex: 0,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
},
|
||||
&qualifiedRefPlanExpression{
|
||||
tableName: "fb_tables",
|
||||
columnName: "name",
|
||||
columnIndex: 1,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
},
|
||||
&qualifiedRefPlanExpression{
|
||||
tableName: "fb_tables",
|
||||
columnName: "owner",
|
||||
columnIndex: 2,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
},
|
||||
&qualifiedRefPlanExpression{
|
||||
tableName: "fb_tables",
|
||||
columnName: "last_updated_user",
|
||||
columnIndex: 3,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
},
|
||||
&qualifiedRefPlanExpression{
|
||||
tableName: "fb_tables",
|
||||
columnName: "created_at",
|
||||
columnIndex: 4,
|
||||
dataType: parser.NewDataTypeTimestamp(),
|
||||
},
|
||||
&qualifiedRefPlanExpression{
|
||||
tableName: "fb_tables",
|
||||
columnName: "track_existence",
|
||||
columnIndex: 5,
|
||||
dataType: parser.NewDataTypeBool(),
|
||||
},
|
||||
&qualifiedRefPlanExpression{
|
||||
tableName: "fb_tables",
|
||||
columnName: "keys",
|
||||
columnIndex: 6,
|
||||
dataType: parser.NewDataTypeBool(),
|
||||
},
|
||||
&qualifiedRefPlanExpression{
|
||||
tableName: "fb_tables",
|
||||
columnName: "shard_width",
|
||||
columnIndex: 7,
|
||||
dataType: parser.NewDataTypeInt(),
|
||||
},
|
||||
&qualifiedRefPlanExpression{
|
||||
tableName: "fb_tables",
|
||||
columnName: "description",
|
||||
columnIndex: 8,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}}
|
||||
|
||||
return NewPlanOpQuery(p, NewPlanOpProjection(columns, NewPlanOpFeatureBaseTables(indexInfo)), p.sql), nil
|
||||
}
|
||||
|
|
@ -59,76 +89,127 @@ func (p *ExecutionPlanner) compileShowColumnsStatement(stmt *parser.ShowColumnsS
|
|||
}
|
||||
|
||||
columns := []types.PlanExpression{&qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "name",
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "_id",
|
||||
columnIndex: 0,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}, &qualifiedRefPlanExpression{ // the SQL3 data type description
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "type",
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "name",
|
||||
columnIndex: 1,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}, &qualifiedRefPlanExpression{ // the FeatureBase 'native' data type description
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "internal_type",
|
||||
}, &qualifiedRefPlanExpression{ // the SQL3 data type description
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "type",
|
||||
columnIndex: 2,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "created_at",
|
||||
}, &qualifiedRefPlanExpression{ // the FeatureBase 'native' data type description
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "internal_type",
|
||||
columnIndex: 3,
|
||||
dataType: parser.NewDataTypeTimestamp(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "keys",
|
||||
columnIndex: 4,
|
||||
dataType: parser.NewDataTypeBool(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "cache_type",
|
||||
columnIndex: 5,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "cache_size",
|
||||
columnIndex: 6,
|
||||
dataType: parser.NewDataTypeInt(),
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "created_at",
|
||||
columnIndex: 4,
|
||||
dataType: parser.NewDataTypeTimestamp(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "scale",
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "keys",
|
||||
columnIndex: 5,
|
||||
dataType: parser.NewDataTypeBool(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "cache_type",
|
||||
columnIndex: 6,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "cache_size",
|
||||
columnIndex: 7,
|
||||
dataType: parser.NewDataTypeInt(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "min",
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "scale",
|
||||
columnIndex: 8,
|
||||
dataType: parser.NewDataTypeInt(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "max",
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "min",
|
||||
columnIndex: 9,
|
||||
dataType: parser.NewDataTypeInt(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "timeunit",
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "max",
|
||||
columnIndex: 10,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "epoch",
|
||||
columnIndex: 11,
|
||||
dataType: parser.NewDataTypeInt(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "timequantum",
|
||||
columnIndex: 12,
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "timeunit",
|
||||
columnIndex: 11,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb$table_columns",
|
||||
columnName: "ttl",
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "epoch",
|
||||
columnIndex: 12,
|
||||
dataType: parser.NewDataTypeInt(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "timequantum",
|
||||
columnIndex: 13,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}, &qualifiedRefPlanExpression{
|
||||
tableName: "fb_table_columns",
|
||||
columnName: "ttl",
|
||||
columnIndex: 14,
|
||||
dataType: parser.NewDataTypeString(),
|
||||
}}
|
||||
|
||||
return NewPlanOpQuery(p, NewPlanOpProjection(columns, NewPlanOpFeatureBaseColumns(index)), p.sql), nil
|
||||
}
|
||||
|
||||
func (p *ExecutionPlanner) compileShowCreateTableStatement(stmt *parser.ShowCreateTableStatement) (_ types.PlanOperator, err error) {
|
||||
tableName := parser.IdentName(stmt.TableName)
|
||||
_, err = p.schemaAPI.IndexInfo(context.Background(), tableName)
|
||||
if err != nil {
|
||||
if errors.Is(err, pilosa.ErrIndexNotFound) {
|
||||
return nil, sql3.NewErrTableNotFound(stmt.TableName.NamePos.Line, stmt.TableName.NamePos.Column, tableName)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get the system table
|
||||
systemTable, ok := systemTables[fbTableDDL]
|
||||
if !ok {
|
||||
return nil, sql3.NewErrInternalf("unable to find system table fb_table_ddl")
|
||||
}
|
||||
|
||||
// make an op for the system table
|
||||
systemTableScan := NewPlanOpSystemTable(p, systemTable)
|
||||
|
||||
// get the columns from the schmema
|
||||
columns := systemTable.schema
|
||||
|
||||
// get the ref name column and build projections
|
||||
projections := make([]types.PlanExpression, 0)
|
||||
var nameRef *qualifiedRefPlanExpression
|
||||
for idx, col := range columns {
|
||||
if strings.EqualFold(col.ColumnName, "name") {
|
||||
nameRef = newQualifiedRefPlanExpression(col.RelationName, col.ColumnName, idx, col.Type)
|
||||
}
|
||||
if strings.EqualFold(col.ColumnName, "ddl") {
|
||||
projections = append(projections, newQualifiedRefPlanExpression(col.RelationName, col.ColumnName, idx, col.Type))
|
||||
}
|
||||
}
|
||||
if nameRef == nil || len(projections) == 0 {
|
||||
return nil, sql3.NewErrInternalf("unable to find system table columns")
|
||||
}
|
||||
|
||||
// make a filter espression
|
||||
filterExpr := newBinOpPlanExpression(nameRef, parser.EQ, newStringLiteralPlanExpression(tableName), parser.NewDataTypeBool())
|
||||
|
||||
// make a filter op
|
||||
filter := NewPlanOpFilter(p, filterExpr, systemTableScan)
|
||||
|
||||
return NewPlanOpQuery(p, NewPlanOpProjection(projections, filter), p.sql), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ func (p *ExecutionPlanner) CompilePlan(ctx context.Context, stmt parser.Statemen
|
|||
rootOperator, err = p.compileShowTablesStatement(stmt)
|
||||
case *parser.ShowColumnsStatement:
|
||||
rootOperator, err = p.compileShowColumnsStatement(stmt)
|
||||
case *parser.ShowCreateTableStatement:
|
||||
rootOperator, err = p.compileShowCreateTableStatement(stmt)
|
||||
case *parser.CreateTableStatement:
|
||||
rootOperator, err = p.compileCreateTableStatement(stmt)
|
||||
case *parser.AlterTableStatement:
|
||||
|
|
@ -96,6 +98,8 @@ func (p *ExecutionPlanner) analyzePlan(stmt parser.Statement) error {
|
|||
return nil
|
||||
case *parser.ShowColumnsStatement:
|
||||
return nil
|
||||
case *parser.ShowCreateTableStatement:
|
||||
return nil
|
||||
case *parser.CreateTableStatement:
|
||||
return p.analyzeCreateTableStatement(stmt)
|
||||
case *parser.AlterTableStatement:
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ func coerceValue(sourceType parser.ExprDataType, targetType parser.ExprDataType,
|
|||
} else if tm, err := time.ParseInLocation("2006-01-02", val, time.UTC); err == nil {
|
||||
return tm, nil
|
||||
} else {
|
||||
return nil, sql3.NewErrInvalidTypeCoercion(0, 0, val, targetType.TypeName())
|
||||
return nil, sql3.NewErrInvalidTypeCoercion(0, 0, val, targetType.TypeDescription())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ func coerceValue(sourceType parser.ExprDataType, targetType parser.ExprDataType,
|
|||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled source type '%T'", sourceType)
|
||||
}
|
||||
return nil, sql3.NewErrTypeMismatch(atPos.Line, atPos.Column, targetType.TypeName(), sourceType.TypeName())
|
||||
return nil, sql3.NewErrTypeMismatch(atPos.Line, atPos.Column, targetType.TypeDescription(), sourceType.TypeDescription())
|
||||
}
|
||||
|
||||
// unaryOpPlanExpression is a unary op
|
||||
|
|
@ -173,7 +173,7 @@ func (n *unaryOpPlanExpression) String() string {
|
|||
func (n *unaryOpPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["op"] = n.op
|
||||
result["rhs"] = n.rhs.Plan()
|
||||
return result
|
||||
|
|
@ -649,7 +649,7 @@ func (n *binOpPlanExpression) Evaluate(currentRow []interface{}) (interface{}, e
|
|||
return nil, sql3.NewErrInternalf("unexpected type conversion error '%t', '%t'", nlok, nrok)
|
||||
|
||||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled type '%s'", coercedDataType.TypeName())
|
||||
return nil, sql3.NewErrInternalf("unhandled type '%s'", coercedDataType.TypeDescription())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -664,7 +664,7 @@ func (n *binOpPlanExpression) String() string {
|
|||
func (n *binOpPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["op"] = n.op
|
||||
result["lhs"] = n.lhs.Plan()
|
||||
result["rhs"] = n.rhs.Plan()
|
||||
|
|
@ -735,7 +735,7 @@ func (n *rangePlanExpression) String() string {
|
|||
func (n *rangePlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["lhs"] = n.lhs.Plan()
|
||||
result["rhs"] = n.rhs.Plan()
|
||||
return result
|
||||
|
|
@ -950,7 +950,7 @@ func (n *casePlanExpression) String() string {
|
|||
func (n *casePlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
if n.baseExpr != nil {
|
||||
result["baseExpr"] = n.baseExpr.Plan()
|
||||
}
|
||||
|
|
@ -1035,7 +1035,7 @@ func (n *caseBlockPlanExpression) String() string {
|
|||
func (n *caseBlockPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["condition"] = n.condition.Plan()
|
||||
result["body"] = n.body.Plan()
|
||||
return result
|
||||
|
|
@ -1104,7 +1104,7 @@ func (n *subqueryPlanExpression) String() string {
|
|||
func (n *subqueryPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["subquery"] = n.op.Plan()
|
||||
return result
|
||||
}
|
||||
|
|
@ -1212,7 +1212,7 @@ func (n *betweenOpPlanExpression) String() string {
|
|||
func (n *betweenOpPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["lhs"] = n.lhs.Plan()
|
||||
result["rhs"] = n.rhs.Plan()
|
||||
return result
|
||||
|
|
@ -1285,13 +1285,13 @@ func (n *inOpPlanExpression) Evaluate(currentRow []interface{}) (interface{}, er
|
|||
case *parser.DataTypeInt, *parser.DataTypeID:
|
||||
nl, nlok := evalLhs.(int64)
|
||||
if !nlok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
|
||||
for _, lm := range listMembers {
|
||||
l, lok := lm.(int64)
|
||||
if !lok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
if nl == l {
|
||||
result = true
|
||||
|
|
@ -1302,13 +1302,13 @@ func (n *inOpPlanExpression) Evaluate(currentRow []interface{}) (interface{}, er
|
|||
case *parser.DataTypeBool:
|
||||
nl, nlok := evalLhs.(bool)
|
||||
if !nlok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
|
||||
for _, lm := range listMembers {
|
||||
l, lok := lm.(bool)
|
||||
if !lok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
if nl == l {
|
||||
result = true
|
||||
|
|
@ -1319,13 +1319,13 @@ func (n *inOpPlanExpression) Evaluate(currentRow []interface{}) (interface{}, er
|
|||
case *parser.DataTypeDecimal:
|
||||
nl, nlok := evalLhs.(pql.Decimal)
|
||||
if !nlok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
|
||||
for _, lm := range listMembers {
|
||||
l, lok := lm.(pql.Decimal)
|
||||
if !lok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
if nl.EqualTo(l) {
|
||||
result = true
|
||||
|
|
@ -1336,13 +1336,13 @@ func (n *inOpPlanExpression) Evaluate(currentRow []interface{}) (interface{}, er
|
|||
case *parser.DataTypeIDSet:
|
||||
nl, nlok := evalLhs.([]int64)
|
||||
if !nlok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
|
||||
for _, lm := range listMembers {
|
||||
l, lok := lm.([]int64)
|
||||
if !lok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
if intSetContainsAll(nl, l) {
|
||||
result = true
|
||||
|
|
@ -1353,13 +1353,13 @@ func (n *inOpPlanExpression) Evaluate(currentRow []interface{}) (interface{}, er
|
|||
case *parser.DataTypeString:
|
||||
nl, nlok := evalLhs.(string)
|
||||
if !nlok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
|
||||
for _, lm := range listMembers {
|
||||
l, lok := lm.(string)
|
||||
if !lok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
if nl == l {
|
||||
result = true
|
||||
|
|
@ -1370,13 +1370,13 @@ func (n *inOpPlanExpression) Evaluate(currentRow []interface{}) (interface{}, er
|
|||
case *parser.DataTypeStringSet:
|
||||
nl, nlok := evalLhs.([]string)
|
||||
if !nlok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
|
||||
for _, lm := range listMembers {
|
||||
l, lok := lm.([]string)
|
||||
if !lok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
if stringSetContainsAll(nl, l) {
|
||||
result = true
|
||||
|
|
@ -1387,13 +1387,13 @@ func (n *inOpPlanExpression) Evaluate(currentRow []interface{}) (interface{}, er
|
|||
case *parser.DataTypeTimestamp:
|
||||
nl, nlok := evalLhs.(time.Time)
|
||||
if !nlok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert lhs expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
|
||||
for _, lm := range listMembers {
|
||||
l, lok := lm.(time.Time)
|
||||
if !lok {
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeName())
|
||||
return nil, sql3.NewErrInternalf("unable to convert list expression to type '%s'", n.lhs.Type().TypeDescription())
|
||||
}
|
||||
if nl == l {
|
||||
result = true
|
||||
|
|
@ -1430,7 +1430,7 @@ func (n *inOpPlanExpression) String() string {
|
|||
func (n *inOpPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["lhs"] = n.lhs.Plan()
|
||||
result["rhs"] = n.rhs.Plan()
|
||||
return result
|
||||
|
|
@ -1500,7 +1500,7 @@ func (n *callPlanExpression) Plan() map[string]interface{} {
|
|||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["name"] = n.name
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
ps := make([]interface{}, 0)
|
||||
for _, e := range n.args {
|
||||
ps = append(ps, e.Plan())
|
||||
|
|
@ -1555,7 +1555,7 @@ func (n *aliasPlanExpression) String() string {
|
|||
func (n *aliasPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["aliasName"] = n.aliasName
|
||||
result["expr"] = n.expr.Plan()
|
||||
return result
|
||||
|
|
@ -1651,7 +1651,7 @@ func (n *qualifiedRefPlanExpression) Plan() map[string]interface{} {
|
|||
result["tableName"] = n.tableName
|
||||
result["columnName"] = n.columnName
|
||||
result["columnIndex"] = n.columnIndex
|
||||
result["dataType"] = n.dataType.TypeName()
|
||||
result["dataType"] = n.dataType.TypeDescription()
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
@ -1711,7 +1711,7 @@ func (n *variableRefPlanExpression) Plan() map[string]interface{} {
|
|||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["name"] = n.name
|
||||
result["dataType"] = n.dataType.TypeName()
|
||||
result["dataType"] = n.dataType.TypeDescription()
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
@ -1745,7 +1745,7 @@ func (n *nullLiteralPlanExpression) String() string {
|
|||
func (n *nullLiteralPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
@ -1783,7 +1783,7 @@ func (n *intLiteralPlanExpression) String() string {
|
|||
func (n *intLiteralPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["value"] = n.value
|
||||
return result
|
||||
}
|
||||
|
|
@ -1823,7 +1823,7 @@ func (n *floatLiteralPlanExpression) String() string {
|
|||
func (n *floatLiteralPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["value"] = n.value
|
||||
return result
|
||||
}
|
||||
|
|
@ -1862,7 +1862,7 @@ func (n *boolLiteralPlanExpression) String() string {
|
|||
func (n *boolLiteralPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["value"] = n.value
|
||||
return result
|
||||
}
|
||||
|
|
@ -1901,7 +1901,7 @@ func (n *dateLiteralPlanExpression) String() string {
|
|||
func (n *dateLiteralPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["value"] = n.value
|
||||
return result
|
||||
}
|
||||
|
|
@ -1940,7 +1940,7 @@ func (n *stringLiteralPlanExpression) String() string {
|
|||
func (n *stringLiteralPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["value"] = n.value
|
||||
return result
|
||||
}
|
||||
|
|
@ -2158,13 +2158,13 @@ func (n *castPlanExpression) Type() parser.ExprDataType {
|
|||
}
|
||||
|
||||
func (n *castPlanExpression) String() string {
|
||||
return fmt.Sprintf("cast(%s as %s)", n.lhs.String(), n.targetType.TypeName())
|
||||
return fmt.Sprintf("cast(%s as %s)", n.lhs.String(), n.targetType.TypeDescription())
|
||||
}
|
||||
|
||||
func (n *castPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["lhs"] = n.lhs.Plan()
|
||||
return result
|
||||
}
|
||||
|
|
@ -2346,7 +2346,7 @@ func (n *exprTupleLiteralPlanExpression) Evaluate(currentRow []interface{}) (int
|
|||
// if it is a string, do a coercion
|
||||
if val, ok := timestampEval.(string); ok {
|
||||
if tm, err := timestampFromString(val); err != nil {
|
||||
return nil, sql3.NewErrInvalidTypeCoercion(0, 0, val, n.members[0].Type().TypeName())
|
||||
return nil, sql3.NewErrInvalidTypeCoercion(0, 0, val, n.members[0].Type().TypeDescription())
|
||||
} else {
|
||||
timestampEval = tm
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ func TestExpressions(t *testing.T) {
|
|||
assert.Equal(t, slop.String(), "'foo'")
|
||||
|
||||
ctop := newCastPlanExpression(newIntLiteralPlanExpression(10), parser.NewDataTypeString())
|
||||
assert.Equal(t, ctop.String(), "cast(10 as STRING)")
|
||||
assert.Equal(t, ctop.String(), "cast(10 as string)")
|
||||
|
||||
elop := newExprListExpression([]types.PlanExpression{newStringLiteralPlanExpression("foo"), newStringLiteralPlanExpression("bar")})
|
||||
assert.Equal(t, elop.String(), "('foo', 'bar')")
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ func (n *countPlanExpression) String() string {
|
|||
func (n *countPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["arg"] = n.arg.Plan()
|
||||
return result
|
||||
}
|
||||
|
|
@ -194,7 +194,7 @@ func (n *countDistinctPlanExpression) String() string {
|
|||
func (n *countDistinctPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["arg"] = n.arg.Plan()
|
||||
return result
|
||||
}
|
||||
|
|
@ -327,7 +327,7 @@ func (n *sumPlanExpression) String() string {
|
|||
func (n *sumPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["arg"] = n.arg.Plan()
|
||||
return result
|
||||
}
|
||||
|
|
@ -500,7 +500,7 @@ func (n *avgPlanExpression) String() string {
|
|||
func (n *avgPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["arg"] = n.arg.Plan()
|
||||
return result
|
||||
}
|
||||
|
|
@ -641,7 +641,7 @@ func (n *minPlanExpression) String() string {
|
|||
func (n *minPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["arg"] = n.arg.Plan()
|
||||
return result
|
||||
}
|
||||
|
|
@ -783,7 +783,7 @@ func (n *maxPlanExpression) String() string {
|
|||
func (n *maxPlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["arg"] = n.arg.Plan()
|
||||
return result
|
||||
}
|
||||
|
|
@ -855,7 +855,7 @@ func (n *percentilePlanExpression) String() string {
|
|||
func (n *percentilePlanExpression) Plan() map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
result["_expr"] = fmt.Sprintf("%T", n)
|
||||
result["dataType"] = n.Type().TypeName()
|
||||
result["dataType"] = n.Type().TypeDescription()
|
||||
result["arg"] = n.arg.Plan()
|
||||
result["ntharg"] = n.nthArg.Plan()
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -279,14 +279,14 @@ func (p *ExecutionPlanner) analyzeExpression(expr parser.Expr, scope parser.Stat
|
|||
//now check all the other blocks to make sure that each body is assignment compatible with that type
|
||||
for _, blk := range e.Blocks {
|
||||
if !typesAreAssignmentCompatible(caseType, blk.Body.DataType()) {
|
||||
return nil, sql3.NewErrTypeAssignmentIncompatible(blk.Body.Pos().Line, blk.Body.Pos().Column, caseType.TypeName(), blk.Body.DataType().TypeName())
|
||||
return nil, sql3.NewErrTypeAssignmentIncompatible(blk.Body.Pos().Line, blk.Body.Pos().Column, caseType.TypeDescription(), blk.Body.DataType().TypeDescription())
|
||||
}
|
||||
}
|
||||
|
||||
//if there is an else check that too
|
||||
if e.ElseExpr != nil {
|
||||
if !typesAreAssignmentCompatible(caseType, e.ElseExpr.DataType()) {
|
||||
return nil, sql3.NewErrTypeAssignmentIncompatible(e.ElseExpr.Pos().Line, e.ElseExpr.Pos().Column, caseType.TypeName(), e.ElseExpr.DataType().TypeName())
|
||||
return nil, sql3.NewErrTypeAssignmentIncompatible(e.ElseExpr.Pos().Line, e.ElseExpr.Pos().Column, caseType.TypeDescription(), e.ElseExpr.DataType().TypeDescription())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -720,7 +720,7 @@ func (p *ExecutionPlanner) analyzeRangeExpression(expr *parser.Range, scope pars
|
|||
return nil, sql3.NewErrTypeCannotBeUsedAsRangeSubscript(expr.Y.Pos().Line, expr.Y.Pos().Column, expr.Y.DataType().TypeDescription())
|
||||
}
|
||||
if !typesOfRangeBoundsAreTheSame(expr.X.DataType(), expr.Y.DataType()) {
|
||||
return nil, sql3.NewErrIncompatibleTypesForRangeSubscripts(expr.Pos().Line, expr.Pos().Column, expr.X.DataType().TypeName(), expr.Y.DataType().TypeName())
|
||||
return nil, sql3.NewErrIncompatibleTypesForRangeSubscripts(expr.Pos().Line, expr.Pos().Column, expr.X.DataType().TypeDescription(), expr.Y.DataType().TypeDescription())
|
||||
}
|
||||
|
||||
expr.ResultDataType = parser.NewDataTypeRange(expr.X.DataType())
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ func (p *ExecutionPlanner) analyzeCallExpression(call *parser.Call, scope parser
|
|||
//second column is the nth value
|
||||
targetType := parser.NewDataTypeDecimal(4)
|
||||
if !typesAreAssignmentCompatible(targetType, call.Args[1].DataType()) {
|
||||
return nil, sql3.NewErrParameterTypeMistmatch(call.Args[1].Pos().Line, call.Args[1].Pos().Column, targetType.TypeName(), call.Args[1].DataType().TypeName())
|
||||
return nil, sql3.NewErrParameterTypeMistmatch(call.Args[1].Pos().Line, call.Args[1].Pos().Column, targetType.TypeDescription(), call.Args[1].DataType().TypeDescription())
|
||||
}
|
||||
|
||||
//make sure it's literal
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ func (p *ExecutionPlanner) generatePQLCallFromBinaryExpr(ctx context.Context, ex
|
|||
if strings.EqualFold(lhs.columnName, "_id") {
|
||||
return nil, sql3.NewErrInvalidColumnInFilterExpression(0, 0, "_id", "is/is not null")
|
||||
}
|
||||
return nil, sql3.NewErrInvalidTypeInFilterExpression(0, 0, typ.TypeName(), "is/is not null")
|
||||
return nil, sql3.NewErrInvalidTypeInFilterExpression(0, 0, typ.TypeDescription(), "is/is not null")
|
||||
|
||||
case *parser.DataTypeInt, *parser.DataTypeDecimal, *parser.DataTypeTimestamp:
|
||||
return &pql.Call{
|
||||
|
|
@ -239,7 +239,7 @@ func (p *ExecutionPlanner) generatePQLCallFromBinaryExpr(ctx context.Context, ex
|
|||
}, nil
|
||||
|
||||
default:
|
||||
return nil, sql3.NewErrInvalidTypeInFilterExpression(0, 0, typ.TypeName(), "is/is not null")
|
||||
return nil, sql3.NewErrInvalidTypeInFilterExpression(0, 0, typ.TypeDescription(), "is/is not null")
|
||||
}
|
||||
|
||||
case parser.BETWEEN, parser.NOTBETWEEN:
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
pilosa "github.com/featurebasedb/featurebase/v3"
|
||||
"github.com/featurebasedb/featurebase/v3/sql3"
|
||||
"github.com/featurebasedb/featurebase/v3/sql3/parser"
|
||||
pilosa "github.com/molecula/featurebase/v3"
|
||||
"github.com/molecula/featurebase/v3/dax"
|
||||
"github.com/molecula/featurebase/v3/sql3"
|
||||
"github.com/molecula/featurebase/v3/sql3/parser"
|
||||
)
|
||||
|
||||
// takes a *pilosa.FieldInfo and returns a sql data type
|
||||
|
|
@ -75,33 +76,33 @@ func fieldSQLDataType(f *pilosa.FieldInfo) parser.ExprDataType {
|
|||
// resolves type names to type representations
|
||||
func dataTypeFromParserType(typ *parser.Type) (parser.ExprDataType, error) {
|
||||
typeName := parser.IdentName(typ.Name)
|
||||
switch strings.ToUpper(typeName) {
|
||||
case parser.FieldTypeBool:
|
||||
switch strings.ToLower(typeName) {
|
||||
case dax.BaseTypeBool:
|
||||
return parser.NewDataTypeBool(), nil
|
||||
|
||||
case parser.FieldTypeDecimal:
|
||||
case dax.BaseTypeDecimal:
|
||||
scale, err := strconv.Atoi(typ.Scale.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parser.NewDataTypeDecimal(int64(scale)), nil
|
||||
|
||||
case parser.FieldTypeID:
|
||||
case dax.BaseTypeID:
|
||||
return parser.NewDataTypeID(), nil
|
||||
|
||||
case parser.FieldTypeIDSet:
|
||||
case dax.BaseTypeIDSet:
|
||||
return parser.NewDataTypeIDSet(), nil
|
||||
|
||||
case parser.FieldTypeInt:
|
||||
case dax.BaseTypeInt:
|
||||
return parser.NewDataTypeInt(), nil
|
||||
|
||||
case parser.FieldTypeString:
|
||||
case dax.BaseTypeString:
|
||||
return parser.NewDataTypeString(), nil
|
||||
|
||||
case parser.FieldTypeStringSet:
|
||||
case dax.BaseTypeStringSet:
|
||||
return parser.NewDataTypeStringSet(), nil
|
||||
|
||||
case parser.FieldTypeTimestamp:
|
||||
case dax.BaseTypeTimestamp:
|
||||
return parser.NewDataTypeTimestamp(), nil
|
||||
|
||||
default:
|
||||
|
|
@ -603,7 +604,7 @@ func typesCoercedForArithmeticOperator(testTypeL parser.ExprDataType, testTypeR
|
|||
}
|
||||
|
||||
}
|
||||
return nil, sql3.NewErrTypeMismatch(atPos.Line, atPos.Column, testTypeL.TypeName(), testTypeR.TypeName())
|
||||
return nil, sql3.NewErrTypeMismatch(atPos.Line, atPos.Column, testTypeL.TypeDescription(), testTypeR.TypeDescription())
|
||||
}
|
||||
|
||||
// returns the target type given two operand types for a bitwise operation (or an error)
|
||||
|
|
@ -635,7 +636,7 @@ func typesCoercedForBitwiseOperator(testTypeL parser.ExprDataType, testTypeR par
|
|||
return parser.NewDataTypeDecimal(rhsType.Scale), nil
|
||||
}
|
||||
}
|
||||
return nil, sql3.NewErrTypeMismatch(atPos.Line, atPos.Column, testTypeL.TypeName(), testTypeR.TypeName())
|
||||
return nil, sql3.NewErrTypeMismatch(atPos.Line, atPos.Column, testTypeL.TypeDescription(), testTypeR.TypeDescription())
|
||||
}
|
||||
|
||||
// returns the target type given two operand types type coercion operation (or an error)
|
||||
|
|
@ -709,7 +710,7 @@ func typeCoerceType(testTypeL parser.ExprDataType, testTypeR parser.ExprDataType
|
|||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled lhs type '%t'", testTypeL)
|
||||
}
|
||||
return nil, sql3.NewErrTypeMismatch(atPos.Line, atPos.Line, testTypeL.TypeName(), testTypeR.TypeName())
|
||||
return nil, sql3.NewErrTypeMismatch(atPos.Line, atPos.Line, testTypeL.TypeDescription(), testTypeR.TypeDescription())
|
||||
}
|
||||
|
||||
// returns true if source type can be cast to target type
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ func (p *ExecutionPlanner) analyzeFunctionDatePart(call *parser.Call, scope pars
|
|||
// interval
|
||||
intervalType := parser.NewDataTypeString()
|
||||
if !typesAreAssignmentCompatible(intervalType, call.Args[0].DataType()) {
|
||||
return nil, sql3.NewErrParameterTypeMistmatch(call.Args[0].Pos().Line, call.Args[0].Pos().Column, call.Args[0].DataType().TypeName(), intervalType.TypeName())
|
||||
return nil, sql3.NewErrParameterTypeMistmatch(call.Args[0].Pos().Line, call.Args[0].Pos().Column, call.Args[0].DataType().TypeDescription(), intervalType.TypeDescription())
|
||||
}
|
||||
|
||||
// date
|
||||
dateType := parser.NewDataTypeTimestamp()
|
||||
if !typesAreAssignmentCompatible(dateType, call.Args[1].DataType()) {
|
||||
return nil, sql3.NewErrParameterTypeMistmatch(call.Args[1].Pos().Line, call.Args[1].Pos().Column, call.Args[1].DataType().TypeName(), dateType.TypeName())
|
||||
return nil, sql3.NewErrParameterTypeMistmatch(call.Args[1].Pos().Line, call.Args[1].Pos().Column, call.Args[1].DataType().TypeDescription(), dateType.TypeDescription())
|
||||
}
|
||||
|
||||
//return int
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ func (p *PlanOpBulkInsert) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
result["tableName"] = p.tableName
|
||||
|
|
@ -99,7 +99,7 @@ func (p *PlanOpBulkInsert) Plan() map[string]interface{} {
|
|||
for _, m := range p.options.mapExpressions {
|
||||
mapItem := make(map[string]interface{})
|
||||
options["name"] = m.name
|
||||
options["type"] = m.colType.TypeName()
|
||||
options["type"] = m.colType.TypeDescription()
|
||||
options["expr"] = m.expr.Plan()
|
||||
mapList = append(mapList, mapItem)
|
||||
}
|
||||
|
|
@ -274,15 +274,15 @@ func (i *bulkInsertSourceCSVRowIter) Next(ctx context.Context) (types.Row, error
|
|||
case *parser.DataTypeID, *parser.DataTypeInt:
|
||||
intVal, err := strconv.ParseInt(evalValue, 10, 64)
|
||||
if err != nil {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
result[idx] = intVal
|
||||
|
||||
case *parser.DataTypeIDSet:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeDescription())
|
||||
|
||||
case *parser.DataTypeStringSet:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeDescription())
|
||||
|
||||
case *parser.DataTypeTimestamp:
|
||||
intVal, err := strconv.ParseInt(evalValue, 10, 64)
|
||||
|
|
@ -294,7 +294,7 @@ func (i *bulkInsertSourceCSVRowIter) Next(ctx context.Context) (types.Row, error
|
|||
} else if tm, err := time.ParseInLocation("2006-01-02", evalValue, time.UTC); err == nil {
|
||||
result[idx] = tm
|
||||
} else {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
}
|
||||
result[idx] = time.UnixMilli(intVal).UTC()
|
||||
|
|
@ -305,14 +305,14 @@ func (i *bulkInsertSourceCSVRowIter) Next(ctx context.Context) (types.Row, error
|
|||
case *parser.DataTypeBool:
|
||||
bval, err := strconv.ParseInt(evalValue, 10, 64)
|
||||
if err != nil {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
result[idx] = bval
|
||||
|
||||
case *parser.DataTypeDecimal:
|
||||
dval, err := pql.ParseDecimal(evalValue)
|
||||
if err != nil {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, evalValue, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
result[idx] = dval
|
||||
|
||||
|
|
@ -494,24 +494,24 @@ func (i *bulkInsertSourceNDJsonRowIter) Next(ctx context.Context) (types.Row, er
|
|||
if v == float64(int64(v)) {
|
||||
result[idx] = int64(v)
|
||||
} else {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
|
||||
case []interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case string:
|
||||
intVal, err := strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
result[idx] = intVal
|
||||
|
||||
case bool:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled type '%T'", evalValue)
|
||||
|
|
@ -520,31 +520,31 @@ func (i *bulkInsertSourceNDJsonRowIter) Next(ctx context.Context) (types.Row, er
|
|||
case *parser.DataTypeIDSet:
|
||||
switch v := evalValue.(type) {
|
||||
case float64:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case []interface{}:
|
||||
setValue := make([]int64, 0)
|
||||
for _, i := range v {
|
||||
f, ok := i.(float64)
|
||||
if !ok {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
if f == float64(int64(f)) {
|
||||
setValue = append(setValue, int64(f))
|
||||
} else {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
}
|
||||
result[idx] = setValue
|
||||
|
||||
case string:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case bool:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled type '%T'", evalValue)
|
||||
|
|
@ -553,27 +553,27 @@ func (i *bulkInsertSourceNDJsonRowIter) Next(ctx context.Context) (types.Row, er
|
|||
case *parser.DataTypeStringSet:
|
||||
switch v := evalValue.(type) {
|
||||
case float64:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case []interface{}:
|
||||
setValue := make([]string, 0)
|
||||
for _, i := range v {
|
||||
f, ok := i.(string)
|
||||
if !ok {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
setValue = append(setValue, f)
|
||||
}
|
||||
result[idx] = setValue
|
||||
|
||||
case string:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case bool:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled type '%T'", evalValue)
|
||||
|
|
@ -586,11 +586,11 @@ func (i *bulkInsertSourceNDJsonRowIter) Next(ctx context.Context) (types.Row, er
|
|||
if v == float64(int64(v)) {
|
||||
result[idx] = time.UnixMilli(int64(v)).UTC()
|
||||
} else {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
|
||||
case []interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case string:
|
||||
if tm, err := time.ParseInLocation(time.RFC3339Nano, v, time.UTC); err == nil {
|
||||
|
|
@ -600,14 +600,14 @@ func (i *bulkInsertSourceNDJsonRowIter) Next(ctx context.Context) (types.Row, er
|
|||
} else if tm, err := time.ParseInLocation("2006-01-02", v, time.UTC); err == nil {
|
||||
result[idx] = tm
|
||||
} else {
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
}
|
||||
|
||||
case bool:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled type '%T'", evalValue)
|
||||
|
|
@ -616,19 +616,19 @@ func (i *bulkInsertSourceNDJsonRowIter) Next(ctx context.Context) (types.Row, er
|
|||
case *parser.DataTypeString:
|
||||
switch v := evalValue.(type) {
|
||||
case float64:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case []interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case string:
|
||||
result[idx] = v
|
||||
|
||||
case bool:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled type '%T'", evalValue)
|
||||
|
|
@ -637,19 +637,19 @@ func (i *bulkInsertSourceNDJsonRowIter) Next(ctx context.Context) (types.Row, er
|
|||
case *parser.DataTypeBool:
|
||||
switch v := evalValue.(type) {
|
||||
case float64:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case []interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case string:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case bool:
|
||||
result[idx] = v
|
||||
|
||||
case interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled type '%T'", evalValue)
|
||||
|
|
@ -661,16 +661,16 @@ func (i *bulkInsertSourceNDJsonRowIter) Next(ctx context.Context) (types.Row, er
|
|||
result[idx] = pql.FromFloat64(v)
|
||||
|
||||
case []interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case string:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case bool:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
case interface{}:
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeName())
|
||||
return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription())
|
||||
|
||||
default:
|
||||
return nil, sql3.NewErrInternalf("unhandled type '%T'", evalValue)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func (p *PlanOpCreateTable) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
ps := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = ps
|
||||
result["name"] = p.tableName
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func (p *PlanOpDropTable) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
ps := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = ps
|
||||
result["tableName"] = p.index.Name
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ func (p *PlanOpFeatureBaseColumns) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
ps := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = ps
|
||||
return result
|
||||
|
|
@ -52,72 +52,77 @@ func (p *PlanOpFeatureBaseColumns) Warnings() []string {
|
|||
func (p *PlanOpFeatureBaseColumns) Schema() types.Schema {
|
||||
return types.Schema{
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "_id",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "name",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "type",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "internal_type",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "created_at",
|
||||
Type: parser.NewDataTypeTimestamp(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "keys",
|
||||
Type: parser.NewDataTypeBool(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "cache_type",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "cache_size",
|
||||
Type: parser.NewDataTypeInt(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "scale",
|
||||
Type: parser.NewDataTypeInt(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "min",
|
||||
Type: parser.NewDataTypeInt(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "max",
|
||||
Type: parser.NewDataTypeInt(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "timeunit",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "epoch",
|
||||
Type: parser.NewDataTypeInt(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "timequantum",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$table_columns",
|
||||
RelationName: "fb_table_columns",
|
||||
ColumnName: "ttl",
|
||||
Type: parser.NewDataTypeInt(),
|
||||
},
|
||||
|
|
@ -153,7 +158,8 @@ func (i *showColumnsRowIter) Next(ctx context.Context) (types.Row, error) {
|
|||
|
||||
row := []interface{}{
|
||||
fields[i.rowIndex].Name,
|
||||
fieldSQLDataType(fields[i.rowIndex]).TypeName(),
|
||||
fields[i.rowIndex].Name,
|
||||
fieldSQLDataType(fields[i.rowIndex]).TypeDescription(),
|
||||
fields[i.rowIndex].Options.Type,
|
||||
tm.Format(time.RFC3339),
|
||||
fields[i.rowIndex].Options.Keys,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ func (p *PlanOpFeatureBaseTables) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
ps := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = ps
|
||||
return result
|
||||
|
|
@ -52,30 +52,50 @@ func (p *PlanOpFeatureBaseTables) Warnings() []string {
|
|||
func (p *PlanOpFeatureBaseTables) Schema() types.Schema {
|
||||
return types.Schema{
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$tables",
|
||||
RelationName: "fb_tables",
|
||||
ColumnName: "_id",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb_tables",
|
||||
ColumnName: "name",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$tables",
|
||||
RelationName: "fb_tables",
|
||||
ColumnName: "owner",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb_tables",
|
||||
ColumnName: "last_updated_user",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb_tables",
|
||||
ColumnName: "created_at",
|
||||
Type: parser.NewDataTypeTimestamp(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$tables",
|
||||
RelationName: "fb_tables",
|
||||
ColumnName: "track_existence",
|
||||
Type: parser.NewDataTypeBool(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$tables",
|
||||
RelationName: "fb_tables",
|
||||
ColumnName: "keys",
|
||||
Type: parser.NewDataTypeBool(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb$tables",
|
||||
RelationName: "fb_tables",
|
||||
ColumnName: "shard_width",
|
||||
Type: parser.NewDataTypeInt(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: "fb_tables",
|
||||
ColumnName: "description",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -105,10 +125,14 @@ func (i *showTablesRowIter) Next(ctx context.Context) (types.Row, error) {
|
|||
tm := time.Unix(0, i.indexInfo[i.rowIndex].CreatedAt)
|
||||
row := []interface{}{
|
||||
i.indexInfo[i.rowIndex].Name,
|
||||
i.indexInfo[i.rowIndex].Name,
|
||||
i.indexInfo[i.rowIndex].Owner,
|
||||
i.indexInfo[i.rowIndex].LastUpdateUser,
|
||||
tm.Format(time.RFC3339),
|
||||
i.indexInfo[i.rowIndex].Options.TrackExistence,
|
||||
i.indexInfo[i.rowIndex].Options.Keys,
|
||||
i.indexInfo[i.rowIndex].ShardWidth,
|
||||
i.indexInfo[i.rowIndex].Options.Description,
|
||||
}
|
||||
i.rowIndex += 1
|
||||
return row, nil
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ func (p *PlanOpFilter) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
ps := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = ps
|
||||
result["predicate"] = p.Predicate.Plan()
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ func (p *PlanOpGroupBy) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
result["child"] = p.ChildOp.Plan()
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func (p *PlanOpInsert) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
result["tableName"] = p.tableName
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ func (p *PlanOpNestedLoops) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
ps := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = ps
|
||||
result["top"] = p.top.Plan()
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ func (p *PlanOpNullTable) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
ps := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = ps
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ func (n *PlanOpOrderBy) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", n)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range n.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ func (n *PlanOpOrderBy) Plan() map[string]interface{} {
|
|||
for _, e := range n.orderByFields {
|
||||
ps = append(ps, &map[string]interface{}{
|
||||
"index": e.Index,
|
||||
"exprType": e.ExprType.TypeName(),
|
||||
"exprType": e.ExprType.TypeDescription(),
|
||||
"order": e.Order,
|
||||
"nullOrdering": e.NullOrdering,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func (p *PlanOpPQLAggregate) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
ps := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = ps
|
||||
result["tableName"] = p.tableName
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ func (p *PlanOpPQLGroupBy) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
result["tableName"] = p.tableName
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ func (p *PlanOpPQLMultiAggregate) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ func (p *PlanOpPQLMultiGroupBy) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func (p *PlanOpPQLTableScan) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func (p *PlanOpProjection) Plan() map[string]interface{} {
|
|||
result["__op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["__schema"] = sc
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func (p *PlanOpQuery) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func (p *PlanOpRelAlias) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func (p *PlanOpSubquery) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
|
||||
|
|
|
|||
|
|
@ -3,38 +3,25 @@
|
|||
package planner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
pilosa "github.com/featurebasedb/featurebase/v3"
|
||||
"github.com/featurebasedb/featurebase/v3/sql3"
|
||||
"github.com/featurebasedb/featurebase/v3/sql3/parser"
|
||||
"github.com/featurebasedb/featurebase/v3/sql3/planner/types"
|
||||
pilosa "github.com/molecula/featurebase/v3"
|
||||
"github.com/molecula/featurebase/v3/pql"
|
||||
"github.com/molecula/featurebase/v3/sql3"
|
||||
"github.com/molecula/featurebase/v3/sql3/parser"
|
||||
"github.com/molecula/featurebase/v3/sql3/planner/types"
|
||||
)
|
||||
|
||||
//fb_exec_requests
|
||||
// session
|
||||
// user
|
||||
// start_time
|
||||
// end_time
|
||||
// status
|
||||
// plan
|
||||
// wait_type
|
||||
// wait_time
|
||||
// wait_resource
|
||||
// cpu_time
|
||||
// elapsed_time
|
||||
// reads
|
||||
// writes
|
||||
// logical_reads
|
||||
// row_count
|
||||
|
||||
// exclude this file from SonarCloud dupe eval
|
||||
|
||||
const (
|
||||
fbClusterInfo = "fb_cluster_info"
|
||||
fbClusterNodes = "fb_cluster_nodes"
|
||||
fbExecRequests = "fb_exec_requests"
|
||||
|
||||
fbTableDDL = "fb_table_ddl"
|
||||
)
|
||||
|
||||
type systemTable struct {
|
||||
|
|
@ -209,6 +196,27 @@ var systemTables = map[string]*systemTable{
|
|||
},
|
||||
},
|
||||
},
|
||||
|
||||
fbTableDDL: {
|
||||
name: fbTableDDL,
|
||||
schema: types.Schema{
|
||||
&types.PlannerColumn{
|
||||
RelationName: fbTableDDL,
|
||||
ColumnName: "id",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: fbTableDDL,
|
||||
ColumnName: "name",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
&types.PlannerColumn{
|
||||
RelationName: fbTableDDL,
|
||||
ColumnName: "ddl",
|
||||
Type: parser.NewDataTypeString(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// PlanOpSystemTable handles system tables
|
||||
|
|
@ -231,7 +239,7 @@ func (p *PlanOpSystemTable) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
ps := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
ps = append(ps, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = ps
|
||||
return result
|
||||
|
|
@ -271,6 +279,10 @@ func (p *PlanOpSystemTable) Iterator(ctx context.Context, row types.Row) (types.
|
|||
return &fbExecRequestsRowIter{
|
||||
planner: p.planner,
|
||||
}, nil
|
||||
case fbTableDDL:
|
||||
return &fbTableDDLRowIter{
|
||||
planner: p.planner,
|
||||
}, nil
|
||||
default:
|
||||
return nil, sql3.NewErrInternalf("unable to find system table '%s'", p.table.name)
|
||||
}
|
||||
|
|
@ -379,3 +391,136 @@ func (i *fbExecRequestsRowIter) Next(ctx context.Context) (types.Row, error) {
|
|||
}
|
||||
return nil, types.ErrNoMoreRows
|
||||
}
|
||||
|
||||
type fbTableDDLRow struct {
|
||||
id string
|
||||
name string
|
||||
ddl string
|
||||
}
|
||||
|
||||
type fbTableDDLRowIter struct {
|
||||
planner *ExecutionPlanner
|
||||
result []*fbTableDDLRow
|
||||
}
|
||||
|
||||
var _ types.RowIterator = (*fbTableDDLRowIter)(nil)
|
||||
|
||||
func (i *fbTableDDLRowIter) Next(ctx context.Context) (types.Row, error) {
|
||||
if i.result == nil {
|
||||
schema, err := i.planner.schemaAPI.Schema(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
i.result = make([]*fbTableDDLRow, len(schema))
|
||||
|
||||
for idx, table := range schema {
|
||||
|
||||
index, err := i.planner.schemaAPI.IndexInfo(context.Background(), table.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// build the ddl for this table
|
||||
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString("create table ")
|
||||
fmt.Fprintf(&buf, "%s", index.Name)
|
||||
buf.WriteString(" (")
|
||||
|
||||
for idx, col := range index.Fields {
|
||||
if idx > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
fmt.Fprintf(&buf, "%s", col.Name)
|
||||
dataType := fieldSQLDataType(col)
|
||||
fmt.Fprintf(&buf, " %s", dataType.TypeDescription())
|
||||
|
||||
switch dt := dataType.(type) {
|
||||
case *parser.DataTypeID, *parser.DataTypeString:
|
||||
if col.Options.CacheType != pilosa.DefaultCacheType && len(col.Options.CacheType) > 0 {
|
||||
fmt.Fprintf(&buf, " cachetype %s", col.Options.CacheType)
|
||||
}
|
||||
if col.Options.CacheSize != pilosa.DefaultCacheSize && col.Options.CacheSize > 0 {
|
||||
fmt.Fprintf(&buf, " cachesize %d", col.Options.CacheSize)
|
||||
}
|
||||
|
||||
case *parser.DataTypeIDSet, *parser.DataTypeStringSet:
|
||||
if col.Options.CacheType != pilosa.DefaultCacheType && len(col.Options.CacheType) > 0 {
|
||||
fmt.Fprintf(&buf, " cachetype %s", col.Options.CacheType)
|
||||
}
|
||||
if col.Options.CacheSize != pilosa.DefaultCacheSize && col.Options.CacheSize > 0 {
|
||||
fmt.Fprintf(&buf, " cachesize %d", col.Options.CacheSize)
|
||||
}
|
||||
|
||||
case *parser.DataTypeIDSetQuantum, *parser.DataTypeStringSetQuantum:
|
||||
if col.Options.CacheType != pilosa.DefaultCacheType && len(col.Options.CacheType) > 0 {
|
||||
fmt.Fprintf(&buf, " cachetype %s", col.Options.CacheType)
|
||||
}
|
||||
if col.Options.CacheSize != pilosa.DefaultCacheSize && col.Options.CacheSize > 0 {
|
||||
fmt.Fprintf(&buf, " cachesize %d", col.Options.CacheSize)
|
||||
}
|
||||
if !col.Options.TimeQuantum.IsEmpty() {
|
||||
fmt.Fprintf(&buf, " timequantum '%s'", col.Options.TimeQuantum)
|
||||
}
|
||||
if col.Options.TTL > 0 {
|
||||
fmt.Fprintf(&buf, " ttl '%s'", col.Options.TTL.String())
|
||||
}
|
||||
|
||||
case *parser.DataTypeInt:
|
||||
minValue, maxValue := pql.MinMax(0)
|
||||
|
||||
min := col.Options.Min
|
||||
if !min.EqualTo(minValue) {
|
||||
fmt.Fprintf(&buf, " min %d", min.ToInt64(0))
|
||||
}
|
||||
|
||||
max := col.Options.Max
|
||||
if !max.EqualTo(maxValue) {
|
||||
fmt.Fprintf(&buf, " max %d", max.ToInt64(0))
|
||||
}
|
||||
|
||||
case *parser.DataTypeDecimal:
|
||||
minValue, maxValue := pql.MinMax(dt.Scale)
|
||||
|
||||
min := col.Options.Min
|
||||
if !min.EqualTo(minValue) {
|
||||
fmt.Fprintf(&buf, " min %v", min)
|
||||
}
|
||||
|
||||
max := col.Options.Max
|
||||
if !max.EqualTo(maxValue) {
|
||||
fmt.Fprintf(&buf, " max %v", max)
|
||||
}
|
||||
|
||||
case *parser.DataTypeTimestamp:
|
||||
if len(col.Options.TimeUnit) > 0 {
|
||||
fmt.Fprintf(&buf, " timeunit '%s'", col.Options.TimeUnit)
|
||||
}
|
||||
// TODO(pok) how do we get epoch out of col?
|
||||
|
||||
}
|
||||
}
|
||||
buf.WriteString(");")
|
||||
ddl := buf.String()
|
||||
|
||||
i.result[idx] = &fbTableDDLRow{
|
||||
id: table.Name,
|
||||
name: table.Name,
|
||||
ddl: ddl,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(i.result) > 0 {
|
||||
n := i.result[0]
|
||||
row := []interface{}{
|
||||
n.id,
|
||||
n.name,
|
||||
n.ddl,
|
||||
}
|
||||
// Move to next result element.
|
||||
i.result = i.result[1:]
|
||||
return row, nil
|
||||
}
|
||||
return nil, types.ErrNoMoreRows
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ func (p *PlanOpTableValuedFunction) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func (p *PlanOpTop) Plan() map[string]interface{} {
|
|||
result["_op"] = fmt.Sprintf("%T", p)
|
||||
sc := make([]string, 0)
|
||||
for _, e := range p.Schema() {
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeName()))
|
||||
sc = append(sc, fmt.Sprintf("'%s', '%s', '%s'", e.ColumnName, e.RelationName, e.Type.TypeDescription()))
|
||||
}
|
||||
result["_schema"] = sc
|
||||
|
||||
|
|
|
|||
|
|
@ -164,16 +164,42 @@ func TestPlanner_Show(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(results) != 5 {
|
||||
if len(results) != 6 {
|
||||
t.Fatal(fmt.Errorf("unexpected result set length"))
|
||||
}
|
||||
|
||||
if diff := cmp.Diff([]*pilosa.WireQueryField{
|
||||
wireQueryFieldString("_id"),
|
||||
wireQueryFieldString("name"),
|
||||
wireQueryFieldString("owner"),
|
||||
wireQueryFieldString("last_updated_user"),
|
||||
wireQueryFieldTimestamp("created_at"),
|
||||
wireQueryFieldBool("track_existence"),
|
||||
wireQueryFieldBool("keys"),
|
||||
wireQueryFieldInt("shard_width"),
|
||||
wireQueryFieldString("description"),
|
||||
}, columns); diff != "" {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ShowCreateTable", func(t *testing.T) {
|
||||
results, columns, err := sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`SHOW CREATE TABLE %i`, c))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(results) != 1 {
|
||||
t.Fatal(fmt.Errorf("unexpected result set length: %d", len(results)))
|
||||
}
|
||||
|
||||
if diff := cmp.Diff([][]interface{}{
|
||||
{string("create table testplannershowi (_id id, f int min 0 max 1000, x int min 0 max 1000);")},
|
||||
}, results); diff != "" {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff([]*pilosa.WireQueryField{
|
||||
wireQueryFieldString("ddl"),
|
||||
}, columns); diff != "" {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
|
|
@ -189,6 +215,7 @@ func TestPlanner_Show(t *testing.T) {
|
|||
}
|
||||
|
||||
if diff := cmp.Diff([]*pilosa.WireQueryField{
|
||||
wireQueryFieldString("_id"),
|
||||
wireQueryFieldString("name"),
|
||||
wireQueryFieldString("type"),
|
||||
wireQueryFieldString("internal_type"),
|
||||
|
|
@ -218,6 +245,7 @@ func TestPlanner_Show(t *testing.T) {
|
|||
}
|
||||
|
||||
if diff := cmp.Diff([]*pilosa.WireQueryField{
|
||||
wireQueryFieldString("_id"),
|
||||
wireQueryFieldString("name"),
|
||||
wireQueryFieldString("type"),
|
||||
wireQueryFieldString("internal_type"),
|
||||
|
|
@ -598,6 +626,7 @@ func TestPlanner_CreateTable(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
if diff := cmp.Diff([]*pilosa.WireQueryField{
|
||||
wireQueryFieldString("_id"),
|
||||
wireQueryFieldString("name"),
|
||||
wireQueryFieldString("type"),
|
||||
wireQueryFieldString("internal_type"),
|
||||
|
|
@ -1432,7 +1461,7 @@ func TestPlanner_BulkInsert(t *testing.T) {
|
|||
}
|
||||
|
||||
_, _, err = sql_test.MustQueryRows(t, c.GetNode(0).Server, fmt.Sprintf(`bulk insert into j1 (_id, a, b) map (0 id, 1 int, 2 int) from '%s' WITH FORMAT 'CSV' INPUT 'FILE';`, tmpfile.Name()))
|
||||
if err == nil || !strings.Contains(err.Error(), `value '_id' cannot be converted to type 'ID'`) {
|
||||
if err == nil || !strings.Contains(err.Error(), `value '_id' cannot be converted to type 'id'`) {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,13 +48,13 @@ var betweenTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select b1 between true and false from between_all_types",
|
||||
),
|
||||
ExpErr: "type 'BOOL' cannot be used as a range subscript",
|
||||
ExpErr: "type 'bool' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select d1 between 1.23 and 4.56 from between_all_types",
|
||||
),
|
||||
ExpErr: "type 'DECIMAL(2)' cannot be used as a range subscript",
|
||||
ExpErr: "type 'decimal(2)' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -72,19 +72,19 @@ var betweenTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select ids1 between [100, 102] and [456, 789] from between_all_types",
|
||||
),
|
||||
ExpErr: "type 'IDSET' cannot be used as a range subscript",
|
||||
ExpErr: "type 'idset' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select s1 between 'foo' and 'bar' from between_all_types",
|
||||
),
|
||||
ExpErr: "type 'STRING' cannot be used as a range subscript",
|
||||
ExpErr: "type 'string' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select ss1 between ['a', 'b'] and ['c', 'd'] from between_all_types",
|
||||
),
|
||||
ExpErr: "type 'STRINGSET' cannot be used as a range subscript",
|
||||
ExpErr: "type 'stringset' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -149,13 +149,13 @@ var notBetweenTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select b1 not between true and false from not_between_all_types",
|
||||
),
|
||||
ExpErr: "type 'BOOL' cannot be used as a range subscript",
|
||||
ExpErr: "type 'bool' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select d1 not between 1.23 and 4.56 from not_between_all_types",
|
||||
),
|
||||
ExpErr: "type 'DECIMAL(2)' cannot be used as a range subscript",
|
||||
ExpErr: "type 'decimal(2)' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -173,19 +173,19 @@ var notBetweenTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select ids1 not between [100, 102] and [456, 789] from not_between_all_types",
|
||||
),
|
||||
ExpErr: "type 'IDSET' cannot be used as a range subscript",
|
||||
ExpErr: "type 'idset' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select s1 not between 'foo' and 'bar' from not_between_all_types",
|
||||
),
|
||||
ExpErr: "type 'STRING' cannot be used as a range subscript",
|
||||
ExpErr: "type 'string' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select ss1 not between ['a', 'b'] and ['c', 'd'] from not_between_all_types",
|
||||
),
|
||||
ExpErr: "type 'STRINGSET' cannot be used as a range subscript",
|
||||
ExpErr: "type 'stringset' cannot be used as a range subscript",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -81,7 +81,7 @@ var castIntLiteral = TableTest{
|
|||
SQLs: sqls(
|
||||
"select cast(1 as idset)",
|
||||
),
|
||||
ExpErr: "'INT' cannot be cast to 'IDSET'",
|
||||
ExpErr: "'int' cannot be cast to 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -99,7 +99,7 @@ var castIntLiteral = TableTest{
|
|||
SQLs: sqls(
|
||||
"select cast(1 as stringset)",
|
||||
),
|
||||
ExpErr: "'INT' cannot be cast to 'STRINGSET'",
|
||||
ExpErr: "'int' cannot be cast to 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -191,7 +191,7 @@ var castInt = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(i1 as idset) from cast_int",
|
||||
),
|
||||
ExpErr: "'INT' cannot be cast to 'IDSET'",
|
||||
ExpErr: "'int' cannot be cast to 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -210,7 +210,7 @@ var castInt = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(i1 as stringset) from cast_int",
|
||||
),
|
||||
ExpErr: "'INT' cannot be cast to 'STRINGSET'",
|
||||
ExpErr: "'int' cannot be cast to 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -277,19 +277,19 @@ var castBool = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(b1 as decimal(2)) from cast_bool",
|
||||
),
|
||||
ExpErr: "'BOOL' cannot be cast to 'DECIMAL(2)'",
|
||||
ExpErr: "'bool' cannot be cast to 'decimal(2)'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(b1 as id) from cast_bool",
|
||||
),
|
||||
ExpErr: "'BOOL' cannot be cast to 'ID'",
|
||||
ExpErr: "'bool' cannot be cast to 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(b1 as idset) from cast_bool",
|
||||
),
|
||||
ExpErr: "'BOOL' cannot be cast to 'IDSET'",
|
||||
ExpErr: "'bool' cannot be cast to 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -308,13 +308,13 @@ var castBool = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(b1 as stringset) from cast_bool",
|
||||
),
|
||||
ExpErr: "'BOOL' cannot be cast to 'STRINGSET'",
|
||||
ExpErr: "'bool' cannot be cast to 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(b1 as timestamp) from cast_bool",
|
||||
),
|
||||
ExpErr: "'BOOL' cannot be cast to 'TIMESTAMP'",
|
||||
ExpErr: "'bool' cannot be cast to 'timestamp'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -342,13 +342,13 @@ var castDecimal = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(d1 as int) from cast_dec",
|
||||
),
|
||||
ExpErr: "'DECIMAL(2)' cannot be cast to 'INT'",
|
||||
ExpErr: "'decimal(2)' cannot be cast to 'int'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(d1 as bool) from cast_dec",
|
||||
),
|
||||
ExpErr: "'DECIMAL(2)' cannot be cast to 'BOOL'",
|
||||
ExpErr: "'decimal(2)' cannot be cast to 'bool'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -367,13 +367,13 @@ var castDecimal = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(d1 as id) from cast_dec",
|
||||
),
|
||||
ExpErr: "'DECIMAL(2)' cannot be cast to 'ID'",
|
||||
ExpErr: "'decimal(2)' cannot be cast to 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(d1 as idset) from cast_dec",
|
||||
),
|
||||
ExpErr: "'DECIMAL(2)' cannot be cast to 'IDSET'",
|
||||
ExpErr: "'decimal(2)' cannot be cast to 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -392,13 +392,13 @@ var castDecimal = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(d1 as stringset) from cast_dec",
|
||||
),
|
||||
ExpErr: "'DECIMAL(2)' cannot be cast to 'STRINGSET'",
|
||||
ExpErr: "'decimal(2)' cannot be cast to 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(d1 as timestamp) from cast_dec",
|
||||
),
|
||||
ExpErr: "'DECIMAL(2)' cannot be cast to 'TIMESTAMP'",
|
||||
ExpErr: "'decimal(2)' cannot be cast to 'timestamp'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -478,25 +478,25 @@ var castID = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(id1 as idset) from cast_id",
|
||||
),
|
||||
ExpErr: "'ID' cannot be cast to 'IDSET'",
|
||||
ExpErr: "'id' cannot be cast to 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(id1 as string) from cast_id",
|
||||
),
|
||||
ExpErr: "'ID' cannot be cast to 'STRING'",
|
||||
ExpErr: "'id' cannot be cast to 'string'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(id1 as stringset) from cast_id",
|
||||
),
|
||||
ExpErr: "'ID' cannot be cast to 'STRINGSET'",
|
||||
ExpErr: "'id' cannot be cast to 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(id1 as timestamp) from cast_id",
|
||||
),
|
||||
ExpErr: "'ID' cannot be cast to 'TIMESTAMP'",
|
||||
ExpErr: "'id' cannot be cast to 'timestamp'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -524,25 +524,25 @@ var castIDSet = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(ids1 as int) from cast_ids",
|
||||
),
|
||||
ExpErr: "'IDSET' cannot be cast to 'INT'",
|
||||
ExpErr: "'idset' cannot be cast to 'int'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(ids1 as bool) from cast_ids",
|
||||
),
|
||||
ExpErr: "'IDSET' cannot be cast to 'BOOL'",
|
||||
ExpErr: "'idset' cannot be cast to 'bool'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(ids1 as decimal(2)) from cast_ids",
|
||||
),
|
||||
ExpErr: "'IDSET' cannot be cast to 'DECIMAL(2)'",
|
||||
ExpErr: "'idset' cannot be cast to 'decimal(2)'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(ids1 as id) from cast_ids",
|
||||
),
|
||||
ExpErr: "'IDSET' cannot be cast to 'ID'",
|
||||
ExpErr: "'idset' cannot be cast to 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -574,13 +574,13 @@ var castIDSet = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(ids1 as stringset) from cast_ids",
|
||||
),
|
||||
ExpErr: "'IDSET' cannot be cast to 'STRINGSET'",
|
||||
ExpErr: "'idset' cannot be cast to 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(ids1 as timestamp) from cast_ids",
|
||||
),
|
||||
ExpErr: "'IDSET' cannot be cast to 'TIMESTAMP'",
|
||||
ExpErr: "'idset' cannot be cast to 'timestamp'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -608,7 +608,7 @@ var castString = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(s1 as int) from cast_string",
|
||||
),
|
||||
ExpErr: "'foo' cannot be cast to 'INT'",
|
||||
ExpErr: "'foo' cannot be cast to 'int'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -627,7 +627,7 @@ var castString = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(s1 as bool) from cast_string",
|
||||
),
|
||||
ExpErr: "'foo' cannot be cast to 'BOOL'",
|
||||
ExpErr: "'foo' cannot be cast to 'bool'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -646,7 +646,7 @@ var castString = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(s1 as decimal(2)) from cast_string",
|
||||
),
|
||||
ExpErr: "'foo' cannot be cast to 'DECIMAL(2)'",
|
||||
ExpErr: "'foo' cannot be cast to 'decimal(2)'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -665,7 +665,7 @@ var castString = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(s1 as id) from cast_string",
|
||||
),
|
||||
ExpErr: "'foo' cannot be cast to 'ID'",
|
||||
ExpErr: "'foo' cannot be cast to 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -684,7 +684,7 @@ var castString = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(s1 as idset) from cast_string",
|
||||
),
|
||||
ExpErr: "'STRING' cannot be cast to 'IDSET'",
|
||||
ExpErr: "'string' cannot be cast to 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -703,13 +703,13 @@ var castString = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(s1 as stringset) from cast_string",
|
||||
),
|
||||
ExpErr: "'STRING' cannot be cast to 'STRINGSET'",
|
||||
ExpErr: "'string' cannot be cast to 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(s1 as timestamp) from cast_string",
|
||||
),
|
||||
ExpErr: "'foo' cannot be cast to 'TIMESTAMP'",
|
||||
ExpErr: "'foo' cannot be cast to 'timestamp'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -750,31 +750,31 @@ var castStringSet = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(ss1 as int) from cast_ss",
|
||||
),
|
||||
ExpErr: "'STRINGSET' cannot be cast to 'INT'",
|
||||
ExpErr: "'stringset' cannot be cast to 'int'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(ss1 as bool) from cast_ss",
|
||||
),
|
||||
ExpErr: "'STRINGSET' cannot be cast to 'BOOL'",
|
||||
ExpErr: "'stringset' cannot be cast to 'bool'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(ss1 as decimal(2)) from cast_ss",
|
||||
),
|
||||
ExpErr: "'STRINGSET' cannot be cast to 'DECIMAL(2)'",
|
||||
ExpErr: "'stringset' cannot be cast to 'decimal(2)'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(ss1 as id) from cast_ss",
|
||||
),
|
||||
ExpErr: "'STRINGSET' cannot be cast to 'ID'",
|
||||
ExpErr: "'stringset' cannot be cast to 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(ss1 as idset) from cast_ss",
|
||||
),
|
||||
ExpErr: "'STRINGSET' cannot be cast to 'IDSET'",
|
||||
ExpErr: "'stringset' cannot be cast to 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -807,7 +807,7 @@ var castStringSet = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(ss1 as timestamp) from cast_ss",
|
||||
),
|
||||
ExpErr: "'STRINGSET' cannot be cast to 'TIMESTAMP'",
|
||||
ExpErr: "'stringset' cannot be cast to 'timestamp'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -848,25 +848,25 @@ var castTimestamp = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(t1 as bool) from cast_ts",
|
||||
),
|
||||
ExpErr: "'TIMESTAMP' cannot be cast to 'BOOL'",
|
||||
ExpErr: "'timestamp' cannot be cast to 'bool'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(t1 as decimal(2)) from cast_ts",
|
||||
),
|
||||
ExpErr: "'TIMESTAMP' cannot be cast to 'DECIMAL(2)'",
|
||||
ExpErr: "'timestamp' cannot be cast to 'decimal(2)'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(t1 as id) from cast_ts",
|
||||
),
|
||||
ExpErr: "'TIMESTAMP' cannot be cast to 'ID'",
|
||||
ExpErr: "'timestamp' cannot be cast to 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id, cast(t1 as idset) from cast_ts",
|
||||
),
|
||||
ExpErr: "'TIMESTAMP' cannot be cast to 'IDSET'",
|
||||
ExpErr: "'timestamp' cannot be cast to 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -885,7 +885,7 @@ var castTimestamp = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id, cast(t1 as stringset) from cast_ts",
|
||||
),
|
||||
ExpErr: "'TIMESTAMP' cannot be cast to 'STRINGSET'",
|
||||
ExpErr: "'timestamp' cannot be cast to 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
|
|||
|
|
@ -26,13 +26,13 @@ var datePartTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select datepart(1, 2)",
|
||||
),
|
||||
ExpErr: "an expression of type 'INT' cannot be passed to a parameter of type 'STRING'",
|
||||
ExpErr: "an expression of type 'int' cannot be passed to a parameter of type 'string'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select datepart('1', 2)",
|
||||
),
|
||||
ExpErr: "an expression of type 'INT' cannot be passed to a parameter of type 'TIMESTAMP'",
|
||||
ExpErr: "an expression of type 'int' cannot be passed to a parameter of type 'timestamp'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
|
|||
|
|
@ -115,14 +115,14 @@ var insertTest = TableTest{
|
|||
SQLs: sqls(
|
||||
"insert into testinsert (_id, a, event) values (4, 40, [101, 150])",
|
||||
),
|
||||
ExpErr: "an expression of type 'IDSET' cannot be assigned to type 'STRINGSET'",
|
||||
ExpErr: "an expression of type 'idset' cannot be assigned to type 'stringset'",
|
||||
},
|
||||
{
|
||||
// InsertSetsTypeError2
|
||||
SQLs: sqls(
|
||||
"insert into testinsert (_id, a, ievent) values (4, 40, ['POST', 'GET'])",
|
||||
),
|
||||
ExpErr: "an expression of type 'STRINGSET' cannot be assigned to type 'IDSET'",
|
||||
ExpErr: "an expression of type 'stringset' cannot be assigned to type 'idset'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,37 +24,37 @@ var likeTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id like '%f_' from like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'ID'",
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select i1 like '%f_' from like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'INT'",
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'int'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select b1 like '%f_' from like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'BOOL'",
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'bool'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select d1 like '%f_' from like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'DECIMAL(2)'",
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'decimal(2)'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select id1 like '%f_' from like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'ID'",
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select ids1 like '%f_' from like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'IDSET'",
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -72,13 +72,13 @@ var likeTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select ss1 like '%f_' from like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'STRINGSET'",
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select t1 like '%f_' from like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'TIMESTAMP'",
|
||||
ExpErr: "operator 'LIKE' incompatible with type 'timestamp'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -107,37 +107,37 @@ var notLikeTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id not like '%f_' from not_like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'ID'",
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select i1 not like '%f_' from not_like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'INT'",
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'int'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select b1 not like '%f_' from not_like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'BOOL'",
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'bool'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select d1 not like '%f_' from not_like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'DECIMAL(2)'",
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'decimal(2)'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select id1 not like '%f_' from not_like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'ID'",
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'id'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select ids1 not like '%f_' from not_like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'IDSET'",
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -155,13 +155,13 @@ var notLikeTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select ss1 not like '%f_' from not_like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'STRINGSET'",
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select t1 not like '%f_' from not_like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'TIMESTAMP'",
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'timestamp'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -338,13 +338,13 @@ var nullFilterTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where b1 is null",
|
||||
),
|
||||
ExpErr: "unsupported type 'BOOL' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'bool' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where b1 is not null",
|
||||
),
|
||||
ExpErr: "unsupported type 'BOOL' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'bool' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -374,49 +374,49 @@ var nullFilterTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where id1 is null",
|
||||
),
|
||||
ExpErr: "unsupported type 'ID' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'id' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where id1 is not null",
|
||||
),
|
||||
ExpErr: "unsupported type 'ID' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'id' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where ids1 is null",
|
||||
),
|
||||
ExpErr: "unsupported type 'IDSET' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'idset' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where ids1 is not null",
|
||||
),
|
||||
ExpErr: "unsupported type 'IDSET' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'idset' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where s1 is null",
|
||||
),
|
||||
ExpErr: "unsupported type 'STRING' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'string' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where s1 is not null",
|
||||
),
|
||||
ExpErr: "unsupported type 'STRING' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'string' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where ss1 is null",
|
||||
),
|
||||
ExpErr: "unsupported type 'STRINGSET' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'stringset' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select _id from null_filter_all_types where ss1 is not null",
|
||||
),
|
||||
ExpErr: "unsupported type 'STRINGSET' for is/is not null filter expression",
|
||||
ExpErr: "unsupported type 'stringset' for is/is not null filter expression",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@ var orderByTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select * from order_by_test order by a_string_set asc",
|
||||
),
|
||||
ExpErr: "unable to sort a column of type 'STRINGSET'",
|
||||
ExpErr: "unable to sort a column of type 'stringset'",
|
||||
},
|
||||
{
|
||||
name: "order-by-idset",
|
||||
SQLs: sqls(
|
||||
"select * from order_by_test order by an_id_set asc",
|
||||
),
|
||||
ExpErr: "unable to sort a column of type 'IDSET'",
|
||||
ExpErr: "unable to sort a column of type 'idset'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ var setFunctionTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select * from selectwithset where setcontains(event, 1)",
|
||||
),
|
||||
ExpErr: "types 'STRINGSET' and 'INT' are not equatable",
|
||||
ExpErr: "types 'stringset' and 'int' are not equatable",
|
||||
},
|
||||
{
|
||||
// SetContainsWrongTypeInt
|
||||
|
|
@ -217,7 +217,7 @@ var setFunctionTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select * from selectwithset where setcontains(ievent, 'foo')",
|
||||
),
|
||||
ExpErr: "types 'IDSET' and 'STRING' are not equatable",
|
||||
ExpErr: "types 'idset' and 'string' are not equatable",
|
||||
},
|
||||
{
|
||||
// SetContainsWrongTypeSet
|
||||
|
|
@ -225,7 +225,7 @@ var setFunctionTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select * from selectwithset where setcontains(event, ['foo'])",
|
||||
),
|
||||
ExpErr: "types 'STRINGSET' and 'STRINGSET' are not equatable",
|
||||
ExpErr: "types 'stringset' and 'stringset' are not equatable",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -265,13 +265,13 @@ var setParameterTests = TableTest{
|
|||
SQLs: sqls(
|
||||
"select setcontains(['POST', 'GET'], 1)",
|
||||
),
|
||||
ExpErr: "types 'STRINGSET' and 'INT' are not equatable",
|
||||
ExpErr: "types 'stringset' and 'int' are not equatable",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select setcontains([1, 2], '1')",
|
||||
),
|
||||
ExpErr: "types 'IDSET' and 'STRING' are not equatable",
|
||||
ExpErr: "types 'idset' and 'string' are not equatable",
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -293,14 +293,14 @@ var setParameterTests = TableTest{
|
|||
"select setcontainsall(['POST', 'GET'], [1, 2])",
|
||||
"select setcontainsany(['POST', 'GET'], [1, 2])",
|
||||
),
|
||||
ExpErr: "types 'STRING' and 'ID' are not equatable",
|
||||
ExpErr: "types 'string' and 'id' are not equatable",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select setcontainsall([1, 2], ['1', '2'])",
|
||||
"select setcontainsany([1, 2], ['1', '2'])",
|
||||
),
|
||||
ExpErr: "types 'ID' and 'STRING' are not equatable",
|
||||
ExpErr: "types 'id' and 'string' are not equatable",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ var timeQuantumQueryTest = TableTest{
|
|||
SQLs: sqls(
|
||||
"select _id not like '%f_' from not_like_all_types",
|
||||
),
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'ID'",
|
||||
ExpErr: "operator 'NOTLIKE' incompatible with type 'id'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,19 +73,19 @@ var unaryOpExprWithBool = TableTest{
|
|||
SQLs: sqls(
|
||||
"select -i from unoptest_b;",
|
||||
),
|
||||
ExpErr: "operator '-' incompatible with type 'BOOL'",
|
||||
ExpErr: "operator '-' incompatible with type 'bool'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select !i from unoptest_b;",
|
||||
),
|
||||
ExpErr: "operator '!' incompatible with type 'BOOL'",
|
||||
ExpErr: "operator '!' incompatible with type 'bool'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select +i from unoptest_b;",
|
||||
),
|
||||
ExpErr: "operator '+' incompatible with type 'BOOL'",
|
||||
ExpErr: "operator '+' incompatible with type 'bool'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -169,7 +169,7 @@ var unaryOpExprWithDecimal = TableTest{
|
|||
SQLs: sqls(
|
||||
"select !d from unoptestd;",
|
||||
),
|
||||
ExpErr: "operator '!' incompatible with type 'DECIMAL(2)'",
|
||||
ExpErr: "operator '!' incompatible with type 'decimal(2)'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
|
|
@ -202,19 +202,19 @@ var unaryOpExprWithTimestamp = TableTest{
|
|||
SQLs: sqls(
|
||||
"select -ts from unoptestts;",
|
||||
),
|
||||
ExpErr: "operator '-' incompatible with type 'TIMESTAMP'",
|
||||
ExpErr: "operator '-' incompatible with type 'timestamp'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select !ts from unoptestts;",
|
||||
),
|
||||
ExpErr: "operator '!' incompatible with type 'TIMESTAMP'",
|
||||
ExpErr: "operator '!' incompatible with type 'timestamp'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select +ts from unoptestts;",
|
||||
),
|
||||
ExpErr: "operator '+' incompatible with type 'TIMESTAMP'",
|
||||
ExpErr: "operator '+' incompatible with type 'timestamp'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -235,19 +235,19 @@ var unaryOpExprWithIDSet = TableTest{
|
|||
SQLs: sqls(
|
||||
"select -ids from unoptestids;",
|
||||
),
|
||||
ExpErr: "operator '-' incompatible with type 'IDSET'",
|
||||
ExpErr: "operator '-' incompatible with type 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select !ids from unoptestids;",
|
||||
),
|
||||
ExpErr: "operator '!' incompatible with type 'IDSET'",
|
||||
ExpErr: "operator '!' incompatible with type 'idset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select +ids from unoptestids;",
|
||||
),
|
||||
ExpErr: "operator '+' incompatible with type 'IDSET'",
|
||||
ExpErr: "operator '+' incompatible with type 'idset'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -268,19 +268,19 @@ var unaryOpExprWithString = TableTest{
|
|||
SQLs: sqls(
|
||||
"select -s from unoptest_s;",
|
||||
),
|
||||
ExpErr: "operator '-' incompatible with type 'STRING'",
|
||||
ExpErr: "operator '-' incompatible with type 'string'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select !s from unoptest_s;",
|
||||
),
|
||||
ExpErr: "operator '!' incompatible with type 'STRING'",
|
||||
ExpErr: "operator '!' incompatible with type 'string'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select +s from unoptest_s;",
|
||||
),
|
||||
ExpErr: "operator '+' incompatible with type 'STRING'",
|
||||
ExpErr: "operator '+' incompatible with type 'string'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -301,19 +301,19 @@ var unaryOpExprWithStringSet = TableTest{
|
|||
SQLs: sqls(
|
||||
"select -s from unoptestss;",
|
||||
),
|
||||
ExpErr: "operator '-' incompatible with type 'STRINGSET'",
|
||||
ExpErr: "operator '-' incompatible with type 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select !s from unoptestss;",
|
||||
),
|
||||
ExpErr: "operator '!' incompatible with type 'STRINGSET'",
|
||||
ExpErr: "operator '!' incompatible with type 'stringset'",
|
||||
},
|
||||
{
|
||||
SQLs: sqls(
|
||||
"select +s from unoptestss;",
|
||||
),
|
||||
ExpErr: "operator '+' incompatible with type 'STRINGSET'",
|
||||
ExpErr: "operator '+' incompatible with type 'stringset'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package test
|
|||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
featurebase "github.com/molecula/featurebase/v3"
|
||||
|
|
@ -59,8 +58,8 @@ func MustQueryRows(tb testing.TB, svr *featurebase.Server, q string) ([][]interf
|
|||
for _, oc := range ocolumns {
|
||||
cols = append(cols, &featurebase.WireQueryField{
|
||||
Name: dax.FieldName(oc.ColumnName),
|
||||
Type: strings.ToLower(oc.Type.TypeDescription()),
|
||||
BaseType: dax.BaseType(strings.ToLower(oc.Type.TypeName())),
|
||||
Type: oc.Type.TypeDescription(),
|
||||
BaseType: dax.BaseType(oc.Type.BaseTypeName()),
|
||||
TypeInfo: oc.Type.TypeInfo(),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue