1 karl 1.14 //%2006////////////////////////////////////////////////////////////////////////
|
2 schuur 1.1 //
|
3 karl 1.8 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 schuur 1.1 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.8 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.11 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.14 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 schuur 1.1 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.8 //
|
21 schuur 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34
|
35 schuur 1.6 #include "CMPI_Version.h"
|
36 schuur 1.1
37 #include <Pegasus/Common/Stack.h>
38 #include <Pegasus/WQL/WQLParser.h>
|
39 chuck 1.9 #include <Pegasus/WQL/WQLSelectStatementRep.h>
|
40 ms.aruran 1.18 #include <Pegasus/Common/Tracer.h>
|
41 schuur 1.1
42 #include "CMPI_Wql2Dnf.h"
43
|
44 schuur 1.4 PEGASUS_USING_STD;
|
45 schuur 1.1 PEGASUS_NAMESPACE_BEGIN
46
47 //
48 // Terminal element methods
49 //
|
50 konrad.r 1.10 void term_el_WQL::negate(void)
|
51 schuur 1.1 {
|
52 venkat.puvvada 1.17 switch( op )
|
53 schuur 1.1 {
|
54 venkat.puvvada 1.17 case WQL_EQ: op = WQL_NE;
55 break;
56 case WQL_NE: op = WQL_EQ;
57 break;
58 case WQL_LT: op = WQL_GE;
59 break;
60 case WQL_LE: op = WQL_GT;
61 break;
62 case WQL_GT: op = WQL_LE;
63 break;
64 case WQL_GE: op = WQL_LT;
65 break;
66 default:
67 break;
|
68 schuur 1.1 }
69 };
|
70 mike 1.16
|
71 konrad.r 1.10 /*
|
72 venkat.puvvada 1.17 String opnd2string(const WQLOperand &o)
73 {
|
74 schuur 1.1 switch (o.getType()) {
75 case WQLOperand::PROPERTY_NAME:
76 return o.getPropertyName();
77 case WQLOperand::STRING_VALUE:
78 return o.getStringValue();
79 case WQLOperand::INTEGER_VALUE:
80 return Formatter::format("$0",o.getIntegerValue());
81 case WQLOperand::DOUBLE_VALUE:
82 return Formatter::format("$0",o.getDoubleValue());
83 case WQLOperand::BOOLEAN_VALUE:
84 return Formatter::format("$0",o.getBooleanValue());
85 default: ;
|
86 venkat.puvvada 1.17 }
87 return "NULL_VALUE";
|
88 schuur 1.1 }
89
90
|
91 venkat.puvvada 1.17 CMPIPredOp mapOperation(WQLOperation op)
92 {
93 static CMPIPredOp ops[]={(CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,
|
94 schuur 1.1 CMPI_PredOp_Equals,
95 CMPI_PredOp_NotEquals,
96 CMPI_PredOp_LessThan,
97 CMPI_PredOp_LessThanOrEquals,
98 CMPI_PredOp_GreaterThan,
99 CMPI_PredOp_GreaterThanOrEquals,
|
100 venkat.puvvada 1.17 (CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,
101 (CMPIPredOp)0,(CMPIPredOp)0};
102 return ops[(int)op];
|
103 schuur 1.3 }
|
104 schuur 1.1
|
105 venkat.puvvada 1.17 CMPIType mapType(WQLOperand::Type typ)
106 {
107 switch (typ) {
|
108 schuur 1.1 case WQLOperand::PROPERTY_NAME:
109 return CMPI_nameString;
110 case WQLOperand::STRING_VALUE:
111 return CMPI_charString;
112 case WQLOperand::INTEGER_VALUE:
113 return CMPI_integerString;
114 case WQLOperand::DOUBLE_VALUE:
115 return CMPI_realString;
116 case WQLOperand::BOOLEAN_VALUE:
117 return CMPI_booleanString;
118 case WQLOperand::NULL_VALUE:
119 return CMPI_null;
|
120 venkat.puvvada 1.17 }
121 return CMPI_null;
|
122 schuur 1.1 }
123
|
124 venkat.puvvada 1.17 int term_el::toStrings(
125 CMPIType &typ,
126 CMPIPredOp &opr,
127 String &o1,
128 String &o2 ) const
129 {
130 opr=mapOperation(op);
131 o1=opnd2string(opn1);
132 o2=opnd2string(opn2);
133 if (opn1.getType()==WQLOperand::PROPERTY_NAME) typ=mapType(opn2.getType());
134 else typ=mapType(opn1.getType());
135 return 0;
|
136 schuur 1.1 }
|
137 konrad.r 1.10 */
138
|
139 venkat.puvvada 1.17 CMPIPredOp mapOperation(WQLOperation op)
140 {
141 static CMPIPredOp ops[]={(CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,
142 CMPI_PredOp_Equals,
143 CMPI_PredOp_NotEquals,
144 CMPI_PredOp_LessThan,
145 CMPI_PredOp_LessThanOrEquals,
146 CMPI_PredOp_GreaterThan,
147 CMPI_PredOp_GreaterThanOrEquals,
148 (CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,
149 (CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0};
150 return ops[(int)op];
|
151 konrad.r 1.10 }
152
|
153 venkat.puvvada 1.17 CMPIType mapType(WQLOperand::Type typ)
154 {
155 switch( typ )
156 {
157 case WQLOperand::PROPERTY_NAME:
158 return CMPI_nameString;
159 case WQLOperand::STRING_VALUE:
160 return CMPI_charString;
161 case WQLOperand::INTEGER_VALUE:
162 return CMPI_integerString;
163 case WQLOperand::DOUBLE_VALUE:
164 return CMPI_realString;
165 case WQLOperand::BOOLEAN_VALUE:
166 return CMPI_booleanString;
167 case WQLOperand::NULL_VALUE:
168 return CMPI_null;
169 }
170 return CMPI_null;
|
171 konrad.r 1.10 }
|
172 schuur 1.1
173 //
174 // Helper function copied from WQLSelectStatement
175 //
176
177 template<class T>
178 inline static Boolean _Compare(const T& x, const T& y, WQLOperation op)
179 {
|
180 venkat.puvvada 1.17 switch( op )
|
181 schuur 1.1 {
182 case WQL_EQ:
183 return x == y;
184
185 case WQL_NE:
186 return x != y;
187
188 case WQL_LT:
189 return x < y;
190 case WQL_LE:
191 return x <= y;
192
193 case WQL_GT:
194 return x > y;
195
196 case WQL_GE:
197 return x >= y;
198
199 default:
200 PEGASUS_ASSERT(0);
201 }
202 schuur 1.1
203 return false;
204 }
205
206 static bool operator==(const WQLOperand& x, const WQLOperand& y)
207 {
|
208 venkat.puvvada 1.17 if( x.getType()==y.getType() )
209 {
210 switch( x.getType() )
211 {
212 case WQLOperand::PROPERTY_NAME:
213 return x.getPropertyName()==y.getPropertyName();
214 case WQLOperand::INTEGER_VALUE:
215 return x.getIntegerValue()==y.getIntegerValue();
216 case WQLOperand::DOUBLE_VALUE:
217 return x.getDoubleValue()==y.getDoubleValue();
218 case WQLOperand::BOOLEAN_VALUE:
219 return x.getBooleanValue()==y.getBooleanValue();
220 case WQLOperand::STRING_VALUE:
221 return x.getStringValue()==y.getStringValue();
222 case WQLOperand::NULL_VALUE:
223 return true;
224 }
225 }
226 return false;
|
227 schuur 1.1 }
228
|
229 konrad.r 1.10 static bool operator==(const term_el_WQL& x, const term_el_WQL& y)
|
230 schuur 1.1 {
|
231 venkat.puvvada 1.17 return x.op == y.op &&
232 x.opn1 == y.opn1 &&
233 x.opn2 == y.opn2;
|
234 schuur 1.1 }
235
|
236 konrad.r 1.10 static void addIfNotExists(TableauRow_WQL &tr, const term_el_WQL& el)
|
237 schuur 1.1 {
|
238 ms.aruran 1.18 PEG_METHOD_ENTER(
239 TRC_CMPIPROVIDERINTERFACE,
240 "CMPI_Wql2Dnf:addIfNotExists()");
|
241 venkat.puvvada 1.17 for( int i=0,m=tr.size(); i<m; i++ )
242 {
243 if( tr[i]==el )
244 {
|
245 ms.aruran 1.18 PEG_METHOD_EXIT();
|
246 venkat.puvvada 1.17 return;
247 }
248 }
249 tr.append(el);
|
250 ms.aruran 1.18 PEG_METHOD_EXIT();
|
251 schuur 1.1 }
252
253
254 static Boolean _Evaluate(
255 const WQLOperand& lhs,
256 const WQLOperand& rhs,
257 WQLOperation op)
258 {
|
259 ms.aruran 1.18 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPI_Wql2Dnf:_Evaluate()");
|
260 venkat.puvvada 1.17 switch( lhs.getType() )
|
261 schuur 1.1 {
262 case WQLOperand::NULL_VALUE:
|
263 venkat.puvvada 1.17 {
264 // This cannot happen since expressions of the form
265 // OPERAND OPERATOR NULL are converted to unary form.
266 // For example: "count IS NULL" is treated as a unary
267 // operation in which IS_NULL is the unary operation
268 // and count is the the unary operand.
|
269 schuur 1.1
|
270 venkat.puvvada 1.17 PEGASUS_ASSERT(0);
271 break;
272 }
|
273 schuur 1.1
274 case WQLOperand::INTEGER_VALUE:
|
275 venkat.puvvada 1.17 {
|
276 ms.aruran 1.18 PEG_METHOD_EXIT();
|
277 venkat.puvvada 1.17 return _Compare(
|
278 schuur 1.1 lhs.getIntegerValue(),
279 rhs.getIntegerValue(),
280 op);
|
281 venkat.puvvada 1.17 }
|
282 schuur 1.1
283 case WQLOperand::DOUBLE_VALUE:
|
284 venkat.puvvada 1.17 {
|
285 ms.aruran 1.18 PEG_METHOD_EXIT();
|
286 venkat.puvvada 1.17 return _Compare(
|
287 schuur 1.1 lhs.getDoubleValue(),
288 rhs.getDoubleValue(),
289 op);
|
290 venkat.puvvada 1.17 }
|
291 schuur 1.1
292 case WQLOperand::BOOLEAN_VALUE:
|
293 venkat.puvvada 1.17 {
|
294 ms.aruran 1.18 PEG_METHOD_EXIT();
|
295 venkat.puvvada 1.17 return _Compare(
|
296 schuur 1.1 lhs.getBooleanValue(),
297 rhs.getBooleanValue(),
298 op);
|
299 venkat.puvvada 1.17 }
|
300 schuur 1.1
301 case WQLOperand::STRING_VALUE:
|
302 venkat.puvvada 1.17 {
|
303 ms.aruran 1.18 PEG_METHOD_EXIT();
|
304 venkat.puvvada 1.17 return _Compare(
|
305 schuur 1.1 lhs.getStringValue(),
306 rhs.getStringValue(),
307 op);
|
308 venkat.puvvada 1.17 }
|
309 schuur 1.1
310 default:
311 PEGASUS_ASSERT(0);
312 }
313
|
314 ms.aruran 1.18 PEG_METHOD_EXIT();
|
315 schuur 1.1 return false;
316 }
317
318
319 //
320 // WQL Compiler methods
321 //
|
322 venkat.puvvada 1.17
|
323 konrad.r 1.10 CMPI_Wql2Dnf::CMPI_Wql2Dnf(const String &condition, const String &pref)
|
324 schuur 1.1 {
325 WQLSelectStatement wqs;
326 WQLParser::parse(pref+condition,wqs);
327 eval_heap.reserveCapacity(16);
328 terminal_heap.reserveCapacity(16);
329 _tableau.clear();
330 compile(&wqs);
331 }
332
333 CMPI_Wql2Dnf::CMPI_Wql2Dnf()
334 {
335 eval_heap.reserveCapacity(16);
336 terminal_heap.reserveCapacity(16);
337 _tableau.clear();
338 }
339
340 CMPI_Wql2Dnf::CMPI_Wql2Dnf(const WQLSelectStatement & wqs)
341 {
342 eval_heap.reserveCapacity(16);
343 terminal_heap.reserveCapacity(16);
344 _tableau.clear();
345 schuur 1.1 compile(&wqs);
346 }
347
348 CMPI_Wql2Dnf::CMPI_Wql2Dnf(const WQLSelectStatement * wqs)
349 {
350 eval_heap.reserveCapacity(16);
351 terminal_heap.reserveCapacity(16);
352 _tableau.clear();
353 compile(wqs);
354 }
355
|
356 venkat.puvvada 1.17 CMPI_Wql2Dnf::~CMPI_Wql2Dnf()
357 {
358 }
|
359 schuur 1.1
360 void CMPI_Wql2Dnf::compile(const WQLSelectStatement * wqs)
361 {
|
362 ms.aruran 1.18 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPI_Wql2Dnf::compile()");
|
363 venkat.puvvada 1.17 if( !wqs->hasWhereClause() )
364 {
|
365 ms.aruran 1.18 PEG_METHOD_EXIT();
|
366 venkat.puvvada 1.17 return;
367 }
|
368 schuur 1.1 _tableau.clear();
369
370 _buildEvalHeap(wqs);
371 _pushNOTDown();
372 _factoring();
|
373 venkat.puvvada 1.17
|
374 mike 1.16 Array<CMPI_stack_el> disj;
|
375 schuur 1.1 _gatherDisj(disj);
|
376 venkat.puvvada 1.17 if( disj.size() == 0 )
377 {
378 if( terminal_heap.size() > 0 )
379 {
380 // point to the remaining terminal element
|
381 mike 1.16 disj.append(CMPI_stack_el(0,true));
|
382 venkat.puvvada 1.17 }
383 }
|
384 schuur 1.1
|
385 venkat.puvvada 1.17 for( Uint32 i=0, n =disj.size(); i< n; i++ )
|
386 schuur 1.1 {
|
387 konrad.r 1.10 TableauRow_WQL tr;
|
388 mike 1.16 Array<CMPI_stack_el> conj;
|
389 schuur 1.1
|
390 venkat.puvvada 1.17 if( !disj[i].is_terminal )
|
391 schuur 1.1 {
|
392 venkat.puvvada 1.17 _gatherConj(conj, disj[i]);
393 for( Uint32 j=0, m = conj.size(); j < m; j++ )
394 {
395 addIfNotExists(tr,terminal_heap[conj[j].opn]);
396 // tr.append(terminal_heap[conj[j].opn]);
397 }
|
398 schuur 1.1 }
399 else
|
400 venkat.puvvada 1.17 {
401 addIfNotExists(tr,terminal_heap[disj[i].opn]);
402 // tr.append(terminal_heap[disj[i].opn]);
403 }
|
404 schuur 1.1 _tableau.append(tr);
405 }
406
407 eval_heap.clear();
|
408 venkat.puvvada 1.17
|
409 schuur 1.1 //print();
|
410 konrad.r 1.10 //printTableau();
|
411 schuur 1.1 //_sortTableau();
|
412 venkat.puvvada 1.17 _populateTableau();
|
413 ms.aruran 1.18 PEG_METHOD_EXIT();
|
414 schuur 1.1 }
415
416 Boolean CMPI_Wql2Dnf::evaluate(WQLPropertySource * source) const
417 {
|
418 ms.aruran 1.18 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPI_Wql2Dnf::evaluate()");
|
419 venkat.puvvada 1.17 Boolean b = false;
420 WQLOperand lhs, rhs;
|
421 schuur 1.1
|
422 venkat.puvvada 1.17 for( Uint32 i=0,n = _tableau.size(); i < n; i++ )
423 {
424 TableauRow_WQL tr = _tableau[i];
425 for( Uint32 j=0,m = tr.size(); j < m; j++ )
426 {
427 lhs = tr[j].opn1;
428 CMPI_Wql2Dnf::_ResolveProperty(lhs,source);
429 rhs = tr[j].opn2;
430 CMPI_Wql2Dnf::_ResolveProperty(rhs,source);
431
432 if( rhs.getType() != lhs.getType() )
433 {
434 throw TypeMismatchException();
435 }
436
437 if( !_Evaluate(lhs, rhs, tr[j].op) )
438 {
439 b = false;
440 break;
441 }
442 else
443 venkat.puvvada 1.17 {
444 b = true;
445 }
446 }
447 if( b )
448 {
|
449 ms.aruran 1.18 PEG_METHOD_EXIT();
|
450 venkat.puvvada 1.17 return true;
451 }
452 }
|
453 ms.aruran 1.18 PEG_METHOD_EXIT();
|
454 venkat.puvvada 1.17 return false;
|
455 schuur 1.1 }
456
457 void CMPI_Wql2Dnf::print(void)
458 {
|
459 ms.aruran 1.18 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPI_Wql2Dnf::print()");
|
460 venkat.puvvada 1.17 for( Uint32 i=0, n=eval_heap.size();i < n;i++ )
461 {
462 WQLOperation wop = eval_heap[i].op;
463 if( wop == WQL_IS_TRUE )
464 {
465 continue;
466 }
467 cout << "Eval element " << i << ": ";
468 if( eval_heap[i].is_terminal1 )
469 {
470 cout << "T(";
471 }
472 else
473 {
474 cout << "E(";
475 }
476 cout << eval_heap[i].opn1 << ") ";
477 cout << WQLOperationToString(eval_heap[i].op);
478 if( eval_heap[i].is_terminal2 )
479 {
480 cout << " T(";
481 venkat.puvvada 1.17 }
482 else
483 {
484 cout << " E(";
485 }
486 cout << eval_heap[i].opn2 << ")" << endl;
487 }
488
489 for( Uint32 i=0, n=terminal_heap.size();i < n;i++ )
490 {
491 cout << "Terminal expression " << i << ": ";
492 cout << terminal_heap[i].opn1.toString() << " ";
493 cout << WQLOperationToString(terminal_heap[i].op) << " "
494 << terminal_heap[i].opn2.toString() << endl;
495 }
|
496 ms.aruran 1.18 PEG_METHOD_EXIT();
|
497 schuur 1.1 }
498
499 void CMPI_Wql2Dnf::printTableau(void)
500 {
|
501 ms.aruran 1.18 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPI_Wql2Dnf::printTableau()");
|
502 venkat.puvvada 1.17 for( Uint32 i=0,n = _tableau.size(); i < n; i++ )
503 {
504 cout << "Tableau " << i << endl;
505 TableauRow_WQL tr = _tableau[i];
506 for( Uint32 j=0,m = tr.size(); j < m; j++ )
507 {
508 cout << tr[j].opn1.toString() << " ";
509 cout << WQLOperationToString(tr[j].op) << " "
510 << tr[j].opn2.toString() << endl;
511 }
512 }
|
513 ms.aruran 1.18 PEG_METHOD_EXIT();
|
514 schuur 1.1 }
515
|
516 venkat.puvvada 1.17 String WQL2String(const WQLOperand &o)
517 {
518 switch( o.getType() )
519 {
520 case WQLOperand::PROPERTY_NAME:
521 return o.getPropertyName();
522 case WQLOperand::STRING_VALUE:
523 return o.getStringValue();
524 case WQLOperand::INTEGER_VALUE:
525 return Formatter::format("$0",o.getIntegerValue());
526 case WQLOperand::DOUBLE_VALUE:
527 return Formatter::format("$0",o.getDoubleValue());
528 case WQLOperand::BOOLEAN_VALUE:
529 return Formatter::format("$0",o.getBooleanValue());
530 default: ;
531 }
532 return "NULL_VALUE";
|
533 konrad.r 1.10 }
534
|
535 venkat.puvvada 1.17 CMPIPredOp WQL2PredOp(const WQLOperation &op)
536 {
|
537 ms.aruran 1.18 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE,"CMPI_Wql2Dnf:WQL2PredOp()");
|
538 venkat.puvvada 1.17 static CMPIPredOp ops[]={(CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,
539 CMPI_PredOp_Equals,
540 CMPI_PredOp_NotEquals,
541 CMPI_PredOp_LessThan,
542 CMPI_PredOp_LessThanOrEquals,
543 CMPI_PredOp_GreaterThan,
544 CMPI_PredOp_GreaterThanOrEquals,
545 (CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,
546 (CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0};
|
547 ms.aruran 1.18 PEG_METHOD_EXIT();
|
548 venkat.puvvada 1.17 return ops[(int)op];
|
549 konrad.r 1.10 }
550
|
551 venkat.puvvada 1.17 CMPI_QueryOperand::Type WQL2Type(WQLOperand::Type typ)
552 {
553 switch( typ )
554 {
555 case WQLOperand::PROPERTY_NAME:
556 return CMPI_QueryOperand::PROPERTY_TYPE;
557 case WQLOperand::STRING_VALUE:
558 return CMPI_QueryOperand::STRING_TYPE;
559 case WQLOperand::INTEGER_VALUE:
560 return CMPI_QueryOperand::UINT64_TYPE;
561 case WQLOperand::DOUBLE_VALUE:
562 return CMPI_QueryOperand::REAL_TYPE;
563 case WQLOperand::BOOLEAN_VALUE:
564 return CMPI_QueryOperand::BOOLEAN_TYPE;
565 case WQLOperand::NULL_VALUE:
566 return CMPI_QueryOperand::NULL_TYPE;
567 }
568 return CMPI_QueryOperand::NULL_TYPE;
|
569 konrad.r 1.10 }
570
571
572 void CMPI_Wql2Dnf::_populateTableau(void)
573 {
|
574 ms.aruran 1.18 PEG_METHOD_ENTER(
575 TRC_CMPIPROVIDERINTERFACE,
576 "CMPI_Wql2Dnf::_populateTableau()");
|
577 venkat.puvvada 1.17 for( Uint32 i=0,n = _tableau.size(); i < n; i++ )
578 {
579 TableauRow_WQL tr_wql = _tableau[i];
580
581 for( Uint32 j=0,m = tr_wql.size(); j < m; j++ )
582 {
583 term_el_WQL t = tr_wql[j];
|
584 konrad.r 1.10
|
585 venkat.puvvada 1.17 CMPI_TableauRow tr;
586 CMPI_QueryOperand lhs(WQL2String(t.opn1),
587 WQL2Type(t.opn1.getType()));
588 CMPI_QueryOperand rhs(WQL2String(t.opn2),
589 WQL2Type(t.opn2.getType()));
|
590 konrad.r 1.10
|
591 venkat.puvvada 1.17 tr.append(CMPI_term_el(t.mark, WQL2PredOp(t.op), lhs, rhs));
592 _CMPI_tableau.append (tr);
|
593 konrad.r 1.10
|
594 venkat.puvvada 1.17 }
595
596 }
|
597 ms.aruran 1.18 PEG_METHOD_EXIT();
|
598 konrad.r 1.10 }
|
599 schuur 1.1 void CMPI_Wql2Dnf::_buildEvalHeap(const WQLSelectStatement * wqs)
600 {
|
601 ms.aruran 1.18 PEG_METHOD_ENTER(
602 TRC_CMPIPROVIDERINTERFACE,
603 "CMPI_Wql2Dnf::_buildEvalHeap()");
|
604 schuur 1.1 //WQLSelectStatement* that = (WQLSelectStatement*)wqs;
605
|
606 chuck 1.9 WQLSelectStatementRep* wqsrep = wqs->_rep;
607
|
608 schuur 1.1 WQLOperand dummy;
609 dummy.clear();
|
610 mike 1.16 Stack<CMPI_stack_el> stack;
|
611 schuur 1.3
|
612 schuur 1.1 // Counter for Operands
613
614 Uint32 j = 0;
615
616 //cerr << "Build eval heap\n";
617
|
618 venkat.puvvada 1.17 for( Uint32 i = 0, n = wqsrep->_operations.size(); i < n; i++ )
|
619 schuur 1.1 {
|
620 chuck 1.9 WQLOperation op = wqsrep->_operations[i];
|
621 schuur 1.1
|
622 venkat.puvvada 1.17 switch( op )
|
623 schuur 1.1 {
624 case WQL_OR:
625 case WQL_AND:
|
626 venkat.puvvada 1.17 {
627 PEGASUS_ASSERT(stack.size() >= 2);
|
628 schuur 1.1
|
629 venkat.puvvada 1.17 CMPI_stack_el op1 = stack.top();
630 stack.pop();
|
631 schuur 1.1
|
632 venkat.puvvada 1.17 CMPI_stack_el op2 = stack.top();
|
633 schuur 1.1
|
634 venkat.puvvada 1.17 // generate Eval expression
635 eval_heap.append(CMPI_eval_el(
636 0, op , op1.opn,
637 op1.is_terminal,op2.opn ,
638 op2.is_terminal));
|
639 schuur 1.1
|
640 venkat.puvvada 1.17 stack.top() = CMPI_stack_el(eval_heap.size()-1, false);
|
641 schuur 1.1
|
642 venkat.puvvada 1.17 break;
643 }
|
644 schuur 1.1
645 case WQL_NOT:
646 case WQL_IS_FALSE:
647 case WQL_IS_NOT_TRUE:
|
648 venkat.puvvada 1.17 {
649 PEGASUS_ASSERT(stack.size() >= 1);
|
650 schuur 1.1
|
651 venkat.puvvada 1.17 CMPI_stack_el op1 = stack.top();
|
652 schuur 1.1
|
653 venkat.puvvada 1.17 // generate Eval expression
654 eval_heap.append(CMPI_eval_el(
655 0, op , op1.opn,
656 op1.is_terminal,-1, true));
|
657 schuur 1.1
|
658 venkat.puvvada 1.17 stack.top() = CMPI_stack_el(eval_heap.size()-1, false);
|
659 schuur 1.1
|
660 venkat.puvvada 1.17 break;
661 }
|
662 schuur 1.1
663 case WQL_EQ:
664 case WQL_NE:
665 case WQL_LT:
666 case WQL_LE:
667 case WQL_GT:
668 case WQL_GE:
|
669 venkat.puvvada 1.17 {
670 PEGASUS_ASSERT(wqsrep->_operands.size() >= 2);
|
671 schuur 1.1
|
672 venkat.puvvada 1.17 WQLOperand lhs = wqsrep->_operands[j++];
|
673 schuur 1.1
|
674 venkat.puvvada 1.17 WQLOperand rhs = wqsrep->_operands[j++];
|
675 schuur 1.1
|
676 venkat.puvvada 1.17 terminal_heap.push(term_el_WQL(false, op, lhs, rhs));
|
677 schuur 1.1
|
678 venkat.puvvada 1.17 stack.push(CMPI_stack_el(terminal_heap.size()-1, true));
|
679 schuur 1.1
|
680 venkat.puvvada 1.17 break;
681 }
|
682 schuur 1.1
683 case WQL_IS_TRUE:
684 case WQL_IS_NOT_FALSE:
|
685 venkat.puvvada 1.17 {
686 PEGASUS_ASSERT(stack.size() >= 1);
687 break;
688 }
|
689 schuur 1.1
690 case WQL_IS_NULL:
|
691 venkat.puvvada 1.17 {
692 PEGASUS_ASSERT(wqsrep->_operands.size() >= 1);
693 WQLOperand op = wqsrep->_operands[j++];
|
694 schuur 1.1
|
695 venkat.puvvada 1.17 terminal_heap.push(term_el_WQL(false, WQL_EQ, op, dummy));
|
696 schuur 1.1
|
697 venkat.puvvada 1.17 stack.push(CMPI_stack_el(terminal_heap.size()-1, true));
|
698 schuur 1.1
|
699 venkat.puvvada 1.17 break;
700 }
|
701 schuur 1.1
702 case WQL_IS_NOT_NULL:
|
703 venkat.puvvada 1.17 {
704 PEGASUS_ASSERT(wqsrep->_operands.size() >= 1);
705 WQLOperand op = wqsrep->_operands[j++];
|
706 schuur 1.1
|
707 venkat.puvvada 1.17 terminal_heap.push(term_el_WQL(false, WQL_NE, op, dummy));
|
708 schuur 1.1
|
709 venkat.puvvada 1.17 stack.push(CMPI_stack_el(terminal_heap.size()-1, true));
|
710 schuur 1.1
|
711 venkat.puvvada 1.17 break;
712 }
|
713 schuur 1.1 }
714 }
715
716 PEGASUS_ASSERT(stack.size() == 1);
|
717 ms.aruran 1.18 PEG_METHOD_EXIT();
|
718 schuur 1.1 }
719
720 void CMPI_Wql2Dnf::_pushNOTDown()
721 {
|
722 ms.aruran 1.18 PEG_METHOD_ENTER(
723 TRC_CMPIPROVIDERINTERFACE,
724 "CMPI_Wql2Dnf::_pushNOTDown()");
|
725 venkat.puvvada 1.17 for( int i=eval_heap.size()-1; i >= 0; i-- )
|
726 schuur 1.1 {
727 Boolean _found = false;
728
729 // Order all operators, so that op1 > op2 for non-terminals
730 // and terminals appear as second operand
731
732 eval_heap[i].order();
733
734 // First solve the unary NOT operator
735
|
736 venkat.puvvada 1.17 if( eval_heap[i].op == WQL_NOT ||
737 eval_heap[i].op == WQL_IS_FALSE ||
738 eval_heap[i].op == WQL_IS_NOT_TRUE )
739 {
|
740 schuur 1.1 // This serves as the equivalent of an empty operator
741 eval_heap[i].op = WQL_IS_TRUE;
742
743 // Substitute this expression in all higher order eval statements
744 // so that this node becomes disconnected from the tree
745
|
746 venkat.puvvada 1.17 for( int j=eval_heap.size()-1; j > i;j-- )
|
747 schuur 1.1 {
|
748 venkat.puvvada 1.17 // Test first operand
749 if( (!eval_heap[j].is_terminal1) && (eval_heap[j].opn1 == i) )
750 {
751
752 eval_heap[j].assign_unary_to_first(eval_heap[i]);
753 }
754
755 // Test second operand
756 if( (!eval_heap[j].is_terminal2) && (eval_heap[j].opn2 == i) )
757 {
|
758 schuur 1.1
|
759 venkat.puvvada 1.17 eval_heap[j].assign_unary_to_second(eval_heap[i]);
760 }
|
761 schuur 1.1 }
762
763 // Test: Double NOT created by moving down
764
|
765 venkat.puvvada 1.17 if( eval_heap[i].mark )
766 {
767 eval_heap[i].mark = false;
768 }
|
769 schuur 1.1 else
|
770 venkat.puvvada 1.17 {
771 _found = true;
772 }
|
773 schuur 1.1 // else indicate a pending NOT to be pushed down further
774 }
775
776 // Simple NOT created by moving down
777
|
778 venkat.puvvada 1.17 if( eval_heap[i].mark )
|
779 schuur 1.1 {
780 // Remove the mark, indicate a pending NOT to be pushed down
781 // further and switch operators (AND / OR)
782
783 eval_heap[i].mark=false;
|
784 venkat.puvvada 1.17 if( eval_heap[i].op == WQL_OR )
785 {
786 eval_heap[i].op = WQL_AND;
787 }
788 else
789 {
790 if( eval_heap[i].op == WQL_AND )
791 {
792 eval_heap[i].op = WQL_OR;
793 }
794 }
|
795 schuur 1.1
796 // NOT operator is already ruled out
797 _found = true;
798 }
799
800 // Push a pending NOT further down
|
801 venkat.puvvada 1.17 if( _found )
|
802 schuur 1.1 {
|
803 venkat.puvvada 1.17 // First operand
|
804 schuur 1.1
|
805 venkat.puvvada 1.17 int j = eval_heap[i].opn1;
806 if( eval_heap[i].is_terminal1 )
807 {
808 // Flip NOT mark
809 terminal_heap[j].negate();
810 }
811 else
812 {
813 eval_heap[j].mark = !(eval_heap[j].mark);
814 }
815
816 //Second operand (if it exists)
817
818 if( (j = eval_heap[i].opn2) >= 0 )
819 {
820 if( eval_heap[i].is_terminal2 )
821 {
822 // Flip NOT mark
823 terminal_heap[j].negate();
824 }
825 else
826 venkat.puvvada 1.17 {
827 eval_heap[j].mark = !(eval_heap[j].mark);
828 }
829 }
|
830 schuur 1.1 }
831 }
|
832 ms.aruran 1.18 PEG_METHOD_EXIT();
|
833 schuur 1.1 }
834
835 void CMPI_Wql2Dnf::_factoring(void)
836 {
|
837 ms.aruran 1.18 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPI_Wql2Dnf::_factoring()");
|
838 schuur 1.1 int i = 0,n = eval_heap.size();
839 //for (int i=eval_heap.size()-1; i >= 0; i--)
|
840 venkat.puvvada 1.17 while( i < n )
|
841 schuur 1.1 {
842 int _found = 0;
843 int index = 0;
844
845 // look for expressions (A | B) & C ---> A & C | A & B
|
846 venkat.puvvada 1.17 if( eval_heap[i].op == WQL_AND )
|
847 schuur 1.1 {
|
848 venkat.puvvada 1.17 if( !eval_heap[i].is_terminal1 )
|
849 schuur 1.1 {
850 index = eval_heap[i].opn1; // remember the index
|
851 venkat.puvvada 1.17 if( eval_heap[index].op == WQL_OR )
852 {
853 _found = 1;
854 }
855
856 if( (_found == 0) && (!eval_heap[i].is_terminal2) )
857 {
858 index = eval_heap[i].opn2; // remember the index
859 if( eval_heap[index].op == WQL_OR )
860 {
861 _found = 2;
862 }
863 }
864
865 if( _found != 0 )
866 {
867 //int u1,u1_t,u2,u2_t,u3,u3_t;
868 CMPI_stack_el s;
869
870 if( _found == 1 )
871 {
872 venkat.puvvada 1.17 s = eval_heap[i].getSecond();
873 }
874 else
875 {
876 s = eval_heap[i].getFirst();
877 }
878
879 // insert two new expression before entry i
880 CMPI_eval_el evl;
881
882 evl = CMPI_eval_el(false, WQL_OR, i+1, false, i, false);
883 if( (Uint32 )i < eval_heap.size()-1 )
884 {
885 eval_heap.insert(i+1, evl);
886 }
887 else
888 {
889 eval_heap.append(evl);
890 }
891 eval_heap.insert(i+1, evl);
892
893 venkat.puvvada 1.17 for( int j=eval_heap.size()-1; j > i + 2; j-- )
894 {
895 //eval_heap[j] = eval_heap[j-2];
896
897 // adjust pointers
898
899 if( (!eval_heap[j].is_terminal1)&&
900 (eval_heap[j].opn1 >= i) )
901 {
902 eval_heap[j].opn1 += 2;
903 }
904
905 if( (!eval_heap[j].is_terminal2)&&
906 (eval_heap[j].opn2 >= i) )
907 {
908 eval_heap[j].opn2 += 2;
909 }
910 }
911
912 n+=2; // increase size of array
913
914 venkat.puvvada 1.17 // generate the new expressions : new OR expression
915
916
917 // first new AND expression
918 eval_heap[i+1].mark = false;
919 eval_heap[i+1].op = WQL_AND;
920 eval_heap[i+1].setFirst(s);
921 eval_heap[i+1].setSecond( eval_heap[index].getFirst());
922 eval_heap[i+1].order();
923
924
925 // second new AND expression
926 eval_heap[i].mark = false;
927 eval_heap[i].op = WQL_AND;
928 eval_heap[i].setFirst(s);
929 eval_heap[i].setSecond( eval_heap[index].getSecond());
930 eval_heap[i].order();
931
932 // mark the indexed expression as inactive
933 //eval_heap[index].op = WQL_IS_TRUE; possible disconnects
934 i--;
|
935 schuur 1.1
|
936 venkat.puvvada 1.17 } /* endif _found > 0 */
|
937 schuur 1.1
|
938 venkat.puvvada 1.17 } /* endif found AND operator */
|
939 schuur 1.1
|
940 venkat.puvvada 1.17 i++; // increase pointer
941 }
|
942 schuur 1.1 }
|
943 ms.aruran 1.18 PEG_METHOD_EXIT();
|
944 schuur 1.1 }
|
945 venkat.puvvada 1.17 void CMPI_Wql2Dnf::_gatherDisj(Array<CMPI_stack_el>& stk)
946 {
947 _gather(stk, CMPI_stack_el(0,true), true);
948 }
|
949 schuur 1.1
|
950 venkat.puvvada 1.17 void CMPI_Wql2Dnf::_gatherConj(
951 Array<CMPI_stack_el>& stk,
952 CMPI_stack_el sel)
|
953 schuur 1.1 {
|
954 venkat.puvvada 1.17 _gather(stk, sel, false);
|
955 schuur 1.1 }
956
|
957 venkat.puvvada 1.17 void CMPI_Wql2Dnf::_gather(
958 Array<CMPI_stack_el>& stk,
959 CMPI_stack_el sel,
960 Boolean or_flag)
|
961 schuur 1.1 {
|
962 ms.aruran 1.18 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPI_Wql2Dnf::_gather()");
|
963 venkat.puvvada 1.17 Uint32 i = 0;
964
965 stk.clear();
966 stk.reserveCapacity(16);
|
967 schuur 1.1
|
968 venkat.puvvada 1.17 if( (i = eval_heap.size()) == 0 )
969 {
|
970 ms.aruran 1.18 PEG_METHOD_EXIT();
|
971 venkat.puvvada 1.17 return;
972 }
|
973 schuur 1.1
|
974 venkat.puvvada 1.17 while( eval_heap[i-1].op == WQL_IS_TRUE )
975 {
976 eval_heap.remove(i-1);
977 i--;
978 if( i == 0 )
979 {
|
980 ms.aruran 1.18 PEG_METHOD_EXIT();
|
981 venkat.puvvada 1.17 return;
982 }
983 }
984 //if (i == 0) return;
|
985 schuur 1.1
|
986 venkat.puvvada 1.17 if( or_flag )
987 {
988 stk.append(CMPI_stack_el(i-1,false));
989 }
|
990 schuur 1.1 else
991 {
|
992 venkat.puvvada 1.17 if( sel.is_terminal )
993 {
|
994 ms.aruran 1.18 PEG_METHOD_EXIT();
|
995 venkat.puvvada 1.17 return;
996 }
997 stk.append(sel);
998 }
999
1000 i = 0;
1001
1002 while( i<stk.size() )
1003 {
1004 int k = stk[i].opn;
1005
1006 if( (k < 0) || (stk[i].is_terminal) )
1007 {
|
1008 schuur 1.3 i++;
|
1009 venkat.puvvada 1.17 }
|
1010 schuur 1.1 else
1011 {
|
1012 venkat.puvvada 1.17 if ( ((eval_heap[k].op != WQL_OR) && (or_flag)) ||
1013 ((eval_heap[k].op != WQL_AND) && (!or_flag)) )
1014 {
1015 i++;
1016 }
1017 else
1018 {
1019 // replace the element with disjunction
1020 stk[i] = eval_heap[k].getSecond();
1021 stk.insert(i, eval_heap[k].getFirst());
1022 if (or_flag)
1023 {
1024 eval_heap[k].op = WQL_IS_TRUE;
1025 }
1026 }
|
1027 schuur 1.1 }
1028 }
|
1029 ms.aruran 1.18 PEG_METHOD_EXIT();
|
1030 schuur 1.1 }
1031
|
1032 venkat.puvvada 1.17 //=============================================================================
|
1033 mike 1.16 //
1034 // class CMPI_stack_el
1035 //
|
1036 venkat.puvvada 1.17 //=============================================================================
|
1037 mike 1.16
|
1038 venkat.puvvada 1.17 //=============================================================================
|
1039 mike 1.16 //
1040 // class CMPI_eval_el
1041 //
|
1042 venkat.puvvada 1.17 //=============================================================================
|
1043 mike 1.16
|
1044 venkat.puvvada 1.17 CMPI_stack_el CMPI_eval_el::getFirst()
1045 {
1046 return CMPI_stack_el(opn1, is_terminal1);
1047 }
|
1048 mike 1.16
|
1049 venkat.puvvada 1.17 CMPI_stack_el CMPI_eval_el::getSecond()
1050 {
1051 return CMPI_stack_el(opn2, is_terminal2);
1052 }
|
1053 mike 1.16
|
1054 venkat.puvvada 1.17 void CMPI_eval_el::setFirst(const CMPI_stack_el s)
1055 {
1056 opn1 = s.opn;
1057 is_terminal1 = s.is_terminal;
1058 }
|
1059 mike 1.16
|
1060 venkat.puvvada 1.17 void CMPI_eval_el::setSecond(const CMPI_stack_el s)
1061 {
1062 opn2 = s.opn;
1063 is_terminal2 = s.is_terminal;
1064 }
|
1065 mike 1.16
|
1066 venkat.puvvada 1.17 void CMPI_eval_el::assign_unary_to_first(const CMPI_eval_el & assignee)
1067 {
1068 opn1 = assignee.opn1;
1069 is_terminal1 = assignee.is_terminal1;
1070 }
|
1071 mike 1.16
|
1072 venkat.puvvada 1.17 void CMPI_eval_el::assign_unary_to_second(const CMPI_eval_el & assignee)
1073 {
1074 opn2 = assignee.opn1;
1075 is_terminal2 = assignee.is_terminal1;
1076 }
|
1077 mike 1.16
1078 // Ordering operators, so that op1 > op2 for all non-terminals
1079 // and terminals appear in the second operand first
1080 void CMPI_eval_el::order(void)
1081 {
|
1082 ms.aruran 1.18 PEG_METHOD_ENTER(TRC_CMPIPROVIDERINTERFACE, "CMPI_eval_el::order()");
|
1083 mike 1.16 int k;
|
1084 venkat.puvvada 1.17 if( (!is_terminal1) && (!is_terminal2) )
1085 if( (k = opn2) > opn1 )
|
1086 mike 1.16 {
1087 opn2 = opn1;
1088 opn1 = k;
1089 }
|
1090 venkat.puvvada 1.17 else
|
1091 mike 1.16 {
|
1092 venkat.puvvada 1.17 if( (is_terminal1) && (!is_terminal2) )
1093 {
1094 if( (k = opn2) > opn1 )
1095 {
1096 opn2 = opn1;
1097 opn1 = k;
1098 is_terminal1 = false;
1099 is_terminal2 = true;
1100 }
1101 }
|
1102 mike 1.16 }
|
1103 ms.aruran 1.18 PEG_METHOD_EXIT();
|
1104 mike 1.16 }
1105
|
1106 schuur 1.1 PEGASUS_NAMESPACE_END
|