Skip to content

Commit c4cedf3

Browse files
fetzermsamotl
authored andcommitted
Columnstore: Adding tests and error handling for non TEXT columns
1 parent 7be41e2 commit c4cedf3

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

src/crate/client/sqlalchemy/compiler.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import sqlalchemy as sa
2626
from sqlalchemy.dialects.postgresql.base import PGCompiler
2727
from sqlalchemy.sql import compiler
28+
from sqlalchemy.types import String
2829
from .types import MutableDict, _Craty, Geopoint, Geoshape
2930
from .sa_version import SA_VERSION, SA_1_4
3031

@@ -129,6 +130,11 @@ def get_column_specification(self, column, **kwargs):
129130
colspec += " INDEX OFF"
130131

131132
if column.dialect_options['crate'].get('columnstore') is False:
133+
if not isinstance(column.type, (String, )):
134+
raise sa.exc.CompileError(
135+
"Controlling the columnstore is only allowed for STRING columns"
136+
)
137+
132138
colspec += " STORAGE WITH (columnstore = false)"
133139

134140
return colspec

src/crate/client/sqlalchemy/tests/create_table_test.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
# software solely pursuant to the terms of the relevant commercial agreement.
2121

2222
import sqlalchemy as sa
23+
2324
try:
2425
from sqlalchemy.orm import declarative_base
2526
except ImportError:
@@ -31,7 +32,6 @@
3132
from unittest import TestCase
3233
from unittest.mock import patch, MagicMock
3334

34-
3535
fake_cursor = MagicMock(name='fake_cursor')
3636
FakeCursor = MagicMock(name='FakeCursor', spec=Cursor)
3737
FakeCursor.return_value = fake_cursor
@@ -77,6 +77,7 @@ class DummyTable(self.Base):
7777
__tablename__ = 'dummy'
7878
pk = sa.Column(sa.String, primary_key=True)
7979
obj_col = sa.Column(Object)
80+
8081
self.Base.metadata.create_all(bind=self.engine)
8182
fake_cursor.execute.assert_called_with(
8283
('\nCREATE TABLE dummy (\n\tpk STRING NOT NULL, \n\tobj_col OBJECT, '
@@ -91,6 +92,7 @@ class DummyTable(self.Base):
9192
}
9293
pk = sa.Column(sa.String, primary_key=True)
9394
p = sa.Column(sa.String)
95+
9496
self.Base.metadata.create_all(bind=self.engine)
9597
fake_cursor.execute.assert_called_with(
9698
('\nCREATE TABLE t (\n\t'
@@ -105,6 +107,7 @@ class DummyTable(self.Base):
105107
__tablename__ = 't'
106108
ts = sa.Column(sa.BigInteger, primary_key=True)
107109
p = sa.Column(sa.BigInteger, sa.Computed("date_trunc('day', ts)"))
110+
108111
self.Base.metadata.create_all(bind=self.engine)
109112
fake_cursor.execute.assert_called_with(
110113
('\nCREATE TABLE t (\n\t'
@@ -119,6 +122,7 @@ class DummyTable(self.Base):
119122
__tablename__ = 't'
120123
ts = sa.Column(sa.BigInteger, primary_key=True)
121124
p = sa.Column(sa.BigInteger, sa.Computed("date_trunc('day', ts)", persisted=False))
125+
122126
with self.assertRaises(sa.exc.CompileError):
123127
self.Base.metadata.create_all(bind=self.engine)
124128

@@ -131,6 +135,7 @@ class DummyTable(self.Base):
131135
}
132136
pk = sa.Column(sa.String, primary_key=True)
133137
p = sa.Column(sa.String)
138+
134139
self.Base.metadata.create_all(bind=self.engine)
135140
fake_cursor.execute.assert_called_with(
136141
('\nCREATE TABLE t (\n\t'
@@ -166,6 +171,7 @@ class DummyTable(self.Base):
166171
}
167172
pk = sa.Column(sa.String, primary_key=True)
168173
p = sa.Column(sa.String, primary_key=True)
174+
169175
self.Base.metadata.create_all(bind=self.engine)
170176
fake_cursor.execute.assert_called_with(
171177
('\nCREATE TABLE t (\n\t'
@@ -207,6 +213,7 @@ def test_column_pk_nullable(self):
207213
class DummyTable(self.Base):
208214
__tablename__ = 't'
209215
pk = sa.Column(sa.String, primary_key=True, nullable=True)
216+
210217
with self.assertRaises(sa.exc.CompileError):
211218
self.Base.metadata.create_all(bind=self.engine)
212219

@@ -230,5 +237,33 @@ class DummyTable(self.Base):
230237
__tablename__ = 't'
231238
pk = sa.Column(sa.String, primary_key=True)
232239
a = sa.Column(Geopoint, crate_index=False)
240+
241+
with self.assertRaises(sa.exc.CompileError):
242+
self.Base.metadata.create_all(bind=self.engine)
243+
244+
def test_text_column_without_columnstore(self):
245+
class DummyTable(self.Base):
246+
__tablename__ = 't'
247+
pk = sa.Column(sa.String, primary_key=True)
248+
a = sa.Column(sa.String, crate_columnstore=False)
249+
b = sa.Column(sa.String, crate_columnstore=True)
250+
c = sa.Column(sa.String)
251+
252+
self.Base.metadata.create_all(bind=self.engine)
253+
254+
fake_cursor.execute.assert_called_with(
255+
('\nCREATE TABLE t (\n\t'
256+
'pk STRING NOT NULL, \n\t'
257+
'a STRING STORAGE WITH (columnstore = false), \n\t'
258+
'b STRING, \n\t'
259+
'c STRING, \n\t'
260+
'PRIMARY KEY (pk)\n)\n\n'), ())
261+
262+
def test_non_text_column_without_columnstore(self):
263+
class DummyTable(self.Base):
264+
__tablename__ = 't'
265+
pk = sa.Column(sa.String, primary_key=True)
266+
a = sa.Column(sa.Integer, crate_columnstore=False)
267+
233268
with self.assertRaises(sa.exc.CompileError):
234269
self.Base.metadata.create_all(bind=self.engine)

0 commit comments

Comments
 (0)