package compute
import (
"fmt"
"strings"
"github.com/daviszhen/plan/pkg/common"
"github.com/daviszhen/plan/pkg/storage"
)
func WildcardMatch(pattern, target *common.String) bool {
var p = 0
var t = 0
var positionOfPercentPlusOne int = -1
var positionOfTargetEncounterPercent int = -1
plen := pattern.Length()
tlen := target.Length()
pSlice := pattern.DataSlice()
tSlice := target.DataSlice()
for t < tlen {
if p < plen && pSlice[p] == '%' {
p++
positionOfPercentPlusOne = p
if p >= plen {
return true
}
positionOfTargetEncounterPercent = t
} else if p < plen && (pSlice[p] == '_' || pSlice[p] == tSlice[t]) {
p++
t++
} else {
if positionOfPercentPlusOne == -1 {
return false
}
if positionOfTargetEncounterPercent == -1 {
return false
}
p = positionOfPercentPlusOne
positionOfTargetEncounterPercent++
t = positionOfTargetEncounterPercent
}
}
for p < plen && pSlice[p] == '%' {
p++
}
return p >= plen
}
var _ TypeOp[common.Decimal] = new(common.Decimal)
type DataType int
const (
DataTypeInteger DataType = iota
DataTypeVarchar
DataTypeDecimal
DataTypeDate
DataTypeBool
DataTypeInterval
DataTypeFloat64
DataTypeInvalid
)
var dataType2Str = map[DataType]string{
DataTypeInteger: "int",
DataTypeVarchar: "varchar",
DataTypeDecimal: "decimal",
DataTypeDate: "date",
DataTypeBool: "bool",
DataTypeInvalid: "invalid",
}
func (dt DataType) String() string {
if s, ok := dataType2Str[dt]; ok {
return s
}
return "invalid"
}
type Catalog struct {
tpch map[string]*CatalogTable
}
func (c *Catalog) Table(db, table string) (*CatalogTable, error) {
if db == "tpch" {
if c, ok := c.tpch[table]; ok {
return c, nil
} else {
panic(fmt.Errorf("table %s in database %s does not exist", table, db))
}
} else {
panic(fmt.Sprintf("database %s does not exist", db))
}
}
type Stats struct {
RowCount float64
ColStats []*BaseStats
}
func (s *Stats) Copy() *Stats {
ret := &Stats{
RowCount: s.RowCount,
}
ret.ColStats = make([]*BaseStats, len(s.ColStats))
for i, stat := range s.ColStats {
ret.ColStats[i] = stat.Copy()
}
return ret
}
func (s *Stats) String() string {
if s == nil {
return ""
}
sb := strings.Builder{}
sb.WriteString(fmt.Sprintf("rowcount %v\n", s.RowCount))
for i, stat := range s.ColStats {
sb.WriteString(fmt.Sprintf("col %v ", i))
sb.WriteString(stat.String())
sb.WriteByte('\n')
}
return sb.String()
}
func convertStats(tstats *storage.TableStats) *Stats {
ret := &Stats{
RowCount: float64(tstats.GetStats(0).Count()),
}
for _, cstats := range tstats.GetStats2() {
ret.ColStats = append(ret.ColStats, convertStats2(cstats))
}
return ret
}
func convertStats2(cstats *storage.ColumnStats) *BaseStats {
return &BaseStats{
hasNull: cstats.HasNull(),
hasNoNull: cstats.HasNoNull(),
distinctCount: cstats.DistinctCount(),
}
}
func convertStats3(bstats *storage.BaseStats) *BaseStats {
return &BaseStats{
hasNull: bstats.HasNull(),
hasNoNull: bstats.HasNoNull(),
distinctCount: bstats.DistinctCount(),
}
}
type CatalogTable struct {
Db string
Table string
Columns []string
Types []common.LType
PK []int
Column2Idx map[string]int
Stats *Stats
}