alf-shell 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|