Skip to content

Commit

Permalink
Write more message explanations
Browse files Browse the repository at this point in the history
  • Loading branch information
erik committed Dec 30, 2018
1 parent c2fdf27 commit 8dedcd6
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 3 deletions.
21 changes: 18 additions & 3 deletions squabble/rules/add_column_disallow_constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class AddColumnDisallowConstraints(BaseRule):
Tags: performance, backwards-compatibility
"""

CONSTRAINT_MAP = {
_CONSTRAINT_MAP = {
'DEFAULT': ConstrType.CONSTR_DEFAULT,
'NULL': ConstrType.CONSTR_NULL,
'NOT NULL': ConstrType.CONSTR_NOTNULL,
Expand All @@ -43,7 +43,22 @@ class AddColumnDisallowConstraints(BaseRule):
}

def explain_constraint_not_allowed():
pass
"""
When adding a column to an existing table, certain constraints can have
unintentional side effects, like locking the table or introducing
performance issues.
For example, adding a ``DEFAULT`` constraint may hold a lock on the
table while all existing rows are modified to fill in the default
value.
A ``UNIQUE`` constraint will require scanning the table to confirm
there are no duplicates.
On a particularly hot table, a ``FOREIGN`` constraint will introduce
possibly dangerous overhead to confirm the referential integrity of
each row.
"""

def enable(self, ctx, config):
disallowed = config.get('disallowed', [])
Expand All @@ -54,7 +69,7 @@ def enable(self, ctx, config):
constraints = set()

for c in disallowed:
ty = self.CONSTRAINT_MAP[c.upper()]
ty = self._CONSTRAINT_MAP[c.upper()]
if ty is None:
raise RuleConfigurationException(
self, 'unknown constraint: `%s`' % c)
Expand Down
6 changes: 6 additions & 0 deletions squabble/rules/disallow_rename_enum_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ class DisallowRenameEnumValue(BaseRule):
'rename_not_allowed': 'cannot rename existing enum value "{value}"'
}

def explain_rename_not_allowed():
"""
Renaming an existing enum value may be backwards compatible
with code that is live in production.
"""

def enable(self, ctx, _config):
ctx.register('AlterEnumStmt', self._check_enum())

Expand Down
13 changes: 13 additions & 0 deletions squabble/rules/require_concurrent_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,23 @@ class RequireConcurrentIndex(BaseRule):
Tags: performance
"""

MESSAGES = {
'index_not_concurrent': 'index "{name}" not created `CONCURRENTLY`'
}

def explain_index_not_concurrent():
"""
Adding a new index to an existing table may hold a full table lock
while the index is being built. On large tables, this may take a long
time, so the preferred approach is to create the index concurrently
instead.
.. code-block:: sql
CREATE INDEX CONCURRENTLY users_by_name ON users(name);
"""

def enable(self, ctx, config):
include_new = config.get('include_new_tables', False)
tables = set()
Expand Down
9 changes: 9 additions & 0 deletions squabble/rules/require_primary_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ class RequirePrimaryKey(BaseRule):
'missing_primary_key': 'table "{tbl}" does not name a primary key'
}

def explain_missing_primary_key():
"""
When creating a new table, it's usually a good idea to define a primary
key, as it can guarantee a unique, fast lookup into the table.
If no single column will uniquely identify a row, creating a composite
primary key is also possible.
"""

def enable(self, ctx, _config):
ctx.register('CreateStmt', self._create_table())

Expand Down

0 comments on commit 8dedcd6

Please sign in to comment.