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/lt.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Lt
|
|
2
|
+
|
|
3
|
+
Less than
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
lt(left: Alpha|AttrName, right: Alpha|AttrName) -> Predicate
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
lt(:status, 20)
|
|
11
|
+
lt(:status, 30)
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
This predicates checks whether a value (`left`) is less than another one
|
|
16
|
+
(`right`).
|
|
17
|
+
|
|
18
|
+
## Implementation notes
|
|
19
|
+
|
|
20
|
+
This predicate is equivalent to `->(t){ _left_ < _right_ }`.
|
data/doc/txt/lte.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Lte
|
|
2
|
+
|
|
3
|
+
Less than or equal to
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
lte(left: Alpha|AttrName, right: Alpha|AttrName) -> Predicate
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
lte(:status, 20)
|
|
11
|
+
lte(:status, 30)
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
This predicates checks whether a value (`left`) is less than or equal to
|
|
16
|
+
another one (`right`).
|
|
17
|
+
|
|
18
|
+
## Implementation notes
|
|
19
|
+
|
|
20
|
+
This predicate is equivalent to `->(t){ _left_ <= _right_ }`.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Matching
|
|
2
|
+
|
|
3
|
+
Aka 'where exists'
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
matching(left: Relation, right: Relation) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
matching(suppliers, supplies)
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
Computes a relation as a subset of `left` tuples for which at least one
|
|
16
|
+
`right` tuple would join on common attributes.
|
|
17
|
+
|
|
18
|
+
This operator, also known as semi-join, can be explained through the
|
|
19
|
+
definition below. As shown, it consists in joining `left` and `right`
|
|
20
|
+
relations and projecting the result back on `left` attributes.
|
|
21
|
+
|
|
22
|
+
def matching(left, right)
|
|
23
|
+
project(join(left, right), left.attr_list)
|
|
24
|
+
end
|
|
25
|
+
matching(suppliers, supplies)
|
|
26
|
+
|
|
27
|
+
Or, in SQL terms:
|
|
28
|
+
|
|
29
|
+
SELECT left.* FROM left NATURAL JOIN right
|
|
30
|
+
|
|
31
|
+
The synonym 'where exists' comes from the fact that, since right attributes
|
|
32
|
+
are projected away, it may seem more intuitive to think about this operator
|
|
33
|
+
as filtering tuples from left where _there exists_ some tuple at right that
|
|
34
|
+
_would_ join. In SQL terms:
|
|
35
|
+
|
|
36
|
+
SELECT * FROM left WHERE EXISTS (SELECT * FROM right WHERE [join condition])
|
|
37
|
+
|
|
38
|
+
## Implementation notes
|
|
39
|
+
|
|
40
|
+
As for (natural) `join`, you must take care of ensuring that the list of
|
|
41
|
+
common attributes on which the matching applies corresponds to what you
|
|
42
|
+
want. Renamings and projections are worth having at hand when using
|
|
43
|
+
matching. Alternatively, shortcuts can be considered. A (advanced) example
|
|
44
|
+
below:
|
|
45
|
+
|
|
46
|
+
# Same as matching(left, right) except that only attributes in `wish`
|
|
47
|
+
# are take into account in matching.
|
|
48
|
+
def matching_on(left, right, wish)
|
|
49
|
+
matching(left, project(right, wish))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# observe here how part names have been discarded to avoid matching them
|
|
53
|
+
# with supplier names (empty result guaranteed)
|
|
54
|
+
matching_on(suppliers, parts, [:city])
|
data/doc/txt/max.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Max
|
|
2
|
+
|
|
3
|
+
Maximal value
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
max(expr: AttrName|(Tuple->Numeric)) -> Aggregator
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
max(:qty)
|
|
11
|
+
max{|t| t.qty * t.price }
|
|
12
|
+
max(->(t){ t.qty * t.price })
|
|
13
|
+
|
|
14
|
+
## Description
|
|
15
|
+
|
|
16
|
+
Returns the greatest of input values.
|
|
17
|
+
|
|
18
|
+
## Implementation notes
|
|
19
|
+
|
|
20
|
+
This aggregate function must only be used with comparable types. As of
|
|
21
|
+
current Alf version, it does not aggregate empty sets correctly.
|
data/doc/txt/min.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Min
|
|
2
|
+
|
|
3
|
+
Minimal value
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
min(expr: AttrName|(Tuple->Numeric)) -> Aggregator
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
min(:qty)
|
|
11
|
+
min{|t| t.qty * t.price }
|
|
12
|
+
min(->(t){ t.qty * t.price })
|
|
13
|
+
|
|
14
|
+
## Description
|
|
15
|
+
|
|
16
|
+
Returns the smallest of input values.
|
|
17
|
+
|
|
18
|
+
## Implementation notes
|
|
19
|
+
|
|
20
|
+
This aggregate function must only be used with comparable types. As of
|
|
21
|
+
current Alf version, it does not aggregate empty sets correctly.
|
data/doc/txt/minus.txt
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Minus
|
|
2
|
+
|
|
3
|
+
Logical AND NOT
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
minus(left: Relation, right: Relation) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
minus(
|
|
12
|
+
restrict(suppliers, eq(:city, 'Paris')),
|
|
13
|
+
restrict(suppliers, gt(:status, 10)))
|
|
14
|
+
|
|
15
|
+
## Description
|
|
16
|
+
|
|
17
|
+
Computes the relation as the set difference of `left` and `right`.
|
|
18
|
+
|
|
19
|
+
The `left` and `right` relations must be minus-compatible, which meaning
|
|
20
|
+
that they must have same heading (type inheritance is partly supported
|
|
21
|
+
through ruby's own type system, so that the actual behavior is slighlty more
|
|
22
|
+
permissive).
|
|
23
|
+
|
|
24
|
+
## Implementation notes
|
|
25
|
+
|
|
26
|
+
Unlike SQL, this operator ALWAYS remove duplicates. There is no way, in
|
|
27
|
+
Alf, to compute _bags_ of tuples and therefore no way to express something
|
|
28
|
+
such as SQL's EXCEPT ALL.
|
|
29
|
+
|
|
30
|
+
It is sometimes idiomatic in Alf to use `intersect` as a logical AND NOT, as
|
|
31
|
+
illustrated below. So far, the optimizer/compiler is not smart enough to
|
|
32
|
+
translate the former into the latter (which is likely to have a better query
|
|
33
|
+
plan when using faithful SQL compilation and available SQL DBMSs). Any patch
|
|
34
|
+
is welcome here too!
|
|
35
|
+
|
|
36
|
+
minus(
|
|
37
|
+
restrict(suppliers, eq(:city, 'Paris')),
|
|
38
|
+
restrict(suppliers, gt(:status, 10)))
|
|
39
|
+
|
|
40
|
+
is equivalent to
|
|
41
|
+
|
|
42
|
+
restrict(suppliers, eq(:city, 'Paris') & !gt(:status, 10))
|
data/doc/txt/native.txt
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Native
|
|
2
|
+
|
|
3
|
+
User-defined tuple predicate
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
native(predicate: (Tuple -> Boolean)) -> Predicate
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
->(t){ t.city == 'London' }
|
|
11
|
+
|
|
12
|
+
## Description
|
|
13
|
+
|
|
14
|
+
So called 'native' predicates are functions computing truth values from
|
|
15
|
+
tuples.
|
|
16
|
+
|
|
17
|
+
## Implementation notes
|
|
18
|
+
|
|
19
|
+
Native predicates can be any ruby Proc object of arity 1. The argument
|
|
20
|
+
will be a Tuple instance. the Proc SHOULD return true or false, but ruby
|
|
21
|
+
patterns for boolean expressions are supported to (such a nil evaluating
|
|
22
|
+
to false, etc.).
|
|
23
|
+
|
|
24
|
+
Note that, as of current Alf version, native predicates cannot be delegated
|
|
25
|
+
to an underlying data engine, and are not compiled to SQL in particular.
|
|
26
|
+
Please always use predicate factories such as `eq(:city, 'London')` if
|
|
27
|
+
possible, as they do not hurt logical optimizations and compilation.
|
data/doc/txt/neq.txt
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Neq
|
|
2
|
+
|
|
3
|
+
Not equal to
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
neq(left: Alpha|AttrName, right: Alpha|AttrName) -> Predicate
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
neq(:city, 'London')
|
|
11
|
+
neq(:supplier_city, :part_city)
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
This predicates checks whether two values are different.
|
|
16
|
+
|
|
17
|
+
## Implementation notes
|
|
18
|
+
|
|
19
|
+
This predicate is equivalent to `->(t){ _left_ != _right_ }`.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Not_matching
|
|
2
|
+
|
|
3
|
+
Aka 'where not exists'
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
not_matching(left: Relation, right: Relation) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
not_matching(suppliers, supplies)
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
Computes a relation as a subset of `left` tuples for which no tuple from
|
|
16
|
+
`right` would join on common attributes.
|
|
17
|
+
|
|
18
|
+
This operator is the inverse of `matching`, as shown by the definition
|
|
19
|
+
below. It keeps all tuples from `left` but those that match a tuple from
|
|
20
|
+
`right`.
|
|
21
|
+
|
|
22
|
+
def not_matching(left, right)
|
|
23
|
+
minus(left, matching(left, right))
|
|
24
|
+
end
|
|
25
|
+
not_matching(suppliers, supplies)
|
|
26
|
+
|
|
27
|
+
The synonym 'where not exists' comes from the fact that, since right
|
|
28
|
+
attributes do not appear in the result, it may seem more intuitive to think
|
|
29
|
+
about this operator as filtering tuples from left where _there does not
|
|
30
|
+
exist_ any tuple from right that _would_ join. In SQL terms:
|
|
31
|
+
|
|
32
|
+
SELECT * FROM left WHERE NOT EXISTS (SELECT * FROM right WHERE [join condition])
|
|
33
|
+
|
|
34
|
+
## Implementation notes
|
|
35
|
+
|
|
36
|
+
As for join and matching, you must take care of ensuring that the list of
|
|
37
|
+
common attributes on which the (not) matching applies corresponds to what
|
|
38
|
+
you want. Renamings and projections are worth having at hand.
|
|
39
|
+
Alternatively, shortcuts can be considered (see `matching` and `join`).
|
data/doc/txt/page.txt
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Page
|
|
2
|
+
|
|
3
|
+
Pagination
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
page(operand: Relation, ordering: Ordering, nth: Integer) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
page(suppliers, [:status, :sid], 1, page_size: 3)
|
|
12
|
+
|
|
13
|
+
page(suppliers, [:status, :sid], -1, page_size: 3)
|
|
14
|
+
|
|
15
|
+
## Description
|
|
16
|
+
|
|
17
|
+
Computes a relation by restricting the tuples of `operand` to those
|
|
18
|
+
belonging to the `nth` page (starting at 1). When `nth` is negative, returns
|
|
19
|
+
tuples that belong to the `nth` page from the end (e.g., -1 is last page).
|
|
20
|
+
|
|
21
|
+
Formally, the page is defined by those tuples whose ranking according to
|
|
22
|
+
`order` is such that `(nth-1)*page_size <= rank < nth*page_size`. In other
|
|
23
|
+
words, this operator is almost equivalent to the following definition
|
|
24
|
+
(ignoring negative page indexes for simplicity):
|
|
25
|
+
|
|
26
|
+
def page(operand, order, nth, page_size)
|
|
27
|
+
allbut(
|
|
28
|
+
restrict(
|
|
29
|
+
rank(operand, order, :rank),
|
|
30
|
+
lte((nth-1)*page_size, :rank) & lt(:rank, nth*page_size)),
|
|
31
|
+
[:rank])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
As of current Alf version, for this operator to be semantically sound and
|
|
35
|
+
deterministic, `order` MUST be a total order, that is, it must at least
|
|
36
|
+
cover a candidate key. As of current Alf version, no error is raised if
|
|
37
|
+
this is not the case but that might change in future versions.
|
|
38
|
+
|
|
39
|
+
## Implementation notes
|
|
40
|
+
|
|
41
|
+
Contrary to the longer expression shown above, this operator compiles to
|
|
42
|
+
SQL (rank does not, so far) at the cost of having to provide a total
|
|
43
|
+
order.
|
|
44
|
+
|
|
45
|
+
As the result is a relation and relations are not ordered by definition,
|
|
46
|
+
the order in which tuples can be observed in the result (e.g. through
|
|
47
|
+
explicit tuple iteration, casting to an array, json encoding) is NOT
|
|
48
|
+
guaranteed to follow `order`.
|
data/doc/txt/project.txt
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Project
|
|
2
|
+
|
|
3
|
+
Keeps only a subset of attributes.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
project(operand: Relation, attributes: AttrList) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
project(suppliers, [:city])
|
|
12
|
+
|
|
13
|
+
project(suppliers, [:city], allbut: true)
|
|
14
|
+
|
|
15
|
+
## Description
|
|
16
|
+
|
|
17
|
+
Computes the relation obtained by projecting tuples from `operand` on a
|
|
18
|
+
subset of their attributes.
|
|
19
|
+
|
|
20
|
+
This operator supports an ALL BUT variant, through the `allbut` option.
|
|
21
|
+
When set to true, the operator _removes_ specified attributes instead of
|
|
22
|
+
keeping them. An `allbut` operator is also provided that has the same
|
|
23
|
+
effect.
|
|
24
|
+
|
|
25
|
+
## Implementation notes
|
|
26
|
+
|
|
27
|
+
Unlike SQL, this operator ALWAYS remove duplicates. There is no way, in
|
|
28
|
+
Alf, to compute _bags_ of tuples.
|
data/doc/txt/rank.txt
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Rank
|
|
2
|
+
|
|
3
|
+
Tuple ranking
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
rank(operand: Relation, order: Ordering, as: AttrName) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
rank(suppliers, [:status], :ranking)
|
|
12
|
+
|
|
13
|
+
rank(suppliers, [:status, :sid], :ranking)
|
|
14
|
+
|
|
15
|
+
## Description
|
|
16
|
+
|
|
17
|
+
Extends tuples from `operand` with a new attribute (`as`) capturing the
|
|
18
|
+
tuple position with respect to `order`.
|
|
19
|
+
|
|
20
|
+
The ranking of a tuple `t` is more precisely defined as the number of tuples
|
|
21
|
+
from `operand` that would come strictly before `t` if they were all ordered
|
|
22
|
+
according to `order`. 'Equal' tuples with respect to `order` are not counted
|
|
23
|
+
in this ranking.
|
|
24
|
+
|
|
25
|
+
This means that, unless `order` is a total order, duplicate ranking may be
|
|
26
|
+
observed. In contrast, if `order` covers a candidate key then the ranking
|
|
27
|
+
attribute (`as`) is unique, and therefore defines an additional candidate
|
|
28
|
+
key for the resulting relation.
|
|
29
|
+
|
|
30
|
+
## Implementation notes
|
|
31
|
+
|
|
32
|
+
Note that this operator does not compile to SQL so far. The `page` and
|
|
33
|
+
`frame` operators provide useful alternatives when the aim is to compute
|
|
34
|
+
a subset of tuples based on a ranking.
|
data/doc/txt/rename.txt
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Rename
|
|
2
|
+
|
|
3
|
+
Rename attributes
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
rename(operand: Relation, renaming: Renaming) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
rename(suppliers, :sid => :supplier_id, :city => :lives_in)
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
Computes the same relation as `operand` expect that some attributes have
|
|
16
|
+
been renamed.
|
|
17
|
+
|
|
18
|
+
## Implementation notes
|
|
19
|
+
|
|
20
|
+
As of current version, renamings can only be expressed through a Hash
|
|
21
|
+
mapping input to output attribute names.
|
|
22
|
+
|
|
23
|
+
Other ways of specifying renamining will be added in future versions, such
|
|
24
|
+
as prefixing, postfixing, renaming through a Proc, etc. Any patch towards
|
|
25
|
+
these improvements is welcome.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Restrict
|
|
2
|
+
|
|
3
|
+
Predicate-based filtering
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
restrict(operand: Relation, predicate: Predicate) -> Relation
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
restrict(suppliers, city: 'Paris', status: 20)
|
|
12
|
+
|
|
13
|
+
restrict(suppliers, eq(city: 'Paris') & gt(:status, 20))
|
|
14
|
+
|
|
15
|
+
restrict(suppliers, ->(t){ t.city == 'Paris' and t.status > 20 })
|
|
16
|
+
|
|
17
|
+
## Description
|
|
18
|
+
|
|
19
|
+
Computes a relation as a subset of `operand` tuples for which a tuple
|
|
20
|
+
predicate evaluates to TRUE.
|
|
21
|
+
|
|
22
|
+
## Implementation notes
|
|
23
|
+
|
|
24
|
+
As of current Alf version, native predicates (through ruby `Proc` objects)
|
|
25
|
+
cannot be optimized nor compiled to SQL. The use of predicate factories
|
|
26
|
+
(`eq`, `gt`, etc.) is strongly recommanded.
|
data/doc/txt/stddev.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Stddev
|
|
2
|
+
|
|
3
|
+
Standard deviation
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
stddev(expr: AttrName|(Tuple->Numeric)) -> Aggregator
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
stddev(:qty)
|
|
11
|
+
stddev{|t| t.qty * t.price }
|
|
12
|
+
stddev(->(t){ t.qty * t.price })
|
|
13
|
+
|
|
14
|
+
## Description
|
|
15
|
+
|
|
16
|
+
Computes how much variation from the average exists.
|
|
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.
|