Kirill Simonov avatar Kirill Simonov committed 8aa339d

id(): optimized serialization, use for default ordering.

Comments (0)

Files changed (13)

src/htsql/core/cache.py

         except KeyError:
             with self.cache_lock:
                 if service not in self.locks:
-                    self.locks[service] = threading.Lock()
+                    self.locks[service] = threading.RLock()
             return self.locks[service]
 
     def set(self, key, value):

src/htsql/core/classify.py

                 for label in self.labels]
 
 
+class Localize(Adapter):
+
+    adapt(Node)
+
+    def __init__(self, node):
+        self.node = node
+
+    def __call__(self):
+        return None
+
+
+class LocalizeTable(Localize):
+
+    adapt(TableNode)
+
+    def __call__(self):
+        label_by_column = {}
+        label_by_join = {}
+        for label in classify(self.node):
+            if (isinstance(label.arc, ColumnArc) and
+                    label.arc.column not in label_by_column):
+                label_by_column[label.arc.column] = label
+            if (isinstance(label.arc, ChainArc) and
+                    len(label.arc.joins) == 1 and
+                    label.arc.joins[0] not in label_by_join):
+                label_by_join[label.arc.joins[0]] = label
+        table = self.node.table
+        for key in [table.primary_key]+table.unique_keys:
+            if key.is_partial:
+                continue
+            if not all(not column.is_nullable for column in key.origin_columns):
+                continue
+            columns = key.origin_columns[:]
+            identity = []
+            while columns:
+                for foreign_key in self.node.table.foreign_keys:
+                    if foreign_key.is_partial:
+                        continue
+                    width = len(foreign_key.origin_columns)
+                    if foreign_key.origin_columns == columns[:width]:
+                        join = DirectJoin(foreign_key)
+                        if join not in label_by_join:
+                            continue
+                        label = label_by_join[join]
+                        if localize(label.target) is None:
+                            continue
+                        identity.append(label)
+                        columns = columns[width:]
+                        break
+                else:
+                    column = columns[0]
+                    if column not in label_by_column:
+                        break
+                    columns.pop(0)
+                    identity.append(label_by_column[column])
+            if not columns:
+                return identity
+
+
 @once
 def classify(node):
     assert isinstance(node, Node)
     return labels_by_arc[arcs[0]]
 
 
+@once
+def localize(node):
+    assert isinstance(node, Node)
+    return Localize.__invoke__(node)
+
+

src/htsql/core/tr/assemble.py

         for field in self.code.fields:
             compose_field = self.state.decompose(field)
             compose_fields.append(compose_field)
-        def compose_identity(row, stream, compose_fields=compose_fields):
-            return tuple(compose_field(row, stream)
-                         for compose_field in compose_fields)
+        # FIXME: a reference leak?
+        record_class = Record.make(None, [None]*len(self.code.fields),
+                                   self.code.domain.dump)
+        def compose_identity(row, stream, compose_fields=compose_fields,
+                             record_class=record_class):
+            return record_class(*[compose_field(row, stream)
+                                  for compose_field in compose_fields])
         return compose_identity
 
 

src/htsql/core/tr/lookup.py

 from ..entity import DirectJoin
 from ..model import (HomeNode, TableNode, Arc, TableArc, ChainArc, ColumnArc,
         SyntaxArc, InvalidArc, AmbiguousArc)
-from ..classify import classify, relabel, normalize
+from ..classify import classify, relabel, localize, normalize
 from .syntax import IdentifierSyntax
 from .binding import (Binding, ScopingBinding, ChainingBinding,
         WrappingBinding, SegmentBinding, HomeBinding, RootBinding,
     adapt(TableBinding, IdentityProbe)
 
     def __call__(self):
-        unique_key = self.binding.table.primary_key
-        if unique_key is None:
-            for key in self.binding.table.unique_keys:
-                if key.is_partial:
-                    continue
-                if all(not column.is_nullable for column in key.origin_columns):
-                    unique_key = key
-                    break
-        if unique_key is None:
-            return None
-        columns = unique_key.origin_columns[:]
-        recipes = []
-        while columns:
-            for foreign_key in self.binding.table.foreign_keys:
-                if foreign_key.is_partial:
-                    continue
-                width = len(foreign_key.origin_columns)
-                if foreign_key.origin_columns == columns[:width]:
-                    join = DirectJoin(foreign_key)
-                    chain = [AttachedTableRecipe([join])]
-                    binding = AttachedTableBinding(self.binding, join,
-                                                   self.binding.syntax)
-                    recipe = lookup(binding, self.probe)
-                    if recipe is None:
-                        return None
-                    chain.append(recipe)
-                    recipe = ChainRecipe(chain)
-                    recipes.append(recipe)
-                    columns = columns[width:]
-                    break
-            else:
-                column = columns.pop(0)
-                recipe = ColumnRecipe(column)
+        def chain(node):
+            labels = localize(node)
+            if labels is None:
+                return None
+            recipes = []
+            for label in labels:
+                recipe = prescribe(label.arc, self.binding)
+                target_chain = chain(label.target)
+                if target_chain is not None:
+                    recipe = ChainRecipe([recipe, target_chain])
                 recipes.append(recipe)
-        return IdentityRecipe(recipes)
+            return IdentityRecipe(recipes)
+        return chain(TableNode(self.binding.table))
 
 
 class GuessPathForFreeTable(Lookup):
     # with the column; if there is no associated link, the request
     # fails.
 
-    adapt(ColumnBinding, AttributeProbe)
+    adapt_many((ColumnBinding, AttributeProbe),
+               (ColumnBinding, IdentityProbe))
 
     def __call__(self):
         # If there is an associated link node, delegate the request to it.

src/htsql/core/tr/rewrite.py

 from .error import EncodeError
 from .coerce import coerce
 from .flow import (Expression, QueryExpr, SegmentCode, Flow, RootFlow,
-        QuotientFlow, ComplementFlow, MonikerFlow, ForkedFlow, LinkedFlow,
-        ClippedFlow, LocatorFlow, FilteredFlow, OrderedFlow, Code, LiteralCode,
-        CastCode, RecordCode, IdentityCode, AnnihilatorCode, FormulaCode, Unit,
-        CompoundUnit, ScalarUnit, AggregateUnitBase, AggregateUnit, KernelUnit,
-        CoveringUnit)
+        FiberTableFlow, QuotientFlow, ComplementFlow, MonikerFlow, ForkedFlow,
+        LinkedFlow, ClippedFlow, LocatorFlow, FilteredFlow, OrderedFlow, Code,
+        LiteralCode, CastCode, RecordCode, IdentityCode, AnnihilatorCode,
+        FormulaCode, Unit, ColumnUnit, CompoundUnit, ScalarUnit,
+        AggregateUnitBase, AggregateUnit, KernelUnit, CoveringUnit)
 from .signature import Signature, OrSig, AndSig
 # FIXME: move `IfSig` and `SwitchSig` to `htsql.core.tr.signature`.
 from .fn.signature import IfSig
     adapt(LocatorFlow)
 
     def __call__(self):
-        # Apply the adapter to all child nodes.
+        #if self.flow.base.dominates(self.flow.seed):
+        #    flow = FilteredFlow(self.flow.seed, self.flow.filter,
+        #                        self.flow.binding)
+        #    return self.state.rewrite(flow)
         base = self.state.rewrite(self.flow.base)
         seed = self.state.rewrite(self.flow.seed)
         filter = self.state.rewrite(self.flow.filter)
         return self.unit.clone(flow=flow)
 
 
+class UnmaskColumn(UnmaskUnit):
+
+    adapt(ColumnUnit)
+
+    def __call__(self):
+        flow = self.state.unmask(self.unit.flow)
+        column = self.unit.column
+        while (isinstance(flow, FiberTableFlow) and flow.join.is_direct and
+               flow.is_expanding and flow.is_contracting):
+            for origin_column, target_column in zip(flow.join.origin_columns,
+                                                    flow.join.target_columns):
+                if column is target_column:
+                    flow = flow.base
+                    column = origin_column
+                    break
+            else:
+                break
+        return self.unit.clone(flow=flow, column=column)
+
+
 class RewriteCompound(RewriteUnit):
 
     adapt(CompoundUnit)

src/htsql/core/tr/stitch.py

 
 
 from ..adapter import Adapter, adapt, adapt_many
