Package

io.getquill

norm

Permalink

package norm

Visibility
  1. Public
  2. All

Type Members

  1. case class BetaReduction(map: Map[Ast, Ast], typeBehavior: TypeBehavior, emptyBehavior: EmptyProductQuatBehavior) extends StatelessTransformer with Product with Serializable

    Permalink
  2. trait ConcatBehavior extends AnyRef

    Permalink
  3. sealed trait EmptyProductQuatBehavior extends AnyRef

    Permalink
  4. trait EqualityBehavior extends AnyRef

    Permalink
  5. class FlattenOptionOperation extends StatelessTransformer

    Permalink
  6. sealed trait ProductAggregationToken extends AnyRef

    Permalink
  7. case class SheathLeafClauses(state: Option[String]) extends StatefulTransformerWithStack[Option[String]] with Product with Serializable

    Permalink

    The state produced in some child clause by the sheathLeaf function is essentially "consumed" by the elaborateSheath function in the parent.

    The state produced in some child clause by the sheathLeaf function is essentially "consumed" by the elaborateSheath function in the parent.

    Note that in the documentation is use a couple of shorthands:

    M - means Map Fm - means FlatMap ent - means a Ast Query. Typically just a Ast Entity e.v - this dot-shorthand means Property(e, v) where e is an Ast Ident. This is essentially a scalar-projection from the entity e. leaf - Typically this is a query-ast clause that results in a scalar type. It could be M(ent,e,e.v) or an infix"stuff".as[Query[Int/String/Boolean/etc...] ]

  8. class SimplifyNullChecks extends StatelessTransformer

    Permalink

    Due to the introduction of null checks in map, flatMap, and exists, in FlattenOptionOperation in order to resolve #1053, as well as to support non-ansi compliant string concatenation as outlined in #1295, large conditional composites became common.

    Due to the introduction of null checks in map, flatMap, and exists, in FlattenOptionOperation in order to resolve #1053, as well as to support non-ansi compliant string concatenation as outlined in #1295, large conditional composites became common. For example:

    case class Holder(value:Option[String])
    
    // The following statement
    query[Holder].map(h => h.value.map(_ + "foo"))
    // Will yield the following result
    SELECT CASE WHEN h.value IS NOT NULL THEN h.value || 'foo' ELSE null END FROM Holder h
    
    Now, let's add a getOrElse statement to the clause that requires an additional wrapped null check. We cannot rely on there being a map call beforehand since we could be reading value as a nullable field directly from the database).
    // The following statement
    query[Holder].map(h => h.value.map(_ + "foo").getOrElse("bar"))
    // Yields the following result:
    SELECT CASE WHEN
    CASE WHEN h.value IS NOT NULL THEN h.value || 'foo' ELSE null END
    IS NOT NULL THEN
    CASE WHEN h.value IS NOT NULL THEN h.value || 'foo' ELSE null END
    ELSE 'bar' END FROM Holder h
    
    This of course is highly redundant and can be reduced to simply:
    SELECT CASE WHEN h.value IS NOT NULL AND (h.value || 'foo') IS NOT NULL THEN h.value || 'foo' ELSE 'bar' END FROM Holder h
    
    This reduction is done by the "Center Rule." There are some other simplification rules as well. Note how we are force to null-check both h.value as well as (h.value || 'foo') because a user may use Option[T].flatMap and explicitly transform a particular value to null.

  9. sealed trait TypeBehavior extends AnyRef

    Permalink

    How do we want beta reduction to treat Quats? Typically the right answer is when any variable x type X is reduced to t type T we check that T is a subtype of X and replace it e.g:

    x.foo reduce v:V -> t:T where V is CC(foo:V) and T is CC(foo:V, bar:V)
    
    (NOTE: see the notes on Quat Shorthand Syntax in Quats.scala if unfamiliar with the syntax above) However if T is not a subtype of X, then we need to throw an error.

    How do we want beta reduction to treat Quats? Typically the right answer is when any variable x type X is reduced to t type T we check that T is a subtype of X and replace it e.g:

    x.foo reduce v:V -> t:T where V is CC(foo:V) and T is CC(foo:V, bar:V)
    
    (NOTE: see the notes on Quat Shorthand Syntax in Quats.scala if unfamiliar with the syntax above) However if T is not a subtype of X, then we need to throw an error. The exception to this is in the case where we are substutiting a real type for a Quat.Null or Quat.Generic (roughly speaking, a 'Bottom Type'). In that case, just do the substitution. This general behavior we call SubstituteSubtypes, it is also considered the default.

    The behavior with variable-renaming in PropagateRenames is and ReifyLiftings slightly different. In these cases, it is a carte-blanche replacement of properties that is necessary. In this case we are either plugging in a Generic type that is being specialized (e.g. X is Quat.Generic) or reducing some type CC(foo:V) to the corresponding renamed type CC(foo:V)[foo->renameFoo]. This general behavior we call ReplaceWithReduction i.e. Quat types are replaced with whatever varaibles are being beta-reduced irregardless of subtyping.

