~clint-fewbar/drizzle/regex-policy-cache-limiter

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: Clint Byrum
  • Date: 2012-03-15 18:05:43 UTC
  • mfrom: (2224.1.302 workspace)
  • Revision ID: clint@ubuntu.com-20120315180543-9jxxm4q10k3np2ws
merging with latest trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
#include <drizzled/select_max_min_finder_subselect.h>
46
46
#include <drizzled/select_exists_subselect.h>
47
47
#include <drizzled/select_union.h>
 
48
#include <drizzled/sql_lex.h>
 
49
#include <drizzled/system_variables.h>
48
50
 
49
 
namespace drizzled
50
 
{
 
51
namespace drizzled {
51
52
 
52
53
extern plugin::StorageEngine *myisam_engine;
53
54
 
54
 
inline Item * and_items(Item* cond, Item *item)
 
55
inline Item* and_items(Item* cond, Item *item)
55
56
{
56
 
  return (cond? (new Item_cond_and(cond, item)) : item);
 
57
  return cond ? new Item_cond_and(cond, item) : item;
57
58
}
58
59
 
59
60
Item_subselect::Item_subselect() :
148
149
    engine->cleanup();
149
150
  reset();
150
151
  value_assigned= 0;
151
 
  return;
152
152
}
153
153
 
154
154
void Item_singlerow_subselect::cleanup()
155
155
{
156
156
  value= 0; row= 0;
157
157
  Item_subselect::cleanup();
158
 
  return;
159
158
}
160
159
 
161
160
 
169
168
  }
170
169
  first_execution= true;
171
170
  Item_subselect::cleanup();
172
 
  return;
173
171
}
174
172
 
175
173
Item_subselect::~Item_subselect()
180
178
Item_subselect::trans_res
181
179
Item_subselect::select_transformer(Join *)
182
180
{
183
 
  return(RES_OK);
 
181
  return RES_OK;
184
182
}
185
183
 
186
184
 
352
350
  {
353
351
    /* Always compute IN for the first row as the cache is not valid for it. */
354
352
    if (!first_execution)
355
 
      return(false);
 
353
      return false;
356
354
    first_execution= false;
357
355
  }
358
356
 
420
418
  init(select_lex, new select_singlerow_subselect(this));
421
419
  maybe_null= 1;
422
420
  max_columns= UINT_MAX;
423
 
  return;
424
421
}
425
422
 
426
423
Select_Lex *
466
463
    session here
467
464
  */
468
465
  session= session_param;
469
 
 
470
 
  return;
471
466
}
472
467
 
473
468
void Item_maxmin_subselect::cleanup()
483
478
    value will be found.
484
479
  */
485
480
  was_values= true;
486
 
  return;
487
481
}
488
482
 
489
483
 