-from ..classify import normalize
+from ..model import TableNode, ColumnArc, ChainArc
+from ..classify import normalize, localize
 from .error import CompileError
 from .syntax import IdentifierSyntax
 from .flow import (Flow, ScalarFlow, TableFlow, FiberTableFlow, QuotientFlow,
         if self.with_weak:
             # Augment the parent ordering with ordering by the primary key
             # of the table (but only if the cardinality of the flow grows).
+
+            # FIXME: the binding tree should pass the ordering information
+            # to the flow tree.
+            def chain(flow):
+                node = TableNode(flow.family.table)
+                labels = localize(node)
+                if labels is None:
+                    return None
+                units = []
+                for label in labels:
+                    if isinstance(label.arc, ColumnArc):
+                        identifier = IdentifierSyntax(label.name, flow.mark)
+                        binding = self.flow.binding.clone(syntax=identifier)
+                        code = ColumnUnit(label.arc.column, flow, binding)
+                        units.append(code)
+                    elif isinstance(label.arc, ChainArc):
+                        identifier = IdentifierSyntax(label.name, flow.mark)
+                        binding = self.flow.binding.clone(syntax=identifier)
+                        subflow = flow
+                        for join in label.arc.joins:
+                            subflow = FiberTableFlow(subflow, join,
+                                                     binding)
+                        subunits = chain(subflow)
+                        assert subunits is not None
+                        units.extend(subunits)
+                    else:
+                        assert False, label.arc
+                return units
             if not self.flow.is_contracting:
+                flow = self.flow.inflate()
+                units = chain(flow)
+                if units is not None:
+                    for unit in units:
+                        flow = unit.flow
+                        column = unit.column
+                        while (isinstance(flow, FiberTableFlow) and
+                               flow.join.is_direct and
+                               flow.is_expanding and flow.is_contracting):
+                            for origin_column, target_column in \
+                                    zip(flow.join.origin_columns,
+                                        flow.join.target_columns):
+                                if column is target_column:
+                                    flow = flow.base
+                                    column = origin_column
+                                    break
+                            else:
+                                break
+                        unit = unit.clone(flow=flow, column=column)
+                        yield (unit, +1)
+                    return
                 # List of columns which provide the default table ordering.
                 columns = []
                 # When possible, we take the columns from the primary key

src/htsql/core/util.py

 
     __slots__ = ()
     __fields__ = ()
+    __dump__ = None
 
     @classmethod
-    def make(cls, name, fields):
+    def make(cls, name, fields, dump=None):
         assert isinstance(name, maybe(oneof(str, unicode)))
         assert isinstance(fields, listof(maybe(oneof(str, unicode))))
         if isinstance(name, unicode):
             if field is None:
                 continue
             attributes[field] = property(operator.itemgetter(idx))
+        if dump is not None:
+            attributes['__dump__'] = dump
         return type(name, bases, attributes)
 
     def __new__(cls, *args, **kwds):
     def __getnewargs__(self):
         return tuple(self)
 
+    def __str__(self):
+        if self.__class__.__dump__ is None:
+            return repr(self)
+        return self.__class__.__dump__(self)
+
     def __repr__(self):
         return ("%s(%s)"
                 % (self.__class__.__name__,

test/input/translation.yaml

     - uri: /school[ns]
     - uri: /school[ns].department
     - uri: /school[ns].program
-    - uri: /program?school[ns]
+    - uri: /program?school[ns]  # FIXME: improve SQL serialization
     - uri: /program[ns.uchem]
     - uri: /school{id(), *}
     - uri: /department{id(), school{id()}}

test/output/mssql.yaml

              +------------+-----------+--------+-------+
              | student_id | class_seq | status | grade |
             -+------------+-----------+--------+-------+-
+             |       1001 |      1121 | inc    |  2.30 |
+             |       1001 |      1117 | ngr    |  4.00 |
+             |       1001 |      1096 | inc    |  2.90 |
              |       1001 |      1070 | ngr    |       |
+             |       1001 |      1098 | ngr    |  2.80 |
              |       1001 |      1088 | enr    |  2.60 |
-             |       1001 |      1096 | inc    |  2.90 |
-             |       1001 |      1098 | ngr    |  2.80 |
-             |       1001 |      1117 | ngr    |  4.00 |
-             |       1001 |      1121 | inc    |  2.30 |
              |       1001 |      1301 | enr    |  0.40 |
              |       1001 |      1397 | inc    |  1.50 |
+             |       1001 |      1442 | enr    |  2.30 |
              |       1001 |      1430 | enr    |  3.50 |
-             |       1001 |      1442 | enr    |  2.30 |
              |       1001 |      1516 | ngr    |  4.00 |
              |       1001 |      1551 | ngr    |  0.20 |
              |       1001 |      1576 | inc    |  4.00 |
              |       1001 |      1586 | enr    |  1.10 |
              |       1001 |      1666 | enr    |       |
-             |       1001 |      1672 | enr    |  3.00 |
+             |       1001 |      1738 | ngr    |  1.20 |
              |       1001 |      1679 | inc    |  2.70 |
              |       1001 |      1687 | ngr    |  1.90 |
+             |       1001 |      1723 | inc    |  4.00 |
+             |       1001 |      1672 | enr    |  3.00 |
              |       1001 |      1715 | inc    |  2.80 |
-             |       1001 |      1723 | inc    |  4.00 |
-             |       1001 |      1738 | ngr    |  1.20 |
              |       1001 |      1741 | enr    |  1.90 |
+             |       1001 |      1770 | inc    |  3.50 |
              |       1001 |      1766 | ngr    |  1.40 |
-             |       1001 |      1770 | inc    |  3.50 |
              |       1001 |      1785 | ngr    |  0.70 |
+             |       1001 |      1821 | enr    |  2.60 |
              |       1001 |      1795 | inc    |  3.40 |
-             |       1001 |      1821 | enr    |  2.60 |
+             |       1001 |      1881 | enr    |  1.70 |
+             |       1001 |      1928 | ngr    |  1.80 |
+             |       1001 |      1873 | ngr    |  2.60 |
              |       1001 |      1857 | ngr    |  2.90 |
-             |       1001 |      1873 | ngr    |  2.60 |
-             |       1001 |      1881 | enr    |  1.70 |
              |       1001 |      1911 | inc    |  0.60 |
-             |       1001 |      1928 | ngr    |  1.80 |
              |       1001 |      2135 | ngr    |  2.30 |
-             |       1001 |      2158 | enr    |  1.40 |
              |       1001 |      2194 | enr    |  2.40 |
              |       1001 |      2198 | enr    |  3.20 |
+             |       1001 |      2158 | enr    |  1.40 |
              |       1001 |      2252 | enr    |  2.90 |
+             |       1001 |      2318 | enr    |  1.70 |
+             |       1001 |      2287 | enr    |       |
              |       1001 |      2280 | enr    |  2.00 |
-             |       1001 |      2287 | enr    |       |
-             |       1001 |      2318 | enr    |  1.70 |
              |       1001 |      2382 | inc    |  3.20 |
              |       1001 |      2393 | enr    |  1.50 |
-             |       1001 |      2443 | ngr    |  0.90 |
+             |       1001 |      2462 | ngr    |  3.40 |
              |       1001 |      2448 | ngr    |  4.00 |
              |       1001 |      2457 | enr    |  1.70 |
-             |       1001 |      2462 | ngr    |  3.40 |
              |       1001 |      2473 | ngr    |  2.60 |
+             |       1001 |      2443 | ngr    |  0.90 |
+             |       1001 |      2544 | ngr    |  3.10 |
              |       1001 |      2492 | ngr    |  2.90 |
              |       1001 |      2502 | ngr    |  2.30 |
-             |       1001 |      2544 | ngr    |  3.10 |
 
              ----
              /enrollment.limit(50)
                     [enrollment].[status],
                     [enrollment].[grade]
              FROM [ed].[enrollment]
-             ORDER BY 1 ASC, 2 ASC
+                  INNER JOIN [cd].[class]
+                             ON ([enrollment].[class_seq] = [class].[class_seq])
+             ORDER BY 1 ASC, [class].[department_code] ASC, [class].[course_no] ASC, [class].[year] ASC, [class].[season] ASC, [class].[section] ASC
         - uri: /prerequisite.limit(50)
           status: 200 OK
           headers:
 
              ----
              /(program?school_code='la'&code='uengl').school
-             SELECT [school].[code],
+             SELECT [program].[school_code],
                     [school].[name],
                     [school].[campus]
              FROM [ad].[program]
                              ON ([program].[school_code] = [school].[code])
              WHERE ([program].[school_code] = 'la')
                    AND ([program].[code] = 'uengl')
-             ORDER BY [program].[school_code] ASC, [program].[code] ASC
+             ORDER BY 1 ASC, [program].[code] ASC
         - uri: /(program?school_code='la'&code='uengl').program
           status: 400 Bad Request
           headers:
 
              ----
              /(course?department_code='lang'&no=345).department
-             SELECT [department].[code],
+             SELECT [course].[department_code],
                     [department].[name],
                     [department].[school_code]
              FROM [ad].[course]
                              ON ([course].[department_code] = [department].[code])
              WHERE ([course].[department_code] = 'lang')
                    AND ([course].[no] = 345)
-             ORDER BY [course].[department_code] ASC, [course].[no] ASC
+             ORDER BY 1 ASC, [course].[no] ASC
         - uri: /(course?department_code='lang'&no=345).class
           status: 200 OK
           headers:
 
              ----
              /(confidential?instructor_code='bdoyle').instructor
-             SELECT [instructor].[code],
+             SELECT [confidential].[instructor_code],
                     [instructor].[title],
                     [instructor].[full_name],
                     [instructor].[phone],
                   INNER JOIN [id].[instructor]
                              ON ([confidential].[instructor_code] = [instructor].[code])
              WHERE ([confidential].[instructor_code] = 'bdoyle')
-             ORDER BY [confidential].[instructor_code] ASC
+             ORDER BY 1 ASC
         - uri: /(appointment?department_code='be' &instructor_code='bdoyle').department
           status: 200 OK
           headers:
 
              ----
              /(appointment?department_code='be'&instructor_code='bdoyle').department
-             SELECT [department].[code],
+             SELECT [appointment].[department_code],
                     [department].[name],
                     [department].[school_code]
              FROM [id].[appointment]
                              ON ([appointment].[department_code] = [department].[code])
              WHERE ([appointment].[department_code] = 'be')
                    AND ([appointment].[instructor_code] = 'bdoyle')
-             ORDER BY [appointment].[department_code] ASC, [appointment].[instructor_code] ASC
+             ORDER BY 1 ASC, [appointment].[instructor_code] ASC
         - uri: /(appointment?department_code='be' &instructor_code='bdoyle').instructor
           status: 200 OK
           headers:
 
              ----
              /(appointment?department_code='be'&instructor_code='bdoyle').instructor
-             SELECT [instructor].[code],
+             SELECT [appointment].[instructor_code],
                     [instructor].[title],
                     [instructor].[full_name],
                     [instructor].[phone],
                              ON ([appointment].[instructor_code] = [instructor].[code])
              WHERE ([appointment].[department_code] = 'be')
                    AND ([appointment].[instructor_code] = 'bdoyle')
-             ORDER BY [appointment].[department_code] ASC, [appointment].[instructor_code] ASC
+             ORDER BY [appointment].[department_code] ASC, 1 ASC
         - uri: /(semester?year=2010&season='fall').class.limit(50)
           status: 200 OK
           headers:
 
              ----
              /(class?class_seq=1055).course
-             SELECT [course].[department_code],
-                    [course].[no],
+             SELECT [class].[department_code],
+                    [class].[course_no],
                     [course].[title],
                     [course].[credits],
                     [course].[description]
                   INNER JOIN [ad].[course]
                              ON (([class].[department_code] = [course].[department_code]) AND ([class].[course_no] = [course].[no]))
              WHERE ([class].[class_seq] = 1055)
-             ORDER BY [class].[department_code] ASC, [class].[course_no] ASC, [class].[year] ASC, [class].[season] ASC, [class].[section] ASC
+             ORDER BY 1 ASC, 2 ASC, [class].[year] ASC, [class].[season] ASC, [class].[section] ASC
         - uri: /(class?class_seq=1055).semester
           status: 200 OK
           headers:
 
              ----
              /(class?class_seq=1055).semester
-             SELECT [semester].[year],
-                    [semester].[season],
+             SELECT [class].[year],
+                    [class].[season],
                     [semester].[begin_date],
                     [semester].[end_date]
              FROM [cd].[class]
                   INNER JOIN [cd].[semester]
                              ON (([class].[year] = [semester].[year]) AND ([class].[season] = [semester].[season]))
              WHERE ([class].[class_seq] = 1055)
-             ORDER BY [class].[department_code] ASC, [class].[course_no] ASC, [class].[year] ASC, [class].[season] ASC, [class].[section] ASC
+             ORDER BY [class].[department_code] ASC, [class].[course_no] ASC, 1 ASC, 2 ASC, [class].[section] ASC
         - uri: /(class?class_seq=1055).instructor
           status: 200 OK
           headers:
                     [enrollment].[class_seq],
                     [enrollment].[status],
                     [enrollment].[grade]
-             FROM [cd].[class]
+             FROM [cd].[class] AS [class_1]
                   INNER JOIN [ed].[enrollment]
-                             ON ([class].[class_seq] = [enrollment].[class_seq])
-             WHERE ([class].[class_seq] = 1055)
-             ORDER BY [class].[department_code] ASC, [class].[course_no] ASC, [class].[year] ASC, [class].[season] ASC, [class].[section] ASC, 1 ASC, 2 ASC
+                             ON ([class_1].[class_seq] = [enrollment].[class_seq])
+                  INNER JOIN [cd].[class] AS [class_2]
+                             ON ([enrollment].[class_seq] = [class_2].[class_seq])
+             WHERE ([class_1].[class_seq] = 1055)
+             ORDER BY [class_1].[department_code] ASC, [class_1].[course_no] ASC, [class_1].[year] ASC, [class_1].[season] ASC, [class_1].[section] ASC, 1 ASC, [class_2].[department_code] ASC, [class_2].[course_no] ASC, [class_2].[year] ASC, [class_2].[season] ASC, [class_2].[section] ASC
         - uri: /(student?id=1010).program
           status: 200 OK
           headers:
              | student_id | class_seq | status | grade |
             -+------------+-----------+--------+-------+-
              |       1010 |      1041 | inc    |  4.00 |
+             |       1010 |      1122 | inc    |  3.80 |
+             |       1010 |      1082 | enr    |  0.20 |
              |       1010 |      1066 | enr    |  2.20 |
+             |       1010 |      1123 | inc    |  0.00 |
              |       1010 |      1071 | inc    |  3.70 |
-             |       1010 |      1082 | enr    |  0.20 |
+             |       1010 |      1097 | enr    |  4.00 |
              |       1010 |      1085 | enr    |  3.10 |
              |       1010 |      1089 | ngr    |       |
-             |       1010 |      1097 | enr    |  4.00 |
-             |       1010 |      1122 | inc    |  3.80 |
-             |       1010 |      1123 | inc    |  0.00 |
+             |       1010 |      1220 | ngr    |  3.00 |
              |       1010 |      1213 | enr    |  2.40 |
-             |       1010 |      1220 | ngr    |  3.00 |
              |       1010 |      1409 | ngr    |  3.30 |
              |       1010 |      1429 | enr    |  1.90 |
+             |       1010 |      1514 | enr    |  2.10 |
              |       1010 |      1509 | inc    |  1.60 |
-             |       1010 |      1514 | enr    |  2.10 |
              |       1010 |      1544 | ngr    |  0.40 |
              |       1010 |      1590 | inc    |  2.20 |
              |       1010 |      1658 | ngr    |  3.70 |
+             |       1010 |      1746 | ngr    |  1.00 |
              |       1010 |      1666 | enr    |  2.60 |
              |       1010 |      1713 | inc    |  3.30 |
+             |       1010 |      1729 | ngr    |  3.30 |
              |       1010 |      1719 | enr    |  0.40 |
-             |       1010 |      1729 | ngr    |  3.30 |
              |       1010 |      1742 | ngr    |  2.50 |
-             |       1010 |      1746 | ngr    |  1.00 |
              |       1010 |      1752 | enr    |  1.20 |
+             |       1010 |      1825 | enr    |  3.00 |
+             |       1010 |      1829 | inc    |  2.00 |
+             |       1010 |      1812 | ngr    |  3.70 |
              |       1010 |      1785 | inc    |  3.10 |
              |       1010 |      1804 | ngr    |  2.40 |
-             |       1010 |      1812 | ngr    |  3.70 |
              |       1010 |      1817 | inc    |  4.00 |
-             |       1010 |      1825 | enr    |  3.00 |
-             |       1010 |      1829 | inc    |  2.00 |
+             |       1010 |      1896 | ngr    |  3.90 |
+             |       1010 |      1895 | ngr    |  4.00 |
+             |       1010 |      1847 | inc    |  2.70 |
+             |       1010 |      1854 | inc    |  3.80 |
              |       1010 |      1844 | ngr    |  4.00 |
-             |       1010 |      1847 | inc    |  2.70 |
              |       1010 |      1852 | ngr    |  3.60 |
-             |       1010 |      1854 | inc    |  3.80 |
-             |       1010 |      1895 | ngr    |  4.00 |
-             |       1010 |      1896 | ngr    |  3.90 |
+             |       1010 |      2105 | ngr    |  3.10 |
              |       1010 |      2101 | ngr    |  2.50 |
-             |       1010 |      2105 | ngr    |  3.10 |
              |       1010 |      2109 | enr    |  4.00 |
              |       1010 |      2121 | ngr    |       |
              |       1010 |      2192 | ngr    |  2.90 |
+             |       1010 |      2272 | enr    |  4.00 |
              |       1010 |      2256 | ngr    |  0.50 |
-             |       1010 |      2272 | enr    |  4.00 |
+             |       1010 |      2315 | ngr    |  2.40 |
              |       1010 |      2276 | enr    |  2.10 |
              |       1010 |      2311 | enr    |  1.50 |
-             |       1010 |      2315 | ngr    |  2.40 |
              |       1010 |      2393 | enr    |  4.00 |
              |       1010 |      2447 | ngr    |  4.00 |
              |       1010 |      2471 | enr    |  1.70 |
              FROM [ed].[student]
                   INNER JOIN [ed].[enrollment]
                              ON ([student].[id] = [enrollment].[student_id])
+                  INNER JOIN [cd].[class]
+                             ON ([enrollment].[class_seq] = [class].[class_seq])
              WHERE ([student].[id] = 1010)
-             ORDER BY [student].[id] ASC, 1 ASC, 2 ASC
+             ORDER BY [student].[id] ASC, 1 ASC, [class].[department_code] ASC, [class].[course_no] ASC, [class].[year] ASC, [class].[season] ASC, [class].[section] ASC
         - uri: /(enrollment?student_id=1100&class_seq=1110).student
           status: 200 OK
           headers:
 
              ----
              /(enrollment?student_id=1100&class_seq=1110).student
-             SELECT [student].[id],
+             SELECT [enrollment].[student_id],
                     [student].[name],
                     [student].[gender],
                     [student].[dob],
              FROM [ed].[enrollment]
                   INNER JOIN [ed].[student]
                              ON ([enrollment].[student_id] = [student].[id])
+                  INNER JOIN [cd].[class]
+                             ON ([enrollment].[class_seq] = [class].[class_seq])
              WHERE ([enrollment].[student_id] = 1100)
                    AND ([enrollment].[class_seq] = 1110)
-             ORDER BY [enrollment].[student_id] ASC, [enrollment].[class_seq] ASC
+             ORDER BY 1 ASC, [class].[department_code] ASC, [class].[course_no] ASC, [class].[year] ASC, [class].[season] ASC, [class].[section] ASC
         - uri: /(enrollment?student_id=1100&class_seq=1110).class
           status: 200 OK
           headers:
                     [class].[season],
                     [class].[section],
                     [class].[instructor_code],
-                    [class].[class_seq]
+                    [enrollment].[class_seq]
              FROM [ed].[enrollment]
                   INNER JOIN [cd].[class]
                              ON ([enrollment].[class_seq] = [class].[class_seq])
              WHERE ([enrollment].[student_id] = 1100)
                    AND ([enrollment].[class_seq] = 1110)
-             ORDER BY [enrollment].[student_id] ASC, [enrollment].[class_seq] ASC
+             ORDER BY [enrollment].[student_id] ASC, 1 ASC, 2 ASC, 3 ASC, 4 ASC, 5 ASC
         - uri: /(prerequisite?of_department_code='astro'&of_course_no=230 &on_department_code='phys'&on_course_no=130).course
           status: 400 Bad Request
           headers:
 
              ----
              /(prerequisite?of_department_code='astro'&of_course_no=230&on_department_code='phys'&on_course_no=130).of_course
-             SELECT [course].[department_code],
-                    [course].[no],
+             SELECT [prerequisite].[of_department_code],
+                    [prerequisite].[of_course_no],
                     [course].[title],
                     [course].[credits],
                     [course].[description]
                    AND ([prerequisite].[of_course_no] = 230)
                    AND ([prerequisite].[on_department_code] = 'phys')
                    AND ([prerequisite].[on_course_no] = 130)
-             ORDER BY [prerequisite].[of_department_code] ASC, [prerequisite].[of_course_no] ASC, [prerequisite].[on_department_code] ASC, [prerequisite].[on_course_no] ASC
+             ORDER BY 1 ASC, 2 ASC, [prerequisite].[on_department_code] ASC, [prerequisite].[on_course_no] ASC
         - uri: /(prerequisite?of_department_code='astro'&of_course_no=230 &on_department_code='phys'&on_course_no=130).on_course
           status: 200 OK
           headers:
 
              ----
              /(prerequisite?of_department_code='astro'&of_course_no=230&on_department_code='phys'&on_course_no=130).on_course
-             SELECT [course].[department_code],
-                    [course].[no],
+             SELECT [prerequisite].[on_department_code],
+                    [prerequisite].[on_course_no],
                     [course].[title],
                     [course].[credits],
                     [course].[description]
                    AND ([prerequisite].[of_course_no] = 230)
                    AND ([prerequisite].[on_department_code] = 'phys')
                    AND ([prerequisite].[on_course_no] = 130)
-             ORDER BY [prerequisite].[of_department_code] ASC, [prerequisite].[of_course_no] ASC, [prerequisite].[on_department_code] ASC, [prerequisite].[on_course_no] ASC
+             ORDER BY [prerequisite].[of_department_code] ASC, [prerequisite].[of_course_no] ASC, 1 ASC, 2 ASC
         - uri: /(classification?code='math').classification
           status: 400 Bad Request
           headers:
 
              ----
              /(course_classification?department_code='astro'&course_no=110&classification_code='astrotheory').course
-             SELECT [course].[department_code],
-                    [course].[no],
+             SELECT [course_classification].[department_code],
+                    [course_classification].[course_no],
                     [course].[title],
                     [course].[credits],
                     [course].[description]
              WHERE ([course_classification].[department_code] = 'astro')
                    AND ([course_classification].[course_no] = 110)
                    AND ([course_classification].[classification_code] = 'astrotheory')
-             ORDER BY [course_classification].[department_code] ASC, [course_classification].[course_no] ASC, [course_classification].[classification_code] ASC
+             ORDER BY 1 ASC, 2 ASC, [course_classification].[classification_code] ASC
         - uri: /(course_classification?department_code='astro'&course_no=110 &classification_code='astrotheory').classification
           status: 200 OK
           headers:
 
              ----
              /(course_classification?department_code='astro'&course_no=110&classification_code='astrotheory').classification
-             SELECT [classification].[code],
+             SELECT [course_classification].[classification_code],
                     [classification].[type],
                     [classification].[title],
                     [classification].[description],
              WHERE ([course_classification].[department_code] = 'astro')
                    AND ([course_classification].[course_no] = 110)
                    AND ([course_classification].[classification_code] = 'astrotheory')
-             ORDER BY [course_classification].[department_code] ASC, [course_classification].[course_no] ASC, [course_classification].[classification_code] ASC
+             ORDER BY [course_classification].[department_code] ASC, [course_classification].[course_no] ASC, 1 ASC
         - uri: /(program_requirement?school_code='bus'&program_code='uacct' &classification_code='accounting').program
           status: 200 OK
           headers:
 
              ----
              /(program_requirement?school_code='bus'&program_code='uacct'&classification_code='accounting').program
-             SELECT [program].[school_code],
-                    [program].[code],
+             SELECT [program_requirement].[school_code],
+                    [program_requirement].[program_code],
                     [program].[title],
                     [program].[degree],
                     [program].[part_of_code]
              WHERE ([program_requirement].[school_code] = 'bus')
                    AND ([program_requirement].[program_code] = 'uacct')
                    AND ([program_requirement].[classification_code] = 'accounting')
-             ORDER BY [program_requirement].[school_code] ASC, [program_requirement].[program_code] ASC, [program_requirement].[classification_code] ASC
+             ORDER BY 1 ASC, 2 ASC, [program_requirement].[classification_code] ASC
         - uri: /(program_requirement?school_code='bus'&program_code='uacct' &classification_code='accounting').classification
           status: 200 OK
           headers:
 
              ----
              /(program_requirement?school_code='bus'&program_code='uacct'&classification_code='accounting').classification
-             SELECT [classification].[code],
+             SELECT [program_requirement].[classification_code],
                     [classification].[type],
                     [classification].[title],
                     [classification].[description],
              WHERE ([program_requirement].[school_code] = 'bus')
                    AND ([program_requirement].[program_code] = 'uacct')
                    AND ([program_requirement].[classification_code] = 'accounting')
-             ORDER BY [program_requirement].[school_code] ASC, [program_requirement].[program_code] ASC, [program_requirement].[classification_code] ASC
+             ORDER BY [program_requirement].[school_code] ASC, [program_requirement].[program_code] ASC, 1 ASC
   - include: test/input/tutorial.yaml
     output:
       id: tutorial
                     [program].[degree],
                     [program].[part_of_code]
              FROM [ad].[program]
-                  INNER JOIN [ad].[school]
-                             ON ([program].[school_code] = [school].[code])
-             WHERE ([school].[code] = 'bus')
+             WHERE ([program].[school_code] = 'bus')
                    AND ([program].[degree] <> 'bs')
              ORDER BY 1 ASC, 2 ASC
         - uri: /course{department_code, no, title} ?credits<3&department.school.code='ns'
 
              ----
              /program.school
-             SELECT [school].[code],
+             SELECT [program].[school_code],
                     [school].[name],
                     [school].[campus]
              FROM [ad].[program]
                   INNER JOIN [ad].[school]
                              ON ([program].[school_code] = [school].[code])
-             ORDER BY [program].[school_code] ASC, [program].[code] ASC
+             ORDER BY 1 ASC, [program].[code] ASC
         - uri: /department
           status: 200 OK
           headers:
 
              ----
              /confidential.instructor
-             SELECT [instructor].[code],
+             SELECT [confidential].[instructor_code],
                     [instructor].[title],
                     [instructor].[full_name],
                     [instructor].[phone],
              FROM [id].[confidential]
                   INNER JOIN [id].[instructor]
                              ON ([confidential].[instructor_code] = [instructor].[code])
-             ORDER BY [confidential].[instructor_code] ASC
+             ORDER BY 1 ASC
         - uri: /school.({} -> school)
           status: 200 OK
           headers:
                       [program].[degree],
                       [program].[part_of_code]
                FROM [ad].[program]
-                    INNER JOIN [ad].[school]
-                               ON ([program].[school_code] = [school].[code])
-               WHERE ([school].[code] = 'ns')
+               WHERE ([program].[school_code] = 'ns')
                      AND ([program].[code] = 'uchem')
                ORDER BY 1 ASC, 2 ASC
           - uri: /course?credits=5
                FROM [ad].[program]
                     INNER JOIN [ad].[school]
                                ON ([program].[school_code] = [school].[code])
-               WHERE ([school].[code] = 'art')
+               WHERE ([program].[school_code] = 'art')
                ORDER BY [program].[school_code] ASC, [program].[code] ASC
           - uri: /school.filter(code='ns')
             status: 200 OK
                ----
                /define(course_0:=course,course_1:=course_0?credits=3,course_2:=course_1?department.code='econ',course_3:=course_2?count(class)>4){count(course_1),count(course_3)}
                SELECT COUNT(1),
-                      COUNT((CASE WHEN ((COALESCE([class].[count], 0) > 4) AND ([department].[code] = 'econ')) THEN 1 END))
+                      COUNT((CASE WHEN ((COALESCE([class].[count], 0) > 4) AND ([course].[department_code] = 'econ')) THEN 1 END))
                FROM [ad].[course]
                     LEFT OUTER JOIN (SELECT COUNT(1) AS [count],
                                             [class].[department_code],
                                      FROM [cd].[class]
                                      GROUP BY [class].[department_code], [class].[course_no]) AS [class]
                                     ON (([course].[department_code] = [class].[department_code]) AND ([course].[no] = [class].[course_no]))
-                    INNER JOIN [ad].[department]
-                               ON ([course].[department_code] = [department].[code])
                WHERE ([course].[credits] = 3)
           - uri: /define(course_0 := course, course_1 := course_0?credits=3, course_2
               := course_1?department.code='econ', course_3 := course_2?count(class)>4)
                /define(course_0:=course,course_1:=course_0?credits=3,course_2:=course_1?department.code='econ',course_3:=course_2?count(class)>4){count(course_0),count(course_1),count(course_2),count(course_3)}
                SELECT COUNT(1),
                       COUNT((CASE WHEN ([course].[credits] = 3) THEN 1 END)),
-                      COUNT((CASE WHEN (([department].[code] = 'econ') AND ([course].[credits] = 3)) THEN 1 END)),
-                      COUNT((CASE WHEN ((COALESCE([class].[count], 0) > 4) AND ([department].[code] = 'econ') AND ([course].[credits] = 3)) THEN 1 END))
+                      COUNT((CASE WHEN (([course].[department_code] = 'econ') AND ([course].[credits] = 3)) THEN 1 END)),
+                      COUNT((CASE WHEN ((COALESCE([class].[count], 0) > 4) AND ([course].[department_code] = 'econ') AND ([course].[credits] = 3)) THEN 1 END))
                FROM [ad].[course]
-                    INNER JOIN [ad].[department]
-                               ON ([course].[department_code] = [department].[code])
                     LEFT OUTER JOIN (SELECT COUNT(1) AS [count],
                                             [class].[department_code],
                                             [class].[course_no]
                /define(course_0:=course,course_1:=course?credits=3,course_2:=course?department.code='econ',course_3:=course?count(class)>4){count(course_0),count(course_1),count(course_2),count(course_3)}
                SELECT COUNT(1),
                       COUNT((CASE WHEN ([course].[credits] = 3) THEN 1 END)),
-                      COUNT((CASE WHEN ([department].[code] = 'econ') THEN 1 END)),
+                      COUNT((CASE WHEN ([course].[department_code] = 'econ') THEN 1 END)),
                       COUNT((CASE WHEN (COALESCE([class].[count], 0) > 4) THEN 1 END))
                FROM [ad].[course]
-                    INNER JOIN [ad].[department]
-                               ON ([course].[department_code] = [department].[code])
                     LEFT OUTER JOIN (SELECT COUNT(1) AS [count],
                                             [class].[department_code],
                                             [class].[course_no]
                ----
                /define(course_1:=course?credits=3,course_2:=course?department.code='econ',course_3:=course?count(class)>4){count(course_1),count(course_2),count(course_3)}
                SELECT COUNT((CASE WHEN ([course].[credits] = 3) THEN 1 END)),
-                      COUNT((CASE WHEN ([department].[code] = 'econ') THEN 1 END)),
+                      COUNT((CASE WHEN ([course].[department_code] = 'econ') THEN 1 END)),
                       COUNT((CASE WHEN (COALESCE([class].[count], 0) > 4) THEN 1 END))
                FROM [ad].[course]
-                    INNER JOIN [ad].[department]
-                               ON ([course].[department_code] = [department].[code])
                     LEFT OUTER JOIN (SELECT COUNT(1) AS [count],
                                             [class].[department_code],
                                             [class].[course_no]
                                      FROM [cd].[class]
                                      GROUP BY [class].[department_code], [class].[course_no]) AS [class]
                                     ON (([course].[department_code] = [class].[department_code]) AND ([course].[no] = [class].[course_no]))
-               WHERE (([course].[credits] = 3) OR ([department].[code] = 'econ') OR (COALESCE([class].[count], 0) > 4))
+               WHERE (([course].[credits] = 3) OR ([course].[department_code] = 'econ') OR (COALESCE([class].[count], 0) > 4))
           - uri: /{avg(department{count(course?credits=3)}?code!='econ') :round(2),
               avg(department{count(course?credits=5)}?code!='mth') :round(2)}
             status: 200 OK
                ----
                /(program?school.code='art').school.limit(1)
                SELECT TOP 1
-                      [school].[code],
+                      [program].[school_code],
                       [school].[name],
                       [school].[campus]
                FROM [ad].[program]
                     INNER JOIN [ad].[school]
                                ON ([program].[school_code] = [school].[code])
-               WHERE ([school].[code] = 'art')
-               ORDER BY [program].[school_code] ASC, [program].[code] ASC
+               WHERE ([program].[school_code] = 'art')
+               ORDER BY 1 ASC, [program].[code] ASC
           - uri: /department.define($avg_credits := avg(course.credits), course :=
               course?credits>$avg_credits, course_level := course^integer(no/100)).limit(3)
               {code, count(course_level), count(course_level.course)}
                       [program_2].[degree]
                FROM (SELECT [program].[degree]
                      FROM [ad].[program]
-                          INNER JOIN [ad].[school]
-                                     ON ([program].[school_code] = [school].[code])
                      WHERE ([program].[degree] IS NOT NULL)
-                           AND ([school].[code] = 'art')
+                           AND ([program].[school_code] = 'art')
                      GROUP BY [program].[degree]) AS [program_1]
                     CROSS JOIN (SELECT [program].[degree]
                                 FROM [ad].[program]
-                                     INNER JOIN [ad].[school]
-                                                ON ([program].[school_code] = [school].[code])
                                 WHERE ([program].[degree] IS NOT NULL)
-                                      AND ([school].[code] = 'la')
+                                      AND ([program].[school_code] = 'la')
                                 GROUP BY [program].[degree]) AS [program_2]
                ORDER BY 1 ASC, 2 ASC
           - uri: /school{code,count(department)} ?count(department)>avg(home().school.count(department))
 
                ----
                /course{department.code,no,credits}?credits=max(({}->course).credits)
-               SELECT [department].[code],
+               SELECT [course_1].[department_code],
                       [course_1].[no],
                       [course_1].[credits]
                FROM [ad].[course] AS [course_1]
                     LEFT OUTER JOIN (SELECT MAX([course].[credits]) AS [max]
                                      FROM [ad].[course]) AS [course_2]
                                     ON (1 <> 0)
-                    INNER JOIN [ad].[department]
-                               ON ([course_1].[department_code] = [department].[code])
                WHERE ([course_1].[credits] = [course_2].[max])
-               ORDER BY [course_1].[department_code] ASC, 2 ASC
+               ORDER BY 1 ASC, 2 ASC
           - uri: /course{department.code,no,credits,count(class)} ?credits=max((count(class)
               -> course).credits)
             status: 200 OK
 
                ----
                /course{department.code,no,credits,count(class)}?credits=max((count(class)->course).credits)
-               SELECT [department].[code],
+               SELECT [course_1].[department_code],
                       [course_1].[no],
                       [course_1].[credits],
                       COALESCE([class].[count], 0)
                                                           ON (([course].[department_code] = [class].[department_code]) AND ([course].[no] = [class].[course_no]))
                                      GROUP BY COALESCE([class].[count], 0)) AS [course_2]
                                     ON (COALESCE([class].[count], 0) = [course_2].[count])
-                    INNER JOIN [ad].[department]
-                               ON ([course_1].[department_code] = [department].[code])
                WHERE ([course_1].[credits] = [course_2].[max])
-               ORDER BY [course_1].[department_code] ASC, 2 ASC
+               ORDER BY 1 ASC, 2 ASC
           - uri: /program{school.code, code, degree, num_parts := count({school_code,code}
               -> program{school_code,part_of_code})} ?num_parts=max(fork().num_parts)
             status: 200 OK
 
                ----
                /program{school.code,code,degree,num_parts:=count({school_code,code}->program{school_code,part_of_code})}?num_parts=max(fork().num_parts)
-               SELECT [school].[code],
+               SELECT [program_1].[school_code],
                       [program_1].[code],
                       [program_1].[degree],
                       COALESCE([program_2].[count], 0)
                                                            GROUP BY [program].[school_code], [program].[part_of_code]) AS [program_2]
                                                           ON (([program_1].[school_code] = [program_2].[school_code]) AND ([program_1].[code] = [program_2].[part_of_code]))) AS [program_3]
                                     ON (1 <> 0)
-                    INNER JOIN [ad].[school]
-                               ON ([program_1].[school_code] = [school].[code])
                WHERE (COALESCE([program_2].[count], 0) = [program_3].[max])
-               ORDER BY [program_1].[school_code] ASC, 2 ASC
+               ORDER BY 1 ASC, 2 ASC
           - uri: /'art'->school{code}
             status: 200 OK
             headers:
 
                ----
                /course{department.code,no,credits}?credits=max(fork().credits)
-               SELECT [department].[code],
+               SELECT [course_1].[department_code],
                       [course_1].[no],
                       [course_1].[credits]
                FROM [ad].[course] AS [course_1]
                     LEFT OUTER JOIN (SELECT MAX([course].[credits]) AS [max]
                                      FROM [ad].[course]) AS [course_2]
                                     ON (1 <> 0)
-                    INNER JOIN [ad].[department]
-                               ON ([course_1].[department_code] = [department].[code])
                WHERE ([course_1].[credits] = [course_2].[max])
-               ORDER BY [course_1].[department_code] ASC, 2 ASC
+               ORDER BY 1 ASC, 2 ASC
           - uri: /course{department.code,no,credits}?credits=max(fork(department_code).credits)
             status: 200 OK
             headers:
 
                ----
                /course{department.code,no,credits}?credits=max(fork(department_code).credits)
-               SELECT [department].[code],
+               SELECT [course_1].[department_code],
                       [course_1].[no],
                       [course_1].[credits]
                FROM [ad].[course] AS [course_1]
                                      FROM [ad].[course]
                                      GROUP BY [course].[department_code]) AS [course_2]
                                     ON ([course_1].[department_code] = [course_2].[department_code])
-                    INNER JOIN [ad].[department]
-                               ON ([course_1].[department_code] = [department].[code])
                WHERE ([course_1].[credits] = [course_2].[max])
-               ORDER BY [course_1].[department_code] ASC, 2 ASC
+               ORDER BY 1 ASC, 2 ASC
           - uri: /department.course{department.code,no,credits}?credits=max(fork().credits)
             status: 200 OK
             headers:
 
                ----
                /department.course{department.code,no,credits}?credits=max(fork().credits)
-               SELECT [department_2].[code],
+               SELECT [course_1].[department_code],
                       [course_1].[no],
                       [course_1].[credits]
-               FROM [ad].[department] AS [department_1]
+               FROM [ad].[department]
                     INNER JOIN [ad].[course] AS [course_1]
-                               ON ([department_1].[code] = [course_1].[department_code])
+                               ON ([department].[code] = [course_1].[department_code])
                     LEFT OUTER JOIN (SELECT MAX([course].[credits]) AS [max],
                                             [course].[department_code]
                                      FROM [ad].[course]
                                      GROUP BY [course].[department_code]) AS [course_2]
                                     ON ([course_1].[department_code] = [course_2].[department_code])
-                    INNER JOIN [ad].[department] AS [department_2]
-                               ON ([course_1].[department_code] = [department_2].[code])
                WHERE ([course_1].[credits] = [course_2].[max])
-               ORDER BY [department_1].[code] ASC, [course_1].[department_code] ASC, 2 ASC
+               ORDER BY [department].[code] ASC, 1 ASC, 2 ASC
           - uri: /course{department.code,no,credits,count(class)}?credits=max(fork(count(class)).credits)
             status: 200 OK
             headers:
 
                ----
                /course{department.code,no,credits,count(class)}?credits=max(fork(count(class)).credits)
-               SELECT [department].[code],
+               SELECT [course_1].[department_code],
                       [course_1].[no],
                       [course_1].[credits],
                       COALESCE([class].[count], 0)
                                                           ON (([course].[department_code] = [class].[department_code]) AND ([course].[no] = [class].[course_no]))
                                      GROUP BY COALESCE([class].[count], 0)) AS [course_2]
                                     ON (COALESCE([class].[count], 0) = [course_2].[count])
