=== modified file 'storage/ndb/src/ndbapi/NdbScanFilter.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanFilter.cpp	2008-04-07 09:56:30 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanFilter.cpp	2008-08-06 15:33:19 +0000
@@ -75,7 +75,11 @@
     m_code= code;
     m_associated_op= NULL;
     
-    m_error.code = 0;
+    if (code == NULL)
+      /* NdbInterpretedCode not supported for operation type */
+      m_error.code = 4539;
+    else
+      m_error.code = 0;
   };
 
   /* This method propagates an error code from NdbInterpretedCode
@@ -136,13 +140,22 @@
 {
   DBUG_ENTER("NdbScanFilter::NdbScanFilter(NdbOperation)");
   
-  /* We ask the NdbScanOperation to allocate an InterpretedCode
-   * object for us.  It will look after freeing it when 
-   * necessary.  This allows the InterpretedCode object to 
-   * survive after the NdbScanFilter has gone out of scope
+  NdbInterpretedCode* code= NULL;
+  NdbOperation::Type opType= op->getType();
+
+  /* If the operation is not of the correct type then
+   * m_impl.init() will set an error on the scan filter
    */
-  NdbInterpretedCode* code= 
-    ((NdbScanOperation *)op)->allocInterpretedCodeOldApi();
+  if (likely((opType == NdbOperation::TableScan) || 
+             (opType == NdbOperation::OrderedIndexScan)))
+  {    
+    /* We ask the NdbScanOperation to allocate an InterpretedCode
+     * object for us.  It will look after freeing it when 
+     * necessary.  This allows the InterpretedCode object to 
+     * survive after the NdbScanFilter has gone out of scope
+     */
+    code= ((NdbScanOperation *)op)->allocInterpretedCodeOldApi();
+  }
 
   m_impl.init(code);
 
