Fixed an issue where View/Edit data is throwing an error if the user deleted and re-create the same table for which View/Edit data was opened. #6431

This commit is contained in:
Nikhil Mohite 2023-06-19 19:37:10 +05:30 committed by GitHub
parent 5d619fd455
commit 4746fbd346
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 91 additions and 30 deletions

View File

@ -13,7 +13,13 @@ FROM pg_catalog.pg_attribute att
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=att.attrelid AND des.objsubid=att.attnum AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_catalog.pg_sequence seq ON cs.oid=seq.seqrelid
WHERE
{% if tid %}
att.attrelid = {{ tid|qtLiteral(conn) }}::oid
{% endif %}
{% if table_name and table_nspname %}
cl.relname= {{table_name |qtLiteral(conn)}} and na.nspname={{table_nspname|qtLiteral(conn)}}
{% endif %}
{% if clid %}
AND att.attnum = {{ clid|qtLiteral(conn) }}
{% endif %}

View File

@ -761,6 +761,7 @@ def start_view_data(trans_id):
if status and conn is not None and \
trans_obj is not None and session_obj is not None:
# set fetched row count to 0 as we are executing query again.
trans_obj.update_fetched_row_cnt(0)
@ -1411,7 +1412,7 @@ def append_filter_exclusive(trans_id):
else:
filter_sql = driver.qtIdent(
conn, column_name
) + ' IS DISTINCT FROM ' + driver.qtLiteral(column_value)
) + ' IS DISTINCT FROM ' + driver.qtLiteral(column_value, conn)
# Call the append_filter method of transaction object
trans_obj.append_filter(filter_sql)

View File

@ -17,7 +17,7 @@ from werkzeug.exceptions import InternalServerError
from pgadmin.utils.ajax import forbidden
from pgadmin.utils.driver import get_driver
from pgadmin.tools.sqleditor.utils.is_query_resultset_updatable \
import is_query_resultset_updatable
import is_query_resultset_updatable, _check_single_table
from pgadmin.tools.sqleditor.utils.save_changed_data import save_changed_data
from pgadmin.tools.sqleditor.utils.get_column_types import get_columns_types
from pgadmin.utils.preferences import Preferences
@ -394,7 +394,9 @@ class GridCommand(BaseCommand, SQLFilter, FetchedRowTracker):
# Fetch the rest of the column names
query = render_template(
"/".join([self.sql_path, 'get_columns.sql']),
obj_id=self.obj_id
table_name=self.object_name,
table_nspname=self.nsp_name,
conn=conn,
)
status, result = conn.execute_dict(query)
if not status:
@ -532,7 +534,9 @@ class TableCommand(GridCommand):
# Fetch the primary key column names
query = render_template(
"/".join([self.sql_path, 'primary_keys.sql']),
obj_id=self.obj_id
table_name=self.object_name,
table_nspname=self.nsp_name,
conn=conn,
)
status, result = conn.execute_dict(query)
@ -576,7 +580,9 @@ class TableCommand(GridCommand):
# Fetch the primary key column names
query = render_template(
"/".join([self.sql_path, 'primary_keys.sql']),
obj_id=self.obj_id
table_name=self.object_name,
table_nspname=self.nsp_name,
conn=conn,
)
status, result = conn.execute_dict(query)
@ -590,7 +596,9 @@ class TableCommand(GridCommand):
# Fetch the rest of the column names
query = render_template(
"/".join([self.sql_path, 'get_columns.sql']),
obj_id=self.obj_id
table_name=self.object_name,
table_nspname=self.nsp_name,
conn=conn,
)
status, result = conn.execute_dict(query)
if not status:
@ -677,12 +685,22 @@ class TableCommand(GridCommand):
def get_columns_types(self, conn):
columns_info = conn.get_column_info()
has_oids = self.has_oids()
table_oid = self.obj_id
# table_oid = self.obj_id
table_name = None
table_nspname = None
table_oid = _check_single_table(columns_info)
if table_oid is None:
table_name = self.object_name
table_nspname = self.nsp_name
return get_columns_types(conn=conn,
columns_info=columns_info,
has_oids=has_oids,
table_oid=table_oid,
is_query_tool=False)
is_query_tool=False,
table_name=table_name,
table_nspname=table_nspname,
)
class ViewCommand(GridCommand):

View File