-                    INNER JOIN [ad].[department]
-                               ON ([course_1].[department_code] = [department].[code])
                WHERE ([course_1].[credits] = [course_2].[max])
-               ORDER BY [course_1].[department_code] ASC, 2 ASC
+               ORDER BY 1 ASC, 2 ASC
           - uri: /program{school_code,code,count(student)}?count(student)>avg(fork().count(student))
             status: 200 OK
             headers:
                ----
                /program.fork(part_of_code){root().program{school.code,code,part_of_code},school.code,code,part_of_code}
                SELECT [program_3].[!],
-                      [program_3].[code_1],
-                      [program_3].[code_2],
+                      [program_3].[school_code],
+                      [program_3].[code],
                       [program_3].[part_of_code],
-                      [school].[code],
+                      [program_2].[school_code],
                       [program_2].[code],
                       [program_2].[part_of_code]
                FROM [ad].[program] AS [program_1]
-                    INNER JOIN (SELECT [program].[code],
-                                       [program].[part_of_code],
-                                       [program].[school_code]
+                    INNER JOIN (SELECT [program].[school_code],
+                                       [program].[code],
+                                       [program].[part_of_code]
                                 FROM [ad].[program]) AS [program_2]
                                ON ([program_1].[part_of_code] = [program_2].[part_of_code])
                     INNER JOIN (SELECT 1 AS [!],
-                                       [school].[code] AS [code_1],
-                                       [program].[code] AS [code_2],
-                                       [program].[part_of_code],
-                                       [program].[school_code]
-                                FROM [ad].[program]
-                                     INNER JOIN [ad].[school]
-                                                ON ([program].[school_code] = [school].[code])) AS [program_3]
-                               ON (([program_1].[school_code] = [program_3].[school_code]) AND ([program_1].[code] = [program_3].[code_2]))
-                    INNER JOIN [ad].[school]
-                               ON ([program_2].[school_code] = [school].[code])
-               ORDER BY [program_1].[school_code] ASC, [program_1].[code] ASC, [program_2].[school_code] ASC, 6 ASC
+                                       [program].[school_code],
+                                       [program].[code],
+                                       [program].[part_of_code]
+                                FROM [ad].[program]) AS [program_3]
+                               ON (([program_1].[school_code] = [program_3].[school_code]) AND ([program_1].[code] = [program_3].[code]))
+               ORDER BY [program_1].[school_code] ASC, [program_1].[code] ASC, 5 ASC, 6 ASC
           - uri: /school.fork().fork().fork().limit(1)
             status: 200 OK
             headers:
 
                ----
                /course{department.code,no,credits}?credits=max(@course.credits)
