/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is also distributed with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have included with MySQL. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ /** @file sql_data_change.cc Contains classes representing SQL-data change statements. Currently the only data change functionality implemented here is function defaults. */ #include "sql_data_change.h" #include "sql_class.h" /** Allocates and initializes a MY_BITMAP bitmap, containing one bit per column in the table. The table THD's MEM_ROOT is used to allocate memory. @param table The table whose columns should be used as a template for the bitmap. @param[out] bitmap A pointer to the allocated bitmap. @retval false Success. @retval true Memory allocation error. */ static bool allocate_column_bitmap(TABLE *table, MY_BITMAP **bitmap) { DBUG_ENTER("allocate_column_bitmap"); const uint number_bits= table->s->fields; MY_BITMAP *the_struct; my_bitmap_map *the_bits; DBUG_ASSERT(current_thd == table->in_use); if (multi_alloc_root(table->in_use->mem_root, &the_struct, sizeof(MY_BITMAP), &the_bits, bitmap_buffer_size(number_bits), NULL) == NULL) DBUG_RETURN(true); if (bitmap_init(the_struct, the_bits, number_bits, FALSE) != 0) DBUG_RETURN(true); *bitmap= the_struct; DBUG_RETURN(false); } bool COPY_INFO::get_function_default_columns(TABLE *table) { DBUG_ENTER("COPY_INFO::get_function_default_columns"); if (m_function_default_columns != NULL) DBUG_RETURN(false); if (allocate_column_bitmap(table, &m_function_default_columns)) DBUG_RETURN(true); if (!m_manage_defaults) DBUG_RETURN(false); // leave bitmap full of zeroes /* Find columns with function default on insert or update, mark them in bitmap. */ for (uint i= 0; i < table->s->fields; ++i) { Field *f= table->field[i]; if ((m_optype == INSERT_OPERATION && f->has_insert_default_function()) || (m_optype == UPDATE_OPERATION && f->has_update_default_function())) bitmap_set_bit(m_function_default_columns, f->field_index); } if (bitmap_is_clear_all(m_function_default_columns)) DBUG_RETURN(false); // no bit set, next step unneeded /* Remove explicitly assigned columns from the bitmap. The assignment target (lvalue) may not always be a column (Item_field), e.g. we could be inserting into a view, whose column is actually a base table's column converted with COLLATE: the lvalue would then be an Item_func_set_collation. If the lvalue is an expression tree, we clear all columns in it from the bitmap. */ List *all_changed_columns[2]= { m_changed_columns, m_changed_columns2 }; for (uint i= 0; i < 2; i++) { if (all_changed_columns[i] != NULL) { List_iterator lvalue_it(*all_changed_columns[i]); Item *lvalue_item; while ((lvalue_item= lvalue_it++) != NULL) lvalue_item->walk(&Item::remove_column_from_bitmap, true, reinterpret_cast(m_function_default_columns)); } } DBUG_RETURN(false); } void COPY_INFO::set_function_defaults(TABLE *table) { DBUG_ENTER("COPY_INFO::set_function_defaults"); DBUG_ASSERT(m_function_default_columns != NULL); /* Quick reject test for checking the case when no defaults are invoked. */ if (bitmap_is_clear_all(m_function_default_columns)) DBUG_VOID_RETURN; for (uint i= 0; i < table->s->fields; ++i) if (bitmap_is_set(m_function_default_columns, i)) { DBUG_ASSERT(bitmap_is_set(table->write_set, i)); switch (m_optype) { case INSERT_OPERATION: table->field[i]->evaluate_insert_default_function(); break; case UPDATE_OPERATION: table->field[i]->evaluate_update_default_function(); break; } } DBUG_VOID_RETURN; } bool COPY_INFO::ignore_last_columns(TABLE *table, uint count) { if (get_function_default_columns(table)) return true; for (uint i= 0; i < count; i++) bitmap_clear_bit(m_function_default_columns, table->s->fields - 1 - i); return false; }