@ -1,8 +1,19 @@
{# ============= Fetch the primary keys for given object id ============= #}
{% if obj_id %}
SELECT at.attname, at.attnum, ty.typname
FROM pg_catalog.pg_attribute at LEFT JOIN pg_catalog.pg_type ty ON (ty.oid = at.atttypid)
WHERE attrelid={{obj_id}}::oid AND attnum = ANY (
(SELECT con.conkey FROM pg_catalog.pg_class rel LEFT OUTER JOIN pg_catalog.pg_constraint con ON con.conrelid=rel.oid
AND con.contype='p' WHERE rel.relkind IN ('r','s','t', 'p') AND rel.oid = {{obj_id}}::oid)::oid[])
JOIN pg_catalog.pg_class as cl ON cl.oid=AT.attrelid
JOIN pg_catalog.pg_namespace as nsp ON nsp.oid=cl.relnamespace
WHERE
{% if obj_id %}
attrelid={{obj_id}}::oid AND
{% elif table_name and table_nspname %}
cl.relname = {{table_name|qtLiteral(conn)}} AND nsp.nspname={{table_nspname|qtLiteral(conn)}} AND
{% endif %}
attnum = ANY (
(SELECT con.conkey FROM pg_catalog.pg_class rel LEFT OUTER JOIN pg_catalog.pg_constraint con ON con.conrelid=rel.oid
JOIN pg_catalog.pg_namespace as nsp ON nsp.oid=REL.relnamespace
AND con.contype='p' WHERE rel.relkind IN ('r','s','t', 'p') AND
{% if obj_id %}
rel.oid = ({{obj_id}})::oid
{% elif table_name and table_nspname%}
rel.relname = {{table_name|qtLiteral(conn)}} AND nsp.nspname={{table_nspname|qtLiteral(conn)}}
{% endif %})::oid[])

View File

@ -1,9 +1,13 @@
{# ============= Fetch the columns ============= #}
{% if obj_id %}
SELECT at.attname, ty.typname, at.attnum
FROM pg_catalog.pg_attribute at
LEFT JOIN pg_catalog.pg_type ty ON (ty.oid = at.atttypid)
WHERE attrelid={{obj_id}}::oid
AND at.attnum > 0
AND at.attisdropped = FALSE
JOIN pg_catalog.pg_class as cl ON cl.oid=at.attrelid
JOIN pg_catalog.pg_namespace as nsp ON nsp.oid=cl.relnamespace
WHERE
{% if obj_id %}
attrelid={{obj_id}}::oid AND
{% elif table_name and table_nspname %}
cl.relname={{table_name|qtLiteral(conn)}} AND nsp.nspname={{table_nspname|qtLiteral(conn)}} AND
{% endif %}
at.attnum > 0
AND at.attisdropped = FALSE

View File

@ -1,8 +1,19 @@
{# ============= Fetch the primary keys for given object id ============= #}
{% if obj_id %}
SELECT at.attname, at.attnum, ty.typname
FROM pg_catalog.pg_attribute at LEFT JOIN pg_catalog.pg_type ty ON (ty.oid = at.atttypid)
WHERE attrelid={{obj_id}}::oid AND attnum = ANY (
(SELECT con.conkey FROM pg_catalog.pg_class rel LEFT OUTER JOIN pg_catalog.pg_constraint con ON con.conrelid=rel.oid
AND con.contype='p' WHERE rel.relkind IN ('r','s','t') AND rel.oid = ({{obj_id}})::oid)::oid[])
JOIN pg_catalog.pg_class as cl ON cl.oid=AT.attrelid
JOIN pg_catalog.pg_namespace as nsp ON nsp.oid=cl.relnamespace
WHERE
{% if obj_id %}
attrelid={{obj_id}}::oid AND
{% elif table_name and table_nspname %}
cl.relname = {{table_name|qtLiteral(conn)}} AND nsp.nspname={{table_nspname|qtLiteral(conn)}} AND
{% endif %}
attnum = ANY (
(SELECT con.conkey FROM pg_catalog.pg_class LEFT OUTER JOIN pg_catalog.pg_constraint con ON con.conrelid=rel.oid
JOIN pg_catalog.pg_namespace as nsp ON nsp.oid=REL.relnamespace
AND con.contype='p' WHERE rel.relkind IN ('r','s','t') AND
{% if obj_id %}
rel.oid = ({{obj_id}})::oid
{% elif table_name and table_nspname%}
rel.relname = {{table_name|qtLiteral(conn)}} AND nsp.nspname={{table_nspname|qtLiteral(conn)}}
{% endif %})::oid[])

View File

@ -16,19 +16,29 @@ from flask_babel import gettext
from pgadmin.utils.exception import ExecuteError, ObjectGone
def get_columns_types(is_query_tool, columns_info, table_oid, conn, has_oids):
def get_columns_types(is_query_tool, columns_info, table_oid, conn, has_oids,
table_name=None, table_nspname=None):
nodes_sqlpath = 'columns/sql/#{0}#'.format(conn.manager.version)
param = {
'has_oids': has_oids,
}
if table_name and table_nspname:
param.update({
'table_name': table_name,
'table_nspname': table_nspname,
})
else:
param.update({
'tid': table_oid
})
query = render_template(
"/".join([nodes_sqlpath, 'nodes.sql']),
tid=table_oid,
has_oids=has_oids,
conn=conn
conn=conn,
**param
)
colst, rset = conn.execute_2darray(query)
# If no record found consider table is deleted, raise error
if len(rset['rows']) == 0:
raise ObjectGone(gettext("The specified object could not be found."))
if not colst:
raise ExecuteError(rset)