-               SELECT [department].[code],
+               SELECT [course_1].[department_code],
                       [course_1].[no],
                       [course_1].[credits]
                FROM [ad].[course] AS [course_1]
                     LEFT OUTER JOIN (SELECT MAX([course].[credits]) AS [max]
                                      FROM [ad].[course]) AS [course_2]
                                     ON (1 <> 0)
-                    INNER JOIN [ad].[department]
-                               ON ([course_1].[department_code] = [department].[code])
                WHERE ([course_1].[credits] = [course_2].[max])
-               ORDER BY [course_1].[department_code] ASC, 2 ASC
+               ORDER BY 1 ASC, 2 ASC
           - uri: /course{department.code,no,credits}?credits=@max(course.credits)
             status: 200 OK
             headers:
 
                ----
                /course{department.code,no,credits}?credits=@max(course.credits)
-               SELECT [department].[code],
+               SELECT [course_1].[department_code],
                       [course_1].[no],
                       [course_1].[credits]
                FROM [ad].[course] AS [course_1]
                     LEFT OUTER JOIN (SELECT MAX([course].[credits]) AS [max]
                                      FROM [ad].[course]) AS [course_2]
                                     ON (1 <> 0)
-                    INNER JOIN [ad].[department]
-                               ON ([course_1].[department_code] = [department].[code])
                WHERE ([course_1].[credits] = [course_2].[max])
