mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-10 15:01:03 +00:00
drop float/decimal distinction in PQL
PQL always produces decimals, which have effectively-arbitrary range, but can convert them to floats when required; the executor then requests this conversion in the handful of cases (SetRowAttrs and SetColumnAttrs) where it wants floats rather than decimals. Not yet fixed: The "Range" call may also be wrong now. It was specifying an "fvalue" but is now effectively getting what used to be called a "dvalue". However, so far as I can tell, that didn't work before either.
This commit is contained in:
parent
b8bb438b69
commit
18ed02d7fb
4 changed files with 1405 additions and 1812 deletions
|
|
@ -4286,7 +4286,7 @@ func (e *executor) executeSetRowAttrs(ctx context.Context, qcx *Qcx, index strin
|
|||
}
|
||||
|
||||
// Copy args and remove reserved fields.
|
||||
attrs := pql.CopyArgs(c.Args)
|
||||
attrs := pql.CopyArgsDecimalToFloat(c.Args)
|
||||
delete(attrs, "_field")
|
||||
delete(attrs, "_"+rowLabel)
|
||||
|
||||
|
|
@ -4353,7 +4353,7 @@ func (e *executor) executeBulkSetRowAttrs(ctx context.Context, qcx *Qcx, index s
|
|||
}
|
||||
|
||||
// Copy args and remove reserved fields.
|
||||
attrs := pql.CopyArgs(c.Args)
|
||||
attrs := pql.CopyArgsDecimalToFloat(c.Args)
|
||||
delete(attrs, "_field")
|
||||
delete(attrs, "_"+rowLabel)
|
||||
|
||||
|
|
@ -4437,7 +4437,7 @@ func (e *executor) executeSetColumnAttrs(ctx context.Context, qcx *Qcx, index st
|
|||
}
|
||||
|
||||
// Copy args and remove reserved fields.
|
||||
attrs := pql.CopyArgs(c.Args)
|
||||
attrs := pql.CopyArgsDecimalToFloat(c.Args)
|
||||
delete(attrs, "_"+columnLabel)
|
||||
delete(attrs, "field")
|
||||
|
||||
|
|
|
|||
32
pql/ast.go
32
pql/ast.go
|
|
@ -60,7 +60,7 @@ func (q *Query) lastCallStackElem() *callStackElem {
|
|||
|
||||
func (q *Query) addPosNum(key, value string) {
|
||||
q.addField(key)
|
||||
q.addNumVal(value, false)
|
||||
q.addNumVal(value)
|
||||
}
|
||||
|
||||
func (q *Query) addPosStr(key, value string) {
|
||||
|
|
@ -85,9 +85,9 @@ func (q *Query) endConditional() {
|
|||
if len(q.conditional) != 5 {
|
||||
panic(fmt.Sprintf("conditional of wrong length: %#v", q.conditional))
|
||||
}
|
||||
low := parseNum(q.conditional[0], false)
|
||||
low := parseNum(q.conditional[0])
|
||||
field := q.conditional[2]
|
||||
high := parseNum(q.conditional[4], false)
|
||||
high := parseNum(q.conditional[4])
|
||||
|
||||
var op Token
|
||||
switch q.conditional[1] + q.conditional[3] {
|
||||
|
|
@ -162,12 +162,12 @@ func (q *Query) addVal(val interface{}) {
|
|||
elem.lastCond = ILLEGAL
|
||||
}
|
||||
|
||||
func (q *Query) addNumVal(val string, asFloat bool) {
|
||||
func (q *Query) addNumVal(val string) {
|
||||
elem := q.lastCallStackElem()
|
||||
if elem == nil || elem.lastField == "" {
|
||||
panic(fmt.Sprintf("addIntVal called with '%s' when lastField is empty", val))
|
||||
}
|
||||
ival := parseNum(val, asFloat)
|
||||
ival := parseNum(val)
|
||||
if elem.inList {
|
||||
if elem.lastCond != ILLEGAL {
|
||||
list := elem.call.Args[elem.lastField].(*Condition).Value.([]interface{})
|
||||
|
|
@ -991,6 +991,20 @@ func CopyArgs(m map[string]interface{}) map[string]interface{} {
|
|||
return other
|
||||
}
|
||||
|
||||
// CopyArgsDecimalToFloat makes a copy of m, but in the process,
|
||||
// replaces any Decimal values with Float64 values.
|
||||
func CopyArgsDecimalToFloat(m map[string]interface{}) map[string]interface{} {
|
||||
other := make(map[string]interface{}, len(m))
|
||||
for k, v := range m {
|
||||
if dec, ok := v.(Decimal); ok {
|
||||
other[k] = dec.Float64()
|
||||
} else {
|
||||
other[k] = v
|
||||
}
|
||||
}
|
||||
return other
|
||||
}
|
||||
|
||||
func joinInterfaceSlice(a []interface{}) string {
|
||||
other := make([]string, len(a))
|
||||
for i := range a {
|
||||
|
|
@ -1012,15 +1026,11 @@ func joinUint64Slice(a []uint64) string {
|
|||
return "[" + strings.Join(other, ",") + "]"
|
||||
}
|
||||
|
||||
func parseNum(val string, asFloat bool) interface{} {
|
||||
func parseNum(val string) interface{} {
|
||||
var ival interface{}
|
||||
var err error
|
||||
if strings.Contains(val, ".") {
|
||||
if asFloat {
|
||||
ival, err = strconv.ParseFloat(val, 64)
|
||||
} else {
|
||||
ival, err = ParseDecimal(val)
|
||||
}
|
||||
ival, err = ParseDecimal(val)
|
||||
} else {
|
||||
ival, err = strconv.ParseInt(val, 10, 64)
|
||||
}
|
||||
|
|
|
|||
51
pql/pql.peg
51
pql/pql.peg
|
|
@ -6,24 +6,20 @@ type PQL Peg {
|
|||
|
||||
|
||||
Calls <- sp (Call sp)* !.
|
||||
Call <- 'Set' {p.startCall("Set")} open col comma dargs (comma timestamp)? close {p.endCall()}
|
||||
/ 'SetRowAttrs' {p.startCall("SetRowAttrs")} open posfield comma row comma fargs close {p.endCall()}
|
||||
/ 'SetColumnAttrs' {p.startCall("SetColumnAttrs")} open col comma fargs close {p.endCall()}
|
||||
/ 'Clear' {p.startCall("Clear")} open col comma dargs close {p.endCall()}
|
||||
/ 'ClearRow' {p.startCall("ClearRow")} open darg close {p.endCall()}
|
||||
/ 'Store' {p.startCall("Store")} open Call comma darg close {p.endCall()}
|
||||
Call <- 'Set' {p.startCall("Set")} open col comma args (comma timestamp)? close {p.endCall()}
|
||||
/ 'SetRowAttrs' {p.startCall("SetRowAttrs")} open posfield comma row comma args close {p.endCall()}
|
||||
/ 'SetColumnAttrs' {p.startCall("SetColumnAttrs")} open col comma args close {p.endCall()}
|
||||
/ 'Clear' {p.startCall("Clear")} open col comma args close {p.endCall()}
|
||||
/ 'ClearRow' {p.startCall("ClearRow")} open arg close {p.endCall()}
|
||||
/ 'Store' {p.startCall("Store")} open Call comma arg close {p.endCall()}
|
||||
/ 'TopN' {p.startCall("TopN")} open posfield (comma allargs)? close {p.endCall()}
|
||||
/ 'Rows' {p.startCall("Rows")} open posfield (comma allargs)? close {p.endCall()}
|
||||
/ 'Range' {p.startCall("Range")} open field sp '=' sp fvalue comma 'from='? {p.addField("from")} timestampfmt {p.addVal(text)} comma 'to='? sp {p.addField("to")} timestampfmt {p.addVal(text)} close {p.endCall()}
|
||||
/ 'Range' {p.startCall("Range")} open field sp '=' sp value comma 'from='? {p.addField("from")} timestampfmt {p.addVal(text)} comma 'to='? sp {p.addField("to")} timestampfmt {p.addVal(text)} close {p.endCall()}
|
||||
/ < IDENT > { p.startCall(text ) } open allargs comma? close { p.endCall() }
|
||||
allargs <- Call (comma Call)* (comma dargs)? / dargs / sp
|
||||
fargs <- farg (comma fargs)? sp
|
||||
farg <- field sp '=' sp fvalue
|
||||
/ field sp COND sp fvalue
|
||||
/ conditional
|
||||
dargs <- darg (comma dargs)? sp
|
||||
darg <- field sp '=' sp dvalue
|
||||
/ field sp COND sp dvalue
|
||||
allargs <- Call (comma Call)* (comma args)? / args / sp
|
||||
args <- arg (comma args)? sp
|
||||
arg <- field sp '=' sp value
|
||||
/ field sp COND sp value
|
||||
/ conditional
|
||||
COND <- '><' { p.addBTWN() }
|
||||
/ '<=' { p.addLTE() }
|
||||
|
|
@ -38,30 +34,19 @@ condint <- < '-'? [0-9]* '.' [0-9]+ / '0' / '-'? [1-9] [0-9]* > sp {p.condAdd(te
|
|||
condLT <- <('<=' / '<')> sp {p.condAdd(text)}
|
||||
condfield <- <fieldExpr> sp {p.condAdd(text)}
|
||||
|
||||
dvalue <- ditem
|
||||
/ lbrack { p.startList() } dlist rbrack { p.endList() }
|
||||
fvalue <- fitem
|
||||
/ lbrack { p.startList() } flist rbrack { p.endList() }
|
||||
dlist <- ditem (comma dlist)?
|
||||
flist <- fitem (comma flist)?
|
||||
ditem <- itema
|
||||
/ decimal
|
||||
/ itemb
|
||||
fitem <- itema
|
||||
/ float
|
||||
/ itemb
|
||||
itema <- 'null' &(comma / sp close) { p.addVal(nil) }
|
||||
value <- item
|
||||
/ lbrack { p.startList() } list rbrack { p.endList() }
|
||||
list <- item (comma list)?
|
||||
item <- 'null' &(comma / sp close) { p.addVal(nil) }
|
||||
/ 'true' &(comma / sp close) { p.addVal(true) }
|
||||
/ 'false' &(comma / sp close) { p.addVal(false) }
|
||||
/ timestampfmt { p.addVal(text) }
|
||||
itemb <- < IDENT > { p.startCall(text) } open allargs comma? close { p.addVal(p.endCall()) }
|
||||
/ < '-'? [0-9]+ ('.'[0-9]*)? > { p.addNumVal(text) }
|
||||
/ < '-'? '.'[0-9]+ > { p.addNumVal(text) }
|
||||
/ < IDENT > { p.startCall(text) } open allargs comma? close { p.addVal(p.endCall()) }
|
||||
/ < ([[A-Z]] / [0-9] / '-' / '_' / ':')+ > { p.addVal(text) }
|
||||
/ < '"' doublequotedstring '"' > { p.addVal(text) }
|
||||
/ < '\'' singlequotedstring '\'' > { p.addVal(text) }
|
||||
float <- < '-'? [0-9]+ ('.'[0-9]*)? > { p.addNumVal(text, true) }
|
||||
/ < '-'? '.'[0-9]+ > { p.addNumVal(text, true) }
|
||||
decimal <- < '-'? [0-9]+ ('.'[0-9]*)? > { p.addNumVal(text, false) }
|
||||
/ < '-'? '.'[0-9]+ > { p.addNumVal(text, false) }
|
||||
|
||||
doublequotedstring <- ( '\\"' / '\\\\' / '\\n' / '\\t' / [^"\\] )*
|
||||
singlequotedstring <- ( '\\\'' / '\\\\' / '\\n' / '\\t' / [^'\\] )*
|
||||
|
|
|
|||
3128
pql/pql.peg.go
3128
pql/pql.peg.go
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue