List:Commits« Previous MessageNext Message »
From:Martin Skold Date:April 23 2007 1:17pm
Subject:bk commit into 5.1 tree (mskold:1.2602)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of marty. When marty does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-04-23 15:17:30+02:00, mskold@stripped +3 -0
  Merge mysql.com:/windows/Linux_space/MySQL/mysql-5.0-ndb
  into  mysql.com:/windows/Linux_space/MySQL/mysql-5.1-new-ndb
  MERGE: 1.1810.2374.139

  sql/Makefile.am@stripped, 2007-04-23 14:37:57+02:00, mskold@stripped +0 -3
    Merge (using local), will hand merge.
    MERGE: 1.103.1.30

  sql/ha_ndbcluster.cc@stripped, 2007-04-23 15:17:25+02:00, mskold@stripped +11 -64
    Merge
    MERGE: 1.175.1.136

  sql/ha_ndbcluster.h@stripped, 2007-04-23 15:17:25+02:00, mskold@stripped +1 -4
    Merge
    MERGE: 1.82.4.15

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	mskold
# Host:	linux.site
# Root:	/windows/Linux_space/MySQL/mysql-5.1-new-ndb/RESYNC

--- 1.446/sql/ha_ndbcluster.cc	2007-04-23 15:17:42 +02:00
+++ 1.447/sql/ha_ndbcluster.cc	2007-04-23 15:17:42 +02:00
@@ -29,7 +29,7 @@
 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
 #include "ha_ndbcluster.h"
 #include <ndbapi/NdbApi.hpp>
-#include <ndbapi/NdbScanFilter.hpp>
+#include "ha_ndbcluster_cond.h"
 #include <../util/Bitmask.hpp>
 #include <ndbapi/NdbIndexStat.hpp>
 
