[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /* Driver template for the PHP_VTQL_ParserrGenerator parser generator. (PHP port of LEMON) 3 */ 4 5 /** 6 * This can be used to store both the string representation of 7 * a token, and any useful meta-data associated with the token. 8 * 9 * meta-data should be stored as an array 10 */ 11 class VTQL_ParseryyToken implements ArrayAccess 12 { 13 public $string = ''; 14 public $metadata = array(); 15 16 function __construct($s, $m = array()) 17 { 18 if ($s instanceof VTQL_ParseryyToken) { 19 $this->string = $s->string; 20 $this->metadata = $s->metadata; 21 } else { 22 $this->string = (string) $s; 23 if ($m instanceof VTQL_ParseryyToken) { 24 $this->metadata = $m->metadata; 25 } elseif (is_array($m)) { 26 $this->metadata = $m; 27 } 28 } 29 } 30 31 function __toString() 32 { 33 return $this->_string; 34 } 35 36 function offsetExists($offset) 37 { 38 return isset($this->metadata[$offset]); 39 } 40 41 function offsetGet($offset) 42 { 43 return $this->metadata[$offset]; 44 } 45 46 function offsetSet($offset, $value) 47 { 48 if ($offset === null) { 49 if (isset($value[0])) { 50 $x = ($value instanceof VTQL_ParseryyToken) ? 51 $value->metadata : $value; 52 $this->metadata = array_merge($this->metadata, $x); 53 return; 54 } 55 $offset = count($this->metadata); 56 } 57 if ($value === null) { 58 return; 59 } 60 if ($value instanceof VTQL_ParseryyToken) { 61 if ($value->metadata) { 62 $this->metadata[$offset] = $value->metadata; 63 } 64 } elseif ($value) { 65 $this->metadata[$offset] = $value; 66 } 67 } 68 69 function offsetUnset($offset) 70 { 71 unset($this->metadata[$offset]); 72 } 73 } 74 75 /** The following structure represents a single element of the 76 * parser's stack. Information stored includes: 77 * 78 * + The state number for the parser at this level of the stack. 79 * 80 * + The value of the token stored at this level of the stack. 81 * (In other words, the "major" token.) 82 * 83 * + The semantic value stored at this level of the stack. This is 84 * the information used by the action routines in the grammar. 85 * It is sometimes called the "minor" token. 86 */ 87 class VTQL_ParseryyStackEntry 88 { 89 public $stateno; /* The state-number */ 90 public $major; /* The major token value. This is the code 91 ** number for the token at this stack level */ 92 public $minor; /* The user-supplied minor token value. This 93 ** is the value of the token */ 94 }; 95 96 // code external to the class is included here 97 98 // declare_class is output here 99 #line 451 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 100 class VTQL_Parser#line 102 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 101 { 102 /* First off, code is included which follows the "include_class" declaration 103 ** in the input file. */ 104 #line 199 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 105 106 /* 107 add this rule to add parenthesis support. 108 condition ::= PARENOPEN expr_set expr(E) PARENCLOSE. 109 sample format(for contacts) for generated sql object 110 Array ( 111 [column_list] => c4,c3,c2,c1 112 [tableName] => vtiger_crmentity,vtiger_contactdetails,vtiger_contactaddress,vtiger_contactsubdetails,vtiger_contactscf,vtiger_customerdetails 113 [where_condition] => Array ( 114 [column_operators] => Array ( 115 [0] => = 116 [1] => = 117 [2] => = 118 ) 119 [column_names] => Array ( 120 [0] => c1 121 [1] => c2 122 [2] => c3 123 ) 124 [column_values] => Array ( 125 [0] => 'llet me' 126 [1] => 45 127 [2] => -1 128 ) 129 //TO BE DONE 130 [grouping] => Array ( 131 [0] => Array ( 132 [0] => 1 133 [1] => 2 134 ) 135 ) 136 [operators] => Array ( 137 [0] => and 138 [1] => or 139 ) 140 ) 141 [orderby] => Array ( 142 [0] => c4 143 [1] => c5 144 ) 145 [select] => SELECT 146 [from] => from 147 [semi_colon] => ; 148 )*/ 149 private $out; 150 public $lex; 151 private $success ; 152 private $query ; 153 private $error_msg; 154 private $syntax_error; 155 private $user; 156 function __construct($user, $lex,$out){ 157 if(!is_array($out)){ 158 $out = array(); 159 } 160 $this->out = &$out; 161 $this->lex = $lex; 162 $this->success = false; 163 $this->error_msg =''; 164 $this->query = ''; 165 $this->syntax_error = false; 166 $this->user = $user; 167 } 168 169 function __toString(){ 170 return $this->value.""; 171 } 172 function buildSelectStmt($sqlDump){ 173 $meta = $sqlDump['meta']; 174 $fieldcol = $meta->getFieldColumnMapping(); 175 $columnTable = $meta->getColumnTableMapping(); 176 $this->query = 'SELECT '; 177 if(in_array('*', $sqlDump['column_list'])){ 178 $i=0; 179 foreach($fieldcol as $field=>$col){ 180 if($i===0){ 181 $this->query = $this->query.$columnTable[$col].'.'.$col; 182 $i++; 183 }else{ 184 $this->query = $this->query.','.$columnTable[$col].'.'.$col; 185 } 186 } 187 }else if(in_array('count(*)', $sqlDump['column_list'])){ 188 $this->query = $this->query." COUNT(*)"; 189 }else{ 190 $i=0; 191 foreach($sqlDump['column_list'] as $ind=>$field){ 192 if(!$fieldcol[$field]){ 193 throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Permission to access '.$field.' attribute denied."); 194 } 195 if($i===0){ 196 $this->query = $this->query.$columnTable[$fieldcol[$field]].'.'.$fieldcol[$field]; 197 $i++; 198 }else{ 199 $this->query = $this->query.','.$columnTable[$fieldcol[$field]].'.'.$fieldcol[$field]; 200 } 201 } 202 } 203 $this->query = $this->query.' FROM '.$sqlDump['tableName'].$sqlDump['defaultJoinConditions']; 204 $deletedQuery = $meta->getEntityDeletedQuery(); 205 $accessControlQuery = $meta->getEntityAccessControlQuery(); 206 $this->query = $this->query.' '.$accessControlQuery; 207 if($sqlDump['where_condition']){ 208 if((sizeof($sqlDump['where_condition']['column_names']) == 209 sizeof($sqlDump['where_condition']['column_values'])) && 210 (sizeof($sqlDump['where_condition']['column_operators']) == sizeof($sqlDump['where_condition']['operators'])+1)){ 211 $this->query = $this->query.' WHERE ('; 212 $i=0; 213 $referenceFields = $meta->getReferenceFieldDetails(); 214 $ownerFields = $meta->getOwnerFields(); 215 for(;$i<sizeof($sqlDump['where_condition']['column_values']);++$i){ 216 if(!$fieldcol[$sqlDump['where_condition']['column_names'][$i]]){ 217 throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Permission to access ".$sqlDump['where_condition']['column_names'][$i]." attribute denied."); 218 } 219 $whereField = $sqlDump['where_condition']['column_names'][$i]; 220 $whereOperator = $sqlDump['where_condition']['column_operators'][$i]; 221 $whereValue = $sqlDump['where_condition']['column_values'][$i]; 222 if(in_array($whereField,array_keys($referenceFields))){ 223 if(is_array($whereValue)){ 224 foreach($whereValue as $index=>$value){ 225 if(strpos($value,'x')===false){ 226 throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect"); 227 } 228 } 229 $whereValue = array_map(array($this, 'getReferenceValue'),$whereValue); 230 }else if(strpos($whereValue,'x')!==false){ 231 $whereValue = $this->getReferenceValue($whereValue); 232 if(strcasecmp($whereOperator,'like')===0){ 233 $whereValue = "'".$whereValue."'"; 234 } 235 }else{ 236 throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect"); 237 } 238 }else if(in_array($whereField,$ownerFields)){ 239 if(is_array($whereValue)){ 240 $groupId = array_map(array($this, 'getOwner'),$whereValue); 241 }else{ 242 $groupId = $this->getOwner($whereValue); 243 if(strcasecmp($whereOperator,'like')===0){ 244 $groupId = "'$groupId'"; 245 } 246 } 247 $whereValue = $groupId; 248 } 249 if(is_array($whereValue)){ 250 $whereValue = "(".implode(',',$whereValue).")"; 251 }elseif(strcasecmp($whereOperator, 'in') === 0){ 252 $whereValue = "($whereValue)"; 253 } 254 $this->query = $this->query.$columnTable[$fieldcol[$whereField]].'.'. 255 $fieldcol[$whereField]." ".$whereOperator." ".$whereValue; 256 if($i <sizeof($sqlDump['where_condition']['column_values'])-1){ 257 $this->query = $this->query.' '; 258 $this->query = $this->query.$sqlDump['where_condition']['operators'][$i].' '; 259 } 260 } 261 }else{ 262 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "columns data inappropriate"); 263 } 264 $this->query = $this->query.")"; 265 $nextToken = ' AND '; 266 }else{ 267 if(!empty($deletedQuery)){ 268 $nextToken = " WHERE "; 269 } 270 } 271 if(strcasecmp('calendar',$this->out['moduleName'])===0){ 272 $this->query = $this->query." $nextToken activitytype='Task' AND "; 273 }elseif(strcasecmp('events',$this->out['moduleName'])===0){ 274 $this->query = $this->query."$nextToken activitytype!='Emails' AND activitytype!='Task' AND "; 275 }else if(strcasecmp('emails',$this->out['moduleName'])===0){ 276 $this->query = $this->query."$nextToken activitytype='Emails' AND "; 277 }elseif(!empty($deletedQuery)){ 278 $this->query = $this->query.$nextToken; 279 } 280 281 $this->query = $this->query.' '.$deletedQuery; 282 283 if($sqlDump['orderby']){ 284 $i=0; 285 $this->query = $this->query.' ORDER BY '; 286 foreach($sqlDump['orderby'] as $ind=>$field){ 287 if($i===0){ 288 $this->query = $this->query.$columnTable[$fieldcol[$field]].".".$fieldcol[$field]; 289 $i++; 290 }else{ 291 $this->query = $this->query.','.$columnTable[$fieldcol[$field]].".".$fieldcol[$field]; 292 } 293 } 294 if($sqlDump['sortOrder']) { 295 $this->query .= ' '.$sqlDump['sortOrder']; 296 } 297 } 298 if($sqlDump['limit']){ 299 $i=0; 300 $offset =false; 301 if(sizeof($sqlDump['limit'])>1){ 302 $offset = true; 303 } 304 $this->query = $this->query.' LIMIT '; 305 foreach($sqlDump['limit'] as $ind=>$field){ 306 if(!$offset){ 307 $field = ($field>100)? 100: $field; 308 } 309 if($i===0){ 310 $this->query = $this->query.$field; 311 $i++; 312 $offset = false; 313 }else{ 314 $this->query = $this->query.','.$field; 315 } 316 } 317 }else{ 318 $this->query = $this->query.' LIMIT 100'; 319 } 320 $this->query = $this->query.';'; 321 } 322 function getTables($sqlDump,$columns){ 323 $meta = $sqlDump['meta']; 324 $coltable = $meta->getColumnTableMapping(); 325 $tables = array(); 326 foreach($columns as $ind=>$col){ 327 $tables[$coltable[$col]] = $coltable[$col]; 328 } 329 $tables = array_keys($tables); 330 return ($tables); 331 } 332 function getReferenceValue($whereValue){ 333 $whereValue = trim($whereValue,'\'"'); 334 $whereValue = vtws_getIdComponents($whereValue); 335 $whereValue = $whereValue[1]; 336 return $whereValue; 337 } 338 function getOwner($whereValue){ 339 $whereValue = trim($whereValue,'\'"'); 340 $whereValue = vtws_getIdComponents($whereValue); 341 $whereValue = $whereValue[1]; 342 return $whereValue; 343 } 344 function isSuccess(){ 345 return $this->success; 346 } 347 function getErrorMsg(){ 348 return $this->error_msg; 349 } 350 function getQuery(){ 351 return $this->query; 352 } 353 function getObjectMetaData(){ 354 return $this->out['meta']; 355 } 356 #line 359 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 357 358 /* Next is all token values, as class constants 359 */ 360 /* 361 ** These constants (all generated automatically by the parser generator) 362 ** specify the various kinds of tokens (terminals) that the parser 363 ** understands. 364 ** 365 ** Each symbol here is a terminal symbol in the grammar. 366 */ 367 const SELECT = 1; 368 const FRM = 2; 369 const COLUMNNAME = 3; 370 const ASTERISK = 4; 371 const COUNT = 5; 372 const PARENOPEN = 6; 373 const PARENCLOSE = 7; 374 const COMMA = 8; 375 const TABLENAME = 9; 376 const WHERE = 10; 377 const LOGICAL_AND = 11; 378 const LOGICAL_OR = 12; 379 const VALUE = 13; 380 const EQ = 14; 381 const LT = 15; 382 const GT = 16; 383 const LTE = 17; 384 const GTE = 18; 385 const NE = 19; 386 const IN = 20; 387 const LIKE = 21; 388 const ORDERBY = 22; 389 const ASC = 23; 390 const DESC = 24; 391 const LIMIT = 25; 392 const SEMICOLON = 26; 393 const YY_NO_ACTION = 102; 394 const YY_ACCEPT_ACTION = 101; 395 const YY_ERROR_ACTION = 100; 396 397 /* Next are that tables used to determine what action to take based on the 398 ** current state and lookahead token. These tables are used to implement 399 ** functions that take a state number and lookahead value and return an 400 ** action integer. 401 ** 402 ** Suppose the action integer is N. Then the action is determined as 403 ** follows 404 ** 405 ** 0 <= N < self::YYNSTATE Shift N. That is, 406 ** push the lookahead 407 ** token onto the stack 408 ** and goto state N. 409 ** 410 ** self::YYNSTATE <= N < self::YYNSTATE+self::YYNRULE Reduce by rule N-YYNSTATE. 411 ** 412 ** N == self::YYNSTATE+self::YYNRULE A syntax error has occurred. 413 ** 414 ** N == self::YYNSTATE+self::YYNRULE+1 The parser accepts its 415 ** input. (and concludes parsing) 416 ** 417 ** N == self::YYNSTATE+self::YYNRULE+2 No such action. Denotes unused 418 ** slots in the yy_action[] table. 419 ** 420 ** The action table is constructed as a single large static array $yy_action. 421 ** Given state S and lookahead X, the action is computed as 422 ** 423 ** self::$yy_action[self::$yy_shift_ofst[S] + X ] 424 ** 425 ** If the index value self::$yy_shift_ofst[S]+X is out of range or if the value 426 ** self::$yy_lookahead[self::$yy_shift_ofst[S]+X] is not equal to X or if 427 ** self::$yy_shift_ofst[S] is equal to self::YY_SHIFT_USE_DFLT, it means that 428 ** the action is not in the table and that self::$yy_default[S] should be used instead. 429 ** 430 ** The formula above is for computing the action when the lookahead is 431 ** a terminal symbol. If the lookahead is a non-terminal (as occurs after 432 ** a reduce action) then the static $yy_reduce_ofst array is used in place of 433 ** the static $yy_shift_ofst array and self::YY_REDUCE_USE_DFLT is used in place of 434 ** self::YY_SHIFT_USE_DFLT. 435 ** 436 ** The following are the tables generated in this section: 437 ** 438 ** self::$yy_action A single table containing all actions. 439 ** self::$yy_lookahead A table containing the lookahead for each entry in 440 ** yy_action. Used to detect hash collisions. 441 ** self::$yy_shift_ofst For each state, the offset into self::$yy_action for 442 ** shifting terminals. 443 ** self::$yy_reduce_ofst For each state, the offset into self::$yy_action for 444 ** shifting non-terminals after a reduce. 445 ** self::$yy_default Default action for each state. 446 */ 447 const YY_SZ_ACTTAB = 60; 448 static public $yy_action = array( 449 /* 0 */ 36, 29, 28, 30, 31, 38, 39, 37, 41, 26, 450 /* 10 */ 18, 57, 7, 10, 27, 22, 50, 55, 17, 18, 451 /* 20 */ 15, 9, 12, 42, 43, 35, 25, 16, 33, 51, 452 /* 30 */ 52, 101, 56, 21, 47, 2, 19, 46, 52, 44, 453 /* 40 */ 3, 20, 53, 49, 24, 34, 23, 6, 40, 45, 454 /* 50 */ 1, 4, 13, 54, 11, 48, 5, 14, 32, 8, 455 ); 456 static public $yy_lookahead = array( 457 /* 0 */ 14, 15, 16, 17, 18, 19, 20, 21, 41, 42, 458 /* 10 */ 43, 13, 44, 33, 46, 47, 11, 12, 42, 43, 459 /* 20 */ 37, 38, 2, 23, 24, 4, 5, 30, 8, 7, 460 /* 30 */ 8, 28, 29, 36, 35, 22, 4, 13, 8, 8, 461 /* 40 */ 1, 6, 26, 3, 8, 3, 13, 3, 7, 45, 462 /* 50 */ 40, 6, 34, 39, 31, 48, 10, 32, 9, 25, 463 ); 464 const YY_SHIFT_USE_DFLT = -15; 465 const YY_SHIFT_MAX = 27; 466 static public $yy_shift_ofst = array( 467 /* 0 */ 39, 45, -15, 21, -15, -15, -14, 0, 33, 44, 468 /* 10 */ 34, 46, 49, 16, 13, 5, 20, 22, -2, 41, 469 /* 20 */ 32, 42, 40, 36, 24, 35, 30, 31, 470 ); 471 const YY_REDUCE_USE_DFLT = -34; 472 const YY_REDUCE_MAX = 14; 473 static public $yy_reduce_ofst = array( 474 /* 0 */ 3, -33, -32, -3, -24, -17, 10, 4, 7, 14, 475 /* 10 */ 18, 25, 23, -1, -20, 476 ); 477 static public $yyExpectedTokens = array( 478 /* 0 */ array(1, ), 479 /* 1 */ array(6, ), 480 /* 2 */ array(), 481 /* 3 */ array(4, 5, ), 482 /* 4 */ array(), 483 /* 5 */ array(), 484 /* 6 */ array(14, 15, 16, 17, 18, 19, 20, 21, ), 485 /* 7 */ array(23, 24, ), 486 /* 8 */ array(13, ), 487 /* 9 */ array(3, ), 488 /* 10 */ array(25, ), 489 /* 11 */ array(10, ), 490 /* 12 */ array(9, ), 491 /* 13 */ array(26, ), 492 /* 14 */ array(22, ), 493 /* 15 */ array(11, 12, ), 494 /* 16 */ array(2, 8, ), 495 /* 17 */ array(7, 8, ), 496 /* 18 */ array(13, ), 497 /* 19 */ array(7, ), 498 /* 20 */ array(4, ), 499 /* 21 */ array(3, ), 500 /* 22 */ array(3, ), 501 /* 23 */ array(8, ), 502 /* 24 */ array(13, ), 503 /* 25 */ array(6, ), 504 /* 26 */ array(8, ), 505 /* 27 */ array(8, ), 506 /* 28 */ array(), 507 /* 29 */ array(), 508 /* 30 */ array(), 509 /* 31 */ array(), 510 /* 32 */ array(), 511 /* 33 */ array(), 512 /* 34 */ array(), 513 /* 35 */ array(), 514 /* 36 */ array(), 515 /* 37 */ array(), 516 /* 38 */ array(), 517 /* 39 */ array(), 518 /* 40 */ array(), 519 /* 41 */ array(), 520 /* 42 */ array(), 521 /* 43 */ array(), 522 /* 44 */ array(), 523 /* 45 */ array(), 524 /* 46 */ array(), 525 /* 47 */ array(), 526 /* 48 */ array(), 527 /* 49 */ array(), 528 /* 50 */ array(), 529 /* 51 */ array(), 530 /* 52 */ array(), 531 /* 53 */ array(), 532 /* 54 */ array(), 533 /* 55 */ array(), 534 /* 56 */ array(), 535 /* 57 */ array(), 536 ); 537 static public $yy_default = array( 538 /* 0 */ 100, 77, 91, 64, 77, 71, 100, 94, 100, 100, 539 /* 10 */ 96, 67, 100, 100, 87, 66, 100, 100, 100, 100, 540 /* 20 */ 100, 100, 100, 97, 100, 100, 74, 88, 80, 79, 541 /* 30 */ 81, 82, 65, 63, 60, 61, 78, 85, 83, 84, 542 /* 40 */ 62, 72, 92, 93, 90, 86, 98, 59, 95, 89, 543 /* 50 */ 69, 73, 76, 99, 68, 70, 58, 75, 544 ); 545 /* The next thing included is series of defines which control 546 ** various aspects of the generated parser. 547 ** self::YYNOCODE is a number which corresponds 548 ** to no legal terminal or nonterminal number. This 549 ** number is used to fill in empty slots of the hash 550 ** table. 551 ** self::YYFALLBACK If defined, this indicates that one or more tokens 552 ** have fall-back values which should be used if the 553 ** original value of the token will not parse. 554 ** self::YYSTACKDEPTH is the maximum depth of the parser's stack. 555 ** self::YYNSTATE the combined number of states. 556 ** self::YYNRULE the number of rules in the grammar 557 ** self::YYERRORSYMBOL is the code number of the error symbol. If not 558 ** defined, then do no error processing. 559 */ 560 const YYNOCODE = 50; 561 const YYSTACKDEPTH = 100; 562 const YYNSTATE = 58; 563 const YYNRULE = 42; 564 const YYERRORSYMBOL = 27; 565 const YYERRSYMDT = 'yy0'; 566 const YYFALLBACK = 0; 567 /** The next table maps tokens into fallback tokens. If a construct 568 * like the following: 569 * 570 * %fallback ID X Y Z. 571 * 572 * appears in the grammer, then ID becomes a fallback token for X, Y, 573 * and Z. Whenever one of the tokens X, Y, or Z is input to the parser 574 * but it does not parse, the type of the token is changed to ID and 575 * the parse is retried before an error is thrown. 576 */ 577 static public $yyFallback = array( 578 ); 579 /** 580 * Turn parser tracing on by giving a stream to which to write the trace 581 * and a prompt to preface each trace message. Tracing is turned off 582 * by making either argument NULL 583 * 584 * Inputs: 585 * 586 * - A stream resource to which trace output should be written. 587 * If NULL, then tracing is turned off. 588 * - A prefix string written at the beginning of every 589 * line of trace output. If NULL, then tracing is 590 * turned off. 591 * 592 * Outputs: 593 * 594 * - None. 595 * @param resource 596 * @param string 597 */ 598 static function Trace($TraceFILE, $zTracePrompt) 599 { 600 if (!$TraceFILE) { 601 $zTracePrompt = 0; 602 } elseif (!$zTracePrompt) { 603 $TraceFILE = 0; 604 } 605 self::$yyTraceFILE = $TraceFILE; 606 self::$yyTracePrompt = $zTracePrompt; 607 } 608 609 /** 610 * Output debug information to output (php://output stream) 611 */ 612 static function PrintTrace() 613 { 614 self::$yyTraceFILE = fopen('php://output', 'w'); 615 self::$yyTracePrompt = ''; 616 } 617 618 /** 619 * @var resource|0 620 */ 621 static public $yyTraceFILE; 622 /** 623 * String to prepend to debug output 624 * @var string|0 625 */ 626 static public $yyTracePrompt; 627 /** 628 * @var int 629 */ 630 public $yyidx; /* Index of top element in stack */ 631 /** 632 * @var int 633 */ 634 public $yyerrcnt; /* Shifts left before out of the error */ 635 /** 636 * @var array 637 */ 638 public $yystack = array(); /* The parser's stack */ 639 640 /** 641 * For tracing shifts, the names of all terminals and nonterminals 642 * are required. The following table supplies these names 643 * @var array 644 */ 645 static public $yyTokenName = array( 646 '$', 'SELECT', 'FRM', 'COLUMNNAME', 647 'ASTERISK', 'COUNT', 'PARENOPEN', 'PARENCLOSE', 648 'COMMA', 'TABLENAME', 'WHERE', 'LOGICAL_AND', 649 'LOGICAL_OR', 'VALUE', 'EQ', 'LT', 650 'GT', 'LTE', 'GTE', 'NE', 651 'IN', 'LIKE', 'ORDERBY', 'ASC', 652 'DESC', 'LIMIT', 'SEMICOLON', 'error', 653 'sql', 'select_statement', 'selectcol_list', 'table_list', 654 'where_condition', 'order_clause', 'limit_clause', 'end_stmt', 655 'selectcolumn_exp', 'condition', 'expr_set', 'expr', 656 'logical_term', 'valuelist', 'valueref', 'value_exp', 657 'column_group', 'clause', 'column_list', 'column_exp', 658 'limit_set', 659 ); 660 661 /** 662 * For tracing reduce actions, the names of all rules are required. 663 * @var array 664 */ 665 static public $yyRuleName = array( 666 /* 0 */ "sql ::= select_statement", 667 /* 1 */ "select_statement ::= SELECT selectcol_list FRM table_list where_condition order_clause limit_clause end_stmt", 668 /* 2 */ "selectcol_list ::= selectcolumn_exp COLUMNNAME", 669 /* 3 */ "selectcol_list ::= ASTERISK", 670 /* 4 */ "selectcol_list ::= COUNT PARENOPEN ASTERISK PARENCLOSE", 671 /* 5 */ "selectcolumn_exp ::= selectcol_list COMMA", 672 /* 6 */ "selectcolumn_exp ::=", 673 /* 7 */ "table_list ::= TABLENAME", 674 /* 8 */ "where_condition ::= WHERE condition", 675 /* 9 */ "where_condition ::=", 676 /* 10 */ "condition ::= expr_set expr", 677 /* 11 */ "expr_set ::= condition LOGICAL_AND", 678 /* 12 */ "expr_set ::= condition LOGICAL_OR", 679 /* 13 */ "expr_set ::=", 680 /* 14 */ "expr ::= COLUMNNAME logical_term valuelist", 681 /* 15 */ "valuelist ::= PARENOPEN valueref PARENCLOSE", 682 /* 16 */ "valuelist ::= valueref", 683 /* 17 */ "valueref ::= value_exp VALUE", 684 /* 18 */ "value_exp ::= valueref COMMA", 685 /* 19 */ "value_exp ::=", 686 /* 20 */ "logical_term ::= EQ", 687 /* 21 */ "logical_term ::= LT", 688 /* 22 */ "logical_term ::= GT", 689 /* 23 */ "logical_term ::= LTE", 690 /* 24 */ "logical_term ::= GTE", 691 /* 25 */ "logical_term ::= NE", 692 /* 26 */ "logical_term ::= IN", 693 /* 27 */ "logical_term ::= LIKE", 694 /* 28 */ "order_clause ::= ORDERBY column_group clause", 695 /* 29 */ "order_clause ::=", 696 /* 30 */ "column_group ::= column_list", 697 /* 31 */ "column_list ::= column_exp COLUMNNAME", 698 /* 32 */ "column_exp ::= column_list COMMA", 699 /* 33 */ "column_exp ::=", 700 /* 34 */ "clause ::= ASC", 701 /* 35 */ "clause ::= DESC", 702 /* 36 */ "clause ::=", 703 /* 37 */ "limit_clause ::= LIMIT limit_set", 704 /* 38 */ "limit_clause ::=", 705 /* 39 */ "limit_set ::= VALUE", 706 /* 40 */ "limit_set ::= VALUE COMMA VALUE", 707 /* 41 */ "end_stmt ::= SEMICOLON", 708 ); 709 710 /** 711 * This function returns the symbolic name associated with a token 712 * value. 713 * @param int 714 * @return string 715 */ 716 function tokenName($tokenType) 717 { 718 if ($tokenType === 0) { 719 return 'End of Input'; 720 } 721 if ($tokenType > 0 && $tokenType < count(self::$yyTokenName)) { 722 return self::$yyTokenName[$tokenType]; 723 } else { 724 return "Unknown"; 725 } 726 } 727 728 /** 729 * The following function deletes the value associated with a 730 * symbol. The symbol can be either a terminal or nonterminal. 731 * @param int the symbol code 732 * @param mixed the symbol's value 733 */ 734 static function yy_destructor($yymajor, $yypminor) 735 { 736 switch ($yymajor) { 737 /* Here is inserted the actions which take place when a 738 ** terminal or non-terminal is destroyed. This can happen 739 ** when the symbol is popped from the stack during a 740 ** reduce or during error processing or when a parser is 741 ** being destroyed before it is finished parsing. 742 ** 743 ** Note: during a reduce, the only symbols destroyed are those 744 ** which appear on the RHS of the rule, but which are not used 745 ** inside the C code. 746 */ 747 default: break; /* If no destructor action specified: do nothing */ 748 } 749 } 750 751 /** 752 * Pop the parser's stack once. 753 * 754 * If there is a destructor routine associated with the token which 755 * is popped from the stack, then call it. 756 * 757 * Return the major token number for the symbol popped. 758 * @param VTQL_ParseryyParser 759 * @return int 760 */ 761 function yy_pop_parser_stack() 762 { 763 if (!count($this->yystack)) { 764 return; 765 } 766 $yytos = array_pop($this->yystack); 767 if (self::$yyTraceFILE && $this->yyidx >= 0) { 768 fwrite(self::$yyTraceFILE, 769 self::$yyTracePrompt . 'Popping ' . self::$yyTokenName[$yytos->major] . 770 "\n"); 771 } 772 $yymajor = $yytos->major; 773 self::yy_destructor($yymajor, $yytos->minor); 774 $this->yyidx--; 775 return $yymajor; 776 } 777 778 /** 779 * Deallocate and destroy a parser. Destructors are all called for 780 * all stack elements before shutting the parser down. 781 */ 782 function __destruct() 783 { 784 while ($this->yyidx >= 0) { 785 $this->yy_pop_parser_stack(); 786 } 787 if (is_resource(self::$yyTraceFILE)) { 788 fclose(self::$yyTraceFILE); 789 } 790 } 791 792 /** 793 * Based on the current state and parser stack, get a list of all 794 * possible lookahead tokens 795 * @param int 796 * @return array 797 */ 798 function yy_get_expected_tokens($token) 799 { 800 $state = $this->yystack[$this->yyidx]->stateno; 801 $expected = self::$yyExpectedTokens[$state]; 802 if (in_array($token, self::$yyExpectedTokens[$state], true)) { 803 return $expected; 804 } 805 $stack = $this->yystack; 806 $yyidx = $this->yyidx; 807 do { 808 $yyact = $this->yy_find_shift_action($token); 809 if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) { 810 // reduce action 811 $done = 0; 812 do { 813 if ($done++ == 100) { 814 $this->yyidx = $yyidx; 815 $this->yystack = $stack; 816 // too much recursion prevents proper detection 817 // so give up 818 return array_unique($expected); 819 } 820 $yyruleno = $yyact - self::YYNSTATE; 821 $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs']; 822 $nextstate = $this->yy_find_reduce_action( 823 $this->yystack[$this->yyidx]->stateno, 824 self::$yyRuleInfo[$yyruleno]['lhs']); 825 if (isset(self::$yyExpectedTokens[$nextstate])) { 826 $expected += self::$yyExpectedTokens[$nextstate]; 827 if (in_array($token, 828 self::$yyExpectedTokens[$nextstate], true)) { 829 $this->yyidx = $yyidx; 830 $this->yystack = $stack; 831 return array_unique($expected); 832 } 833 } 834 if ($nextstate < self::YYNSTATE) { 835 // we need to shift a non-terminal 836 $this->yyidx++; 837 $x = new VTQL_ParseryyStackEntry; 838 $x->stateno = $nextstate; 839 $x->major = self::$yyRuleInfo[$yyruleno]['lhs']; 840 $this->yystack[$this->yyidx] = $x; 841 continue 2; 842 } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) { 843 $this->yyidx = $yyidx; 844 $this->yystack = $stack; 845 // the last token was just ignored, we can't accept 846 // by ignoring input, this is in essence ignoring a 847 // syntax error! 848 return array_unique($expected); 849 } elseif ($nextstate === self::YY_NO_ACTION) { 850 $this->yyidx = $yyidx; 851 $this->yystack = $stack; 852 // input accepted, but not shifted (I guess) 853 return $expected; 854 } else { 855 $yyact = $nextstate; 856 } 857 } while (true); 858 } 859 break; 860 } while (true); 861 return array_unique($expected); 862 } 863 864 /** 865 * Based on the parser state and current parser stack, determine whether 866 * the lookahead token is possible. 867 * 868 * The parser will convert the token value to an error token if not. This 869 * catches some unusual edge cases where the parser would fail. 870 * @param int 871 * @return bool 872 */ 873 function yy_is_expected_token($token) 874 { 875 if ($token === 0) { 876 return true; // 0 is not part of this 877 } 878 $state = $this->yystack[$this->yyidx]->stateno; 879 if (in_array($token, self::$yyExpectedTokens[$state], true)) { 880 return true; 881 } 882 $stack = $this->yystack; 883 $yyidx = $this->yyidx; 884 do { 885 $yyact = $this->yy_find_shift_action($token); 886 if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) { 887 // reduce action 888 $done = 0; 889 do { 890 if ($done++ == 100) { 891 $this->yyidx = $yyidx; 892 $this->yystack = $stack; 893 // too much recursion prevents proper detection 894 // so give up 895 return true; 896 } 897 $yyruleno = $yyact - self::YYNSTATE; 898 $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs']; 899 $nextstate = $this->yy_find_reduce_action( 900 $this->yystack[$this->yyidx]->stateno, 901 self::$yyRuleInfo[$yyruleno]['lhs']); 902 if (isset(self::$yyExpectedTokens[$nextstate]) && 903 in_array($token, self::$yyExpectedTokens[$nextstate], true)) { 904 $this->yyidx = $yyidx; 905 $this->yystack = $stack; 906 return true; 907 } 908 if ($nextstate < self::YYNSTATE) { 909 // we need to shift a non-terminal 910 $this->yyidx++; 911 $x = new VTQL_ParseryyStackEntry; 912 $x->stateno = $nextstate; 913 $x->major = self::$yyRuleInfo[$yyruleno]['lhs']; 914 $this->yystack[$this->yyidx] = $x; 915 continue 2; 916 } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) { 917 $this->yyidx = $yyidx; 918 $this->yystack = $stack; 919 if (!$token) { 920 // end of input: this is valid 921 return true; 922 } 923 // the last token was just ignored, we can't accept 924 // by ignoring input, this is in essence ignoring a 925 // syntax error! 926 return false; 927 } elseif ($nextstate === self::YY_NO_ACTION) { 928 $this->yyidx = $yyidx; 929 $this->yystack = $stack; 930 // input accepted, but not shifted (I guess) 931 return true; 932 } else { 933 $yyact = $nextstate; 934 } 935 } while (true); 936 } 937 break; 938 } while (true); 939 return true; 940 } 941 942 /** 943 * Find the appropriate action for a parser given the terminal 944 * look-ahead token iLookAhead. 945 * 946 * If the look-ahead token is YYNOCODE, then check to see if the action is 947 * independent of the look-ahead. If it is, return the action, otherwise 948 * return YY_NO_ACTION. 949 * @param int The look-ahead token 950 */ 951 function yy_find_shift_action($iLookAhead) 952 { 953 $stateno = $this->yystack[$this->yyidx]->stateno; 954 955 /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */ 956 if (!isset(self::$yy_shift_ofst[$stateno])) { 957 // no shift actions 958 return self::$yy_default[$stateno]; 959 } 960 $i = self::$yy_shift_ofst[$stateno]; 961 if ($i === self::YY_SHIFT_USE_DFLT) { 962 return self::$yy_default[$stateno]; 963 } 964 if ($iLookAhead == self::YYNOCODE) { 965 return self::YY_NO_ACTION; 966 } 967 $i += $iLookAhead; 968 if ($i < 0 || $i >= self::YY_SZ_ACTTAB || 969 self::$yy_lookahead[$i] != $iLookAhead) { 970 if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback) 971 && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) { 972 if (self::$yyTraceFILE) { 973 fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " . 974 self::$yyTokenName[$iLookAhead] . " => " . 975 self::$yyTokenName[$iFallback] . "\n"); 976 } 977 return $this->yy_find_shift_action($iFallback); 978 } 979 return self::$yy_default[$stateno]; 980 } else { 981 return self::$yy_action[$i]; 982 } 983 } 984 985 /** 986 * Find the appropriate action for a parser given the non-terminal 987 * look-ahead token $iLookAhead. 988 * 989 * If the look-ahead token is self::YYNOCODE, then check to see if the action is 990 * independent of the look-ahead. If it is, return the action, otherwise 991 * return self::YY_NO_ACTION. 992 * @param int Current state number 993 * @param int The look-ahead token 994 */ 995 function yy_find_reduce_action($stateno, $iLookAhead) 996 { 997 /* $stateno = $this->yystack[$this->yyidx]->stateno; */ 998 999 if (!isset(self::$yy_reduce_ofst[$stateno])) { 1000 return self::$yy_default[$stateno]; 1001 } 1002 $i = self::$yy_reduce_ofst[$stateno]; 1003 if ($i == self::YY_REDUCE_USE_DFLT) { 1004 return self::$yy_default[$stateno]; 1005 } 1006 if ($iLookAhead == self::YYNOCODE) { 1007 return self::YY_NO_ACTION; 1008 } 1009 $i += $iLookAhead; 1010 if ($i < 0 || $i >= self::YY_SZ_ACTTAB || 1011 self::$yy_lookahead[$i] != $iLookAhead) { 1012 return self::$yy_default[$stateno]; 1013 } else { 1014 return self::$yy_action[$i]; 1015 } 1016 } 1017 1018 /** 1019 * Perform a shift action. 1020 * @param int The new state to shift in 1021 * @param int The major token to shift in 1022 * @param mixed the minor token to shift in 1023 */ 1024 function yy_shift($yyNewState, $yyMajor, $yypMinor) 1025 { 1026 $this->yyidx++; 1027 if ($this->yyidx >= self::YYSTACKDEPTH) { 1028 $this->yyidx--; 1029 if (self::$yyTraceFILE) { 1030 fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt); 1031 } 1032 while ($this->yyidx >= 0) { 1033 $this->yy_pop_parser_stack(); 1034 } 1035 /* Here code is inserted which will execute if the parser 1036 ** stack ever overflows */ 1037 #line 462 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1038 1039 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "Parser stack overflow"); 1040 #line 1046 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1041 return; 1042 } 1043 $yytos = new VTQL_ParseryyStackEntry; 1044 $yytos->stateno = $yyNewState; 1045 $yytos->major = $yyMajor; 1046 $yytos->minor = $yypMinor; 1047 array_push($this->yystack, $yytos); 1048 if (self::$yyTraceFILE && $this->yyidx > 0) { 1049 fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt, 1050 $yyNewState); 1051 fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt); 1052 for($i = 1; $i <= $this->yyidx; $i++) { 1053 fprintf(self::$yyTraceFILE, " %s", 1054 self::$yyTokenName[$this->yystack[$i]->major]); 1055 } 1056 fwrite(self::$yyTraceFILE,"\n"); 1057 } 1058 } 1059 1060 /** 1061 * The following table contains information about every rule that 1062 * is used during the reduce. 1063 * 1064 * <pre> 1065 * array( 1066 * array( 1067 * int $lhs; Symbol on the left-hand side of the rule 1068 * int $nrhs; Number of right-hand side symbols in the rule 1069 * ),... 1070 * ); 1071 * </pre> 1072 */ 1073 static public $yyRuleInfo = array( 1074 array( 'lhs' => 28, 'rhs' => 1 ), 1075 array( 'lhs' => 29, 'rhs' => 8 ), 1076 array( 'lhs' => 30, 'rhs' => 2 ), 1077 array( 'lhs' => 30, 'rhs' => 1 ), 1078 array( 'lhs' => 30, 'rhs' => 4 ), 1079 array( 'lhs' => 36, 'rhs' => 2 ), 1080 array( 'lhs' => 36, 'rhs' => 0 ), 1081 array( 'lhs' => 31, 'rhs' => 1 ), 1082 array( 'lhs' => 32, 'rhs' => 2 ), 1083 array( 'lhs' => 32, 'rhs' => 0 ), 1084 array( 'lhs' => 37, 'rhs' => 2 ), 1085 array( 'lhs' => 38, 'rhs' => 2 ), 1086 array( 'lhs' => 38, 'rhs' => 2 ), 1087 array( 'lhs' => 38, 'rhs' => 0 ), 1088 array( 'lhs' => 39, 'rhs' => 3 ), 1089 array( 'lhs' => 41, 'rhs' => 3 ), 1090 array( 'lhs' => 41, 'rhs' => 1 ), 1091 array( 'lhs' => 42, 'rhs' => 2 ), 1092 array( 'lhs' => 43, 'rhs' => 2 ), 1093 array( 'lhs' => 43, 'rhs' => 0 ), 1094 array( 'lhs' => 40, 'rhs' => 1 ), 1095 array( 'lhs' => 40, 'rhs' => 1 ), 1096 array( 'lhs' => 40, 'rhs' => 1 ), 1097 array( 'lhs' => 40, 'rhs' => 1 ), 1098 array( 'lhs' => 40, 'rhs' => 1 ), 1099 array( 'lhs' => 40, 'rhs' => 1 ), 1100 array( 'lhs' => 40, 'rhs' => 1 ), 1101 array( 'lhs' => 40, 'rhs' => 1 ), 1102 array( 'lhs' => 33, 'rhs' => 3 ), 1103 array( 'lhs' => 33, 'rhs' => 0 ), 1104 array( 'lhs' => 44, 'rhs' => 1 ), 1105 array( 'lhs' => 46, 'rhs' => 2 ), 1106 array( 'lhs' => 47, 'rhs' => 2 ), 1107 array( 'lhs' => 47, 'rhs' => 0 ), 1108 array( 'lhs' => 45, 'rhs' => 1 ), 1109 array( 'lhs' => 45, 'rhs' => 1 ), 1110 array( 'lhs' => 45, 'rhs' => 0 ), 1111 array( 'lhs' => 34, 'rhs' => 2 ), 1112 array( 'lhs' => 34, 'rhs' => 0 ), 1113 array( 'lhs' => 48, 'rhs' => 1 ), 1114 array( 'lhs' => 48, 'rhs' => 3 ), 1115 array( 'lhs' => 35, 'rhs' => 1 ), 1116 ); 1117 1118 /** 1119 * The following table contains a mapping of reduce action to method name 1120 * that handles the reduction. 1121 * 1122 * If a rule is not set, it has no handler. 1123 */ 1124 static public $yyReduceMap = array( 1125 1 => 1, 1126 2 => 2, 1127 3 => 3, 1128 4 => 4, 1129 7 => 7, 1130 11 => 11, 1131 12 => 11, 1132 14 => 14, 1133 17 => 17, 1134 20 => 20, 1135 21 => 21, 1136 22 => 22, 1137 23 => 23, 1138 24 => 24, 1139 25 => 25, 1140 26 => 26, 1141 27 => 27, 1142 31 => 31, 1143 34 => 34, 1144 35 => 35, 1145 39 => 39, 1146 40 => 40, 1147 41 => 41, 1148 ); 1149 /* Beginning here are the reduction cases. A typical example 1150 ** follows: 1151 ** #line <lineno> <grammarfile> 1152 ** function yy_r0($yymsp){ ... } // User supplied code 1153 ** #line <lineno> <thisfile> 1154 */ 1155 #line 5 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1156 function yy_r1(){ 1157 if($this->yystack[$this->yyidx + -7]->minor){ 1158 $this->out['select'] = $this->yystack[$this->yyidx + -7]->minor; 1159 } 1160 if($this->yystack[$this->yyidx + -5]->minor){ 1161 $this->out['from'] = $this->yystack[$this->yyidx + -5]->minor ; 1162 } 1163 if(SEMI){ 1164 $this->out['semi_colon'] = SEMI; 1165 } 1166 if($this->out['select']){ 1167 $this->buildSelectStmt($this->out); 1168 } 1169 } 1170 #line 1176 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1171 #line 19 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1172 function yy_r2(){ 1173 $this->out['column_list'][] = $this->yystack[$this->yyidx + 0]->minor; 1174 } 1175 #line 1181 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1176 #line 22 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1177 function yy_r3(){ 1178 $this->out['column_list'][] = $this->yystack[$this->yyidx + 0]->minor; 1179 } 1180 #line 1186 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1181 #line 25 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1182 function yy_r4(){ 1183 $this->out['column_list'][] = 'count(*)'; 1184 } 1185 #line 1191 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1186 #line 30 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1187 function yy_r7(){ 1188 if(!in_array("*", $this->out["column_list"]) && !in_array("count(*)", array_map(strtolower, $this->out["column_list"]))){ 1189 if(!in_array("id",$this->out["column_list"])){ 1190 $this->out["column_list"][] = "id"; 1191 } 1192 } 1193 $moduleName = $this->yystack[$this->yyidx + 0]->minor; 1194 if(!$moduleName){ 1195 $this->syntax_error = true; 1196 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "There is an syntax error in query"); 1197 } 1198 global $adb; 1199 $handler = vtws_getModuleHandlerFromName($moduleName,$this->user); 1200 $objectMeta = $handler->getMeta(); 1201 $this->out['moduleName'] = $moduleName; 1202 $this->out['tableName'] = implode(',',$objectMeta->getEntityTableList()); 1203 } 1204 #line 1210 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1205 #line 50 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1206 function yy_r11(){ 1207 $this->out['where_condition']['operators'][] = $this->yystack[$this->yyidx + 0]->minor; 1208 } 1209 #line 1215 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1210 #line 57 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1211 function yy_r14(){ 1212 $this->out['columnDone']=true; 1213 $this->out['where_condition']['column_names'][] = $this->yystack[$this->yyidx + -2]->minor; 1214 if(strcmp($this->yystack[$this->yyidx + -2]->minor, 'id')===0){ 1215 $prev = $this->out['where_condition']['column_values'][sizeof($this->out['where_condition']['column_values'])-1]; 1216 if(is_array($prev)){ 1217 $new = array(); 1218 foreach($prev as $ind=>$val){ 1219 $val = trim($val,'\'"'); 1220 $value = vtws_getIdComponents($val); 1221 $new[] = $value[1]; 1222 } 1223 $this->out['where_condition']['column_values'][sizeof($this->out['where_condition']['column_values'])-1] = $new; 1224 }else{ 1225 $prev = trim($prev,'\'"'); 1226 $value = vtws_getIdComponents($prev); 1227 if(strcasecmp($this->out['where_condition']['column_operators'][sizeof($this->out['where_condition']['column_operators'])-1],'like')===0){ 1228 $value[1] = "'".$value[1]."'"; 1229 } 1230 $this->out['where_condition']['column_values'][sizeof($this->out['where_condition']['column_values'])-1] = $value[1]; 1231 } 1232 } 1233 } 1234 #line 1240 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1235 #line 82 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1236 function yy_r17(){ 1237 $length = sizeof($this->out['where_condition']['column_values']); 1238 $pos = $length - 1; 1239 if($pos < 0){ 1240 $pos = 0; 1241 } 1242 if(strcasecmp($this->out['where_condition']['column_operators'][$pos],"in")===0 && 1243 !empty($this->out['where_condition']['column_values'][$pos]) && !$this->out['columnDone']){ 1244 if(!is_array($this->out['where_condition']['column_values'][$pos])){ 1245 $prev = $this->out['where_condition']['column_values'][$pos]; 1246 $this->out['where_condition']['column_values'][$pos] = array(); 1247 $this->out['where_condition']['column_values'][$pos][] = $prev; 1248 } 1249 $this->out['where_condition']['column_values'][$pos][] = $this->yystack[$this->yyidx + 0]->minor; 1250 }else{ 1251 $this->out['columnDone'] = false; 1252 $this->out['where_condition']['column_values'][] = $this->yystack[$this->yyidx + 0]->minor; 1253 } 1254 } 1255 #line 1261 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1256 #line 103 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1257 function yy_r20(){ 1258 $this->out['where_condition']['column_operators'][] = '='; 1259 } 1260 #line 1266 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1261 #line 106 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1262 function yy_r21(){ 1263 $this->out['where_condition']['column_operators'][] = '<'; 1264 } 1265 #line 1271 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1266 #line 109 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1267 function yy_r22(){ 1268 $this->out['where_condition']['column_operators'][] = '>'; 1269 } 1270 #line 1276 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1271 #line 112 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1272 function yy_r23(){ 1273 $this->out['where_condition']['column_operators'][] = '<='; 1274 } 1275 #line 1281 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1276 #line 115 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1277 function yy_r24(){ 1278 $this->out['where_condition']['column_operators'][] = '>='; 1279 } 1280 #line 1286 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1281 #line 118 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1282 function yy_r25(){ 1283 $this->out['where_condition']['column_operators'][] = '!='; 1284 } 1285 #line 1291 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1286 #line 121 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1287 function yy_r26(){ 1288 $this->out['where_condition']['column_operators'][] = 'IN'; 1289 } 1290 #line 1296 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1291 #line 124 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1292 function yy_r27(){ 1293 $this->out['where_condition']['column_operators'][] = 'LIKE'; 1294 } 1295 #line 1301 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1296 #line 130 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1297 function yy_r31(){ 1298 $this->out['orderby'][] = $this->yystack[$this->yyidx + 0]->minor; 1299 } 1300 #line 1306 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1301 #line 135 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1302 function yy_r34(){ 1303 $this->out['sortOrder'] = 'ASC'; 1304 } 1305 #line 1311 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1306 #line 138 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1307 function yy_r35(){ 1308 $this->out['sortOrder'] = 'DESC'; 1309 } 1310 #line 1316 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1311 #line 144 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1312 function yy_r39(){ 1313 $this->out['limit'][] = $this->yystack[$this->yyidx + 0]->minor; 1314 } 1315 #line 1321 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1316 #line 147 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1317 function yy_r40(){ 1318 $this->out['limit'][] = $this->yystack[$this->yyidx + -2]->minor; 1319 $this->out['limit'][] = $this->yystack[$this->yyidx + 0]->minor; 1320 } 1321 #line 1327 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1322 #line 151 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1323 function yy_r41(){ 1324 global $adb; 1325 if(!$this->out['meta']){ 1326 $module = $this->out['moduleName']; 1327 $handler = vtws_getModuleHandlerFromName($module,$this->user); 1328 $objectMeta = $handler->getMeta(); 1329 $this->out['meta'] = $objectMeta; 1330 $meta = $this->out['meta']; 1331 $fieldcol = $meta->getFieldColumnMapping(); 1332 $columns = array(); 1333 if(in_array('*', $this->out['column_list'])){ 1334 $columns = array_values($fieldcol); 1335 }elseif( !in_array('count(*)', array_map(strtolower, $this->out['column_list']))){ 1336 foreach($this->out['column_list'] as $ind=>$field){ 1337 $columns[] = $fieldcol[$field]; 1338 } 1339 } 1340 if($this->out['where_condition']){ 1341 foreach($this->out['where_condition']['column_names'] as $ind=>$field){ 1342 $columns[] = $fieldcol[$field]; 1343 } 1344 } 1345 $tables = $this->getTables($this->out, $columns); 1346 if(!in_array($objectMeta->getEntityBaseTable(), $tables)){ 1347 $tables[] = $objectMeta->getEntityBaseTable(); 1348 } 1349 $defaultTableList = $objectMeta->getEntityDefaultTableList(); 1350 foreach($defaultTableList as $tableName){ 1351 if(!in_array($tableName,$tables)){ 1352 array_push($tables,$tableName); 1353 } 1354 } 1355 $firstTable = $objectMeta->getEntityBaseTable(); 1356 $tabNameIndex = $objectMeta->getEntityTableIndexList(); 1357 $firstIndex = $tabNameIndex[$firstTable]; 1358 foreach($tables as $ind=>$table){ 1359 if($firstTable!=$table){ 1360 if(!isset($tabNameIndex[$table]) && $table == "vtiger_crmentity"){ 1361 $this->out['defaultJoinConditions'] = $this->out['defaultJoinConditions']." LEFT JOIN $table ON $firstTable.$firstIndex=$table.crmid"; 1362 }else{ 1363 $this->out['defaultJoinConditions'] = $this->out['defaultJoinConditions']." LEFT JOIN $table ON $firstTable.$firstIndex=$table.{$tabNameIndex[$table]}"; 1364 } 1365 }else{ 1366 $this->out['tableName'] = $table; 1367 } 1368 } 1369 } 1370 } 1371 #line 1377 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1372 1373 /** 1374 * placeholder for the left hand side in a reduce operation. 1375 * 1376 * For a parser with a rule like this: 1377 * <pre> 1378 * rule(A) ::= B. { A = 1; } 1379 * </pre> 1380 * 1381 * The parser will translate to something like: 1382 * 1383 * <code> 1384 * function yy_r0(){$this->_retvalue = 1;} 1385 * </code> 1386 */ 1387 private $_retvalue; 1388 1389 /** 1390 * Perform a reduce action and the shift that must immediately 1391 * follow the reduce. 1392 * 1393 * For a rule such as: 1394 * 1395 * <pre> 1396 * A ::= B blah C. { dosomething(); } 1397 * </pre> 1398 * 1399 * This function will first call the action, if any, ("dosomething();" in our 1400 * example), and then it will pop three states from the stack, 1401 * one for each entry on the right-hand side of the expression 1402 * (B, blah, and C in our example rule), and then push the result of the action 1403 * back on to the stack with the resulting state reduced to (as described in the .out 1404 * file) 1405 * @param int Number of the rule by which to reduce 1406 */ 1407 function yy_reduce($yyruleno) 1408 { 1409 //int $yygoto; /* The next state */ 1410 //int $yyact; /* The next action */ 1411 //mixed $yygotominor; /* The LHS of the rule reduced */ 1412 //VTQL_ParseryyStackEntry $yymsp; /* The top of the parser's stack */ 1413 //int $yysize; /* Amount to pop the stack */ 1414 $yymsp = $this->yystack[$this->yyidx]; 1415 if (self::$yyTraceFILE && $yyruleno >= 0 1416 && $yyruleno < count(self::$yyRuleName)) { 1417 fprintf(self::$yyTraceFILE, "%sReduce (%d) [%s].\n", 1418 self::$yyTracePrompt, $yyruleno, 1419 self::$yyRuleName[$yyruleno]); 1420 } 1421 1422 $this->_retvalue = $yy_lefthand_side = null; 1423 if (array_key_exists($yyruleno, self::$yyReduceMap)) { 1424 // call the action 1425 $this->_retvalue = null; 1426 $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}(); 1427 $yy_lefthand_side = $this->_retvalue; 1428 } 1429 $yygoto = self::$yyRuleInfo[$yyruleno]['lhs']; 1430 $yysize = self::$yyRuleInfo[$yyruleno]['rhs']; 1431 $this->yyidx -= $yysize; 1432 for($i = $yysize; $i; $i--) { 1433 // pop all of the right-hand side parameters 1434 array_pop($this->yystack); 1435 } 1436 $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto); 1437 if ($yyact < self::YYNSTATE) { 1438 /* If we are not debugging and the reduce action popped at least 1439 ** one element off the stack, then we can push the new element back 1440 ** onto the stack here, and skip the stack overflow test in yy_shift(). 1441 ** That gives a significant speed improvement. */ 1442 if (!self::$yyTraceFILE && $yysize) { 1443 $this->yyidx++; 1444 $x = new VTQL_ParseryyStackEntry; 1445 $x->stateno = $yyact; 1446 $x->major = $yygoto; 1447 $x->minor = $yy_lefthand_side; 1448 $this->yystack[$this->yyidx] = $x; 1449 } else { 1450 $this->yy_shift($yyact, $yygoto, $yy_lefthand_side); 1451 } 1452 } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) { 1453 $this->yy_accept(); 1454 } 1455 } 1456 1457 /** 1458 * The following code executes when the parse fails 1459 * 1460 * Code from %parse_fail is inserted here 1461 */ 1462 function yy_parse_failed() 1463 { 1464 if (self::$yyTraceFILE) { 1465 fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt); 1466 } 1467 while ($this->yyidx >= 0) { 1468 $this->yy_pop_parser_stack(); 1469 } 1470 /* Here code is inserted which will be executed whenever the 1471 ** parser fails */ 1472 #line 456 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1473 1474 if(!$this->syntax_error){ 1475 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "Parsing failed"); 1476 } 1477 #line 1484 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1478 } 1479 1480 /** 1481 * The following code executes when a syntax error first occurs. 1482 * 1483 * %syntax_error code is inserted here 1484 * @param int The major type of the error token 1485 * @param mixed The minor type of the error token 1486 */ 1487 function yy_syntax_error($yymajor, $TOKEN) 1488 { 1489 #line 466 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1490 1491 $synMsg = "Syntax Error on line " . $this->lex->linenum . ": token '" .$this->lex->value."' "; 1492 $expect = array(); 1493 foreach ($this->yy_get_expected_tokens($yymajor) as $token) { 1494 $expect[] = self::$yyTokenName[$token]; 1495 } 1496 $synMsg =$synMsg.('Unexpected ' . $this->tokenName($yymajor) . '(' . $TOKEN 1497 . '), expected one of: ' . implode(',', $expect)); 1498 1499 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, $synMsg); 1500 #line 1508 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1501 } 1502 1503 /** 1504 * The following is executed when the parser accepts 1505 * 1506 * %parse_accept code is inserted here 1507 */ 1508 function yy_accept() 1509 { 1510 if (self::$yyTraceFILE) { 1511 fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt); 1512 } 1513 while ($this->yyidx >= 0) { 1514 $stack = $this->yy_pop_parser_stack(); 1515 } 1516 /* Here code is inserted which will be executed whenever the 1517 ** parser accepts */ 1518 #line 452 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.y" 1519 1520 $this->success = true; 1521 #line 1530 "e:\workspace\nonadmin\pkg\vtiger\extensions\Webservices\VTQL_parser.php" 1522 } 1523 1524 /** 1525 * The main parser program. 1526 * 1527 * The first argument is the major token number. The second is 1528 * the token value string as scanned from the input. 1529 * 1530 * @param int the token number 1531 * @param mixed the token value 1532 * @param mixed any extra arguments that should be passed to handlers 1533 */ 1534 function doParse($yymajor, $yytokenvalue) 1535 { 1536 // $yyact; /* The parser action. */ 1537 // $yyendofinput; /* True if we are at the end of input */ 1538 $yyerrorhit = 0; /* True if yymajor has invoked an error */ 1539 1540 /* (re)initialize the parser, if necessary */ 1541 if ($this->yyidx === null || $this->yyidx < 0) { 1542 /* if ($yymajor == 0) return; // not sure why this was here... */ 1543 $this->yyidx = 0; 1544 $this->yyerrcnt = -1; 1545 $x = new VTQL_ParseryyStackEntry; 1546 $x->stateno = 0; 1547 $x->major = 0; 1548 $this->yystack = array(); 1549 array_push($this->yystack, $x); 1550 } 1551 $yyendofinput = ($yymajor==0); 1552 1553 if (self::$yyTraceFILE) { 1554 fprintf(self::$yyTraceFILE, "%sInput %s\n", 1555 self::$yyTracePrompt, self::$yyTokenName[$yymajor]); 1556 } 1557 1558 do { 1559 $yyact = $this->yy_find_shift_action($yymajor); 1560 if ($yymajor < self::YYERRORSYMBOL && 1561 !$this->yy_is_expected_token($yymajor)) { 1562 // force a syntax error 1563 $yyact = self::YY_ERROR_ACTION; 1564 } 1565 if ($yyact < self::YYNSTATE) { 1566 $this->yy_shift($yyact, $yymajor, $yytokenvalue); 1567 $this->yyerrcnt--; 1568 if ($yyendofinput && $this->yyidx >= 0) { 1569 $yymajor = 0; 1570 } else { 1571 $yymajor = self::YYNOCODE; 1572 } 1573 } elseif ($yyact < self::YYNSTATE + self::YYNRULE) { 1574 $this->yy_reduce($yyact - self::YYNSTATE); 1575 } elseif ($yyact == self::YY_ERROR_ACTION) { 1576 if (self::$yyTraceFILE) { 1577 fprintf(self::$yyTraceFILE, "%sSyntax Error!\n", 1578 self::$yyTracePrompt); 1579 } 1580 if (self::YYERRORSYMBOL) { 1581 /* A syntax error has occurred. 1582 ** The response to an error depends upon whether or not the 1583 ** grammar defines an error token "ERROR". 1584 ** 1585 ** This is what we do if the grammar does define ERROR: 1586 ** 1587 ** * Call the %syntax_error function. 1588 ** 1589 ** * Begin popping the stack until we enter a state where 1590 ** it is legal to shift the error symbol, then shift 1591 ** the error symbol. 1592 ** 1593 ** * Set the error count to three. 1594 ** 1595 ** * Begin accepting and shifting new tokens. No new error 1596 ** processing will occur until three tokens have been 1597 ** shifted successfully. 1598 ** 1599 */ 1600 if ($this->yyerrcnt < 0) { 1601 $this->yy_syntax_error($yymajor, $yytokenvalue); 1602 } 1603 $yymx = $this->yystack[$this->yyidx]->major; 1604 if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ){ 1605 if (self::$yyTraceFILE) { 1606 fprintf(self::$yyTraceFILE, "%sDiscard input token %s\n", 1607 self::$yyTracePrompt, self::$yyTokenName[$yymajor]); 1608 } 1609 $this->yy_destructor($yymajor, $yytokenvalue); 1610 $yymajor = self::YYNOCODE; 1611 } else { 1612 while ($this->yyidx >= 0 && 1613 $yymx != self::YYERRORSYMBOL && 1614 ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE 1615 ){ 1616 $this->yy_pop_parser_stack(); 1617 } 1618 if ($this->yyidx < 0 || $yymajor==0) { 1619 $this->yy_destructor($yymajor, $yytokenvalue); 1620 $this->yy_parse_failed(); 1621 $yymajor = self::YYNOCODE; 1622 } elseif ($yymx != self::YYERRORSYMBOL) { 1623 $u2 = 0; 1624 $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2); 1625 } 1626 } 1627 $this->yyerrcnt = 3; 1628 $yyerrorhit = 1; 1629 } else { 1630 /* YYERRORSYMBOL is not defined */ 1631 /* This is what we do if the grammar does not define ERROR: 1632 ** 1633 ** * Report an error message, and throw away the input token. 1634 ** 1635 ** * If the input token is $, then fail the parse. 1636 ** 1637 ** As before, subsequent error messages are suppressed until 1638 ** three input tokens have been successfully shifted. 1639 */ 1640 if ($this->yyerrcnt <= 0) { 1641 $this->yy_syntax_error($yymajor, $yytokenvalue); 1642 } 1643 $this->yyerrcnt = 3; 1644 $this->yy_destructor($yymajor, $yytokenvalue); 1645 if ($yyendofinput) { 1646 $this->yy_parse_failed(); 1647 } 1648 $yymajor = self::YYNOCODE; 1649 } 1650 } else { 1651 $this->yy_accept(); 1652 $yymajor = self::YYNOCODE; 1653 } 1654 } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0); 1655 } 1656 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |