Commits

Kirill Simonov committed b453c41

Added `/:tsv` formatter that generates output in tab-separated format
(Thank to Andrey Popp).

Comments (0)

Files changed (9)

     Alexei Golovko
     Elena Komendantova
     Owen McGettrick
+    Andrey Popp
     Eugenia Rudenko
     Andrey Sukhanov
     Charles H. Tirrell

src/htsql/fmt/__init__.py

 
 from .format import FindRenderer
 from .json import JSONRenderer
-from .spreadsheet import CSVRenderer
+from .spreadsheet import CSVRenderer, TSVRenderer
 from .html import HTMLRenderer
 from .text import TextRenderer
 
 class FindStandardRenderer(FindRenderer):
 
     def get_renderers(self):
-        return ([CSVRenderer, JSONRenderer, HTMLRenderer, TextRenderer]
+        return ([CSVRenderer, TSVRenderer, JSONRenderer,
+                 HTMLRenderer, TextRenderer]
                 + super(FindStandardRenderer, self).get_renderers())
 
 

src/htsql/fmt/spreadsheet.py

 :mod:`htsql.fmt.spreadsheet`
 ============================
 
-This module implements the CSV renderer.
+This module implements the CSV and TSV renderers.
 """
 
 
 
     name = 'text/csv'
     aliases = ['csv']
+    content_type = 'text/csv'
+    extension = 'csv'
+    dialect = 'excel'
 
     def render(self, product):
         status = self.generate_status(product)
     def generate_headers(self, product):
         filename = str(product.profile.segment.syntax)
         filename = filename.replace('\\', '\\\\').replace('"', '\\"')
-        return [('Content-Type', 'text/csv; charset=UTF-8'),
+        return [('Content-Type', '%s; charset=UTF-8' % self.content_type),
                 ('Content-Disposition',
-                 'attachment; filename="(%s).csv"' % filename)]
+                 'attachment; filename="(%s).%s"'
+                 % (filename, self.extension))]
 
     def generate_body(self, product):
         if not product:
         tool = Formatter(self)
         formats = [Format(self, domain, tool) for domain in domains]
         output = cStringIO.StringIO()
-        writer = csv.writer(output)
+        writer = csv.writer(output, dialect=self.dialect)
         writer.writerow(titles)
         yield output.getvalue()
         output.seek(0)
             output.truncate()
 
 
+class TSVRenderer(CSVRenderer):
+
+    name = 'text/tab-separated-values'
+    aliases = ['tsv']
+    content_type = 'text/tab-separated-values'
+    extension = 'tsv'
+    dialect = 'excel-tab'
+
+
 class CSVFormatter(Formatter):
 
     adapts(CSVRenderer)
 
 
+class TSVFormatter(Formatter):
+
+    adapts(TSVRenderer)
+
+
 class FormatDomain(Format):
 
     adapts(CSVRenderer, Domain)

test/regress/input/format.yaml

   tests:
   - uri: /school/:json
   - uri: /school/:csv
+  - uri: /school/:tsv
   - uri: /school/:txt
   - uri: /school/:html
   - uri: /school/:unknown
       Accept: text/csv
   - uri: /school
     headers:
+      Accept: text/tab-separated-values
+  - uri: /school
+    headers:
       Accept: text/plain
   - uri: /school
     headers:
             /:csv
     - uri: /(school :as 'List of Schools')
             {name :as Name, count(department) :as '# of Departments'}
+            /:tsv
+    - uri: /(school :as 'List of Schools')
+            {name :as Name, count(department) :as '# of Departments'}
             /:txt
     - uri: /(school :as 'List of Schools')
             {name :as Name, count(department) :as '# of Departments'}
 
 - title: Data Types
   tests:
-  - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
+  - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL',
+           date('2010-04-15'), time('20:13:04.5'), datetime('2010-04-15 20:13')}
           /:json
-  - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
+  - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL',
+           date('2010-04-15'), time('20:13:04.5'), datetime('2010-04-15 20:13')}
           /:csv
-  - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
+  - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL',
+           date('2010-04-15'), time('20:13:04.5'), datetime('2010-04-15 20:13')}
+          /:tsv
+  - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL',
+           date('2010-04-15'), time('20:13:04.5'), datetime('2010-04-15 20:13')}
           /:txt
-  - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
+  - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL',
+           date('2010-04-15'), time('20:13:04.5'), datetime('2010-04-15 20:13')}
           /:html
 
 - title: No Rows
   tests:
   - uri: /school?false()/:json
   - uri: /school?false()/:csv
+  - uri: /school?false()/:tsv
   - uri: /school?false()/:txt
   - uri: /school?false()/:html
 
+- title: Special Characters
+  tests:
+  - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10',
+           '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+           '%CE%BE', '\/%25''"&<>#', ''}/:json
+  - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10',
+           '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+           '%CE%BE', '\/%25''"&<>#', ''}/:csv
+  - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10',
+           '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+           '%CE%BE', '\/%25''"&<>#', ''}/:tsv
+  - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10',
+           '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+           '%CE%BE', '\/%25''"&<>#', ''}/:txt
+  - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10',
+           '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+           '%CE%BE', '\/%25''"&<>#', ''}/:html
+

test/regress/output/mssql.yaml

             of Arts and Humanities,old\r\nmus,School of Music & Dance,south\r\nns,School
             of Natural Sciences,old\r\nph,Public Honorariums,\r\nsc,School of Continuing
             Studies,\r\n"
+        - uri: /school/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
         - uri: /school/:txt
           status: 200 OK
           headers:
         - uri: /school
           status: 200 OK
           headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
+        - uri: /school
+          status: 200 OK
+          headers:
           - [Content-Type, text/plain; charset=UTF-8]
           body: |2
              | school                                        |
             of Arts and Humanities,5\r\nSchool of Music & Dance,4\r\nSchool of Natural
             Sciences,4\r\nPublic Honorariums,0\r\nSchool of Continuing Studies,0\r\n"
         - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
+            '# of Departments'} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="((school:as(''List of Schools'')){name:as(Name),count(department):as(''#
+              of Departments'')}).tsv"']
+          body: "Name\t# of Departments\r\nSchool of Art and Design\t2\r\nSchool of
+            Business\t3\r\nCollege of Education\t2\r\nSchool of Engineering\t4\r\nSchool
+            of Arts and Humanities\t5\r\nSchool of Music & Dance\t4\r\nSchool of Natural
+            Sciences\t4\r\nPublic Honorariums\t0\r\nSchool of Continuing Studies\t0\r\n"
+        - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
             '# of Departments'} /:txt
           status: 200 OK
           headers:
             </html>
       - id: data-types
         tests:
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:json
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:json
           status: 200 OK
           headers:
           - [Content-Type, application/javascript]
-          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).js"']
+          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).js"']
           body: |
             {
               "meta": [
                 {"title": "2.125", "domain": "number"},
                 {"title": "271828e-5", "domain": "number"},
                 {"title": "'HTSQL'", "domain": "string"},
-                {"title": "'2010-04-15'", "domain": "date"}
+                {"title": "'2010-04-15'", "domain": "date"},
+                {"title": "'20:13:04.5'", "domain": "time"},
+                {"title": "'2010-04-15 20:13'", "domain": "datetime"}
               ],
               "data": [
-                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15"]
+                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15", "20:13:04.500000", "2010-04-15 20:13:00"]
               ]
             }
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:csv
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:csv
           status: 200 OK
           headers:
           - [Content-Type, text/csv; charset=UTF-8]
-          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).csv"']
-          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15\r\n"
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:txt
-          status: 200 OK
-          headers:
-          - [Content-Type, text/plain; charset=UTF-8]
-          body: |2
-             |                                                                             |
-            -+-----------------------------------------------------------------------------+-
-             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' |
-            -+--------+--------+---------+----+-------+-----------+---------+--------------+-
-             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   |
-                                                                                     (1 row)
-
-             ----
-             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:txt
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).csv"']
+          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15','20:13:04.5','2010-04-15
+            20:13'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15,20:13:04.500000,2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).tsv"']
+          body: "null()\ttrue()\tfalse()\t60\t2.125\t271828e-5\t'HTSQL'\t'2010-04-15'\t'20:13:04.5'\t'2010-04-15
+            20:13'\r\n\ttrue\tfalse\t60\t2.125\t2.71828\tHTSQL\t2010-04-15\t20:13:04.500000\t2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                                                                                     |
+            -+---------------------------------------------------------------------------------------------------------------------+-
+             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' | '20:13:04.5'    | '2010-04-15 20:13'  |
+            -+--------+--------+---------+----+-------+-----------+---------+--------------+-----------------+---------------------+-
+             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   | 20:13:04.500000 | 2010-04-15 20:13:00 |
+                                                                                                                             (1 row)
+
+             ----
+             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:txt
              SELECT NULL,
                     1,
                     0,
                     2.125,
                     2.71828e0,
                     'HTSQL',
-                    CAST('2010-04-15' AS DATETIME)
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:html
+                    CAST('2010-04-15' AS DATETIME),
+                    0.8424131944444444e0,
+                    CAST('2010-04-15 20:13:00' AS DATETIME)
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:html
           status: 200 OK
           headers:
           - [Content-Type, text/html; charset=UTF-8]
             <html>
             <head>
             <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</title>
+            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</title>
             <style type="text/css">
             body { font-family: sans-serif; font-size: 90%; color: #515151; background: #ffffff }
             a:link, a:visited { color: #1f4884; text-decoration: none }
             </style>
             </head>
             <body>
-            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html">
+            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html">
             <tr>
             <td class="content">
             <table class="chart" summary="">
-            <tr class="caption"><th colspan="8"><div class="tab"></div></th></tr>
-            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th></tr>
-            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td></tr>
-            <tr class="total"><td colspan="8">(1 row)</td></tr></table></td>
+            <tr class="caption"><th colspan="10"><div class="tab"></div></th></tr>
+            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th><th>'20:13:04.5'</th><th>'2010-04-15 20:13'</th></tr>
+            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td><td>20:13:04.500000</td><td>2010-04-15 20:13:00</td></tr>
+            <tr class="total"><td colspan="10">(1 row)</td></tr></table></td>
             </tr>
-            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</td></tr>
+            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</td></tr>
             </table>
             </body>
             </html>
           - [Content-Type, text/csv; charset=UTF-8]
           - [Content-Disposition, 'attachment; filename="(school?false()).csv"']
           body: "code,name,campus\r\n"
+        - uri: /school?false()/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="(school?false()).tsv"']
+          body: "code\tname\tcampus\r\n"
         - uri: /school?false()/:txt
           status: 200 OK
           headers:
             </table>
             </body>
             </html>
+      - id: special-characters
+        tests:
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:json
+          status: 200 OK
+          headers:
+          - [Content-Type, application/javascript]
+          - [Content-Disposition, "inline; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).js\""]
+          body: "{\n  \"meta\": [\n    {\"title\": \"'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'\u03BE'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"'\\\\\\/%25''\\\"&<>#'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"''\", \"domain\": \"string\"}\n  ],\n  \"data\": [\n
+            \   [\"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F\\u0010\",
+            \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F\x7F\",
+            \"?\", \"\\\\\\/%'\\\"&<>#\", \"\"]\n  ]\n}\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:csv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/csv; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).csv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE',\"'\\/%25''\"\"&<>#'\",''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\",\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F,?,\"\\/%'\"\"&<>#\",\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).tsv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\t'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\t'\u03BE'\t\"'\\/%25''\"\"&<>#'\"\t''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\"\t\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F\t?\t\"\\/%'\"\"&<>#\"\t\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: " |                                                                                                                                                                                                            |\n-+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-\n
+            | '%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'                             |
+            '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'                                            |
+            '\u03BE' | '\\/%25''\"&<>#' | '' |\n-+--------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+-----+----------------+----+-\n
+            | \"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u0010\"
+            | \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\x7F\"
+            | ?   | \\/%'\"&<>#      | \"\" |\n                                                                                                                                                                                                        (1
+            row)\n\n ----\n /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&<>#',''}/:txt\n
+            SELECT '\x01\x02\x03\x04\x05\x06\a\b\t\n \v\f\n \x0E\x0F\x10',\n        '\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F',\n
+            \       '\u03BE',\n        '\\/%''\"&<>#',\n        ''\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:html
+          status: 200 OK
+          headers:
+          - [Content-Type, text/html; charset=UTF-8]
+          body: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
+            \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\"
+            content=\"text/html; charset=UTF-8\">\n<title>/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</title>\n<style
+            type=\"text/css\">\nbody { font-family: sans-serif; font-size: 90%; color:
+            #515151; background: #ffffff }\na:link, a:visited { color: #1f4884; text-decoration:
+            none }\na:hover { text-decoration: underline }\ntable { border-collapse:
+            collapse; margin: 0.5em auto; width: 100% }\ntable, tr { border-style:
+            solid; border-width: 0 }\ntd, th { padding: 0.2em 0.5em; vertical-align:
+            top; text-align: left }\ndiv.tab { position: relative; left: -1px; margin-right:
+            60%; padding: 0.2em 0.5em; background: #ffffff; border-style: solid; border-width:
+            5px 1px 0; border-top-left-radius: 10px; border-top-right-radius: 10px;
+            -moz-border-radius-topleft: 10px; -moz-border-radius-topright: 10px; -webkit-border-top-left-radius:
+            10px; -webkit-border-top-right-radius: 10px }\ntable.page { border: 0;
+            padding: 1em; width: auto }\ntr.content { padding: 1em 1em 0.5em }\ntr.footer
+            { padding: 0 1em 1em; text-align: left; font-style: italic }\ntable.chart
+            .number { text-align: right }\ntr.caption { font-size: 105%; background:
+            transparent }\ntr.caption th { padding: 0 }\ndiv.tab { border-color: #6f9ad3
+            #c3c3c3 }\ntr.header { background: #dae3ea; border-color: #c3c3c3; border-width:
+            1px 1px 0 }\ntr.odd { background: #ffffff; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.even { background: #f2f2f2; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.odd:hover, tr.even:hover { background: #ffe3bd }\ntr.total
+            { background: transparent;border-color: #c3c3c3; border-width: 1px 0 0
+            }\ntr.total td { text-align: right; font-size: 75%; font-style: italic;
+            padding: 0.3em 0.5em 0 }\ntable.void { text-align: center; border-color:
+            #c3c3c3; border-width: 1px 0 }\n</style>\n</head>\n<body>\n<table class=\"page\"
+            summary=\"/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''&quot;&amp;&lt;&gt;#',''}/:html\">\n<tr>\n<td
+            class=\"content\">\n<table class=\"chart\" summary=\"\">\n<tr class=\"caption\"><th
+            colspan=\"5\"><div class=\"tab\"></div></th></tr>\n<tr class=\"header\"><th>'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'</th><th>'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'</th><th>'\u03BE'</th><th>'\\/%25''\"&amp;&lt;&gt;#'</th><th>''</th></tr>\n<tr
+            class=\"odd\"><td>\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10</td><td>\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F</td><td>?</td><td>\\/%'\"&amp;&lt;&gt;#</td><td>&nbsp;</td></tr>\n<tr
+            class=\"total\"><td colspan=\"5\">(1 row)</td></tr></table></td>\n</tr>\n<tr><td
+            class=\"footer\">/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</td></tr>\n</table>\n</body>\n</html>\n"

test/regress/output/mysql.yaml

             of Arts and Humanities,old\r\nmus,School of Music & Dance,south\r\nns,School
             of Natural Sciences,old\r\nph,Public Honorariums,\r\nsc,School of Continuing
             Studies,\r\n"
+        - uri: /school/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
         - uri: /school/:txt
           status: 200 OK
           headers:
         - uri: /school
           status: 200 OK
           headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
+        - uri: /school
+          status: 200 OK
+          headers:
           - [Content-Type, text/plain; charset=UTF-8]
           body: |2
              | school                                        |
             of Arts and Humanities,5\r\nSchool of Music & Dance,4\r\nSchool of Natural
             Sciences,4\r\nPublic Honorariums,0\r\nSchool of Continuing Studies,0\r\n"
         - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
+            '# of Departments'} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="((school:as(''List of Schools'')){name:as(Name),count(department):as(''#
+              of Departments'')}).tsv"']
+          body: "Name\t# of Departments\r\nSchool of Art and Design\t2\r\nSchool of
+            Business\t3\r\nCollege of Education\t2\r\nSchool of Engineering\t4\r\nSchool
+            of Arts and Humanities\t5\r\nSchool of Music & Dance\t4\r\nSchool of Natural
+            Sciences\t4\r\nPublic Honorariums\t0\r\nSchool of Continuing Studies\t0\r\n"
+        - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
             '# of Departments'} /:txt
           status: 200 OK
           headers:
             </html>
       - id: data-types
         tests:
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:json
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:json
           status: 200 OK
           headers:
           - [Content-Type, application/javascript]
-          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).js"']
+          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).js"']
           body: |
             {
               "meta": [
                 {"title": "2.125", "domain": "number"},
                 {"title": "271828e-5", "domain": "number"},
                 {"title": "'HTSQL'", "domain": "string"},
-                {"title": "'2010-04-15'", "domain": "date"}
+                {"title": "'2010-04-15'", "domain": "date"},
+                {"title": "'20:13:04.5'", "domain": "time"},
+                {"title": "'2010-04-15 20:13'", "domain": "datetime"}
               ],
               "data": [
-                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15"]
+                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15", "20:13:04.500000", "2010-04-15 20:13:00"]
               ]
             }
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:csv
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:csv
           status: 200 OK
           headers:
           - [Content-Type, text/csv; charset=UTF-8]
-          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).csv"']
-          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15\r\n"
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:txt
-          status: 200 OK
-          headers:
-          - [Content-Type, text/plain; charset=UTF-8]
-          body: |2
-             |                                                                             |
-            -+-----------------------------------------------------------------------------+-
-             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' |
-            -+--------+--------+---------+----+-------+-----------+---------+--------------+-
-             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   |
-                                                                                     (1 row)
-
-             ----
-             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:txt
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).csv"']
+          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15','20:13:04.5','2010-04-15
+            20:13'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15,20:13:04.500000,2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).tsv"']
+          body: "null()\ttrue()\tfalse()\t60\t2.125\t271828e-5\t'HTSQL'\t'2010-04-15'\t'20:13:04.5'\t'2010-04-15
+            20:13'\r\n\ttrue\tfalse\t60\t2.125\t2.71828\tHTSQL\t2010-04-15\t20:13:04.500000\t2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                                                                                     |
+            -+---------------------------------------------------------------------------------------------------------------------+-
+             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' | '20:13:04.5'    | '2010-04-15 20:13'  |
+            -+--------+--------+---------+----+-------+-----------+---------+--------------+-----------------+---------------------+-
+             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   | 20:13:04.500000 | 2010-04-15 20:13:00 |
+                                                                                                                             (1 row)
+
+             ----
+             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:txt
              SELECT NULL,
                     TRUE,
                     FALSE,
                     2.125,
                     2.71828e0,
                     'HTSQL',
-                    DATE('2010-04-15')
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:html
+                    DATE('2010-04-15'),
+                    TIME('20:13:04.500000'),
+                    TIMESTAMP('2010-04-15 20:13:00')
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:html
           status: 200 OK
           headers:
           - [Content-Type, text/html; charset=UTF-8]
             <html>
             <head>
             <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</title>
+            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</title>
             <style type="text/css">
             body { font-family: sans-serif; font-size: 90%; color: #515151; background: #ffffff }
             a:link, a:visited { color: #1f4884; text-decoration: none }
             </style>
             </head>
             <body>
-            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html">
+            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html">
             <tr>
             <td class="content">
             <table class="chart" summary="">
-            <tr class="caption"><th colspan="8"><div class="tab"></div></th></tr>
-            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th></tr>
-            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td></tr>
-            <tr class="total"><td colspan="8">(1 row)</td></tr></table></td>
+            <tr class="caption"><th colspan="10"><div class="tab"></div></th></tr>
+            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th><th>'20:13:04.5'</th><th>'2010-04-15 20:13'</th></tr>
+            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td><td>20:13:04.500000</td><td>2010-04-15 20:13:00</td></tr>
+            <tr class="total"><td colspan="10">(1 row)</td></tr></table></td>
             </tr>
-            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</td></tr>
+            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</td></tr>
             </table>
             </body>
             </html>
           - [Content-Type, text/csv; charset=UTF-8]
           - [Content-Disposition, 'attachment; filename="(school?false()).csv"']
           body: "code,name,campus\r\n"
+        - uri: /school?false()/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="(school?false()).tsv"']
+          body: "code\tname\tcampus\r\n"
         - uri: /school?false()/:txt
           status: 200 OK
           headers:
             </table>
             </body>
             </html>
+      - id: special-characters
+        tests:
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:json
+          status: 200 OK
+          headers:
+          - [Content-Type, application/javascript]
+          - [Content-Disposition, "inline; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).js\""]
+          body: "{\n  \"meta\": [\n    {\"title\": \"'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'\u03BE'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"'\\\\\\/%25''\\\"&<>#'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"''\", \"domain\": \"string\"}\n  ],\n  \"data\": [\n
+            \   [\"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F\\u0010\",
+            \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F\x7F\",
+            \"\u03BE\", \"\\\\\\/%'\\\"&<>#\", \"\"]\n  ]\n}\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:csv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/csv; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).csv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE',\"'\\/%25''\"\"&<>#'\",''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\",\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F,\u03BE,\"\\/%'\"\"&<>#\",\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).tsv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\t'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\t'\u03BE'\t\"'\\/%25''\"\"&<>#'\"\t''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\"\t\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F\t\u03BE\t\"\\/%'\"\"&<>#\"\t\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: " |                                                                                                                                                                                                            |\n-+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-\n
+            | '%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'                             |
+            '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'                                            |
+            '\u03BE' | '\\/%25''\"&<>#' | '' |\n-+--------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+-----+----------------+----+-\n
+            | \"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u0010\"
+            | \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\x7F\"
+            | \u03BE   | \\/%'\"&<>#      | \"\" |\n                                                                                                                                                                                                        (1
+            row)\n\n ----\n /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&<>#',''}/:txt\n
+            SELECT '\x01\x02\x03\x04\x05\x06\a\b\t\\n\v\f\\r\x0E\x0F\x10',\n        '\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F',\n
+            \       '\u03BE',\n        '\\\\/%\\'\"&<>#',\n        ''\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:html
+          status: 200 OK
+          headers:
+          - [Content-Type, text/html; charset=UTF-8]
+          body: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
+            \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\"
+            content=\"text/html; charset=UTF-8\">\n<title>/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</title>\n<style
+            type=\"text/css\">\nbody { font-family: sans-serif; font-size: 90%; color:
+            #515151; background: #ffffff }\na:link, a:visited { color: #1f4884; text-decoration:
+            none }\na:hover { text-decoration: underline }\ntable { border-collapse:
+            collapse; margin: 0.5em auto; width: 100% }\ntable, tr { border-style:
+            solid; border-width: 0 }\ntd, th { padding: 0.2em 0.5em; vertical-align:
+            top; text-align: left }\ndiv.tab { position: relative; left: -1px; margin-right:
+            60%; padding: 0.2em 0.5em; background: #ffffff; border-style: solid; border-width:
+            5px 1px 0; border-top-left-radius: 10px; border-top-right-radius: 10px;
+            -moz-border-radius-topleft: 10px; -moz-border-radius-topright: 10px; -webkit-border-top-left-radius:
+            10px; -webkit-border-top-right-radius: 10px }\ntable.page { border: 0;
+            padding: 1em; width: auto }\ntr.content { padding: 1em 1em 0.5em }\ntr.footer
+            { padding: 0 1em 1em; text-align: left; font-style: italic }\ntable.chart
+            .number { text-align: right }\ntr.caption { font-size: 105%; background:
+            transparent }\ntr.caption th { padding: 0 }\ndiv.tab { border-color: #6f9ad3
+            #c3c3c3 }\ntr.header { background: #dae3ea; border-color: #c3c3c3; border-width:
+            1px 1px 0 }\ntr.odd { background: #ffffff; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.even { background: #f2f2f2; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.odd:hover, tr.even:hover { background: #ffe3bd }\ntr.total
+            { background: transparent;border-color: #c3c3c3; border-width: 1px 0 0
+            }\ntr.total td { text-align: right; font-size: 75%; font-style: italic;
+            padding: 0.3em 0.5em 0 }\ntable.void { text-align: center; border-color:
+            #c3c3c3; border-width: 1px 0 }\n</style>\n</head>\n<body>\n<table class=\"page\"
+            summary=\"/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''&quot;&amp;&lt;&gt;#',''}/:html\">\n<tr>\n<td
+            class=\"content\">\n<table class=\"chart\" summary=\"\">\n<tr class=\"caption\"><th
+            colspan=\"5\"><div class=\"tab\"></div></th></tr>\n<tr class=\"header\"><th>'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'</th><th>'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'</th><th>'\u03BE'</th><th>'\\/%25''\"&amp;&lt;&gt;#'</th><th>''</th></tr>\n<tr
+            class=\"odd\"><td>\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10</td><td>\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F</td><td>\u03BE</td><td>\\/%'\"&amp;&lt;&gt;#</td><td>&nbsp;</td></tr>\n<tr
+            class=\"total\"><td colspan=\"5\">(1 row)</td></tr></table></td>\n</tr>\n<tr><td
+            class=\"footer\">/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</td></tr>\n</table>\n</body>\n</html>\n"

test/regress/output/oracle.yaml

             of Arts and Humanities,old\r\nmus,School of Music & Dance,south\r\nns,School
             of Natural Sciences,old\r\nph,Public Honorariums,\r\nsc,School of Continuing
             Studies,\r\n"
+        - uri: /school/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
         - uri: /school/:txt
           status: 200 OK
           headers:
         - uri: /school
           status: 200 OK
           headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
+        - uri: /school
+          status: 200 OK
+          headers:
           - [Content-Type, text/plain; charset=UTF-8]
           body: |2
              | school                                        |
             of Arts and Humanities,5\r\nSchool of Music & Dance,4\r\nSchool of Natural
             Sciences,4\r\nPublic Honorariums,0\r\nSchool of Continuing Studies,0\r\n"
         - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
+            '# of Departments'} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="((school:as(''List of Schools'')){name:as(Name),count(department):as(''#
+              of Departments'')}).tsv"']
+          body: "Name\t# of Departments\r\nSchool of Art and Design\t2\r\nSchool of
+            Business\t3\r\nCollege of Education\t2\r\nSchool of Engineering\t4\r\nSchool
+            of Arts and Humanities\t5\r\nSchool of Music & Dance\t4\r\nSchool of Natural
+            Sciences\t4\r\nPublic Honorariums\t0\r\nSchool of Continuing Studies\t0\r\n"
+        - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
             '# of Departments'} /:txt
           status: 200 OK
           headers:
             </html>
       - id: data-types
         tests:
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:json
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:json
           status: 200 OK
           headers:
           - [Content-Type, application/javascript]
-          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).js"']
+          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).js"']
           body: |
             {
               "meta": [
                 {"title": "2.125", "domain": "number"},
                 {"title": "271828e-5", "domain": "number"},
                 {"title": "'HTSQL'", "domain": "string"},
-                {"title": "'2010-04-15'", "domain": "date"}
+                {"title": "'2010-04-15'", "domain": "date"},
+                {"title": "'20:13:04.5'", "domain": "time"},
+                {"title": "'2010-04-15 20:13'", "domain": "datetime"}
               ],
               "data": [
-                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15"]
+                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15", "20:13:04.500000", "2010-04-15 20:13:00"]
               ]
             }
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:csv
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:csv
           status: 200 OK
           headers:
           - [Content-Type, text/csv; charset=UTF-8]
-          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).csv"']
-          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15\r\n"
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:txt
-          status: 200 OK
-          headers:
-          - [Content-Type, text/plain; charset=UTF-8]
-          body: |2
-             |                                                                             |
-            -+-----------------------------------------------------------------------------+-
-             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' |
-            -+--------+--------+---------+----+-------+-----------+---------+--------------+-
-             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   |
-                                                                                     (1 row)
-
-             ----
-             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:txt
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).csv"']
+          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15','20:13:04.5','2010-04-15
+            20:13'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15,20:13:04.500000,2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).tsv"']
+          body: "null()\ttrue()\tfalse()\t60\t2.125\t271828e-5\t'HTSQL'\t'2010-04-15'\t'20:13:04.5'\t'2010-04-15
+            20:13'\r\n\ttrue\tfalse\t60\t2.125\t2.71828\tHTSQL\t2010-04-15\t20:13:04.500000\t2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                                                                                     |
+            -+---------------------------------------------------------------------------------------------------------------------+-
+             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' | '20:13:04.5'    | '2010-04-15 20:13'  |
+            -+--------+--------+---------+----+-------+-----------+---------+--------------+-----------------+---------------------+-
+             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   | 20:13:04.500000 | 2010-04-15 20:13:00 |
+                                                                                                                             (1 row)
+
+             ----
+             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:txt
              SELECT NULL,
                     1,
                     0,
                     2.125,
                     2.71828D,
                     'HTSQL',
-                    DATE '2010-04-15'
-             FROM DUAL "!"
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:html
+                    DATE '2010-04-15',
+                    INTERVAL '20:13:04.500000' HOUR TO SECOND,
+                    TIMESTAMP '2010-04-15 20:13:00'
+             FROM DUAL "!"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:html
           status: 200 OK
           headers:
           - [Content-Type, text/html; charset=UTF-8]
             <html>
             <head>
             <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</title>
+            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</title>
             <style type="text/css">
             body { font-family: sans-serif; font-size: 90%; color: #515151; background: #ffffff }
             a:link, a:visited { color: #1f4884; text-decoration: none }
             </style>
             </head>
             <body>
-            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html">
+            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html">
             <tr>
             <td class="content">
             <table class="chart" summary="">
-            <tr class="caption"><th colspan="8"><div class="tab"></div></th></tr>
-            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th></tr>
-            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td></tr>
-            <tr class="total"><td colspan="8">(1 row)</td></tr></table></td>
+            <tr class="caption"><th colspan="10"><div class="tab"></div></th></tr>
+            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th><th>'20:13:04.5'</th><th>'2010-04-15 20:13'</th></tr>
+            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td><td>20:13:04.500000</td><td>2010-04-15 20:13:00</td></tr>
+            <tr class="total"><td colspan="10">(1 row)</td></tr></table></td>
             </tr>
-            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</td></tr>
+            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</td></tr>
             </table>
             </body>
             </html>
           - [Content-Type, text/csv; charset=UTF-8]
           - [Content-Disposition, 'attachment; filename="(school?false()).csv"']
           body: "code,name,campus\r\n"
+        - uri: /school?false()/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="(school?false()).tsv"']
+          body: "code\tname\tcampus\r\n"
         - uri: /school?false()/:txt
           status: 200 OK
           headers:
             </table>
             </body>
             </html>
+      - id: special-characters
+        tests:
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:json
+          status: 200 OK
+          headers:
+          - [Content-Type, application/javascript]
+          - [Content-Disposition, "inline; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).js\""]
+          body: "{\n  \"meta\": [\n    {\"title\": \"'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'\u03BE'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"'\\\\\\/%25''\\\"&<>#'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"''\", \"domain\": \"string\"}\n  ],\n  \"data\": [\n
+            \   [\"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F\\u0010\",
+            \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F\x7F\",
+            \"\u03BE\", \"\\\\\\/%'\\\"&<>#\", null]\n  ]\n}\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:csv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/csv; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).csv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE',\"'\\/%25''\"\"&<>#'\",''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\",\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F,\u03BE,\"\\/%'\"\"&<>#\",\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).tsv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\t'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\t'\u03BE'\t\"'\\/%25''\"\"&<>#'\"\t''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\"\t\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F\t\u03BE\t\"\\/%'\"\"&<>#\"\t\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: " |                                                                                                                                                                                                            |\n-+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-\n
+            | '%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'                             |
+            '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'                                            |
+            '\u03BE' | '\\/%25''\"&<>#' | '' |\n-+--------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+-----+----------------+----+-\n
+            | \"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u0010\"
+            | \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\x7F\"
+            | \u03BE   | \\/%'\"&<>#      |    |\n                                                                                                                                                                                                        (1
+            row)\n\n ----\n /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&<>#',''}/:txt\n
+            SELECT '\x01\x02\x03\x04\x05\x06\a\b\t\n \v\f\n \x0E\x0F\x10',\n        '\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F',\n
+            \       '\u03BE',\n        '\\/%''\"&<>#',\n        NULL\n FROM DUAL \"!\"\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:html
+          status: 200 OK
+          headers:
+          - [Content-Type, text/html; charset=UTF-8]
+          body: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
+            \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\"
+            content=\"text/html; charset=UTF-8\">\n<title>/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</title>\n<style
+            type=\"text/css\">\nbody { font-family: sans-serif; font-size: 90%; color:
+            #515151; background: #ffffff }\na:link, a:visited { color: #1f4884; text-decoration:
+            none }\na:hover { text-decoration: underline }\ntable { border-collapse:
+            collapse; margin: 0.5em auto; width: 100% }\ntable, tr { border-style:
+            solid; border-width: 0 }\ntd, th { padding: 0.2em 0.5em; vertical-align:
+            top; text-align: left }\ndiv.tab { position: relative; left: -1px; margin-right:
+            60%; padding: 0.2em 0.5em; background: #ffffff; border-style: solid; border-width:
+            5px 1px 0; border-top-left-radius: 10px; border-top-right-radius: 10px;
+            -moz-border-radius-topleft: 10px; -moz-border-radius-topright: 10px; -webkit-border-top-left-radius:
+            10px; -webkit-border-top-right-radius: 10px }\ntable.page { border: 0;
+            padding: 1em; width: auto }\ntr.content { padding: 1em 1em 0.5em }\ntr.footer
+            { padding: 0 1em 1em; text-align: left; font-style: italic }\ntable.chart
+            .number { text-align: right }\ntr.caption { font-size: 105%; background:
+            transparent }\ntr.caption th { padding: 0 }\ndiv.tab { border-color: #6f9ad3
+            #c3c3c3 }\ntr.header { background: #dae3ea; border-color: #c3c3c3; border-width:
+            1px 1px 0 }\ntr.odd { background: #ffffff; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.even { background: #f2f2f2; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.odd:hover, tr.even:hover { background: #ffe3bd }\ntr.total
+            { background: transparent;border-color: #c3c3c3; border-width: 1px 0 0
+            }\ntr.total td { text-align: right; font-size: 75%; font-style: italic;
+            padding: 0.3em 0.5em 0 }\ntable.void { text-align: center; border-color:
+            #c3c3c3; border-width: 1px 0 }\n</style>\n</head>\n<body>\n<table class=\"page\"
+            summary=\"/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''&quot;&amp;&lt;&gt;#',''}/:html\">\n<tr>\n<td
+            class=\"content\">\n<table class=\"chart\" summary=\"\">\n<tr class=\"caption\"><th
+            colspan=\"5\"><div class=\"tab\"></div></th></tr>\n<tr class=\"header\"><th>'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'</th><th>'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'</th><th>'\u03BE'</th><th>'\\/%25''\"&amp;&lt;&gt;#'</th><th>''</th></tr>\n<tr
+            class=\"odd\"><td>\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10</td><td>\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F</td><td>\u03BE</td><td>\\/%'\"&amp;&lt;&gt;#</td><td><em>&mdash;</em></td></tr>\n<tr
+            class=\"total\"><td colspan=\"5\">(1 row)</td></tr></table></td>\n</tr>\n<tr><td
+            class=\"footer\">/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</td></tr>\n</table>\n</body>\n</html>\n"

test/regress/output/pgsql.yaml

             of Arts and Humanities,old\r\nmus,School of Music & Dance,south\r\nns,School
             of Natural Sciences,old\r\nph,Public Honorariums,\r\nsc,School of Continuing
             Studies,\r\n"
+        - uri: /school/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
         - uri: /school/:txt
           status: 200 OK
           headers:
         - uri: /school
           status: 200 OK
           headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
+        - uri: /school
+          status: 200 OK
+          headers:
           - [Content-Type, text/plain; charset=UTF-8]
           body: |2
              | school                                        |
             of Arts and Humanities,5\r\nSchool of Music & Dance,4\r\nSchool of Natural
             Sciences,4\r\nPublic Honorariums,0\r\nSchool of Continuing Studies,0\r\n"
         - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
+            '# of Departments'} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="((school:as(''List of Schools'')){name:as(Name),count(department):as(''#
+              of Departments'')}).tsv"']
+          body: "Name\t# of Departments\r\nSchool of Art and Design\t2\r\nSchool of
+            Business\t3\r\nCollege of Education\t2\r\nSchool of Engineering\t4\r\nSchool
+            of Arts and Humanities\t5\r\nSchool of Music & Dance\t4\r\nSchool of Natural
+            Sciences\t4\r\nPublic Honorariums\t0\r\nSchool of Continuing Studies\t0\r\n"
+        - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
             '# of Departments'} /:txt
           status: 200 OK
           headers:
             </html>
       - id: data-types
         tests:
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:json
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:json
           status: 200 OK
           headers:
           - [Content-Type, application/javascript]
-          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).js"']
+          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).js"']
           body: |
             {
               "meta": [
                 {"title": "2.125", "domain": "number"},
                 {"title": "271828e-5", "domain": "number"},
                 {"title": "'HTSQL'", "domain": "string"},
-                {"title": "'2010-04-15'", "domain": "date"}
+                {"title": "'2010-04-15'", "domain": "date"},
+                {"title": "'20:13:04.5'", "domain": "time"},
+                {"title": "'2010-04-15 20:13'", "domain": "datetime"}
               ],
               "data": [
-                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15"]
+                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15", "20:13:04.500000", "2010-04-15 20:13:00"]
               ]
             }
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:csv
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:csv
           status: 200 OK
           headers:
           - [Content-Type, text/csv; charset=UTF-8]
-          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).csv"']
-          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15\r\n"
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:txt
-          status: 200 OK
-          headers:
-          - [Content-Type, text/plain; charset=UTF-8]
-          body: |2
-             |                                                                             |
-            -+-----------------------------------------------------------------------------+-
-             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' |
-            -+--------+--------+---------+----+-------+-----------+---------+--------------+-
-             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   |
-                                                                                     (1 row)
-
-             ----
-             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:txt
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).csv"']
+          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15','20:13:04.5','2010-04-15
+            20:13'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15,20:13:04.500000,2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).tsv"']
+          body: "null()\ttrue()\tfalse()\t60\t2.125\t271828e-5\t'HTSQL'\t'2010-04-15'\t'20:13:04.5'\t'2010-04-15
+            20:13'\r\n\ttrue\tfalse\t60\t2.125\t2.71828\tHTSQL\t2010-04-15\t20:13:04.500000\t2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                                                                                     |
+            -+---------------------------------------------------------------------------------------------------------------------+-
+             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' | '20:13:04.5'    | '2010-04-15 20:13'  |
+            -+--------+--------+---------+----+-------+-----------+---------+--------------+-----------------+---------------------+-
+             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   | 20:13:04.500000 | 2010-04-15 20:13:00 |
+                                                                                                                             (1 row)
+
+             ----
+             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:txt
              SELECT NULL,
                     TRUE,
                     FALSE,
                     2.125::NUMERIC,
                     2.71828::FLOAT8,
                     'HTSQL',
-                    '2010-04-15'::DATE
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:html
+                    '2010-04-15'::DATE,
+                    '20:13:04.500000'::TIME,
+                    '2010-04-15 20:13:00'::TIMESTAMP
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:html
           status: 200 OK
           headers:
           - [Content-Type, text/html; charset=UTF-8]
             <html>
             <head>
             <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</title>
+            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</title>
             <style type="text/css">
             body { font-family: sans-serif; font-size: 90%; color: #515151; background: #ffffff }
             a:link, a:visited { color: #1f4884; text-decoration: none }
             </style>
             </head>
             <body>
-            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html">
+            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html">
             <tr>
             <td class="content">
             <table class="chart" summary="">
-            <tr class="caption"><th colspan="8"><div class="tab"></div></th></tr>
-            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th></tr>
-            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td></tr>
-            <tr class="total"><td colspan="8">(1 row)</td></tr></table></td>
+            <tr class="caption"><th colspan="10"><div class="tab"></div></th></tr>
+            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th><th>'20:13:04.5'</th><th>'2010-04-15 20:13'</th></tr>
+            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td><td>20:13:04.500000</td><td>2010-04-15 20:13:00</td></tr>
+            <tr class="total"><td colspan="10">(1 row)</td></tr></table></td>
             </tr>
-            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</td></tr>
+            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</td></tr>
             </table>
             </body>
             </html>
           - [Content-Type, text/csv; charset=UTF-8]
           - [Content-Disposition, 'attachment; filename="(school?false()).csv"']
           body: "code,name,campus\r\n"
+        - uri: /school?false()/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="(school?false()).tsv"']
+          body: "code\tname\tcampus\r\n"
         - uri: /school?false()/:txt
           status: 200 OK
           headers:
             </table>
             </body>
             </html>
+      - id: special-characters
+        tests:
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:json
+          status: 200 OK
+          headers:
+          - [Content-Type, application/javascript]
+          - [Content-Disposition, "inline; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).js\""]
+          body: "{\n  \"meta\": [\n    {\"title\": \"'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'\u03BE'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"'\\\\\\/%25''\\\"&<>#'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"''\", \"domain\": \"string\"}\n  ],\n  \"data\": [\n
+            \   [\"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F\\u0010\",
+            \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F\x7F\",
+            \"\u03BE\", \"\\\\\\/%'\\\"&<>#\", \"\"]\n  ]\n}\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:csv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/csv; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).csv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE',\"'\\/%25''\"\"&<>#'\",''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\",\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F,\u03BE,\"\\/%'\"\"&<>#\",\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).tsv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\t'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\t'\u03BE'\t\"'\\/%25''\"\"&<>#'\"\t''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\"\t\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F\t\u03BE\t\"\\/%'\"\"&<>#\"\t\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: " |                                                                                                                                                                                                            |\n-+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-\n
+            | '%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'                             |
+            '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'                                            |
+            '\u03BE' | '\\/%25''\"&<>#' | '' |\n-+--------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+-----+----------------+----+-\n
+            | \"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u0010\"
+            | \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\x7F\"
+            | \u03BE   | \\/%'\"&<>#      | \"\" |\n                                                                                                                                                                                                        (1
+            row)\n\n ----\n /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&<>#',''}/:txt\n
+            SELECT '\x01\x02\x03\x04\x05\x06\a\b\t\n \v\f\n \x0E\x0F\x10',\n        '\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F',\n
+            \       '\u03BE',\n        E'\\\\/%''\"&<>#',\n        ''\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:html
+          status: 200 OK
+          headers:
+          - [Content-Type, text/html; charset=UTF-8]
+          body: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
+            \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\"
+            content=\"text/html; charset=UTF-8\">\n<title>/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</title>\n<style
+            type=\"text/css\">\nbody { font-family: sans-serif; font-size: 90%; color:
+            #515151; background: #ffffff }\na:link, a:visited { color: #1f4884; text-decoration:
+            none }\na:hover { text-decoration: underline }\ntable { border-collapse:
+            collapse; margin: 0.5em auto; width: 100% }\ntable, tr { border-style:
+            solid; border-width: 0 }\ntd, th { padding: 0.2em 0.5em; vertical-align:
+            top; text-align: left }\ndiv.tab { position: relative; left: -1px; margin-right:
+            60%; padding: 0.2em 0.5em; background: #ffffff; border-style: solid; border-width:
+            5px 1px 0; border-top-left-radius: 10px; border-top-right-radius: 10px;
+            -moz-border-radius-topleft: 10px; -moz-border-radius-topright: 10px; -webkit-border-top-left-radius:
+            10px; -webkit-border-top-right-radius: 10px }\ntable.page { border: 0;
+            padding: 1em; width: auto }\ntr.content { padding: 1em 1em 0.5em }\ntr.footer
+            { padding: 0 1em 1em; text-align: left; font-style: italic }\ntable.chart
+            .number { text-align: right }\ntr.caption { font-size: 105%; background:
+            transparent }\ntr.caption th { padding: 0 }\ndiv.tab { border-color: #6f9ad3
+            #c3c3c3 }\ntr.header { background: #dae3ea; border-color: #c3c3c3; border-width:
+            1px 1px 0 }\ntr.odd { background: #ffffff; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.even { background: #f2f2f2; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.odd:hover, tr.even:hover { background: #ffe3bd }\ntr.total
+            { background: transparent;border-color: #c3c3c3; border-width: 1px 0 0
+            }\ntr.total td { text-align: right; font-size: 75%; font-style: italic;
+            padding: 0.3em 0.5em 0 }\ntable.void { text-align: center; border-color:
+            #c3c3c3; border-width: 1px 0 }\n</style>\n</head>\n<body>\n<table class=\"page\"
+            summary=\"/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''&quot;&amp;&lt;&gt;#',''}/:html\">\n<tr>\n<td
+            class=\"content\">\n<table class=\"chart\" summary=\"\">\n<tr class=\"caption\"><th
+            colspan=\"5\"><div class=\"tab\"></div></th></tr>\n<tr class=\"header\"><th>'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'</th><th>'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'</th><th>'\u03BE'</th><th>'\\/%25''\"&amp;&lt;&gt;#'</th><th>''</th></tr>\n<tr
+            class=\"odd\"><td>\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10</td><td>\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F</td><td>\u03BE</td><td>\\/%'\"&amp;&lt;&gt;#</td><td>&nbsp;</td></tr>\n<tr
+            class=\"total\"><td colspan=\"5\">(1 row)</td></tr></table></td>\n</tr>\n<tr><td
+            class=\"footer\">/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</td></tr>\n</table>\n</body>\n</html>\n"

test/regress/output/sqlite.yaml

             of Arts and Humanities,old\r\nmus,School of Music & Dance,south\r\nns,School
             of Natural Sciences,old\r\nph,Public Honorariums,\r\nsc,School of Continuing
             Studies,\r\n"
+        - uri: /school/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
         - uri: /school/:txt
           status: 200 OK
           headers:
         - uri: /school
           status: 200 OK
           headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, attachment; filename="(school).tsv"]
+          body: "code\tname\tcampus\r\nart\tSchool of Art and Design\told\r\nbus\tSchool
+            of Business\tsouth\r\nedu\tCollege of Education\told\r\neng\tSchool of
+            Engineering\tnorth\r\nla\tSchool of Arts and Humanities\told\r\nmus\tSchool
+            of Music & Dance\tsouth\r\nns\tSchool of Natural Sciences\told\r\nph\tPublic
+            Honorariums\t\r\nsc\tSchool of Continuing Studies\t\r\n"
+        - uri: /school
+          status: 200 OK
+          headers:
           - [Content-Type, text/plain; charset=UTF-8]
           body: |2
              | school                                        |
             of Arts and Humanities,5\r\nSchool of Music & Dance,4\r\nSchool of Natural
             Sciences,4\r\nPublic Honorariums,0\r\nSchool of Continuing Studies,0\r\n"
         - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
+            '# of Departments'} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="((school:as(''List of Schools'')){name:as(Name),count(department):as(''#
+              of Departments'')}).tsv"']
+          body: "Name\t# of Departments\r\nSchool of Art and Design\t2\r\nSchool of
+            Business\t3\r\nCollege of Education\t2\r\nSchool of Engineering\t4\r\nSchool
+            of Arts and Humanities\t5\r\nSchool of Music & Dance\t4\r\nSchool of Natural
+            Sciences\t4\r\nPublic Honorariums\t0\r\nSchool of Continuing Studies\t0\r\n"
+        - uri: /(school :as 'List of Schools') {name :as Name, count(department) :as
             '# of Departments'} /:txt
           status: 200 OK
           headers:
             </html>
       - id: data-types
         tests:
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:json
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:json
           status: 200 OK
           headers:
           - [Content-Type, application/javascript]
-          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).js"']
+          - [Content-Disposition, 'inline; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).js"']
           body: |
             {
               "meta": [
                 {"title": "2.125", "domain": "number"},
                 {"title": "271828e-5", "domain": "number"},
                 {"title": "'HTSQL'", "domain": "string"},
-                {"title": "'2010-04-15'", "domain": "date"}
+                {"title": "'2010-04-15'", "domain": "date"},
+                {"title": "'20:13:04.5'", "domain": "time"},
+                {"title": "'2010-04-15 20:13'", "domain": "datetime"}
               ],
               "data": [
-                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15"]
+                [null, true, false, 60, 2.125, 2.71828, "HTSQL", "2010-04-15", "20:13:04.500000", "2010-04-15 20:13:00"]
               ]
             }
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:csv
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:csv
           status: 200 OK
           headers:
           - [Content-Type, text/csv; charset=UTF-8]
-          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15'')}).csv"']
-          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15\r\n"
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:txt
-          status: 200 OK
-          headers:
-          - [Content-Type, text/plain; charset=UTF-8]
-          body: |2
-             |                                                                             |
-            -+-----------------------------------------------------------------------------+-
-             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' |
-            -+--------+--------+---------+----+-------+-----------+---------+--------------+-
-             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   |
-                                                                                     (1 row)
-
-             ----
-             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:txt
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).csv"']
+          body: "null(),true(),false(),60,2.125,271828e-5,'HTSQL','2010-04-15','20:13:04.5','2010-04-15
+            20:13'\r\n,true,false,60,2.125,2.71828,HTSQL,2010-04-15,20:13:04.500000,2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="({null(),true(),false(),60,2.125,271828e-5,''HTSQL'',date(''2010-04-15''),time(''20:13:04.5''),datetime(''2010-04-15
+              20:13'')}).tsv"']
+          body: "null()\ttrue()\tfalse()\t60\t2.125\t271828e-5\t'HTSQL'\t'2010-04-15'\t'20:13:04.5'\t'2010-04-15
+            20:13'\r\n\ttrue\tfalse\t60\t2.125\t2.71828\tHTSQL\t2010-04-15\t20:13:04.500000\t2010-04-15
+            20:13:00\r\n"
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |2
+             |                                                                                                                     |
+            -+---------------------------------------------------------------------------------------------------------------------+-
+             | null() | true() | false() | 60 | 2.125 | 271828e-5 | 'HTSQL' | '2010-04-15' | '20:13:04.5'    | '2010-04-15 20:13'  |
+            -+--------+--------+---------+----+-------+-----------+---------+--------------+-----------------+---------------------+-
+             |        | true   | false   | 60 | 2.125 |   2.71828 | HTSQL   | 2010-04-15   | 20:13:04.500000 | 2010-04-15 20:13:00 |
+                                                                                                                             (1 row)
+
+             ----
+             /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:txt
              SELECT NULL,
                     1,
                     0,
                     2.125,
                     2.71828,
                     'HTSQL',
-                    '2010-04-15'
-        - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-            /:html
+                    '2010-04-15',
+                    '20:13:04.500000',
+                    '2010-04-15 20:13:00'
+        - uri: /{null(), true(), false(), 60, 2.125, 271828e-5, 'HTSQL', date('2010-04-15'),
+            time('20:13:04.5'), datetime('2010-04-15 20:13')} /:html
           status: 200 OK
           headers:
           - [Content-Type, text/html; charset=UTF-8]
             <html>
             <head>
             <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</title>
+            <title>/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</title>
             <style type="text/css">
             body { font-family: sans-serif; font-size: 90%; color: #515151; background: #ffffff }
             a:link, a:visited { color: #1f4884; text-decoration: none }
             </style>
             </head>
             <body>
-            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html">
+            <table class="page" summary="/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html">
             <tr>
             <td class="content">
             <table class="chart" summary="">
-            <tr class="caption"><th colspan="8"><div class="tab"></div></th></tr>
-            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th></tr>
-            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td></tr>
-            <tr class="total"><td colspan="8">(1 row)</td></tr></table></td>
+            <tr class="caption"><th colspan="10"><div class="tab"></div></th></tr>
+            <tr class="header"><th>null()</th><th>true()</th><th>false()</th><th class="number">60</th><th class="number">2.125</th><th class="number">271828e-5</th><th>'HTSQL'</th><th>'2010-04-15'</th><th>'20:13:04.5'</th><th>'2010-04-15 20:13'</th></tr>
+            <tr class="odd"><td><em>&mdash;</em></td><td><em>true</em></td><td><em>false</em></td><td class="number">60</td><td class="number">2.125</td><td class="number">2.71828</td><td>HTSQL</td><td>2010-04-15</td><td>20:13:04.500000</td><td>2010-04-15 20:13:00</td></tr>
+            <tr class="total"><td colspan="10">(1 row)</td></tr></table></td>
             </tr>
-            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}/:html</td></tr>
+            <tr><td class="footer">/{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15'),time('20:13:04.5'),datetime('2010-04-15 20:13')}/:html</td></tr>
             </table>
             </body>
             </html>
           - [Content-Type, text/csv; charset=UTF-8]
           - [Content-Disposition, 'attachment; filename="(school?false()).csv"']
           body: "code,name,campus\r\n"
+        - uri: /school?false()/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, 'attachment; filename="(school?false()).tsv"']
+          body: "code\tname\tcampus\r\n"
         - uri: /school?false()/:txt
           status: 200 OK
           headers:
             </table>
             </body>
             </html>
+      - id: special-characters
+        tests:
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:json
+          status: 200 OK
+          headers:
+          - [Content-Type, application/javascript]
+          - [Content-Disposition, "inline; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).js\""]
+          body: "{\n  \"meta\": [\n    {\"title\": \"'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\",
+            \"domain\": \"string\"},\n    {\"title\": \"'\u03BE'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"'\\\\\\/%25''\\\"&<>#'\", \"domain\": \"string\"},\n
+            \   {\"title\": \"''\", \"domain\": \"string\"}\n  ],\n  \"data\": [\n
+            \   [\"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F\\u0010\",
+            \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F\x7F\",
+            \"\u03BE\", \"\\\\\\/%'\\\"&<>#\", \"\"]\n  ]\n}\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:csv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/csv; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).csv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE',\"'\\/%25''\"\"&<>#'\",''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\",\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F,\u03BE,\"\\/%'\"\"&<>#\",\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:tsv
+          status: 200 OK
+          headers:
+          - [Content-Type, text/tab-separated-values; charset=UTF-8]
+          - [Content-Disposition, "attachment; filename=\"({'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\\\/%25''\\\"&<>#',''}).tsv\""]
+          body: "'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'\t'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'\t'\u03BE'\t\"'\\/%25''\"\"&<>#'\"\t''\r\n\"\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10\"\t\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F\t\u03BE\t\"\\/%'\"\"&<>#\"\t\r\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:txt
+          status: 200 OK
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: " |                                                                                                                                                                                                            |\n-+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-\n
+            | '%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'                             |
+            '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'                                            |
+            '\u03BE' | '\\/%25''\"&<>#' | '' |\n-+--------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------+-----+----------------+----+-\n
+            | \"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u0010\"
+            | \"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\x7F\"
+            | \u03BE   | \\/%'\"&<>#      | \"\" |\n                                                                                                                                                                                                        (1
+            row)\n\n ----\n /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&<>#',''}/:txt\n
+            SELECT '\x01\x02\x03\x04\x05\x06\a\b\t\n \v\f\n \x0E\x0F\x10',\n        '\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F',\n
+            \       '\u03BE',\n        '\\/%''\"&<>#',\n        ''\n"
+        - uri: /{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10', '%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F',
+            '%CE%BE', '\/%25''"&<>#', ''}/:html
+          status: 200 OK
+          headers:
+          - [Content-Type, text/html; charset=UTF-8]
+          body: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
+            \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\"
+            content=\"text/html; charset=UTF-8\">\n<title>/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</title>\n<style
+            type=\"text/css\">\nbody { font-family: sans-serif; font-size: 90%; color:
+            #515151; background: #ffffff }\na:link, a:visited { color: #1f4884; text-decoration:
+            none }\na:hover { text-decoration: underline }\ntable { border-collapse:
+            collapse; margin: 0.5em auto; width: 100% }\ntable, tr { border-style:
+            solid; border-width: 0 }\ntd, th { padding: 0.2em 0.5em; vertical-align:
+            top; text-align: left }\ndiv.tab { position: relative; left: -1px; margin-right:
+            60%; padding: 0.2em 0.5em; background: #ffffff; border-style: solid; border-width:
+            5px 1px 0; border-top-left-radius: 10px; border-top-right-radius: 10px;
+            -moz-border-radius-topleft: 10px; -moz-border-radius-topright: 10px; -webkit-border-top-left-radius:
+            10px; -webkit-border-top-right-radius: 10px }\ntable.page { border: 0;
+            padding: 1em; width: auto }\ntr.content { padding: 1em 1em 0.5em }\ntr.footer
+            { padding: 0 1em 1em; text-align: left; font-style: italic }\ntable.chart
+            .number { text-align: right }\ntr.caption { font-size: 105%; background:
+            transparent }\ntr.caption th { padding: 0 }\ndiv.tab { border-color: #6f9ad3
+            #c3c3c3 }\ntr.header { background: #dae3ea; border-color: #c3c3c3; border-width:
+            1px 1px 0 }\ntr.odd { background: #ffffff; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.even { background: #f2f2f2; border-color: #c3c3c3; border-width:
+            0 1px }\ntr.odd:hover, tr.even:hover { background: #ffe3bd }\ntr.total
+            { background: transparent;border-color: #c3c3c3; border-width: 1px 0 0
+            }\ntr.total td { text-align: right; font-size: 75%; font-style: italic;
+            padding: 0.3em 0.5em 0 }\ntable.void { text-align: center; border-color:
+            #c3c3c3; border-width: 1px 0 }\n</style>\n</head>\n<body>\n<table class=\"page\"
+            summary=\"/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''&quot;&amp;&lt;&gt;#',''}/:html\">\n<tr>\n<td
+            class=\"content\">\n<table class=\"chart\" summary=\"\">\n<tr class=\"caption\"><th
+            colspan=\"5\"><div class=\"tab\"></div></th></tr>\n<tr class=\"header\"><th>'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10'</th><th>'%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F'</th><th>'\u03BE'</th><th>'\\/%25''\"&amp;&lt;&gt;#'</th><th>''</th></tr>\n<tr
+            class=\"odd\"><td>\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F\x10</td><td>\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\e\x1C\x1D\x1E\x1F\x7F</td><td>\u03BE</td><td>\\/%'\"&amp;&lt;&gt;#</td><td>&nbsp;</td></tr>\n<tr
+            class=\"total\"><td colspan=\"5\">(1 row)</td></tr></table></td>\n</tr>\n<tr><td
+            class=\"footer\">/{'%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10','%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F','\u03BE','\\/%25''\"&amp;&lt;&gt;#',''}/:html</td></tr>\n</table>\n</body>\n</html>\n"