@@ -2402,7 +2402,7 @@ int ha_ndbcluster::ordered_index_scan(co
 
   if (!restart)
   {
-    if (generate_scan_filter(m_cond_stack, op))
+    if (m_cond && m_cond->generate_scan_filter(op))
       DBUG_RETURN(ndb_err(trans));
 
     if ((res= define_read_attrs(buf, op)))
@@ -2508,8 +2508,14 @@ int ha_ndbcluster::unique_index_scan(con
         (get_ndb_partition_id(op)))
       ERR_RETURN(trans->getNdbError());
   }
-
-  if (generate_scan_filter_from_key(op, key_info, key, key_len, buf))
+  if (!m_cond)
+    m_cond= new ha_ndbcluster_cond;
+  if (!m_cond)
+  {
+    my_errno= HA_ERR_OUT_OF_MEM;
+    DBUG_RETURN(my_errno);
+  }    
+  if (m_cond->generate_scan_filter_from_key(op, key_info, key, key_len, buf))
     DBUG_RETURN(ndb_err(trans));
   if ((res= define_read_attrs(buf, op)))
     DBUG_RETURN(res);
@@ -2578,7 +2584,7 @@ int ha_ndbcluster::full_table_scan(byte 
       ERR_RETURN(trans->getNdbError());
   }
 
-  if (generate_scan_filter(m_cond_stack, op))
+  if (m_cond && m_cond->generate_scan_filter(op))
     DBUG_RETURN(ndb_err(trans));
   if ((res= define_read_attrs(buf, op)))
     DBUG_RETURN(res);
@@ -3949,7 +3955,10 @@ int ha_ndbcluster::extra(enum ha_extra_f
 int ha_ndbcluster::reset()
 {
   DBUG_ENTER("ha_ndbcluster::reset");
-  cond_clear();
+  if (m_cond)
+  {
+    m_cond->cond_clear();
+  }
   /*
     Regular partition pruning will set the bitmap appropriately.
     Some queries like ALTER TABLE doesn't use partition pruning and
@@ -6001,7 +6010,7 @@ ha_ndbcluster::ha_ndbcluster(handlerton 
   m_force_send(TRUE),
   m_autoincrement_prefetch((ha_rows) 32),
   m_transaction_on(TRUE),
-  m_cond_stack(NULL),
+  m_cond(NULL),
   m_multi_cursor(NULL)
 {
   int i;
@@ -6060,9 +6069,13 @@ ha_ndbcluster::~ha_ndbcluster() 
   }
   DBUG_ASSERT(m_active_trans == NULL);
 
-  // Discard the condition stack
-  DBUG_PRINT("info", ("Clearing condition stack"));
-  cond_clear();
+  // Discard any generated condition
+  DBUG_PRINT("info", ("Deleting generated condition"));
+  if (m_cond)
+  {
+    delete m_cond;
+    m_cond= NULL;
+  }
 
   DBUG_VOID_RETURN;
 }
@@ -8434,7 +8447,7 @@ ha_ndbcluster::read_multi_range_first(KE
         else if ((scanOp= m_active_trans->getNdbIndexScanOperation(idx, tab)) 
                  &&!scanOp->readTuples(lm, 0, parallelism, sorted, 
 				       FALSE, TRUE, need_pk, TRUE)
-                 &&!generate_scan_filter(m_cond_stack, scanOp)
+                 &&!(m_cond && m_cond->generate_scan_filter(scanOp))
                  &&!define_read_attrs(end_of_buffer-reclength, scanOp))
         {
           m_multi_cursor= scanOp;
@@ -8995,1465 +9008,8 @@ ndb_util_thread_fail:
   DBUG_RETURN(NULL);
 }
 
-/*
-  Condition pushdown
-*/
-/*
-  Push a condition to ndbcluster storage engine for evaluation 
-  during table   and index scans. The conditions will be stored on a stack
-  for possibly storing several conditions. The stack can be popped
-  by calling cond_pop, handler::extra(HA_EXTRA_RESET) (handler::reset())
-  will clear the stack.
-  The current implementation supports arbitrary AND/OR nested conditions
-  with comparisons between columns and constants (including constant
-  expressions and function calls) and the following comparison operators:
-  =, !=, >, >=, <, <=, "is null", and "is not null".
-  
-  RETURN
-    NULL The condition was supported and will be evaluated for each 
-    row found during the scan
-    cond The condition was not supported and all rows will be returned from
-         the scan for evaluation (and thus not saved on stack)
-*/
-const 
-COND* 
-ha_ndbcluster::cond_push(const COND *cond) 
-{ 
-  DBUG_ENTER("cond_push");
-  Ndb_cond_stack *ndb_cond = new Ndb_cond_stack();
-  if (ndb_cond == NULL)
-  {
-    my_errno= HA_ERR_OUT_OF_MEM;
-    DBUG_RETURN(NULL);
-  }
-  DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname););
-  if (m_cond_stack)
-    ndb_cond->next= m_cond_stack;
-  else
-    ndb_cond->next= NULL;
-  m_cond_stack= ndb_cond;
-  
-  if (serialize_cond(cond, ndb_cond))
-  {
-    DBUG_RETURN(NULL);
-  }
-  else
-  {
-    cond_pop();
-  }
-  DBUG_RETURN(cond); 
-}
-
-/*
-  Pop the top condition from the condition stack of the handler instance.
-*/
-void 
-ha_ndbcluster::cond_pop() 
-{ 
-  Ndb_cond_stack *ndb_cond_stack= m_cond_stack;  
-  if (ndb_cond_stack)
-  {
-    m_cond_stack= ndb_cond_stack->next;
-    delete ndb_cond_stack;
-  }
-}
-
-/*
-  Clear the condition stack
-*/
-void
-ha_ndbcluster::cond_clear()
-{
-  DBUG_ENTER("cond_clear");
-  while (m_cond_stack)
-    cond_pop();
-
-  DBUG_VOID_RETURN;
-}
-
-/*
-  Serialize the item tree into a linked list represented by Ndb_cond
-  for fast generation of NbdScanFilter. Adds information such as
-  position of fields that is not directly available in the Item tree.
-  Also checks if condition is supported.
-*/
-void ndb_serialize_cond(const Item *item, void *arg)
-{
-  Ndb_cond_traverse_context *context= (Ndb_cond_traverse_context *) arg;
-  DBUG_ENTER("ndb_serialize_cond");  
-
-  // Check if we are skipping arguments to a function to be evaluated
-  if (context->skip)
-  {
-    DBUG_PRINT("info", ("Skiping argument %d", context->skip));
-    context->skip--;
-    switch (item->type()) {
-    case Item::FUNC_ITEM:
-    {
-      Item_func *func_item= (Item_func *) item;
-      context->skip+= func_item->argument_count();
-      break;
-    }
-    case Item::INT_ITEM:
-    case Item::REAL_ITEM:
-    case Item::STRING_ITEM:
-    case Item::VARBIN_ITEM:
-    case Item::DECIMAL_ITEM:
-      break;
-    default:
-      context->supported= FALSE;
-      break;
-    }
-    
-    DBUG_VOID_RETURN;
-  }
-  
-  if (context->supported)
-  {
-    Ndb_rewrite_context *rewrite_context2= context->rewrite_stack;
-    const Item_func *rewrite_func_item;
-    // Check if we are rewriting some unsupported function call
-    if (rewrite_context2 &&
-        (rewrite_func_item= rewrite_context2->func_item) &&
-        rewrite_context2->count++ == 0)
-    {
-      switch (rewrite_func_item->functype()) {
-      case Item_func::BETWEEN:
-        /*
-          Rewrite 
-          <field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
-          to <field>|<const> > <const1>|<field1> AND 
-          <field>|<const> < <const2>|<field2>
-          or actually in prefix format
-          BEGIN(AND) GT(<field>|<const>, <const1>|<field1>), 
-          LT(<field>|<const>, <const2>|<field2>), END()
-        */
-      case Item_func::IN_FUNC:
-      {
-        /*
-          Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
-          to <field>|<const> = <const1>|<field1> OR 
-          <field> = <const2>|<field2> ...
-          or actually in prefix format
-          BEGIN(OR) EQ(<field>|<const>, <const1><field1>), 
-          EQ(<field>|<const>, <const2>|<field2>), ... END()
-          Each part of the disjunction is added for each call
-          to ndb_serialize_cond and end of rewrite statement 
-          is wrapped in end of ndb_serialize_cond
-        */
-        if (context->expecting(item->type()))
-        {
-          // This is the <field>|<const> item, save it in the rewrite context
-          rewrite_context2->left_hand_item= item;
-          if (item->type() == Item::FUNC_ITEM)
-          {
-            Item_func *func_item= (Item_func *) item;
-            if (func_item->functype() == Item_func::UNKNOWN_FUNC &&
-                func_item->const_item())
-            {
-              // Skip any arguments since we will evaluate function instead
-              DBUG_PRINT("info", ("Skip until end of arguments marker"));
-              context->skip= func_item->argument_count();
-            }
-            else
-            {
-              DBUG_PRINT("info", ("Found unsupported functional expression in BETWEEN|IN"));
-              context->supported= FALSE;
-              DBUG_VOID_RETURN;
-              
-            }
-          }
-        }
-        else
-        {
-          // Non-supported BETWEEN|IN expression
-          DBUG_PRINT("info", ("Found unexpected item of type %u in BETWEEN|IN",
-                              item->type()));
-          context->supported= FALSE;
-          DBUG_VOID_RETURN;
-        }
-        break;
-      }
-      default:
-        context->supported= FALSE;
-        break;
-      }
-      DBUG_VOID_RETURN;
-    }
-    else
-    {
-      Ndb_cond_stack *ndb_stack= context->stack_ptr;
-      Ndb_cond *prev_cond= context->cond_ptr;
-      Ndb_cond *curr_cond= context->cond_ptr= new Ndb_cond();
-      if (!ndb_stack->ndb_cond)
-        ndb_stack->ndb_cond= curr_cond;
-      curr_cond->prev= prev_cond;
-      if (prev_cond) prev_cond->next= curr_cond;
-    // Check if we are rewriting some unsupported function call
-      if (context->rewrite_stack)
-      {
-        Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
-        const Item_func *func_item= rewrite_context->func_item;
-        switch (func_item->functype()) {
-        case Item_func::BETWEEN:
-        {
-          /*
-            Rewrite 
-            <field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
-            to <field>|<const> > <const1>|<field1> AND 
-            <field>|<const> < <const2>|<field2>
-            or actually in prefix format
-            BEGIN(AND) GT(<field>|<const>, <const1>|<field1>), 
-            LT(<field>|<const>, <const2>|<field2>), END()
-          */
-          if (rewrite_context->count == 2)
-          {
-            // Lower limit of BETWEEN
-            DBUG_PRINT("info", ("GE_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(Item_func::GE_FUNC, 2);
-          }
-          else if (rewrite_context->count == 3)
-          {
-            // Upper limit of BETWEEN
-            DBUG_PRINT("info", ("LE_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(Item_func::LE_FUNC, 2);
-          }
-          else
-          {
-            // Illegal BETWEEN expression
-            DBUG_PRINT("info", ("Illegal BETWEEN expression"));
-            context->supported= FALSE;
-            DBUG_VOID_RETURN;
-          }
-          break;
-        }
-        case Item_func::IN_FUNC:
-        {
-          /*
-            Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
-            to <field>|<const> = <const1>|<field1> OR 
-            <field> = <const2>|<field2> ...
-            or actually in prefix format
-            BEGIN(OR) EQ(<field>|<const>, <const1><field1>), 
-            EQ(<field>|<const>, <const2>|<field2>), ... END()
-            Each part of the disjunction is added for each call
-            to ndb_serialize_cond and end of rewrite statement 
-            is wrapped in end of ndb_serialize_cond
-          */
-          DBUG_PRINT("info", ("EQ_FUNC"));      
-          curr_cond->ndb_item= new Ndb_item(Item_func::EQ_FUNC, 2);
-          break;
-        }
-        default:
-          context->supported= FALSE;
-        }
-        // Handle left hand <field>|<const>
-        context->rewrite_stack= NULL; // Disable rewrite mode
-        context->expect_only(Item::FIELD_ITEM);
-        context->expect_field_result(STRING_RESULT);
-        context->expect_field_result(REAL_RESULT);
-        context->expect_field_result(INT_RESULT);
-        context->expect_field_result(DECIMAL_RESULT);
-        context->expect(Item::INT_ITEM);
-        context->expect(Item::STRING_ITEM);
-        context->expect(Item::VARBIN_ITEM);
-        context->expect(Item::FUNC_ITEM);
-        ndb_serialize_cond(rewrite_context->left_hand_item, arg);
-        context->skip= 0; // Any FUNC_ITEM expression has already been parsed
-        context->rewrite_stack= rewrite_context; // Enable rewrite mode
-        if (!context->supported)
-          DBUG_VOID_RETURN;
-
-        prev_cond= context->cond_ptr;
-        curr_cond= context->cond_ptr= new Ndb_cond();
-        prev_cond->next= curr_cond;
-      }
-      
-      // Check for end of AND/OR expression
-      if (!item)
-      {
-        // End marker for condition group
-        DBUG_PRINT("info", ("End of condition group"));
-        curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
-      }
-      else
-      {
-        switch (item->type()) {
-        case Item::FIELD_ITEM:
-        {
-          Item_field *field_item= (Item_field *) item;
-          Field *field= field_item->field;
-          enum_field_types type= field->type();
-          /*
-            Check that the field is part of the table of the handler
-            instance and that we expect a field with of this result type.
-          */
-          if (context->table->s == field->table->s)
-          {       
-            const NDBTAB *tab= (const NDBTAB *) context->ndb_table;
-            DBUG_PRINT("info", ("FIELD_ITEM"));
-            DBUG_PRINT("info", ("table %s", tab->getName()));
-            DBUG_PRINT("info", ("column %s", field->field_name));
-            DBUG_PRINT("info", ("type %d", field->type()));
-            DBUG_PRINT("info", ("result type %d", field->result_type()));
-            
-            // Check that we are expecting a field and with the correct
-            // result type
-            if (context->expecting(Item::FIELD_ITEM) &&
-                context->expecting_field_type(field->type()) &&
-                (context->expecting_field_result(field->result_type()) ||
-                 // Date and year can be written as string or int
-                 ((type == MYSQL_TYPE_TIME ||
-                   type == MYSQL_TYPE_DATE || 
-                   type == MYSQL_TYPE_YEAR ||
-                   type == MYSQL_TYPE_DATETIME)
-                  ? (context->expecting_field_result(STRING_RESULT) ||
-                     context->expecting_field_result(INT_RESULT))
-                  : TRUE)) &&
-                // Bit fields no yet supported in scan filter
-                type != MYSQL_TYPE_BIT &&
-                // No BLOB support in scan filter
-                type != MYSQL_TYPE_TINY_BLOB &&
-                type != MYSQL_TYPE_MEDIUM_BLOB &&
-                type != MYSQL_TYPE_LONG_BLOB &&
-                type != MYSQL_TYPE_BLOB)
-            {
-              const NDBCOL *col= tab->getColumn(field->field_name);
-              DBUG_ASSERT(col);
-              curr_cond->ndb_item= new Ndb_item(field, col->getColumnNo());
-              context->dont_expect(Item::FIELD_ITEM);
-              context->expect_no_field_result();
-              if (! context->expecting_nothing())
-              {
-                // We have not seen second argument yet
-                if (type == MYSQL_TYPE_TIME ||
-                    type == MYSQL_TYPE_DATE || 
-                    type == MYSQL_TYPE_YEAR ||
-                    type == MYSQL_TYPE_DATETIME)
-                {
-                  context->expect_only(Item::STRING_ITEM);
-                  context->expect(Item::INT_ITEM);
-                }
-                else
-                  switch (field->result_type()) {
-                  case STRING_RESULT:
-                    // Expect char string or binary string
-                    context->expect_only(Item::STRING_ITEM);
-                    context->expect(Item::VARBIN_ITEM);
-                    context->expect_collation(field_item->collation.collation);
-                    break;
-                  case REAL_RESULT:
-                    context->expect_only(Item::REAL_ITEM);
-                    context->expect(Item::DECIMAL_ITEM);
-                    context->expect(Item::INT_ITEM);
-                    break;
-                  case INT_RESULT:
-                    context->expect_only(Item::INT_ITEM);
-                    context->expect(Item::VARBIN_ITEM);
-                    break;
-                  case DECIMAL_RESULT:
-                    context->expect_only(Item::DECIMAL_ITEM);
-                    context->expect(Item::REAL_ITEM);
-                    context->expect(Item::INT_ITEM);
-                    break;
-                  default:
-                    break;
-                  }    
-              }
-              else
-              {
-                // Expect another logical expression
-                context->expect_only(Item::FUNC_ITEM);
-                context->expect(Item::COND_ITEM);
-                // Check that field and string constant collations are the same
-                if ((field->result_type() == STRING_RESULT) &&
-                    !context->expecting_collation(item->collation.collation)
-                    && type != MYSQL_TYPE_TIME
-                    && type != MYSQL_TYPE_DATE
-                    && type != MYSQL_TYPE_YEAR
-                    && type != MYSQL_TYPE_DATETIME)
-                {
-                  DBUG_PRINT("info", ("Found non-matching collation %s",  
-                                      item->collation.collation->name)); 
-                  context->supported= FALSE;                
-                }
-              }
-              break;
-            }
-            else
-            {
-              DBUG_PRINT("info", ("Was not expecting field of type %u(%u)",
-                                  field->result_type(), type));
-              context->supported= FALSE;
-            }
-          }
-          else
-          {
-            DBUG_PRINT("info", ("Was not expecting field from table %s (%s)",
-                                context->table->s->table_name.str, 
-                                field->table->s->table_name.str));
-            context->supported= FALSE;
-          }
-          break;
-        }
-        case Item::FUNC_ITEM:
-        {
-          Item_func *func_item= (Item_func *) item;
-          // Check that we expect a function or functional expression here
-          if (context->expecting(Item::FUNC_ITEM) || 
-              func_item->functype() == Item_func::UNKNOWN_FUNC)
-            context->expect_nothing();
-          else
-          {
-            // Did not expect function here
-            context->supported= FALSE;
-            break;
-          }
-          
-          switch (func_item->functype()) {
-          case Item_func::EQ_FUNC:
-          {
-            DBUG_PRINT("info", ("EQ_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(), 
-                                              func_item);      
-            context->expect(Item::STRING_ITEM);
-            context->expect(Item::INT_ITEM);
-            context->expect(Item::REAL_ITEM);
-            context->expect(Item::DECIMAL_ITEM);
-            context->expect(Item::VARBIN_ITEM);
-            context->expect(Item::FIELD_ITEM);
-            context->expect_field_result(STRING_RESULT);
-            context->expect_field_result(REAL_RESULT);
-            context->expect_field_result(INT_RESULT);
-            context->expect_field_result(DECIMAL_RESULT);
-            break;
-          }
-          case Item_func::NE_FUNC:
-          {
-            DBUG_PRINT("info", ("NE_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(),
-                                              func_item);      
-            context->expect(Item::STRING_ITEM);
-            context->expect(Item::INT_ITEM);
-            context->expect(Item::REAL_ITEM);
-            context->expect(Item::DECIMAL_ITEM);
-            context->expect(Item::VARBIN_ITEM);
-            context->expect(Item::FIELD_ITEM);
-            context->expect_field_result(STRING_RESULT);
-            context->expect_field_result(REAL_RESULT);
-            context->expect_field_result(INT_RESULT);
-            context->expect_field_result(DECIMAL_RESULT);
-            break;
-          }
-          case Item_func::LT_FUNC:
-          {
-            DBUG_PRINT("info", ("LT_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(),
-                                              func_item);      
-            context->expect(Item::STRING_ITEM);
-            context->expect(Item::INT_ITEM);
-            context->expect(Item::REAL_ITEM);
-            context->expect(Item::DECIMAL_ITEM);
-            context->expect(Item::VARBIN_ITEM);
-            context->expect(Item::FIELD_ITEM);
-            context->expect_field_result(STRING_RESULT);
-            context->expect_field_result(REAL_RESULT);
-            context->expect_field_result(INT_RESULT);
-            context->expect_field_result(DECIMAL_RESULT);
-            break;
-          }
-          case Item_func::LE_FUNC:
-          {
-            DBUG_PRINT("info", ("LE_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(),
-                                              func_item);      
-            context->expect(Item::STRING_ITEM);
-            context->expect(Item::INT_ITEM);
-            context->expect(Item::REAL_ITEM);
-            context->expect(Item::DECIMAL_ITEM);
-            context->expect(Item::VARBIN_ITEM);
-            context->expect(Item::FIELD_ITEM);
-            context->expect_field_result(STRING_RESULT);
-            context->expect_field_result(REAL_RESULT);
-            context->expect_field_result(INT_RESULT);
-            context->expect_field_result(DECIMAL_RESULT);
-            break;
-          }
-          case Item_func::GE_FUNC:
-          {
-            DBUG_PRINT("info", ("GE_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(),
-                                              func_item);      
-            context->expect(Item::STRING_ITEM);
-            context->expect(Item::INT_ITEM);
-            context->expect(Item::REAL_ITEM);
-            context->expect(Item::DECIMAL_ITEM);
-            context->expect(Item::VARBIN_ITEM);
-            context->expect(Item::FIELD_ITEM);
-            context->expect_field_result(STRING_RESULT);
-            context->expect_field_result(REAL_RESULT);
-            context->expect_field_result(INT_RESULT);
-            context->expect_field_result(DECIMAL_RESULT);
-            break;
-          }
-          case Item_func::GT_FUNC:
-          {
-            DBUG_PRINT("info", ("GT_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(),
-                                              func_item);      
-            context->expect(Item::STRING_ITEM);
-            context->expect(Item::REAL_ITEM);
-            context->expect(Item::DECIMAL_ITEM);
-            context->expect(Item::INT_ITEM);
-            context->expect(Item::VARBIN_ITEM);
-            context->expect(Item::FIELD_ITEM);
-            context->expect_field_result(STRING_RESULT);
-            context->expect_field_result(REAL_RESULT);
-            context->expect_field_result(INT_RESULT);
-            context->expect_field_result(DECIMAL_RESULT);
-            break;
-          }
-          case Item_func::LIKE_FUNC:
-          {
-            DBUG_PRINT("info", ("LIKE_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(),
-                                              func_item);      
-            context->expect(Item::STRING_ITEM);
-            context->expect(Item::FIELD_ITEM);
-            context->expect_only_field_type(MYSQL_TYPE_STRING);
-            context->expect_field_type(MYSQL_TYPE_VAR_STRING);
-            context->expect_field_type(MYSQL_TYPE_VARCHAR);
-            context->expect_field_result(STRING_RESULT);
-            context->expect(Item::FUNC_ITEM);
-            break;
-          }
-          case Item_func::ISNULL_FUNC:
-          {
-            DBUG_PRINT("info", ("ISNULL_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(),
-                                              func_item);      
-            context->expect(Item::FIELD_ITEM);
-            context->expect_field_result(STRING_RESULT);
-            context->expect_field_result(REAL_RESULT);
-            context->expect_field_result(INT_RESULT);
-            context->expect_field_result(DECIMAL_RESULT);
-            break;
-          }
-          case Item_func::ISNOTNULL_FUNC:
-          {
-            DBUG_PRINT("info", ("ISNOTNULL_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(),
-                                              func_item);     
-            context->expect(Item::FIELD_ITEM);
-            context->expect_field_result(STRING_RESULT);
-            context->expect_field_result(REAL_RESULT);
-            context->expect_field_result(INT_RESULT);
-            context->expect_field_result(DECIMAL_RESULT);
-            break;
-          }
-          case Item_func::NOT_FUNC:
-          {
-            DBUG_PRINT("info", ("NOT_FUNC"));      
-            curr_cond->ndb_item= new Ndb_item(func_item->functype(),
-                                              func_item);     
-            context->expect(Item::FUNC_ITEM);
-            context->expect(Item::COND_ITEM);
-            break;
-          }
-          case Item_func::BETWEEN:
-          {
-            DBUG_PRINT("info", ("BETWEEN, rewriting using AND"));
-            Item_func_between *between_func= (Item_func_between *) func_item;
-            Ndb_rewrite_context *rewrite_context= 
-              new Ndb_rewrite_context(func_item);
-            rewrite_context->next= context->rewrite_stack;
-            context->rewrite_stack= rewrite_context;
-            if (between_func->negated)
-            {
-              DBUG_PRINT("info", ("NOT_FUNC"));
-              curr_cond->ndb_item= new Ndb_item(Item_func::NOT_FUNC, 1);
-              prev_cond= curr_cond;
-              curr_cond= context->cond_ptr= new Ndb_cond();
-              curr_cond->prev= prev_cond;
-              prev_cond->next= curr_cond;
-            }
-            DBUG_PRINT("info", ("COND_AND_FUNC"));
-            curr_cond->ndb_item= 
-              new Ndb_item(Item_func::COND_AND_FUNC, 
-                           func_item->argument_count() - 1);
-            context->expect_only(Item::FIELD_ITEM);
-            context->expect(Item::INT_ITEM);
-            context->expect(Item::STRING_ITEM);
-            context->expect(Item::VARBIN_ITEM);
-            context->expect(Item::FUNC_ITEM);
-            break;
-          }
-          case Item_func::IN_FUNC:
-          {
-            DBUG_PRINT("info", ("IN_FUNC, rewriting using OR"));
-            Item_func_in *in_func= (Item_func_in *) func_item;
-            Ndb_rewrite_context *rewrite_context= 
-              new Ndb_rewrite_context(func_item);
-            rewrite_context->next= context->rewrite_stack;
-            context->rewrite_stack= rewrite_context;
-            if (in_func->negated)
-            {
-              DBUG_PRINT("info", ("NOT_FUNC"));
-              curr_cond->ndb_item= new Ndb_item(Item_func::NOT_FUNC, 1);
-              prev_cond= curr_cond;
-              curr_cond= context->cond_ptr= new Ndb_cond();
-              curr_cond->prev= prev_cond;
-              prev_cond->next= curr_cond;
-            }
-            DBUG_PRINT("info", ("COND_OR_FUNC"));
-            curr_cond->ndb_item= new Ndb_item(Item_func::COND_OR_FUNC, 
-                                              func_item->argument_count() - 1);
-            context->expect_only(Item::FIELD_ITEM);
-            context->expect(Item::INT_ITEM);
-            context->expect(Item::STRING_ITEM);
-            context->expect(Item::VARBIN_ITEM);
-            context->expect(Item::FUNC_ITEM);
-            break;
-          }
-          case Item_func::UNKNOWN_FUNC:
-          {
-            DBUG_PRINT("info", ("UNKNOWN_FUNC %s", 
-                                func_item->const_item()?"const":""));  
-            DBUG_PRINT("info", ("result type %d", func_item->result_type()));
-            if (func_item->const_item())
-            {
-              switch (func_item->result_type()) {
-              case STRING_RESULT:
-              {
-                NDB_ITEM_QUALIFICATION q;
-                q.value_type= Item::STRING_ITEM;
-                curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); 
-                if (! context->expecting_no_field_result())
-                {
-                  // We have not seen the field argument yet
-                  context->expect_only(Item::FIELD_ITEM);
-                  context->expect_only_field_result(STRING_RESULT);
-                  context->expect_collation(func_item->collation.collation);
-                }
-                else
-                {
-                  // Expect another logical expression
-                  context->expect_only(Item::FUNC_ITEM);
-                  context->expect(Item::COND_ITEM);
-                  // Check that string result have correct collation
-                  if (!context->expecting_collation(item->collation.collation))
-                  {
-                    DBUG_PRINT("info", ("Found non-matching collation %s",  
-                                        item->collation.collation->name));
-                    context->supported= FALSE;
-                  }
-                }
-                // Skip any arguments since we will evaluate function instead
-                DBUG_PRINT("info", ("Skip until end of arguments marker"));
-                context->skip= func_item->argument_count();
-                break;
-              }
-              case REAL_RESULT:
-              {
-                NDB_ITEM_QUALIFICATION q;
-                q.value_type= Item::REAL_ITEM;
-                curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
-                if (! context->expecting_no_field_result()) 
-                {
-                  // We have not seen the field argument yet
-                  context->expect_only(Item::FIELD_ITEM);
-                  context->expect_only_field_result(REAL_RESULT);
-                }
-                else
-                {
-                  // Expect another logical expression
-                  context->expect_only(Item::FUNC_ITEM);
-                  context->expect(Item::COND_ITEM);
-                }
-                
-                // Skip any arguments since we will evaluate function instead
-                DBUG_PRINT("info", ("Skip until end of arguments marker"));
-                context->skip= func_item->argument_count();
-                break;
-              }
-              case INT_RESULT:
-              {
-                NDB_ITEM_QUALIFICATION q;
-                q.value_type= Item::INT_ITEM;
-                curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
-                if (! context->expecting_no_field_result()) 
-                {
-                  // We have not seen the field argument yet
-                  context->expect_only(Item::FIELD_ITEM);
-                  context->expect_only_field_result(INT_RESULT);
-                }
-                else
-                {
-                  // Expect another logical expression
-                  context->expect_only(Item::FUNC_ITEM);
-                  context->expect(Item::COND_ITEM);
-                }
-                
-                // Skip any arguments since we will evaluate function instead
-                DBUG_PRINT("info", ("Skip until end of arguments marker"));
-                context->skip= func_item->argument_count();
-                break;
-              }
-              case DECIMAL_RESULT:
-              {
-                NDB_ITEM_QUALIFICATION q;
-                q.value_type= Item::DECIMAL_ITEM;
-                curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
-                if (! context->expecting_no_field_result()) 
-                {
-                  // We have not seen the field argument yet
-                  context->expect_only(Item::FIELD_ITEM);
-                  context->expect_only_field_result(DECIMAL_RESULT);
-                }
-                else
-                {
-                  // Expect another logical expression
-                  context->expect_only(Item::FUNC_ITEM);
-                  context->expect(Item::COND_ITEM);
-                }
-                // Skip any arguments since we will evaluate function instead
-                DBUG_PRINT("info", ("Skip until end of arguments marker"));
-                context->skip= func_item->argument_count();
-                break;
-              }
-              default:
-                break;
-              }
-            }
-            else
-              // Function does not return constant expression
-              context->supported= FALSE;
-            break;
-          }
-          default:
-          {
-            DBUG_PRINT("info", ("Found func_item of type %d", 
-                                func_item->functype()));
-            context->supported= FALSE;
-          }
-          }
-          break;
-        }
-        case Item::STRING_ITEM:
-          DBUG_PRINT("info", ("STRING_ITEM")); 
-          if (context->expecting(Item::STRING_ITEM)) 
-          {
-#ifndef DBUG_OFF
-            char buff[256];
-            String str(buff,(uint32) sizeof(buff), system_charset_info);
-            str.length(0);
-            Item_string *string_item= (Item_string *) item;
-            DBUG_PRINT("info", ("value \"%s\"", 
-                                string_item->val_str(&str)->ptr()));
-#endif
-            NDB_ITEM_QUALIFICATION q;
-            q.value_type= Item::STRING_ITEM;
-            curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);      
-            if (! context->expecting_no_field_result())
-            {
-              // We have not seen the field argument yet
-              context->expect_only(Item::FIELD_ITEM);
-              context->expect_only_field_result(STRING_RESULT);
-              context->expect_collation(item->collation.collation);
-            }
-            else 
-            {
-              // Expect another logical expression
-              context->expect_only(Item::FUNC_ITEM);
-              context->expect(Item::COND_ITEM);
-              // Check that we are comparing with a field with same collation
-              if (!context->expecting_collation(item->collation.collation))
-              {
-                DBUG_PRINT("info", ("Found non-matching collation %s",  
-                                    item->collation.collation->name));
-                context->supported= FALSE;
-              }
-            }
-          }
-          else
-            context->supported= FALSE;
-          break;
-        case Item::INT_ITEM:
-          DBUG_PRINT("info", ("INT_ITEM"));
-          if (context->expecting(Item::INT_ITEM)) 
-          {
-            DBUG_PRINT("info", ("value %ld",
-                                (long) ((Item_int*) item)->value));
-            NDB_ITEM_QUALIFICATION q;
-            q.value_type= Item::INT_ITEM;
-            curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
-            if (! context->expecting_no_field_result()) 
-            {
-              // We have not seen the field argument yet
-              context->expect_only(Item::FIELD_ITEM);
-              context->expect_only_field_result(INT_RESULT);
-              context->expect_field_result(REAL_RESULT);
-              context->expect_field_result(DECIMAL_RESULT);
-            }
-            else
-            {
-              // Expect another logical expression
-              context->expect_only(Item::FUNC_ITEM);
-              context->expect(Item::COND_ITEM);
-            }
-          }
-          else
-            context->supported= FALSE;
-          break;
-        case Item::REAL_ITEM:
-          DBUG_PRINT("info", ("REAL_ITEM"));
-          if (context->expecting(Item::REAL_ITEM)) 
-          {
-            DBUG_PRINT("info", ("value %f", ((Item_float*) item)->value));
-            NDB_ITEM_QUALIFICATION q;
-            q.value_type= Item::REAL_ITEM;
-            curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
-            if (! context->expecting_no_field_result()) 
-            {
-              // We have not seen the field argument yet
-              context->expect_only(Item::FIELD_ITEM);
-              context->expect_only_field_result(REAL_RESULT);
-            }
-            else
-            {
-              // Expect another logical expression
-              context->expect_only(Item::FUNC_ITEM);
-              context->expect(Item::COND_ITEM);
-            }
-          }
-          else
-            context->supported= FALSE;
-          break;
-        case Item::VARBIN_ITEM:
-          DBUG_PRINT("info", ("VARBIN_ITEM"));
-          if (context->expecting(Item::VARBIN_ITEM)) 
-          {
-            NDB_ITEM_QUALIFICATION q;
-            q.value_type= Item::VARBIN_ITEM;
-            curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);      
-            if (! context->expecting_no_field_result())
-            {
-              // We have not seen the field argument yet
-              context->expect_only(Item::FIELD_ITEM);
-              context->expect_only_field_result(STRING_RESULT);
-            }
-            else
-            {
-              // Expect another logical expression
-              context->expect_only(Item::FUNC_ITEM);
-              context->expect(Item::COND_ITEM);
-            }
-          }
-          else
-            context->supported= FALSE;
-          break;
-        case Item::DECIMAL_ITEM:
-          DBUG_PRINT("info", ("DECIMAL_ITEM"));
-          if (context->expecting(Item::DECIMAL_ITEM)) 
-          {
-            DBUG_PRINT("info", ("value %f",
-                                ((Item_decimal*) item)->val_real()));
-            NDB_ITEM_QUALIFICATION q;
-            q.value_type= Item::DECIMAL_ITEM;
-            curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
-            if (! context->expecting_no_field_result()) 
-            {
-              // We have not seen the field argument yet
-              context->expect_only(Item::FIELD_ITEM);
-              context->expect_only_field_result(REAL_RESULT);
-              context->expect_field_result(DECIMAL_RESULT);
-            }
-            else
-            {
-              // Expect another logical expression
-              context->expect_only(Item::FUNC_ITEM);
-              context->expect(Item::COND_ITEM);
-            }
-          }
-          else
-            context->supported= FALSE;
-          break;
-        case Item::COND_ITEM:
-        {
-          Item_cond *cond_item= (Item_cond *) item;
-          
-          if (context->expecting(Item::COND_ITEM))
-          {
-            switch (cond_item->functype()) {
-            case Item_func::COND_AND_FUNC:
-              DBUG_PRINT("info", ("COND_AND_FUNC"));
-              curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
-                                                cond_item);      
-              break;
-            case Item_func::COND_OR_FUNC:
-              DBUG_PRINT("info", ("COND_OR_FUNC"));
-              curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
-                                                cond_item);      
-              break;
-            default:
-              DBUG_PRINT("info", ("COND_ITEM %d", cond_item->functype()));
-              context->supported= FALSE;
-              break;
-            }
-          }
-          else
-          {
-            /* Did not expect condition */
-            context->supported= FALSE;          
-          }
-          break;
-        }
-        default:
-        {
-          DBUG_PRINT("info", ("Found item of type %d", item->type()));
-          context->supported= FALSE;
-        }
-        }
-      }
-      if (context->supported && context->rewrite_stack)
-      {
-        Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
-        if (rewrite_context->count == 
-            rewrite_context->func_item->argument_count())
-        {
-          // Rewrite is done, wrap an END() at the en
-          DBUG_PRINT("info", ("End of condition group"));
-          prev_cond= curr_cond;
-          curr_cond= context->cond_ptr= new Ndb_cond();
-          curr_cond->prev= prev_cond;
-          prev_cond->next= curr_cond;
-          curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
-          // Pop rewrite stack
-          context->rewrite_stack=  rewrite_context->next;
-          rewrite_context->next= NULL;
-          delete(rewrite_context);
-        }
-      }
-    }
-  }
- 
-  DBUG_VOID_RETURN;
-}
-
-bool
-ha_ndbcluster::serialize_cond(const COND *cond, Ndb_cond_stack *ndb_cond)
-{
-  DBUG_ENTER("serialize_cond");
-  Item *item= (Item *) cond;
-  Ndb_cond_traverse_context context(table, (void *)m_table, ndb_cond);
-  // Expect a logical expression
-  context.expect(Item::FUNC_ITEM);
-  context.expect(Item::COND_ITEM);
-  item->traverse_cond(&ndb_serialize_cond, (void *) &context, Item::PREFIX);
-  DBUG_PRINT("info", ("The pushed condition is %ssupported", (context.supported)?"":"not "));
-
-  DBUG_RETURN(context.supported);
-}
-
 int
-ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, 
-                                           NdbScanFilter *filter,
-                                           bool negated)
-{
-  DBUG_ENTER("build_scan_filter_predicate");  
-  switch (cond->ndb_item->type) {
-  case NDB_FUNCTION:
-  {
-    if (!cond->next)
-      break;
-    Ndb_item *a= cond->next->ndb_item;
-    Ndb_item *b, *field, *value= NULL;
-
-    switch (cond->ndb_item->argument_count()) {
-    case 1:
-      field= (a->type == NDB_FIELD)? a : NULL;
-      break;
-    case 2:
-      if (!cond->next->next)
-      {
-        field= NULL;
-        break;
-      }
-      b= cond->next->next->ndb_item;
-      value= ((a->type == NDB_VALUE) ? a :
-              (b->type == NDB_VALUE) ? b :
-              NULL);
-      field= ((a->type == NDB_FIELD) ? a :
-              (b->type == NDB_FIELD) ? b :
-              NULL);
-      break;
-    default:
-      field= NULL; //Keep compiler happy
-      DBUG_ASSERT(0);
-      break;
-    }
-    switch ((negated) ? 
-            Ndb_item::negate(cond->ndb_item->qualification.function_type)
-            : cond->ndb_item->qualification.function_type) {
-    case NDB_EQ_FUNC:
-    {
-      if (!value || !field) break;
-      // Save value in right format for the field type
-      value->save_in_field(field);
-      DBUG_PRINT("info", ("Generating EQ filter"));
-      if (filter->cmp(NdbScanFilter::COND_EQ, 
-                      field->get_field_no(),
-                      field->get_val(),
-                      field->pack_length()) == -1)
-        DBUG_RETURN(1);
-      cond= cond->next->next->next;
-      DBUG_RETURN(0);
-    }
-    case NDB_NE_FUNC:
-    {
-      if (!value || !field) break;
-      // Save value in right format for the field type
-      value->save_in_field(field);
-      DBUG_PRINT("info", ("Generating NE filter"));
-      if (filter->cmp(NdbScanFilter::COND_NE, 
-                      field->get_field_no(),
-                      field->get_val(),
-                      field->pack_length()) == -1)
-        DBUG_RETURN(1);
-      cond= cond->next->next->next;
-      DBUG_RETURN(0);
-    }
-    case NDB_LT_FUNC:
-    {
-      if (!value || !field) break;
-      // Save value in right format for the field type
-      value->save_in_field(field);
-      if (a == field)
-      {
-        DBUG_PRINT("info", ("Generating LT filter")); 
-        if (filter->cmp(NdbScanFilter::COND_LT, 
-                        field->get_field_no(),
-                        field->get_val(),
-                        field->pack_length()) == -1)
-          DBUG_RETURN(1);
-      }
-      else
-      {
-        DBUG_PRINT("info", ("Generating GT filter")); 
-        if (filter->cmp(NdbScanFilter::COND_GT, 
-                        field->get_field_no(),
-                        field->get_val(),
-                        field->pack_length()) == -1)
-          DBUG_RETURN(1);
-      }
-      cond= cond->next->next->next;
-      DBUG_RETURN(0);
-    }
-    case NDB_LE_FUNC:
-    {
-      if (!value || !field) break;
-      // Save value in right format for the field type
-      value->save_in_field(field);
-      if (a == field)
-      {
-        DBUG_PRINT("info", ("Generating LE filter")); 
-        if (filter->cmp(NdbScanFilter::COND_LE, 
-                        field->get_field_no(),
-                        field->get_val(),
-                        field->pack_length()) == -1)
-          DBUG_RETURN(1);       
-      }
-      else
-      {
-        DBUG_PRINT("info", ("Generating GE filter")); 
-        if (filter->cmp(NdbScanFilter::COND_GE, 
-                        field->get_field_no(),
-                        field->get_val(),
-                        field->pack_length()) == -1)
-          DBUG_RETURN(1);
-      }
-      cond= cond->next->next->next;
-      DBUG_RETURN(0);
-    }
-    case NDB_GE_FUNC:
-    {
-      if (!value || !field) break;
-      // Save value in right format for the field type
-      value->save_in_field(field);
-      if (a == field)
-      {
-        DBUG_PRINT("info", ("Generating GE filter")); 
-        if (filter->cmp(NdbScanFilter::COND_GE, 
-                        field->get_field_no(),
-                        field->get_val(),
-                        field->pack_length()) == -1)
-          DBUG_RETURN(1);
-      }
-      else
-      {
-        DBUG_PRINT("info", ("Generating LE filter")); 
-        if (filter->cmp(NdbScanFilter::COND_LE, 
-                        field->get_field_no(),
-                        field->get_val(),
-                        field->pack_length()) == -1)
-          DBUG_RETURN(1);
-      }
-      cond= cond->next->next->next;
-      DBUG_RETURN(0);
-    }
-    case NDB_GT_FUNC:
-    {
-      if (!value || !field) break;
-      // Save value in right format for the field type
-      value->save_in_field(field);
-      if (a == field)
-      {
-        DBUG_PRINT("info", ("Generating GT filter"));
-        if (filter->cmp(NdbScanFilter::COND_GT, 
-                        field->get_field_no(),
-                        field->get_val(),
-                        field->pack_length()) == -1)
-          DBUG_RETURN(1);
-      }
-      else
-      {
-        DBUG_PRINT("info", ("Generating LT filter"));
-        if (filter->cmp(NdbScanFilter::COND_LT, 
-                        field->get_field_no(),
-                        field->get_val(),
-                        field->pack_length()) == -1)
-          DBUG_RETURN(1);
-      }
-      cond= cond->next->next->next;
-      DBUG_RETURN(0);
-    }
-    case NDB_LIKE_FUNC:
-    {
-      if (!value || !field) break;
-      if ((value->qualification.value_type != Item::STRING_ITEM) &&
-          (value->qualification.value_type != Item::VARBIN_ITEM))
-          break;
-      // Save value in right format for the field type
-      value->save_in_field(field);
-      DBUG_PRINT("info", ("Generating LIKE filter: like(%d,%s,%d)", 
-                          field->get_field_no(), value->get_val(), 
-                          value->pack_length()));
-      if (filter->cmp(NdbScanFilter::COND_LIKE, 
-                      field->get_field_no(),
-                      value->get_val(),
-                      value->pack_length()) == -1)
-        DBUG_RETURN(1);
-      cond= cond->next->next->next;
-      DBUG_RETURN(0);
-    }
-    case NDB_NOTLIKE_FUNC:
-    {
-      if (!value || !field) break;
-      if ((value->qualification.value_type != Item::STRING_ITEM) &&
-          (value->qualification.value_type != Item::VARBIN_ITEM))
-          break;
-      // Save value in right format for the field type
-      value->save_in_field(field);
-      DBUG_PRINT("info", ("Generating NOTLIKE filter: notlike(%d,%s,%d)", 
-                          field->get_field_no(), value->get_val(), 
-                          value->pack_length()));
-      if (filter->cmp(NdbScanFilter::COND_NOT_LIKE, 
-                      field->get_field_no(),
-                      value->get_val(),
-                      value->pack_length()) == -1)
-        DBUG_RETURN(1);
-      cond= cond->next->next->next;
-      DBUG_RETURN(0);
-    }
-    case NDB_ISNULL_FUNC:
-      if (!field)
-        break;
-      DBUG_PRINT("info", ("Generating ISNULL filter"));
-      if (filter->isnull(field->get_field_no()) == -1)
-        DBUG_RETURN(1);
-      cond= cond->next->next;
-      DBUG_RETURN(0);
-    case NDB_ISNOTNULL_FUNC:
-    {
-      if (!field)
-        break;
-      DBUG_PRINT("info", ("Generating ISNOTNULL filter"));
-      if (filter->isnotnull(field->get_field_no()) == -1)
-        DBUG_RETURN(1);         
-      cond= cond->next->next;
-      DBUG_RETURN(0);
-    }
-    default:
-      break;
-    }
-    break;
-  }
-  default:
-    break;
-  }
-  DBUG_PRINT("info", ("Found illegal condition"));
-  DBUG_RETURN(1);
-}
-
-
-int
-ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter)
-{
-  uint level=0;
-  bool negated= FALSE;
-  DBUG_ENTER("build_scan_filter_group");
-
-  do
-  {
-    if (!cond)
-      DBUG_RETURN(1);
-    switch (cond->ndb_item->type) {
-    case NDB_FUNCTION:
-    {
-      switch (cond->ndb_item->qualification.function_type) {
-      case NDB_COND_AND_FUNC:
-      {
-        level++;
-        DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NAND":"AND",
-                            level));
-        if ((negated) ? filter->begin(NdbScanFilter::NAND)
-            : filter->begin(NdbScanFilter::AND) == -1)
-          DBUG_RETURN(1);
-        negated= FALSE;
-        cond= cond->next;
-        break;
-      }
-      case NDB_COND_OR_FUNC:
-      {
-        level++;
-        DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NOR":"OR",
-                            level));
-        if ((negated) ? filter->begin(NdbScanFilter::NOR)
-            : filter->begin(NdbScanFilter::OR) == -1)
-          DBUG_RETURN(1);
-        negated= FALSE;
-        cond= cond->next;
-        break;
-      }
-      case NDB_NOT_FUNC:
-      {
-        DBUG_PRINT("info", ("Generating negated query"));
-        cond= cond->next;
-        negated= TRUE;
-        break;
-      }
-      default:
-        if (build_scan_filter_predicate(cond, filter, negated))
-          DBUG_RETURN(1);
-        negated= FALSE;
-        break;
-      }
-      break;
-    }
-    case NDB_END_COND:
-      DBUG_PRINT("info", ("End of group %u", level));
-      level--;
-      if (cond) cond= cond->next;
-      if (filter->end() == -1)
-        DBUG_RETURN(1);
-      if (!negated)
-        break;
-      // else fall through (NOT END is an illegal condition)
-    default:
-    {
-      DBUG_PRINT("info", ("Illegal scan filter"));
-    }
-    }
-  }  while (level > 0 || negated);
-  
-  DBUG_RETURN(0);
-}
-
-
-int
-ha_ndbcluster::build_scan_filter(Ndb_cond * &cond, NdbScanFilter *filter)
-{
-  bool simple_cond= TRUE;
-  DBUG_ENTER("build_scan_filter");  
-
-    switch (cond->ndb_item->type) {
-    case NDB_FUNCTION:
-      switch (cond->ndb_item->qualification.function_type) {
-      case NDB_COND_AND_FUNC:
-      case NDB_COND_OR_FUNC:
-        simple_cond= FALSE;
-        break;
-      default:
-        break;
-      }
-      break;
-    default:
-      break;
-    }
-  if (simple_cond && filter->begin() == -1)
-    DBUG_RETURN(1);
-  if (build_scan_filter_group(cond, filter))
-    DBUG_RETURN(1);
-  if (simple_cond && filter->end() == -1)
-    DBUG_RETURN(1);
-
-  DBUG_RETURN(0);
-}
-
-int
-ha_ndbcluster::generate_scan_filter(Ndb_cond_stack *ndb_cond_stack,
-                                    NdbScanOperation *op)
-{
-  DBUG_ENTER("generate_scan_filter");
-
-  if (ndb_cond_stack)
-  {
-    NdbScanFilter filter(op);
-    
-    DBUG_RETURN(generate_scan_filter_from_cond(ndb_cond_stack, filter));
-  }
-  else
-  {  
-    DBUG_PRINT("info", ("Empty stack"));
-  }
-
-  DBUG_RETURN(0);
-}
-
-
-int
-ha_ndbcluster::generate_scan_filter_from_cond(Ndb_cond_stack *ndb_cond_stack,
-					      NdbScanFilter& filter)
-{
-  bool multiple_cond= FALSE;
-  DBUG_ENTER("generate_scan_filter_from_cond");
-
-  // Wrap an AND group around multiple conditions
-  if (ndb_cond_stack->next) 
-  {
-    multiple_cond= TRUE;
-    if (filter.begin() == -1)
-      DBUG_RETURN(1); 
-  }
-  for (Ndb_cond_stack *stack= ndb_cond_stack; 
-       (stack); 
-       stack= stack->next)
-  {
-    Ndb_cond *cond= stack->ndb_cond;
-    
-    if (build_scan_filter(cond, &filter))
-    {
-      DBUG_PRINT("info", ("build_scan_filter failed"));
-      DBUG_RETURN(1);
-    }
-  }
-  if (multiple_cond && filter.end() == -1)
-    DBUG_RETURN(1);
-
-  DBUG_RETURN(0);
-}
-
-
-int ha_ndbcluster::generate_scan_filter_from_key(NdbScanOperation *op,
-						 const KEY* key_info, 
-						 const byte *key, 
-						 uint key_len,
-						 byte *buf)
-{
-  KEY_PART_INFO* key_part= key_info->key_part;
-  KEY_PART_INFO* end= key_part+key_info->key_parts;
-  NdbScanFilter filter(op);
-  int res;
-  DBUG_ENTER("generate_scan_filter_from_key");
-
-  filter.begin(NdbScanFilter::AND);
-  for (; key_part != end; key_part++) 
-  {
-    Field* field= key_part->field;
-    uint32 pack_len= field->pack_length();
-    const byte* ptr= key;
-    DBUG_PRINT("info", ("Filtering value for %s", field->field_name));
-    DBUG_DUMP("key", (char*)ptr, pack_len);
-    if (key_part->null_bit)
-    {
-      DBUG_PRINT("info", ("Generating ISNULL filter"));
-      if (filter.isnull(key_part->fieldnr-1) == -1)
-	DBUG_RETURN(1);
-    }
-    else
-    {
-      DBUG_PRINT("info", ("Generating EQ filter"));
-      if (filter.cmp(NdbScanFilter::COND_EQ, 
-		     key_part->fieldnr-1,
-		     ptr,
-		     pack_len) == -1)
-	DBUG_RETURN(1);
-    }
-    key += key_part->store_length;
-  }      
-  // Add any pushed condition
-  if (m_cond_stack &&
-      (res= generate_scan_filter_from_cond(m_cond_stack, filter)))
-    DBUG_RETURN(res);
-    
-  if (filter.end() == -1)
-    DBUG_RETURN(1);
-
-  DBUG_RETURN(0);
-}
-
-
-/*
-  get table space info for SHOW CREATE TABLE
-*/
-char* ha_ndbcluster::get_tablespace_name(THD *thd, char* name, uint name_len)
-{
-  Ndb *ndb= check_ndb_in_thd(thd);
-  NDBDICT *ndbdict= ndb->getDictionary();
-  NdbError ndberr;
-  Uint32 id;
-  ndb->setDatabaseName(m_dbname);
-  const NDBTAB *ndbtab= m_table;
-  DBUG_ASSERT(ndbtab != NULL);
-  if (!ndbtab->getTablespace(&id))
-  {
-    return 0;
-  }
-  {
-    NdbDictionary::Tablespace ts= ndbdict->getTablespace(id);
-    ndberr= ndbdict->getNdbError();
-    if(ndberr.classification != NdbError::NoError)
-      goto err;
-    DBUG_PRINT("info", ("Found tablespace '%s'", ts.getName()));
-    if (name)
-    {
-      strxnmov(name, name_len, ts.getName(), NullS);
-      return name;
-    }
-    else
-      return (my_strdup(ts.getName(), MYF(0)));
-  }
-err:
-  if (ndberr.status == NdbError::TemporaryError)
-    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-			ER_GET_TEMPORARY_ERRMSG, ER(ER_GET_TEMPORARY_ERRMSG),
-			ndberr.code, ndberr.message, "NDB");
-  else
-    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-			ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
-			ndberr.code, ndberr.message, "NDB");
-  return 0;
-}
-
-/*
-  Implements the SHOW NDB STATUS command.
-*/
-bool
-ndbcluster_show_status(handlerton *hton, THD* thd, stat_print_fn *stat_print,
-                       enum ha_stat_type stat_type)
-{
-  char buf[IO_SIZE];
-  uint buflen;
+ndbcluster_show_status(THD* thd)
   DBUG_ENTER("ndbcluster_show_status");
   
   if (have_ndbcluster != SHOW_OPTION_YES) 
@@ -10505,6 +9061,52 @@ ndbcluster_show_status(handlerton *hton,
 #endif
 
   DBUG_RETURN(FALSE);
+}
+
+/*
+  Condition pushdown
+*/
+/*
+  Push a condition to ndbcluster storage engine for evaluation 
+  during table   and index scans. The conditions will be stored on a stack
+  for possibly storing several conditions. The stack can be popped
+  by calling cond_pop, handler::extra(HA_EXTRA_RESET) (handler::reset())
+  will clear the stack.
+  The current implementation supports arbitrary AND/OR nested conditions
+  with comparisons between columns and constants (including constant
+  expressions and function calls) and the following comparison operators:
+  =, !=, >, >=, <, <=, "is null", and "is not null".
+  
+  RETURN
+    NULL The condition was supported and will be evaluated for each 
+    row found during the scan
+    cond The condition was not supported and all rows will be returned from
+         the scan for evaluation (and thus not saved on stack)
+*/
+const 
+COND* 
+ha_ndbcluster::cond_push(const COND *cond) 
+{ 
+  DBUG_ENTER("cond_push");
+  if (!m_cond) 
+    m_cond= new ha_ndbcluster_cond;
+  if (!m_cond)
+  {
+    my_errno= HA_ERR_OUT_OF_MEM;
+    DBUG_RETURN(NULL);
+  }
+  DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname););
+  DBUG_RETURN(m_cond->cond_push(cond, table, (NDBTAB *)m_table));
+}
+
+/*
+  Pop the top condition from the condition stack of the handler instance.
+*/
+void 
+ha_ndbcluster::cond_pop() 
+{ 
+  if (m_cond)
+    m_cond->cond_pop();
 }
 
 