-               ORDER BY [course_1].[department_code] ASC, 2 ASC
+               ORDER BY 1 ASC, 2 ASC
           - uri: /program{school_code,code,count(student)}?count(student)>avg(@program.count(student))
             status: 200 OK
             headers:
                       [program].[part_of_code]
                FROM [ad].[program]
                     LEFT OUTER JOIN (SELECT 1 AS [!],
-                                            [school].[code]
-                                     FROM [ad].[school]
-                                     WHERE ([school].[code] = 'ns')) AS [school]
-                                    ON ([program].[school_code] = [school].[code])
+                                            [program].[school_code],
+                                            [program].[code]
+                                     FROM [ad].[program]
+                                          INNER JOIN (SELECT [program].[school_code],
+                                                             [program].[code] AS [code_1],
+                                                             [school].[code] AS [code_2]
+                                                      FROM [ad].[program]
+                                                           INNER JOIN [ad].[school]
+                                                                      ON ([program].[school_code] = [school].[code])
+                                                      WHERE ([program].[school_code] = 'ns')) AS [school]
+                                                     ON (([program].[school_code] = [school].[school_code]) AND ([program].[code] = [school].[code_1]) AND ([program].[school_code] = [school].[code_2]))) AS [school]
+                                    ON (([program].[school_code] = [school].[school_code]) AND ([program].[code] = [school].[code]))
                WHERE ([school].[!] IS NOT NULL)
                ORDER BY 1 ASC, 2 ASC
           - uri: /program[ns.uchem]
                       [program].[degree],
                       [program].[part_of_code]
                FROM [ad].[program]
-                    INNER JOIN [ad].[school]
-                               ON ([program].[school_code] = [school].[code])
-               WHERE ([school].[code] = 'ns')
+               WHERE ([program].[school_code] = 'ns')
                      AND ([program].[code] = 'uchem')
                ORDER BY 1 ASC, 2 ASC
           - uri: /school{id(), *}
 
                ----
                /course[astro.105].class.id()
-               SELECT [department_2].[code],
-                      [course_2].[no],
-                      [semester].[year],
-                      [semester].[season],
+               SELECT [class].[department_code],
+                      [class].[course_no],
+                      [class].[year],
+                      [class].[season],
                       [class].[section]
-               FROM [ad].[course] AS [course_1]
-                    INNER JOIN [ad].[department] AS [department_1]
-                               ON ([course_1].[department_code] = [department_1].[code])
+               FROM [ad].[course]
                     INNER JOIN [cd].[class]
-                               ON (([course_1].[department_code] = [class].[department_code]) AND ([course_1].[no] = [class].[course_no]))
-                    INNER JOIN [ad].[course] AS [course_2]
-                               ON (([class].[department_code] = [course_2].[department_code]) AND ([class].[course_no] = [course_2].[no]))
-                    INNER JOIN [ad].[department] AS [department_2]
-                               ON ([course_2].[department_code] = [department_2].[code])
-                    INNER JOIN [cd].[semester]
-                               ON (([class].[year] = [semester].[year]) AND ([class].[season] = [semester].[season]))
-               WHERE ([department_1].[code] = 'astro')
-                     AND ([course_1].[no] = 105)
-               ORDER BY [course_1].[department_code] ASC, [course_1].[no] ASC, [class].[department_code] ASC, [class].[course_no] ASC, [class].[year] ASC, [class].[season] ASC, 5 ASC
+                               ON (([course].[department_code] = [class].[department_code]) AND ([course].[no] = [class].[course_no]))
+               WHERE ([course].[department_code] = 'astro')
+                     AND ([course].[no] = 105)
+               ORDER BY [course].[department_code] ASC, [course].[no] ASC, 1 ASC, 2 ASC, 3 ASC, 4 ASC, 5 ASC
           - uri: /program^degree{*, /^.id()}
             status: 200 OK
             headers:
                GROUP BY [program].[degree]
                ORDER BY 1 ASC
 
-                 SELECT [school].[code],
+                 SELECT [program].[school_code],
                         [program].[code],
                         [program].[degree]
                  FROM [ad].[program]
-                      INNER JOIN [ad].[school]
-                                 ON ([program].[school_code] = [school].[code])
                  WHERE ([program].[degree] IS NOT NULL)
-                 ORDER BY 3 ASC, [program].[school_code] ASC, 2 ASC
+                 ORDER BY 3 ASC, 1 ASC, 2 ASC
           - uri: /program[ns]
             status: 400 Bad Request
             headers:
                SELECT [program].[code],
                       COALESCE([student].[count], 0)
                FROM [ad].[program]
-                    INNER JOIN [ad].[school]
-                               ON ([program].[school_code] = [school].[code])
                     LEFT OUTER JOIN (SELECT COUNT(1) AS [count],
                                             [student].[school_code],
                                             [student].[program_code]
                                      WHERE ([student].[is_active] <> 0)
                                      GROUP BY [student].[school_code], [student].[program_code]) AS [student]
                                     ON (([program].[school_code] = [student].[school_code]) AND ([program].[code] = [student].[program_code]))