Value Members

  1. object AdHocReduction

    Permalink
  2. object ApplyMap

    Permalink

    Notes for the conceptual examples below.

    Notes for the conceptual examples below. Gin and Tonic were used as prototypical examples of things that "are joined". In the table form, they are alude to the following tonics is Query[Tonic], tonic is Tonic gins is Query[Gin], is Gin waters is Query[Water], water is Water

    ginifySpirit is some f:Spirit => Gin tonicfyWater is some f:Tonic => Water bottleGin is some f:Gin => Bottle Additionally Map(a,b,c).quat is the same as c.quat. The former is used in most examples with DetachableMap

  3. object ApplyRenamesToProps extends StatelessTransformer

    Permalink

    Take renames propogated to the quats and apply them to properties

  4. object AttachToEntity

    Permalink

    Find the innermost clause that contains an entity and attach some other kind of clause into it, e.g.

    Find the innermost clause that contains an entity and attach some other kind of clause into it, e.g. a Filter. For example if you have an AST that looks like this:

    FlatMap(Map(Entity(A), a, B), b, C)

    Then AttachToEntity(Filter(_, _, Cond) will result in this:

    FlatMap(Map(Filter(Entity(A), {tmp}, Cond), a, B), b, C)

    Note how the inner ident {tmp} needs to be unique and not conflict with any ident higher in the AST that is used inside the Cond clause, otherwise, the various kinds of ASTs will be irreversibly corrupted. Here is an example:

    Take:

    FlatMap(A, a, Entity(C))

    Attached to the clause:

    Filter(_, {dangerous_tmp}, If(a == x, foo, bar))

    Which results in:

    FlatMap(A, a, Filter(Entity(C), {dangerous_tmp}, If(a == x, foo, bar))

    If {dangerious_tmp} is the Ident 'a' then the following happens: (I have added curly braces {} around this Ident just to distinguish it)

    FlatMap(A, a, Filter(Entity(C), {a}, If(b == x, foo, bar))

    At that point the 'a' inside the attached Filter and the outside FlatMap are indistinguishable and indeed, the next phase of AvoidAliasConflict will likely turn this expression into the following:

    FlatMap(A, a, Filter(Entity(C), {a1}, If(a1 == x, foo, bar))

    This is of course completely incorrect because the ident {a1} should actually be {a} referring to the ident of the outer FlatMap.

  5. object BetaReduction extends Serializable

    Permalink
  6. object CompleteRenames extends StatelessTransformer

    Permalink
  7. object ConcatBehavior

    Permalink
  8. object EmptyProductQuatBehavior

    Permalink
  9. object EqualityBehavior

    Permalink
  10. object ExpandReturning

    Permalink

    Take the .returning part in a query that contains it and return the array of columns representing of the returning seccovtion with any other operations etc...

    Take the .returning part in a query that contains it and return the array of columns representing of the returning seccovtion with any other operations etc... that they might contain.

  11. object NestImpureMappedInfix extends StatelessTransformer

    Permalink

    A problem occurred in the original way infixes were done in that it was assumed that infix clauses represented pure functions.

    A problem occurred in the original way infixes were done in that it was assumed that infix clauses represented pure functions. While this is true of many UDFs (e.g. CONCAT, GETDATE) it is certainly not true of many others e.g. RAND(), and most importantly RANK(). For this reason, the operations that are done in ApplyMap on standard AST Map clauses cannot be done therefore additional safety checks were introduced there in order to assure this does not happen. In addition to this however, it is necessary to add this normalization step which inserts Nested AST elements in every map that contains impure infix. See more information and examples in #1534.

  12. object Normalize extends StatelessTransformer

    Permalink
  13. object NormalizeCaching

    Permalink
  14. object NormalizeNestedStructures

    Permalink
  15. object NormalizeReturning

    Permalink

    When actions are used with a .returning clause, remove the columns used in the returning clause from the action.

    When actions are used with a .returning clause, remove the columns used in the returning clause from the action. E.g. for insert(Person(id, name)).returning(_.id) remove the id column from the original insert.

  16. object NormalizeStringConcat extends StatelessTransformer

    Permalink
  17. object OrderTerms

    Permalink
  18. object ProductAggregationToken

    Permalink
  19. object PropertyMatroshka

    Permalink
  20. object RenameProperties

    Permalink

    Rename properties now relies on the Quats themselves to propagate field renames.

    Rename properties now relies on the Quats themselves to propagate field renames. The previous itreations of this phase relied on schema propagation via stateful transforms holding field-renames which were then compared to Property AST elements. This was a painstakingly complex and highly error-prone especially when embedded objects were used requiring computation of sub-schemas in a process called 'schema protraction'. The new variation of this phase relies on the Quats directly since the Quats of every Identity, Lift, etc... now know what the field-names contained therein as well as the sub-Quats of any embedded property. This is fairly simple process:

    • Learning what Quats have which renames is simple since this can be propagated from the Quats of the Entity objects, to the rest of the AST.
    • This has the simple requirement that renames must be propagated fully before they are actually committed so that the knowledge of what needs to be renamed into what can be distributed easily throughout the AST.
    • Once these future-renames are staged to Quats throught the AST, a simple stateless reduction will then apply the renames to the Property AST elements around the Ident's (and potentially Lifts etc...) with the renamed Quats.

    The entire process above can be done with a series of stateless transformations with straighforward operations since the majority of the logic actually lives within the Quats themselves.

  21. object RepropagateQuats extends StatelessTransformer

    Permalink
  22. object SeedRenames extends StatelessTransformer

    Permalink
  23. object SymbolicReduction

    Permalink

    This stage represents Normalization Stage1: Symbolic Reduction in Philip Wadler's Paper "A Practical Theory of Language Integrated Query", given in Figure 11.

    This stage represents Normalization Stage1: Symbolic Reduction in Philip Wadler's Paper "A Practical Theory of Language Integrated Query", given in Figure 11. http://homepages.inf.ed.ac.uk/slindley/papers/practical-theory-of-linq.pdf

    It represents foundational normalizations done to sequences that represents queries. In Wadler's paper, he characterizes them as for x in P ... whereas in Quill they are characterized as list comprehensions i.e. P.flatMap(x => ...).

  24. object TypeBehavior

    Permalink
  25. package capture

    Permalink

Ungrouped