@@ -28,6 +28,15 @@ TutorialD is strongly-typed. The basic built-in types are:
29With regards to boolean values, be sure not to conflate ```t``` or ```f``` as a boolean value with ```true``` and ```false``` which are relation variables.
29With regards to boolean values, be sure not to conflate ```t``` or ```f``` as a boolean value with ```true``` and ```false``` which are relation variables.
31+Project:M36 will complain loudly if the expected types do not match. Automatic type coercion does not exist.
34+TutorialD (master): :showexpr S:{more:=add(10,@SNAME)}
35+ERR: AtomFunctionTypeError "add" 2 IntAtomType StringAtomType
38+The integer "10" cannot be added to the string SNAME value.
31### Using Relation Variables
40### Using Relation Variables
33Relation Variables are named cells which reference relations within a transaction state. The relation can be replaced with another relation through assignment.
42Relation Variables are named cells which reference relations within a transaction state. The relation can be replaced with another relation through assignment.
@@ -429,3 +438,41 @@ TutorialD (master): constraint S_status_less_than_50 (S where ^lt(50,@STATUS)){}
429This expression ensures that the relation variable's relation can never include a tuple with STATUS greater than 50.
438This expression ensures that the relation variable's relation can never include a tuple with STATUS greater than 50.
431## Aggregate Queries
440## Aggregate Queries
442+Aggregate queries in TutorialD are able to provide much more information than SQL queries due to the support for relation-valued attributes. For example, a single query can return aggregate results alongside its constituent tuples.
444+SQL supports aggregate queries using aggregate functions (SUM(), COUNT(), AVERAGE(), etc.) and GROUP BY while the aggregate functions in the relational algebra simply accept relation values as arguments.
447+TutorialD (master): :showexpr S group ({S#,SNAME,STATUS} as subrel):{citycount:=count(@subrel)}
448+┌──────┬─────────┬─────────────────┐
449+│CITY │citycount│subrel │
450+├──────┼─────────┼─────────────────┤
451+│Paris │2 │┌──┬─────┬──────┐│
452+│ │ ││S#│SNAME│STATUS││
453+│ │ │├──┼─────┼──────┤│
456+│ │ │└──┴─────┴──────┘│
457+│London│2 │┌──┬─────┬──────┐│
458+│ │ ││S#│SNAME│STATUS││
459+│ │ │├──┼─────┼──────┤│
462+│ │ │└──┴─────┴──────┘│
463+│Athens│1 │┌──┬─────┬──────┐│
464+│ │ ││S#│SNAME│STATUS││
465+│ │ │├──┼─────┼──────┤│
467+│ │ │└──┴─────┴──────┘│
468+└──────┴─────────┴─────────────────┘
471+In this query result, we can simultaneously answer how many suppliers are located in each city and which suppliers they are. The expression is constructed by first grouping to isolate the city, then extending the query to add a attribute containing the tuple count for each subrelation.
473+|Function Name|Description|
475+|count(relation{any tuple types})|return the number of tuples in each relation value|
476+|sum(relation{int})|return the int sum of the relation's values|
477+|max(relation{int})|return the maximum int from all the relation's values|
478+|min(relation{int})|return the minimum int from all the relation's values|