-               WHERE ([school].[code] = 'bus')
+               WHERE ([program].[school_code] = 'bus')
                ORDER BY [program].[school_code] ASC, 1 ASC
           - uri: /define(school.program.student:=student?is_active) .count((school?code='bus').program.student)
             status: 200 OK
 
                ----
                /define(school.department.course:=course?credits>2,school.department.course:=course?credits<5,school.department:=department?code='acc').school.department.course{department.code,no,title,credits}
-               SELECT [department_2].[code],
+               SELECT [course].[department_code],
                       [course].[no],
                       [course].[title],
                       [course].[credits]
                FROM [ad].[school]
-                    INNER JOIN [ad].[department] AS [department_1]
-                               ON ([school].[code] = [department_1].[school_code])
+                    INNER JOIN [ad].[department]
+                               ON ([school].[code] = [department].[school_code])
                     INNER JOIN [ad].[course]
-                               ON ([department_1].[code] = [course].[department_code])
-                    INNER JOIN [ad].[department] AS [department_2]
-                               ON ([course].[department_code] = [department_2].[code])
+                               ON ([department].[code] = [course].[department_code])
                WHERE ([course].[credits] < 5)
                      AND ([course].[credits] > 2)
-                     AND ([department_1].[code] = 'acc')
-               ORDER BY [school].[code] ASC, [department_1].[code] ASC, [course].[department_code] ASC, 2 ASC
+                     AND ([department].[code] = 'acc')
+               ORDER BY [school].[code] ASC, [department].[code] ASC, 1 ASC, 2 ASC
           - uri: /define(double(x):=x*2){double(1),double(2),double(3)}
             status: 200 OK
             headers:
                FROM (SELECT [program].[degree],
                             COUNT(1) AS [count]
                      FROM [ad].[program]
-                          INNER JOIN [ad].[school]
-                                     ON ([program].[school_code] = [school].[code])
                      WHERE ([program].[degree] IS NOT NULL)
-                           AND ([school].[code] IN ('art', 'la'))
+                           AND ([program].[school_code] IN ('art', 'la'))
                      GROUP BY [program].[degree]) AS [program]
                     LEFT OUTER JOIN (SELECT COUNT(1) AS [count],
                                             [program].[degree]
                                      FROM [ad].[program]
-                                          INNER JOIN [ad].[school]
-                                                     ON ([program].[school_code] = [school].[code])
                                           INNER JOIN [ed].[student]
                                                      ON (([program].[school_code] = [student].[school_code]) AND ([program].[code] = [student].[program_code]))
-                                     WHERE ([school].[code] IN ('art', 'la'))
+                                     WHERE ([program].[school_code] IN ('art', 'la'))
                                      GROUP BY [program].[degree]) AS [student]
                                     ON ([program].[degree] = [student].[degree])
                ORDER BY 1 ASC
                       [program].[degree],
                       [program].[part_of_code]
                FROM [ad].[program]
-                    INNER JOIN [ad].[school]
-                               ON ([program].[school_code] = [school].[code])
                WHERE ([program].[degree] IS NOT NULL)
-                     AND ([school].[code] IN ('art', 'la'))
+                     AND ([program].[school_code] IN ('art', 'la'))
                ORDER BY 4 ASC, 1 ASC, 2 ASC
           - uri: /{(school^campus).campus}
             status: 400 Bad Request
 
              ----
              /enrollment[1010.[[mth.101].[2008.fall].001]]{id()}
-             SELECT [student_2].[id],
-                    [department_2].[code],
-                    [course_2].[no],
-                    [semester_2].[year],
-                    [semester_2].[season],
+             SELECT [enrollment].[student_id],
+                    [class_2].[department_code],
+                    [class_2].[course_no],
+                    [class_2].[year],
+                    [class_2].[season],
                     [class_2].[section]
              FROM [ed].[enrollment]
-                  INNER JOIN [ed].[student] AS [student_1]
-                             ON ([enrollment].[student_id] = [student_1].[id])
                   INNER JOIN [cd].[class] AS [class_1]
                              ON ([enrollment].[class_seq] = [class_1].[class_seq])
-                  INNER JOIN [ad].[course] AS [course_1]
-                             ON (([class_1].[department_code] = [course_1].[department_code]) AND ([class_1].[course_no] = [course_1].[no]))
-                  INNER JOIN [ad].[department] AS [department_1]
-                             ON ([course_1].[department_code] = [department_1].[code])
-                  INNER JOIN [cd].[semester] AS [semester_1]
-                             ON (([class_1].[year] = [semester_1].[year]) AND ([class_1].[season] = [semester_1].[season]))
-                  INNER JOIN [ed].[student] AS [student_2]
-                             ON ([enrollment].[student_id] = [student_2].[id])
                   INNER JOIN [cd].[class] AS [class_2]
                              ON ([enrollment].[class_seq] = [class_2].[class_seq])
-                  INNER JOIN [ad].[course] AS [course_2]
-                             ON (([class_2].[department_code] = [course_2].[department_code]) AND ([class_2].[course_no] = [course_2].[no]))
-                  INNER JOIN [ad].[department] AS [department_2]
-                             ON ([course_2].[department_code] = [department_2].[code])
-                  INNER JOIN [cd].[semester] AS [semester_2]
-                             ON (([class_2].[year] = [semester_2].[year]) AND ([class_2].[season] = [semester_2].[season]))
-             WHERE ([student_1].[id] = 1010)
-                   AND ([department_1].[code] = 'mth')
-                   AND ([course_1].[no] = 101)
-                   AND ([semester_1].[year] = 2008.)
-                   AND ([semester_1].[season] = 'fall')
+             WHERE ([enrollment].[student_id] = 1010)
+                   AND ([class_1].[department_code] = 'mth')
+                   AND ([class_1].[course_no] = 101)
+                   AND ([class_1].[year] = 2008.)
+                   AND ([class_1].[season] = 'fall')
                    AND ([class_1].[section] = '001')
-             ORDER BY [enrollment].[student_id] ASC, [enrollment].[class_seq] ASC
+             ORDER BY 1 ASC, [class_1].[department_code] ASC, [class_1].[course_no] ASC, [class_1].[year] ASC, [class_1].[season] ASC, [class_1].[section] ASC
       - id: no-rows
         tests:
         - uri: /school?false()/:raw
 
              ----
              /program.limit(2,3).school