538
532
  {
539
533
 
540
534
    have_to_be_excluded= 1;
541
 
    if (session->getLex()->describe)
 
535
    if (session->lex().describe)
542
536
    {
543
537
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
544
538
      snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
729
723
{
730
724
  if (unit_arg->fake_select_lex &&
731
725
      unit_arg->fake_select_lex->test_limit())
732
 
    return(1);
 
726
    return 1;
733
727
 
734
728
  Select_Lex *sl= unit_arg->first_select();
735
729
  for (; sl; sl= sl->next_select())
736
730
  {
737
731
    if (sl->test_limit())
738
 
      return(1);
 
732
      return 1;
739
733
  }
740
 
  return(0);
 
734
  return 0;
741
735
}
742
736
 
743
737
Item_in_subselect::Item_in_subselect(Item * left_exp,
1062
1056
        it.replace(item);
1063
1057
      }
1064
1058
 
1065
 
      save_allow_sum_func= session->getLex()->allow_sum_func;
1066
 
      session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
 
1059
      save_allow_sum_func= session->lex().allow_sum_func;
 
1060
      session->lex().allow_sum_func|= 1 << session->lex().current_select->nest_level;
1067
1061
      /*
1068
1062
        Item_sum_(max|min) can't substitute other item => we can use 0 as
1069
1063
        reference, also Item_sum_(max|min) can't be fixed after creation, so
1071
1065
      */
1072
1066
      if (item->fix_fields(session, 0))
1073
1067
        return(RES_ERROR);
1074
 
      session->getLex()->allow_sum_func= save_allow_sum_func;
 
1068
      session->lex().allow_sum_func= save_allow_sum_func;
1075
1069
      /* we added aggregate function => we have to change statistic */
1076
1070
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1077
1071
                        0);
1096
1090
    Select_Lex_Unit *master_unit= select_lex->master_unit();
1097
1091
    substitution= optimizer;
1098
1092
 
1099
 
    Select_Lex *current= session->getLex()->current_select, *up;
 
1093
    Select_Lex *current= session->lex().current_select, *up;
1100
1094
 
1101
 
    session->getLex()->current_select= up= current->return_after_parsing();
 
1095
    session->lex().current_select= up= current->return_after_parsing();
1102
1096
    //optimizer never use Item **ref => we can pass 0 as parameter
1103
1097
    if (!optimizer || optimizer->fix_left(session, 0))
1104
1098
    {
1105
 
      session->getLex()->current_select= current;
 
1099
      session->lex().current_select= current;
1106
1100
      return(RES_ERROR);
1107
1101
    }
1108
 
    session->getLex()->current_select= current;
 
1102
    session->lex().current_select= current;
1109
1103
 
1110
1104
    /*
1111
1105
      As far as  Item_ref_in_optimizer do not substitute itself on fix_fields
1112
1106
      we can use same item for all selects.
1113
1107
    */
1114
 
    expr= new Item_direct_ref(&select_lex->context,
1115
 
                              (Item**)optimizer->get_cache(),
1116
 
                              (char *)"<no matter>",
1117
 
                              (char *)in_left_expr_name);
 
1108
    expr= new Item_direct_ref(&select_lex->context, (Item**)optimizer->get_cache(), "<no matter>", in_left_expr_name);
1118
1109
 
1119
1110
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1120
1111
  }
1121
1112
 
1122
1113
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1123
1114
  {
1124
 
    if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool))))
1125
 
      return(RES_ERROR);
 
1115
    pushed_cond_guards= new (join->session->mem) bool;
1126
1116
    pushed_cond_guards[0]= true;
1127
1117
  }
1128
1118
 
1184
1174
      select_lex->group_list.elements)
