Fixed an issue where 'ALTER VIEW' statement is missing when the user sets the default value of a column for View. Fixes #5664

This commit is contained in:
Rahul Shirsat authored and Akshay Joshi committed 2020-08-10 15:27:57 +05:30
1 parent 4f74609ecf
commit 604937cf66
8 files changed
+82 -6

No files matched your search

@@ -683,6 +683,10 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
gettext("Could not find the column on the server.")
)
old_data = dict(res['rows'][0])
is_view_only = True if 'is_view_only' in old_data and old_data[
'is_view_only'] else False
if 'seqcycle' in old_data and old_data['seqcycle'] is False:
old_data['seqcycle'] = None
# We will add table & schema as well
@@ -694,7 +698,8 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
sql = render_template(
"/".join([self.template_path, self._UPDATE_SQL]),
data=data, o_data=old_data, conn=self.conn
data=data, o_data=old_data, conn=self.conn,
is_view_only=is_view_only
)
else:
is_error, errmsg, sql = self._get_sql_for_create(data, is_sql)
@@ -16,7 +16,8 @@ SELECT att.attname as name, att.atttypid, att.attlen, att.attnum, att.attndims,
EXISTS(SELECT 1 FROM pg_constraint WHERE conrelid=att.attrelid AND contype='f' AND att.attnum=ANY(conkey)) As is_fk,
(SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=att.attrelid AND sl1.objsubid=att.attnum) AS seclabels,
(CASE WHEN (att.attnum < 1) THEN true ElSE false END) AS is_sys_column,
(CASE WHEN (att.attidentity in ('a', 'd')) THEN 'i' ELSE 'n' END) AS colconstype,
(CASE WHEN (att.attidentity in ('a', 'd')) THEN 'i' ELSE 'n' END) AS colconstype, tab.relname as relname,
(CASE WHEN tab.relkind = 'v' THEN true ELSE false END) AS is_view_only,
seq.*
FROM pg_attribute att
JOIN pg_type ty ON ty.oid=atttypid
@@ -27,6 +28,7 @@ FROM pg_attribute att
LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid
LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid
LEFT OUTER JOIN pg_sequence seq ON cs.oid=seq.seqrelid
LEFT OUTER JOIN pg_class tab on tab.oid = att.attrelid
WHERE att.attrelid = {{tid}}::oid
{% if clid %}
AND att.attnum = {{clid}}::int
@@ -21,7 +21,11 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
COLLATE {{data.collspcname}}{% elif o_data.collspcname %} COLLATE {{o_data.collspcname}}{% endif %};
{% endif %}
{### Alter column default value ###}
{% if data.defval is defined and data.defval is not none and data.defval != '' and data.defval != o_data.defval %}
{% if is_view_only and data.defval is defined and data.defval is not none and data.defval != '' and data.defval != o_data.defval %}
ALTER VIEW {{conn|qtIdent(data.schema, data.table)}}
ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET DEFAULT {{data.defval}};
{% elif data.defval is defined and data.defval is not none and data.defval != '' and data.defval != o_data.defval %}
ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET DEFAULT {{data.defval}};
@@ -17,7 +17,8 @@ SELECT att.attname as name, att.atttypid, att.attlen, att.attnum, att.attndims,
(SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=att.attrelid AND sl1.objsubid=att.attnum) AS seclabels,
(CASE WHEN (att.attnum < 1) THEN true ElSE false END) AS is_sys_column,
(CASE WHEN (att.attidentity in ('a', 'd')) THEN 'i' WHEN (att.attgenerated in ('s')) THEN 'g' ELSE 'n' END) AS colconstype,
(CASE WHEN (att.attgenerated in ('s')) THEN pg_catalog.pg_get_expr(def.adbin, def.adrelid) END) AS genexpr,
(CASE WHEN (att.attgenerated in ('s')) THEN pg_catalog.pg_get_expr(def.adbin, def.adrelid) END) AS genexpr, tab.relname as relname,
(CASE WHEN tab.relkind = 'v' THEN true ELSE false END) AS is_view_only,
seq.*
FROM pg_attribute att
JOIN pg_type ty ON ty.oid=atttypid
@@ -28,6 +29,7 @@ FROM pg_attribute att
LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid
LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid
LEFT OUTER JOIN pg_sequence seq ON cs.oid=seq.seqrelid
LEFT OUTER JOIN pg_class tab on tab.oid = att.attrelid
WHERE att.attrelid = {{tid}}::oid
{% if clid %}
AND att.attnum = {{clid}}::int
@@ -14,7 +14,8 @@ SELECT att.attname as name, att.atttypid, att.attlen, att.attnum, att.attndims,
ELSE '' END AS collspcname,
EXISTS(SELECT 1 FROM pg_constraint WHERE conrelid=att.attrelid AND contype='f' AND att.attnum=ANY(conkey)) As is_fk,
(SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=att.attrelid AND sl1.objsubid=att.attnum) AS seclabels,
(CASE WHEN (att.attnum < 1) THEN true ElSE false END) AS is_sys_column
(CASE WHEN (att.attnum < 1) THEN true ElSE false END) AS is_sys_column, tab.relname as relname,
(CASE WHEN tab.relkind = 'v' THEN true ELSE false END) AS is_view_only
FROM pg_attribute att
JOIN pg_type ty ON ty.oid=atttypid
LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
@@ -23,6 +24,7 @@ FROM pg_attribute att
LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary
LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid
LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid
LEFT OUTER JOIN pg_class tab on tab.oid = att.attrelid
WHERE att.attrelid = {{tid}}::oid
{% if clid %}
AND att.attnum = {{clid}}::int
@@ -21,7 +21,11 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
COLLATE {{data.collspcname}}{% elif o_data.collspcname %} COLLATE {{o_data.collspcname}}{% endif %};
{% endif %}
{### Alter column default value ###}
{% if data.defval is defined and data.defval is not none and data.defval != '' and data.defval != o_data.defval %}
{% if is_view_only and data.defval is defined and data.defval is not none and data.defval != '' and data.defval != o_data.defval %}
ALTER VIEW {{conn|qtIdent(data.schema, data.table)}}
ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET DEFAULT {{data.defval}};
{% elif data.defval is defined and data.defval is not none and data.defval != '' and data.defval != o_data.defval %}
ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET DEFAULT {{data.defval}};
@@ -9,6 +9,7 @@
"""Implements View and Materialized View Node"""
import copy
import re
from functools import wraps
@@ -815,12 +816,17 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
if is_error:
return None, errmsg
self.view_schema = old_data['schema']
try:
sql = render_template("/".join(
[self.template_path,
self._SQL_PREFIX + self._UPDATE_SQL]), data=data,
o_data=old_data, conn=self.conn)
if 'definition' in data and data['definition']:
sql += self.get_columns_sql(did, vid)
except Exception as e:
current_app.logger.exception(e)
return None, internal_server_error(errormsg=str(e))
@@ -1300,6 +1306,51 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
sql_data += SQL
return sql_data
def get_columns_sql(self, did, vid):
"""
Get all column associated with view node,
generate their sql and render
into sql tab
"""
sql_data = ''
SQL = render_template("/".join(
[self.column_template_path,
self._PROPERTIES_SQL.format(self.manager.version)]),
did=did,
tid=vid)
status, data = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=data)
for rows in data['rows']:
res = {
'name': rows['name'],
'atttypid': rows['atttypid'],
'attlen': rows['attlen'],
'typnspname': rows['typnspname'],
'defval': None,
'table': rows['relname'],
'schema': self.view_schema
}
o_data = copy.deepcopy(rows)
# Generate alter statement for default value
if 'defval' in rows and rows['defval'] is not None:
res['defval'] = rows['defval']
o_data['defval'] = None
else:
continue
SQL = render_template("/".join(
[self.column_template_path,
self._UPDATE_SQL.format(self.manager.version)]),
o_data=o_data, data=res, is_view_only=True)
sql_data += SQL
return sql_data
@check_precondition
def sql(self, gid, sid, did, scid, vid, **kwargs):
"""
@@ -1376,11 +1427,16 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
[self.template_path, self._SQL_PREFIX + self._GRANT_SQL]),
data=result)
if ('seclabels' in result and len(result['seclabels']) > 0)\
or ('datacl' in result and len(result['datacl']) > 0):
SQL += "\n"
sql_data += SQL
sql_data += self.get_rule_sql(vid, display_comments)
sql_data += self.get_trigger_sql(vid, display_comments)
sql_data += self.get_compound_trigger_sql(vid, display_comments)
sql_data += self.get_index_sql(did, vid, display_comments)
sql_data += self.get_columns_sql(did, vid)
if not json_resp:
return sql_data