-             SELECT [school].[code],
+             SELECT [program].[school_code],
                     [school].[name],
                     [school].[campus]
              FROM (SELECT [program].[school_code],
                              ON ([program].[school_code] = [school].[code])
              WHERE ([program].[limit] >= 4)
                    AND ([program].[limit] < 6)
-             ORDER BY [program].[school_code] ASC, [program].[code] ASC
+             ORDER BY 1 ASC, [program].[code] ASC
         - uri: /program.limit(2,3).student
           status: 200 OK
           headers:
 
              ----
              /program.limit(2,3).school
-             SELECT [school].[code],
+             SELECT [program].[school_code],
                     [school].[name],
                     [school].[campus]
              FROM (SELECT [program].[school_code],
                              ON ([program].[school_code] = [school].[code])
              WHERE ([program].[limit] >= 4)
                    AND ([program].[limit] < 6)
-             ORDER BY [program].[school_code] ASC, [program].[code] ASC
+             ORDER BY 1 ASC, [program].[code] ASC
         - uri: /program.limit(2,3).student
           status: 200 OK
           headers:
 
              ----
              /(field?table_name='school').table
-             SELECT "table"."name"
+             SELECT "field"."table_name"
              FROM "field"
                   INNER JOIN "table"
                              ON ("field"."table_name" = "table"."name")
              WHERE ("field"."table_name" = 'school')
-             ORDER BY "field"."table_name" ASC, "field"."name" ASC
+             ORDER BY 1 ASC, "field"."name" ASC
         - uri: /(field?table_name='school').column/:meta
           status: 200 OK
           headers:
 
              ----
              /(column?table_name='program').table
-             SELECT "table"."name"
+             SELECT "column"."table_name"
              FROM "column"
                   INNER JOIN "table"
                              ON ("column"."table_name" = "table"."name")
              WHERE ("column"."table_name" = 'program')
-             ORDER BY "column"."table_name" ASC, "column"."name" ASC
+             ORDER BY 1 ASC, "column"."name" ASC
         - uri: /(column?table_name='program').field/:meta
           status: 200 OK
           headers:
 
              ----
              /(column?table_name='program').field
-             SELECT "field"."table_name",
-                    "field"."name",
+             SELECT "column"."table_name",
+                    "column"."name",
                     "field"."kind",
                     "field"."sort"
              FROM "column"
                   INNER JOIN "field"
                              ON (("column"."table_name" = "field"."table_name") AND ("column"."name" = "field"."name"))
              WHERE ("column"."table_name" = 'program')
-             ORDER BY "column"."table_name" ASC, "column"."name" ASC
+             ORDER BY 1 ASC, 2 ASC
         - uri: /(link?table_name='student').table/:meta
           status: 200 OK
           headers:
 
              ----
              /(link?table_name='student').table
-             SELECT "table"."name"
+             SELECT "link"."table_name"
              FROM "link"
                   INNER JOIN "table"
                              ON ("link"."table_name" = "table"."name")
              WHERE ("link"."table_name" = 'student')
-             ORDER BY "link"."table_name" ASC, "link"."name" ASC
+             ORDER BY 1 ASC, "link"."name" ASC
         - uri: /(link?table_name='student').target/:meta
           status: 200 OK
           headers:
 
              ----
              /(link?table_name='student').target
-             SELECT "table"."name"
+             SELECT "link"."target_name"
              FROM "link"
                   INNER JOIN "table"
                              ON ("link"."target_name" = "table"."name")
 
              ----
              /(link?table_name='student').field
-             SELECT "field"."table_name",
-                    "field"."name",
+             SELECT "link"."table_name",
+                    "link"."name",
                     "field"."kind",
                     "field"."sort"
              FROM "link"
                   INNER JOIN "field"
                              ON (("link"."table_name" = "field"."table_name") AND ("link"."name" = "field"."name"))
              WHERE ("link"."table_name" = 'student')
-             ORDER BY "link"."table_name" ASC, "link"."name" ASC
+             ORDER BY 1 ASC, 2 ASC
         - uri: /(link?table_name='student').reverse/:meta
           status: 200 OK
           headers:
 
              ----
              /field?table_name='school'{table{name},name,kind,column{domain},link{is_singular}}
-             SELECT "table"."name",
+             SELECT "field"."table_name",
                     "field"."name",
                     "field"."kind",
                     "column"."!",
                     "link"."!",
                     "link"."is_singular"
              FROM "field"
-                  INNER JOIN "table"
-                             ON ("field"."table_name" = "table"."name")
                   LEFT OUTER JOIN (SELECT 1 AS "!",
                                           "column"."domain",
                                           "column"."table_name",
                                    FROM "link") AS "link"
                                   ON (("field"."table_name" = "link"."table_name") AND ("field"."name" = "link"."name"))
              WHERE ("field"."table_name" = 'school')
-             ORDER BY "field"."table_name" ASC, 2 ASC
+             ORDER BY 1 ASC, 2 ASC
         - uri: /column?table_name='program' {table{name}, field{name, sort}} /:meta
           status: 200 OK
           headers:
 
              ----
              /column?table_name='program'{table{name},field{name,sort}}
-             SELECT "table"."name",
-                    "field"."name",
+             SELECT "column"."table_name",
+                    "column"."name",
                     "field"."sort"
              FROM "column"
-                  INNER JOIN "table"
-                             ON ("column"."table_name" = "table"."name")
                   INNER JOIN "field"
                              ON (("column"."table_name" = "field"."table_name") AND ("column"."name" = "field"."name"))
              WHERE ("column"."table_name" = 'program')
-             ORDER BY "column"."table_name" ASC, "column"."name" ASC
+             ORDER BY 1 ASC, 2 ASC
         - uri: /link?table_name='student' {table{name}, target{name}, field{name},
             reverse{name}, link_via_reverse{name}} /:meta
           status: 200 OK
 
              ----
              /link?table_name='student'{table{name},target{name},field{name},reverse{name},link_via_reverse{name}}
-             SELECT "table_1"."name",
-                    "table_2"."name",
-                    "field"."name",
+             SELECT "link_1"."table_name",
+                    "link_1"."target_name",
+                    "link_1"."name",
                     "link_2"."!",
                     "link_2"."name",
                     "link_3"."!",
                     "link_3"."name"
              FROM "link" AS "link_1"
-                  INNER JOIN "table" AS "table_1"
-                             ON ("link_1"."table_name" = "table_1"."name")
-                  INNER JOIN "table" AS "table_2"
-                             ON ("link_1"."target_name" = "table_2"."name")
-                  INNER JOIN "field"
-                             ON (("link_1"."table_name" = "field"."table_name") AND ("link_1"."name" = "field"."name"))
                   LEFT OUTER JOIN (SELECT 1 AS "!",
                                           "link"."name",
                                           "link"."table_name"
                                    FROM "link") AS "link_3"
                                   ON (("link_1"."table_name" = "link_3"."target_name") AND ("link_1"."name" = "link_3"."reverse_name"))
              WHERE ("link_1"."table_name" = 'student')
-             ORDER BY "link_1"."table_name" ASC, "link_1"."name" ASC
+             ORDER BY 1 ASC, 3 ASC
         - uri: /count(table)/:meta
           status: 200 OK
           headers:
             | _\u043D\u0430\u0444_\u043D\u0430\u0444_        | string   | false        |\n\n
             ----\n /column.sort(table.name,field.sort)\n SELECT \"column\".\"table_name\",\n
             \       \"column\".\"name\",\n        \"column\".\"domain\",\n        \"column\".\"is_mandatory\"\n
-            FROM \"column\"\n      INNER JOIN \"table\"\n                 ON (\"column\".\"table_name\"
-            = \"table\".\"name\")\n      INNER JOIN \"field\"\n                 ON
-            ((\"column\".\"table_name\" = \"field\".\"table_name\") AND (\"column\".\"name\"
-            = \"field\".\"name\"))\n ORDER BY \"table\".\"name\" ASC, \"field\".\"sort\"
-            ASC, 1 ASC, 2 ASC\n"
+            FROM \"column\"\n      INNER JOIN \"field\"\n                 ON ((\"column\".\"table_name\"
+            = \"field\".\"table_name\") AND (\"column\".\"name\" = \"field\".\"name\"))\n
+            ORDER BY 1 ASC, \"field\".\"sort\" ASC, 2 ASC\n"
       - id: tweak.override
         tests:
         - ctl: [ext, tweak.override]
              SELECT TOP 1
                     [student].[name],
                     [student].[dob],
-                    [school].[code],
-                    [program].[code],
+                    [student].[school_code],
+                    [student].[program_code],
                     (CASE WHEN EXISTS(SELECT 1
                                       FROM [id].[instructor]
                                       WHERE ([student].[name] = [instructor].[full_name])
                                             AND (1 <> 0)) THEN 1 ELSE 0 END)
              FROM [ed].[student]
-                  INNER JOIN [ad].[school]
-                             ON ([student].[school_code] = [school].[code])
-                  INNER JOIN [ad].[program]
-                             ON (([student].[school_code] = [program].[school_code]) AND ([student].[program_code] = [program].[code]))
              ORDER BY 1 ASC, 2 ASC
         - uri: /count(c14n)
           status: 200 OK

test/output/mysql.yaml

              +------------+-----------+--------+-------+
              | student_id | class_seq | status | grade |
             -+------------+-----------+--------+-------+-
+             |       1001 |      1121 | inc    |  2.30 |
+             |       1001 |      1117 | ngr    |  4.00 |
+             |       1001 |      1096 | inc    |  2.90 |
              |       1001 |      1070 | ngr    |       |
+             |       1001 |      1098 | ngr    |  2.80 |
              |       1001 |      1088 | enr    |  2.60 |
-             |       1001 |      1096 | inc    |  2.90 |
-             |       1001 |      1098 | ngr    |  2.80 |
-             |       1001 |      1117 | ngr    |  4.00 |
-             |       1001 |      1121 | inc    |  2.30 |
              |       1001 |      1301 | enr    |  0.40 |
              |       1001 |      1397 | inc    |  1.50 |
+             |       1001 |      1442 | enr    |  2.30 |
              |       1001 |      1430 | enr    |  3.50 |
-             |       1001 |      1442 | enr    |  2.30 |
              |       1001 |      1516 | ngr    |  4.00 |
              |       1001 |      1551 | ngr    |  0.20 |
              |       1001 |      1576 | inc    |  4.00 |
              |       1001 |      1586 | enr    |  1.10 |
              |       1001 |      1666 | enr    |       |
-             |       1001 |      1672 | enr    |  3.00 |
+             |       1001 |      1738 | ngr    |  1.20 |
              |       1001 |      1679 | inc    |  2.70 |
              |       1001 |      1687 | ngr    |  1.90 |
+             |       1001 |      1723 | inc    |  4.00 |
+             |       1001 |      1672 | enr    |  3.00 |
              |       1001 |      1715 | inc    |  2.80 |
-             |       1001 |      1723 | inc    |  4.00 |
-             |       1001 |      1738 | ngr    |  1.20 |
              |       1001 |      1741 | enr    |  1.90 |
+             |       1001 |      1770 | inc    |  3.50 |
              |       1001 |      1766 | ngr    |  1.40 |
-             |       1001 |      1770 | inc    |  3.50 |
              |       1001 |      1785 | ngr    |  0.70 |
+             |       1001 |      1821 | enr    |  2.60 |
              |       1001 |      1795 | inc    |  3.40 |
-             |       1001 |      1821 | enr    |  2.60 |
+             |       1001 |      1881 | enr    |  1.70 |
+             |       1001 |      1928 | ngr    |  1.80 |
+             |       1001 |      1873 | ngr    |  2.60 |
              |       1001 |      1857 | ngr    |  2.90 |
-             |       1001 |      1873 | ngr    |  2.60 |
-             |       1001 |      1881 | enr    |  1.70 |
              |       1001 |      1911 | inc    |  0.60 |
-             |       1001 |      1928 | ngr    |  1.80 |
              |       1001 |      2135 | ngr    |  2.30 |
-             |       1001 |      2158 | enr    |  1.40 |
              |       1001 |      2194 | enr    |  2.40 |
              |       1001 |      2198 | enr    |  3.20 |
+             |       1001 |      2158 | enr    |  1.40 |
              |       1001 |      2252 | enr    |  2.90 |
+             |       1001 |      2318 | enr    |  1.70 |
+             |       1001 |      2287 | enr    |       |
              |       1001 |      2280 | enr    |  2.00 |
-             |       1001 |      2287 | enr    |       |
-             |       1001 |      2318 | enr    |  1.70 |
              |       1001 |      2382 | inc    |  3.20 |
              |       1001 |      2393 | enr    |  1.50 |
-             |       1001 |      2443 | ngr    |  0.90 |
+             |       1001 |      2462 | ngr    |  3.40 |
              |       1001 |      2448 | ngr    |  4.00 |
              |       1001 |      2457 | enr    |  1.70 |
-             |       1001 |      2462 | ngr    |  3.40 |
              |       1001 |      2473 | ngr    |  2.60 |
+             |       1001 |      2443 | ngr    |  0.90 |
+             |       1001 |      2544 | ngr    |  3.10 |
              |       1001 |      2492 | ngr    |  2.90 |
              |       1001 |      2502 | ngr    |  2.30 |
-             |       1001 |      2544 | ngr    |  3.10 |
 
              ----
              /enrollment.limit(50)
                     `enrollment`.`status`,
                     `enrollment`.`grade`
              FROM `enrollment`
-             ORDER BY 1 ASC, 2 ASC
+                  INNER JOIN `class`
+                             ON (`enrollment`.`class_seq` = `class`.`class_seq`)
+             ORDER BY 1 ASC, `class`.`department_code` ASC, `class`.`course_no` ASC, `class`.`year` ASC, `class`.`season` ASC, `class`.`section` ASC
              LIMIT 50
         - uri: /prerequisite.limit(50)
           status: 200 OK
 
              ----
              /(program?school_code='la'&code='uengl').school
-             SELECT `school`.`code`,
+             SELECT `program`.`school_code`,
                     `school`.`name`,
                     `school`.`campus`
              FROM `program`
                              ON (`program`.`school_code` = `school`.`code`)
              WHERE (`program`.`school_code` = 'la')
                    AND (`program`.`code` = 'uengl')
-             ORDER BY `program`.`school_code` ASC, `program`.`code` ASC
+             ORDER BY 1 ASC, `program`.`code` ASC
         - uri: /(program?school_code='la'&code='uengl').program
           status: 400 Bad Request
           headers:
 
              ----
              /(course?department_code='lang'&no=345).department
-             SELECT `department`.`code`,
+             SELECT `course`.`department_code`,
                     `department`.`name`,
                     `department`.`school_code`
              FROM `course`
                              ON (`course`.`department_code` = `department`.`code`)
              WHERE (`course`.`department_code` = 'lang')
                    AND (`course`.`no` = 345)
-             ORDER BY `course`.`department_code` ASC, `course`.`no` ASC
+             ORDER BY 1 ASC, `course`.`no` ASC
         - uri: /(course?department_code='lang'&no=345).class
           status: 200 OK
           headers:
 
              ----
              /(confidential?instructor_code='bdoyle').instructor
-             SELECT `instructor`.`code`,
+             SELECT `confidential`.`instructor_code`,
                     `instructor`.`title`,
                     `instructor`.`full_name`,
                     `instructor`.`phone`,
                   INNER JOIN `instructor`
                              ON (`confidential`.`instructor_code` = `instructor`.`code`)
              WHERE (`confidential`.`instructor_code` = 'bdoyle')
-             ORDER BY `confidential`.`instructor_code` ASC
+             ORDER BY 1 ASC
         - uri: /(appointment?department_code='be' &instructor_code='bdoyle').department
           status: 200 OK
           headers:
 
              ----
              /(appointment?department_code='be'&instructor_code='bdoyle').department
-             SELECT `department`.`code`,
+             SELECT `appointment`.`department_code`,
                     `department`.`name`,
                     `department`.`school_code`
              FROM `appointment`
                              ON (`appointment`.`department_code` = `department`.`code`)
              WHERE (`appointment`.`department_code` = 'be')
                    AND (`appointment`.`instructor_code` = 'bdoyle')
-             ORDER BY `appointment`.`department_code` ASC, `appointment`.`instructor_code` ASC
+             ORDER BY 1 ASC, `appointment`.`instructor_code` ASC
         - uri: /(appointment?department_code='be' &instructor_code='bdoyle').instructor
           status: 200 OK
           headers:
 
              ----
              /(appointment?department_code='be'&instructor_code='bdoyle').instructor
-             SELECT `instructor`.`code`,
+             SELECT `appointment`.`instructor_code`,
                     `instructor`.`title`,
                     `instructor`.`full_name`,
                     `instructor`.`phone`,
                              ON (`appointment`.`instructor_code` = `instructor`.`code`)
              WHERE (`appointment`.`department_code` = 'be')
                    AND (`appointment`.`instructor_code` = 'bdoyle')
-             ORDER BY `appointment`.`department_code` ASC, `appointment`.`instructor_code` ASC
+             ORDER BY `appointment`.`department_code` ASC, 1 ASC
         - uri: /(semester?year=2010&season='fall').class.limit(50)
           status: 200 OK
           headers:
 
              ----
              /(class?class_seq=1055).course
-             SELECT `course`.`department_code`,
-                    `course`.`no`,
+             SELECT `class`.`department_code`,
+                    `class`.`course_no`,
                     `course`.`title`,
                     `course`.`credits`,
                     `course`.`description`
                   INNER JOIN `course`
                              ON ((`class`.`department_code` = `course`.`department_code`) AND (`class`.`course_no` = `course`.`no`))
              WHERE (`class`.`class_seq` = 1055)
-             ORDER BY `class`.`department_code` ASC, `class`.`course_no` ASC, `class`.`year` ASC, `class`.`season` ASC, `class`.`section` ASC
+             ORDER BY 1 ASC, 2 ASC, `class`.`year` ASC, `class`.`season` ASC, `class`.`section` ASC
         - uri: /(class?class_seq=1055).semester
           status: 200 OK
           headers:
 
              ----
              /(class?class_seq=1055).semester
-             SELECT `semester`.`year`,
-                    `semester`.`season`,
+             SELECT `class`.`year`,
+                    `class`.`season`,
                     `semester`.`begin_date`,
                     `semester`.`end_date`
              FROM `class`
                   INNER JOIN `semester`
                              ON ((`class`.`year` = `semester`.`year`) AND (`class`.`season` = `semester`.`season`))
              WHERE (`class`.`class_seq` = 1055)
-             ORDER BY `class`.`department_code` ASC, `class`.`course_no` ASC, `class`.`year` ASC, `class`.`season` ASC, `class`.`section` ASC
+             ORDER BY `class`.`department_code` ASC, `class`.`course_no` ASC, 1 ASC, 2 ASC, `class`.`section` ASC
         - uri: /(class?class_seq=1055).instructor
           status: 200 OK
           headers:
                     `enrollment`.`class_seq`,
                     `enrollment`.`status`,
                     `enrollment`.`grade`
-             FROM `class`
+             FROM `class` AS `class_1`
                   INNER JOIN `enrollment`
-                             ON (`class`.`class_seq` = `enrollment`.`class_seq`)
-             WHERE (`class`.`class_seq` = 1055)
-             ORDER BY `class`.`department_code` ASC, `class`.`course_no` ASC, `class`.`year` ASC, `class`.`season` ASC, `class`.`section` ASC, 1 ASC, 2 ASC
+                             ON (`class_1`.`class_seq` = `enrollment`.`class_seq`)
+                  INNER JOIN `class` AS `class_2`
+                             ON (`enrollment`.`class_seq` = `class_2`.`class_seq`)
+             WHERE (`class_1`.`class_seq` = 1055)
+             ORDER BY `class_1`.`department_code` ASC, `class_1`.`course_no` ASC, `class_1`.`year` ASC, `class_1`.`season` ASC, `class_1`.`section` ASC, 1 ASC, `class_2`.`department_code` ASC, `class_2`.`course_no` ASC, `class_2`.`year` ASC, `class_2`.`season` ASC, `class_2`.`section` ASC
         - uri: /(student?id=1010).program
           status: 200 OK
           headers:
              | student_id | class_seq | status | grade |
             -+------------+-----------+--------+-------+-
              |       1010 |      1041 | inc    |  4.00 |
+             |       1010 |      1122 | inc    |  3.80 |
+             |       1010 |      1082 | enr    |  0.20 |
              |       1010 |      1066 | enr    |  2.20 |
+             |       1010 |      1123 | inc    |  0.00 |
              |       1010 |      1071 | inc    |  3.70 |
-             |       1010 |      1082 | enr    |  0.20 |
+             |       1010 |      1097 | enr    |  4.00 |
              |       1010 |      1085 | enr    |  3.10 |
              |       1010 |      1089 | ngr    |       |
-             |       1010 |      1097 | enr    |  4.00 |
-             |       1010 |      1122 | inc    |  3.80 |
-             |       1010 |      1123 | inc    |  0.00 |
+             |       1010 |      1220 | ngr    |  3.00 |
              |       1010 |      1213 | enr    |  2.40 |
-             |       1010 |      1220 | ngr    |  3.00 |
              |       1010 |      1409 | ngr    |  3.30 |
              |       1010 |      1429 | enr    |  1.90 |
+             |       1010 |      1514 | enr    |  2.10 |
              |       1010 |      1509 | inc    |  1.60 |
-             |       1010 |      1514 | enr    |  2.10 |
              |       1010 |      1544 | ngr    |  0.40 |
              |       1010 |      1590 | inc    |  2.20 |
              |       1010 |      1658 | ngr    |  3.70 |
+             |       1010 |      1746 | ngr    |  1.00 |
              |       1010 |      1666 | enr    |  2.60 |
              |       1010 |      1713 | inc    |  3.30 |
+             |       1010 |      1729 | ngr    |  3.30 |
              |       1010 |      1719 | enr    |  0.40 |
-             |       1010 |      1729 | ngr    |  3.30 |
              |       1010 |      1742 | ngr    |  2.50 |
-             |       1010 |      1746 | ngr    |  1.00 |
              |       1010 |      1752 | enr    |  1.20 |
+             |       1010 |      1825 | enr    |  3.00 |
+             |       1010 |      1829 | inc    |  2.00 |
+             |       1010 |      1812 | ngr    |  3.70 |
              |       1010 |      1785 | inc    |  3.10 |
              |       1010 |      1804 | ngr    |  2.40 |
-             |       1010 |      1812 | ngr    |  3.70 |
              |       1010 |      1817 | inc    |  4.00 |
-             |       1010 |      1825 | enr    |  3.00 |
-             |       1010 |      1829 | inc    |  2.00 |
+             |       1010 |      1896 | ngr    |  3.90 |
+             |       1010 |      1895 | ngr    |  4.00 |
+             |       1010 |      1847 | inc    |  2.70 |
+             |       1010 |      1854 | inc    |  3.80 |
              |       1010 |      1844 | ngr    |  4.00 |
-             |       1010 |      1847 | inc    |  2.70 |
              |       1010 |      1852 | ngr    |  3.60 |
-             |       1010 |      1854 | inc    |  3.80 |
-             |       1010 |      1895 | ngr    |  4.00 |
-             |       1010 |      1896 | ngr    |  3.90 |
+             |       1010 |      2105 | ngr    |  3.10 |
              |       1010 |      2101 | ngr    |  2.50 |
-             |       1010 |      2105 | ngr    |  3.10 |
              |       1010 |      2109 | enr    |  4.00 |
              |       1010 |      2121 | ngr    |       |
              |       1010 |      2192 | ngr    |  2.90 |
+             |       1010 |      2272 | enr    |  4.00 |
              |       1010 |      2256 | ngr    |  0.50 |
-             |       1010 |      2272 | enr    |  4.00 |
+             |       1010 |      2315 | ngr    |  2.40 |
              |       1010 |      2276 | enr    |  2.10 |
              |       1010 |      2311 | enr    |  1.50 |
-             |       1010 |      2315 | ngr    |  2.40 |
              |       1010 |      2393 | enr    |  4.00 |
              |       1010 |      2447 | ngr    |  4.00 |
              |       1010 |      2471 | enr    |  1.70 |
              FROM `student`
                   INNER JOIN `enrollment`
                              ON (`student`.`id` = `enrollment`.`student_id`)
+                  INNER JOIN `class`
+                             ON (`enrollment`.`class_seq` = `class`.`class_seq`)
              WHERE (`student`.`id` = 1010)
-             ORDER BY `student`.`id` ASC, 1 ASC, 2 ASC
+             ORDER BY `student`.`id` ASC, 1 ASC, `class`.`department_code` ASC, `class`.`course_no` ASC, `class`.`year` ASC, `class`.`season` ASC, `class`.`section` ASC
              LIMIT 50
         - uri: /(enrollment?student_id=1100&class_seq=1110).student
           status: 200 OK
 
              ----
              /(enrollment?student_id=1100&class_seq=1110).student
-             SELECT `student`.`id`,
+             SELECT `enrollment`.`student_id`,
                     `student`.`name`,
                     `student`.`gender`,
                     `student`.`dob`,
              FROM `enrollment`
                   INNER JOIN `student`
                              ON (`enrollment`.`student_id` = `student`.`id`)
+                  INNER JOIN `class`
+                             ON (`enrollment`.`class_seq` = `class`.`class_seq`)
              WHERE (`enrollment`.`student_id` = 1100)
                    AND (`enrollment`.`class_seq` = 1110)
-             ORDER BY `enrollment`.`student_id` ASC, `enrollment`.`class_seq` ASC
+             ORDER BY 1 ASC, `class`.`department_code` ASC, `class`.`course_no` ASC, `class`.`year` ASC, `class`.`season` ASC, `class`.`section` ASC
         - uri: /(enrollment?student_id=1100&class_seq=1110).class
           status: 200 OK
           headers:
                     `class`.`season`,
                     `class`.`section`,
                     `class`.`instructor_code`,
-                    `class`.`class_seq`
+                    `enrollment`.`class_seq`
              FROM `enrollment`
                   INNER JOIN `class`
                              ON (`enrollment`.`class_seq` = `class`.`class_seq`)
              WHERE (`enrollment`.`student_id` = 1100)
                    AND (`enrollment`.`class_seq` = 1110)
-             ORDER BY `enrollment`.`student_id` ASC, `enrollment`.`class_seq` ASC
+             ORDER BY `enrollment`.`student_id` ASC, 1 ASC, 2 ASC, 3 ASC, 4 ASC, 5 ASC
         - uri: /(prerequisite?of_department_code='astro'&of_course_no=230 &on_department_code='phys'&on_course_no=130).course
           status: 400 Bad Request
           headers:
 
              ----
              /(prerequisite?of_department_code='astro'&of_course_no=230&on_department_code='phys'&on_course_no=130).of_course
-             SELECT `course`.`department_code`,
-                    `course`.`no`,
+             SELECT `prerequisite`.`of_department_code`,
+                    `prerequisite`.`of_course_no`,
                     `course`.`title`,
                     `course`.`credits`,
                     `course`.`description`
                    AND (`prerequisite`.`of_course_no` = 230)
                    AND (`prerequisite`.`on_department_code` = 'phys')
                    AND (`prerequisite`.`on_course_no` = 130)
-             ORDER BY `prerequisite`.`of_department_code` ASC, `prerequisite`.`of_course_no` ASC, `prerequisite`.`on_department_code` ASC, `prerequisite`.`on_course_no` ASC
+             ORDER BY 1 ASC, 2 ASC, `prerequisite`.`on_department_code` ASC, `prerequisite`.`on_course_no` ASC
         - uri: /(prerequisite?of_department_code='astro'&of_course_no=230 &on_department_code='phys'&on_course_no=130).on_course
           status: 200 OK
           headers:
 
              ----
              /(prerequisite?of_department_code='astro'&of_course_no=230&on_department_code='phys'&on_course_no=130).on_course
-             SELECT `course`.`department_code`,
-                    `course`.`no`,
+             SELECT `prerequisite`.`on_department_code`,
+                    `prerequisite`.`on_course_no`,
                     `course`.`title`,
                     `course`.`credits`,
                     `course`.`description`
                    AND (`prerequisite`.`of_course_no` = 230)
                    AND (`prerequisite`.`on_department_code` = 'phys')
                    AND (`prerequisite`.`on_course_no` = 130)
-             ORDER BY `prerequisite`.`of_department_code` ASC, `prerequisite`.`of_course_no` ASC, `prerequisite`.`on_department_code` ASC, `prerequisite`.`on_course_no` ASC
+             ORDER BY `prerequisite`.`of_department_code` ASC, `prerequisite`.`of_course_no` ASC, 1 ASC, 2 ASC
         - uri: /(classification?code='math').classification
           status: 400 Bad Request
           headers:
 
              ----
              /(course_classification?department_code='astro'&course_no=110&classification_code='astrotheory').course