1185
1175
  {
1186
1176
    bool tmp;
1187
 
    Item *item= func->create(expr,
1188
 
                             new Item_ref_null_helper(&select_lex->context,
1189
 
                                                      this,
1190
 
                                                      select_lex->
1191
 
                                                      ref_pointer_array,
1192
 
                                                      (char *)"<ref>",
1193
 
                                                      this->full_name()));
 
1177
    Item *item= func->create(expr, new Item_ref_null_helper(&select_lex->context, this, select_lex->ref_pointer_array, "<ref>", this->full_name()));
1194
1178
    if (!abort_on_null && left_expr->maybe_null)
1195
1179
    {
1196
1180
      /*
1228
1212
      bool tmp;
1229
1213
      Item *having= item, *orig_item= item;
1230
1214
      select_lex->item_list.clear();
1231
 
      select_lex->item_list.push_back(new Item_int("Not_used",
1232
 
                                                   (int64_t) 1,
1233
 
                                                   MY_INT64_NUM_DECIMAL_DIGITS));
 
1215
      select_lex->item_list.push_back(new Item_int("Not_used", 1, MY_INT64_NUM_DECIMAL_DIGITS));
1234
1216
      select_lex->ref_pointer_array[0]= &select_lex->item_list.front();
1235
1217
 
1236
1218
      item= func->create(expr, item);
1238
1220
      {
1239
1221
        having= new Item_is_not_null_test(this, having);
1240
1222
        if (left_expr->maybe_null)
1241
 
        {
1242
 
          if (!(having= new Item_func_trig_cond(having,
1243
 
                                                get_cond_guard(0))))
1244
 
            return(RES_ERROR);
1245
 
        }
 
1223
          having= new Item_func_trig_cond(having, get_cond_guard(0));
1246
1224
        /*
1247
1225
          Item_is_not_null_test can't be changed during fix_fields()
1248
1226
          we can assign select_lex->having here, and pass 0 as last
1260
1238
        select_lex->having_fix_field= 0;
1261
1239
        if (tmp)
1262
1240
          return(RES_ERROR);
1263
 
        item= new Item_cond_or(item,
1264
 
                               new Item_func_isnull(orig_item));
 
1241
        item= new Item_cond_or(item, new Item_func_isnull(orig_item));
1265
1242
      }
1266
1243
      /*
1267
1244
        If we may encounter NULL IN (SELECT ...) and care whether subquery
1268
1245
        result is NULL or false, wrap condition in a trig_cond.
1269
1246
      */
1270
1247
      if (!abort_on_null && left_expr->maybe_null)
1271
 
      {
1272
 
        if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
1273
 
          return(RES_ERROR);
1274
 
      }
 
1248
        item= new Item_func_trig_cond(item, get_cond_guard(0));
1275
1249
      /*
1276
1250
        TODO: figure out why the following is done here in
1277
1251
        single_value_transformer but there is no corresponding action in
1303
1277
          we can assign select_lex->having here, and pass 0 as last
1304
1278
          argument (reference) to fix_fields()
1305
1279
        */
1306
 
        Item *new_having=
1307
 
          func->create(expr,
1308
 
                       new Item_ref_null_helper(&select_lex->context, this,
1309
 
                                            select_lex->ref_pointer_array,
1310
 
                                            (char *)"<no matter>",
1311
 
                                            (char *)"<result>"));
 
1280
        Item *new_having= func->create(expr, new Item_ref_null_helper(&select_lex->context, this, select_lex->ref_pointer_array, "<no matter>", "<result>"));
1312
1281
        if (!abort_on_null && left_expr->maybe_null)
1313
 
        {
1314
 
          if (!(new_having= new Item_func_trig_cond(new_having,
1315
 
                                                    get_cond_guard(0))))
1316
 
            return(RES_ERROR);
1317
 
        }
1318
 
        new_having->name= (char*)in_having_cond;
 
1282
          new_having= new Item_func_trig_cond(new_having, get_cond_guard(0));
 
1283
        new_having->name= in_having_cond;
1319
1284
        select_lex->having= join->having= new_having;
1320
1285
        select_lex->having_fix_field= 1;
1321
1286
 
1335
1300
        // fix_field of item will be done in time of substituting
1336
1301
        substitution= item;
1337
1302
        have_to_be_excluded= 1;
1338
 
        if (session->getLex()->describe)
 
1303
        if (session->lex().describe)
1339
1304
        {
1340
1305
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1341
1306
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1373
1338
    Select_Lex_Unit *master_unit= select_lex->master_unit();
1374
1339
    substitution= optimizer;
1375
1340
 
1376
 
    Select_Lex *current= session->getLex()->current_select, *up;
1377
 
    session->getLex()->current_select= up= current->return_after_parsing();
 
1341
    Select_Lex *current= session->lex().current_select, *up;
 
1342
    session->lex().current_select= up= current->return_after_parsing();
1378
1343
    //optimizer never use Item **ref => we can pass 0 as parameter
1379
1344
    if (!optimizer || optimizer->fix_left(session, 0))
1380
1345
    {
1381
 
      session->getLex()->current_select= current;
 
1346
      session->lex().current_select= current;
1382
1347
      return(RES_ERROR);
1383
1348
    }
1384
1349
 
1385
1350
    // we will refer to upper level cache array => we have to save it in PS
1386
1351
    optimizer->keep_top_level_cache();
1387
1352
 
1388
 
    session->getLex()->current_select= current;
 
1353
    session->lex().current_select= current;
1389
1354
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1390
1355
 
1391
1356
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1392
1357
    {
1393
 
      if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool) *
1394
 
                                                        left_expr->cols())))
1395
 
        return(RES_ERROR);
 
1358
      pushed_cond_guards= new (join->session->mem) bool[left_expr->cols()];
1396
1359
      for (uint32_t i= 0; i < cols_num; i++)
1397
1360
        pushed_cond_guards[i]= true;
1398
1361
    }
1469
1432
                         Item_ref(&select_lex->context,
1470
1433
                                  (*optimizer->get_cache())->
1471
1434
                                  addr(i),
1472
 
                                  (char *)"<no matter>",
1473
 
                                  (char *)in_left_expr_name),
 
1435
                                  "<no matter>",
 
1436
                                  in_left_expr_name),
1474
1437
                         new
1475
1438
                         Item_ref(&select_lex->context,
1476
1439
                                  select_lex->ref_pointer_array + i,
1477
 
                                  (char *)"<no matter>",
1478
 
                                  (char *)"<list ref>")
 
