[sql lab] option to disable cross schema search (#4551)

* [sql lab] disable cross schema search

This is killing our metastore as people type it emits large
all-table-dump as they hit the keystroke. It never returns as it times
out and hammers the poor metastore.

Also some improvements around the disabling the table select on the left
panel and having the table name not be sticky.

* typo
This commit is contained in:
Maxime Beauchemin 2018-03-09 14:54:39 -08:00 committed by GitHub
parent 34a081b926
commit d522292b01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 59 additions and 4 deletions

View File

@ -241,6 +241,7 @@ class SqlEditor extends React.PureComponent {
>
<SqlEditorLeftBar
height={height}
database={this.props.database}
queryEditor={this.props.queryEditor}
tables={this.props.tables}
actions={this.props.actions}

View File

@ -16,6 +16,7 @@ const propTypes = {
height: PropTypes.number.isRequired,
tables: PropTypes.array,
actions: PropTypes.object,
database: PropTypes.object,
};
const defaultProps = {
@ -139,6 +140,14 @@ class SqlEditorLeftBar extends React.PureComponent {
render() {
const shouldShowReset = window.location.search === '?reset=1';
const tableMetaDataHeight = this.props.height - 130; // 130 is the height of the selects above
let tableSelectPlaceholder;
let tableSelectDisabled = false;
if (this.props.database && this.props.database.allow_multi_schema_metadata_fetch) {
tableSelectPlaceholder = t('Type to search ...');
} else {
tableSelectPlaceholder = t('Select table ');
tableSelectDisabled = true;
}
return (
<div className="clearfix sql-toolbar">
<div>
@ -186,7 +195,6 @@ class SqlEditorLeftBar extends React.PureComponent {
name="select-table"
ref="selectTable"
isLoading={this.state.tableLoading}
value={this.state.tableName}
placeholder={t('Add a table (%s)', this.state.tableOptions.length)}
autosize={false}
onChange={this.changeTable.bind(this)}
@ -199,8 +207,8 @@ class SqlEditorLeftBar extends React.PureComponent {
async
name="async-select-table"
ref="selectTable"
value={this.state.tableName}
placeholder={t('Type to search ...')}
placeholder={tableSelectPlaceholder}
disabled={tableSelectDisabled}
autosize={false}
onChange={this.changeTable.bind(this)}
loadOptions={this.getTableNamesBySubStr.bind(this)}

View File

@ -23,6 +23,7 @@ describe('SqlEditorLeftBar', () => {
},
tables: [table],
queryEditor: defaultQueryEditor,
database: {},
height: 0,
};

View File

@ -51,6 +51,7 @@ describe('TabbedSqlEditors', () => {
tabHistory: initialState.tabHistory,
editorHeight: '',
getHeight: () => ('100px'),
database: {},
};
const getWrapper = () => (
shallow(<TabbedSqlEditors {...mockedProps} />, {

View File

@ -0,0 +1,30 @@
"""allow_multi_schema_metadata_fetch
Revision ID: e68c4473c581
Revises: e866bd2d4976
Create Date: 2018-03-06 12:24:30.896293
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'e68c4473c581'
down_revision = 'e866bd2d4976'
def upgrade():
op.add_column(
'dbs',
sa.Column(
'allow_multi_schema_metadata_fetch',
sa.Boolean(),
nullable=True,
default=True,
),
)
def downgrade():
op.drop_column('dbs', 'allow_multi_schema_metadata_fetch')

View File

@ -567,6 +567,7 @@ class Database(Model, AuditMixinNullable, ImportMixin):
allow_ctas = Column(Boolean, default=False)
allow_dml = Column(Boolean, default=False)
force_ctas_schema = Column(String(250))
allow_multi_schema_metadata_fetch = Column(Boolean, default=True)
extra = Column(Text, default=textwrap.dedent("""\
{
"metadata_params": {},
@ -593,6 +594,8 @@ class Database(Model, AuditMixinNullable, ImportMixin):
return {
'name': self.database_name,
'backend': self.backend,
'allow_multi_schema_metadata_fetch':
self.allow_multi_schema_metadata_fetch,
}
@property
@ -736,6 +739,8 @@ class Database(Model, AuditMixinNullable, ImportMixin):
def all_table_names(self, schema=None, force=False):
if not schema:
if not self.allow_multi_schema_metadata_fetch:
return []
tables_dict = self.db_engine_spec.fetch_result_sets(
self, 'table', force=force)
return tables_dict.get('', [])
@ -744,6 +749,8 @@ class Database(Model, AuditMixinNullable, ImportMixin):
def all_view_names(self, schema=None, force=False):
if not schema:
if not self.allow_multi_schema_metadata_fetch:
return []
views_dict = self.db_engine_spec.fetch_result_sets(
self, 'view', force=force)
return views_dict.get('', [])

View File

@ -199,7 +199,9 @@ class DatabaseView(SupersetModelView, DeleteMixin, YamlExportMixin): # noqa
add_columns = [
'database_name', 'sqlalchemy_uri', 'cache_timeout', 'extra',
'expose_in_sqllab', 'allow_run_sync', 'allow_run_async',
'allow_ctas', 'allow_dml', 'force_ctas_schema', 'impersonate_user']
'allow_ctas', 'allow_dml', 'force_ctas_schema', 'impersonate_user',
'allow_multi_schema_metadata_fetch',
]
search_exclude_columns = (
'password', 'tables', 'created_by', 'changed_by', 'queries',
'saved_queries')
@ -258,6 +260,10 @@ class DatabaseView(SupersetModelView, DeleteMixin, YamlExportMixin): # noqa
'If Hive and hive.server2.enable.doAs is enabled, will run the queries as '
'service account, but impersonate the currently logged on user '
'via hive.server2.proxy.user property.'),
'allow_multi_schema_metadata_fetch': _(
'Allow SQL Lab to fetch a list of all tables and all views across '
'all database schemas. For large data warehouse with thousands of '
'tables, this can be expensive and put strain on the system.'),
}
label_columns = {
'expose_in_sqllab': _('Expose in SQL Lab'),
@ -314,6 +320,7 @@ class DatabaseAsync(DatabaseView):
'id', 'database_name',
'expose_in_sqllab', 'allow_ctas', 'force_ctas_schema',
'allow_run_async', 'allow_run_sync', 'allow_dml',
'allow_multi_schema_metadata_fetch',
]