summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@mariadb.com>2016-04-25 11:06:16 -0400
committerNirbhay Choubey <nirbhay@mariadb.com>2016-04-25 11:06:16 -0400
commit4f1c1975b5f3d98321ad9e5b6f952c166d3606a7 (patch)
tree50c83e846f4a4d538b94bce41201d4a2847a852d /sql
parent9c89b84d46e0645820acb9e3cc339af10c68cfb7 (diff)
parent0991e19e9d38f7475390276c0557c2390e4d93c9 (diff)
downloadmariadb-git-4f1c1975b5f3d98321ad9e5b6f952c166d3606a7.tar.gz
Merge tag 'mariadb-5.5.49' into 5.5-galera
Diffstat (limited to 'sql')
-rw-r--r--sql/gcalc_slicescan.cc266
-rw-r--r--sql/gcalc_slicescan.h22
-rw-r--r--sql/gcalc_tools.cc6
-rw-r--r--sql/handler.cc4
-rw-r--r--sql/handler.h14
-rw-r--r--sql/item.cc12
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_cmpfunc.cc65
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_func.cc22
-rw-r--r--sql/item_func.h21
-rw-r--r--sql/item_geofunc.cc22
-rw-r--r--sql/item_geofunc.h6
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/mysqld.h12
-rw-r--r--sql/sql_acl.cc35
-rw-r--r--sql/sql_class.h14
-rw-r--r--sql/sql_insert.cc13
-rw-r--r--sql/sql_load.cc5
-rw-r--r--sql/sql_locale.cc2
-rw-r--r--sql/sql_select.cc67
-rw-r--r--sql/sql_table.cc20
-rw-r--r--sql/sql_update.cc14
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> &not_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> &not_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;