'Runs arbitrary sql and returns and json'

@has_access_api
@expose(u'/sql_json/', methods=[u'POST', u'GET'])
@log_this
def sql_json(self):

    async = (request.form.get(u'runAsync') == u'true')
    sql = request.form.get(u'sql')
    database_id = request.form.get(u'database_id')
    schema = (request.form.get(u'schema') or None)
    session = db.session()
    mydb = session.query(models.Database).filter_by(id=database_id).one()
    if (not mydb):
        json_error_response(u'Database    with    id    {}    is    missing.'.format(database_id))
    rejected_tables = self.rejected_datasources(sql, mydb, schema)
    if rejected_tables:
        return json_error_response(get_datasource_access_error_msg(u'{}'.format(rejected_tables)))
    session.commit()
    select_as_cta = (request.form.get(u'select_as_cta') == u'true')
    tmp_table_name = request.form.get(u'tmp_table_name')
    if (select_as_cta and mydb.force_ctas_schema):
        tmp_table_name = u'{}.{}'.format(mydb.force_ctas_schema, tmp_table_name)
    query = Query(database_id=int(database_id), limit=int(app.config.get(u'SQL_MAX_ROW', None)), sql=sql, schema=schema, select_as_cta=(request.form.get(u'select_as_cta') == u'true'), start_time=utils.now_as_float(), tab_name=request.form.get(u'tab'), status=(QueryStatus.PENDING if async else QueryStatus.RUNNING), sql_editor_id=request.form.get(u'sql_editor_id'), tmp_table_name=tmp_table_name, user_id=int(g.user.get_id()), client_id=request.form.get(u'client_id'))
    session.add(query)
    session.flush()
    query_id = query.id
    session.commit()
    if (not query_id):
        raise Exception(u'Query    record    was    not    created    as    expected.')
    logging.info(u'Triggering    query_id:    {}'.format(query_id))
    if async:
        logging.info(u'Running    query    on    a    Celery    worker')
        try:
            sql_lab.get_sql_results.delay(query_id=query_id, return_results=False, store_results=(not query.select_as_cta))
        except Exception as e:
            logging.exception(e)
            msg = u'Failed    to    start    remote    query    on    a    worker.    Tell    your    administrator    to    verify    the    availability    of    the    message    queue.'
            query.status = QueryStatus.FAILED
            query.error_message = msg
            session.commit()
            return json_error_response(u'{}'.format(msg))
        resp = json_success(json.dumps({u'query': query.to_dict()}, default=utils.json_int_dttm_ser, allow_nan=False), status=202)
        session.commit()
        return resp
    try:
        SQLLAB_TIMEOUT = config.get(u'SQLLAB_TIMEOUT')
        with utils.timeout(seconds=SQLLAB_TIMEOUT, error_message=u'The    query    exceeded    the    {SQLLAB_TIMEOUT}    seconds    timeout.    You    may    want    to    run    your    query    as    a    `CREATE    TABLE    AS`    to    prevent    timeouts.'.format(**locals())):
            data = sql_lab.get_sql_results(query_id=query_id, return_results=True)
            payload = json.dumps(data, default=utils.json_iso_dttm_ser)
    except Exception as e:
        logging.exception(e)
        return json_error_response(u'{}'.format(e))
    if (data.get(u'status') == QueryStatus.FAILED):
        return json_error_response(payload)
    return json_success(payload)
