~skinny.moey/drizzle/transaction_id_innodb

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Joseph Daly
  • Date: 2010-10-31 20:44:18 UTC
  • mfrom: (1856.2.38 build)
  • Revision ID: skinny.moey@gmail.com-20101031204418-dq03jokakmudu3iu
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
447
447
  return (cond? (new Item_cond_and(cond, item)) : item);
448
448
}
449
449
 
450
 
static void fix_list_after_tbl_changes(Select_Lex *new_parent, List<TableList> *tlist)
451
 
{
452
 
  List_iterator<TableList> it(*tlist);
453
 
  TableList *table;
454
 
  while ((table= it++))
455
 
  {
456
 
    if (table->on_expr)
457
 
      table->on_expr->fix_after_pullout(new_parent, &table->on_expr);
458
 
    if (table->getNestedJoin())
459
 
      fix_list_after_tbl_changes(new_parent, &table->getNestedJoin()->join_list);
460
 
  }
461
 
}
462
 
 
463
450
/*****************************************************************************
464
451
  Create JoinTableS, make a guess about the table types,
465
452
  Approximate how many records will be used in each table
1216
1203
  return tmp;
1217
1204
}
1218
1205
 
1219
 
/*
1220
 
  Check if given expression uses only table fields covered by the given index
1221
 
 
1222
 
  SYNOPSIS
1223
 
    uses_index_fields_only()
1224
 
      item           Expression to check
1225
 
      tbl            The table having the index
1226
 
      keyno          The index number
1227
 
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
1228
 
 
1229
 
  DESCRIPTION
1230
 
    Check if given expression only uses fields covered by index #keyno in the
1231
 
    table tbl. The expression can use any fields in any other tables.
1232
 
 
1233
 
    The expression is guaranteed not to be AND or OR - those constructs are
1234
 
    handled outside of this function.
1235
 
 
1236
 
  RETURN
1237
 
    true   Yes
1238
 
    false  No
1239
 
*/
1240
 
static bool uses_index_fields_only(Item *item, Table *tbl, uint32_t keyno, bool other_tbls_ok)
1241
 
{
1242
 
  if (item->const_item())
1243
 
    return true;
1244
 
 
1245
 
  /*
1246
 
    Don't push down the triggered conditions. Nested outer joins execution
1247
 
    code may need to evaluate a condition several times (both triggered and
1248
 
    untriggered), and there is no way to put thi
1249
 
    TODO: Consider cloning the triggered condition and using the copies for:
1250
 
      1. push the first copy down, to have most restrictive index condition
1251
 
         possible
1252
 
      2. Put the second copy into tab->select_cond.
1253
 
  */
1254
 
  if (item->type() == Item::FUNC_ITEM &&
1255
 
      ((Item_func*)item)->functype() == Item_func::TRIG_COND_FUNC)
1256
 
    return false;
1257
 
 
1258
 
  if (!(item->used_tables() & tbl->map))
1259
 
    return other_tbls_ok;
1260
 
 
1261
 
  Item::Type item_type= item->type();
1262
 
  switch (item_type) {
1263
 
  case Item::FUNC_ITEM:
1264
 
    {
1265
 
      /* This is a function, apply condition recursively to arguments */
1266
 
      Item_func *item_func= (Item_func*)item;
1267
 
      Item **child;
1268
 
      Item **item_end= (item_func->arguments()) + item_func->argument_count();
1269
 
      for (child= item_func->arguments(); child != item_end; child++)
1270
 
      {
1271
 
        if (!uses_index_fields_only(*child, tbl, keyno, other_tbls_ok))
1272
 
          return false;
1273
 
      }
1274
 
      return true;
1275
 
    }
1276
 
  case Item::COND_ITEM:
1277
 
    {
1278
 
      /* This is a function, apply condition recursively to arguments */
1279
 
      List_iterator<Item> li(*((Item_cond*)item)->argument_list());
1280
 
      Item *list_item;
1281
 
      while ((list_item=li++))
1282
 
      {
1283
 
        if (!uses_index_fields_only(item, tbl, keyno, other_tbls_ok))
1284
 
          return false;
1285
 
      }
1286
 
      return true;
1287
 
    }
1288
 
  case Item::FIELD_ITEM:
1289
 
    {
1290
 
      Item_field *item_field= (Item_field*)item;
1291
 
      if (item_field->field->getTable() != tbl)
1292
 
        return true;
1293
 
      return item_field->field->part_of_key.test(keyno);
1294
 
    }
1295
 
  case Item::REF_ITEM:
1296
 
    return uses_index_fields_only(item->real_item(), tbl, keyno,
1297
 
                                  other_tbls_ok);
1298
 
  default:
1299
 
    return false; /* Play it safe, don't push unknown non-const items */
1300
 
  }
1301
 
}
1302
 
 
1303
1206
#define ICP_COND_USES_INDEX_ONLY 10
1304
1207
 
1305
 