1440
                                  "<no matter>",
 
1441
                                  "<list ref>")
1479
1442
                        );
1480
1443
      Item *item_isnull=
1481
1444
        new Item_func_isnull(new
1482
1445
                             Item_ref(&select_lex->context,
1483
1446
                                      select_lex->ref_pointer_array+i,
1484
 
                                      (char *)"<no matter>",
1485
 
                                      (char *)"<list ref>")
 
1447
                                      "<no matter>",
 
1448
                                      "<list ref>")
1486
1449
                            );
1487
1450
      Item *col_item= new Item_cond_or(item_eq, item_isnull);
1488
1451
      if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1489
 
      {
1490
 
        if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
1491
 
          return(RES_ERROR);
1492
 
      }
 
1452
        col_item= new Item_func_trig_cond(col_item, get_cond_guard(i));
1493
1453
      having_item= and_items(having_item, col_item);
1494
1454
 
1495
1455
      Item *item_nnull_test=
1497
1457
                                   new Item_ref(&select_lex->context,
1498
1458
                                                select_lex->
1499
1459
                                                ref_pointer_array + i,
1500
 
                                                (char *)"<no matter>",
1501
 
                                                (char *)"<list ref>"));
 
1460
                                                "<no matter>",
 
1461
                                                "<list ref>"));
1502
1462
      if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1503
1463
      {
1504
 
        if (!(item_nnull_test=
1505
 
              new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
1506
 
          return(RES_ERROR);
 
1464
        item_nnull_test= new Item_func_trig_cond(item_nnull_test, get_cond_guard(i));
1507
1465
      }
1508
1466
      item_having_part2= and_items(item_having_part2, item_nnull_test);
1509
1467
      item_having_part2->top_level_item();
1546
1504
                         Item_direct_ref(&select_lex->context,
1547
1505
                                         (*optimizer->get_cache())->
1548
1506
                                         addr(i),
1549
 
                                         (char *)"<no matter>",
1550
 
                                         (char *)in_left_expr_name),
 
1507
                                         "<no matter>",
 
1508
                                         in_left_expr_name),
1551
1509
                         new
1552
1510
                         Item_direct_ref(&select_lex->context,
1553
1511
                                         select_lex->
1554
1512
                                         ref_pointer_array+i,
1555
 
                                         (char *)"<no matter>",
1556
 
                                         (char *)"<list ref>")
 
1513
                                         "<no matter>",
 
1514
                                         "<list ref>")
1557
1515
                        );
1558
1516
      if (!abort_on_null)
1559
1517
      {
1562
1520
                                    new
1563
1521
                                    Item_ref(&select_lex->context,
1564
1522
                                             select_lex->ref_pointer_array + i,
1565
 
                                             (char *)"<no matter>",
1566
 
                                             (char *)"<list ref>"));
 
1523
                                             "<no matter>",
 
1524
                                             "<list ref>"));
1567
1525
 
1568
1526
 
1569
1527
        item_isnull= new
1571
1529
                           Item_direct_ref(&select_lex->context,
1572
1530
                                           select_lex->
1573
1531
                                           ref_pointer_array+i,
1574
 
                                           (char *)"<no matter>",
1575
 
                                           (char *)"<list ref>")
 
1532
                                           "<no matter>",
 
1533
                                           "<list ref>")
1576
1534
                          );
1577
1535
        item= new Item_cond_or(item, item_isnull);
1578
1536
        /*
1581
1539
        */
1582
1540
        if (left_expr->element_index(i)->maybe_null)
1583
1541
        {
1584
 
          if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
1585
 
            return(RES_ERROR);
1586
 
          if (!(having_col_item=
1587
 
                  new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
1588
 
            return(RES_ERROR);
 
1542
          item= new Item_func_trig_cond(item, get_cond_guard(i));
 
1543
          having_col_item= new Item_func_trig_cond(having_col_item, get_cond_guard(i));
1589
1544
        }
1590
1545
        having_item= and_items(having_item, having_col_item);
1591
1546
      }
1657
1612
Item_subselect::trans_res
1658
1613
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1659
1614
{
1660
 
  Select_Lex *current= session->getLex()->current_select, *up;
 
1615
  Select_Lex *current= session->lex().current_select, *up;
1661
1616
  const char *save_where= session->where();
1662
1617
  Item_subselect::trans_res res= RES_ERROR;
1663
1618
  bool result;
1692
1647
      goto err;
1693
1648
  }
1694
1649
 
1695
 
  session->getLex()->current_select= up= current->return_after_parsing();
 
1650
  session->lex().current_select= up= current->return_after_parsing();
1696
1651
  result= (!left_expr->fixed &&
1697
1652
           left_expr->fix_fields(session, optimizer->arguments()));
1698
1653
  /* fix_fields can change reference to left_expr, we need reassign it */
1699
1654
  left_expr= optimizer->arguments()[0];
1700
1655
 
1701
 
  session->getLex()->current_select= current;
 
1656
  session->lex().current_select= current;
1702
1657
  if (result)
1703
1658
    goto err;
1704
1659
 
1730
1685
  }
