Skip to content

Commit

Permalink
fix(sql lab): deleting the last saved query or the last executed from…
Browse files Browse the repository at this point in the history
… history (#19225)

* fix: fix issue when deleting the last saved query or the last executed query

* merge migration
  • Loading branch information
diegomedina248 committed Mar 17, 2022
1 parent 51061f0 commit aa5c80b
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""add_on_saved_query_delete_tab_state_null_constraint"
Revision ID: 58df9d617f14
Revises: 6766938c6065
Create Date: 2022-03-16 23:24:40.278937
"""

# revision identifiers, used by Alembic.
revision = "58df9d617f14"
down_revision = "6766938c6065"

import sqlalchemy as sa
from alembic import op

from superset.utils.core import generic_find_fk_constraint_name


def upgrade():
bind = op.get_bind()
insp = sa.engine.reflection.Inspector.from_engine(bind)

with op.batch_alter_table("tab_state") as batch_op:
batch_op.drop_constraint(
generic_find_fk_constraint_name("tab_state", {"id"}, "saved_query", insp),
type_="foreignkey",
)

batch_op.create_foreign_key(
"saved_query_id",
"saved_query",
["saved_query_id"],
["id"],
ondelete="SET NULL",
)


def downgrade():
bind = op.get_bind()
insp = sa.engine.reflection.Inspector.from_engine(bind)

with op.batch_alter_table("tab_state") as batch_op:
batch_op.drop_constraint(
generic_find_fk_constraint_name("tab_state", {"id"}, "saved_query", insp),
type_="foreignkey",
)

batch_op.create_foreign_key(
"saved_query_id", "saved_query", ["saved_query_id"], ["id"],
)
4 changes: 3 additions & 1 deletion superset/models/sql_lab.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,9 @@ class TabState(Model, AuditMixinNullable, ExtraJSONMixin):
hide_left_bar = Column(Boolean, default=False)

# any saved queries that are associated with the Tab State
saved_query_id = Column(Integer, ForeignKey("saved_query.id"), nullable=True)
saved_query_id = Column(
Integer, ForeignKey("saved_query.id", ondelete="SET NULL"), nullable=True
)
saved_query = relationship("SavedQuery", foreign_keys=[saved_query_id])

def to_dict(self) -> Dict[str, Any]:
Expand Down
24 changes: 24 additions & 0 deletions superset/views/sql_lab.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder.security.decorators import has_access, has_access_api
from flask_babel import lazy_gettext as _
from sqlalchemy import and_

from superset import db, is_feature_enabled
from superset.constants import MODEL_VIEW_RW_METHOD_PERMISSION_MAP, RouteMethod
Expand Down Expand Up @@ -228,6 +229,29 @@ def migrate_query( # pylint: disable=no-self-use
def delete_query( # pylint: disable=no-self-use
self, tab_state_id: int, client_id: str
) -> FlaskResponse:
# Before deleting the query, ensure it's not tied to any
# active tab as the last query. If so, replace the query
# with the latest one created in that tab
tab_state_query = db.session.query(TabState).filter_by(
id=tab_state_id, latest_query_id=client_id
)
if tab_state_query.count():
query = (
db.session.query(Query)
.filter(
and_(
Query.client_id != client_id,
Query.user_id == g.user.get_id(),
Query.sql_editor_id == str(tab_state_id),
),
)
.order_by(Query.id.desc())
.first()
)
tab_state_query.update(
{"latest_query_id": query.client_id if query else None}
)

db.session.query(Query).filter_by(
client_id=client_id,
user_id=g.user.get_id(),
Expand Down

0 comments on commit aa5c80b

Please sign in to comment.