/*
1306
 
  Get a part of the condition that can be checked using only index fields
1307
 
 
1308
 
  SYNOPSIS
1309
 
    make_cond_for_index()
1310
 
      cond           The source condition
1311
 
      table          The table that is partially available
1312
 
      keyno          The index in the above table. Only fields covered by the index
1313
 
                     are available
1314
 
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
1315
 
 
1316
 
  DESCRIPTION
1317
 
    Get a part of the condition that can be checked when for the given table
1318
 
    we have values only of fields covered by some index. The condition may
1319
 
    refer to other tables, it is assumed that we have values of all of their
1320
 
    fields.
1321
 
 
1322
 
    Example:
1323
 
      make_cond_for_index(
1324
 
         "cond(t1.field) AND cond(t2.key1) AND cond(t2.non_key) AND cond(t2.key2)",
1325
 
          t2, keyno(t2.key1))
1326
 
      will return
1327
 
        "cond(t1.field) AND cond(t2.key2)"
1328
 
 
1329
 
  RETURN
1330
 
    Index condition, or NULL if no condition could be inferred.
1331
 
*/
1332
 
static Item *make_cond_for_index(Item *cond, Table *table, uint32_t keyno, bool other_tbls_ok)
1333
 
{
1334
 
  if (!cond)
1335
 
    return NULL;
1336
 
  if (cond->type() == Item::COND_ITEM)
1337
 
  {
1338
 
    uint32_t n_marked= 0;
1339
 
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1340
 
    {
1341
 
      Item_cond_and *new_cond=new Item_cond_and;
1342
 
      if (!new_cond)
1343
 
        return (COND*) 0;
1344
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1345
 
      Item *item;
1346
 
      while ((item=li++))
1347
 
      {
1348
 
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
1349
 
        if (fix)
1350
 
          new_cond->argument_list()->push_back(fix);
1351
 
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
1352
 
      }
1353
 
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
1354
 
        cond->marker= ICP_COND_USES_INDEX_ONLY;
1355
 
      switch (new_cond->argument_list()->elements) {
1356
 
      case 0:
1357
 
        return (COND*) 0;
1358
 
      case 1:
1359
 
        return new_cond->argument_list()->head();
1360
 
      default:
1361
 
        new_cond->quick_fix_field();
1362
 
        return new_cond;
1363
 
      }
1364
 
    }
1365
 
    else /* It's OR */
1366
 
    {
1367
 
      Item_cond_or *new_cond=new Item_cond_or;
1368
 
      if (!new_cond)
1369
 
        return (COND*) 0;
1370
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1371
 
      Item *item;
1372
 
      while ((item=li++))
1373
 
      {
1374
 
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
1375
 
        if (!fix)
1376
 
          return (COND*) 0;
1377
 
        new_cond->argument_list()->push_back(fix);
1378
 
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
1379
 
      }
1380
 
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
1381
 
        cond->marker= ICP_COND_USES_INDEX_ONLY;
1382
 
      new_cond->quick_fix_field();
1383
 
      new_cond->top_level_item();
1384
 
      return new_cond;
1385
 
    }
1386
 
  }
1387
 
 
1388
 
  if (!uses_index_fields_only(cond, table, keyno, other_tbls_ok))
1389
 
    return (COND*) 0;
1390
 
  cond->marker= ICP_COND_USES_INDEX_ONLY;
1391
 
  return cond;
1392
 
}
1393
 
 
1394
 
 
1395
 
static Item *make_cond_remainder(Item *cond, bool exclude_index)
1396
 
{
1397
 
  if (exclude_index && cond->marker == ICP_COND_USES_INDEX_ONLY)
1398
 
    return 0; /* Already checked */
1399
 
 
1400
 
  if (cond->type() == Item::COND_ITEM)
1401
 
  {
1402
 
    table_map tbl_map= 0;
1403
 
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1404
 
    {
1405
 
      /* Create new top level AND item */
1406
 
      Item_cond_and *new_cond=new Item_cond_and;
1407
 
      if (!new_cond)
1408
 
        return (COND*) 0;
1409
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1410
 
      Item *item;
1411
 
      while ((item=li++))
1412
 
      {
1413
 
        Item *fix= make_cond_remainder(item, exclude_index);
1414
 
        if (fix)
1415
 
        {
1416
 
          new_cond->argument_list()->push_back(fix);
1417
 
          tbl_map |= fix->used_tables();
1418
 
        }
1419
 
      }
1420
 
      switch (new_cond->argument_list()->elements) {
1421
 
      case 0:
1422
 
        return (COND*) 0;
1423
 
      case 1:
1424
 
        return new_cond->argument_list()->head();
1425
 
      default:
1426
 
        new_cond->quick_fix_field();
1427
 
        ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
1428
 
        return new_cond;
1429
 
      }
1430
 
    }
1431
 
    else /* It's OR */
1432
 
    {
1433
 
      Item_cond_or *new_cond=new Item_cond_or;
1434
 
      if (!new_cond)
1435
 
        return (COND*) 0;
1436
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1437
 
      Item *item;
1438
 
      while ((item=li++))
1439
 
      {
1440
 
        Item *fix= make_cond_remainder(item, false);
1441
 
        if (!fix)
1442
 
          return (COND*) 0;
1443
 
        new_cond->argument_list()->push_back(fix);
1444
 
        tbl_map |= fix->used_tables();
1445
 
      }
1446
 
      new_cond->quick_fix_field();
1447
 
      ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
1448
 
      new_cond->top_level_item();
1449
 
      return new_cond;
1450
 
    }
1451
 
  }
1452
 
  return cond;
1453
 
}
1454
1208
 
1455
1209
/**
1456
1210
  cleanup JoinTable.