1731
1686
err:
1732
1687
  session->setWhere(save_where);
1733
 
  return(res);
 
1688
  return res;
1734
1689
}
1735
1690
 
1736
1691
 
1793
1748
    subselect_single_select_engine *old_engine_ptr;
1794
1749
 
1795
1750
    old_engine_ptr= static_cast<subselect_single_select_engine *>(engine);
1796
 
 
1797
 
    if (!(new_engine= new subselect_hash_sj_engine(session, this,
1798
 
                                                   old_engine_ptr)) ||
1799
 
        new_engine->init_permanent(unit->get_unit_column_types()))
 
1751
    new_engine= new subselect_hash_sj_engine(session, this, old_engine_ptr);
 
1752
    if (new_engine->init_permanent(unit->get_unit_column_types()))
1800
1753
    {
1801
1754
      Item_subselect::trans_res new_trans_res;
1802
1755
      /*
1808
1761
      new_engine= NULL;
1809
1762
      exec_method= NOT_TRANSFORMED;
1810
1763
      if (left_expr->cols() == 1)
1811
 
        new_trans_res= single_value_in_to_exists_transformer(
1812
 
                           old_engine_ptr->join,
1813
 
                           Eq_creator::instance());
 
1764
        new_trans_res= single_value_in_to_exists_transformer(old_engine_ptr->join, Eq_creator::instance());
1814
1765
      else
1815
1766
        new_trans_res= row_value_in_to_exists_transformer(old_engine_ptr->join);
1816
1767
      res= (new_trans_res != Item_subselect::RES_OK);
1836
1787
      we should set the correct limit if given in the query.
1837
1788
    */
1838
1789
    unit->global_parameters->select_limit= NULL;
1839
 
    if ((res= new_engine->init_runtime()))
1840
 
      return(res);
 
1790
    new_engine->init_runtime();
1841
1791
  }
1842
1792
 
1843
 
  return(res);
 
1793
  return res;
1844
1794
}
1845
1795
 
1846
1796
 
1864
1814
  if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
1865
1815
    return true;
1866
1816
 
1867
 
  if (!(left_expr_cache= new List<Cached_item>))
1868
 
    return true;
 
1817
  left_expr_cache= new List<Cached_item>;
1869
1818
 
1870
1819
  for (uint32_t i= 0; i < left_expr->cols(); i++)
1871
1820
  {
1872
1821
    Cached_item *cur_item_cache= new_Cached_item(session, left_expr->element_index(i));
1873
 
    if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
 
1822
    if (!cur_item_cache)
1874
1823
      return true;
 
1824
                left_expr_cache->push_front(cur_item_cache);
1875
1825
  }
1876
1826
  return false;
