NdbScanFilter.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:18k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <NdbScanFilter.hpp>
  14. #include <NdbOperation.hpp>
  15. #include "NdbDictionaryImpl.hpp"
  16. #include <Vector.hpp>
  17. #include <NdbOut.hpp>
  18. #include <Interpreter.hpp>
  19. #ifdef VM_TRACE
  20. #include <NdbEnv.h>
  21. #define INT_DEBUG(x) 
  22.   { const char* tmp = NdbEnv_GetEnv("INT_DEBUG", (char*)0, 0); 
  23.   if (tmp != 0 && strlen(tmp) != 0) { ndbout << "INT:"; ndbout_c x; } }
  24. #else
  25. #define INT_DEBUG(x)
  26. #endif
  27. class NdbScanFilterImpl {
  28. public:
  29.   struct State {
  30.     NdbScanFilter::Group m_group;
  31.     Uint32 m_popCount;
  32.     Uint32 m_ownLabel;
  33.     Uint32 m_trueLabel;
  34.     Uint32 m_falseLabel;
  35.   };
  36.   int m_label;
  37.   State m_current;
  38.   Vector<State> m_stack;
  39.   NdbOperation * m_operation;
  40.   Uint32 m_latestAttrib;
  41.   int cond_col(Interpreter::UnaryCondition, Uint32 attrId);
  42.   
  43.   template<typename T>
  44.   int cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, T value);
  45.   int cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, 
  46.      const char * value, Uint32 len, bool nopad);
  47. };
  48. const Uint32 LabelExit = ~0;
  49. NdbScanFilter::NdbScanFilter(class NdbOperation * op)
  50.   : m_impl(* new NdbScanFilterImpl())
  51. {
  52.   m_impl.m_current.m_group = (NdbScanFilter::Group)0;
  53.   m_impl.m_current.m_popCount = 0;
  54.   m_impl.m_current.m_ownLabel = 0;
  55.   m_impl.m_current.m_trueLabel = ~0;
  56.   m_impl.m_current.m_falseLabel = ~0;
  57.   m_impl.m_label = 0;
  58.   m_impl.m_latestAttrib = ~0;
  59.   m_impl.m_operation = op;
  60. }
  61. NdbScanFilter::~NdbScanFilter(){
  62.   delete &m_impl;
  63. }
  64.  
  65. int
  66. NdbScanFilter::begin(Group group){
  67.   switch(group){
  68.   case NdbScanFilter::AND:
  69.     INT_DEBUG(("Begin(AND)"));
  70.     break;
  71.   case NdbScanFilter::OR:
  72.     INT_DEBUG(("Begin(OR)"));
  73.     break;
  74.   case NdbScanFilter::NAND:
  75.     INT_DEBUG(("Begin(NAND)"));
  76.     break;
  77.   case NdbScanFilter::NOR:
  78.     INT_DEBUG(("Begin(NOR)"));
  79.     break;
  80.   }
  81.   if(group == m_impl.m_current.m_group){
  82.     switch(group){
  83.     case NdbScanFilter::AND:
  84.     case NdbScanFilter::OR:
  85.       m_impl.m_current.m_popCount++;
  86.       return 0;
  87.     case NdbScanFilter::NOR:
  88.     case NdbScanFilter::NAND:
  89.       break;
  90.     }
  91.   }
  92.   NdbScanFilterImpl::State tmp = m_impl.m_current;
  93.   m_impl.m_stack.push_back(m_impl.m_current);
  94.   m_impl.m_current.m_group = group;
  95.   m_impl.m_current.m_ownLabel = m_impl.m_label++;
  96.   m_impl.m_current.m_popCount = 0;
  97.   
  98.   switch(group){
  99.   case NdbScanFilter::AND:
  100.   case NdbScanFilter::NAND:
  101.     m_impl.m_current.m_falseLabel = m_impl.m_current.m_ownLabel;
  102.     m_impl.m_current.m_trueLabel = tmp.m_trueLabel;
  103.     break;
  104.   case NdbScanFilter::OR:
  105.   case NdbScanFilter::NOR:
  106.     m_impl.m_current.m_falseLabel = tmp.m_falseLabel;
  107.     m_impl.m_current.m_trueLabel = m_impl.m_current.m_ownLabel;
  108.     break;
  109.   default: 
  110.     m_impl.m_operation->setErrorCodeAbort(4260);
  111.     return -1;
  112.   }
  113.   
  114.   return 0;
  115. }
  116. int
  117. NdbScanFilter::end(){
  118.   switch(m_impl.m_current.m_group){
  119.   case NdbScanFilter::AND:
  120.     INT_DEBUG(("End(AND pc=%d)", m_impl.m_current.m_popCount));
  121.     break;
  122.   case NdbScanFilter::OR:
  123.     INT_DEBUG(("End(OR pc=%d)", m_impl.m_current.m_popCount));
  124.     break;
  125.   case NdbScanFilter::NAND:
  126.     INT_DEBUG(("End(NAND pc=%d)", m_impl.m_current.m_popCount));
  127.     break;
  128.   case NdbScanFilter::NOR:
  129.     INT_DEBUG(("End(NOR pc=%d)", m_impl.m_current.m_popCount));
  130.     break;
  131.   }
  132.   if(m_impl.m_current.m_popCount > 0){
  133.     m_impl.m_current.m_popCount--;
  134.     return 0;
  135.   }
  136.   
  137.   NdbScanFilterImpl::State tmp = m_impl.m_current;  
  138.   m_impl.m_current = m_impl.m_stack.back();
  139.   m_impl.m_stack.erase(m_impl.m_stack.size() - 1);
  140.   
  141.   switch(tmp.m_group){
  142.   case NdbScanFilter::AND:
  143.     if(tmp.m_trueLabel == (Uint32)~0){
  144.       m_impl.m_operation->interpret_exit_ok();
  145.     } else {
  146.       m_impl.m_operation->branch_label(tmp.m_trueLabel);
  147.     }
  148.     break;
  149.   case NdbScanFilter::NAND:
  150.     if(tmp.m_trueLabel == (Uint32)~0){
  151.       m_impl.m_operation->interpret_exit_nok();
  152.     } else {
  153.       m_impl.m_operation->branch_label(tmp.m_falseLabel);
  154.     }
  155.     break;
  156.   case NdbScanFilter::OR:
  157.     if(tmp.m_falseLabel == (Uint32)~0){
  158.       m_impl.m_operation->interpret_exit_nok();
  159.     } else {
  160.       m_impl.m_operation->branch_label(tmp.m_falseLabel);
  161.     }
  162.     break;
  163.   case NdbScanFilter::NOR:
  164.     if(tmp.m_falseLabel == (Uint32)~0){
  165.       m_impl.m_operation->interpret_exit_ok();
  166.     } else {
  167.       m_impl.m_operation->branch_label(tmp.m_trueLabel);
  168.     }
  169.     break;
  170.   default:
  171.     m_impl.m_operation->setErrorCodeAbort(4260);
  172.     return -1;
  173.   }
  174.   m_impl.m_operation->def_label(tmp.m_ownLabel);
  175.   if(m_impl.m_stack.size() == 0){
  176.     switch(tmp.m_group){
  177.     case NdbScanFilter::AND:
  178.     case NdbScanFilter::NOR:
  179.       m_impl.m_operation->interpret_exit_nok();
  180.       break;
  181.     case NdbScanFilter::OR:
  182.     case NdbScanFilter::NAND:
  183.       m_impl.m_operation->interpret_exit_ok();
  184.       break;
  185.     default:
  186.       m_impl.m_operation->setErrorCodeAbort(4260);
  187.       return -1;
  188.     }
  189.   }
  190.   
  191.   return 0;
  192. }
  193. int
  194. NdbScanFilter::istrue(){
  195.   if(m_impl.m_current.m_group < NdbScanFilter::AND || 
  196.      m_impl.m_current.m_group > NdbScanFilter::NOR){
  197.     m_impl.m_operation->setErrorCodeAbort(4260);
  198.     return -1;
  199.   }
  200.   if(m_impl.m_current.m_trueLabel == (Uint32)~0){
  201.     return m_impl.m_operation->interpret_exit_ok();
  202.   } else {
  203.     return m_impl.m_operation->branch_label(m_impl.m_current.m_trueLabel);
  204.   }
  205. }
  206. int
  207. NdbScanFilter::isfalse(){
  208.   if(m_impl.m_current.m_group < NdbScanFilter::AND || 
  209.      m_impl.m_current.m_group > NdbScanFilter::NOR){
  210.     m_impl.m_operation->setErrorCodeAbort(4260);
  211.     return -1;
  212.   }
  213.   
  214.   if(m_impl.m_current.m_falseLabel == (Uint32)~0){
  215.     return m_impl.m_operation->interpret_exit_nok();
  216.   } else {
  217.     return m_impl.m_operation->branch_label(m_impl.m_current.m_falseLabel);
  218.   }
  219. }
  220. #define action(x, y, z)
  221. typedef int (NdbOperation:: * Branch1)(Uint32, Uint32 label);
  222. typedef int (NdbOperation:: * Branch2)(Uint32, Uint32, Uint32 label);
  223. typedef int (NdbOperation:: * StrBranch2)(Uint32, const char*,Uint32,bool,Uint32);
  224. struct tab {
  225.   Branch2 m_branches[5];
  226. };
  227. static const tab table[] = {
  228.   /**
  229.    * EQ (AND, OR, NAND, NOR)
  230.    */
  231.   { { 0, 
  232.       &NdbOperation::branch_ne, 
  233.       &NdbOperation::branch_eq, 
  234.       &NdbOperation::branch_eq,  
  235.       &NdbOperation::branch_ne } }
  236.   
  237.   /**
  238.    * NEQ
  239.    */
  240.   ,{ { 0, 
  241.        &NdbOperation::branch_eq, 
  242.        &NdbOperation::branch_ne, 
  243.        &NdbOperation::branch_ne, 
  244.        &NdbOperation::branch_eq } }
  245.   
  246.   /**
  247.    * LT
  248.    */
  249.   ,{ { 0, 
  250.        &NdbOperation::branch_le, 
  251.        &NdbOperation::branch_gt, 
  252.        &NdbOperation::branch_gt,
  253.        &NdbOperation::branch_le } }
  254.   
  255.   /**
  256.    * LE
  257.    */
  258.   ,{ { 0, 
  259.        &NdbOperation::branch_lt, 
  260.        &NdbOperation::branch_ge, 
  261.        &NdbOperation::branch_ge, 
  262.        &NdbOperation::branch_lt } }
  263.   
  264.   /**
  265.    * GT
  266.    */
  267.   ,{ { 0, 
  268.        &NdbOperation::branch_ge, 
  269.        &NdbOperation::branch_lt, 
  270.        &NdbOperation::branch_lt, 
  271.        &NdbOperation::branch_ge } }
  272.   /**
  273.    * GE
  274.    */
  275.   ,{ { 0, 
  276.        &NdbOperation::branch_gt, 
  277.        &NdbOperation::branch_le, 
  278.        &NdbOperation::branch_le, 
  279.        &NdbOperation::branch_gt } }
  280. };
  281. struct tab2 {
  282.   Branch1 m_branches[5];
  283. };
  284. static const tab2 table2[] = {
  285.   /**
  286.    * IS NULL
  287.    */
  288.   { { 0, 
  289.       &NdbOperation::branch_col_ne_null, 
  290.       &NdbOperation::branch_col_eq_null, 
  291.       &NdbOperation::branch_col_eq_null,  
  292.       &NdbOperation::branch_col_ne_null } }
  293.   
  294.   /**
  295.    * IS NOT NULL
  296.    */
  297.   ,{ { 0, 
  298.        &NdbOperation::branch_col_eq_null, 
  299.        &NdbOperation::branch_col_ne_null, 
  300.        &NdbOperation::branch_col_ne_null,  
  301.        &NdbOperation::branch_col_eq_null } }
  302. };
  303. const int tab_sz = sizeof(table)/sizeof(table[0]);
  304. const int tab2_sz = sizeof(table2)/sizeof(table2[0]);
  305. int
  306. matchType(const NdbDictionary::Column * col){
  307.   return 1;
  308. }
  309. template<typename T> int load_const(NdbOperation* op, T value, Uint32 reg);
  310. template<>
  311. int
  312. load_const(NdbOperation* op, Uint32 value, Uint32 reg){
  313.   return op->load_const_u32(reg, value);
  314. }
  315. template<>
  316. int
  317. load_const(NdbOperation* op, Uint64 value, Uint32 reg){
  318.   return op->load_const_u64(reg, value);
  319. }
  320. template<typename T>
  321. int
  322. NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, 
  323.   Uint32 AttrId, T value){
  324.   
  325.   if(op < 0 || op >= tab_sz){
  326.     m_operation->setErrorCodeAbort(4262);
  327.     return -1;
  328.   }
  329.   if(m_current.m_group < NdbScanFilter::AND || 
  330.      m_current.m_group > NdbScanFilter::NOR){
  331.     m_operation->setErrorCodeAbort(4260);
  332.     return -1;
  333.   }
  334.   Branch2 branch = table[op].m_branches[m_current.m_group];
  335.   const NdbDictionary::Column * col = 
  336.     m_operation->m_currentTable->getColumn(AttrId);
  337.   
  338.   if(col == 0){
  339.     m_operation->setErrorCodeAbort(4261);
  340.     return -1;
  341.   }
  342.   
  343.   if(!matchType(col)){
  344.     /**
  345.      * Code not reached
  346.      */
  347.     return -1;
  348.   }
  349.   if(m_latestAttrib != AttrId){
  350.     m_operation->read_attr(&NdbColumnImpl::getImpl(* col), 4);
  351.     m_latestAttrib = AttrId;
  352.   }
  353.   
  354.   load_const<T>(m_operation, value, 5);
  355.   (m_operation->* branch)(4, 5, m_current.m_ownLabel);
  356.   return 0;
  357. }
  358. int
  359. NdbScanFilter::eq(int AttrId, Uint32 value){
  360.   return m_impl.cond_col_const(Interpreter::EQ, AttrId, value);
  361. }
  362. int
  363. NdbScanFilter::ne(int AttrId, Uint32 value){
  364.   return m_impl.cond_col_const(Interpreter::NE, AttrId, value);
  365. }
  366. int
  367. NdbScanFilter::lt(int AttrId, Uint32 value){
  368.   return m_impl.cond_col_const(Interpreter::LT, AttrId, value);
  369. }
  370. int
  371. NdbScanFilter::le(int AttrId, Uint32 value){
  372.   return m_impl.cond_col_const(Interpreter::LE, AttrId, value);
  373. }
  374. int
  375. NdbScanFilter::gt(int AttrId, Uint32 value){
  376.   return m_impl.cond_col_const(Interpreter::GT, AttrId, value);
  377. }
  378. int
  379. NdbScanFilter::ge(int AttrId, Uint32 value){
  380.   return m_impl.cond_col_const(Interpreter::GE, AttrId, value);
  381. }
  382. int
  383. NdbScanFilter::eq(int AttrId, Uint64 value){
  384.   return m_impl.cond_col_const(Interpreter::EQ, AttrId, value);
  385. }
  386. int
  387. NdbScanFilter::ne(int AttrId, Uint64 value){
  388.   return m_impl.cond_col_const(Interpreter::NE, AttrId, value);
  389. }
  390. int
  391. NdbScanFilter::lt(int AttrId, Uint64 value){
  392.   return m_impl.cond_col_const(Interpreter::LT, AttrId, value);
  393. }
  394. int
  395. NdbScanFilter::le(int AttrId, Uint64 value){
  396.   return m_impl.cond_col_const(Interpreter::LE, AttrId, value);
  397. }
  398. int
  399. NdbScanFilter::gt(int AttrId, Uint64 value){
  400.   return m_impl.cond_col_const(Interpreter::GT, AttrId, value);
  401. }
  402. int
  403. NdbScanFilter::ge(int AttrId, Uint64 value){
  404.   return m_impl.cond_col_const(Interpreter::GE, AttrId, value);
  405. }
  406. int
  407. NdbScanFilterImpl::cond_col(Interpreter::UnaryCondition op, Uint32 AttrId){
  408.   
  409.   if(op < 0 || op >= tab2_sz){
  410.     m_operation->setErrorCodeAbort(4262);
  411.     return -1;
  412.   }
  413.   
  414.   if(m_current.m_group < NdbScanFilter::AND || 
  415.      m_current.m_group > NdbScanFilter::NOR){
  416.     m_operation->setErrorCodeAbort(4260);
  417.     return -1;
  418.   }
  419.   
  420.   Branch1 branch = table2[op].m_branches[m_current.m_group];
  421.   (m_operation->* branch)(AttrId, m_current.m_ownLabel);
  422.   return 0;
  423. }
  424. int
  425. NdbScanFilter::isnull(int AttrId){
  426.   return m_impl.cond_col(Interpreter::IS_NULL, AttrId);
  427. }
  428. int
  429. NdbScanFilter::isnotnull(int AttrId){
  430.   return m_impl.cond_col(Interpreter::IS_NOT_NULL, AttrId);
  431. }
  432. struct tab3 {
  433.   StrBranch2 m_branches[5];
  434. };
  435. static const tab3 table3[] = {
  436.   /**
  437.    * EQ (AND, OR, NAND, NOR)
  438.    */
  439.   { { 0, 
  440.       &NdbOperation::branch_col_ne, 
  441.       &NdbOperation::branch_col_eq, 
  442.       &NdbOperation::branch_col_ne,  
  443.       &NdbOperation::branch_col_eq } }
  444.   
  445.   /**
  446.    * NEQ
  447.    */
  448.   ,{ { 0, 
  449.        &NdbOperation::branch_col_eq, 
  450.        &NdbOperation::branch_col_ne, 
  451.        &NdbOperation::branch_col_eq, 
  452.        &NdbOperation::branch_col_ne } }
  453.   
  454.   /**
  455.    * LT
  456.    */
  457.   ,{ { 0, 
  458.        &NdbOperation::branch_col_le, 
  459.        &NdbOperation::branch_col_gt, 
  460.        &NdbOperation::branch_col_le,
  461.        &NdbOperation::branch_col_gt } }
  462.   
  463.   /**
  464.    * LE
  465.    */
  466.   ,{ { 0, 
  467.        &NdbOperation::branch_col_lt, 
  468.        &NdbOperation::branch_col_ge, 
  469.        &NdbOperation::branch_col_lt, 
  470.        &NdbOperation::branch_col_ge } }
  471.   
  472.   /**
  473.    * GT
  474.    */
  475.   ,{ { 0, 
  476.        &NdbOperation::branch_col_ge, 
  477.        &NdbOperation::branch_col_lt, 
  478.        &NdbOperation::branch_col_ge, 
  479.        &NdbOperation::branch_col_lt } }
  480.   /**
  481.    * GE
  482.    */
  483.   ,{ { 0, 
  484.        &NdbOperation::branch_col_gt, 
  485.        &NdbOperation::branch_col_le, 
  486.        &NdbOperation::branch_col_gt, 
  487.        &NdbOperation::branch_col_le } }
  488.   /**
  489.    * LIKE
  490.    */
  491.   ,{ { 0, 
  492.        &NdbOperation::branch_col_notlike, 
  493.        &NdbOperation::branch_col_like, 
  494.        &NdbOperation::branch_col_notlike, 
  495.        &NdbOperation::branch_col_like } }
  496.   /**
  497.    * NOT LIKE
  498.    */
  499.   ,{ { 0, 
  500.        &NdbOperation::branch_col_like, 
  501.        &NdbOperation::branch_col_notlike, 
  502.        &NdbOperation::branch_col_like, 
  503.        &NdbOperation::branch_col_notlike } }
  504. };
  505. const int tab3_sz = sizeof(table3)/sizeof(table3[0]);
  506. int
  507. NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, 
  508.   Uint32 AttrId, 
  509.   const char * value, Uint32 len, bool nopad){
  510.   if(op < 0 || op >= tab3_sz){
  511.     m_operation->setErrorCodeAbort(4260);
  512.     return -1;
  513.   }
  514.   
  515.   if(m_current.m_group < NdbScanFilter::AND || 
  516.      m_current.m_group > NdbScanFilter::NOR){
  517.     m_operation->setErrorCodeAbort(4260);
  518.     return -1;
  519.   }
  520.   
  521.   StrBranch2 branch = table3[op].m_branches[m_current.m_group];
  522.   const NdbDictionary::Column * col = 
  523.     m_operation->m_currentTable->getColumn(AttrId);
  524.   
  525.   if(col == 0){
  526.     m_operation->setErrorCodeAbort(4261);
  527.     return -1;
  528.   }
  529.   
  530.   (m_operation->* branch)(AttrId, value, len, nopad, m_current.m_ownLabel);
  531.   return 0;
  532. }
  533. int
  534. NdbScanFilter::eq(int ColId, const char * val, Uint32 len, bool nopad){
  535.   return m_impl.cond_col_const(Interpreter::EQ, ColId, val, len, nopad);
  536. }
  537. int
  538. NdbScanFilter::ne(int ColId, const char * val, Uint32 len, bool nopad){
  539.   return m_impl.cond_col_const(Interpreter::NE, ColId, val, len, nopad);
  540. }
  541. int
  542. NdbScanFilter::lt(int ColId, const char * val, Uint32 len, bool nopad){
  543.   return m_impl.cond_col_const(Interpreter::LT, ColId, val, len, nopad);
  544. }
  545. int
  546. NdbScanFilter::le(int ColId, const char * val, Uint32 len, bool nopad){
  547.   return m_impl.cond_col_const(Interpreter::LE, ColId, val, len, nopad);
  548. }
  549. int
  550. NdbScanFilter::gt(int ColId, const char * val, Uint32 len, bool nopad){
  551.   return m_impl.cond_col_const(Interpreter::GT, ColId, val, len, nopad);
  552. }
  553. int
  554. NdbScanFilter::ge(int ColId, const char * val, Uint32 len, bool nopad){
  555.   return m_impl.cond_col_const(Interpreter::GE, ColId, val, len, nopad);
  556. }
  557. int
  558. NdbScanFilter::like(int ColId, const char * val, Uint32 len, bool nopad){
  559.   return m_impl.cond_col_const(Interpreter::LIKE, ColId, val, len, nopad);
  560. }
  561. int
  562. NdbScanFilter::notlike(int ColId, const char * val, Uint32 len, bool nopad){
  563.   return m_impl.cond_col_const(Interpreter::NOT_LIKE, ColId, val, len, nopad);
  564. }
  565. #if 0
  566. int
  567. main(void){
  568.   if(0)
  569.   {
  570.     ndbout << "a > 7 AND b < 9 AND c = 4" << endl;
  571.     NdbScanFilter f(0);
  572.     f.begin(NdbScanFilter::AND);
  573.     f.gt(0, 7);
  574.     f.lt(1, 9);
  575.     f.eq(2, 4);
  576.     f.end();
  577.     ndbout << endl;
  578.   }
  579.   if(0)
  580.   {
  581.     ndbout << "a > 7 OR b < 9 OR c = 4" << endl;
  582.     NdbScanFilter f(0);
  583.     f.begin(NdbScanFilter::OR);
  584.     f.gt(0, 7);
  585.     f.lt(1, 9);
  586.     f.eq(2, 4);
  587.     f.end();
  588.     ndbout << endl;
  589.   }
  590.   if(0)
  591.   {
  592.     ndbout << "a > 7 AND (b < 9 OR c = 4)" << endl;
  593.     NdbScanFilter f(0);
  594.     f.begin(NdbScanFilter::AND);
  595.     f.gt(0, 7);
  596.     f.begin(NdbScanFilter::OR);
  597.     f.lt(1, 9);
  598.     f.eq(2, 4);
  599.     f.end();
  600.     f.end();
  601.     ndbout << endl;
  602.   }
  603.   if(0)
  604.   {
  605.     ndbout << "a > 7 AND (b < 9 AND c = 4)" << endl;
  606.     NdbScanFilter f(0);
  607.     f.begin(NdbScanFilter::AND);
  608.     f.gt(0, 7);
  609.     f.begin(NdbScanFilter::AND);
  610.     f.lt(1, 9);
  611.     f.eq(2, 4);
  612.     f.end();
  613.     f.end();
  614.     ndbout << endl;
  615.   }
  616.   if(0)
  617.   {
  618.     ndbout << "(a > 7 AND b < 9) AND c = 4" << endl;
  619.     NdbScanFilter f(0);
  620.     f.begin(NdbScanFilter::AND);
  621.     f.begin(NdbScanFilter::AND);
  622.     f.gt(0, 7);
  623.     f.lt(1, 9);
  624.     f.end();
  625.     f.eq(2, 4);
  626.     f.end();
  627.     ndbout << endl;
  628.   }
  629.   if(1)
  630.   {
  631.     ndbout << "(a > 7 OR b < 9) AND (c = 4 OR c = 5)" << endl;
  632.     NdbScanFilter f(0);
  633.     f.begin(NdbScanFilter::AND);
  634.     f.begin(NdbScanFilter::OR);
  635.     f.gt(0, 7);
  636.     f.lt(1, 9);
  637.     f.end();
  638.     f.begin(NdbScanFilter::OR);    
  639.     f.eq(2, 4);
  640.     f.eq(2, 5);
  641.     f.end();
  642.     f.end();
  643.     ndbout << endl;
  644.   }
  645.   if(1)
  646.   {
  647.     ndbout << "(a > 7 AND b < 9) OR (c = 4 AND c = 5)" << endl;
  648.     NdbScanFilter f(0);
  649.     f.begin(NdbScanFilter::OR);
  650.     f.begin(NdbScanFilter::AND);
  651.     f.gt(0, 7);
  652.     f.lt(1, 9);
  653.     f.end();
  654.     f.begin(NdbScanFilter::AND);    
  655.     f.eq(2, 4);
  656.     f.eq(2, 5);
  657.     f.end();
  658.     f.end();
  659.     ndbout << endl;
  660.   }
  661.   if(1)
  662.   {
  663.     ndbout << 
  664.       "((a > 7 AND b < 9) OR (c = 4 AND d = 5)) AND " 
  665.       "((e > 6 AND f < 8) OR (g = 2 AND h = 3)) "  << endl;
  666.     NdbScanFilter f(0);
  667.     f.begin(NdbScanFilter::AND);
  668.     f.begin(NdbScanFilter::OR);
  669.     f.begin(NdbScanFilter::AND);
  670.     f.gt(0, 7);
  671.     f.lt(1, 9);
  672.     f.end();
  673.     f.begin(NdbScanFilter::AND);    
  674.     f.eq(2, 4);
  675.     f.eq(3, 5);
  676.     f.end();
  677.     f.end();
  678.     f.begin(NdbScanFilter::OR);
  679.     f.begin(NdbScanFilter::AND);
  680.     f.gt(4, 6);
  681.     f.lt(5, 8);
  682.     f.end();
  683.     f.begin(NdbScanFilter::AND);    
  684.     f.eq(6, 2);
  685.     f.eq(7, 3);
  686.     f.end();
  687.     f.end();
  688.     f.end();
  689.   }
  690.   
  691.   return 0;
  692. }
  693. #endif
  694. template class Vector<NdbScanFilterImpl::State>;
  695. #if __SUNPRO_CC != 0x560
  696. #ifndef _FORTEC_
  697. template int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, Uint32);
  698. template int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, Uint64);
  699. #endif
  700. #endif