~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/statement/create_table.cc

  • Committer: Brian Aker
  • Date: 2010-12-27 20:04:50 UTC
  • mto: (2060.2.1 clean)
  • mto: This revision was merged to the branch mainline in revision 2063.
  • Revision ID: brian@tangent.org-20101227200450-dmxpemwyfmlinlnm
Merge in first pass.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
  TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
37
37
  TableList *all_tables= session->lex->query_tables;
38
38
  assert(first_table == all_tables && first_table != 0);
39
 
  Select_Lex *select_lex= &session->lex->select_lex;
40
 
  Select_Lex_Unit *unit= &session->lex->unit;
41
39
  bool need_start_waiting= false;
42
 
  bool res= false;
43
 
  bool link_to_local= false;
44
 
  bool lex_identified_temp_table= 
45
 
    create_table_message.type() == message::Table::TEMPORARY;
 
40
  lex_identified_temp_table= create_table_message.type() == message::Table::TEMPORARY;
46
41
 
47
42
  if (is_engine_set)
48
43
  {
77
72
    }
78
73
  }
79
74
  /* Skip first table, which is the table we are creating */
80
 
  TableList *create_table_list= session->lex->unlink_first_table(&link_to_local);
81
 
  TableList *select_tables= session->lex->query_tables;
 
75
  create_table_list= session->lex->unlink_first_table(&link_to_local);
82
76
 
83
77
  drizzled::message::init(create_table_message, create_table_message.name(), create_table_list->getSchemaName(), create_info.db_type->getName());
84
78
 
116
110
    return true;
117
111
  }
118
112
 
119
 
  if (select_lex->item_list.elements)           // With select
120
 
  {
121
 
    select_result *result;
122
 
 
123
 
    select_lex->options|= SELECT_NO_UNLOCK;
124
 
    unit->set_limit(select_lex);
125
 
 
126
 
    if (not lex_identified_temp_table)
127
 
    {
128
 
      session->lex->link_first_table_back(create_table_list, link_to_local);
129
 
      create_table_list->setCreate(true);
130
 
    }
131
 
 
132
 
    if (not (res= session->openTablesLock(session->lex->query_tables)))
133
 
    {
134
 
      /*
135
 
         Is table which we are changing used somewhere in other parts
136
 
         of query
137
 
       */
 
113
  bool res= executeInner(new_table_identifier);
 
114
 
 
115
  /*
 
116
    Release the protection against the global read lock and wake
 
117
    everyone, who might want to set a global read lock.
 
118
  */
 
119
  session->startWaitingGlobalReadLock();
 
120
 
 
121
  return res;
 
122
}
 
123
 
 
124
bool statement::CreateTable::executeInner(TableIdentifier::const_reference new_table_identifier)
 
125
{
 
126
  bool res= false;
 
127
  Select_Lex *select_lex= &session->lex->select_lex;
 
128
  TableList *select_tables= session->lex->query_tables;
 
129
 
 
130
  do {
 
131
    if (select_lex->item_list.elements)         // With select
 
132
    {
 
133
      Select_Lex_Unit *unit= &session->lex->unit;
 
134
      select_result *result;
 
135
 
 
136
      select_lex->options|= SELECT_NO_UNLOCK;
 
137
      unit->set_limit(select_lex);
 
138
 
138
139
      if (not lex_identified_temp_table)
139
140
      {
140
 
        TableList *duplicate= NULL;
 
141
        session->lex->link_first_table_back(create_table_list, link_to_local);
 
142
        create_table_list->setCreate(true);
 
143
      }
 
144
 
 
145
      if (not (res= session->openTablesLock(session->lex->query_tables)))
 
146
      {
 
147
        /*
 
148
          Is table which we are changing used somewhere in other parts
 
149
          of query
 
150
        */
 
151
        if (not lex_identified_temp_table)
 
152
        {
 
153
          TableList *duplicate= NULL;
 
154
          create_table_list= session->lex->unlink_first_table(&link_to_local);
 
155
 
 
156
          if ((duplicate= unique_table(create_table_list, select_tables)))
 
157
          {
 
158
            my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table_list->alias);
 
159
            /* put tables back for PS rexecuting */
 
160
            session->lex->link_first_table_back(create_table_list, link_to_local);
 
161
 
 
162
            res= true;
 
163
            break;
 
164
          }
 
165
        }
 
166
 
 
167
        /*
 
168
          select_create is currently not re-execution friendly and
 
169
          needs to be created for every execution of a PS/SP.
 
170
        */
 
171
        if ((result= new select_create(create_table_list,
 
172
                                       is_if_not_exists,
 
173
                                       &create_info,
 
174
                                       create_table_message,
 
175
                                       &alter_info,
 
176
                                       select_lex->item_list,
 
177
                                       session->lex->duplicates,
 
178
                                       session->lex->ignore,
 
179
                                       select_tables,
 
180
                                       new_table_identifier)))
 
181
        {
 
182
          /*
 
183
            CREATE from SELECT give its Select_Lex for SELECT,
 
184
            and item_list belong to SELECT
 
185
          */
 
186
          res= handle_select(session, session->lex, result, 0);
 
187
          delete result;
 
188
        }
 
189
      }
 
190
      else if (not lex_identified_temp_table)
 
191
      {
141
192
        create_table_list= session->lex->unlink_first_table(&link_to_local);
142
 
        if ((duplicate= unique_table(create_table_list, select_tables)))
143
 
        {
144
 
          my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table_list->alias);
145
 
          /*
146
 
             Release the protection against the global read lock and wake
147
 
             everyone, who might want to set a global read lock.
148
 
           */
149
 
          session->startWaitingGlobalReadLock();
150
 
          /* put tables back for PS rexecuting */
151
 
          session->lex->link_first_table_back(create_table_list, link_to_local);
152
 
 
153
 
          return true;
154
 
        }
155
 
      }
156
 
 
157
 
      /*
158
 
         select_create is currently not re-execution friendly and
159
 
         needs to be created for every execution of a PS/SP.
160
 
       */
161
 
      if ((result= new select_create(create_table_list,
162
 
                                     is_if_not_exists,
163
 
                                     &create_info,
164
 
                                     create_table_message,
165
 
                                     &alter_info,
166
 
                                     select_lex->item_list,
167
 
                                     session->lex->duplicates,
168
 
                                     session->lex->ignore,
169
 
                                     select_tables,
170
 
                                     new_table_identifier)))
171
 
      {
172
 
        /*
173
 
           CREATE from SELECT give its Select_Lex for SELECT,
174
 
           and item_list belong to SELECT
175
 
         */
176
 
        res= handle_select(session, session->lex, result, 0);
177
 
        delete result;
178
 
      }
179
 
    }
180
 
    else if (not lex_identified_temp_table)
181
 
    {
182
 
      create_table_list= session->lex->unlink_first_table(&link_to_local);
183
 
    }
184
 
  }
