diff options
author | Nirbhay Choubey <nirbhay@mariadb.com> | 2016-04-25 11:06:16 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@mariadb.com> | 2016-04-25 11:06:16 -0400 |
commit | 4f1c1975b5f3d98321ad9e5b6f952c166d3606a7 (patch) | |
tree | 50c83e846f4a4d538b94bce41201d4a2847a852d /sql | |
parent | 9c89b84d46e0645820acb9e3cc339af10c68cfb7 (diff) | |
parent | 0991e19e9d38f7475390276c0557c2390e4d93c9 (diff) | |
download | mariadb-git-4f1c1975b5f3d98321ad9e5b6f952c166d3606a7.tar.gz |
Merge tag 'mariadb-5.5.49' into 5.5-galera
Diffstat (limited to 'sql')
-rw-r--r-- | sql/gcalc_slicescan.cc | 266 | ||||
-rw-r--r-- | sql/gcalc_slicescan.h | 22 | ||||
-rw-r--r-- | sql/gcalc_tools.cc | 6 | ||||
-rw-r--r-- | sql/handler.cc | 4 | ||||
-rw-r--r-- | sql/handler.h | 14 | ||||
-rw-r--r-- | sql/item.cc | 12 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 65 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 22 | ||||
-rw-r--r-- | sql/item_func.h | 21 | ||||
-rw-r--r-- | sql/item_geofunc.cc | 22 | ||||
-rw-r--r-- | sql/item_geofunc.h | 6 | ||||
-rw-r--r-- | sql/mysqld.cc | 3 | ||||
-rw-r--r-- | sql/mysqld.h | 12 | ||||
-rw-r--r-- | sql/sql_acl.cc | 35 | ||||
-rw-r--r-- | sql/sql_class.h | 14 | ||||
-rw-r--r-- | sql/sql_insert.cc | 13 | ||||
-rw-r--r-- | sql/sql_load.cc | 5 | ||||
-rw-r--r-- | sql/sql_locale.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 67 | ||||
-rw-r--r-- | sql/sql_table.cc | 20 | ||||
-rw-r--r-- | sql/sql_update.cc | 14 |
23 files changed, 353 insertions, 296 deletions
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc index 251869cad03..c5db5053fb9 100644 --- a/sql/gcalc_slicescan.cc +++ b/sql/gcalc_slicescan.cc @@ -49,14 +49,14 @@ typedef int (*sc_compare_func)(const void*, const void*); static Gcalc_scan_iterator::point *eq_sp(const Gcalc_heap::Info *pi) { GCALC_DBUG_ASSERT(pi->type == Gcalc_heap::nt_eq_node); - return (Gcalc_scan_iterator::point *) pi->eq_data; + return (Gcalc_scan_iterator::point *) pi->node.eq.data; } static Gcalc_scan_iterator::intersection_info *i_data(const Gcalc_heap::Info *pi) { GCALC_DBUG_ASSERT(pi->type == Gcalc_heap::nt_intersection); - return (Gcalc_scan_iterator::intersection_info *) pi->intersection_data; + return (Gcalc_scan_iterator::intersection_info *) pi->node.intersection.data; } @@ -103,8 +103,8 @@ const char *gcalc_ev_name(int ev) static int gcalc_pi_str(char *str, const Gcalc_heap::Info *pi, const char *postfix) { return sprintf(str, "%s %d %d | %s %d %d%s", - GCALC_SIGN(pi->ix[0]) ? "-":"", FIRST_DIGIT(pi->ix[0]),pi->ix[1], - GCALC_SIGN(pi->iy[0]) ? "-":"", FIRST_DIGIT(pi->iy[0]),pi->iy[1], + GCALC_SIGN(pi->node.shape.ix[0]) ? "-":"", FIRST_DIGIT(pi->node.shape.ix[0]),pi->node.shape.ix[1], + GCALC_SIGN(pi->node.shape.iy[0]) ? "-":"", FIRST_DIGIT(pi->node.shape.iy[0]),pi->node.shape.iy[1], postfix); } @@ -594,8 +594,8 @@ void Gcalc_scan_iterator::intersection_info::do_calc_t() Gcalc_coord1 a2_a1x, a2_a1y; Gcalc_coord2 x1y2, x2y1; - gcalc_sub_coord1(a2_a1x, edge_b->pi->ix, edge_a->pi->ix); - gcalc_sub_coord1(a2_a1y, edge_b->pi->iy, edge_a->pi->iy); + gcalc_sub_coord1(a2_a1x, edge_b->pi->node.shape.ix, edge_a->pi->node.shape.ix); + gcalc_sub_coord1(a2_a1y, edge_b->pi->node.shape.iy, edge_a->pi->node.shape.iy); GCALC_DBUG_ASSERT(!gcalc_is_zero(edge_a->dy, GCALC_COORD_BASE) || !gcalc_is_zero(edge_b->dy, GCALC_COORD_BASE)); @@ -619,7 +619,7 @@ void Gcalc_scan_iterator::intersection_info::do_calc_y() Gcalc_coord3 a_tb, b_ta; gcalc_mul_coord(a_tb, GCALC_COORD_BASE3, - t_b, GCALC_COORD_BASE2, edge_a->pi->iy, GCALC_COORD_BASE); + t_b, GCALC_COORD_BASE2, edge_a->pi->node.shape.iy, GCALC_COORD_BASE); gcalc_mul_coord(b_ta, GCALC_COORD_BASE3, t_a, GCALC_COORD_BASE2, edge_a->dy, GCALC_COORD_BASE); @@ -635,7 +635,7 @@ void Gcalc_scan_iterator::intersection_info::do_calc_x() Gcalc_coord3 a_tb, b_ta; gcalc_mul_coord(a_tb, GCALC_COORD_BASE3, - t_b, GCALC_COORD_BASE2, edge_a->pi->ix, GCALC_COORD_BASE); + t_b, GCALC_COORD_BASE2, edge_a->pi->node.shape.ix, GCALC_COORD_BASE); gcalc_mul_coord(b_ta, GCALC_COORD_BASE3, t_a, GCALC_COORD_BASE2, edge_a->dx, GCALC_COORD_BASE); @@ -656,7 +656,7 @@ static int cmp_node_isc(const Gcalc_heap::Info *node, inf->calc_y_exp(); gcalc_mul_coord(exp, GCALC_COORD_BASE3, - inf->t_b, GCALC_COORD_BASE2, node->iy, GCALC_COORD_BASE); + inf->t_b, GCALC_COORD_BASE2, node->node.shape.iy, GCALC_COORD_BASE); result= gcalc_cmp_coord(exp, inf->y_exp, GCALC_COORD_BASE3); #ifdef GCALC_CHECK_WITH_FLOAT @@ -664,18 +664,18 @@ static int cmp_node_isc(const Gcalc_heap::Info *node, isc->calc_xy_ld(&int_x, &int_y); if (result < 0) { - if (!de_check(int_y, node->y) && node->y > int_y) - GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g < %LG", node->y, int_y)); + if (!de_check(int_y, node->node.shape.y) && node->node.shape.y > int_y) + GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g < %LG", node->node.shape.y, int_y)); } else if (result > 0) { - if (!de_check(int_y, node->y) && node->y < int_y) - GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g > %LG", node->y, int_y)); + if (!de_check(int_y, node->node.shape.y) && node->node.shape.y < int_y) + GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g > %LG", node->node.shape.y, int_y)); } else { - if (!de_check(int_y, node->y)) - GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g == %LG", node->y, int_y)); + if (!de_check(int_y, node->node.shape.y)) + GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g == %LG", node->node.shape.y, int_y)); } #endif /*GCALC_CHECK_WITH_FLOAT*/ if (result) @@ -684,27 +684,27 @@ static int cmp_node_isc(const Gcalc_heap::Info *node, inf->calc_x_exp(); gcalc_mul_coord(exp, GCALC_COORD_BASE3, - inf->t_b, GCALC_COORD_BASE2, node->ix, GCALC_COORD_BASE); + inf->t_b, GCALC_COORD_BASE2, node->node.shape.ix, GCALC_COORD_BASE); result= gcalc_cmp_coord(exp, inf->x_exp, GCALC_COORD_BASE3); #ifdef GCALC_CHECK_WITH_FLOAT if (result < 0) { - if (!de_check(int_x, node->x) && node->x > int_x) + if (!de_check(int_x, node->node.shape.x) && node->node.shape.x > int_x) GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscx failed %g < %LG", - node->x, int_x)); + node->node.shape.x, int_x)); } else if (result > 0) { - if (!de_check(int_x, node->x) && node->x < int_x) + if (!de_check(int_x, node->node.shape.x) && node->node.shape.x < int_x) GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscx failed %g > %LG", - node->x, int_x)); + node->node.shape.x, int_x)); } else { - if (!de_check(int_x, node->x)) + if (!de_check(int_x, node->node.shape.x)) GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscx failed %g == %LG", - node->x, int_x)); + node->node.shape.x, int_x)); } #endif /*GCALC_CHECK_WITH_FLOAT*/ exit: @@ -844,13 +844,13 @@ Gcalc_heap::Info *Gcalc_heap::new_point_info(double x, double y, return NULL; *m_hook= result; m_hook= &result->next; - result->x= x; - result->y= y; - result->shape= shape; - result->top_node= 1; + result->node.shape.x= x; + result->node.shape.y= y; + result->node.shape.shape= shape; + result->node.shape.top_node= 1; result->type= nt_shape_node; - gcalc_set_double(result->ix, x, coord_extent); - gcalc_set_double(result->iy, y, coord_extent); + gcalc_set_double(result->node.shape.ix, x, coord_extent); + gcalc_set_double(result->node.shape.iy, y, coord_extent); m_n_points++; return result; @@ -864,11 +864,11 @@ static Gcalc_heap::Info *new_intersection( if (!isc) return 0; isc->type= Gcalc_heap::nt_intersection; - isc->p1= ii->edge_a->pi; - isc->p2= ii->edge_a->next_pi; - isc->p3= ii->edge_b->pi; - isc->p4= ii->edge_b->next_pi; - isc->intersection_data= ii; + isc->node.intersection.p1= ii->edge_a->pi; + isc->node.intersection.p2= ii->edge_a->next_pi; + isc->node.intersection.p3= ii->edge_b->pi; + isc->node.intersection.p4= ii->edge_b->next_pi; + isc->node.intersection.data= ii; return isc; } @@ -881,46 +881,46 @@ static Gcalc_heap::Info *new_eq_point( if (!eqp) return 0; eqp->type= Gcalc_heap::nt_eq_node; - eqp->node= p; - eqp->eq_data= edge; + eqp->node.eq.node= p; + eqp->node.eq.data= edge; return eqp; } void Gcalc_heap::Info::calc_xy(double *x, double *y) const { - double b0_x= p2->x - p1->x; - double b0_y= p2->y - p1->y; - double b1_x= p4->x - p3->x; - double b1_y= p4->y - p3->y; + double b0_x= node.intersection.p2->node.shape.x - node.intersection.p1->node.shape.x; + double b0_y= node.intersection.p2->node.shape.y - node.intersection.p1->node.shape.y; + double b1_x= node.intersection.p4->node.shape.x - node.intersection.p3->node.shape.x; + double b1_y= node.intersection.p4->node.shape.y - node.intersection.p3->node.shape.y; double b0xb1= b0_x * b1_y - b0_y * b1_x; - double t= (p3->x - p1->x) * b1_y - (p3->y - p1->y) * b1_x; + double t= (node.intersection.p3->node.shape.x - node.intersection.p1->node.shape.x) * b1_y - (node.intersection.p3->node.shape.y - node.intersection.p1->node.shape.y) * b1_x; t/= b0xb1; - *x= p1->x + b0_x * t; - *y= p1->y + b0_y * t; + *x= node.intersection.p1->node.shape.x + b0_x * t; + *y= node.intersection.p1->node.shape.y + b0_y * t; } #ifdef GCALC_CHECK_WITH_FLOAT void Gcalc_heap::Info::calc_xy_ld(long double *x, long double *y) const { - long double b0_x= ((long double) p2->x) - p1->x; - long double b0_y= ((long double) p2->y) - p1->y; - long double b1_x= ((long double) p4->x) - p3->x; - long double b1_y= ((long double) p4->y) - p3->y; + long double b0_x= ((long double) p2->node.shape.x) - p1->node.shape.x; + long double b0_y= ((long double) p2->node.shape.y) - p1->node.shape.y; + long double b1_x= ((long double) p4->node.shape.x) - p3->node.shape.x; + long double b1_y= ((long double) p4->node.shape.y) - p3->node.shape.y; long double b0xb1= b0_x * b1_y - b0_y * b1_x; - long double ax= ((long double) p3->x) - p1->x; - long double ay= ((long double) p3->y) - p1->y; + long double ax= ((long double) p3->node.shape.x) - p1->node.shape.x; + long double ay= ((long double) p3->node.shape.y) - p1->node.shape.y; long double t_a= ax * b1_y - ay * b1_x; - long double hx= (b0xb1 * (long double) p1->x + b0_x * t_a); - long double hy= (b0xb1 * (long double) p1->y + b0_y * t_a); + long double hx= (b0xb1 * (long double) p1->node.shape.x + b0_x * t_a); + long double hy= (b0xb1 * (long double) p1->node.shape.y + b0_y * t_a); if (fabs(b0xb1) < 1e-15) { - *x= p1->x; - *y= p1->y; + *x= p1->node.shape.x; + *y= p1->node.shape.y; return; } @@ -933,10 +933,10 @@ void Gcalc_heap::Info::calc_xy_ld(long double *x, long double *y) const static int cmp_point_info(const Gcalc_heap::Info *i0, const Gcalc_heap::Info *i1) { - int cmp_y= gcalc_cmp_coord1(i0->iy, i1->iy); + int cmp_y= gcalc_cmp_coord1(i0->node.shape.iy, i1->node.shape.iy); if (cmp_y) return cmp_y; - return gcalc_cmp_coord1(i0->ix, i1->ix); + return gcalc_cmp_coord1(i0->node.shape.ix, i1->node.shape.ix); } @@ -944,11 +944,11 @@ static inline void trim_node(Gcalc_heap::Info *node, Gcalc_heap::Info *prev_node { if (!node) return; - node->top_node= 0; - GCALC_DBUG_ASSERT((node->left == prev_node) || (node->right == prev_node)); - if (node->left == prev_node) - node->left= node->right; - node->right= NULL; + node->node.shape.top_node= 0; + GCALC_DBUG_ASSERT((node->node.shape.left == prev_node) || (node->node.shape.right == prev_node)); + if (node->node.shape.left == prev_node) + node->node.shape.left= node->node.shape.right; + node->node.shape.right= NULL; GCALC_DBUG_ASSERT(cmp_point_info(node, prev_node)); } @@ -972,8 +972,8 @@ void Gcalc_heap::prepare_operation() /* TODO - move this to the 'normal_scan' loop */ for (cur= get_first(); cur; cur= cur->get_next()) { - trim_node(cur->left, cur); - trim_node(cur->right, cur); + trim_node(cur->node.shape.left, cur); + trim_node(cur->node.shape.right, cur); } } @@ -995,7 +995,7 @@ int Gcalc_shape_transporter::int_single_point(gcalc_shape_info Info, Gcalc_heap::Info *point= m_heap->new_point_info(x, y, Info); if (!point) return 1; - point->left= point->right= 0; + point->node.shape.left= point->node.shape.right= 0; return 0; } @@ -1018,9 +1018,9 @@ int Gcalc_shape_transporter::int_add_point(gcalc_shape_info Info, m_heap->free_point_info(point, hook); return 0; } - GCALC_DBUG_ASSERT(!m_prev || m_prev->x != x || m_prev->y != y); - m_prev->left= point; - point->right= m_prev; + GCALC_DBUG_ASSERT(!m_prev || m_prev->node.shape.x != x || m_prev->node.shape.y != y); + m_prev->node.shape.left= point; + point->node.shape.right= m_prev; } else m_first= point; @@ -1040,16 +1040,16 @@ void Gcalc_shape_transporter::int_complete() /* simple point */ if (m_first == m_prev) { - m_first->right= m_first->left= NULL; + m_first->node.shape.right= m_first->node.shape.left= NULL; return; } /* line */ if (m_shape_started == 1) { - m_first->right= NULL; - m_prev->left= m_prev->right; - m_prev->right= NULL; + m_first->node.shape.right= NULL; + m_prev->node.shape.left= m_prev->node.shape.right; + m_prev->node.shape.right= NULL; return; } @@ -1057,32 +1057,32 @@ void Gcalc_shape_transporter::int_complete() if (cmp_point_info(m_first, m_prev) == 0) { /* Coinciding points, remove the last one from the list */ - m_prev->right->left= m_first; - m_first->right= m_prev->right; + m_prev->node.shape.right->node.shape.left= m_first; + m_first->node.shape.right= m_prev->node.shape.right; m_heap->free_point_info(m_prev, m_prev_hook); } else { - GCALC_DBUG_ASSERT(m_prev->x != m_first->x || m_prev->y != m_first->y); - m_first->right= m_prev; - m_prev->left= m_first; + GCALC_DBUG_ASSERT(m_prev->node.shape.x != m_first->node.shape.x || m_prev->node.shape.y != m_first->node.shape.y); + m_first->node.shape.right= m_prev; + m_prev->node.shape.left= m_first; } } inline void calc_dx_dy(Gcalc_scan_iterator::point *p) { - gcalc_sub_coord1(p->dx, p->next_pi->ix, p->pi->ix); - gcalc_sub_coord1(p->dy, p->next_pi->iy, p->pi->iy); + gcalc_sub_coord1(p->dx, p->next_pi->node.shape.ix, p->pi->node.shape.ix); + gcalc_sub_coord1(p->dy, p->next_pi->node.shape.iy, p->pi->node.shape.iy); if (GCALC_SIGN(p->dx[0])) { - p->l_border= &p->next_pi->ix; - p->r_border= &p->pi->ix; + p->l_border= &p->next_pi->node.shape.ix; + p->r_border= &p->pi->node.shape.ix; } else { - p->r_border= &p->next_pi->ix; - p->l_border= &p->pi->ix; + p->r_border= &p->next_pi->node.shape.ix; + p->l_border= &p->pi->node.shape.ix; } } @@ -1143,10 +1143,10 @@ int Gcalc_scan_iterator::point::cmp_dx_dy(const Gcalc_heap::Info *p1, const Gcalc_heap::Info *p4) { Gcalc_coord1 dx_a, dy_a, dx_b, dy_b; - gcalc_sub_coord1(dx_a, p2->ix, p1->ix); - gcalc_sub_coord1(dy_a, p2->iy, p1->iy); - gcalc_sub_coord1(dx_b, p4->ix, p3->ix); - gcalc_sub_coord1(dy_b, p4->iy, p3->iy); + gcalc_sub_coord1(dx_a, p2->node.shape.ix, p1->node.shape.ix); + gcalc_sub_coord1(dy_a, p2->node.shape.iy, p1->node.shape.iy); + gcalc_sub_coord1(dx_b, p4->node.shape.ix, p3->node.shape.ix); + gcalc_sub_coord1(dy_b, p4->node.shape.iy, p3->node.shape.iy); return cmp_dx_dy(dx_a, dy_a, dx_b, dy_b); } @@ -1168,8 +1168,8 @@ void Gcalc_scan_iterator::point::calc_x(long double *x, long double y, *x= ix; } else - *x= (ddy * (long double) pi->x + gcalc_get_double(dx, GCALC_COORD_BASE) * - (y - pi->y)) / ddy; + *x= (ddy * (long double) pi->node.shape.x + gcalc_get_double(dx, GCALC_COORD_BASE) * + (y - pi->node.shape.y)) / ddy; } #endif /*GCALC_CHECK_WITH_FLOAT*/ @@ -1280,7 +1280,7 @@ int Gcalc_scan_iterator::arrange_event(int do_sorting, int n_intersections) int Gcalc_heap::Info::equal_pi(const Info *pi) const { if (type == nt_intersection) - return equal_intersection; + return node.intersection.equal; if (pi->type == nt_eq_node) return 1; if (type == nt_eq_node || pi->type == nt_intersection) @@ -1322,7 +1322,7 @@ int Gcalc_scan_iterator::step() #ifndef GCALC_DBUG_OFF if (m_cur_pi->type == Gcalc_heap::nt_intersection && m_cur_pi->get_next()->type == Gcalc_heap::nt_intersection && - m_cur_pi->equal_intersection) + m_cur_pi->node.intersection.equal) GCALC_DBUG_ASSERT(cmp_intersections(m_cur_pi, m_cur_pi->get_next()) == 0); #endif /*GCALC_DBUG_OFF*/ GCALC_DBUG_CHECK_COUNTER(); @@ -1377,23 +1377,23 @@ static int node_on_right(const Gcalc_heap::Info *node, Gcalc_coord2 ax_by, ay_bx; int result; - gcalc_sub_coord1(a_x, node->ix, edge_a->ix); - gcalc_sub_coord1(a_y, node->iy, edge_a->iy); - gcalc_sub_coord1(b_x, edge_b->ix, edge_a->ix); - gcalc_sub_coord1(b_y, edge_b->iy, edge_a->iy); + gcalc_sub_coord1(a_x, node->node.shape.ix, edge_a->node.shape.ix); + gcalc_sub_coord1(a_y, node->node.shape.iy, edge_a->node.shape.iy); + gcalc_sub_coord1(b_x, edge_b->node.shape.ix, edge_a->node.shape.ix); + gcalc_sub_coord1(b_y, edge_b->node.shape.iy, edge_a->node.shape.iy); gcalc_mul_coord1(ax_by, a_x, b_y); gcalc_mul_coord1(ay_bx, a_y, b_x); result= gcalc_cmp_coord(ax_by, ay_bx, GCALC_COORD_BASE2); #ifdef GCALC_CHECK_WITH_FLOAT { - long double dx= gcalc_get_double(edge_b->ix, GCALC_COORD_BASE) - - gcalc_get_double(edge_a->ix, GCALC_COORD_BASE); - long double dy= gcalc_get_double(edge_b->iy, GCALC_COORD_BASE) - - gcalc_get_double(edge_a->iy, GCALC_COORD_BASE); - long double ax= gcalc_get_double(node->ix, GCALC_COORD_BASE) - - gcalc_get_double(edge_a->ix, GCALC_COORD_BASE); - long double ay= gcalc_get_double(node->iy, GCALC_COORD_BASE) - - gcalc_get_double(edge_a->iy, GCALC_COORD_BASE); + long double dx= gcalc_get_double(edge_b->node.shape.ix, GCALC_COORD_BASE) - + gcalc_get_double(edge_a->node.shape.ix, GCALC_COORD_BASE); + long double dy= gcalc_get_double(edge_b->node.shape.iy, GCALC_COORD_BASE) - + gcalc_get_double(edge_a->node.shape.iy, GCALC_COORD_BASE); + long double ax= gcalc_get_double(node->node.shape.ix, GCALC_COORD_BASE) - + gcalc_get_double(edge_a->node.shape.ix, GCALC_COORD_BASE); + long double ay= gcalc_get_double(node->node.shape.iy, GCALC_COORD_BASE) - + gcalc_get_double(edge_a->node.shape.iy, GCALC_COORD_BASE); long double d= ax * dy - ay * dx; if (result == 0) GCALC_DBUG_ASSERT(de_check(d, 0.0)); @@ -1412,8 +1412,8 @@ static int cmp_tops(const Gcalc_heap::Info *top_node, { int cmp_res_a, cmp_res_b; - cmp_res_a= gcalc_cmp_coord1(edge_a->ix, top_node->ix); - cmp_res_b= gcalc_cmp_coord1(edge_b->ix, top_node->ix); + cmp_res_a= gcalc_cmp_coord1(edge_a->node.shape.ix, top_node->node.shape.ix); + cmp_res_b= gcalc_cmp_coord1(edge_b->node.shape.ix, top_node->node.shape.ix); if (cmp_res_a <= 0 && cmp_res_b > 0) return -1; @@ -1438,26 +1438,26 @@ int Gcalc_scan_iterator::insert_top_node() if (!sp0) GCALC_DBUG_RETURN(1); sp0->pi= m_cur_pi; - sp0->next_pi= m_cur_pi->left; + sp0->next_pi= m_cur_pi->node.shape.left; #ifndef GCALC_DBUG_OFF sp0->thread= m_cur_thread++; #endif /*GCALC_DBUG_OFF*/ - if (m_cur_pi->left) + if (m_cur_pi->node.shape.left) { calc_dx_dy(sp0); - if (m_cur_pi->right) + if (m_cur_pi->node.shape.right) { if (!(sp1= new_slice_point())) GCALC_DBUG_RETURN(1); sp1->event= sp0->event= scev_two_threads; sp1->pi= m_cur_pi; - sp1->next_pi= m_cur_pi->right; + sp1->next_pi= m_cur_pi->node.shape.right; #ifndef GCALC_DBUG_OFF sp1->thread= m_cur_thread++; #endif /*GCALC_DBUG_OFF*/ calc_dx_dy(sp1); /* We have two threads so should decide which one will be first */ - cmp_res= cmp_tops(m_cur_pi, m_cur_pi->left, m_cur_pi->right); + cmp_res= cmp_tops(m_cur_pi, m_cur_pi->node.shape.left, m_cur_pi->node.shape.right); if (cmp_res > 0) { point *tmp= sp0; @@ -1467,7 +1467,7 @@ int Gcalc_scan_iterator::insert_top_node() else if (cmp_res == 0) { /* Exactly same direction of the edges. */ - cmp_res= gcalc_cmp_coord1(m_cur_pi->left->iy, m_cur_pi->right->iy); + cmp_res= gcalc_cmp_coord1(m_cur_pi->node.shape.left->node.shape.iy, m_cur_pi->node.shape.right->node.shape.iy); if (cmp_res != 0) { if (cmp_res < 0) @@ -1483,7 +1483,7 @@ int Gcalc_scan_iterator::insert_top_node() } else { - cmp_res= gcalc_cmp_coord1(m_cur_pi->left->ix, m_cur_pi->right->ix); + cmp_res= gcalc_cmp_coord1(m_cur_pi->node.shape.left->node.shape.ix, m_cur_pi->node.shape.right->node.shape.ix); if (cmp_res != 0) { if (cmp_res < 0) @@ -1517,7 +1517,7 @@ int Gcalc_scan_iterator::insert_top_node() /* We need to find the place to insert. */ for (; sp; prev_hook= sp->next_ptr(), sp=sp->get_next()) { - if (sp->event || gcalc_cmp_coord1(*sp->r_border, m_cur_pi->ix) < 0) + if (sp->event || gcalc_cmp_coord1(*sp->r_border, m_cur_pi->node.shape.ix) < 0) continue; cmp_res= node_on_right(m_cur_pi, sp->pi, sp->next_pi); if (cmp_res == 0) @@ -1743,7 +1743,7 @@ int Gcalc_scan_iterator::node_scan() GCALC_DBUG_PRINT(("node for %d", sp->thread)); /* Handle the point itself. */ sp->pi= cur_pi; - sp->next_pi= cur_pi->left; + sp->next_pi= cur_pi->node.shape.left; sp->event= scev_point; calc_dx_dy(sp); @@ -1794,7 +1794,7 @@ void Gcalc_scan_iterator::intersection_scan() ii->edge_a->event= ii->edge_b->event= scev_intersection; ii->edge_a->ev_pi= ii->edge_b->ev_pi= m_cur_pi; free_item(ii); - m_cur_pi->intersection_data= NULL; + m_cur_pi->node.intersection.data= NULL; GCALC_DBUG_VOID_RETURN; } @@ -1813,7 +1813,7 @@ int Gcalc_scan_iterator::add_intersection(point *sp_a, point *sp_b, !(ii= new_intersection(m_heap, i_calc))) GCALC_DBUG_RETURN(1); - ii->equal_intersection= 0; + ii->node.intersection.equal= 0; for (; pi_from->get_next() != sp_a->next_pi && @@ -1824,7 +1824,7 @@ int Gcalc_scan_iterator::add_intersection(point *sp_a, point *sp_b, if (skip_next) { if (cur->type == Gcalc_heap::nt_intersection) - skip_next= cur->equal_intersection; + skip_next= cur->node.intersection.equal; else skip_next= 0; continue; @@ -1832,7 +1832,7 @@ int Gcalc_scan_iterator::add_intersection(point *sp_a, point *sp_b, if (cur->type == Gcalc_heap::nt_intersection) { cmp_res= cmp_intersections(cur, ii); - skip_next= cur->equal_intersection; + skip_next= cur->node.intersection.equal; } else if (cur->type == Gcalc_heap::nt_eq_node) continue; @@ -1840,7 +1840,7 @@ int Gcalc_scan_iterator::add_intersection(point *sp_a, point *sp_b, cmp_res= cmp_node_isc(cur, ii); if (cmp_res == 0) { - ii->equal_intersection= 1; + ii->node.intersection.equal= 1; break; } else if (cmp_res > 0) @@ -1881,13 +1881,13 @@ void calc_t(Gcalc_coord2 t_a, Gcalc_coord2 t_b, Gcalc_coord2 x1y2, x2y1; Gcalc_coord1 dya, dyb; - gcalc_sub_coord1(a2_a1x, p3->ix, p1->ix); - gcalc_sub_coord1(a2_a1y, p3->iy, p1->iy); + gcalc_sub_coord1(a2_a1x, p3->node.shape.ix, p1->node.shape.ix); + gcalc_sub_coord1(a2_a1y, p3->node.shape.iy, p1->node.shape.iy); - gcalc_sub_coord1(dxa, p2->ix, p1->ix); - gcalc_sub_coord1(dya, p2->iy, p1->iy); - gcalc_sub_coord1(dxb, p4->ix, p3->ix); - gcalc_sub_coord1(dyb, p4->iy, p3->iy); + gcalc_sub_coord1(dxa, p2->node.shape.ix, p1->node.shape.ix); + gcalc_sub_coord1(dya, p2->node.shape.iy, p1->node.shape.iy); + gcalc_sub_coord1(dxb, p4->node.shape.ix, p3->node.shape.ix); + gcalc_sub_coord1(dyb, p4->node.shape.iy, p3->node.shape.iy); gcalc_mul_coord1(x1y2, dxa, dyb); gcalc_mul_coord1(x2y1, dya, dxb); @@ -1908,11 +1908,11 @@ double Gcalc_scan_iterator::get_y() const Gcalc_coord2 t_a, t_b; Gcalc_coord3 a_tb, b_ta, y_exp; calc_t(t_a, t_b, dxa, dya, - state.pi->p1, state.pi->p2, state.pi->p3, state.pi->p4); + state.pi->node.intersection.p1, state.pi->node.intersection.p2, state.pi->node.intersection.p3, state.pi->node.intersection.p4); gcalc_mul_coord(a_tb, GCALC_COORD_BASE3, - t_b, GCALC_COORD_BASE2, state.pi->p1->iy, GCALC_COORD_BASE); + t_b, GCALC_COORD_BASE2, state.pi->node.intersection.p1->node.shape.iy, GCALC_COORD_BASE); gcalc_mul_coord(b_ta, GCALC_COORD_BASE3, t_a, GCALC_COORD_BASE2, dya, GCALC_COORD_BASE); @@ -1922,7 +1922,7 @@ double Gcalc_scan_iterator::get_y() const get_pure_double(t_b, GCALC_COORD_BASE2)) / m_heap->coord_extent; } else - return state.pi->y; + return state.pi->node.shape.y; } @@ -1934,11 +1934,11 @@ double Gcalc_scan_iterator::get_event_x() const Gcalc_coord2 t_a, t_b; Gcalc_coord3 a_tb, b_ta, x_exp; calc_t(t_a, t_b, dxa, dya, - state.pi->p1, state.pi->p2, state.pi->p3, state.pi->p4); + state.pi->node.intersection.p1, state.pi->node.intersection.p2, state.pi->node.intersection.p3, state.pi->node.intersection.p4); gcalc_mul_coord(a_tb, GCALC_COORD_BASE3, - t_b, GCALC_COORD_BASE2, state.pi->p1->ix, GCALC_COORD_BASE); + t_b, GCALC_COORD_BASE2, state.pi->node.intersection.p1->node.shape.ix, GCALC_COORD_BASE); gcalc_mul_coord(b_ta, GCALC_COORD_BASE3, t_a, GCALC_COORD_BASE2, dxa, GCALC_COORD_BASE); @@ -1948,7 +1948,7 @@ double Gcalc_scan_iterator::get_event_x() const get_pure_double(t_b, GCALC_COORD_BASE2)) / m_heap->coord_extent; } else - return state.pi->x; + return state.pi->node.shape.x; } double Gcalc_scan_iterator::get_h() const @@ -1961,7 +1961,7 @@ double Gcalc_scan_iterator::get_h() const state.pi->calc_xy(&x, &next_y); } else - next_y= state.pi->y; + next_y= state.pi->node.shape.y; return next_y - cur_y; } @@ -1970,11 +1970,11 @@ double Gcalc_scan_iterator::get_sp_x(const point *sp) const { double dy; if (sp->event & (scev_end | scev_two_ends | scev_point)) - return sp->pi->x; - dy= sp->next_pi->y - sp->pi->y; + return sp->pi->node.shape.x; + dy= sp->next_pi->node.shape.y - sp->pi->node.shape.y; if (fabs(dy) < 1e-12) - return sp->pi->x; - return (sp->next_pi->x - sp->pi->x) * dy; + return sp->pi->node.shape.x; + return (sp->next_pi->node.shape.x - sp->pi->node.shape.x) * dy; } diff --git a/sql/gcalc_slicescan.h b/sql/gcalc_slicescan.h index 55de497f1ee..4996287ca88 100644 --- a/sql/gcalc_slicescan.h +++ b/sql/gcalc_slicescan.h @@ -26,7 +26,7 @@ #ifndef GCALC_DBUG_OFF #define GCALC_DBUG_PRINT(b) DBUG_PRINT("Gcalc", b) -#define GCALC_DBUG_ENTER(a) DBUG_ENTER("Gcalc "a) +#define GCALC_DBUG_ENTER(a) DBUG_ENTER("Gcalc " a) #define GCALC_DBUG_RETURN(r) DBUG_RETURN(r) #define GCALC_DBUG_VOID_RETURN DBUG_VOID_RETURN #define GCALC_DBUG_ASSERT(r) DBUG_ASSERT(r) @@ -188,7 +188,7 @@ public: double x,y; Gcalc_coord1 ix, iy; int top_node; - }; + } shape; struct { /* nt_intersection */ @@ -197,21 +197,21 @@ public: const Info *p2; const Info *p3; const Info *p4; - void *intersection_data; - int equal_intersection; - }; + void *data; + int equal; + } intersection; struct { /* nt_eq_node */ const Info *node; - void *eq_data; - }; - }; + void *data; + } eq; + } node; bool is_bottom() const - { GCALC_DBUG_ASSERT(type == nt_shape_node); return !left; } + { GCALC_DBUG_ASSERT(type == nt_shape_node); return !node.shape.left; } bool is_top() const - { GCALC_DBUG_ASSERT(type == nt_shape_node); return top_node; } + { GCALC_DBUG_ASSERT(type == nt_shape_node); return node.shape.top_node; } bool is_single_node() const { return is_bottom() && is_top(); } @@ -383,7 +383,7 @@ public: inline const point *c_get_next() const { return (const point *)next; } inline bool is_bottom() const { return !next_pi; } - gcalc_shape_info get_shape() const { return pi->shape; } + gcalc_shape_info get_shape() const { return pi->node.shape.shape; } inline point *get_next() { return (point *)next; } inline const point *get_next() const { return (const point *)next; } /* Compare the dx_dy parameters regarding the horiz_dir */ diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc index 864437401b7..f3c24f9bdf3 100644 --- a/sql/gcalc_tools.cc +++ b/sql/gcalc_tools.cc @@ -1243,7 +1243,7 @@ inline int Gcalc_operation_reducer::get_single_result(res_point *res, GCALC_DBUG_RETURN(1); } else - if (storage->single_point(res->pi->x, res->pi->y)) + if (storage->single_point(res->pi->node.shape.x, res->pi->node.shape.y)) GCALC_DBUG_RETURN(1); free_result(res); GCALC_DBUG_RETURN(0); @@ -1269,8 +1269,8 @@ int Gcalc_operation_reducer::get_result_thread(res_point *cur, } else { - x= cur->pi->x; - y= cur->pi->y; + x= cur->pi->node.shape.x; + y= cur->pi->node.shape.y; } if (storage->add_point(x, y)) GCALC_DBUG_RETURN(1); diff --git a/sql/handler.cc b/sql/handler.cc index 2337eaced55..970c177fee2 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2013, Monty Program Ab. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/handler.h b/sql/handler.h index 692d69cd7c5..1f0241bef86 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1,8 +1,8 @@ #ifndef HANDLER_INCLUDED #define HANDLER_INCLUDED /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2009-2011 Monty Program Ab + Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -333,7 +333,9 @@ /* Flags for method is_fatal_error */ #define HA_CHECK_DUP_KEY 1 #define HA_CHECK_DUP_UNIQUE 2 +#define HA_CHECK_FK_ERROR 4 #define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE) +#define HA_CHECK_ALL (~0U) enum legacy_db_type { @@ -2029,7 +2031,10 @@ public: ((flags & HA_CHECK_DUP_KEY) && (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE)) || - error == HA_ERR_AUTOINC_ERANGE) + error == HA_ERR_AUTOINC_ERANGE || + ((flags & HA_CHECK_FK_ERROR) && + (error == HA_ERR_ROW_IS_REFERENCED || + error == HA_ERR_NO_REFERENCED_ROW))) return FALSE; return TRUE; } @@ -3121,4 +3126,5 @@ inline const char *table_case_name(HA_CREATE_INFO *info, const char *name) { return ((lower_case_table_names == 2 && info->alias) ? info->alias : name); } -#endif + +#endif /* HANDLER_INCLUDED */ diff --git a/sql/item.cc b/sql/item.cc index 3d3f472afc5..3d339334b0d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2014, Oracle and/or its affiliates. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2010, 2016, MariaDB This program is free software; you can redistribute it and/or modify @@ -1272,6 +1272,11 @@ Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs) { uint cnv_errors; String *ostr= val_str(&cnvstr); + if (null_value) + { + Item_null *n= new Item_null(); + return n ? n->safe_charset_converter(tocs) : NULL; + } cnvitem->str_value.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &cnv_errors); if (cnv_errors) @@ -3888,7 +3893,7 @@ Item_param::eq(const Item *arg, bool binary_cmp) const void Item_param::print(String *str, enum_query_type query_type) { - if (state == NO_VALUE) + if (state == NO_VALUE || query_type & QT_NO_DATA_EXPANSION) { str->append('?'); } @@ -6753,7 +6758,8 @@ Item *Item_field::update_value_transformer(uchar *select_arg) void Item_field::print(String *str, enum_query_type query_type) { - if (field && field->table->const_table) + if (field && field->table->const_table && + !(query_type & QT_NO_DATA_EXPANSION)) { print_value(str); return; diff --git a/sql/item.h b/sql/item.h index d09f6572487..41e6fe0e38e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2175,7 +2175,7 @@ public: max_length= 0; name= name_par ? name_par : (char*) "NULL"; fixed= 1; - collation.set(&my_charset_bin, DERIVATION_IGNORABLE); + collation.set(&my_charset_bin, DERIVATION_IGNORABLE, MY_REPERTOIRE_ASCII); } enum Type type() const { return NULL_ITEM; } bool eq(const Item *item, bool binary_cmp) const; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 81688f3321c..fb75c9af794 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2558,10 +2558,7 @@ bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, uint fuzzydate) DBUG_ASSERT(fixed == 1); if (!args[0]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES)) return (null_value= false); - if (!args[1]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES)) - return (null_value= false); - bzero((char*) ltime,sizeof(*ltime)); - return null_value= !(fuzzydate & TIME_FUZZY_DATES); + return (null_value= args[1]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES)); } @@ -3018,24 +3015,6 @@ bool Item_func_case::fix_fields(THD *thd, Item **ref) } -void Item_func_case::agg_str_lengths(Item* arg) -{ - fix_char_length(max(max_char_length(), arg->max_char_length())); - set_if_bigger(decimals, arg->decimals); - unsigned_flag= unsigned_flag && arg->unsigned_flag; -} - - -void Item_func_case::agg_num_lengths(Item *arg) -{ - uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals, - arg->unsigned_flag) - arg->decimals; - set_if_bigger(max_length, len); - set_if_bigger(decimals, arg->decimals); - unsigned_flag= unsigned_flag && arg->unsigned_flag; -} - - /** Check if (*place) and new_value points to different Items and call THD::change_item_tree() if needed. @@ -3101,17 +3080,7 @@ void Item_func_case::fix_length_and_dec() } else { - collation.set_numeric(); - max_length=0; - decimals=0; - unsigned_flag= TRUE; - for (uint i= 0; i < ncases; i+= 2) - agg_num_lengths(args[i + 1]); - if (else_expr_num != -1) - agg_num_lengths(args[else_expr_num]); - max_length= my_decimal_precision_to_length_no_truncation(max_length + - decimals, decimals, - unsigned_flag); + fix_attributes(agg, nagg); } /* @@ -3311,15 +3280,12 @@ double Item_func_coalesce::real_op() bool Item_func_coalesce::date_op(MYSQL_TIME *ltime,uint fuzzydate) { DBUG_ASSERT(fixed == 1); - null_value= 0; for (uint i= 0; i < arg_count; i++) { - bool res= args[i]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES); - if (!args[i]->null_value) - return res; + if (!args[i]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES)) + return (null_value= false); } - bzero((char*) ltime,sizeof(*ltime)); - return null_value|= !(fuzzydate & TIME_FUZZY_DATES); + return (null_value= true); } @@ -3342,19 +3308,32 @@ void Item_func_coalesce::fix_length_and_dec() { cached_field_type= agg_field_type(args, arg_count); agg_result_type(&cached_result_type, args, arg_count); + fix_attributes(args, arg_count); +} + + +#if MYSQL_VERSION_ID > 100100 +#error Rename this to Item_hybrid_func::fix_attributes() when mering to 10.1 +#endif +void Item_func_hybrid_result_type::fix_attributes(Item **items, uint nitems) +{ switch (cached_result_type) { case STRING_RESULT: - if (count_string_result_length(cached_field_type, args, arg_count)) + if (count_string_result_length(field_type(), + items, nitems)) return; break; case DECIMAL_RESULT: - count_decimal_length(); + collation.set_numeric(); + count_decimal_length(items, nitems); break; case REAL_RESULT: - count_real_length(); + collation.set_numeric(); + count_real_length(items, nitems); break; case INT_RESULT: - count_only_length(args, arg_count); + collation.set_numeric(); + count_only_length(items, nitems); decimals= 0; break; case ROW_RESULT: diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 0faba016ba8..0194f9cd0e0 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1255,8 +1255,6 @@ public: Item *find_item(String *str); CHARSET_INFO *compare_collation() { return cmp_collation.collation; } void cleanup(); - void agg_str_lengths(Item *arg); - void agg_num_lengths(Item *arg); }; /* diff --git a/sql/item_func.cc b/sql/item_func.cc index a0f22d283e3..e0e1f1d94e2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -641,16 +641,16 @@ void Item_func::count_datetime_length(Item **item, uint nitems) result length/precision depends on argument ones. */ -void Item_func::count_decimal_length() +void Item_func::count_decimal_length(Item **item, uint nitems) { int max_int_part= 0; decimals= 0; unsigned_flag= 1; - for (uint i=0 ; i < arg_count ; i++) + for (uint i=0 ; i < nitems ; i++) { - set_if_bigger(decimals, args[i]->decimals); - set_if_bigger(max_int_part, args[i]->decimal_int_part()); - set_if_smaller(unsigned_flag, args[i]->unsigned_flag); + set_if_bigger(decimals, item[i]->decimals); + set_if_bigger(max_int_part, item[i]->decimal_int_part()); + set_if_smaller(unsigned_flag, item[i]->unsigned_flag); } int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION); fix_char_length(my_decimal_precision_to_length_no_truncation(precision, @@ -681,19 +681,19 @@ void Item_func::count_only_length(Item **item, uint nitems) result length/precision depends on argument ones. */ -void Item_func::count_real_length() +void Item_func::count_real_length(Item **item, uint nitems) { uint32 length= 0; decimals= 0; max_length= 0; - for (uint i=0 ; i < arg_count ; i++) + for (uint i=0 ; i < nitems ; i++) { if (decimals != NOT_FIXED_DEC) { - set_if_bigger(decimals, args[i]->decimals); - set_if_bigger(length, (args[i]->max_length - args[i]->decimals)); + set_if_bigger(decimals, item[i]->decimals); + set_if_bigger(length, (item[i]->max_length - item[i]->decimals)); } - set_if_bigger(max_length, args[i]->max_length); + set_if_bigger(max_length, item[i]->max_length); } if (decimals != NOT_FIXED_DEC) { @@ -811,7 +811,7 @@ void Item_num_op::fix_length_and_dec(void) if (r0 == REAL_RESULT || r1 == REAL_RESULT || r0 == STRING_RESULT || r1 ==STRING_RESULT) { - count_real_length(); + count_real_length(args, arg_count); max_length= float_length(decimals); cached_result_type= REAL_RESULT; } diff --git a/sql/item_func.h b/sql/item_func.h index 33fa49f9168..667be3c0438 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1,7 +1,7 @@ #ifndef ITEM_FUNC_INCLUDED #define ITEM_FUNC_INCLUDED -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2009, 2014, MariaDB +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,6 +39,13 @@ protected: 0 means get this number from first argument */ uint allowed_arg_cols; + + void count_only_length(Item **item, uint nitems); + void count_real_length(Item **item, uint nitems); + void count_decimal_length(Item **item, uint nitems); + void count_datetime_length(Item **item, uint nitems); + bool count_string_result_length(enum_field_types field_type, + Item **item, uint nitems); public: uint arg_count; table_map used_tables_cache, not_null_tables_cache; @@ -146,16 +153,10 @@ public: virtual void print(String *str, enum_query_type query_type); void print_op(String *str, enum_query_type query_type); void print_args(String *str, uint from, enum_query_type query_type); - void count_only_length(Item **item, uint nitems); - void count_real_length(); - void count_decimal_length(); inline bool get_arg0_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { return (null_value=args[0]->get_date(ltime, fuzzy_date)); } - void count_datetime_length(Item **item, uint nitems); - bool count_string_result_length(enum_field_types field_type, - Item **item, uint nitems); inline bool get_arg0_time(MYSQL_TIME *ltime) { null_value= args[0]->get_time(ltime); @@ -245,7 +246,7 @@ public: char buf[256]; String str(buf, sizeof(buf), system_charset_info); str.length(0); - print(&str, QT_ORDINARY); + print(&str, QT_NO_DATA_EXPANSION); my_error(ER_DATA_OUT_OF_RANGE, MYF(0), type_name, str.c_ptr_safe()); } inline double raise_float_overflow() @@ -436,7 +437,7 @@ class Item_func_hybrid_result_type: public Item_func } protected: Item_result cached_result_type; - + void fix_attributes(Item **item, uint nitems); public: Item_func_hybrid_result_type() :Item_func(), cached_result_type(REAL_RESULT) { collation.set_numeric(); } diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 5e1c0add54b..8815dace9af 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -636,10 +636,10 @@ static double count_edge_t(const Gcalc_heap::Info *ea, double &ex, double &ey, double &vx, double &vy, double &e_sqrlen) { - ex= eb->x - ea->x; - ey= eb->y - ea->y; - vx= v->x - ea->x; - vy= v->y - ea->y; + ex= eb->node.shape.x - ea->node.shape.x; + ey= eb->node.shape.y - ea->node.shape.y; + vx= v->node.shape.x - ea->node.shape.x; + vy= v->node.shape.y - ea->node.shape.y; e_sqrlen= ex * ex + ey * ey; return (ex * vx + ey * vy) / e_sqrlen; } @@ -655,8 +655,8 @@ static double distance_to_line(double ex, double ey, double vx, double vy, static double distance_points(const Gcalc_heap::Info *a, const Gcalc_heap::Info *b) { - double x= a->x - b->x; - double y= a->y - b->y; + double x= a->node.shape.x - b->node.shape.x; + double y= a->node.shape.y - b->node.shape.y; return sqrt(x * x + y * y); } @@ -1697,7 +1697,7 @@ double Item_func_distance::val_real() continue; count_distance: - if (cur_point->shape >= obj2_si) + if (cur_point->node.shape.shape >= obj2_si) continue; cur_point_edge= !cur_point->is_bottom(); @@ -1705,13 +1705,13 @@ count_distance: { /* We only check vertices of object 2 */ if (dist_point->type != Gcalc_heap::nt_shape_node || - dist_point->shape < obj2_si) + dist_point->node.shape.shape < obj2_si) continue; /* if we have an edge to check */ - if (dist_point->left) + if (dist_point->node.shape.left) { - t= count_edge_t(dist_point, dist_point->left, cur_point, + t= count_edge_t(dist_point, dist_point->node.shape.left, cur_point, ex, ey, vx, vy, e_sqrlen); if ((t>0.0) && (t<1.0)) { @@ -1722,7 +1722,7 @@ count_distance: } if (cur_point_edge) { - t= count_edge_t(cur_point, cur_point->left, dist_point, + t= count_edge_t(cur_point, cur_point->node.shape.left, dist_point, ex, ey, vx, vy, e_sqrlen); if ((t>0.0) && (t<1.0)) { diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index a2a61758617..922593f8b91 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -1,8 +1,8 @@ #ifndef ITEM_GEOFUNC_INCLUDED #define ITEM_GEOFUNC_INCLUDED -/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. - Copyright (C) 2011 Monty Program Ab. +/* Copyright (c) 2000, 2016 Oracle and/or its affiliates. + Copyright (C) 2011, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -191,7 +191,7 @@ public: if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY) { String str; - args[i]->print(&str, QT_ORDINARY); + args[i]->print(&str, QT_NO_DATA_EXPANSION); str.append('\0'); my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric", str.ptr()); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a9359ba047e..82a177fd9b0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -286,7 +286,7 @@ const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; static const char *tc_heuristic_recover_names[]= { - "COMMIT", "ROLLBACK", NullS + "OFF", "COMMIT", "ROLLBACK", NullS }; static TYPELIB tc_heuristic_recover_typelib= { @@ -8620,6 +8620,7 @@ mysqld_get_one_option(int optid, case OPT_IGNORE_DB_DIRECTORY: + opt_ignore_db_dirs= NULL; // will be set in ignore_db_dirs_process_additions if (*argument == 0) ignore_db_dirs_reset(); else diff --git a/sql/mysqld.h b/sql/mysqld.h index cfe22101971..14997455f2f 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2015, MariaDB +/* Copyright (c) 2006, 2016, Oracle and/or its affiliates. + Copyright (c) 2010, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -438,7 +438,13 @@ enum enum_query_type /// Without character set introducers. QT_WITHOUT_INTRODUCERS= (1 << 1), /// view internal representation (like QT_ORDINARY except ORDER BY clause) - QT_VIEW_INTERNAL= (1 << 2) + QT_VIEW_INTERNAL= (1 << 2), + /** + If an expression is constant, print the expression, not the value + it evaluates to. Should be used for error messages, so that they + don't reveal values. + */ + QT_NO_DATA_EXPANSION= (1 << 9), }; /* query_id */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 55eff83cb89..ea5b4c51e16 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2014, SkySQL Ab. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -557,9 +557,8 @@ static void init_check_host(void); static void rebuild_check_host(void); static ACL_USER *find_acl_user(const char *host, const char *user, my_bool exact); -static bool update_user_table(THD *thd, TABLE *table, const char *host, - const char *user, const char *new_password, - uint new_password_len); +static bool update_user_table(THD *, TABLE *, const char *, const char *, const + char *, uint, bool); static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables); static inline void get_grantor(THD *thd, char* grantor); @@ -770,7 +769,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) goto end; table->use_all_columns(); - (void) my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50); while (!(read_record_info.read_record(&read_record_info))) { ACL_HOST host; @@ -827,7 +825,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) goto end; table->use_all_columns(); - (void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100); username_char_length= min(table->field[1]->char_length(), USERNAME_CHAR_LENGTH); password_length= table->field[2]->field_length / table->field[2]->charset()->mbmaxlen; @@ -1030,7 +1027,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) goto end; table->use_all_columns(); - (void) my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100); while (!(read_record_info.read_record(&read_record_info))) { ACL_DB db; @@ -1092,8 +1088,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) end_read_record(&read_record_info); freeze_size(&acl_dbs); - (void) my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER), - 50, 100); if (tables[3].table) { init_read_record(&read_record_info, thd, table= tables[3].table, NULL, 1, @@ -1129,6 +1123,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) return_val= FALSE; end: + end_read_record(&read_record_info); thd->variables.sql_mode= old_sql_mode; DBUG_RETURN(return_val); } @@ -1143,12 +1138,12 @@ void acl_free(bool end) delete_dynamic(&acl_wild_hosts); delete_dynamic(&acl_proxy_users); my_hash_free(&acl_check_hosts); - plugin_unlock(0, native_password_plugin); - plugin_unlock(0, old_password_plugin); if (!end) acl_cache->clear(1); /* purecov: inspected */ else { + plugin_unlock(0, native_password_plugin); + plugin_unlock(0, old_password_plugin); delete acl_cache; acl_cache=0; } @@ -1222,6 +1217,10 @@ my_bool acl_reload(THD *thd) old_acl_users= acl_users; old_acl_proxy_users= acl_proxy_users; old_acl_dbs= acl_dbs; + my_init_dynamic_array(&acl_hosts, sizeof(ACL_HOST), 20, 50); + my_init_dynamic_array(&acl_users, sizeof(ACL_USER), 50, 100); + my_init_dynamic_array(&acl_dbs, sizeof(ACL_DB), 50, 100); + my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER), 50, 100); old_mem= mem; delete_dynamic(&acl_wild_hosts); my_hash_free(&acl_check_hosts); @@ -1920,6 +1919,7 @@ bool change_password(THD *thd, const char *host, const char *user, bool save_binlog_row_based; uint new_password_len= (uint) strlen(new_password); bool result= 1; + bool use_salt= 0; #ifdef WITH_WSREP const CSET_STRING query_save = thd->query_string; #endif /* WITH_WSREP */ @@ -1990,6 +1990,7 @@ bool change_password(THD *thd, const char *host, const char *user, acl_user->auth_string.length= new_password_len; set_user_salt(acl_user, new_password, new_password_len); set_user_plugin(acl_user, new_password_len); + use_salt= 1; } else push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -1998,7 +1999,7 @@ bool change_password(THD *thd, const char *host, const char *user, if (update_user_table(thd, table, acl_user->host.hostname ? acl_user->host.hostname : "", acl_user->user ? acl_user->user : "", - new_password, new_password_len)) + new_password, new_password_len, use_salt)) { mysql_mutex_unlock(&acl_cache->lock); /* purecov: deadcode */ goto end; @@ -2259,7 +2260,8 @@ bool hostname_requires_resolving(const char *hostname) static bool update_user_table(THD *thd, TABLE *table, const char *host, const char *user, - const char *new_password, uint new_password_len) + const char *new_password, uint new_password_len, + bool reset_plugin) { char user_key[MAX_KEY_LENGTH]; int error; @@ -2282,6 +2284,11 @@ static bool update_user_table(THD *thd, TABLE *table, } store_record(table,record[1]); table->field[2]->store(new_password, new_password_len, system_charset_info); + if (reset_plugin && table->s->fields >= 41) + { + table->field[40]->reset(); + table->field[41]->reset(); + } if ((error=table->file->ha_update_row(table->record[1],table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) { diff --git a/sql/sql_class.h b/sql/sql_class.h index 48f0776c340..ad3e94d43ca 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify @@ -1826,6 +1826,18 @@ public: current_stmt_binlog_format == BINLOG_FORMAT_ROW); return current_stmt_binlog_format == BINLOG_FORMAT_ROW; } + /** + Determine if binlogging is disabled for this session + @retval 0 if the current statement binlogging is disabled + (could be because of binlog closed/binlog option + is set to false). + @retval 1 if the current statement will be binlogged + */ + inline bool is_current_stmt_binlog_disabled() const + { + return (!(variables.option_bits & OPTION_BIN_LOG) || + !mysql_bin_log.is_open()); + } private: /** diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 8e8745f322f..c039ca67f0e 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2015, MariaDB + Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2010, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1613,9 +1613,10 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) else table->file->insert_id_for_cur_row= insert_id_for_cur_row; bool is_duplicate_key_error; - if (table->file->is_fatal_error(error, HA_CHECK_DUP)) + if (table->file->is_fatal_error(error, HA_CHECK_ALL)) goto err; - is_duplicate_key_error= table->file->is_fatal_error(error, 0); + is_duplicate_key_error= + table->file->is_fatal_error(error, HA_CHECK_ALL & ~HA_CHECK_DUP); if (!is_duplicate_key_error) { /* @@ -1716,7 +1717,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) error != HA_ERR_RECORD_IS_THE_SAME) { if (info->ignore && - !table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + !table->file->is_fatal_error(error, HA_CHECK_ALL)) { if (!(thd->variables.old_behavior & OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE)) @@ -1848,7 +1849,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) { DEBUG_SYNC(thd, "write_row_noreplace"); if (!info->ignore || - table->file->is_fatal_error(error, HA_CHECK_DUP)) + table->file->is_fatal_error(error, HA_CHECK_ALL)) goto err; if (!(thd->variables.old_behavior & OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE)) diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 75ddf80ea66..fba6dcf9ac0 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2015, MariaDB + Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2010, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -255,6 +255,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { DBUG_RETURN(TRUE); } + thd_proc_info(thd, "executing"); /* Let us emit an error if we are loading data to table which is used in subselect in SET clause like we do it for INSERT. diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc index 13e00c99f19..3123474a59b 100644 --- a/sql/sql_locale.cc +++ b/sql/sql_locale.cc @@ -426,7 +426,7 @@ MY_LOCALE my_locale_da_DK /***** LOCALE BEGIN de_AT: German - Austria *****/ static const char *my_locale_month_names_de_AT[13] = - {"Jänner","Feber","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember", NullS }; + {"Jänner","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember", NullS }; static const char *my_locale_ab_month_names_de_AT[13] = {"Jän","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez", NullS }; static const char *my_locale_day_names_de_AT[8] = diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b1e22537b37..91aecadfd0a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015 Oracle and/or its affiliates. +/* Copyright (c) 2000, 2016 Oracle and/or its affiliates. Copyright (c) 2009, 2016 MariaDB This program is free software; you can redistribute it and/or modify @@ -14544,6 +14544,14 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, Field *new_field; LINT_INIT(new_field); + /* + To preserve type or DATE/TIME and GEOMETRY fields, + they need to be handled separately. + */ + if (item->cmp_type() == TIME_RESULT || + item->field_type() == MYSQL_TYPE_GEOMETRY) + new_field= item->tmp_table_field_from_field_type(table, 1); + else switch (item->result_type()) { case REAL_RESULT: new_field= new Field_double(item->max_length, maybe_null, @@ -14566,18 +14574,11 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, case STRING_RESULT: DBUG_ASSERT(item->collation.collation); - /* - DATE/TIME and GEOMETRY fields have STRING_RESULT result type. - To preserve type they needed to be handled separately. - */ - if (item->cmp_type() == TIME_RESULT || - item->field_type() == MYSQL_TYPE_GEOMETRY) - new_field= item->tmp_table_field_from_field_type(table, 1); /* Make sure that the blob fits into a Field_varstring which has 2-byte lenght. */ - else if (item->max_length/item->collation.collation->mbmaxlen > 255 && + if (item->max_length/item->collation.collation->mbmaxlen > 255 && convert_blob_length <= Field_varstring::MAX_SIZE && convert_blob_length) new_field= new Field_varstring(convert_blob_length, maybe_null, @@ -23127,32 +23128,52 @@ static void print_join(THD *thd, /* List is reversed => we should reverse it before using */ List_iterator_fast<TABLE_LIST> ti(*tables); TABLE_LIST **table; - uint non_const_tables= 0; + + /* + If the QT_NO_DATA_EXPANSION flag is specified, we print the + original table list, including constant tables that have been + optimized away, as the constant tables may be referenced in the + expression printed by Item_field::print() when this flag is given. + Otherwise, only non-const tables are printed. + + Example: + + Original SQL: + select * from (select 1) t + + Printed without QT_NO_DATA_EXPANSION: + select '1' AS `1` from dual + + Printed with QT_NO_DATA_EXPANSION: + select `t`.`1` from (select 1 AS `1`) `t` + */ + const bool print_const_tables= (query_type & QT_NO_DATA_EXPANSION); + size_t tables_to_print= 0; for (TABLE_LIST *t= ti++; t ; t= ti++) { - /* - See comment in print_table_array() about the second part of the - condition - */ - if (!t->optimized_away && !is_eliminated_table(eliminated_tables, t)) - non_const_tables++; + /* See comment in print_table_array() about the second condition */ + if (print_const_tables || !t->optimized_away) + if (!is_eliminated_table(eliminated_tables, t)) + tables_to_print++; } - if (!non_const_tables) + if (tables_to_print == 0) { str->append(STRING_WITH_LEN("dual")); return; // all tables were optimized away } ti.rewind(); - if (!(table= (TABLE_LIST **)thd->alloc(sizeof(TABLE_LIST*) * - non_const_tables))) + if (!(table= static_cast<TABLE_LIST **>(thd->alloc(sizeof(TABLE_LIST*) * + tables_to_print)))) return; // out of memory - TABLE_LIST *tmp, **t= table + (non_const_tables - 1); + TABLE_LIST *tmp, **t= table + (tables_to_print - 1); while ((tmp= ti++)) { - if (tmp->optimized_away || is_eliminated_table(eliminated_tables, tmp)) + if (tmp->optimized_away && !print_const_tables) + continue; + if (is_eliminated_table(eliminated_tables, tmp)) continue; *t--= tmp; } @@ -23172,7 +23193,7 @@ static void print_join(THD *thd, */ if ((*table)->sj_inner_tables) { - TABLE_LIST **end= table + non_const_tables; + TABLE_LIST **end= table + tables_to_print; for (TABLE_LIST **t2= table; t2!=end; t2++) { if (!(*t2)->sj_inner_tables) @@ -23185,7 +23206,7 @@ static void print_join(THD *thd, } } print_table_array(thd, eliminated_tables, str, table, - table + non_const_tables, query_type); + table + tables_to_print, query_type); } /** diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d8e9aaf1f5f..95c34ec2760 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2010, 2016, MariaDB This program is free software; you can redistribute it and/or modify @@ -4934,6 +4934,9 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, /* We have to write the query before we unlock the tables. */ + if (thd->is_current_stmt_binlog_disabled()) + goto err; + if (thd->is_current_stmt_binlog_format_row()) { /* @@ -4976,6 +4979,21 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, if (open_table(thd, table, thd->mem_root, &ot_ctx)) goto err; + /* + After opening a MERGE table add the children to the query list of + tables, so that children tables info can be used on "CREATE TABLE" + statement generation by the binary log. + Note that placeholders don't have the handler open. + */ + if (table->table->file->extra(HA_EXTRA_ADD_CHILDREN_LIST)) + goto err; + + /* + As the reference table is temporary and may not exist on slave, we must + force the ENGINE to be present into CREATE TABLE. + */ + create_info->used_fields|= HA_CREATE_USED_ENGINE; + int result __attribute__((unused))= store_create_info(thd, table, &query, create_info, TRUE /* show_database */); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 9f80b063901..7c2f313b4ae 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2011, 2013, Monty Program Ab. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2011, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -774,7 +774,7 @@ int mysql_update(THD *thd, error= 0; } else if (!ignore || - table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + table->file->is_fatal_error(error, HA_CHECK_ALL)) { /* If (ignore && error is ignorable) we don't have to @@ -782,7 +782,7 @@ int mysql_update(THD *thd, */ myf flags= 0; - if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + if (table->file->is_fatal_error(error, HA_CHECK_ALL)) flags|= ME_FATALERROR; /* Other handler errors are fatal */ prepare_record_for_error_message(error, table); @@ -1973,7 +1973,7 @@ int multi_update::send_data(List<Item> ¬_used_values) { updated--; if (!ignore || - table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + table->file->is_fatal_error(error, HA_CHECK_ALL)) { /* If (ignore && error == is ignorable) we don't have to @@ -1981,7 +1981,7 @@ int multi_update::send_data(List<Item> ¬_used_values) */ myf flags= 0; - if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + if (table->file->is_fatal_error(error, HA_CHECK_ALL)) flags|= ME_FATALERROR; /* Other handler errors are fatal */ prepare_record_for_error_message(error, table); @@ -2264,7 +2264,7 @@ int multi_update::do_updates() local_error != HA_ERR_RECORD_IS_THE_SAME) { if (!ignore || - table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY)) + table->file->is_fatal_error(local_error, HA_CHECK_ALL)) { err_table= table; goto err; |