1877
1827
}
1909
1859
void Item_allany_subselect::print(String *str)
1910
1860
{
1911
1861
  if (exec_method == IN_TO_EXISTS)
 
1862
  {
1912
1863
    str->append(STRING_WITH_LEN("<exists>"));
 
1864
  }
1913
1865
  else
1914
1866
  {
1915
1867
    left_expr->print(str);
1916
1868
    str->append(' ');
1917
 
    str->append(func->symbol(all));
 
1869
    str->append(func->symbol(all), strlen(func->symbol(all)));
1918
1870
    str->append(all ? " all " : " any ", 5);
1919
1871
  }
1920
1872
  Item_subselect::print(str);
1925
1877
{
1926
1878
  session= session_arg;
1927
1879
  if (result)
 
1880
  {
1928
1881
    result->set_session(session_arg);
 
1882
  }
1929
1883
}
1930
1884
 
1931
1885
 
2034
1988
{
2035
1989
  if (prepared)
2036
1990
    return 0;
2037
 
  join= new Join(session, select_lex->item_list,
2038
 
                 select_lex->options | SELECT_NO_UNLOCK, result);
2039
 
  if (!join || !result)
 
1991
  join= new Join(session, select_lex->item_list, select_lex->options | SELECT_NO_UNLOCK, result);
 
1992
  if (not result)
2040
1993
    return 1; /* Fatal error is set already. */
2041
1994
  prepared= 1;
2042
 
  Select_Lex *save_select= session->getLex()->current_select;
2043
 
  session->getLex()->current_select= select_lex;
 
1995
  Select_Lex *save_select= session->lex().current_select;
 
1996
  session->lex().current_select= select_lex;
2044
1997
  if (join->prepare(&select_lex->ref_pointer_array,
2045
1998
                    (TableList*) select_lex->table_list.first,
2046
1999
                    select_lex->with_wild,
2052
2005
                    select_lex->having,
2053
2006
                    select_lex, select_lex->master_unit()))
2054
2007
    return 1;
2055
 
  session->getLex()->current_select= save_select;
 
2008
  session->lex().current_select= save_select;
2056
2009
  return 0;
2057
2010
}
2058
2011
 
2151
2104
int subselect_single_select_engine::exec()
2152
2105
{
2153
2106
  char const *save_where= session->where();
2154
 
  Select_Lex *save_select= session->getLex()->current_select;
2155
 
  session->getLex()->current_select= select_lex;
 
2107
  Select_Lex *save_select= session->lex().current_select;
 
2108
  session->lex().current_select= select_lex;
2156
2109
  if (!join->optimized)
2157
2110
  {
2158
2111
    Select_Lex_Unit *unit= select_lex->master_unit();
2162
2115
    {
2163
2116
      session->setWhere(save_where);
2164
2117
      executed= 1;
2165
 
      session->getLex()->current_select= save_select;
 
2118
      session->lex().current_select= save_select;
2166
2119
      return(join->error ? join->error : 1);
2167
2120
    }
2168
 
    if (save_join_if_explain())
2169
 
     return(1);
2170
 
 
 
2121
    save_join_if_explain();
2171
2122
    if (item->engine_changed)
2172
2123
    {
2173
 
      return(1);
 
2124
      return 1;
2174
2125
    }
2175
2126
  }
2176
2127
  if (select_lex->uncacheable.any() &&
2180
2131
    if (join->reinit())
2181
2132
    {
2182
2133
      session->setWhere(save_where);
2183
 
      session->getLex()->current_select= save_select;
 
2134
      session->lex().current_select= save_select;
2184
2135
      return 1;
2185
2136
    }
2186
2137
    item->reset();
2239
2190
    }
2240
2191
    executed= 1;
2241
2192
    session->setWhere(save_where);
2242
 
    session->getLex()->current_select= save_select;
 
2193
    session->lex().current_select= save_select;
2243
2194
    return(join->error||session->is_fatal_error);
2244
2195
  }
2245
2196
  session->setWhere(save_where);
2246
 
  session->getLex()->current_select= save_select;
2247
 
  return(0);
 
2197
  session->lex().current_select= save_select;
 
2198
  return 0;
2248
2199
}
2249
2200
 
2250
 
bool 
2251
 
subselect_single_select_engine::save_join_if_explain()
 
2201
void subselect_single_select_engine::save_join_if_explain()
2252
2202
{
2253
2203
  /*
2254
2204
    Save this JOIN to join->tmp_join since the original layout will be
2263
2213
        make a replacement JOIN by calling make_simple_join(). 
2264
2214
     5) The Item_subselect is cacheable
2265
2215
  */
2266
 
  if (session->getLex()->describe &&                          // 1
 
2216
  if (session->lex().describe &&                          // 1
2267
2217
      select_lex->uncacheable.none() &&                  // 2
2268
2218
      !(join->select_options & SELECT_DESCRIBE) &&       // 3
2269
2219
      join->need_tmp &&                                  // 4
2278
2228
    */
2279
2229
    select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2280
2230
    select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
2281
 
    if (join->init_save_join_tab())
2282
 
      return true;
 
2231
    join->init_save_join_tab();
2283
2232
  }
2284
 
  return false;
2285
2233
}
2286
2234
 
2287
2235
 
2419
2367
      if (top_level)
2420
2368
      {
2421
2369
        /* Partial match on top level */
2422
 
        return(1);
 
2370
        return 1;
2423
2371
      }
2424
2372
      else
2425
2373
      {
2446
2394
      break;
2447
2395
    }
2448
2396
  }