--- 1.175/sql/ha_ndbcluster.h	2007-04-23 15:17:42 +02:00
+++ 1.176/sql/ha_ndbcluster.h	2007-04-23 15:17:42 +02:00
@@ -31,17 +31,17 @@
 #include <ndbapi_limits.h>
 
 #define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8
-
-class Ndb;             // Forward declaration
-class NdbOperation;    // Forward declaration
-class NdbTransaction;  // Forward declaration
-class NdbRecAttr;      // Forward declaration
+/* Forward declarations */
+class Ndb;             
+class NdbOperation;    
+class NdbTransaction;  
+class NdbRecAttr;      
 class NdbScanOperation; 
-class NdbScanFilter; 
 class NdbIndexScanOperation; 
 class NdbBlob;
 class NdbIndexStat;
 class NdbEventOperation;
+class ha_ndbcluster_cond;
 
 // connectstring to cluster if given by mysqld
 extern const char *ndbcluster_connectstring;
@@ -161,424 +161,6 @@ struct Ndb_tuple_id_range_guard {
 #define NSF_NO_BINLOG 4 /* table should not be binlogged */
 #endif
 
-typedef enum ndb_item_type {
-  NDB_VALUE = 0,   // Qualified more with Item::Type
-  NDB_FIELD = 1,   // Qualified from table definition
-  NDB_FUNCTION = 2,// Qualified from Item_func::Functype
-  NDB_END_COND = 3 // End marker for condition group
-} NDB_ITEM_TYPE;
-
-typedef enum ndb_func_type {
-  NDB_EQ_FUNC = 0,
-  NDB_NE_FUNC = 1,
-  NDB_LT_FUNC = 2,
-  NDB_LE_FUNC = 3,
-  NDB_GT_FUNC = 4,
-  NDB_GE_FUNC = 5,
-  NDB_ISNULL_FUNC = 6,
-  NDB_ISNOTNULL_FUNC = 7,
-  NDB_LIKE_FUNC = 8,
-  NDB_NOTLIKE_FUNC = 9,
-  NDB_NOT_FUNC = 10,
-  NDB_UNKNOWN_FUNC = 11,
-  NDB_COND_AND_FUNC = 12,
-  NDB_COND_OR_FUNC = 13,
-  NDB_UNSUPPORTED_FUNC = 14
-} NDB_FUNC_TYPE;
-
-typedef union ndb_item_qualification {
-  Item::Type value_type; 
-  enum_field_types field_type; // Instead of Item::FIELD_ITEM
-  NDB_FUNC_TYPE function_type; // Instead of Item::FUNC_ITEM
-} NDB_ITEM_QUALIFICATION;
-
-typedef struct ndb_item_field_value {
-  Field* field;
-  int column_no;
-} NDB_ITEM_FIELD_VALUE;
-
-typedef union ndb_item_value {
-  const Item *item;
-  NDB_ITEM_FIELD_VALUE *field_value;
-  uint arg_count;
-} NDB_ITEM_VALUE;
-
-struct negated_function_mapping
-{
-  NDB_FUNC_TYPE pos_fun;
-  NDB_FUNC_TYPE neg_fun;
-};
-
-
-/*
-  Define what functions can be negated in condition pushdown.
-  Note, these HAVE to be in the same order as in definition enum
-*/
-static const negated_function_mapping neg_map[]= 
-{
-  {NDB_EQ_FUNC, NDB_NE_FUNC},
-  {NDB_NE_FUNC, NDB_EQ_FUNC},
-  {NDB_LT_FUNC, NDB_GE_FUNC},
-  {NDB_LE_FUNC, NDB_GT_FUNC},
-  {NDB_GT_FUNC, NDB_LE_FUNC},
-  {NDB_GE_FUNC, NDB_LT_FUNC},
-  {NDB_ISNULL_FUNC, NDB_ISNOTNULL_FUNC},
-  {NDB_ISNOTNULL_FUNC, NDB_ISNULL_FUNC},
-  {NDB_LIKE_FUNC, NDB_NOTLIKE_FUNC},
-  {NDB_NOTLIKE_FUNC, NDB_LIKE_FUNC},
-  {NDB_NOT_FUNC, NDB_UNSUPPORTED_FUNC},
-  {NDB_UNKNOWN_FUNC, NDB_UNSUPPORTED_FUNC},
-  {NDB_COND_AND_FUNC, NDB_UNSUPPORTED_FUNC},
-  {NDB_COND_OR_FUNC, NDB_UNSUPPORTED_FUNC},
-  {NDB_UNSUPPORTED_FUNC, NDB_UNSUPPORTED_FUNC}
-};
-  
-/*
-  This class is the construction element for serialization of Item tree 
-  in condition pushdown.
-  An instance of Ndb_Item represents a constant, table field reference,
-  unary or binary comparison predicate, and start/end of AND/OR.
-  Instances of Ndb_Item are stored in a linked list implemented by Ndb_cond
-  class.
-  The order of elements produced by Ndb_cond::next corresponds to
-  breadth-first traversal of the Item (i.e. expression) tree in prefix order.
-  AND and OR have arbitrary arity, so the end of AND/OR group is marked with  
-  Ndb_item with type == NDB_END_COND.
-  NOT items represent negated conditions and generate NAND/NOR groups.
-*/
-class Ndb_item {
- public:
-  Ndb_item(NDB_ITEM_TYPE item_type) : type(item_type) {};
-  Ndb_item(NDB_ITEM_TYPE item_type, 
-           NDB_ITEM_QUALIFICATION item_qualification,
-           const Item *item_value)
-    : type(item_type), qualification(item_qualification)
-  { 
-    switch(item_type) {
-    case(NDB_VALUE):
-      value.item= item_value;
-      break;
-    case(NDB_FIELD): {
-      NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE();
-      Item_field *field_item= (Item_field *) item_value;
-      field_value->field= field_item->field;
-      field_value->column_no= -1; // Will be fetched at scan filter generation
-      value.field_value= field_value;
-      break;
-    }
-    case(NDB_FUNCTION):
-      value.item= item_value;
-      value.arg_count= ((Item_func *) item_value)->argument_count();
-      break;
-    case(NDB_END_COND):
-      break;
-    }
-  };
-  Ndb_item(Field *field, int column_no) : type(NDB_FIELD)
-  {
-    NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE();
-    qualification.field_type= field->type();
-    field_value->field= field;
-    field_value->column_no= column_no;
-    value.field_value= field_value;
-  };
-  Ndb_item(Item_func::Functype func_type, const Item *item_value) 
-    : type(NDB_FUNCTION)
-  {
-    qualification.function_type= item_func_to_ndb_func(func_type);
-    value.item= item_value;
-    value.arg_count= ((Item_func *) item_value)->argument_count();
-  };
-  Ndb_item(Item_func::Functype func_type, uint no_args) 
-    : type(NDB_FUNCTION)
-  {
-    qualification.function_type= item_func_to_ndb_func(func_type);
-    value.arg_count= no_args;
-  };
-  ~Ndb_item()
-  { 
-    if (type == NDB_FIELD)
-      {
-        delete value.field_value;
-        value.field_value= NULL;
-      }
-  };
-
-  uint32 pack_length() 
-  { 
-    switch(type) {
-    case(NDB_VALUE):
-      if(qualification.value_type == Item::STRING_ITEM)
-        return value.item->str_value.length();
-      break;
-    case(NDB_FIELD):
-      return value.field_value->field->pack_length(); 
-    default:
-      break;
-    }
-    
-    return 0;
-  };
-
-  Field * get_field() { return value.field_value->field; };
-
-  int get_field_no() { return value.field_value->column_no; };
-
-  int argument_count() 
-  { 
-    return value.arg_count;
-  };
-
-  const char* get_val() 
-  {  
-    switch(type) {
-    case(NDB_VALUE):
-      if(qualification.value_type == Item::STRING_ITEM)
-        return value.item->str_value.ptr();
-      break;
-    case(NDB_FIELD):
-      return value.field_value->field->ptr; 
-    default:
-      break;
-    }
-    
-    return NULL;
-  };
-
-  void save_in_field(Ndb_item *field_item)
-  {
-    Field *field = field_item->value.field_value->field;
-    const Item *item= value.item;
-
-    if (item && field)
-    {
-      my_bitmap_map *old_map=
-        dbug_tmp_use_all_columns(field->table, field->table->write_set);
-      ((Item *)item)->save_in_field(field, FALSE);
-      dbug_tmp_restore_column_map(field->table->write_set, old_map);
-    }
-  };
-
-  static NDB_FUNC_TYPE item_func_to_ndb_func(Item_func::Functype fun)
-  {
-    switch (fun) {
-    case (Item_func::EQ_FUNC): { return NDB_EQ_FUNC; }
-    case (Item_func::NE_FUNC): { return NDB_NE_FUNC; }
-    case (Item_func::LT_FUNC): { return NDB_LT_FUNC; }
-    case (Item_func::LE_FUNC): { return NDB_LE_FUNC; }
-    case (Item_func::GT_FUNC): { return NDB_GT_FUNC; }
-    case (Item_func::GE_FUNC): { return NDB_GE_FUNC; }
-    case (Item_func::ISNULL_FUNC): { return NDB_ISNULL_FUNC; }
-    case (Item_func::ISNOTNULL_FUNC): { return NDB_ISNOTNULL_FUNC; }
-    case (Item_func::LIKE_FUNC): { return NDB_LIKE_FUNC; }
-    case (Item_func::NOT_FUNC): { return NDB_NOT_FUNC; }
-    case (Item_func::UNKNOWN_FUNC): { return NDB_UNKNOWN_FUNC; }
-    case (Item_func::COND_AND_FUNC): { return NDB_COND_AND_FUNC; }
-    case (Item_func::COND_OR_FUNC): { return NDB_COND_OR_FUNC; }
-    default: { return NDB_UNSUPPORTED_FUNC; }
-    }
-  };
-
-  static NDB_FUNC_TYPE negate(NDB_FUNC_TYPE fun)
-  {
-    uint i= (uint) fun;
-    DBUG_ASSERT(fun == neg_map[i].pos_fun);
-    return  neg_map[i].neg_fun;
-  };
-
-  NDB_ITEM_TYPE type;
-  NDB_ITEM_QUALIFICATION qualification;
- private:
-  NDB_ITEM_VALUE value;
-};
-
-/*
-  This class implements a linked list used for storing a
-  serialization of the Item tree for condition pushdown.
- */
-class Ndb_cond 
-{
- public:
-  Ndb_cond() : ndb_item(NULL), next(NULL), prev(NULL) {};
-  ~Ndb_cond() 
-  { 
-    if (ndb_item) delete ndb_item; 
-    ndb_item= NULL; 
-    if (next) delete next;
-    next= prev= NULL; 
-  };
-  Ndb_item *ndb_item;
-  Ndb_cond *next;
-  Ndb_cond *prev;
-};
-
-/*
-  This class implements a stack for storing several conditions
-  for pushdown (represented as serialized Item trees using Ndb_cond).
-  The current implementation only pushes one condition, but is
-  prepared for handling several (C1 AND C2 ...) if the logic for 
-  pushing conditions is extended in sql_select.
-*/
-class Ndb_cond_stack 
-{
- public:
-  Ndb_cond_stack() : ndb_cond(NULL), next(NULL) {};
-  ~Ndb_cond_stack() 
-  { 
-    if (ndb_cond) delete ndb_cond; 
-    ndb_cond= NULL; 
-    if (next) delete next;
-    next= NULL; 
-  };
-  Ndb_cond *ndb_cond;
-  Ndb_cond_stack *next;
-};
-
-class Ndb_rewrite_context
-{
-public:
-  Ndb_rewrite_context(Item_func *func) 
-    : func_item(func), left_hand_item(NULL), count(0) {};
-  ~Ndb_rewrite_context()
-  {
-    if (next) delete next;
-  }
-  const Item_func *func_item;
-  const Item *left_hand_item;
-  uint count;
-  Ndb_rewrite_context *next;
-};
-
-/*
-  This class is used for storing the context when traversing
-  the Item tree. It stores a reference to the table the condition
-  is defined on, the serialized representation being generated, 
-  if the condition found is supported, and information what is
-  expected next in the tree inorder for the condition to be supported.
-*/
-class Ndb_cond_traverse_context 
-{
- public:
-  Ndb_cond_traverse_context(TABLE *tab, void* ndb_tab, Ndb_cond_stack* stack)
-    : table(tab), ndb_table(ndb_tab), 
-    supported(TRUE), stack_ptr(stack), cond_ptr(NULL),
-    skip(0), collation(NULL), rewrite_stack(NULL)
-  {
-    // Allocate type checking bitmaps   
-    bitmap_init(&expect_mask, 0, 512, FALSE);
-    bitmap_init(&expect_field_type_mask, 0, 512, FALSE);
-    bitmap_init(&expect_field_result_mask, 0, 512, FALSE);
-
-    if (stack)
-      cond_ptr= stack->ndb_cond;
-  };
-  ~Ndb_cond_traverse_context()
-  {
-    bitmap_free(&expect_mask);
-    bitmap_free(&expect_field_type_mask);
-    bitmap_free(&expect_field_result_mask);
-    if (rewrite_stack) delete rewrite_stack;
-  }
-  void expect(Item::Type type)
-  {
-    bitmap_set_bit(&expect_mask, (uint) type);
-    if (type == Item::FIELD_ITEM) expect_all_field_types();
-  };
-  void dont_expect(Item::Type type)
-  {
-    bitmap_clear_bit(&expect_mask, (uint) type);
-  };
-  bool expecting(Item::Type type)
-  {
-    return bitmap_is_set(&expect_mask, (uint) type);
-  };
-  void expect_nothing()
-  {
-    bitmap_clear_all(&expect_mask);
-  };
-  bool expecting_nothing()
-  {
-    return bitmap_is_clear_all(&expect_mask);
-  }
-  void expect_only(Item::Type type)
-  {
-    expect_nothing();
-    expect(type);
-  };
-
-  void expect_field_type(enum_field_types type)
-  {
-    bitmap_set_bit(&expect_field_type_mask, (uint) type);
-  };
-  void expect_all_field_types()
-  {
-    bitmap_set_all(&expect_field_type_mask);
-  };
-  bool expecting_field_type(enum_field_types type)
-  {
-    return bitmap_is_set(&expect_field_type_mask, (uint) type);
-  };
-  void expect_no_field_type()
-  {
-    bitmap_clear_all(&expect_field_type_mask);
-  };
-  bool expecting_no_field_type()
-  {
-    return bitmap_is_clear_all(&expect_field_type_mask);
-  }
-  void expect_only_field_type(enum_field_types result)
-  {
-    expect_no_field_type();
-    expect_field_type(result);
-  };
-
-  void expect_field_result(Item_result result)
-  {
-    bitmap_set_bit(&expect_field_result_mask, (uint) result);
-  };
-  bool expecting_field_result(Item_result result)
-  {
-    return bitmap_is_set(&expect_field_result_mask, (uint) result);
-  };
-  void expect_no_field_result()
-  {
-    bitmap_clear_all(&expect_field_result_mask);
-  };
-  bool expecting_no_field_result()
-  {
-    return bitmap_is_clear_all(&expect_field_result_mask);
-  }
-  void expect_only_field_result(Item_result result)
-  {
-    expect_no_field_result();
-    expect_field_result(result);
-  };
-  void expect_collation(CHARSET_INFO* col)
-  {
-    collation= col;
-  };
-  bool expecting_collation(CHARSET_INFO* col)
-  {
-    bool matching= (!collation) ? true : (collation == col);
-    collation= NULL;
-
-    return matching;
-  };
-
-  TABLE* table;
-  void* ndb_table;
-  bool supported;
-  Ndb_cond_stack* stack_ptr;
-  Ndb_cond* cond_ptr;
-  MY_BITMAP expect_mask;
-  MY_BITMAP expect_field_type_mask;
-  MY_BITMAP expect_field_result_mask;
-  uint skip;
-  CHARSET_INFO* collation;
-  Ndb_rewrite_context *rewrite_stack;
-};
-
-
 typedef enum ndb_query_state_bits {
   NDB_QUERY_NORMAL = 0,
   NDB_QUERY_MULTI_READ_RANGE = 1
@@ -903,29 +485,6 @@ private:
   void no_uncommitted_rows_update(int);
   void no_uncommitted_rows_reset(THD *);
 
-  void release_completed_operations(NdbTransaction*, bool);
-
-  /*
-    Condition pushdown
-  */
-  void cond_clear();
-  bool serialize_cond(const COND *cond, Ndb_cond_stack *ndb_cond);
-  int build_scan_filter_predicate(Ndb_cond* &cond, 
-                                  NdbScanFilter* filter,
-                                  bool negated= false);
-  int build_scan_filter_group(Ndb_cond* &cond, 
-                              NdbScanFilter* filter);
-  int build_scan_filter(Ndb_cond* &cond, NdbScanFilter* filter);
-  int generate_scan_filter(Ndb_cond_stack* cond_stack, 
-                           NdbScanOperation* op);
-  int generate_scan_filter_from_cond(Ndb_cond_stack* cond_stack, 
-				     NdbScanFilter& filter);
-  int generate_scan_filter_from_key(NdbScanOperation* op,
-                                   const KEY* key_info, 
-                                   const byte *key, 
-                                   uint key_len,
-                                   byte *buf);
-
   friend int execute_commit(ha_ndbcluster*, NdbTransaction*);
   friend int execute_no_commit_ignore_no_key(ha_ndbcluster*, NdbTransaction*);
   friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*, bool);
@@ -980,7 +539,7 @@ private:
   ha_rows m_autoincrement_prefetch;
   bool m_transaction_on;
 
-  Ndb_cond_stack *m_cond_stack;
+  ha_ndbcluster_cond *m_cond;
   bool m_disable_multi_read;
   byte *m_multi_range_result_ptr;
   KEY_MULTI_RANGE *m_multi_ranges;
Thread
bk commit into 5.1 tree (mskold:1.2602)Martin Skold23 Apr