diff --git a/docs/src/manpage.md b/docs/src/manpage.md index aef0df1f31..831530aec1 100644 --- a/docs/src/manpage.md +++ b/docs/src/manpage.md @@ -3634,5 +3634,5 @@ MILLER(1) MILLER(1) - 2023-08-26 MILLER(1) + 2023-08-27 MILLER(1) diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt index a4bb520495..43f2ed3865 100644 --- a/docs/src/manpage.txt +++ b/docs/src/manpage.txt @@ -3613,4 +3613,4 @@ MILLER(1) MILLER(1) - 2023-08-26 MILLER(1) + 2023-08-27 MILLER(1) diff --git a/docs/src/missings.csv b/docs/src/missings.csv new file mode 100644 index 0000000000..22abbc0424 --- /dev/null +++ b/docs/src/missings.csv @@ -0,0 +1,4 @@ +a,x,z,w +red,7,, +green,,242,zdatsyg +blue,9,, diff --git a/docs/src/missings.json b/docs/src/missings.json new file mode 100644 index 0000000000..d1dfb13ad6 --- /dev/null +++ b/docs/src/missings.json @@ -0,0 +1,5 @@ +[ + { "a": "red", "x": 7 }, + { "a": "green", "z": 242, "w": "zdatsyg" }, + { "a": "blue", "x": 9 } +] diff --git a/docs/src/reference-main-null-data.md b/docs/src/reference-main-null-data.md index 6ddd2518f8..0de7c67c91 100644 --- a/docs/src/reference-main-null-data.md +++ b/docs/src/reference-main-null-data.md @@ -93,7 +93,7 @@ a=1,b=8 x=9,b=10 -* Functions/operators which have one or more *empty* arguments produce empty output: e.g. +* Most functions/operators which have one or more *empty* arguments produce empty output: e.g.
 echo 'x=2,y=3' | mlr put '$a=$x+$y'
@@ -106,7 +106,7 @@ x=2,y=3,a=5
 echo 'x=,y=3' | mlr put '$a=$x+$y'
 
-x=,y=3,a=
+x=,y=3,a=3
 
@@ -125,6 +125,55 @@ with the exception that the `min` and `max` functions are special: if one argume
 x=,y=3,a=3,b=
 
+Likewise, empty works like 0 for addition and subtraction, and multiplication: + +
+echo 'x=,y=3' | mlr put '$a = $x + $y; $b = $x - $y; $c = $x * $y'
+
+
+x=,y=3,a=3,b=-3,c=3
+
+ +This is intended to follow the arithmetic rule for absent data (explained next). In particular: + +* For file formats allowing for heterogeneity in keys, e.g. JSON, you should be able to keep a running sum of some field, say `$x`. If a given record doesn't have `$x`, then `$x` will be absent for that record, and the sum should simply continue. +* For CSV and TSV, which don't allow for hetrogeneity in keys, the _only_ way a value can be missing is to be empty. Here, if a given record doesn't have `$x`, then `$x` will be empty for that record, and the sum should simply continue. + +
+cat missings.json
+
+
+[
+  { "a": "red",   "x": 7 },
+  { "a": "green", "z": 242, "w": "zdatsyg" },
+  { "a": "blue",  "x": 9 }
+]
+
+ +
+mlr --ijson --from missings.json put -q 'begin { @sum = 0 } @sum += $x; end { print @sum }'
+
+
+16
+
+ +
+cat missings.csv
+
+
+a,x,z,w
+red,7,,
+green,,242,zdatsyg
+blue,9,,
+
+ +
+mlr --icsv --from missings.csv put -q 'begin { @sum = 0 } @sum += $x; end { print @sum }'
+
+
+16
+
+ * Functions of *absent* variables (e.g. `mlr put '$y = log10($nonesuch)'`) evaluate to absent, and arithmetic/bitwise/boolean operators with both operands being absent evaluate to absent. Arithmetic operators with one absent operand return the other operand. More specifically, absent values act like zero for addition/subtraction, and one for multiplication: Furthermore, **any expression which evaluates to absent is not stored in the left-hand side of an assignment statement**:
@@ -145,8 +194,6 @@ x=2,y=3,a=2,b=3
 
 The reasoning is as follows:
 
-* Empty values are explicit in the data so they should explicitly affect accumulations: `mlr put '@sum += $x'` should accumulate numeric `x` values into the sum but an empty `x`, when encountered in the input data stream, should make the sum non-numeric. To work around this you can use the `is_not_null` function as follows: `mlr put 'is_not_null($x) { @sum += $x }'`
-
 * Absent stream-record values should not break accumulations, since Miller by design handles heterogeneous data: the running `@sum` in `mlr put '@sum += $x'` should not be invalidated for records which have no `x`.
 
 * Absent out-of-stream-variable values are precisely what allow you to write `mlr put '@sum += $x'`. Otherwise you would have to write `mlr put 'begin{@sum = 0}; @sum += $x'` -- which is tolerable -- but for `mlr put 'begin{...}; @sum[$a][$b] += $x'` you'd have to pre-initialize `@sum` for all values of `$a` and `$b` in your input data stream, which is intolerable.
