Commits

Kirill Simonov  committed c223a43

Added support for order modifiers: `+` and `-`.

  • Participants
  • Parent commits f686166

Comments (0)

Files changed (4)

File src/htsql/tr/encoder.py

                       ColumnBinding, LiteralBinding, SieveBinding,
                       SortBinding, EqualityBinding, TotalEqualityBinding,
                       ConjunctionBinding, DisjunctionBinding,
-                      NegationBinding, CastBinding, WrapperBinding)
+                      NegationBinding, CastBinding, WrapperBinding,
+                      OrderBinding)
 from .code import (ScalarSpace, CrossProductSpace, JoinProductSpace,
                    FilteredSpace, OrderedSpace,
                    QueryExpression, SegmentExpression, LiteralCode,
         encode = Encode(binding, self)
         return encode.relate()
 
+    def order(self, binding):
+        encode = Encode(binding, self)
+        return encode.order()
+
 
 class Encode(Adapter):
 
         raise InvalidArgumentError("unable to relate a node",
                                    self.binding.mark)
 
+    def order(self):
+        return None
+
 
 class EncodeQuery(Encode):
 
 
     def encode(self):
         space = self.encoder.relate(self.binding.base)
-        space = OrderedSpace(space, [], None, None, self.binding)
         elements = []
+        order = []
         for binding in self.binding.elements:
             element = self.encoder.encode(binding)
+            direction = self.encoder.order(binding)
+            if direction is not None:
+                order.append((element, direction))
             elements.append(element)
+        space = OrderedSpace(space, order, None, None, self.binding)
         return SegmentExpression(space, elements, self.binding)
 
 
         filter = self.encoder.encode(self.binding.filter)
         return FilteredSpace(space, filter, self.binding)
 
+    def order(self):
+        return self.encoder.order(self.binding.base)
+
 
 class EncodeSort(Encode):
 
             return LiteralCode(value, self.binding.domain, self.binding)
         return CastCode(code, self.binding.domain, self.binding)
 
+    def order(self):
+        return self.encoder.order(self.binding.op)
+
 
 class EncodeWrapper(Encode):
 
     def relate(self):
         return self.encoder.relate(self.binding.base)
 
+    def order(self):
+        return self.encoder.order(self.binding.base)
 
+
+class EncodeOrder(Encode):
+
+    adapts(OrderBinding, Encoder)
+
+    def order(self):
+        dir = self.binding.dir
+        base_dir = self.encoder.order(self.binding.base)
+        if base_dir is not None:
+            dir *= base_dir
+        return dir
+
+

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

 from ..binding import (LiteralBinding, SortBinding, FunctionBinding,
                        EqualityBinding, TotalEqualityBinding,
                        ConjunctionBinding, DisjunctionBinding, NegationBinding,
-                       CastBinding, TitleBinding)
+                       CastBinding, TitleBinding, OrderBinding)
 from ..encoder import Encoder, Encode
 from ..code import (FunctionCode, NegationCode, AggregateUnit,
                     CorrelatedUnit, LiteralCode, FilteredSpace)
         yield TitleBinding(base, title, self.syntax)
 
 
+class AscOrderFunction(ProperFunction):
+
+    named('_+')
+
+    parameters = [
+            Parameter('base', is_mandatory=False),
+    ]
+
+    def correlate(self, base):
+        yield OrderBinding(base, +1, self.syntax)
+
+
+class DescOrderFunction(ProperFunction):
+
+    named('_-')
+
+    parameters = [
+            Parameter('base', is_mandatory=False),
+    ]
+
+    def correlate(self, base):
+        yield OrderBinding(base, -1, self.syntax)
+
+
 class LimitMethod(ProperMethod):
 
     named('limit')

File test/input/pgsql.yaml

     - uri: /school{code as school.code}
       expect: 400
 
+  # The order modifiers: `+` and `-`.
+  - title: Order modifiers
+    tests:
+    # Ascending order (default for this table).
+    - uri: /school{code+,name}
+    # Descending order.
+    - uri: /school{code-,name}
+    # Combinations of several order modifiers.
+    - uri: /school{code--,name}
+    # Combined with `as`.
+    - uri: /school{name as Title+}
+    - uri: /school{name+ as Title}
+      expect: 400
+    - uri: /school{(name+) as Title}
+    # Non-unique explicit ordering is complemented with the default ordering.
+    - uri: /course{department+,title,credits-}?number<200
+
   # Simple (non-aggregate) filters.
   - title: Simple filters
     tests:

File test/output/pgsql.yaml

         invalid argument: expected a string literal or an identifier:
             /school{code as school.code}
                             ^^^^^^^^^^^