@@ -158,6 +171,8 @@
 
 int
 NdbScanFilter::begin(Group group){
+  if (m_impl.m_error.code != 0) return -1;
+
   if (m_impl.m_stack2.push_back(m_impl.m_negative))
   {
     /* Memory allocation problem */
@@ -244,6 +259,8 @@
 
 int
 NdbScanFilter::end(){
+  if (m_impl.m_error.code != 0) return -1;
+
   if(m_impl.m_stack2.size() == 0){
     /* Invalid set of range scan bounds */
     m_impl.m_error.code= 4259;
@@ -353,6 +370,8 @@
 
 int
 NdbScanFilter::istrue(){
+  if(m_impl.m_error.code != 0) return -1;
+
   if(m_impl.m_current.m_group < NdbScanFilter::AND || 
      m_impl.m_current.m_group > NdbScanFilter::NOR){
     /* Operator is not defined in NdbScanFilter::Group */
@@ -373,6 +392,7 @@
 
 int
 NdbScanFilter::isfalse(){
+  if (m_impl.m_error.code != 0) return -1;
   if(m_impl.m_current.m_group < NdbScanFilter::AND || 
      m_impl.m_current.m_group > NdbScanFilter::NOR){
     /* Operator is not defined in NdbScanFilter::Group */
@@ -436,6 +456,8 @@
 int
 NdbScanFilterImpl::cond_col(Interpreter::UnaryCondition op, Uint32 AttrId){
   
+  if (m_error.code != 0) return -1;
+
   if(op < 0 || op >= tab2_sz){
     /* Condition is out of bounds */
     m_error.code= 4262;
@@ -458,6 +480,8 @@
 
 int
 NdbScanFilter::isnull(int AttrId){
+  if (m_impl.m_error.code != 0) return -1;
+
   if(m_impl.m_negative == 1)
     return m_impl.cond_col(Interpreter::IS_NOT_NULL, AttrId);
   else
@@ -466,6 +490,8 @@
 
 int
 NdbScanFilter::isnotnull(int AttrId){
+  if (m_impl.m_error.code != 0) return -1;
+
   if(m_impl.m_negative == 1)
     return m_impl.cond_col(Interpreter::IS_NULL, AttrId);
   else
@@ -568,6 +594,8 @@
 NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, 
 				  Uint32 AttrId, 
 				  const void * value, Uint32 len){
+  if (m_error.code != 0) return -1;
+
   if(op < 0 || op >= tab3_sz){
     /* Condition is out of bounds */
     m_error.code= 4262;

=== modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2008-06-03 15:03:16 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2008-08-06 15:39:54 +0000
@@ -53,7 +53,7 @@
   theSCAN_TABREQ = 0;
   m_executed = false;
   m_scan_buffer= NULL;
-  m_scanUsingOldApi= false;
+  m_scanUsingOldApi= true;
   m_interpretedCodeOldApi= NULL;
 }
 
@@ -119,7 +119,7 @@
   m_descending= false;
   m_read_range_no = 0;
   m_executed = false;
-  m_scanUsingOldApi= false;
+  m_scanUsingOldApi= true;
   m_interpretedCodeOldApi= NULL;
 
   m_api_receivers_count = 0;
@@ -944,16 +944,14 @@
                              Uint32 parallel,
                              Uint32 batch)
 {
-  // It is only possible to call readTuples if 
-  //  1. the scan transaction doesn't already  contain another scan operation
-  //  2. We have not already defined an old Api scan operation.
-  if (theNdbCon->theScanningOp != NULL ||
-      m_scanUsingOldApi ){
+  // It is only possible to call readTuples if the scan transaction 
+  // doesn't already contain a scan operation
+  if (theNdbCon->theScanningOp != NULL)
+  {
     setErrorCode(4605);
     return -1;
   }
-
-  m_scanUsingOldApi= true;
+  
   /* Save parameters for later */
   m_savedLockModeOldApi= lm;
   m_savedScanFlagsOldApi= scan_flags;

=== modified file 'storage/ndb/src/ndbapi/NdbTransaction.cpp'
--- a/storage/ndb/src/ndbapi/NdbTransaction.cpp	2008-06-03 16:18:01 +0000
+++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp	2008-08-06 15:39:54 +0000
@@ -2583,6 +2583,8 @@
     DBUG_RETURN(NULL);
   }
 
+  op_idx->m_scanUsingOldApi= false;
+
   /* The real work is done in NdbScanOperation */
   if (op_idx->scanTableImpl(result_record,
                             lock_mode,
@@ -2622,6 +2624,8 @@
     return NULL;
   }
 
+  op->m_scanUsingOldApi= false;
+
   /* Defer the rest of the work to NdbIndexScanOperation */
   if (op->scanIndexImpl(key_record,
                         result_record,

=== modified file 'storage/ndb/test/ndbapi/testScanFilter.cpp'
--- a/storage/ndb/test/ndbapi/testScanFilter.cpp	2008-02-19 15:00:29 +0000
+++ b/storage/ndb/test/ndbapi/testScanFilter.cpp	2008-08-06 15:33:19 +0000
@@ -894,6 +894,132 @@
   return NDBT_OK;
 }
 
+
+int runScanFilterConstructorFail(NDBT_Context* ctx, NDBT_Step* step)
+{
+  /* We test that failures in the ScanFilter constructor can be
+   * detected by the various ScanFilter methods without
+   * issues
+   */
+  Ndb *myNdb = GETNDB(step);
+  const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
+  const NdbDictionary::Table *myTable= myDict->getTable(TABLE_NAME);
+  if(myTable == NULL) 
+    APIERROR(myDict->getNdbError());
+
+  NdbTransaction* trans=myNdb->startTransaction();
+  
+  if (trans == NULL)
+  {
+    APIERROR(trans->getNdbError());
+    return NDBT_FAILED;
+  }
+  
+  /* Create an NdbRecord scan operation */
+  const NdbScanOperation* tabScan=
+    trans->scanTable(myTable->getDefaultRecord());
+  
+  if (tabScan==NULL)
+  {
+    APIERROR(trans->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  /* Now we hackily try to add a ScanFilter after the operation
+   * is defined.  This will cause a failure within the 
+   * constructor
+   */
+  NdbScanFilter brokenSf((NdbScanOperation*) tabScan);
+
+  /* Scan operation should have an error */
+  if (tabScan->getNdbError().code != 4536)
+  {
+    ndbout << "Expected error 4536, had error " << 
+      tabScan->getNdbError().code << " instead" << endl;
+    return NDBT_FAILED;
+  }
+
+  /* ScanFilter should have an error */
+  if (brokenSf.getNdbError().code != 4539)
+  {
+    ndbout  << "Expected error 4539, had error " << 
+      brokenSf.getNdbError().code << " instead" << endl;
+    return NDBT_FAILED;
+  }
+  
+  if (brokenSf.begin() != -1)
+  { ndbout << "Bad rc from begin" << endl; return NDBT_FAILED; }
+
+  if (brokenSf.istrue() != -1)
+  { ndbout << "Bad rc from istrue" << endl; return NDBT_FAILED; }
+
+  if (brokenSf.isfalse() != -1)
+  { ndbout << "Bad rc from isfalse" << endl; return NDBT_FAILED; }
+
+  if (brokenSf.isnull(0) != -1)
+  { ndbout << "Bad rc from isnull" << endl; return NDBT_FAILED; }
+
+  if (brokenSf.isnotnull(0) != -1)
+  { ndbout << "Bad rc from isnotnull" << endl; return NDBT_FAILED; }
+
+  if (brokenSf.cmp(NdbScanFilter::COND_EQ, 0, NULL, 0) != -1)
+  { ndbout << "Bad rc from cmp" << endl; return NDBT_FAILED; }
+
+  if (brokenSf.end() != -1)
+  { ndbout << "Bad rc from begin" << endl; return NDBT_FAILED; }
+
+  trans->close();
+
+  /* Now we check that we can define a ScanFilter before 
+   * calling readTuples() for a scan operation
+   */
+  trans= myNdb->startTransaction();
+  
+  if (trans == NULL)
+  {
+    APIERROR(trans->getNdbError());
+    return NDBT_FAILED;
+  }
+  
+  /* Get an old Api table scan operation */
+  NdbScanOperation* tabScanOp=
+    trans->getNdbScanOperation(myTable);
+
+  if (tabScanOp==NULL)
+  {
+    APIERROR(trans->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  /* Attempt to define a ScanFilter before calling readTuples() */
+  NdbScanFilter sf(tabScanOp);
+
+  /* Should be no problem ... */
+  if (sf.getNdbError().code != 0) 
+  { APIERROR(sf.getNdbError()); return NDBT_FAILED; };
+  
+ 
+  /* Ok, now attempt to define a ScanFilter against a primary key op */
+  NdbOperation* pkOp= trans->getNdbOperation(myTable);
+
+  if (pkOp == NULL)
+  {
+    APIERROR(trans->getNdbError());
+    return NDBT_FAILED;
+  }
+
+  NdbScanFilter sf2(pkOp);
+  
+  if (sf2.getNdbError().code != 4539)
+  {
+    ndbout << "Error, expected 4539" << endl;
+    APIERROR(sf2.getNdbError());
+    return NDBT_FAILED;
+  }
+
+  return NDBT_OK;
+}
+
 NDBT_TESTSUITE(testScanFilter);
 TESTCASE(TEST_NAME, 
 	 "Scan table TABLE_NAME for the records which accord with \
@@ -903,6 +1029,7 @@
   INITIALIZER(runPopulate);
   INITIALIZER(runScanRandomFilterTest);
   INITIALIZER(runMaxScanFilterSize);
+  INITIALIZER(runScanFilterConstructorFail);
   FINALIZER(runDropTables);
 }
 

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2008-08-05 10:13:56 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2008-08-06 15:39:54 +0000
@@ -1171,3 +1171,9 @@
 args -n bug37672 T1
 
 #EOF 2008-07-04
+
+max-time: 500
+cmd: testScanFilter
+args: 
+
+#EOF 2008-07-09



