~ubuntu-branches/ubuntu/quantal/mysql-workbench/quantal

« back to all changes in this revision

Viewing changes to modules/db.mysql.sqlparser/src/mysql_sql_inserts_loader.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2012-03-01 21:57:30 UTC
  • Revision ID: package-import@ubuntu.com-20120301215730-o7y8av8y38n162ro
Tags: upstream-5.2.38+dfsg
ImportĀ upstreamĀ versionĀ 5.2.38+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License as
 
6
 * published by the Free Software Foundation; version 2 of the
 
7
 * License.
 
8
 * 
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
12
 * GNU General Public License for more details.
 
13
 * 
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
17
 * 02110-1301  USA
 
18
 */
 
19
 
 
20
 
 
21
#include "stdafx.h"
 
22
 
 
23
#include "mysql_sql_inserts_loader.h"
 
24
#include "mysql_sql_parser_utils.h"
 
25
#include <boost/foreach.hpp>
 
26
 
 
27
 
 
28
using namespace grt;
 
29
 
 
30
 
 
31
#define NULL_STATE_KEEPER Null_state_keeper _nsk(this);
 
32
 
 
33
 
 
34
Mysql_sql_inserts_loader::Mysql_sql_inserts_loader(grt::GRT *grt)
 
35
:
 
36
Sql_parser_base(grt),
 
37
Mysql_sql_parser_base(grt)
 
38
{
 
39
  NULL_STATE_KEEPER
 
40
}
 
41
 
 
42
 
 
43
void Mysql_sql_inserts_loader::load(const std::string &sql, const std::string &schema_name)
 
44
{
 
45
  NULL_STATE_KEEPER
 
46
 
 
47
  _schema_name= schema_name;
 
48
  _process_sql_statement= boost::bind(&Mysql_sql_inserts_loader::process_sql_statement, this, _1);
 
49
 
 
50
  Mysql_sql_parser_fe sql_parser_fe(_grtm->get_grt());
 
51
  sql_parser_fe.ignore_dml= false;
 
52
  Mysql_sql_parser_base::parse_sql_script(sql_parser_fe, sql.c_str());
 
53
}
 
54
 
 
55
 
 
56
int Mysql_sql_inserts_loader::process_sql_statement(const SqlAstNode *tree)
 
57
{
 
58
  if (tree)
 
59
  {
 
60
    if (const SqlAstNode *item= tree->subitem(sql::_statement, sql::_insert))
 
61
      process_insert_statement(item);
 
62
  }
 
63
 
 
64
  return 0; // error count
 
65
}
 
66
 
 
67
 
 
68
Mysql_sql_inserts_loader::Parse_result
 
69
Mysql_sql_inserts_loader::process_insert_statement(const SqlAstNode *tree)
 