2449
 
  return(0);
 
2397
  return 0;
2450
2398
}
2451
2399
 
2452
2400
 
2489
2437
 
2490
2438
  /* TODO: change to use of 'full_scan' here? */
2491
2439
  if (copy_ref_key())
2492
 
    return(1);
 
2440
    return 1;
2493
2441
  if (table->status)
2494
2442
  {
2495
2443
    /*
2497
2445
      Can be set in copy_ref_key.
2498
2446
    */
2499
2447
    ((Item_in_subselect *) item)->value= 0;
2500
 
    return(0);
 
2448
    return 0;
2501
2449
  }
2502
2450
 
2503
2451
  if (null_keypart)
2610
2558
 
2611
2559
  /* Copy the ref key and check for nulls... */
2612
2560
  if (copy_ref_key())
2613
 
    return(1);
 
2561
    return 1;
2614
2562
 
2615
2563
  if (table->status)
2616
2564
  {
2619
2567
      Can be set in copy_ref_key.
2620
2568
    */
2621
2569
    ((Item_in_subselect *) item)->value= 0;
2622
 
    return(0);
 
2570
    return 0;
2623
2571
  }
2624
2572
 
2625
2573
  if (null_keypart)
2778
2726
 
2779
2727
void subselect_uniquesubquery_engine::print(String *str)
2780
2728
{
2781
 
  const char *table_name= tab->table->getShare()->getTableName();
2782
2729
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2783
2730
  tab->ref.items[0]->print(str);
2784
2731
  str->append(STRING_WITH_LEN(" in "));
2791
2738
    str->append(STRING_WITH_LEN("<temporary table>"));
2792
2739
  }
2793
2740
  else
2794
 
    str->append(table_name, tab->table->getShare()->getTableNameSize());
2795
 
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
 
2741
    str->append(tab->table->getShare()->getTableNameRef());
2796
2742
  str->append(STRING_WITH_LEN(" on "));
2797
 
  str->append(key_info->name);
 
2743
  str->append(tab->table->key_info[tab->ref.key].name, strlen(tab->table->key_info[tab->ref.key].name));
2798
2744
  if (cond)
2799
2745
  {
2800
2746
    str->append(STRING_WITH_LEN(" where "));
2832
2778
  str->append(STRING_WITH_LEN("<index_lookup>("));
2833
2779
  tab->ref.items[0]->print(str);
2834
2780
  str->append(STRING_WITH_LEN(" in "));
2835
 
  str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
 
2781
  str->append(tab->table->getShare()->getTableNameRef());
2836
2782
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2837
2783
  str->append(STRING_WITH_LEN(" on "));
2838
 
  str->append(key_info->name);
 
2784
  str->append(key_info->name, strlen(key_info->name));
2839
2785
  if (check_null)
 
2786
  {
2840
2787
    str->append(STRING_WITH_LEN(" checking NULL"));
 
2788
  }
 
2789
 
2841
2790
  if (cond)
2842
2791
  {
2843
2792
    str->append(STRING_WITH_LEN(" where "));
2844
2793
    cond->print(str);
2845
2794
  }
 
2795
 
2846
2796
  if (having)
2847
2797
  {
2848
2798
    str->append(STRING_WITH_LEN(" having "));
2849
2799
    having->print(str);
2850
2800
  }
 
2801
 
2851
2802
  str->append(')');
2852
2803
}
2853
2804
 
3021
2972
    result stream in a temporary table. The temporary table itself is
3022
2973
    managed (created/filled/etc) internally by the interceptor.
3023
2974
  */
3024
 
  if (!(tmp_result_sink= new select_union))
3025
 
    return(true);
 
2975
  tmp_result_sink= new select_union;
3026
2976
 
3027
 
  if (tmp_result_sink->create_result_table(
3028
 
                         session, tmp_columns, true,
3029
 
                         session->options | TMP_TABLE_ALL_COLUMNS,
3030
 
                         "materialized subselect"))
3031
 
    return(true);
 
