mirror of
https://github.com/johnkerl/miller.git
synced 2026-01-23 02:14:13 +00:00
Insist that filter expressions be boolean
This commit is contained in:
parent
eb972e19eb
commit
a1a3f43ebe
4 changed files with 41 additions and 4 deletions
|
|
@ -54,7 +54,9 @@ func NewEmptyState(options *cli.TOptions, strictMode bool) *State {
|
|||
Inrec: nil,
|
||||
Context: nil,
|
||||
Oosvars: oosvars,
|
||||
FilterExpression: mlrval.TRUE,
|
||||
// XXX
|
||||
//FilterExpression: mlrval.TRUE,
|
||||
FilterExpression: mlrval.NULL,
|
||||
Stack: NewStack(),
|
||||
regexCapturesByFrame: regexCapturesByFrame,
|
||||
|
||||
|
|
|
|||
|
|
@ -364,7 +364,10 @@ func transformerPutOrFilterParseCLI(
|
|||
dslInstanceType = cst.DSLInstanceTypeFilter
|
||||
}
|
||||
|
||||
doFilter := (verb == "filter")
|
||||
|
||||
transformer, err := NewTransformerPut(
|
||||
doFilter,
|
||||
dslStrings,
|
||||
dslInstanceType,
|
||||
presets,
|
||||
|
|
@ -390,6 +393,7 @@ func transformerPutOrFilterParseCLI(
|
|||
|
||||
// ----------------------------------------------------------------
|
||||
type TransformerPut struct {
|
||||
doFilter bool // false for the put verb, true for the filter verb
|
||||
cstRootNode *cst.RootNode
|
||||
runtimeState *runtime.State
|
||||
callCount int
|
||||
|
|
@ -399,6 +403,7 @@ type TransformerPut struct {
|
|||
}
|
||||
|
||||
func NewTransformerPut(
|
||||
doFilter bool, // false for the put verb, true for the filter verb
|
||||
dslStrings []string,
|
||||
dslInstanceType cst.DSLInstanceType,
|
||||
presets []string,
|
||||
|
|
@ -483,6 +488,7 @@ func NewTransformerPut(
|
|||
}
|
||||
|
||||
return &TransformerPut{
|
||||
doFilter: doFilter,
|
||||
cstRootNode: cstRootNode,
|
||||
runtimeState: runtimeState,
|
||||
callCount: 0,
|
||||
|
|
@ -527,10 +533,37 @@ func (tr *TransformerPut) Transform(
|
|||
}
|
||||
|
||||
if !tr.suppressOutputRecord {
|
||||
// The tr.runtimeState.FilterExpression defaults to null. It evaluates to null
|
||||
// for assignment statements, etc.
|
||||
// * If the verb is put, then tr.runtimeState.FilterExpression will get set to
|
||||
// something only when a filter DSL statement is encountered.
|
||||
// * If the verb is filter, then we insist that the expression evaluate to either
|
||||
// boolean, or absent. The latter is for Miller's record-heterogeneity guarantees,
|
||||
// e.g. mlr filter '$x > 10' for records not having a $x.
|
||||
|
||||
filterBool, isBool := tr.runtimeState.FilterExpression.GetBoolValue()
|
||||
if !isBool {
|
||||
filterBool = false
|
||||
|
||||
if tr.doFilter {
|
||||
// This is mlr filter
|
||||
if !isBool {
|
||||
if tr.runtimeState.FilterExpression.IsAbsent() {
|
||||
filterBool = false
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"Filter expression did not evaluate to boolean: got %s value %s",
|
||||
tr.runtimeState.FilterExpression.String(),
|
||||
tr.runtimeState.FilterExpression.GetTypeName(),
|
||||
)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This is mlr put.
|
||||
if !isBool {
|
||||
filterBool = true
|
||||
}
|
||||
}
|
||||
|
||||
wantToEmit := lib.BooleanXOR(filterBool, tr.invertFilter)
|
||||
if wantToEmit {
|
||||
outputRecordsAndContexts.PushBack(types.NewRecordAndContext(outrec, &context))
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
mlr --opprint --from test/input/abixy filter -e -f ${CASEDIR}/mlr
|
||||
mlr --opprint --from test/input/abixy filter -f ${CASEDIR}/mlr
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
a b i x y
|
||||
eks zee 7 0.61178406 0.18788492
|
||||
Loading…
Add table
Add a link
Reference in a new issue