+  - id: order-modifiers
+    tests:
+    - uri: /school{code+,name}
+      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{code+,name}
+         SELECT "school"."code", "school"."name" FROM "ad"."school" AS "school" ORDER BY 1 ASC
+    - uri: /school{code-,name}
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | school                                   |
+        -+------------------------------------------+-
+         | code- | name                             |
+        -+-------+----------------------------------+-
+         | sc    | School of Continuing Studies     |
+         | ns    | School of Natural Sciences       |
+         | mus   | Musical School                   |
+         | mart  | School of Modern Art             |
+         | la    | School of Arts, Letters, and the |
+         :       : Humanities                       :
+         | egn   | School of Engineering            |
+         | edu   | College of Education             |
+         | bus   | School of Business               |
+         | art   | School of Art and Design         |
+                                             (9 rows)
+
+         ----
+         /school{code-,name}
+         SELECT "school"."code", "school"."name" FROM "ad"."school" AS "school" ORDER BY 1 DESC
+    - uri: /school{code--,name}
+      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{code--,name}
+         SELECT "school"."code", "school"."name" FROM "ad"."school" AS "school" ORDER BY 1 ASC
+    - uri: /school{name as Title+}
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | school                           |
+        -+----------------------------------+-
+         | Title                            |
+        -+----------------------------------+-
+         | College of Education             |
+         | Musical School                   |
+         | School of Art and Design         |
+         | School of Arts, Letters, and the |
+         : Humanities                       :
+         | School of Business               |
+         | School of Continuing Studies     |
+         | School of Engineering            |
+         | School of Modern Art             |
+         | School of Natural Sciences       |
+                                     (9 rows)
+
+         ----
+         /school{name as Title+}
+         SELECT "school"."name" FROM "ad"."school" AS "school" ORDER BY 1 ASC, "school"."code" ASC
+    - uri: /school{name+ as Title}
+      status: 400 Bad Request
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |
+        parse error: expected NAME; got SYMBOL '}':
+            /school{name+ as Title}
+                                  ^
+    - uri: /school{(name+) as Title}
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | school                           |
+        -+----------------------------------+-
+         | Title                            |
+        -+----------------------------------+-
+         | College of Education             |
+         | Musical School                   |
+         | School of Art and Design         |
+         | School of Arts, Letters, and the |
+         : Humanities                       :
+         | School of Business               |
+         | School of Continuing Studies     |
+         | School of Engineering            |
+         | School of Modern Art             |
+         | School of Natural Sciences       |
+                                     (9 rows)
+
+         ----
+         /school{(name+) as Title}
+         SELECT "school"."name" FROM "ad"."school" AS "school" ORDER BY 1 ASC, "school"."code" ASC
+    - uri: /course{department+,title,credits-}?number<200
+      status: 200 OK
+      headers:
+      - [Content-Type, text/plain; charset=UTF-8]
+      body: |2
+         | (course?number<200)                                       |
+        -+-----------------------------------------------------------+-
+         | department+ | title                            | credits- |
+        -+-------------+----------------------------------+----------+-
+         | acc         | Practical Bookkeeping            |        2 |
+         | artstd      | Spring Basket Weaving Workshop   |          |
+         | astro       | The Solar System                 |        3 |
+         | astro       | Solar System Lab                 |        2 |
+         | astro       | Telescope Workshop               |        1 |
+         | be          | Introduction to Biomedical       |        3 |
+         :             : Engineering                      :          :
+         | chem        | Principles of Chemistry          |        3 |
+         | chem        | Organic Chemistry I              |        3 |
+         | chem        | Organic Chemistry Laboratory I   |        2 |
+         | comp        | Introduction to Computer Science |        3 |
+         | ee          | Exploration of Electrical        |        3 |
+         :             : Engineering                      :          :
+         | eng         | Introduction to Composition      |        3 |
+         | eng         | College Newspaper                |        2 |
+         | hist        | The United States in World       |        3 |
+         :             : History                          :          :
+         | me          | Introduction to Mechanical       |        3 |
+         :             : Engineering                      :          :
+         | mth         | College Algebra                  |        5 |
+         | poli        | American Government and Politics |        3 |
+         | psych       | General Psychology               |        3 |
+         | tched       | Theory and Practice of Early     |        3 |
+         :             : Childhood Education              :          :
+         | tched       | Methods of Early Science         |        3 |
+         :             : Education                        :          :
+                                                             (20 rows)
+
+         ----
+         /course{department+,title,credits-}?number<200
+         SELECT "course"."department", "course"."title", "course"."credits" FROM "ad"."course" AS "course" WHERE ("course"."number" < 200) ORDER BY 1 ASC, 3 DESC, 1 ASC, "course"."number" ASC
   - id: simple-filters
     tests:
     - uri: /school?code='ns'