70
{
 
71
  std::string schema_name= _schema_name;
 
72
  std::string table_name;
 
73
  Strings fields_names;
 
74
  Strings fields_values;
 
75
  std::vector<bool> null_fields;
 
76
 
 
77
 
 
78
  const SqlAstNode *insert_field_spec= tree->subitem(sql::_insert_field_spec);
 
79
  if (insert_field_spec)
 
80
  {
 
81
    // schema & table name
 
82
    {
 
83
      const SqlAstNode *table_ident= tree->subitem(sql::_insert2, sql::_insert_table, sql::_table_ident);
 
84
      process_obj_full_name_item(table_ident, schema_name, table_name);
 
85
    }
 
86
 
 
87
    // fields names
 
88
    {
 
89
      const SqlAstNode *fields= insert_field_spec->subitem(sql::_fields);
 
90
      if (fields)
 
91
      {
 
92
        BOOST_FOREACH (const SqlAstNode *item, *fields->subitems())
 
93
          if (item->name_equals(sql::_insert_ident))
 
94
            fields_names.push_back(item->restore_sql_text(_sql_statement));
 
95
      }
 
96
    }
 
97
 
 
98
    // fields values
 
99
    {
 
100
      fields_values.reserve(fields_names.size());
 
101
      null_fields.reserve(fields_names.size());
 
102
 
 
103
      const SqlAstNode *insert_values= insert_field_spec->subitem(sql::_insert_values, sql::_values_list);
 
104
      BOOST_FOREACH (const SqlAstNode *item, *insert_values->subitems())
 
105
      {
 
106
        if (item->name_equals(sql::_no_braces))
 
107
        {
 
108
          fields_values.clear();
 
109
          null_fields.clear();
 
110
          
 
111
          const SqlAstNode *values= item->subitem(sql::_opt_values, sql::_values);
 
112
          BOOST_FOREACH (const SqlAstNode *item, *values->subitems())
 
113
          {
 
114
            if (item->name_equals(sql::_expr_or_default))
 
115
            {
 
116
              std::string value;
 
117
              bool is_field_null= false;
 
118
              if (const SqlAstNode *item1= item->subitem(sql::_expr))
 
119
                if (1 == item1->subitems()->size())
 
120
                  if (const SqlAstNode *item2= item1->subitem(sql::_bool_pri))
 
121
                    if (1 == item2->subitems()->size())
 
122
                      if (const SqlAstNode *item3= item2->subitem(sql::_predicate))
 
123
                        if (1 == item3->subitems()->size())
 
124
                          if (const SqlAstNode *item4= item3->subitem(sql::_bit_expr))
 
125
                            if (1 == item4->subitems()->size())
 
126
                              if (const SqlAstNode *item5= item4->subitem(sql::_simple_expr))
 
127
                                if (1 == item5->subitems()->size())
 
128
                                  if (const SqlAstNode *item6= item5->subitem(sql::_literal))
 
129
                                    if (1 == item6->subitems()->size())
 
130
                                      if (/*const SqlAstNode *item7=*/ item6->subitem(sql::_NULL_SYM))
 
131
                                        is_field_null= true;
 
132
 
 
133
              if (!is_field_null)
 
134
              {
 
135
                value= item->restore_sql_text(_sql_statement);
 
136
                if (1 < value.size())
 
137
                {
 
138
                  switch (value[0])
 
139
                  {
 
140
                  case '\'':
 
141
                  case '"':
 
142
                    value= value.substr(1, value.size()-2);
 
143
                    break;
 
144
                  default:
 
145
                    static const std::string func_call_seq= "\\func ";
 
146
                    if (value[0] == '\\')
 
147
                    {
 
148
                      if ((value.size() > func_call_seq.size()) && (value.compare(0, func_call_seq.size(), func_call_seq) == 0))
 
149
                      {
 
150
                        value= '\\' + value;
 
151
                      }
 
152
                    }
 
153
                    else
 
154
                    {
 
155
                      bool is_expression= false;
 
156
                      for (std::string::iterator i= value.begin(), i_end= value.end(); i != i_end; ++i)
 
157
                      {
 
158
                        if (!std::isdigit(*i) && (*i != '.') && (*i != ','))
 
159
                        {
 
160
                          is_expression= true;
 
161
                          break;
 
162
                        }
 
163
                      }
 
164
                      if (is_expression)
 
165
                      {
 
166
                        value= func_call_seq + value;
 
167
                      }
 
168
                    }
 
169
                    break;
 
170
                  }
 
171
                }
 
172
              }
 
173
 
 
174
              fields_values.push_back(value);
 
175
              null_fields.push_back(is_field_null);
 
176
            }
 
177
          }
 
178
 
 
179
          const std::pair<std::string, std::string> schema_table= make_pair(schema_name, table_name);
 
180
          _process_insert(sql_statement(), schema_table, fields_names, fields_values, null_fields);
 
181
        }
 
182
      }
 
183
    }
 
184
  }
 
185
 
 
186
  return pr_processed;
 
187
}