def sql_to_sql_spans(sql_string, table_schemas=None, lowercase=True):
  """Parse sql_string to a list of SqlSpan tuples.

  Args:
    sql_string: The SQL query to convert.
    table_schemas: List of TableSchema tuples.
    lowercase: Whether to lowercase the SQL query.

  Returns:
    List of SqlSpan tuples.

  Raises:
    ParseError: If the SQL query can't be parsed for unexpected reason.
    UnsupportedSqlError: SQL query is not supported by Abstract SQL.
  """
  if sql_string in BAD_SQL:
    raise UnsupportedSqlError('Query matched list of malformed queries.')
  # Get the root sqlparse.sql.Token for the expression.
  if lowercase:
    sql_string = sql_string.lower()
  sql_string = sql_string.strip()
  sql_string = sql_string.rstrip(';')
  # sqlparse expects value literals to have single quotes.
  sql_string = sql_string.replace('"', '\'')
  # Change FROM clause placeholder to avoid breaking sqlparse.
  has_from_placeholder = FROM_CLAUSE_PLACEHOLDER in sql_string
  if has_from_placeholder:
    sql_string = sql_string.replace(FROM_CLAUSE_PLACEHOLDER, 'from')
  # Parse using sqlparse.
  sqlparse_output = sqlparse.parse(sql_string)
  if not sqlparse_output:
    raise ParseError('sqlparse.parse failed for %s' % sql_string)
  sqlparse_token = sqlparse_output[0]
  flat_tokens = _get_flattened_non_whitespace_tokens(sqlparse_token)
  if has_from_placeholder:
    _replace_from_placeholder(flat_tokens)
  grouped_tokens = _regroup_tokens(flat_tokens)
  sql_spans = []
  _populate_spans_for_statement(grouped_tokens, sql_spans, table_schemas)
  if table_schemas:
    _check_spans_against_schema(sql_spans, table_schemas)
  # Add back placeholder for FROM clause.
  return sql_spans
Parse sql_string to a list of SqlSpan tuples.

  Args:
    sql_string: The SQL query to convert.
    table_schemas: List of TableSchema tuples.
    lowercase: Whether to lowercase the SQL query.

  Returns:
    List of SqlSpan tuples.

  Raises:
    ParseError: If the SQL query can't be parsed for unexpected reason.
    UnsupportedSqlError: SQL query is not supported by Abstract SQL.
  
language/xsp/data_preprocessing/abstract_sql.py