Commits

Kirill Simonov committed cd26d5a

Working on `.order()` and `.limit()` methods.

  • Participants
  • Parent commits 44016dc

Comments (0)

Files changed (6)

File src/htsql/tr/assembler.py

 
     def assemble(self, baseline):
         child = self.assembler.assemble(self.space.parent, baseline)
-        for code, dir in self.space.order:
+        order = []
+        codes = set()
+        for code, dir in self.space.ordering():
+            if code not in codes:
+                order.append((code, dir))
+                codes.add(code)
+        for code, dir in order:
             child = self.assembler.inject(code, child)
         assert self.space not in child.routes
         routes = {}
         for key in child.routes:
             routes[key] = [FORWARD] + child.routes[key]
         routes[self.space] = [FORWARD] + child.routes[self.space.parent]
-        return OrderingTerm(child, self.space.order,
+        return OrderingTerm(child, order,
                             self.space.limit, self.space.offset,
                             self.space, baseline, routes, self.space.mark)
 

File src/htsql/tr/code.py

     def resembles(self, other):
         return False
 
+    def ordering(self, with_strong=True, with_weak=True):
+        return self.parent.ordering(with_strong, with_weak)
+
 
 class ScalarSpace(Space):
 
     def resembles(self, other):
         return isinstance(other, ScalarSpace)
 
+    def ordering(self, with_strong=True, with_weak=True):
+        return []
+
 
 class FreeTableSpace(Space):
 
     def resembles(self, other):
         return isinstance(other, FreeTableSpace)
 
+    def ordering(self, with_strong=True, with_weak=True):
+        order = []
+        if with_strong:
+            order += self.parent.ordering(with_strong=True, with_weak=False)
+        if with_weak:
+            order += self.parent.ordering(with_strong=False, with_weak=True)
+            if self.table.primary_key is not None:
+                for column_name in self.table.primary_key.origin_column_names:
+                    column = self.table.columns[column_name]
+                    code = ColumnUnit(column, self, self.mark)
+                    order.append((code, +1))
+        return order
+
 
 class JoinedTableSpace(Space):
 
         return (isinstance(other, JoinedTableSpace) and
                 self.join is other.join)
 
+    def ordering(self, with_strong=True, with_weak=True):
+        order = []
+        if with_strong:
+            order += self.parent.ordering(with_strong=True, with_weak=False)
+        if with_weak:
+            order += self.parent.ordering(with_strong=False, with_weak=True)
+            if not self.is_contracting and self.table.primary_key is not None:
+                for column_name in self.table.primary_key.origin_column_names:
+                    column = self.table.columns[column_name]
+                    code = ColumnUnit(column, self, self.mark)
+                    order.append((code, +1))
+        return order
+
 
 class ScreenSpace(Space):
 
 
     def resembles(self, other):
         return (isinstance(other, OrderedSpace) and
-                self.other == other.order and
+                self.order == other.order and
                 self.limit == other.limit and
                 self.offset == other.offset)
 
+    def ordering(self, with_strong=True, with_weak=True):
+        order = []
+        if with_strong:
+            order += self.parent.ordering(with_strong=True, with_weak=False)
+            order += self.order
+        if with_weak:
+            order += self.parent.ordering(with_strong=False, with_weak=True)
+        return order
+
 
 class Expression(Code):
 

File src/htsql/tr/encoder.py

 
     def encode(self):
         space = self.encoder.relate(self.binding.base)
+        space = OrderedSpace(space, [], None, None, space.mark)
         elements = []
-        order = []
-        order_set = set()
         for binding in self.binding.elements:
             element = self.encoder.encode_element(binding)
             elements.append(element.code)
-        if space.table is not None and space.table.primary_key is not None:
-            for column_name in space.table.primary_key.origin_column_names:
-                column = space.table.columns[column_name]
-                code = ColumnUnit(column, space, self.binding.mark)
-                if code not in order_set:
-                    order.append((code, +1))
-                    order_set.add(code)
-        if order:
-            space = OrderedSpace(space, order, None, None, space.mark)
         return SegmentCode(space, elements, self.binding.mark)
 
 
 
     def relate(self):
         space = self.encoder.relate(self.binding.parent)
-        order = [self.encoder.encode(binding)
-                 for binding in self.binding.order]
+        order = [(self.encoder.encode(binding), dir)
+                 for binding, dir in self.binding.order]
         limit = self.binding.limit
         offset = self.binding.offset
         return OrderedSpace(space, order, limit, offset, self.binding.mark)

File src/htsql/tr/fn/function.py

         yield OrderedBinding(parent, [], limit, offset, syntax)
 
 
+class OrderMethod(ProperMethod):
+
+    adapts(named['order'])
+
+    parameters = [
+            Parameter('this'),
+            Parameter('order', is_list=True),
+    ]
+
+    def correlate(self, this, order, syntax, parent):
+        bindings = order
+        order = []
+        for binding in bindings:
+            domain = self.binder.coerce(binding.domain)
+            if domain is None:
+                raise InvalidArgumentError("unexpected type",
+                                           binding.mark)
+            binding = self.binder.cast(binding, domain)
+            order.append((binding, +1))
+        yield OrderedBinding(parent, order, None, None, syntax)
+
+
 class NullFunction(ProperFunction):
 
     adapts(named['null'])

File test/input/pgsql.yaml

         - uri: /{date('2010-07-28')+1,date('2010-07-28')-1,
                  date('2010-07-28')-date('2009-07-28')}
 
+  # Order and Limit functions.
+  - title: Sorting and paging.
+    tests:
+    - uri: /school
+    - uri: /school.limit(1)
+    - uri: /school.limit(2,5)
+    - uri: /course?department='acc'
+    - uri: /course.order(credits)?department='acc'
+    - uri: /course.order(credits).limit(1,1)?department='acc'
+
+
   # Simple (non-aggregate) filters.
   - title: Simple filters
     tests:

File test/output/pgsql.yaml

              ----
              /{date('2010-07-28')+1,date('2010-07-28')-1,date('2010-07-28')-date('2009-07-28')}
              SELECT (CAST('2010-07-28' AS DATE) + 1), (CAST('2010-07-28' AS DATE) - 1), (CAST('2010-07-28' AS DATE) - CAST('2009-07-28' AS DATE))
+  - id: sorting-and-paging.
+    tests:
+    - uri: /school
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | school                                  |
+        -+-----------------------------------------+-
+         | code | name                             |
+        -+------+----------------------------------+-
+         | art  | School of Art and Design         |
+         | bus  | School of Business               |
+         | edu  | College of Education             |
+         | egn  | School of Engineering            |
+         | la   | School of Arts, Letters, and the |
+         :      : Humanities                       :
+         | mart | School of Modern Art             |
+         | mus  | Musical School                   |
+         | ns   | School of Natural Sciences       |
+         | sc   | School of Continuing Studies     |
+                                            (9 rows)
+
+         ----
+         /school
+         SELECT "school"."code", "school"."name" FROM "ad"."school" AS "school" ORDER BY 1 ASC
+    - uri: /school.limit(1)
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | school.limit(1)                 |
+        -+---------------------------------+-
+         | code | name                     |
+        -+------+--------------------------+-
+         | art  | School of Art and Design |
+                                     (1 row)
+
+         ----
+         /school.limit(1)
+         SELECT "school"."code", "school"."name" FROM (SELECT "school"."code", "school"."name" FROM "ad"."school" AS "school" ORDER BY 1 ASC LIMIT 1) AS "school" ORDER BY 1 ASC
+    - uri: /school.limit(2,5)
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | school.limit(2,5)           |
+        -+-----------------------------+-
+         | code | name                 |
+        -+------+----------------------+-
+         | mart | School of Modern Art |
+         | mus  | Musical School       |
+                                (2 rows)
+
+         ----
+         /school.limit(2,5)
+         SELECT "school"."code", "school"."name" FROM (SELECT "school"."code", "school"."name" FROM "ad"."school" AS "school" ORDER BY 1 ASC LIMIT 2 OFFSET 5) AS "school" ORDER BY 1 ASC
+    - uri: /course?department='acc'
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | (course?department='acc')                                                                     |
+        -+-----------------------------------------------------------------------------------------------+-
+         | department | number | title                      | credits | description                      |
+        -+------------+--------+----------------------------+---------+----------------------------------+-
+         | acc        |    100 | Practical Bookkeeping      |       2 | A introduction to business with  |
+         :            :        :                            :         : practical bookkeeping            :
+         :            :        :                            :         : application.                     :
+         | acc        |    200 | Principles of Accounting I |       3 | The initial course in the theory |
+         :            :        :                            :         : and practice of financial        :
+         :            :        :                            :         : accounting. Topics emphasized    :
+         :            :        :                            :         : include the preparation,         :
+         :            :        :                            :         : reporting, and analysis of       :
+         :            :        :                            :         : financial data.                  :
+         | acc        |    315 | Financial Accounting       |       5 | Integration of the conceptual    |
+         :            :        :                            :         : and computational aspects of     :
+         :            :        :                            :         : asset, liability and             :
+         :            :        :                            :         : stockholders equity accounting.  :
+         | acc        |    426 | Corporate Taxation         |       3 | Concepts and methods of          |
+         :            :        :                            :         : determining federal tax          :
+         :            :        :                            :         : liability of corporations.       :
+         | acc        |    527 | Advanced Accounting        |       3 | Theory and practical             |
+         :            :        :                            :         : applications of accounting for   :
+         :            :        :                            :         : consolidated entities and        :
+         :            :        :                            :         : partnerships; includes foreign   :
+         :            :        :                            :         : currency transactions, hedging   :
+         :            :        :                            :         : and derivatives.                 :
+         | acc        |    606 | Corporate Financial Law    |       3 | Law governing business           |
+         :            :        :                            :         : corporations; fiduciary duties   :
+         :            :        :                            :         : of managers and directors in     :
+         :            :        :                            :         : situations such as mergers,      :
+         :            :        :                            :         : acquisitions, securities         :
+         :            :        :                            :         : offerings, market domination,    :
+         :            :        :                            :         : litigation.                      :
+                                                                                                  (6 rows)
+
+         ----
+         /course?department='acc'
+         SELECT "course"."department", "course"."number", "course"."title", "course"."credits", "course"."description" FROM "ad"."course" AS "course" WHERE ("course"."department" = 'acc') ORDER BY 1 ASC, 2 ASC
+    - uri: /course.order(credits)?department='acc'
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | (course.order(credits)?department='acc')                                                      |
+        -+-----------------------------------------------------------------------------------------------+-
+         | department | number | title                      | credits | description                      |
+        -+------------+--------+----------------------------+---------+----------------------------------+-
+         | acc        |    100 | Practical Bookkeeping      |       2 | A introduction to business with  |
+         :            :        :                            :         : practical bookkeeping            :
+         :            :        :                            :         : application.                     :
+         | acc        |    200 | Principles of Accounting I |       3 | The initial course in the theory |
+         :            :        :                            :         : and practice of financial        :
+         :            :        :                            :         : accounting. Topics emphasized    :
+         :            :        :                            :         : include the preparation,         :
+         :            :        :                            :         : reporting, and analysis of       :
+         :            :        :                            :         : financial data.                  :
+         | acc        |    426 | Corporate Taxation         |       3 | Concepts and methods of          |
+         :            :        :                            :         : determining federal tax          :
+         :            :        :                            :         : liability of corporations.       :
+         | acc        |    527 | Advanced Accounting        |       3 | Theory and practical             |
+         :            :        :                            :         : applications of accounting for   :
+         :            :        :                            :         : consolidated entities and        :
+         :            :        :                            :         : partnerships; includes foreign   :
+         :            :        :                            :         : currency transactions, hedging   :
+         :            :        :                            :         : and derivatives.                 :
+         | acc        |    606 | Corporate Financial Law    |       3 | Law governing business           |
+         :            :        :                            :         : corporations; fiduciary duties   :
+         :            :        :                            :         : of managers and directors in     :
+         :            :        :                            :         : situations such as mergers,      :
+         :            :        :                            :         : acquisitions, securities         :
+         :            :        :                            :         : offerings, market domination,    :
+         :            :        :                            :         : litigation.                      :
+         | acc        |    315 | Financial Accounting       |       5 | Integration of the conceptual    |
+         :            :        :                            :         : and computational aspects of     :
+         :            :        :                            :         : asset, liability and             :
+         :            :        :                            :         : stockholders equity accounting.  :
+                                                                                                  (6 rows)
+
+         ----
+         /course.order(credits)?department='acc'
+         SELECT "course"."department", "course"."number", "course"."title", "course"."credits", "course"."description" FROM (SELECT "course"."department", "course"."number", "course"."title", "course"."credits", "course"."description" FROM "ad"."course" AS "course" WHERE ("course"."department" = 'acc') ORDER BY 4 ASC, 1 ASC, 2 ASC) AS "course" ORDER BY 4 ASC, 1 ASC, 2 ASC
+    - uri: /course.order(credits).limit(1,1)?department='acc'
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | (course.order(credits).limit(1,1)?department='acc')                                           |
+        -+-----------------------------------------------------------------------------------------------+-
+         | department | number | title                      | credits | description                      |
+        -+------------+--------+----------------------------+---------+----------------------------------+-
+         | acc        |    200 | Principles of Accounting I |       3 | The initial course in the theory |
+         :            :        :                            :         : and practice of financial        :
+         :            :        :                            :         : accounting. Topics emphasized    :
+         :            :        :                            :         : include the preparation,         :
+         :            :        :                            :         : reporting, and analysis of       :
+         :            :        :                            :         : financial data.                  :
+                                                                                                   (1 row)
+
+         ----
+         /course.order(credits).limit(1,1)?department='acc'
+         SELECT "course"."department", "course"."number", "course"."title", "course"."credits", "course"."description" FROM (SELECT "course"."department", "course"."number", "course"."title", "course"."credits", "course"."description" FROM (SELECT "course"."department", "course"."number", "course"."title", "course"."credits", "course"."description" FROM "ad"."course" AS "course" ORDER BY 4 ASC, 1 ASC, 2 ASC) AS "course" WHERE ("course"."department" = 'acc') ORDER BY 4 ASC, 1 ASC, 2 ASC LIMIT 1 OFFSET 1) AS "course" ORDER BY 4 ASC, 1 ASC, 2 ASC
   - id: simple-filters
     tests:
     - uri: /school?code='ns'