alf-shell 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +5 -2
- data/Gemfile.lock +29 -10
- data/bin/alf +2 -0
- data/doc/man/alf-explain.man +22 -0
- data/doc/man/alf-metadata.man +13 -0
- data/doc/man/alf-show.man +16 -0
- data/doc/man/alf.man +77 -0
- data/doc/man/allbut.man +39 -0
- data/doc/man/among.man +25 -0
- data/doc/man/avg.man +37 -0
- data/doc/man/between.man +24 -0
- data/doc/man/concat.man +55 -0
- data/doc/man/contradiction.man +26 -0
- data/doc/man/count.man +20 -0
- data/doc/man/eq.man +29 -0
- data/doc/man/extend.man +33 -0
- data/doc/man/frame.man +60 -0
- data/doc/man/group.man +51 -0
- data/doc/man/gt.man +30 -0
- data/doc/man/gte.man +30 -0
- data/doc/man/intersect.man +54 -0
- data/doc/man/join.man +84 -0
- data/doc/man/lt.man +30 -0
- data/doc/man/lte.man +30 -0
- data/doc/man/matching.man +73 -0
- data/doc/man/max.man +36 -0
- data/doc/man/min.man +36 -0
- data/doc/man/minus.man +54 -0
- data/doc/man/native.man +32 -0
- data/doc/man/neq.man +29 -0
- data/doc/man/not_matching.man +51 -0
- data/doc/man/page.man +60 -0
- data/doc/man/project.man +36 -0
- data/doc/man/rank.man +42 -0
- data/doc/man/rename.man +29 -0
- data/doc/man/restrict.man +38 -0
- data/doc/man/stddev.man +37 -0
- data/doc/man/sum.man +37 -0
- data/doc/man/summarize.man +45 -0
- data/doc/man/tautology.man +26 -0
- data/doc/man/ungroup.man +30 -0
- data/doc/man/union.man +55 -0
- data/doc/man/unwrap.man +37 -0
- data/doc/man/variance.man +37 -0
- data/doc/man/wrap.man +37 -0
- data/doc/txt/alf-explain.man +22 -0
- data/doc/txt/alf-metadata.man +16 -0
- data/doc/txt/alf-show.man +19 -0
- data/doc/txt/alf.man +80 -0
- data/doc/txt/allbut.txt +31 -0
- data/doc/txt/among.txt +20 -0
- data/doc/txt/avg.txt +22 -0
- data/doc/txt/between.txt +19 -0
- data/doc/txt/concat.txt +31 -0
- data/doc/txt/contradiction.txt +15 -0
- data/doc/txt/count.txt +14 -0
- data/doc/txt/eq.txt +19 -0
- data/doc/txt/extend.txt +29 -0
- data/doc/txt/frame.txt +48 -0
- data/doc/txt/group.txt +37 -0
- data/doc/txt/gt.txt +20 -0
- data/doc/txt/gte.txt +20 -0
- data/doc/txt/intersect.txt +42 -0
- data/doc/txt/join.txt +65 -0
- data/doc/txt/lt.txt +20 -0
- data/doc/txt/lte.txt +20 -0
- data/doc/txt/matching.txt +54 -0
- data/doc/txt/max.txt +21 -0
- data/doc/txt/min.txt +21 -0
- data/doc/txt/minus.txt +42 -0
- data/doc/txt/native.txt +27 -0
- data/doc/txt/neq.txt +19 -0
- data/doc/txt/not_matching.txt +39 -0
- data/doc/txt/page.txt +48 -0
- data/doc/txt/project.txt +28 -0
- data/doc/txt/rank.txt +34 -0
- data/doc/txt/rename.txt +25 -0
- data/doc/txt/restrict.txt +26 -0
- data/doc/txt/stddev.txt +22 -0
- data/doc/txt/sum.txt +22 -0
- data/doc/txt/summarize.txt +33 -0
- data/doc/txt/tautology.txt +15 -0
- data/doc/txt/ungroup.txt +26 -0
- data/doc/txt/union.txt +43 -0
- data/doc/txt/unwrap.txt +29 -0
- data/doc/txt/variance.txt +22 -0
- data/doc/txt/wrap.txt +29 -0
- data/lib/alf/shell.rb +2 -32
- data/lib/alf/shell/alfrc.rb +3 -0
- data/lib/alf/shell/command.rb +2 -18
- data/lib/alf/shell/command/explain.rb +37 -0
- data/lib/alf/shell/command/help.rb +3 -21
- data/lib/alf/shell/command/main.rb +20 -78
- data/lib/alf/shell/command/metadata.rb +32 -0
- data/lib/alf/shell/command/show.rb +17 -5
- data/lib/alf/shell/support.rb +21 -13
- data/lib/alf/shell/version.rb +1 -1
- data/spec/integration/explain/explain.cmd +1 -0
- data/spec/integration/explain/explain.stdout +11 -0
- data/spec/integration/show/group.alf +2 -0
- data/spec/integration/show/show_alf.cmd +1 -0
- data/spec/integration/{group/group_0.stdout → show/show_alf.stdout} +0 -0
- data/tasks/doc.rake +4 -0
- metadata +116 -178
- data/doc/commands/exec.md +0 -16
- data/doc/commands/help.md +0 -11
- data/doc/commands/main.md +0 -33
- data/doc/commands/show.md +0 -12
- data/doc/operators/non_relational/autonum.md +0 -23
- data/doc/operators/non_relational/clip.md +0 -31
- data/doc/operators/non_relational/coerce.md +0 -15
- data/doc/operators/non_relational/compact.md +0 -20
- data/doc/operators/non_relational/defaults.md +0 -32
- data/doc/operators/non_relational/generator.md +0 -20
- data/doc/operators/non_relational/sort.md +0 -24
- data/doc/operators/non_relational/type-safe.md +0 -20
- data/doc/operators/relational/extend.md +0 -18
- data/doc/operators/relational/frame.md +0 -26
- data/doc/operators/relational/group.md +0 -27
- data/doc/operators/relational/hierarchize.md +0 -14
- data/doc/operators/relational/infer-heading.md +0 -20
- data/doc/operators/relational/intersect.md +0 -13
- data/doc/operators/relational/join.md +0 -28
- data/doc/operators/relational/matching.md +0 -24
- data/doc/operators/relational/minus.md +0 -12
- data/doc/operators/relational/not-matching.md +0 -20
- data/doc/operators/relational/page.md +0 -31
- data/doc/operators/relational/project.md +0 -28
- data/doc/operators/relational/quota.md +0 -21
- data/doc/operators/relational/rank.md +0 -27
- data/doc/operators/relational/rename.md +0 -17
- data/doc/operators/relational/restrict.md +0 -25
- data/doc/operators/relational/summarize.md +0 -25
- data/doc/operators/relational/ungroup.md +0 -20
- data/doc/operators/relational/union.md +0 -14
- data/doc/operators/relational/unwrap.md +0 -20
- data/doc/operators/relational/wrap.md +0 -24
- data/lib/alf/shell/command/exec.rb +0 -16
- data/lib/alf/shell/doc_manager.rb +0 -84
- data/lib/alf/shell/ext/signature.rb +0 -45
- data/lib/alf/shell/from_argv.rb +0 -84
- data/lib/alf/shell/operator.rb +0 -63
- data/spec/integration/__database__/group.alf +0 -3
- data/spec/integration/alf/alf_e.cmd +0 -1
- data/spec/integration/alf/alf_e.stdout +0 -4
- data/spec/integration/alf/alf_help.cmd +0 -1
- data/spec/integration/alf/alf_help.stdout +0 -76
- data/spec/integration/alf/alf_r.cmd +0 -1
- data/spec/integration/alf/alf_r.stdout +0 -5
- data/spec/integration/autonum/autonum_0.cmd +0 -1
- data/spec/integration/autonum/autonum_0.stdout +0 -9
- data/spec/integration/autonum/autonum_1.cmd +0 -1
- data/spec/integration/autonum/autonum_1.stdout +0 -9
- data/spec/integration/clip/clip_0.cmd +0 -1
- data/spec/integration/clip/clip_0.stdout +0 -9
- data/spec/integration/clip/clip_1.cmd +0 -1
- data/spec/integration/clip/clip_1.stdout +0 -9
- data/spec/integration/coerce/coerce_1.cmd +0 -1
- data/spec/integration/coerce/coerce_1.stdout +0 -5
- data/spec/integration/compact/compact_0.cmd +0 -1
- data/spec/integration/compact/compact_0.stdout +0 -9
- data/spec/integration/defaults/defaults_0.cmd +0 -1
- data/spec/integration/defaults/defaults_0.stdout +0 -9
- data/spec/integration/defaults/defaults_1.cmd +0 -1
- data/spec/integration/defaults/defaults_1.stdout +0 -9
- data/spec/integration/defaults/defaults_2.cmd +0 -1
- data/spec/integration/defaults/defaults_2.stdout +0 -9
- data/spec/integration/extend/extend_0.cmd +0 -1
- data/spec/integration/extend/extend_0.stdout +0 -16
- data/spec/integration/frame/frame_0.cmd +0 -1
- data/spec/integration/frame/frame_0.stdout +0 -6
- data/spec/integration/generator/generator_1.cmd +0 -1
- data/spec/integration/generator/generator_1.stdout +0 -10
- data/spec/integration/generator/generator_2.cmd +0 -1
- data/spec/integration/generator/generator_2.stdout +0 -5
- data/spec/integration/generator/generator_3.cmd +0 -1
- data/spec/integration/generator/generator_3.stdout +0 -5
- data/spec/integration/group/group_0.cmd +0 -1
- data/spec/integration/group/group_1.cmd +0 -1
- data/spec/integration/group/group_1.stdout +0 -32
- data/spec/integration/help/help_1.cmd +0 -1
- data/spec/integration/help/help_1.stdout +0 -12
- data/spec/integration/intersect/intersect_0.cmd +0 -1
- data/spec/integration/intersect/intersect_0.stdout +0 -9
- data/spec/integration/join/join_0.cmd +0 -1
- data/spec/integration/join/join_0.stdout +0 -16
- data/spec/integration/matching/matching_0.cmd +0 -1
- data/spec/integration/matching/matching_0.stdout +0 -8
- data/spec/integration/minus/minus_0.cmd +0 -1
- data/spec/integration/minus/minus_0.stdout +0 -4
- data/spec/integration/not-matching/not-matching_0.cmd +0 -1
- data/spec/integration/not-matching/not-matching_0.stdout +0 -5
- data/spec/integration/page/page_0.cmd +0 -1
- data/spec/integration/page/page_0.stdout +0 -6
- data/spec/integration/project/project_0.cmd +0 -1
- data/spec/integration/project/project_0.stdout +0 -9
- data/spec/integration/project/project_1.cmd +0 -1
- data/spec/integration/project/project_1.stdout +0 -9
- data/spec/integration/quota/quota_0.cmd +0 -1
- data/spec/integration/quota/quota_0.stdout +0 -16
- data/spec/integration/rank/rank_1.cmd +0 -1
- data/spec/integration/rank/rank_1.stdout +0 -10
- data/spec/integration/rank/rank_2.cmd +0 -1
- data/spec/integration/rank/rank_2.stdout +0 -10
- data/spec/integration/rank/rank_3.cmd +0 -1
- data/spec/integration/rank/rank_3.stdout +0 -10
- data/spec/integration/rank/rank_4.cmd +0 -1
- data/spec/integration/rank/rank_4.stdout +0 -6
- data/spec/integration/rank/rank_5.cmd +0 -1
- data/spec/integration/rank/rank_5.stdout +0 -6
- data/spec/integration/rename/rename_0.cmd +0 -1
- data/spec/integration/rename/rename_0.stdout +0 -9
- data/spec/integration/restrict/restrict_0.cmd +0 -1
- data/spec/integration/restrict/restrict_0.stdout +0 -6
- data/spec/integration/restrict/restrict_1.cmd +0 -1
- data/spec/integration/restrict/restrict_1.stdout +0 -6
- data/spec/integration/sort/sort_0.cmd +0 -1
- data/spec/integration/sort/sort_0.stdout +0 -9
- data/spec/integration/sort/sort_1.cmd +0 -1
- data/spec/integration/sort/sort_1.stdout +0 -9
- data/spec/integration/sort/sort_2.cmd +0 -1
- data/spec/integration/sort/sort_2.stdout +0 -9
- data/spec/integration/sort/sort_3.cmd +0 -1
- data/spec/integration/sort/sort_3.stdout +0 -9
- data/spec/integration/summarize/summarize_0.cmd +0 -1
- data/spec/integration/summarize/summarize_0.stdout +0 -8
- data/spec/integration/union/union_0.cmd +0 -1
- data/spec/integration/union/union_0.stdout +0 -9
- data/spec/integration/unwrap/unwrap_0.cmd +0 -1
- data/spec/integration/unwrap/unwrap_0.stdout +0 -9
- data/spec/integration/wrap/wrap_0.cmd +0 -1
- data/spec/integration/wrap/wrap_0.stdout +0 -9
- data/spec/unit/doc_manager/dynamic.md +0 -1
- data/spec/unit/doc_manager/example.md +0 -1
- data/spec/unit/doc_manager/example_1.txt +0 -11
- data/spec/unit/doc_manager/static.md +0 -1
- data/spec/unit/doc_manager/test_call.rb +0 -41
- data/spec/unit/ext/signature/test_argv2args.rb +0 -82
- data/spec/unit/ext/signature/test_to_shell.rb +0 -103
- data/spec/unit/from_argv/test_to_attr_list.rb +0 -30
- data/spec/unit/from_argv/test_to_attr_name.rb +0 -27
- data/spec/unit/from_argv/test_to_boolean.rb +0 -32
- data/spec/unit/from_argv/test_to_heading.rb +0 -37
- data/spec/unit/from_argv/test_to_ordering.rb +0 -28
- data/spec/unit/from_argv/test_to_predicate.rb +0 -26
- data/spec/unit/from_argv/test_to_renaming.rb +0 -23
- data/spec/unit/from_argv/test_to_size.rb +0 -32
- data/spec/unit/from_argv/test_to_summarization.rb +0 -19
- data/spec/unit/from_argv/test_to_tuple_computation.rb +0 -18
- data/spec/unit/from_argv/test_to_tuple_expression.rb +0 -38
- data/spec/unit/main/test_class_methods.rb +0 -44
- data/spec/unit/operator/test_autonum.rb +0 -28
- data/spec/unit/operator/test_clip.rb +0 -29
- data/spec/unit/operator/test_coerce.rb +0 -22
- data/spec/unit/operator/test_compact.rb +0 -16
- data/spec/unit/operator/test_defaults.rb +0 -29
- data/spec/unit/operator/test_extend.rb +0 -21
- data/spec/unit/operator/test_generator.rb +0 -37
- data/spec/unit/operator/test_group.rb +0 -32
- data/spec/unit/operator/test_infer_heading.rb +0 -16
- data/spec/unit/operator/test_intersect.rb +0 -18
- data/spec/unit/operator/test_join.rb +0 -18
- data/spec/unit/operator/test_matching.rb +0 -18
- data/spec/unit/operator/test_minus.rb +0 -18
- data/spec/unit/operator/test_not_matching.rb +0 -18
- data/spec/unit/operator/test_project.rb +0 -38
- data/spec/unit/operator/test_quota.rb +0 -23
- data/spec/unit/operator/test_rank.rb +0 -30
- data/spec/unit/operator/test_rename.rb +0 -21
- data/spec/unit/operator/test_restrict.rb +0 -36
- data/spec/unit/operator/test_sort.rb +0 -49
- data/spec/unit/operator/test_summarize.rb +0 -30
- data/spec/unit/operator/test_ungroup.rb +0 -28
- data/spec/unit/operator/test_union.rb +0 -18
- data/spec/unit/operator/test_unwrap.rb +0 -28
- data/spec/unit/operator/test_wrap.rb +0 -30
data/doc/txt/sum.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Sum
|
|
2
|
+
|
|
3
|
+
Arithmetic sum
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
sum(expr: AttrName|(Tuple->Numeric)) -> Aggregator
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
sum(:qty)
|
|
11
|
+
sum{|t| t.qty * t.price }
|
|
12
|
+
sum(->(t){ t.qty * t.price })
|
|
13
|
+
|
|
14
|
+
## Description
|
|
15
|
+
|
|
16
|
+
Computes `v1 + v2 + ... + vn`.
|
|
17
|
+
|
|
18
|
+
## Implementation notes
|
|
19
|
+
|
|
20
|
+
This aggregate function should only be used with numeric types. As of
|
|
21
|
+
current Alf version, it does not aggregate empty sets correctly on
|
|
22
|
+
non-numeric data types.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Summarize
|
|
2
|
+
|
|
3
|
+
Aggregate and compute
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
summarize(operand: Relation, by: AttrList, aggs: Summarization) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
summarize(supplies, [:sid], total: sum(:qty))
|
|
12
|
+
|
|
13
|
+
summarize(supplies, [:sid], total: sum{|t| t.qty * 2 })
|
|
14
|
+
|
|
15
|
+
summarize(supplies, [:pid, :qty], {total: sum{|t| t.qty * 2 }}, allbut: true)
|
|
16
|
+
|
|
17
|
+
## Description
|
|
18
|
+
|
|
19
|
+
Computes the relation obtained by taking the projection of `operand`
|
|
20
|
+
on `by` attributes then extending each tuple `t` with the result of
|
|
21
|
+
aggregations defined by `aggs` on the tuples from `operand` matching `t`.
|
|
22
|
+
|
|
23
|
+
In SQL terms, `SELECT [by], [agg] FROM operand GROUP BY [by]`.
|
|
24
|
+
|
|
25
|
+
## Implementation notes
|
|
26
|
+
|
|
27
|
+
As of current Alf version, this operator cannot be translated to SQL code.
|
|
28
|
+
That means that all computations are done in ruby, which may seriously
|
|
29
|
+
hurt performance.
|
|
30
|
+
|
|
31
|
+
Similarly, as `summarize` tends to be a showstopper during compilation, it
|
|
32
|
+
is strongly recommanded to use it as high as possible in query expressions
|
|
33
|
+
trees so as to delegate the largest possible query parts to data engines.
|
data/doc/txt/ungroup.txt
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Ungroup
|
|
2
|
+
|
|
3
|
+
Inverse of group
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
ungroup(operand: Relation, rva: AttrName) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
ungroup(group(suppliers, [:city], :suppliers, allbut: true), :suppliers)
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
Computes the relation obtained by ungrouping a relation-valued attribute
|
|
16
|
+
`rva`. Ungrouping `rva` leads as many tuples as in `rva`, each extended
|
|
17
|
+
with the other attributes of `operand`.
|
|
18
|
+
|
|
19
|
+
`rva` must be a relation-valued attribute. It should not itself contain
|
|
20
|
+
any attribute whose name clashes with an attribute of `operand`.
|
|
21
|
+
|
|
22
|
+
## Implementation notes
|
|
23
|
+
|
|
24
|
+
This operator does not compile to SQL so far. Contributions are welcome
|
|
25
|
+
to provide it with a SQL compilation for SQL DBMSs that support this kind
|
|
26
|
+
of feature (e.g. PostgreSQL with JSON data type)
|
data/doc/txt/union.txt
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Union
|
|
2
|
+
|
|
3
|
+
Logical OR
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
union(left: Relation, right: Relation) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
union(project(suppliers, [:city]), project(parts, [:city]))
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
Computes the relation as the set union of `left` and `right`.
|
|
16
|
+
|
|
17
|
+
The `left` and `right` relations must be union-compatible, meaning that they
|
|
18
|
+
must have same heading (type inheritance is partly supported through ruby's
|
|
19
|
+
own type system, so that the actual behavior is slighlty more permissive).
|
|
20
|
+
|
|
21
|
+
## Implementation notes
|
|
22
|
+
|
|
23
|
+
Unlike SQL, this operator ALWAYS remove duplicates. There is no way, in
|
|
24
|
+
Alf, to compute _bags_ of tuples and therefore no way to express something
|
|
25
|
+
such as SQL's UNION ALL.
|
|
26
|
+
|
|
27
|
+
The optimizer is not smart enough so far to discover when operands are
|
|
28
|
+
actually disjoint and duplicate removal not needed (e.g. the SQL compiler
|
|
29
|
+
never generates UNION ALL). Any patch improving this is welcome!
|
|
30
|
+
|
|
31
|
+
Similarly, it is sometimes idiomatic in Alf to use `union` as a logical OR,
|
|
32
|
+
as illustrated below. So far, the optimizer/compiler is not smart enough to
|
|
33
|
+
translate the former in the latter (which is likely to have a better query
|
|
34
|
+
plan, especially when using faithful SQL compilation and usual SQL DBMSs).
|
|
35
|
+
Any patch is welcome here too!
|
|
36
|
+
|
|
37
|
+
union(
|
|
38
|
+
restrict(suppliers, city: 'Paris'),
|
|
39
|
+
restrict(suppliers, city: 'London'))
|
|
40
|
+
|
|
41
|
+
is equivalent to
|
|
42
|
+
|
|
43
|
+
restrict(suppliers, eq(:city, 'Paris') | eq(:city, 'London'))
|
data/doc/txt/unwrap.txt
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Unwrap
|
|
2
|
+
|
|
3
|
+
Inverse of wrap
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
unwrap(operand: Relation, tva: AttrName) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
unwrap(wrap(suppliers, [:city, :status], :extra), :extra)
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
Computes the relation obtained by unwrapping a tuple-valued attribute `tva`.
|
|
16
|
+
Unwrapping of `tva` on an input tuple `t` consists in removing `tva` from
|
|
17
|
+
`t` and extending the result with `tva`'s own attributes:
|
|
18
|
+
|
|
19
|
+
Tuple(x: 1, tva: Tuple(y: 2, z: 3)) -> Tuple(x: 1, y: 2, z: 3)
|
|
20
|
+
|
|
21
|
+
`tva` must be a tuple-valued attribute. It should not itself contain any
|
|
22
|
+
attribute whose name clashes with an attribute of `operand`. In the examples
|
|
23
|
+
above, `tva` may not contain an attribute called `x`.
|
|
24
|
+
|
|
25
|
+
## Implementation notes
|
|
26
|
+
|
|
27
|
+
This operator does not compile to SQL so far. Contributions are welcome to
|
|
28
|
+
provide it with a SQL compilation for SQL DBMSs that support this kind of
|
|
29
|
+
feature (e.g. PostgreSQL with JSON data type)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Variance
|
|
2
|
+
|
|
3
|
+
Variance
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
variance(expr: AttrName|(Tuple->Numeric)) -> Aggregator
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
variance(:qty)
|
|
11
|
+
variance{|t| t.qty * t.price }
|
|
12
|
+
variance(->(t){ t.qty * t.price })
|
|
13
|
+
|
|
14
|
+
## Description
|
|
15
|
+
|
|
16
|
+
Computes how far the set of input values is spread out.
|
|
17
|
+
|
|
18
|
+
## Implementation notes
|
|
19
|
+
|
|
20
|
+
This aggregate function should only be used with numeric types. As of
|
|
21
|
+
current Alf version, it does not aggregate empty sets correctly on
|
|
22
|
+
non-numeric data types.
|
data/doc/txt/wrap.txt
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Wrap
|
|
2
|
+
|
|
3
|
+
Tuple-valued attribute
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
wrap(operand: Relation, attributes: AttrList, as: AttrName) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
wrap(suppliers, [:city, :status], :extra)
|
|
12
|
+
|
|
13
|
+
wrap(suppliers, [:city, :status], :extra, allbut: true)
|
|
14
|
+
|
|
15
|
+
## Description
|
|
16
|
+
|
|
17
|
+
Computes the relation obtained by removing `attributes` and replacing them
|
|
18
|
+
by a single attribute (`as`). The latter is a tuple-valued attribute
|
|
19
|
+
obtained by projecting the input tuple on `attributes`.
|
|
20
|
+
|
|
21
|
+
This operators supports an ALL BUT variant, through the `allbut` option.
|
|
22
|
+
When set to true, the operator keeps specified attributes and wraps all the
|
|
23
|
+
remaining ones as a tuple-valued attribute.
|
|
24
|
+
|
|
25
|
+
## Implementation notes
|
|
26
|
+
|
|
27
|
+
This operator does not compile to SQL so far. Contributions are welcome to
|
|
28
|
+
provide it with a SQL compilation for SQL DBMSs that support this kind of
|
|
29
|
+
feature (e.g. PostgreSQL with JSON data type)
|
data/lib/alf/shell.rb
CHANGED
|
@@ -1,52 +1,22 @@
|
|
|
1
1
|
require_relative 'shell/version'
|
|
2
2
|
require_relative 'shell/loader'
|
|
3
|
-
require_relative 'shell/ext/signature'
|
|
4
3
|
require_relative 'shell/alfrc'
|
|
5
|
-
require_relative 'shell/doc_manager'
|
|
6
4
|
module Alf
|
|
7
5
|
module Shell
|
|
8
6
|
|
|
9
|
-
# This is the main documentation extractor
|
|
10
|
-
DOC_EXTRACTOR = DocManager.new
|
|
11
|
-
|
|
12
7
|
# This is the default configuration to be forked from
|
|
13
8
|
DEFAULT_CONFIG = Alfrc.new
|
|
14
9
|
|
|
15
|
-
# Delegator command factory
|
|
16
|
-
def self.Delegator()
|
|
17
|
-
Quickl::Delegator(){|builder|
|
|
18
|
-
builder.doc_extractor = DOC_EXTRACTOR
|
|
19
|
-
builder.class_module Command::ClassMethods
|
|
20
|
-
yield(builder) if block_given?
|
|
21
|
-
}
|
|
22
|
-
end
|
|
23
|
-
|
|
24
10
|
# Command factory
|
|
25
|
-
def self.Command()
|
|
26
|
-
Quickl::Command(){|builder|
|
|
27
|
-
builder.command_parent = Alf::Shell::Main
|
|
28
|
-
builder.doc_extractor = DOC_EXTRACTOR
|
|
29
|
-
builder.class_module Command::ClassMethods
|
|
30
|
-
builder.instance_module Shell::Support
|
|
31
|
-
yield(builder) if block_given?
|
|
32
|
-
}
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Operator factory
|
|
36
|
-
def self.Operator()
|
|
37
|
-
Quickl::Command(){|builder|
|
|
11
|
+
def self.Command(*args)
|
|
12
|
+
Quickl::Command(*args){|builder|
|
|
38
13
|
builder.command_parent = Alf::Shell::Main
|
|
39
|
-
builder.doc_extractor = DOC_EXTRACTOR
|
|
40
|
-
builder.class_module Operator::ClassMethods
|
|
41
14
|
builder.instance_module Shell::Support
|
|
42
|
-
builder.instance_module Operator::InstanceMethods
|
|
43
15
|
yield(builder) if block_given?
|
|
44
16
|
}
|
|
45
17
|
end
|
|
46
18
|
|
|
47
19
|
end # module Shell
|
|
48
20
|
end # module Alf
|
|
49
|
-
require_relative 'shell/from_argv'
|
|
50
21
|
require_relative 'shell/support'
|
|
51
22
|
require_relative 'shell/command'
|
|
52
|
-
require_relative 'shell/operator'
|
data/lib/alf/shell/alfrc.rb
CHANGED
|
@@ -11,6 +11,9 @@ module Alf
|
|
|
11
11
|
# Default renderer to use for outputting relations
|
|
12
12
|
option :default_renderer, Class, ->{ $stdout.tty? ? Renderer::Text : Renderer::Rash }
|
|
13
13
|
|
|
14
|
+
# Default reader name to use for reading on stdin
|
|
15
|
+
option :stdin_reader, Symbol, :rash
|
|
16
|
+
|
|
14
17
|
# Float format to use
|
|
15
18
|
option :float_format, String, "%.3f"
|
|
16
19
|
|
data/lib/alf/shell/command.rb
CHANGED
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
module Alf
|
|
2
|
-
module Command
|
|
3
|
-
module ClassMethods
|
|
4
|
-
|
|
5
|
-
# @return true
|
|
6
|
-
def command?
|
|
7
|
-
true
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# @return false
|
|
11
|
-
def operator?
|
|
12
|
-
false
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
end # module ClassMethods
|
|
16
|
-
end # module Command
|
|
17
|
-
end # module Alf
|
|
18
1
|
require_relative 'command/main'
|
|
19
|
-
require_relative 'command/exec'
|
|
20
2
|
require_relative 'command/help'
|
|
21
3
|
require_relative 'command/show'
|
|
4
|
+
require_relative 'command/metadata'
|
|
5
|
+
require_relative 'command/explain'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Alf
|
|
2
|
+
module Shell
|
|
3
|
+
class Explain < Shell::Command(__FILE__,__LINE__)
|
|
4
|
+
|
|
5
|
+
options do |opt|
|
|
6
|
+
|
|
7
|
+
opt.on_tail('-h', "--help", "Show help") do
|
|
8
|
+
show_help("alf-explain")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def run(argv, requester)
|
|
14
|
+
# set requester and parse options
|
|
15
|
+
@requester = requester
|
|
16
|
+
argv = parse_options(argv, :split)
|
|
17
|
+
|
|
18
|
+
operand = compile(argv)
|
|
19
|
+
|
|
20
|
+
puts "Logical plan:"
|
|
21
|
+
puts
|
|
22
|
+
puts operand.to_ascii_tree.gsub(/^/, " ")
|
|
23
|
+
|
|
24
|
+
puts
|
|
25
|
+
|
|
26
|
+
puts "Physical plan:"
|
|
27
|
+
puts
|
|
28
|
+
puts operand.to_cog.to_ascii_tree.gsub(/^/, " ")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def compile(argv)
|
|
32
|
+
operand(argv.shift)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end # class Explain
|
|
36
|
+
end # module Shell
|
|
37
|
+
end # module Alf
|
|
@@ -1,30 +1,12 @@
|
|
|
1
1
|
module Alf
|
|
2
2
|
module Shell
|
|
3
|
-
class Help < Shell::Command()
|
|
4
|
-
|
|
5
|
-
# Let NoSuchCommandError be passed to higher stage
|
|
6
|
-
no_react_to Quickl::NoSuchCommand
|
|
7
|
-
|
|
8
|
-
options do |opt|
|
|
9
|
-
@dialect = :shell
|
|
10
|
-
opt.on('--lispy',
|
|
11
|
-
'Display operator signatures in lispy DSL') do
|
|
12
|
-
@dialect = :lispy
|
|
13
|
-
end
|
|
14
|
-
opt.on('--shell',
|
|
15
|
-
'Display operator signatures in shell DSL') do
|
|
16
|
-
@dialect = :shell
|
|
17
|
-
end
|
|
18
|
-
end
|
|
3
|
+
class Help < Shell::Command(__FILE__, __LINE__)
|
|
19
4
|
|
|
20
5
|
# Command execution
|
|
21
6
|
def execute(args)
|
|
22
|
-
|
|
23
|
-
sub = (args.size != 1) ? sup : Quickl.sub_command!(sup, args.first)
|
|
24
|
-
doc = sub.documentation(:method => @dialect)
|
|
25
|
-
puts doc
|
|
7
|
+
show_help(args.first.strip)
|
|
26
8
|
end
|
|
27
|
-
|
|
9
|
+
|
|
28
10
|
end # class Help
|
|
29
11
|
end # module Shell
|
|
30
12
|
end # module Alf
|
|
@@ -1,49 +1,7 @@
|
|
|
1
1
|
module Alf
|
|
2
2
|
module Shell
|
|
3
|
-
class Main <
|
|
4
|
-
|
|
5
|
-
class << self
|
|
6
|
-
|
|
7
|
-
def relational_operators(sort_by_name = true)
|
|
8
|
-
ops = subcommands.select{|cmd|
|
|
9
|
-
cmd.operator? and cmd.relational? and !cmd.experimental?
|
|
10
|
-
}
|
|
11
|
-
sort_operators(ops, sort_by_name)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def experimental_operators(sort_by_name = true)
|
|
15
|
-
ops = subcommands.select{|cmd|
|
|
16
|
-
cmd.operator? and cmd.relational? and cmd.experimental?
|
|
17
|
-
}
|
|
18
|
-
sort_operators(ops, sort_by_name)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def non_relational_operators(sort_by_name = true)
|
|
22
|
-
ops = subcommands.select{|cmd|
|
|
23
|
-
cmd.operator? and !cmd.relational?
|
|
24
|
-
}
|
|
25
|
-
sort_operators(ops, sort_by_name)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def other_non_relational_commands(sort_by_name = true)
|
|
29
|
-
ops = subcommands.select{|cmd|
|
|
30
|
-
cmd.command?
|
|
31
|
-
}
|
|
32
|
-
sort_operators(ops, sort_by_name)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
def sort_operators(ops, sort_by_name)
|
|
38
|
-
sort_by_name ? ops.sort{|op1,op2|
|
|
39
|
-
op1.command_name.to_s <=> op2.command_name.to_s
|
|
40
|
-
} : ops
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
end # class << self
|
|
44
|
-
|
|
45
|
-
# The reader to use when stdin is used as operand
|
|
46
|
-
attr_accessor :stdin_operand
|
|
3
|
+
class Main < Quickl::Delegator(__FILE__, __LINE__)
|
|
4
|
+
include Support
|
|
47
5
|
|
|
48
6
|
# Creates a command instance
|
|
49
7
|
def initialize(config = load_config)
|
|
@@ -55,11 +13,6 @@ module Alf
|
|
|
55
13
|
options do |opt|
|
|
56
14
|
@rendering_options = {}
|
|
57
15
|
|
|
58
|
-
@execute = false
|
|
59
|
-
opt.on("-e", "--execute", "Execute one line of script (Lispy API)") do
|
|
60
|
-
@execute = true
|
|
61
|
-
end
|
|
62
|
-
|
|
63
16
|
Renderer.each do |name,descr,clazz|
|
|
64
17
|
opt.on("--#{name}", "Render output #{descr}"){
|
|
65
18
|
config.default_renderer = clazz
|
|
@@ -75,12 +28,11 @@ module Alf
|
|
|
75
28
|
config.adapter = value
|
|
76
29
|
end
|
|
77
30
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"Specify the kind of reader when reading on $stdin "\
|
|
31
|
+
readers = Reader.all.map{|r| r.first }
|
|
32
|
+
opt.on('--stdin=READER', readers,
|
|
33
|
+
"Specify the kind of reader when reading on standard input "\
|
|
82
34
|
"(#{readers.join(',')})") do |value|
|
|
83
|
-
|
|
35
|
+
config.stdin_reader = value.to_sym
|
|
84
36
|
end
|
|
85
37
|
|
|
86
38
|
opt.on("-Idirectory",
|
|
@@ -104,9 +56,7 @@ module Alf
|
|
|
104
56
|
end
|
|
105
57
|
|
|
106
58
|
opt.on_tail('-h', "--help", "Show help") do
|
|
107
|
-
|
|
108
|
-
install_requires
|
|
109
|
-
raise Quickl::Help
|
|
59
|
+
show_help("alf")
|
|
110
60
|
end
|
|
111
61
|
|
|
112
62
|
opt.on_tail('-v', "--version", "Show version") do
|
|
@@ -115,26 +65,17 @@ module Alf
|
|
|
115
65
|
end
|
|
116
66
|
end # Alf's options
|
|
117
67
|
|
|
118
|
-
def stdin_operand
|
|
119
|
-
@stdin_operand || Reader.send(@input_reader, $stdin)
|
|
120
|
-
end
|
|
121
|
-
|
|
122
68
|
def connection
|
|
123
|
-
@connection ||= config.database.connection(viewpoint:
|
|
69
|
+
@connection ||= config.database.connection(viewpoint: build_viewpoint)
|
|
124
70
|
end
|
|
125
71
|
|
|
126
72
|
def execute(argv)
|
|
127
73
|
install_load_path
|
|
128
74
|
install_requires
|
|
129
75
|
|
|
130
|
-
# special case where a .alf file is provided
|
|
131
|
-
if argv.empty? or (argv.size == 1 && Path(argv.first).file?)
|
|
132
|
-
argv.unshift("exec")
|
|
133
|
-
end
|
|
134
|
-
|
|
135
76
|
# compile the operator, render and returns it
|
|
136
|
-
|
|
137
|
-
render(connection.
|
|
77
|
+
super.tap do |op|
|
|
78
|
+
render(connection.relvar(op)) if op && requester
|
|
138
79
|
end
|
|
139
80
|
end
|
|
140
81
|
|
|
@@ -160,19 +101,20 @@ module Alf
|
|
|
160
101
|
config
|
|
161
102
|
end
|
|
162
103
|
|
|
163
|
-
def
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
104
|
+
def build_viewpoint
|
|
105
|
+
config = self.config
|
|
106
|
+
Module.new{
|
|
107
|
+
include Alf::Viewpoint
|
|
108
|
+
include config.viewpoint
|
|
109
|
+
def stdin
|
|
110
|
+
Algebra::Operand.coerce Reader.send(contextual_params[:reader], $stdin)
|
|
111
|
+
end
|
|
112
|
+
}[reader: config.stdin_reader]
|
|
171
113
|
end
|
|
172
114
|
|
|
173
115
|
def rendering_options
|
|
174
116
|
options = { float_format: config.float_format }
|
|
175
|
-
if config.pretty? and (hl = highline)
|
|
117
|
+
if config.pretty? and (hl = highline) and (hl.output_cols)
|
|
176
118
|
options[:pretty] = config.pretty?
|
|
177
119
|
options[:trim_at] = hl.output_cols - 1
|
|
178
120
|
end
|