185
 
  else
186
 
  {
187
 
    /* regular create */
188
 
    if (is_create_table_like)
189
 
    {
190
 
      res= create_like_table(session, 
191
 
                                   new_table_identifier,
192
 
                                   create_table_list, 
193
 
                                   select_tables,
194
 
                                   create_table_message,
195
 
                                   is_if_not_exists,
196
 
                                   is_engine_set);
 
193
      }
197
194
    }
198
195
    else
199
196
    {
200
 
 
201
 
      for (int32_t x= 0; x < alter_info.alter_proto.added_field_size(); x++)
202
 
      {
203
 
        message::Table::Field *field= create_table_message.add_field();
204
 
 
205
 
        *field= alter_info.alter_proto.added_field(x);
206
 
      }
207
 
 
208
 
      res= create_table(session, 
209
 
                              new_table_identifier,
210
 
                              &create_info,
211
 
                              create_table_message,
212
 
                              &alter_info, 
213
 
                              false, 
214
 
                              0,
215
 
                              is_if_not_exists);
216
 
    }
217
 
 
218
 
    if (not res)
219
 
    {
220
 
      session->my_ok();
221
 
    }
222
 
  }
223
 
 
224
 
  /*
225
 
     Release the protection against the global read lock and wake
226
 
     everyone, who might want to set a global read lock.
227
 
   */
228
 
  session->startWaitingGlobalReadLock();
 
197
      /* regular create */
 
198
      if (is_create_table_like)
 
199
      {
 
200
        res= create_like_table(session, 
 
201
                               new_table_identifier,
 
202
                               create_table_list, 
 
203
                               select_tables,
 
204
                               create_table_message,
 
205
                               is_if_not_exists,
 
206
                               is_engine_set);
 
207
      }
 
208
      else
 
209
      {
 
210
 
 
211
        for (int32_t x= 0; x < alter_info.alter_proto.added_field_size(); x++)
 
212
        {
 
213
          message::Table::Field *field= create_table_message.add_field();
 
214
 
 
215
          *field= alter_info.alter_proto.added_field(x);
 
216
        }
 
217
 
 
218
        res= create_table(session, 
 
219
                          new_table_identifier,
 
220
                          &create_info,
 
221
                          create_table_message,
 
222
                          &alter_info, 
 
223
                          false, 
 
224
                          0,
 
225
                          is_if_not_exists);
 
226
      }
 
227
 
 
228
      if (not res)
 
229
      {
 
230
        session->my_ok();
 
231
      }
 
232
    }
 
233
  } while (0);
229
234
 
230
235
  return res;
231
236
}