Reviewers: ,
Please review this at
http://codereview.appspot.com/13621044/
Affected files (+35, -4 lines):
M CHANGELOG
M sql/__init__.py
M sql/functions.py
M sql/tests/test_select.py
Index: CHANGELOG
===================================================================
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,5 @@
+* Add columns definitions to Function
+
Version 0.2 - 2013-09-18
* Fix usage mixture between Div operator and function
* Add array support in operators
Index: sql/__init__.py
===================================================================
--- a/sql/__init__.py
+++ b/sql/__init__.py
@@ -774,7 +774,14 @@
return '(%s) AS "%s"' % (from_, from_.alias)
else:
alias = getattr(from_, 'alias', None)
- if alias:
+ columns_definitions = getattr(from_, 'columns_definitions',
+ None)
+ # XXX find a better test for __getattr__ which returns
Column
+ if (alias and columns_definitions
+ and not isinstance(columns_definitions, Column)):
+ return '%s AS "%s" (%s)' % (from_, alias,
+ columns_definitions)
+ elif alias:
return '%s AS "%s"' % (from_, alias)
else:
return str(from_)
Index: sql/functions.py
===================================================================
--- a/sql/functions.py
+++ b/sql/functions.py
@@ -47,13 +47,24 @@
class Function(Expression, FromItem):
- __slots__ = ('args',)
+ __slots__ = ('args', '__columns_definitions')
table = ''
name = ''
_function = ''
- def __init__(self, *args):
+ def __init__(self, *args, **kwargs):
self.args = args
+ self.columns_definitions = kwargs.get('columns_definitions', [])
+
+ @property
+ def columns_definitions(self):
+ return ', '.join('"%s" %s' % (c, d)
+ for c, d in self.__columns_definitions)
+
+ @columns_definitions.setter
+ def columns_definitions(self, value):
+ assert isinstance(value, list)
+ self.__columns_definitions = value
@staticmethod
def _format(value):
Index: sql/tests/test_select.py
===================================================================
--- a/sql/tests/test_select.py
+++ b/sql/tests/test_select.py
@@ -30,7 +30,7 @@
import unittest
from sql import Table, Join, Union, Literal, Flavor
-from sql.functions import Now
+from sql.functions import Now, Function
from sql.aggregate import Min
@@ -114,6 +114,17 @@
self.assertEqual(str(query), 'SELECT * FROM NOW() AS "a"')
self.assertEqual(query.params, ())
+ def test_select_function_columns_definitions(self):
+ class Crosstab(Function):
+ _function = 'CROSSTAB'
+
+ query = Crosstab('query1', 'query2',
+ columns_definitions=[
+ ('c1', 'INT'), ('c2', 'CHAR'), ('c3', 'BOOL')]).select()
+ self.assertEqual(str(query), 'SELECT * FROM CROSSTAB(%s, %s) '
+ 'AS "a" ("c1" INT, "c2" CHAR, "c3" BOOL)')
+ self.assertEqual(query.params, ('query1', 'query2'))
+
def test_select_group_by(self):
column = self.table.c
query = self.table.select(column, group_by=column)