@@ -198,10 +245,11 @@ If you're interested in a formal description of how empty and absent fields part
 mlr help type-arithmetic-info
 
-(+)        | 1          2.5        (absent)   (error)   
-------     + ------     ------     ------     ------    
-1          | 2          3.5        1          (error)   
-2.5        | 3.5        5          2.5        (error)   
-(absent)   | 1          2.5        (absent)   (error)   
-(error)    | (error)    (error)    (error)    (error)   
+(+)        | 1          2.5       (empty)    (absent)   (error)   
+------     + ------     ------     ------     ------     ------    
+1          | 2          3.5        1          1          (error)   
+2.5        | 3.5        5          2.5        2.5        (error)   
+(empty)    | 1          2.5        (empty)    (absent)   (error)   
+(absent)   | 1          2.5        (absent)   (absent)   (error)   
+(error)    | (error)    (error)    (error)    (error)    (error)   
 
diff --git a/docs/src/reference-main-null-data.md.in b/docs/src/reference-main-null-data.md.in index 4a9b446164..381a46522b 100644 --- a/docs/src/reference-main-null-data.md.in +++ b/docs/src/reference-main-null-data.md.in @@ -34,7 +34,7 @@ GENMD-RUN-COMMAND mlr sort -nr a data/sort-null.dat GENMD-EOF -* Functions/operators which have one or more *empty* arguments produce empty output: e.g. +* Most functions/operators which have one or more *empty* arguments produce empty output: e.g. GENMD-RUN-COMMAND echo 'x=2,y=3' | mlr put '$a=$x+$y' @@ -54,6 +54,33 @@ GENMD-RUN-COMMAND echo 'x=,y=3' | mlr put '$a=min($x,$y);$b=max($x,$y)' GENMD-EOF +Likewise, empty works like 0 for addition and subtraction, and multiplication: + +GENMD-RUN-COMMAND +echo 'x=,y=3' | mlr put '$a = $x + $y; $b = $x - $y; $c = $x * $y' +GENMD-EOF + +This is intended to follow the arithmetic rule for absent data (explained next). In particular: + +* For file formats allowing for heterogeneity in keys, e.g. JSON, you should be able to keep a running sum of some field, say `$x`. If a given record doesn't have `$x`, then `$x` will be absent for that record, and the sum should simply continue. +* For CSV and TSV, which don't allow for hetrogeneity in keys, the _only_ way a value can be missing is to be empty. Here, if a given record doesn't have `$x`, then `$x` will be empty for that record, and the sum should simply continue. + +GENMD-RUN-COMMAND +cat missings.json +GENMD-EOF + +GENMD-RUN-COMMAND +mlr --ijson --from missings.json put -q 'begin { @sum = 0 } @sum += $x; end { print @sum }' +GENMD-EOF + +GENMD-RUN-COMMAND +cat missings.csv +GENMD-EOF + +GENMD-RUN-COMMAND +mlr --icsv --from missings.csv put -q 'begin { @sum = 0 } @sum += $x; end { print @sum }' +GENMD-EOF + * Functions of *absent* variables (e.g. `mlr put '$y = log10($nonesuch)'`) evaluate to absent, and arithmetic/bitwise/boolean operators with both operands being absent evaluate to absent. Arithmetic operators with one absent operand return the other operand. More specifically, absent values act like zero for addition/subtraction, and one for multiplication: Furthermore, **any expression which evaluates to absent is not stored in the left-hand side of an assignment statement**: GENMD-RUN-COMMAND @@ -68,8 +95,6 @@ GENMD-EOF The reasoning is as follows: -* Empty values are explicit in the data so they should explicitly affect accumulations: `mlr put '@sum += $x'` should accumulate numeric `x` values into the sum but an empty `x`, when encountered in the input data stream, should make the sum non-numeric. To work around this you can use the `is_not_null` function as follows: `mlr put 'is_not_null($x) { @sum += $x }'` - * Absent stream-record values should not break accumulations, since Miller by design handles heterogeneous data: the running `@sum` in `mlr put '@sum += $x'` should not be invalidated for records which have no `x`. * Absent out-of-stream-variable values are precisely what allow you to write `mlr put '@sum += $x'`. Otherwise you would have to write `mlr put 'begin{@sum = 0}; @sum += $x'` -- which is tolerable -- but for `mlr put 'begin{...}; @sum[$a][$b] += $x'` you'd have to pre-initialize `@sum` for all values of `$a` and `$b` in your input data stream, which is intolerable. diff --git a/docs/src/split_circle.csv b/docs/src/split_circle.csv new file mode 100644 index 0000000000..6ea6a0a937 --- /dev/null +++ b/docs/src/split_circle.csv @@ -0,0 +1,4 @@ +color,shape,flag,k,index,quantity,rate +red,circle,true,3,16,13.8103,2.9010 +yellow,circle,true,8,73,63.9785,4.2370 +yellow,circle,true,9,87,63.5058,8.3350 diff --git a/docs/src/split_square.csv b/docs/src/split_square.csv new file mode 100644 index 0000000000..122663bfec --- /dev/null +++ b/docs/src/split_square.csv @@ -0,0 +1,5 @@ +color,shape,flag,k,index,quantity,rate +red,square,true,2,15,79.2778,0.0130 +red,square,false,4,48,77.5542,7.4670 +red,square,false,6,64,77.1991,9.5310 +purple,square,false,10,91,72.3735,8.2430 diff --git a/docs/src/split_triangle.csv b/docs/src/split_triangle.csv new file mode 100644 index 0000000000..70bce77e6c --- /dev/null +++ b/docs/src/split_triangle.csv @@ -0,0 +1,4 @@ +color,shape,flag,k,index,quantity,rate +yellow,triangle,true,1,11,43.6498,9.8870 +purple,triangle,false,5,51,81.2290,8.5910 +purple,triangle,false,7,65,80.1405,5.8240 diff --git a/internal/pkg/bifs/arithmetic.go b/internal/pkg/bifs/arithmetic.go index 86f6d1e7f9..871874e7e5 100644 --- a/internal/pkg/bifs/arithmetic.go +++ b/internal/pkg/bifs/arithmetic.go @@ -14,7 +14,7 @@ var upos_dispositions = [mlrval.MT_DIM]UnaryFunc{ /*INT */ _1u___, /*FLOAT */ _1u___, /*BOOL */ _erro1, - /*VOID */ _void1, + /*VOID */ _zero1, /*STRING */ _erro1, /*ARRAY */ _absn1, /*MAP */ _absn1, @@ -43,7 +43,7 @@ var uneg_dispositions = [mlrval.MT_DIM]UnaryFunc{ /*INT */ uneg_i_i, /*FLOAT */ uneg_f_f, /*BOOL */ _erro1, - /*VOID */ _void1, + /*VOID */ _zero1, /*STRING */ _erro1, /*ARRAY */ _absn1, /*MAP */ _absn1, @@ -97,11 +97,11 @@ func plus_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { } var plus_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{ - // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT - /*INT */ {plus_n_ii, plus_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, - /*FLOAT */ {plus_f_fi, plus_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT + /*INT */ {plus_n_ii, plus_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + /*FLOAT */ {plus_f_fi, plus_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, /*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, - /*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, + /*VOID */ {_2___, _2___, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, /*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, /*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, @@ -155,11 +155,11 @@ func minus_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { } var minus_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{ - // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT - /*INT */ {minus_n_ii, minus_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, - /*FLOAT */ {minus_f_fi, minus_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT + /*INT */ {minus_n_ii, minus_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + /*FLOAT */ {minus_f_fi, minus_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, /*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, - /*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, + /*VOID */ {_n2__, _n2__, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, /*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, /*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, @@ -229,11 +229,11 @@ func times_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { } var times_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{ - // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT - /*INT */ {times_n_ii, times_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, - /*FLOAT */ {times_f_fi, times_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT + /*INT */ {times_n_ii, times_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + /*FLOAT */ {times_f_fi, times_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, /*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, - /*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, + /*VOID */ {_2___, _2___, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, /*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, /*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, @@ -389,11 +389,11 @@ func dotplus_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { } var dot_plus_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{ - // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT - /*INT */ {dotplus_i_ii, dotplus_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, - /*FLOAT */ {dotplus_f_fi, dotplus_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT + /*INT */ {dotplus_i_ii, dotplus_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + /*FLOAT */ {dotplus_f_fi, dotplus_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, /*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, - /*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, + /*VOID */ {_2___, _2___, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, /*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, /*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, @@ -425,11 +425,11 @@ func dotminus_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { } var dotminus_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{ - // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT - /*INT */ {dotminus_i_ii, dotminus_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, - /*FLOAT */ {dotminus_f_fi, dotminus_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT + /*INT */ {dotminus_i_ii, dotminus_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + /*FLOAT */ {dotminus_f_fi, dotminus_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, /*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, - /*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, + /*VOID */ {_n2__, _n2__, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, /*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, /*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, @@ -461,11 +461,11 @@ func dottimes_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { } var dottimes_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{ - // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT - /*INT */ {dottimes_i_ii, dottimes_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, - /*FLOAT */ {dottimes_f_fi, dottimes_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + // . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT + /*INT */ {dottimes_i_ii, dottimes_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, + /*FLOAT */ {dottimes_f_fi, dottimes_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___}, /*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, - /*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, + /*VOID */ {_n2__, _n2__, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn}, /*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro}, /*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn}, diff --git a/internal/pkg/bifs/base.go b/internal/pkg/bifs/base.go index 700cfab262..36aeb63d28 100644 --- a/internal/pkg/bifs/base.go +++ b/internal/pkg/bifs/base.go @@ -106,6 +106,11 @@ func _zero1(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mlrval.FromInt(0) } +// Return one (unary) +func __one1(input1 *mlrval.Mlrval) *mlrval.Mlrval { + return mlrval.FromInt(1) +} + // Return null (unary) func _null1(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mlrval.NULL diff --git a/internal/pkg/terminals/help/entry.go b/internal/pkg/terminals/help/entry.go index 5fe7c9a9f7..17130fe26d 100644 --- a/internal/pkg/terminals/help/entry.go +++ b/internal/pkg/terminals/help/entry.go @@ -486,6 +486,7 @@ func helpTypeArithmeticInfo() { mlrvals := []*mlrval.Mlrval{ mlrval.FromInt(1), mlrval.FromFloat(2.5), + mlrval.VOID, mlrval.ABSENT, mlrval.ERROR, } @@ -497,17 +498,27 @@ func helpTypeArithmeticInfo() { fmt.Printf("%-10s |", "(+)") } else if i == -1 { fmt.Printf("%-10s +", "------") + } else if mlrvals[i].IsVoid() { + fmt.Printf("%-10s |", "(empty)") } else { fmt.Printf("%-10s |", mlrvals[i].String()) } for j := 0; j < n; j++ { if i == -2 { - fmt.Printf(" %-10s", mlrvals[j].String()) + if mlrvals[j].IsVoid() { + fmt.Printf("%-10s", "(empty)") + } else { + fmt.Printf(" %-10s", mlrvals[j].String()) + } } else if i == -1 { fmt.Printf(" %-10s", "------") } else { sum := bifs.BIF_plus_binary(mlrvals[i], mlrvals[j]) - fmt.Printf(" %-10s", sum.String()) + if sum.IsVoid() { + fmt.Printf(" %-10s", "(empty)") + } else { + fmt.Printf(" %-10s", sum.String()) + } } } fmt.Println() diff --git a/man/manpage.txt b/man/manpage.txt index a4bb520495..43f2ed3865 100644 --- a/man/manpage.txt +++ b/man/manpage.txt @@ -3613,4 +3613,4 @@ MILLER(1) MILLER(1) - 2023-08-26 MILLER(1) + 2023-08-27 MILLER(1) diff --git a/man/mlr.1 b/man/mlr.1 index 702d51667c..51320a9a88 100644 --- a/man/mlr.1 +++ b/man/mlr.1 @@ -2,12 +2,12 @@ .\" Title: mlr .\" Author: [see the "AUTHOR" section] .\" Generator: ./mkman.rb -.\" Date: 2023-08-26 +.\" Date: 2023-08-27 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MILLER" "1" "2023-08-26" "\ \&" "\ \&" +.TH "MILLER" "1" "2023-08-27" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Portability definitions .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/test/cases/dsl-absent-empty/0009/expout b/test/cases/dsl-absent-empty/0009/expout index 0a9b64d06d..eaae444884 100644 --- a/test/cases/dsl-absent-empty/0009/expout +++ b/test/cases/dsl-absent-empty/0009/expout @@ -1,6 +1,6 @@ x=1,y=2,z=3 -x=1,y=,z= -x=,y=2,z= +x=1,y=,z=1 +x=,y=2,z=2 x=,y=,z= a=1,y=2,z=2 a=1,y= diff --git a/test/cases/dsl-absent-empty/0011/expout b/test/cases/dsl-absent-empty/0011/expout index 46b9c18aa8..e13ed42e18 100644 --- a/test/cases/dsl-absent-empty/0011/expout +++ b/test/cases/dsl-absent-empty/0011/expout @@ -1,24 +1,24 @@ s=2 x=1,y=2 -s= +s=2 x=1,y= -s= +s=4 x=,y=2 -s= +s=4 x=,y= -s= +s=6 a=1,y=2 -s= +s=6 a=1,y= -s= +s=8 a=,y=2 -s= +s=8 a=,y= -s= +s=8 x=1,b=2 -s= +s=8 x=1,b= -s= +s=8 x=,b=2 -s= +s=8 x=,b= diff --git a/test/cases/dsl-absent-empty/0013/expout b/test/cases/dsl-absent-empty/0013/expout index 35bd567868..68ab9a155d 100644 --- a/test/cases/dsl-absent-empty/0013/expout +++ b/test/cases/dsl-absent-empty/0013/expout @@ -1,6 +1,6 @@ x=int,y=int,z=int -x=int,y=empty,z=empty -x=empty,y=int,z=empty +x=int,y=empty,z=int +x=empty,y=int,z=int x=empty,y=empty,z=empty a=1,y=int,z=int,x=absent a=1,y=empty,x=absent,z=absent diff --git a/test/cases/dsl-absent-empty/0015/expout b/test/cases/dsl-absent-empty/0015/expout index cfcebeab9c..bef580d780 100644 --- a/test/cases/dsl-absent-empty/0015/expout +++ b/test/cases/dsl-absent-empty/0015/expout @@ -1,12 +1,12 @@ x=int,y=int,z=absent,s=int -x=int,y=empty,z=absent,s=empty -x=empty,y=int,z=absent,s=empty -x=empty,y=empty,z=absent,s=empty -a=1,y=int,x=absent,z=absent,s=empty -a=1,y=empty,x=absent,z=absent,s=empty -a=,y=int,x=absent,z=absent,s=empty -a=,y=empty,x=absent,z=absent,s=empty -x=int,b=2,y=absent,z=absent,s=empty -x=int,b=,y=absent,z=absent,s=empty -x=empty,b=2,y=absent,z=absent,s=empty -x=empty,b=,y=absent,z=absent,s=empty +x=int,y=empty,z=absent,s=int +x=empty,y=int,z=absent,s=int +x=empty,y=empty,z=absent,s=int +a=1,y=int,x=absent,z=absent,s=int +a=1,y=empty,x=absent,z=absent,s=int +a=,y=int,x=absent,z=absent,s=int +a=,y=empty,x=absent,z=absent,s=int +x=int,b=2,y=absent,z=absent,s=int +x=int,b=,y=absent,z=absent,s=int +x=empty,b=2,y=absent,z=absent,s=int +x=empty,b=,y=absent,z=absent,s=int diff --git a/test/cases/dsl-absent-empty/0018/expout b/test/cases/dsl-absent-empty/0018/expout index 5f0fd1b7cb..245f83dfe6 100644 --- a/test/cases/dsl-absent-empty/0018/expout +++ b/test/cases/dsl-absent-empty/0018/expout @@ -1,4 +1,4 @@ x=1 ostype=absent xtype=int nstype=int nsum=1 -x= osum=1 ostype=int xtype=empty nstype=empty nsum= -x=7 osum= ostype=empty xtype=int nstype=empty nsum= -sum= +x= osum=1 ostype=int xtype=empty nstype=int nsum=1 +x=7 osum=1 ostype=int xtype=int nstype=int nsum=8 +sum=8 diff --git a/test/cases/dsl-absent-empty/0019/expout b/test/cases/dsl-absent-empty/0019/expout index 5f0fd1b7cb..245f83dfe6 100644 --- a/test/cases/dsl-absent-empty/0019/expout +++ b/test/cases/dsl-absent-empty/0019/expout @@ -1,4 +1,4 @@ x=1 ostype=absent xtype=int nstype=int nsum=1 -x= osum=1 ostype=int xtype=empty nstype=empty nsum= -x=7 osum= ostype=empty xtype=int nstype=empty nsum= -sum= +x= osum=1 ostype=int xtype=empty nstype=int nsum=1 +x=7 osum=1 ostype=int xtype=int nstype=int nsum=8 +sum=8 diff --git a/test/cases/dsl-absent-empty/0024/expout b/test/cases/dsl-absent-empty/0024/expout index e65c673b38..d9c7706251 100644 --- a/test/cases/dsl-absent-empty/0024/expout +++ b/test/cases/dsl-absent-empty/0024/expout @@ -1,4 +1,4 @@ x=1 xtype=int sum=11 stype=int -x= xtype=empty sum= stype=empty +x= xtype=empty sum=10 stype=int y= xtype=absent sum=10 stype=int x=7 xtype=int sum=17 stype=int diff --git a/test/cases/dsl-absent-empty/0025/expout b/test/cases/dsl-absent-empty/0025/expout index 1f25de3ba8..1c914b16e0 100644 --- a/test/cases/dsl-absent-empty/0025/expout +++ b/test/cases/dsl-absent-empty/0025/expout @@ -1,4 +1,4 @@ x=1 xtype=int sum=11 stype=int -x= xtype=empty sum= stype=empty +x= xtype=empty sum=10 stype=int y= xtype=absent sum=999 stype=int x=7 xtype=int sum=17 stype=int diff --git a/test/cases/dsl-null-empty-handling/0005/expout b/test/cases/dsl-null-empty-handling/0005/expout index 578780bf4c..ffaf4cbd05 100644 --- a/test/cases/dsl-null-empty-handling/0005/expout +++ b/test/cases/dsl-null-empty-handling/0005/expout @@ -1,3 +1,3 @@ x=1,y=2,s=hello,z=3 -x=1,y=,s=,z= +x=1,y=,s=,z=1 x=,y=,s=hurrah,z= diff --git a/test/cases/dsl-null-empty-handling/0018/expout b/test/cases/dsl-null-empty-handling/0018/expout index 533c22c7c9..16af929a2b 100644 --- a/test/cases/dsl-null-empty-handling/0018/expout +++ b/test/cases/dsl-null-empty-handling/0018/expout @@ -1,6 +1,6 @@ x=1 y=2 xy=3 sy=2 xt=1 -x=1 y= xy= xt=1 -x= y=2 xy= sy=2 +x=1 y= xy=1 xt=1 +x= y=2 xy=2 sy=2 x= y= xy= a=1 y=2 xy=2 sy=2 a=1 y= diff --git a/test/cases/dsl-null-empty-handling/0019/expout b/test/cases/dsl-null-empty-handling/0019/expout index 12833dc938..8f1ee88802 100644 --- a/test/cases/dsl-null-empty-handling/0019/expout +++ b/test/cases/dsl-null-empty-handling/0019/expout @@ -1,11 +1,11 @@ x=1 y=2 xy=3 sy=5 xt=1 st=3 -x=1 y= xy= sy= xt=1 st=3 -x= y=2 xy= sy=5 st=3 -x= y= xy= sy= st=3 +x=1 y= xy=1 sy=3 xt=1 st=3 +x= y=2 xy=2 sy=5 st=3 +x= y= xy= sy=3 st=3 a=1 y=2 xy=2 sy=5 st=3 -a=1 y= sy= st=3 +a=1 y= sy=3 st=3 a= y=2 xy=2 sy=5 st=3 -a= y= sy= st=3 +a= y= sy=3 st=3 x=1 b=2 xy=1 sy=3 xt=1 st=3 x=1 b= xy=1 sy=3 xt=1 st=3 x= b=2 sy=3 st=3 diff --git a/test/cases/dsl-null-empty-handling/0020/expout b/test/cases/dsl-null-empty-handling/0020/expout index bac8fc502c..40c4af232d 100644 --- a/test/cases/dsl-null-empty-handling/0020/expout +++ b/test/cases/dsl-null-empty-handling/0020/expout @@ -1,12 +1,12 @@ x=1 y=2 xy=3 sy=2 xt=5 st=4 -x=1 y= xy= xt=5 st=4 -x= y=2 xy= sy=2 xt= st=4 -x= y= xy= xt= st=4 +x=1 y= xy=1 xt=5 st=4 +x= y=2 xy=2 sy=2 xt=4 st=4 +x= y= xy= xt=4 st=4 a=1 y=2 xy=2 sy=2 xt=4 st=4 a=1 y= xt=4 st=4 a= y=2 xy=2 sy=2 xt=4 st=4 a= y= xt=4 st=4 x=1 b=2 xy=1 xt=5 st=4 x=1 b= xy=1 xt=5 st=4 -x= b=2 xt= st=4 -x= b= xt= st=4 +x= b=2 xt=4 st=4 +x= b= xt=4 st=4 diff --git a/test/cases/dsl-null-empty-handling/0021/expout b/test/cases/dsl-null-empty-handling/0021/expout index a57679797d..76d169e421 100644 --- a/test/cases/dsl-null-empty-handling/0021/expout +++ b/test/cases/dsl-null-empty-handling/0021/expout @@ -1,12 +1,12 @@ x=1 y=2 xy=3 sy=5 xt=5 st=7 -x=1 y= xy= sy= xt=5 st=7 -x= y=2 xy= sy=5 xt= st=7 -x= y= xy= sy= xt= st=7 +x=1 y= xy=1 sy=3 xt=5 st=7 +x= y=2 xy=2 sy=5 xt=4 st=7 +x= y= xy= sy=3 xt=4 st=7 a=1 y=2 xy=2 sy=5 xt=4 st=7 -a=1 y= sy= xt=4 st=7 +a=1 y= sy=3 xt=4 st=7 a= y=2 xy=2 sy=5 xt=4 st=7 -a= y= sy= xt=4 st=7 +a= y= sy=3 xt=4 st=7 x=1 b=2 xy=1 sy=3 xt=5 st=7 x=1 b= xy=1 sy=3 xt=5 st=7 -x= b=2 sy=3 xt= st=7 -x= b= sy=3 xt= st=7 +x= b=2 sy=3 xt=4 st=7 +x= b= sy=3 xt=4 st=7 diff --git a/test/cases/dsl-null-empty-handling/0022/expout b/test/cases/dsl-null-empty-handling/0022/expout index b8d0e6ef30..2ec0bac9c6 100644 --- a/test/cases/dsl-null-empty-handling/0022/expout +++ b/test/cases/dsl-null-empty-handling/0022/expout @@ -1,6 +1,6 @@ x=1 y=2 xy=-1 sy=2 xt=1 -x=1 y= xy= xt=1 -x= y=2 xy= sy=2 +x=1 y= xy=1 xt=1 +x= y=2 xy=-2 sy=2 x= y= xy= a=1 y=2 xy=2 sy=2 a=1 y= diff --git a/test/cases/dsl-null-empty-handling/0023/expout b/test/cases/dsl-null-empty-handling/0023/expout index 60236a2bfe..5490ccccde 100644 --- a/test/cases/dsl-null-empty-handling/0023/expout +++ b/test/cases/dsl-null-empty-handling/0023/expout @@ -1,11 +1,11 @@ x=1 y=2 xy=-1 sy=1 xt=1 st=3 -x=1 y= xy= sy= xt=1 st=3 -x= y=2 xy= sy=1 st=3 -x= y= xy= sy= st=3 +x=1 y= xy=1 sy=3 xt=1 st=3 +x= y=2 xy=-2 sy=1 st=3 +x= y= xy= sy=3 st=3 a=1 y=2 xy=2 sy=1 st=3 -a=1 y= sy= st=3 +a=1 y= sy=3 st=3 a= y=2 xy=2 sy=1 st=3 -a= y= sy= st=3 +a= y= sy=3 st=3 x=1 b=2 xy=1 sy=3 xt=1 st=3 x=1 b= xy=1 sy=3 xt=1 st=3 x= b=2 sy=3 st=3 diff --git a/test/cases/dsl-null-empty-handling/0024/expout b/test/cases/dsl-null-empty-handling/0024/expout index decc36a948..df8e604895 100644 --- a/test/cases/dsl-null-empty-handling/0024/expout +++ b/test/cases/dsl-null-empty-handling/0024/expout @@ -1,12 +1,12 @@ x=1 y=2 xy=-1 sy=2 xt=-3 st=4 -x=1 y= xy= xt=-3 st=4 -x= y=2 xy= sy=2 xt= st=4 -x= y= xy= xt= st=4 +x=1 y= xy=1 xt=-3 st=4 +x= y=2 xy=-2 sy=2 xt=-4 st=4 +x= y= xy= xt=-4 st=4 a=1 y=2 xy=2 sy=2 xt=4 st=4 a=1 y= xt=4 st=4 a= y=2 xy=2 sy=2 xt=4 st=4 a= y= xt=4 st=4 x=1 b=2 xy=1 xt=-3 st=4 x=1 b= xy=1 xt=-3 st=4 -x= b=2 xt= st=4 -x= b= xt= st=4 +x= b=2 xt=-4 st=4 +x= b= xt=-4 st=4 diff --git a/test/cases/dsl-null-empty-handling/0025/expout b/test/cases/dsl-null-empty-handling/0025/expout index c19e412d0b..ab04b574e9 100644 --- a/test/cases/dsl-null-empty-handling/0025/expout +++ b/test/cases/dsl-null-empty-handling/0025/expout @@ -1,12 +1,12 @@ x=1 y=2 xy=-1 sy=1 xt=-3 st=-1 -x=1 y= xy= sy= xt=-3 st=-1 -x= y=2 xy= sy=1 xt= st=-1 -x= y= xy= sy= xt= st=-1 +x=1 y= xy=1 sy=3 xt=-3 st=-1 +x= y=2 xy=-2 sy=1 xt=-4 st=-1 +x= y= xy= sy=3 xt=-4 st=-1 a=1 y=2 xy=2 sy=1 xt=4 st=-1 -a=1 y= sy= xt=4 st=-1 +a=1 y= sy=3 xt=4 st=-1 a= y=2 xy=2 sy=1 xt=4 st=-1 -a= y= sy= xt=4 st=-1 +a= y= sy=3 xt=4 st=-1 x=1 b=2 xy=1 sy=3 xt=-3 st=-1 x=1 b= xy=1 sy=3 xt=-3 st=-1 -x= b=2 sy=3 xt= st=-1 -x= b= sy=3 xt= st=-1 +x= b=2 sy=3 xt=-4 st=-1 +x= b= sy=3 xt=-4 st=-1 diff --git a/test/cases/dsl-null-empty-handling/0026/expout b/test/cases/dsl-null-empty-handling/0026/expout index 5ed9ed8076..b96c6e6612 100644 --- a/test/cases/dsl-null-empty-handling/0026/expout +++ b/test/cases/dsl-null-empty-handling/0026/expout @@ -1,6 +1,6 @@ x=1 y=2 xy=2 sy=2 xt=1 -x=1 y= xy= xt=1 -x= y=2 xy= sy=2 +x=1 y= xy=1 xt=1 +x= y=2 xy=2 sy=2 x= y= xy= a=1 y=2 xy=2 sy=2 a=1 y= diff --git a/test/cases/dsl-null-empty-handling/0027/expout b/test/cases/dsl-null-empty-handling/0027/expout index 70c01ab4bb..8b51ffa510 100644 --- a/test/cases/dsl-null-empty-handling/0027/expout +++ b/test/cases/dsl-null-empty-handling/0027/expout @@ -1,11 +1,11 @@ x=1 y=2 xy=2 sy=6 xt=1 st=3 -x=1 y= xy= sy= xt=1 st=3 -x= y=2 xy= sy=6 st=3 -x= y= xy= sy= st=3 +x=1 y= xy=1 sy=3 xt=1 st=3 +x= y=2 xy=2 sy=6 st=3 +x= y= xy= sy=3 st=3 a=1 y=2 xy=2 sy=6 st=3 -a=1 y= sy= st=3 +a=1 y= sy=3 st=3 a= y=2 xy=2 sy=6 st=3 -a= y= sy= st=3 +a= y= sy=3 st=3 x=1 b=2 xy=1 sy=3 xt=1 st=3 x=1 b= xy=1 sy=3 xt=1 st=3 x= b=2 sy=3 st=3 diff --git a/test/cases/dsl-null-empty-handling/0028/expout b/test/cases/dsl-null-empty-handling/0028/expout index 862ac3fc46..ccb1e4fa7b 100644 --- a/test/cases/dsl-null-empty-handling/0028/expout +++ b/test/cases/dsl-null-empty-handling/0028/expout @@ -1,12 +1,12 @@ x=1 y=2 xy=2 sy=2 xt=4 st=4 -x=1 y= xy= xt=4 st=4 -x= y=2 xy= sy=2 xt= st=4 -x= y= xy= xt= st=4 +x=1 y= xy=1 xt=4 st=4 +x= y=2 xy=2 sy=2 xt=4 st=4 +x= y= xy= xt=4 st=4 a=1 y=2 xy=2 sy=2 xt=4 st=4 a=1 y= xt=4 st=4 a= y=2 xy=2 sy=2 xt=4 st=4 a= y= xt=4 st=4 x=1 b=2 xy=1 xt=4 st=4 x=1 b= xy=1 xt=4 st=4 -x= b=2 xt= st=4 -x= b= xt= st=4 +x= b=2 xt=4 st=4 +x= b= xt=4 st=4 diff --git a/test/cases/dsl-null-empty-handling/0029/expout b/test/cases/dsl-null-empty-handling/0029/expout index c6d1029429..e5309caf0c 100644 --- a/test/cases/dsl-null-empty-handling/0029/expout +++ b/test/cases/dsl-null-empty-handling/0029/expout @@ -1,12 +1,12 @@ x=1 y=2 xy=2 sy=6 xt=4 st=12 -x=1 y= xy= sy= xt=4 st=12 -x= y=2 xy= sy=6 xt= st=12 -x= y= xy= sy= xt= st=12 +x=1 y= xy=1 sy=3 xt=4 st=12 +x= y=2 xy=2 sy=6 xt=4 st=12 +x= y= xy= sy=3 xt=4 st=12 a=1 y=2 xy=2 sy=6 xt=4 st=12 -a=1 y= sy= xt=4 st=12 +a=1 y= sy=3 xt=4 st=12 a= y=2 xy=2 sy=6 xt=4 st=12 -a= y= sy= xt=4 st=12 +a= y= sy=3 xt=4 st=12 x=1 b=2 xy=1 sy=3 xt=4 st=12 x=1 b= xy=1 sy=3 xt=4 st=12 -x= b=2 sy=3 xt= st=12 -x= b= sy=3 xt= st=12 +x= b=2 sy=3 xt=4 st=12 +x= b= sy=3 xt=4 st=12