#include "stdafx.h"

#include "mysql_sql_parser_base.h"
#include "mysql_sql_parser_fe.h"
#include "myx_statement_parser.h"


using namespace grt;
using namespace bec;


Mysql_sql_parser_base::Null_state_keeper::~Null_state_keeper()
{
  _sql_parser->_err_msg= std::string();
  _sql_parser->_lineno= 0;
  _sql_parser->_err_tok_line_pos= 0;
  _sql_parser->_err_tok_len= 0;
  _sql_parser->_active_schema= db_mysql_SchemaRef();
  _sql_parser->_catalog= db_mysql_CatalogRef();
  _sql_parser->_splitter= NULL;
  _sql_parser->_process_sql_statement.disconnect();
}
#define NULL_STATE_KEEPER Null_state_keeper _nsk(this);


Mysql_sql_parser_base::Mysql_sql_parser_base(grt::GRT *grt)
:
Sql_parser_base(grt)
{
  NULL_STATE_KEEPER // reset all members to null-values
}


int Mysql_sql_parser_base::parse_sql_script(Mysql_sql_parser_fe &sql_parser_fe, const std::string &sql)
{
  return sql_parser_fe.parse_sql_script(sql, &process_sql_statement, this);
}


int Mysql_sql_parser_base::parse_sql_script_file(Mysql_sql_parser_fe &sql_parser_fe, const std::string &filename)
{
  return sql_parser_fe.parse_sql_script_file(filename, &process_sql_statement, this);
}


int Mysql_sql_parser_base::process_sql_statement(
  void *sql_parser_ptr,
  const MyxStatementParser *splitter,
  const char* sql_statement,
  const MyxSQLTreeItem *tree,
  int lineno,
  int _err_tok_line_pos,
  int _err_tok_len,
  const std::string &err_msg)
{
  Mysql_sql_parser_base *sql_parser= reinterpret_cast <Mysql_sql_parser_base *> (sql_parser_ptr);

  sql_parser->_splitter= splitter;
  sql_parser->_sql_statement= sql_statement;
  sql_parser->_lineno= lineno;
  sql_parser->_err_tok_line_pos= _err_tok_line_pos;
  sql_parser->_err_tok_len= _err_tok_len;
  sql_parser->_err_msg= err_msg;

  return sql_parser->_process_sql_statement(tree);
}


int Mysql_sql_parser_base::total_line_count()
{
  return _splitter->total_line_count();
}


void Mysql_sql_parser_base::report_semantic_error(const MyxSQLTreeItem *item, const std::string &err_msg, int entry_type)
{
  int lineno= -1;
  int token_line_pos= 0;
  int token_len= 0;
  if (item)
    Mysql_sql_parser_fe::determine_token_position(item, _splitter, _sql_statement.c_str(), lineno, token_line_pos, token_len);
  report_sql_error(lineno, true, token_line_pos, token_len, err_msg, entry_type, "");
}


void Mysql_sql_parser_base::process_obj_full_name_item(const MyxSQLTreeItem *item, std::string &schema_name, std::string &obj_name)
{
  if (!item)
    return;

  if (3 == item->subitems()->size()) // ident.ident
    schema_name= (*item->subitems()->begin())->value();
  obj_name= (*item->subitems()->rbegin())->value();
}