2977
  if (tmp_result_sink->create_result_table(session, tmp_columns, true, 
 
2978
    session->options | TMP_TABLE_ALL_COLUMNS, "materialized subselect"))
 
2979
    return true;
3032
2980
 
3033
2981
  tmp_table= tmp_result_sink->table;
3034
2982
  tmp_key= tmp_table->key_info;
3051
2999
    tmp_table= NULL;
3052
3000
    delete result;
3053
3001
    result= NULL;
3054
 
    return(true);
 
3002
    return true;
3055
3003
  }
3056
3004
  result= tmp_result_sink;
3057
3005
 
3071
3019
    - here we initialize only those members that are used by
3072
3020
      subselect_uniquesubquery_engine, so these objects are incomplete.
3073
3021
  */
3074
 
  if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
3075
 
    return(true);
3076
 
  new (tab) JoinTable();
 
3022
  tab= new (session->mem) JoinTable;
3077
3023
  tab->table= tmp_table;
3078
3024
  tab->ref.key= 0; /* The only temp table index. */
3079
3025
  tab->ref.key_length= tmp_key->key_length;
3080
 
  if (!(tab->ref.key_buff=
3081
 
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3082
 
      !(tab->ref.key_copy=
3083
 
        (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
3084
 
                                  (tmp_key_parts + 1)))) ||
3085
 
      !(tab->ref.items=
3086
 
        (Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
3087
 
    return(true);
 
3026
  tab->ref.key_buff= (unsigned char*) session->mem.calloc(ALIGN_SIZE(tmp_key->key_length) * 2);
 
3027
  tab->ref.key_copy= new (session->mem) StoredKey*[tmp_key_parts + 1];
 
3028
  tab->ref.items= new (session->mem) Item*[tmp_key_parts];
3088
3029
 
3089
3030
  KeyPartInfo *cur_key_part= tmp_key->key_part;
3090
3031
  StoredKey **ref_key= tab->ref.key_copy;
3110
3051
  tab->ref.key_err= 1;
3111
3052
  tab->ref.key_parts= tmp_key_parts;
3112
3053
 
3113
 
  return(false);
 
3054
  return false;
3114
3055
}
3115
3056
 
3116
3057
 
3122
3063
  @retval false if success
3123
3064
*/
3124
3065
 
3125
 
bool subselect_hash_sj_engine::init_runtime()
 
3066
void subselect_hash_sj_engine::init_runtime()
3126
3067
{
3127
3068
  /*
3128
3069
    Create and optimize the JOIN that will be used to materialize
3132
3073
  /* Let our engine reuse this query plan for materialization. */
3133
3074
  materialize_join= materialize_engine->join;
3134
3075
  materialize_join->change_result(result);
3135
 
  return false;
3136
3076
}
3137
3077
 
3138
3078
 
3184
3124
  if (!is_materialized)
3185
3125
  {
3186
3126
    int res= 0;
3187
 
    Select_Lex *save_select= session->getLex()->current_select;
3188
 
    session->getLex()->current_select= materialize_engine->select_lex;
 
3127
    Select_Lex *save_select= session->lex().current_select;
 
3128
    session->lex().current_select= materialize_engine->select_lex;
3189
3129
    if ((res= materialize_join->optimize()))
3190
3130
      goto err;
3191
3131
 
3192
 
    if (materialize_engine->save_join_if_explain())
3193
 
      goto err;
 
3132
    materialize_engine->save_join_if_explain();
3194
3133
 
3195
3134
    materialize_join->exec();
3196
3135
    if ((res= test(materialize_join->error || session->is_fatal_error)))
3218
3157
      empty_result_set= true;
3219
3158
      item_in->value= false;
3220
3159
      /* TODO: check we need this: item_in->null_value= false; */
3221
 
      return(false);
 
3160
      return false;
3222
3161
    }
3223
3162
    /* Set tmp_param only if its usable, i.e. tmp_param->copy_field != NULL. */
3224
3163
    tmp_param= &(item_in->unit->outer_select()->join->tmp_table_param);
3226
3165
      tmp_param= NULL;
3227
3166
 
3228
3167
err:
3229
 
    session->getLex()->current_select= save_select;
 
3168
    session->lex().current_select= save_select;
3230
3169
    if (res)
3231
 
      return(res);
 
3170
      return res;
3232
3171
  }
3233
3172
 
3234
3173
  /*